Skip to content

Commit e5da9aa

Browse files
committed
Added readme for github
1 parent 8ee51ba commit e5da9aa

7 files changed

Lines changed: 55 additions & 278 deletions

File tree

README.md

Lines changed: 22 additions & 251 deletions
Original file line numberDiff line numberDiff line change
@@ -1,263 +1,34 @@
1-
# @beqa/react-slots - Responsible React Parenting (docs are a work in progress)
1+
# beqa/react-slots - Responsible React Parenting
22

3-
@beqa/react-slots brings the slot pattern from Vue and Svelte to React, offering a minimal API that retains all the features you expect while providing unmatched type safety.
3+
> `react-slots` empowers you to prioritize composability in your component APIs.
44
5-
## Why Use the Slot Pattern:
5+
The core of `react-slots` is the slot pattern. It's designed to provide all the
6+
features you'd find in Vue and Svelte's slot implementations while keeping
7+
things familiar for React developers. This slot pattern, complemented by **great
8+
type inference features** and an **intuitive API for manipulating nodes**,
9+
allows you to design highly composable components with previously unimagined
10+
patterns in React.
611

7-
- **Structured Children:** With the slot pattern, your component's children become key-value pairs rather than a simple array. This enables you to indicate where different parts of parent-provided slot content should be rendered.
8-
- **Resilience to Change:** Slot-based components are more adaptable to change. You can start with a basic set of children and gradually add conditional rendering, new UI elements, fallback content, and data passing without breaking existing code that uses your components.
9-
- **Convenient APIs:** The library provides additional APIs like the Template's `as` prop, adding convenience to your component development.
10-
- **Fixing React-Specific Problems:** "@beqa/react-slots" addresses React-specific issues like alternatives to React.Children APIs and React.CloneElement that provide solutions you actually want to use.
12+
## Examples
1113

