Browse Source
* docs: add HOW-TO docs for creating components * Prettified Code! Co-authored-by: jamescallumyoung <jamescallumyoung@users.noreply.github.com>pull/2129/head
2 changed files with 75 additions and 0 deletions
@ -0,0 +1,73 @@
@@ -0,0 +1,73 @@
|
||||
# How we develop components |
||||
|
||||
This document outlines how we develop the components for the Owncast Web UI. |
||||
|
||||
You should use this document as a guide when making changes to existing components, and adding new ones. |
||||
Working with the same development process help keep the project maintainable. |
||||
|
||||
## What are components |
||||
|
||||
A component in React is a custom HTML element. They're included in the DOM just like regular elements `<ChatBox /`>. |
||||
|
||||
## Functional Components |
||||
|
||||
In react, there's two ways to write a component: there's Class-based Components, and Functional Components. |
||||
|
||||
Class-based is older and has fallen out of favor. |
||||
Functional Components are the new standard and you'll find them in most React projects written today. |
||||
|
||||
See the [React Functional Component docs](https://reactjs.org/docs/components-and-props.html) for more info. |
||||
|
||||
### How we write Functional Components |
||||
|
||||
We've defined a pattern for how we write Functional Components in the Owncast Web UI. |
||||
There's a few ways to to write Functional Components that are common, so defining a standard helps keep this project readable and consistent. |
||||
|
||||
The pattern we've settled on is: |
||||
|
||||
**For stateless components:** |
||||
|
||||
```tsx |
||||
export type MyNewButtonProps = { |
||||
label: string; |
||||
onClick: () => void; |
||||
}; |
||||
|
||||
export const MyNewButton: FC<MyNewButtonProps> = ({ label, onClick }) => ( |
||||
<button onClick={onCLick}>{label}</button> |
||||
); |
||||
``` |
||||
|
||||
**For stateful components:** |
||||
|
||||
```tsx |
||||
export type MyNewButtonProps = { |
||||
label: string; |
||||
onClick: () => void; |
||||
}; |
||||
|
||||
export const MyNewButton: FC<MyNewButtonProps> = ({ label, onClick }) => { |
||||
// do something, then call the onClick fn. e.g.: |
||||
const handleClick = useCallback(() => { |
||||
alert(label); |
||||
onClick && onClick(); |
||||
}, [label, onClick]); |
||||
|
||||
return <button onClick={onCLick}>{label}</button>; |
||||
}; |
||||
``` |
||||
|
||||
### Rationale |
||||
|
||||
Since there's a lot of ways to create components, settling on one pattern helps maintain readability. |
||||
But why _this_ style? |
||||
|
||||
See the discussion on the PR that introduced this pattern: [#2082](https://github.com/owncast/owncast/pull/2082). |
||||
|
||||
## Storybook |
||||
|
||||
We use [Storybook](https://storybook.js.org/) to create a component library where we can see and interact with each component. |
||||
|
||||
Make sure to include a `.stories.tsx` file with each (exported) component you create, and to update the stories file when making changes to existing components. |
||||
|
||||
You can run the Storybook server locally with `npm run storybook`. |
Loading…
Reference in new issue