forked from EightfoldAI/octuple
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add component guidelines (EightfoldAI#12)
- Loading branch information
1 parent
4193855
commit 406fc00
Showing
1 changed file
with
176 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
# Component Guidelines | ||
|
||
--- | ||
|
||
## Directory structure | ||
|
||
For a basic component | ||
|
||
``` | ||
├── Component | ||
│ ├── component.module.scss | ||
│ ├── Component.tsx | ||
│ ├── Component.types.ts | ||
│ ├── Component.stories.ts | ||
│ ├── Component.test.js | ||
│ └── index.ts | ||
``` | ||
|
||
For a component suite | ||
|
||
``` | ||
├── Component | ||
│ ├── BaseComponent | ||
│ │ ├── BaseComponent.tsx | ||
│ │ ├── baseComponent.module.scss | ||
│ │ └── BaseComponent.test.js | ||
│ ├── SecondaryComponent | ||
│ │ ├── SecondaryComponent.tsx | ||
│ │ ├── secondaryComponent.module.scss | ||
│ │ └── SecondaryComponent.test.js | ||
│ ├── Component.types.ts | ||
│ ├── Component.stories.ts | ||
│ └── index.ts | ||
``` | ||
|
||
## Component definition | ||
|
||
Create a file called `/src/components/Component/Component.tsx` | ||
|
||
```tsx | ||
import React, { FC } from 'react'; | ||
import { ComponentProps, ComponentType } from './Component.types'; | ||
import { classNames } from '../../shared/utilities'; | ||
|
||
import styles from 'component.module.scss'; | ||
|
||
export const Component: FC<ComponentProps> = ({ | ||
className, | ||
style, | ||
// How to set defaults for props | ||
type = ComponentType.base, | ||
... | ||
}) => { | ||
// Combining class names can be done using the classNames utility | ||
const componentClasses: string = classNames([ | ||
styles.componentWrapper, | ||
className, | ||
// Conditional classes can also be handled as follows | ||
{ [styles.active]: type === ComponentType.base } | ||
]); | ||
return ( | ||
<div className={componentClasses} style={style}> | ||
<div className={styles.componentChild}> | ||
... | ||
</div> | ||
</div> | ||
); | ||
}; | ||
``` | ||
|
||
## Styling | ||
|
||
Defining a scss module | ||
|
||
- Create a file called `/src/components/Component/component.module.scss` | ||
- Use camel case for the class names, they are easier to reference in the component | ||
|
||
For eg: `styles.componentWrapper` as apposed to `styles['component-wrapper']` | ||
|
||
```scss | ||
.componentWrapper { | ||
|
||
&.active { | ||
... | ||
} | ||
|
||
.componentChild { | ||
... | ||
} | ||
} | ||
``` | ||
|
||
## Defining types | ||
|
||
Create a file called `/src/components/Component/Component.types.ts` | ||
|
||
```ts | ||
import React from 'react'; | ||
|
||
// Use enums of property with fixed set of values | ||
export enum ComponentType { | ||
base = 'base', | ||
secondary = 'secondary' | ||
} | ||
|
||
export interface ComponentProps { | ||
/** | ||
* Child of the component | ||
*/ | ||
children: React.ReactNode; | ||
/** | ||
* Custom class name | ||
* @default null | ||
*/ | ||
className?: string; | ||
/** | ||
* Style of the component | ||
* @default null | ||
*/ | ||
style?: React.CSSProperties; | ||
/** | ||
* Type of the component | ||
* @default ComponentType.base | ||
*/ | ||
type?: ComponentType; | ||
... | ||
} | ||
``` | ||
|
||
## Exporting component | ||
|
||
Create a file called `/src/components/Component/index.ts` | ||
|
||
- Export all the components and typing created | ||
|
||
```ts | ||
export * from './Component.types'; | ||
export * from './Component'; | ||
export * from './BaseComponent/BaseComponent'; | ||
export * from './SecondaryComponent/SecondaryComponent'; | ||
... | ||
``` | ||
|
||
## Storybook | ||
|
||
Create a file called `/src/components/Component/Component.stories.ts` | ||
|
||
```tsx | ||
import React from 'react'; | ||
import { Component, SecondaryComponent } from './'; | ||
|
||
export default { | ||
title: 'Component', | ||
component: Component, | ||
}; | ||
|
||
export const Primary = () => ( | ||
<> | ||
<p>Primary</p> | ||
<Component /> | ||
</> | ||
); | ||
|
||
export const Secondary = () => ( | ||
<> | ||
<p>Secondary</p> | ||
<SecondaryComponent /> | ||
</> | ||
); | ||
``` | ||
|
||
## Unit testing [WIP] | ||
|
||
Create a file called `/src/components/Component/Component.test.js` | ||
|
||
TBD |