12-
While these docs are a work in progress, we recommend checking out [Vue's slots documentation](https://vuejs.org/guide/components/slots.html). You'll easily find corresponding APIs and discover how @beqa/react-slots can help you write better code.
14+
| The code samples below represent actual implementations. No need to define external state or event handlers for these components to function. |
15+
| --------------------------------------------------------------------------------------------------------------------------------------------- |
1316

14-
## Quick Guide: Using Slots to Create Reusable DialogTrigger and Dialog Components
17+
### Creating highly composable `Accordion` and `AccordionList` components using react-slots
1518

16-
For a live example, check out this [StackBlitz demo.](https://stackblitz.com/edit/vitejs-vite-pz81vn?file=vite.config.ts,src%2FApp.tsx)
19+
Checkout
20+
[live example](https://stackblitz.com/edit/stackblitz-starters-tq32ef?file=pages%2Findex.tsx)
1721

18-
**Creating the DialogTrigger Component**
22+
![Example showing usage of Accordion component built with react-slots](/packages/react-slots/readme-assets/Accordion.png)
1923

20-
```tsx
21-
export type DialogTriggerProps = {
22-
children: SlotChildren<
23-
| Slot<"trigger"> // Content labeled as 'trigger.'
24-
| Slot<{ isOpen: boolean; close: () => void }> // Unlabeled content or labeled as 'default,' with props
25-
>;
26-
};
24+
### Creating highly composable `Dialog` and `DialogTrigger` components using react-slots
2725

28-
export function DialogTrigger({ children }: DialogTriggerProps) {
29-
const [isOpen, setIsOpen] = useState(false);
30-
const { slot } = useSlot(children); // Inferred magic
26+
Checkout
27+
[live example](https://stackblitz.com/edit/stackblitz-starters-fa5wbe?file=pages%2Findex.tsx)
3128

32-
return (
33-
<div>
34-
<button onClick={() => setIsOpen(true)}>
35-
{/* Render Trigger here or use 'Trigger it' as fallback if no trigger content provided. */}
36-
<slot.trigger>Trigger it</slot.trigger>
37-
</button>
38-
{isOpen && (
39-
<slot.default isOpen={isOpen} close={() => setIsOpen(false)} /> // Props are passed up to the parent
40-
)}
41-
</div>
42-
);
43-
}
29+
![Example showing usage of Dialog component built with react-slots](/packages/react-slots/readme-assets/Accordion.png)
4430

45-
// Create a type-safe template for DialogTrigger by inferring DialogTrigger slots (optional)
46-
export const dialogTriggerTemplate =
47-
createTemplate<DialogTriggerProps["children"]>();
48-
```
31+
---
4932

50-
**Creating the Dialog Component**
51-
52-
```tsx
53-
export type DialogProps = {
54-
children: SlotChildren<
55-
| Slot // Our header element. Shorthand for Slot<'default', {}>
56-
| Slot<"description", { style: object }> // Slot for 'description' with style prop
57-
| Slot<"primaryAction">
58-
| Slot<"secondaryAction">
59-
>;
60-
};
61-
62-
export function Dialog({ children }: DialogProps) {
63-
const { slot, hasSlot } = useSlot(children);
64-
65-
return (
66-
<dialog open>
67-
<slot.default />
68-
{/* Render a horizontal line under the header if a header is provided */}
69-
{hasSlot && <hr />}
70-
<slot.description style={{ textAlign: "center" }} />
71-
<div className="actions">
72-
<slot.secondaryAction />
73-
<slot.primaryAction />
74-
</div>
75-
</dialog>
76-
);
77-
}
78-
79-
// Create a type-safe template for the Dialog component (optional)
80-
export const dialogTemplate = createTemplate<DialogProps["children"]>();
81-
```
82-
83-
**Using in Your App**
84-
85-
```tsx
86-
function App() {
87-
return (
88-
<DialogTrigger>
89-
{/* Label the span as "trigger" (not type-safe) */}
90-
<span slot-name="trigger">Delete</span>
91-
{({ close }) => (
92-
// Normally this function would be wrapped in a template element that specifies the 'default' label:
93-
// <template.default>{({close}) => {...}}</template.default>
94-
// but since it's the default slot we can simplify it.
95-
// `close` comes from the dialog's <slot.default close={() => setIsOpen(false)} />
96-
<Dialog>
97-
Are you sure you want to delete this item?
98-
{/* Type-safe template (the <p> element will be rendered in place of slot.description) */}
99-
<dialogTemplate.description>
100-
{({ style }) => <p style={style}>This action can't be reversed</p>}
101-
</dialogTemplate.description>
102-
{/* Regular template */}
103-
<template.primary>
104-
<button onClick={close}>I understand</button>
105-
</template.primary>
106-
</Dialog>
107-
)}
108-
</DialogTrigger>
109-
);
110-
}
111-
```
112-
113-
## Install the Runtime Library
114-
115-
```bash
116-
npm i @beqa/react-slots
117-
```
118-
119-
## Install the Compile Time Plugin (Optional)
120-
121-
The compile time plugin is required to transform slot elements returned by useSlot into function invocations as shown below:
122-
123-
```tsx
124-
// Before transpilation
125-
<slot.default prop1={"foo"} prop2={42}>
126-
Fallback
127-
</slot.default>;
128-
// After transpilation
129-
slot.default("Fallback", { prop1: "foo", prop2: 42 });
130-
```
131-
132-
You have the option to skip installing the compile time plugin and start using slots as functions immediately.
133-
134-
If your project uses Vite, Rollup, or esbuild, you can install `@beqa/unplugin-transform-react-slots` and follow the configuration steps for your bundler. For other bundlers or if you are using Babel in your project, you should install `@beqa/babel-plugin-transform-react-slots`. Note that you don't need to install both plugins.
135-
136-
<details>
137-
<summary><strong>Babel Plugin</strong></summary>
138-
139-
```bash
140-
npm i @beqa/babel-plugin-transform-react-slots
141-
```
142-
143-
Add react-slots plugin to your babel config
144-
145-
```js
146-
// babel.config.json
147-
{
148-
"plugins": {"@beqa/babel-plugin-transform-react-slots"}
149-
}
150-
```
151-
152-
</details>
153-
154-
<details>
155-
<summary><strong>Vite Integration</strong></summary>
156-
157-
```bash
158-
npm i @beqa/unplugin-transform-react-slots
159-
```
160-
161-
Add the `unplugin.vite` to your Vite configuration (vite.config.js) before the react plugin:
162-
163-
```js
164-
// vite.config.js
165-
import unplugin from "@beqa/unplugin-transform-react-slots";
166-
import react from "@vitejs/plugin-react";
167-
168-
export default {
169-
plugins: [unplugin.vite(), react()],
170-
};
171-
```
172-
173-
</details>
174-
175-
<details>
176-
<summary><strong>Esbuild Integration</strong></summary>
177-
178-
```bash
179-
npm i @beqa/unplugin-transform-react-slots
180-
```
181-
182-
Add `unplugin.esbuild` to your plugins list in your esbuild config
183-
184-
```js
185-
import unplugin from "@beqa/unplugin-transform-react-slots";
186-
187-
// esbuild.config.js
188-
await build({
189-
plugins: [unplugin.esbuild()],
190-
});
191-
```
192-
193-
</details>
194-
195-
<details>
196-
<summary><strong>Rollup Integration</strong></summary>
197-
198-
```bash
199-
npm i @beqa/unplugin-transform-react-slots
200-
```
201-
202-
Add the `unplugin.rollup` to your plugins list before all other plugins in your Rollup configuration (rollup.config.js):
203-
204-
```js
205-
import unplugin from "@beqa/unplugin-transform-react-slots";
206-
207-
// esbuild.config.js
208-
await build({
209-
plugins: [unplugin.rollup()],
210-
});
211-
```
212-
213-
</details>
214-
215-
<details>
216-
<summary><strong>Performance Optimization with Unplugin Options</strong></summary>
217-
218-
```tsx
219-
type Options = {
220-
include: RegEx;
221-
exclude: RegEx | RegEx[];
222-
};
223-
224-
const options = {
225-
include: /\.(tsx)|(jsx)|(js)/,
226-
} satisfies Options;
227-
228-
unplugin.yourBundler(options);
229-
```
230-
231-
`unplugin-transform-react-slots` is designed to be fast at finding and transforming React slots. By default, it checks every JavaScript (js), JSX (jsx), and TypeScript (tsx) file in your project, excluding files in the node_modules directory. However, you can optimize its performance further by using specific options.
232-
233-
**include Option**
234-
235-
If you have other tools configured in a way that JSX syntax is only used in certain files, you can provide the include regular expression (RegEx) as an argument to your plugin. For instance:
236-
237-
```tsx
238-
unplugin.yourBundler({ include: /\.(tsx)|(jsx)/ });
239-
```
240-
241-
With this configuration, the plugin will only check .tsx and .jsx files in your project, improving performance by skipping unnecessary files.
242-
243-
**exclude Option**
244-
245-
Additionally, you can use the exclude option to exclude specific files or directories from being processed. This can be useful for excluding configuration files or large files that don't need slot transformation:
246-
247-
</details>
248-
249-
## Troubleshooting
250-
251-
``Unsupported syntax: `useSlot` or an object holding a nested `useSlot` value used inside ... ``
252-
253-
If you encounter this error message after initializing the compile-time plugin for your project, it likely indicates that the plugin is applied after React elements have already been transpiled. To resolve this issue, you should adjust your configuration to ensure that the plugin runs before other syntax transformations.
254-
255-
This error occurs when useSlot or the return value of useSlot is used in a way that could potentially mutate slots before they are used. It's important to note that this is a specific error related to the compile-time plugin.
256-
257-
If you wish to disable the transformation for a specific file where this error occurs, you can add the following comment at the beginning of the file:
258-
259-
```js
260-
// @disable-transform-react-slots
261-
```
262-
263-
After adding this comment, you should only use the function signature of slots in that file.
33+
| If you like this project please show support by starring it on [Github](https://github.com/Flammae/react-slots) |
34+
| --------------------------------------------------------------------------------------------------------------- |

docs/.github/screenshot.png

-868 KB
Binary file not shown.

docs/README.md

Lines changed: 0 additions & 23 deletions
This file was deleted.

docs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "docs",
3-
"version": "0.0.1",
3+
"private": true,
44
"description": "Nextra docs template",
55
"scripts": {
66
"dev": "next dev",

packages/react-slots/README.md

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,34 @@
1-
# @beqa/react-slots - Responsible React Parenting
1+
# beqa/react-slots - Responsible&nbsp;React&nbsp;Parenting
22

3-
@beqa/react-slots brings the slot pattern from Vue and Svelte to React, offering a minimal API that retains all the features you expect while providing unmatched type safety.
3+
> `react-slots` empowers you to prioritize composability in your component APIs.
44
5-
[Read the docs](https://github.com/Flammae/react-slots)
5+
The core of `react-slots` is the slot pattern. It's designed to provide all the
6+
features you'd find in Vue and Svelte's slot implementations while keeping
7+
things familiar for React developers. This slot pattern, complemented by **great
8+
type inference features** and an **intuitive API for manipulating nodes**,
9+
allows you to design highly composable components with previously unimagined
10+
patterns in React.
11+
12+
## Examples
13+
14+
| The code samples below represent actual implementations. No need to define external state or event handlers for these components to function. |
15+
| --------------------------------------------------------------------------------------------------------------------------------------------- |
16+
17+
### Creating highly composable `Accordion` and `AccordionList` components using react-slots
18+
19+
Checkout
20+
[live example](https://stackblitz.com/edit/stackblitz-starters-tq32ef?file=pages%2Findex.tsx)
21+
22+
![Example showing usage of Accordion component built with react-slots](/packages/react-slots/readme-assets/Accordion.png)
23+
24+
### Creating highly composable `Dialog` and `DialogTrigger` components using react-slots
25+
26+
Checkout
27+
[live example](https://stackblitz.com/edit/stackblitz-starters-fa5wbe?file=pages%2Findex.tsx)
28+
29+
![Example showing usage of Dialog component built with react-slots](/packages/react-slots/readme-assets/Accordion.png)
30+
31+
---
32+
33+
| If you like this project please show support by starring it on [Github](https://github.com/Flammae/react-slots) |
34+
| --------------------------------------------------------------------------------------------------------------- |
172 KB
Loading
202 KB
Loading

0 commit comments

Comments
 (0)