https://github.com/igoodie/react-compound-composer
🖇️ Spend less time crafting your complex Compound Components
https://github.com/igoodie/react-compound-composer
complex component compound library nested react
Last synced: 7 months ago
JSON representation
🖇️ Spend less time crafting your complex Compound Components
- Host: GitHub
- URL: https://github.com/igoodie/react-compound-composer
- Owner: iGoodie
- License: cc-by-sa-4.0
- Created: 2023-08-08T12:15:23.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2024-10-05T22:52:33.000Z (over 1 year ago)
- Last Synced: 2025-02-01T23:51:03.553Z (over 1 year ago)
- Topics: complex, component, compound, library, nested, react
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/react-compound-composer
- Size: 155 KB
- Stars: 4
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
Spend less time crafting your Compound Components structure
# Description
This library aims to make it easier to develop and maintain **Compound Components** by encapsulating **context creation** and **compound composition** logic under two core helpers.
Check those amazing posts to learn more about Compound Components:
- https://www.smashingmagazine.com/2021/08/compound-components-react/
- https://betterprogramming.pub/compound-component-design-pattern-in-react-34b50e32dea0
- https://blog.logrocket.com/understanding-react-compound-components/
# Examples/Demo
- [Stackblitz Collection](https://stackblitz.com/@iGoodie/collections/react-compound-composer)
1. [Simple Counter Example](https://stackblitz.com/edit/stackblitz-starters-e639ls?file=src%2FCounter.component.tsx): An almost in-line example of a Counter with its own state. Here just for a very quick proof-of-concept.
2. [A Better Structured Example](https://stackblitz.com/edit/stackblitz-starters-ltkqyc?file=src%2Fcomponents%2Faccordion%2Faccordion.tsx): An example of an Accordion compound
3. [Nested Compounds Example](https://stackblitz.com/edit/stackblitz-starters-aexdiu?file=src%2Fcomponents%2Faccordion%2Fbody%2Faccordion-body.tsx): An example of nested compound
4. [Flattened Root Example](https://stackblitz.com/edit/stackblitz-starters-yhr2uv?file=src%2FApp.tsx): An example of how you can flatten `Root` components
# How to Use?
## 1. Create your Context
Start off by creating your context. This context will be available via a hook on all the sub-components. A good way to keep a dispatch-editable state across the components.
```tsx
import { contextBuilder } from "react-compound-composer";
interface CounterRootProps extends React.PropsWithChildren {
initialCount?: number;
}
const {
Consumer: CounterConsumer, // Consumer is also returned, just for convenience
Provider: CounterProvider,
useContext: useCounterContext,
} = contextBuilder((rootProps: CounterRootProps) => {
const [count, setCount] = useState(rootProps.initialCount ?? 0);
return {
count,
increase: (count: number) => setCount((c) => c + count),
decrease: (count: number) => setCount((c) => c - count),
};
});
```
## 2. Create your Root & Sub Components
Create a few components to be composed under the compound.
```tsx
import React from "react";
const CounterRoot = (props: CounterRootProps) => {
return (
{props.children}
);
};
```
```tsx
import React from "react";
const CounterCount = () => {
const ctx = useCounterContext();
return {ctx.count};
};
```
```tsx
import React from "react";
const CounterIncrease = () => {
const ctx = useCounterContext();
return ctx.increase(1)}>Increase;
};
```
```tsx
import React from "react";
const CounterDecrease = () => {
const ctx = useCounterContext();
return ctx.decrease(1)}>Decrease;
};
```
## 3. Compose your Compound with them!
Finally compose your Compound with the components you've created.
```tsx
import { compoundBuilder } from "react-compound-composer";
export const Counter = compoundBuilder({
name: "Counter",
provider: CounterProvider,
components: {
Root: CounterRoot,
Count: CounterCount,
Increase: CounterIncrease,
Decrease: CounterDecrease,
},
});
```
## 4. Enjoy your Compound!
Use your compound as desired.
```tsx
export default function App() {
return (
);
}
```
## How to Flatten `Root` Components?
If you prefer using the root components without actually using their `Root` properties, you can set the `flattenRoot` option to `true`. Like so:
```tsx
import { compoundBuilder } from "react-compound-composer";
export const Counter = compoundBuilder({
name: "Counter",
provider: CounterProvider,
flattenRoot: true,
components: {
Root: CounterRoot,
Count: CounterCount,
Increase: CounterIncrease,
Decrease: CounterDecrease,
},
});
```
and use the Compound like so:
```tsx
export default function App() {
return (
);
}
```
## License
© 2023 Taha Anılcan Metinyurt (iGoodie)
For any part of this work for which the license is applicable, this work is licensed under the [Attribution-ShareAlike 4.0 International](http://creativecommons.org/licenses/by-sa/4.0/) license. (See LICENSE).
