Implement Components

Organization

  • every component has a dedicated directory under ./packages/components/src
  • includes an index.js; see exports below
  • includes a README.mdx
  • may include other files that are not publicly exported in the index.js
.
└── packages
    └── components
        └── src
            ├── index.js
            ├── README.mdx
            ├── otherInternalOnlyFunctionality.js
            └── SpacedGroup.js

Exports

The component directory's index.js file export the publicly consumable portions of the component. In other words, it should never be required to import from a file within the component's directory other than the index.js file.

Component directories should always export all items as named exports.

Example index.js

export { default as MainComponent } from './MainComponent';
export { default as SecondaryComponent } from './SecondaryComponent';

Occassionally there will be a group of components that work together and are only relevant when used with each other (example: a list and list items). In these cases, ensure the primary component is a named export and namespace secondary components off the primary one. As an example, in the case of List:

import List from './List';
import Item from './Item';
import ItemText from './ItemText';

List.Item = Item;
List.ItemText = ItemText;

export { List };

Styling

Component styling is powered by our implementation using fela.

See createComponent and ThemeProvider for more a more in-depth explanation.

Using StyleProvider and createComponent Example

const Button = createComponent(
  () => ({
    color: 'blue',
  }),
  'div',
);

const SaveButton = ({ children }) => <Button>{children}</Button>;

Required PropTypes

  • components declare appropriate propTypes and also comments on each propType
  • components declare appropraite defaultProps
const MyComponent = ({text}) => <span>Hello {text}.</span>;

MyComponent.propTypes = {
  /** Inner text */
  text: PropTypes.color,
};
MyComponent.defaultProps: {
  text: 'world',
};

ThemeDefinition

Not all components are theme-enabled; however, those that are should declare a ThemeDefinition and defaultThemeValues.

See createComponent and ThemeProvider for more details on how to consume the theme in your component.

  • components declare appropriate themeDefintion and also comment descriptions for each value; similar to propTypes, but describes the theme-able configuration properites of the component
  • components declare appropriate defaultThemeValues
const MyComponent = () => <span>Hello World</span>;

MyComponent.themeDefintion = {
  /** Text color */
  color: PropTypes.color,
};
MyComponent.defaultThemeValues: {
  color: 'lightgray',
};

Further Reading