Uploaded image for project: 'stripes-components'
  1. stripes-components
  2. STCOM-298

Discussion: Only include presentational components in stripes-components

    XMLWordPrintable

    Details

    • Type: Task
    • Status: Closed (View Workflow)
    • Priority: P3
    • Resolution: Done
    • Affects Version/s: None
    • Fix Version/s: None
    • Labels:
      None
    • Template:
    • Development Team:
      Stripes Force

      Description

      Proposal

      Agree and document that stripes-components should only contain presentational components, making it possible to:

      • Simplify the dependency graph for modules
      • Render and test all components in isolation
      • Free up module developers from lock-in to specific solutions

      What’s a presentational component?

      The industry standard on design systems teams is a reusable component library containing only presentational components.

      A presentational component is:

      • Easy to reason about
      • Context agnostic
      • Independent and isolated

      This means it:

      • Receives data and callbacks exclusively via props.
      • Has no dependencies on any stores or state management tools (Redux, Flux, etc.).

      Resources

      Current problems

      Almost all of the components in stripes-components are presentational. There are a handful that aren’t.

      Those components cause challenges with:

      • Dependencies
      • Isolation
      • Lock-in

      Dependencies

      The handful of components in stripes-components that aren’t presentational have dependencies on stripes-core, stripes-form, redux-form, react-redux, and redux. There are also a few utility functions intended for use with stripes-connect.

      To demonstrate how that manifests itself, here’s part of the dependency graph for ui-users:

      Peer dependencies are dashed
      Circular dependencies are red

      Isolation

      We haven’t been able to take advantage of the efficiency and quality benefits of our tools with components that aren’t presentational.

      Not all of our components…

      … can be rendered in Storybook. Storybook is built exactly for this use case - documenting a library of purely presentational, reusable components.

      ... can be tested by themselves. If it needs any outside context, a data store, or a back end, it won’t run in the stripes-components test suite, and it’s not presentational.

      Example: the <Settings> component requires the stripes object be retrieved through the legacy React context API, so it can’t be rendered in Storybook or tested in isolation.

      Lock-in

      On the back end, the FOLIO project is fully committed to a microservices philosophy. Individual modules make their own choices about language and libraries, as long as they adhere to a limited contract.

      The front end is more restrictive because of runtime needs, but front-end FOLIO module developers are still free to make their own choices about state management, server communication, and adoption of UI components.

      When components are coupled to a specific library (examples: redux and stripes-connect), it limits the ability of module developers to bring alternative solutions into the ecosystem.

      Example: the eHoldings developers are interested in alternatives to redux-form, but because so many form components in stripes-components don’t work outside of a redux-form, they’re locked in.

      What would a purely presentational stripes-components look like?

      • stripes-components would not consume context from outside the stripes-components repo (this includes intl strings, locale, time zone, etc.); UI modules would consume the stripes-core context and pass it in as props to stripes-components
      • stripes-components would have no dependency on stripes-connect, stripes-form, redux-form, react-redux, or redux
      • every form component would work independently of redux-form (but still play nicely with redux-form)
      • no routing inside components; it would be up to UI modules to handle that responsibility

      A stripes-components that meets those requirements would not even have a peer dependency on stripes-core.

      In an ideal scenario, the patterns in stripes-smart-components would also be refactored to have no opinions on state management or back end, and thus could be moved into stripes-components. It would be up to individual modules to use stripes-connect (or any other tools) to connect the reusable components through props.

      Here’s what that same section of dependency graph for ui-users would look like with a purely presentational stripes-components.

      Action items

      • Agree that restricting stripes-components to presentational components is the right approach.
      • Record the rule in stripes-components documentation.
      • Prevent future component development from violating this rule.
      • Create JIRA issues for existing components and utility functions that do not conform.

      Feedback

      If you agree with this direction, please give a thumbs up.

      If you disagree with this direction, are there alternative architectural patterns that will solve the three problems presented: dependencies, isolation, and lock-in?

        TestRail: Results

          Attachments

            Issue Links

              Activity

                People

                Assignee:
                Unassigned Unassigned
                Reporter:
                cherewaty Jeffrey Cherewaty
                Votes:
                0 Vote for this issue
                Watchers:
                6 Start watching this issue

                  Dates

                  Created:
                  Updated:
                  Resolved:

                    TestRail: Runs

                      TestRail: Cases