Skip to content

Building Components

Vindhya edited this page Apr 8, 2021 · 3 revisions
  • Moonstone uses the gitflow branching methodology. Create feature branches off of the develop branch. Branches should be named with the Jira ticket number, e.g., "MOON-555".
  • Commit messages should have this format: "MOON-jira_ticket_number: Short description in the present tense".
  • These files should exist for each component:
    • [ComponentName].tsx with the actual React component code
    • [ComponentName].types.ts to contain the types and any type-related information
    • [ComponentName].scss with any styles
    • [ComponentName].stories.[tj]sx with the Storybook stories
    • [ComponentName].spec.[tj]s with tests for the component
    • [ComponentName].md with additional documentation
    • index.ts to export the component
  • All components should be named in PascalCase.
  • Create a directory inside src/components for each new component. Any sub-components that cannot be used without a parent component should exist within the parent component’s directory. If the sub-component has its own SCSS, tests, types, etc., create a folder to contain its files within the parent component’s sub-directory.
  • If you need to add a new library/dependency for your component, first ask in the #team-moonstone Slack channel.
  • Import the new component in src/component/index.ts.

Writing the Component File (.tsx)

  • All new components should be written in Typescript
  • Use function components wherever possible
  • If default values for the props are necessary, set them as default parameters in the function component definition
  • Where it makes sense to allow the rendered root node element of a component to be dynamic, use the React.createElement syntax so that the user of the component can pass in their chosen HTML element and name this props component.
  • For an example of this, see the Typography component.
  • Ensure that the displayName property is set for the component to ensure ease of debugging.

Types for Components (.tsx and .types.ts)

  • Use an object type alias to describe the props of the component in the .types.ts file.
  • For each prop, use a JSDoc comment to describe the prop. This is important as it will show in the API documentation for the component in Storybook.
  • Name the type like this: [ComponentName]Props.
  • Assign the generic type, React.FC, to the component in its .tsx file and pass in the component prop types defined in the .types.ts file to the generic.
  • Type-checking with React PropTypes is not required because there is a babel plugin in the build process that converts the Typescript definition to PropTypes.

Styles (.scss)

  • Use a modified version of the CSS BEM [http://getbem.com/naming/] naming convention for classes. However, instead of double underscores and dashes, use single underscores and dashes.
  • All classes should be prefixed with moonstone-.
  • We use the prefix because we don’t use CSS modules so that the build process of Moonstone can be simplified.
  • For an example of this, see any existing Moonstone component .scss file.
  • Write classes as flat as possible to prevent specificity issues which also allows them to be overridden more easily.

Stories (.stories.[tj]sx)

  • Stories should be written in the CSF (Component Story Format) and use template args wherever possible. Using template args allows usage of the Controls in stories out of the box.
  • There should be a story to show each major usage/variant of a component.
  • There should be a "playground" story that allows the user to use the controls to quickly change the props and visually see the changes of the component.

Tests (.spec.ts)