@bento/use-props 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +125 -0
- package/package.json +4 -3
package/README.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Props Management
|
|
2
|
+
|
|
3
|
+
The `@bento/use-props` package provides a hook that unifies the component
|
|
4
|
+
and slot based props into a single interface. Both the component and slot-based
|
|
5
|
+
props can be specified as a `renderProp`. A `renderProp` is a function that
|
|
6
|
+
returns the value that should be applied as props to the component.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```shell
|
|
11
|
+
npm install --save @bento/use-props
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## useProps
|
|
15
|
+
|
|
16
|
+
The package exposes a `useProps` hook that can be used to apply the
|
|
17
|
+
props to the component. The hook is designed to be used in conjunction
|
|
18
|
+
with the `@bento/slots` package as it allows the `slots` props that are
|
|
19
|
+
introduced on the component to override the props that are specified on the
|
|
20
|
+
component.
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
import { useProps } from '@bento/use-props';
|
|
24
|
+
import { useState } from 'react';
|
|
25
|
+
|
|
26
|
+
function Component(args) {
|
|
27
|
+
const [value, setValue] = useState(0);
|
|
28
|
+
const { props, apply } = useProps(args, { value });
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
As seen from the example above, the `useProps` hook takes two
|
|
33
|
+
arguments:
|
|
34
|
+
|
|
35
|
+
The `useProps` hook returns an object with two properties:
|
|
36
|
+
|
|
37
|
+
### props
|
|
38
|
+
|
|
39
|
+
The `props` property is a `props`-like object - specifically a `Proxy` instance. It
|
|
40
|
+
provides the familiar `props` interface for retrieving component props. When props
|
|
41
|
+
are modified by slots to add or override values, this Proxy automatically returns
|
|
42
|
+
the correct merged value. The Proxy seamlessly handles both component props and
|
|
43
|
+
slot-based props.
|
|
44
|
+
|
|
45
|
+
When the prop that you're trying to access is specified as a `renderProp`, the
|
|
46
|
+
`Proxy` will automatically call the function and return the value returned by
|
|
47
|
+
the function. It's designed to do all the work for you so you can focus on
|
|
48
|
+
writing your components.
|
|
49
|
+
|
|
50
|
+
Just like normal `props`, you can also use this instance to spread the props
|
|
51
|
+
on your components:
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
import { useProps } from '@bento/use-props';
|
|
55
|
+
import { withSlots } from '@bento/slots';
|
|
56
|
+
import { useState } from 'react';
|
|
57
|
+
|
|
58
|
+
const Anchor = withSlots('Anchor', function AnchorComponent(args) {
|
|
59
|
+
const [value, setValue] = useState(0);
|
|
60
|
+
const { props, apply } = useProps(args, { value });
|
|
61
|
+
|
|
62
|
+
return <a {...props} />;
|
|
63
|
+
})
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The primary use case for the `props` item is to interact with properties that
|
|
67
|
+
do not have a default value assigned to them or when you need to spread unknown
|
|
68
|
+
props to your component. When you interact with a prop that is set as renderProp
|
|
69
|
+
it will automatically call the function and return the value that is returned.
|
|
70
|
+
Given that no default value is applied, this renderProp will not be called
|
|
71
|
+
with the `original` value assigned.
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
import { useProps } from '@bento/use-props';
|
|
75
|
+
import { withSlots } from '@bento/slots';
|
|
76
|
+
|
|
77
|
+
const Anchor = withSlots('Anchor', function AnchorComponent(args) {
|
|
78
|
+
const { props, apply } = useProps(args);
|
|
79
|
+
const { design, ...rest } = props;
|
|
80
|
+
|
|
81
|
+
const className = design === 'foo' ? 'foo' : 'bar';
|
|
82
|
+
return <a {...props} {...apply({ className })} />;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Illustrative purposes only, useCallback is required in a real application
|
|
86
|
+
<Anchor design={function renderProp({ original, state }) {
|
|
87
|
+
console.log(original); // undefined - Design prop was only used to lookup values
|
|
88
|
+
console.log(state); // {} - No state was specified in the useProps
|
|
89
|
+
|
|
90
|
+
return 'foo';
|
|
91
|
+
}} />
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### apply
|
|
95
|
+
|
|
96
|
+
The `apply` function is used to apply props to your component. It takes an
|
|
97
|
+
object of props and returns a new object with all the props applied, taking into
|
|
98
|
+
account any render props and slot overrides.
|
|
99
|
+
|
|
100
|
+
The function accepts an optional second parameter - an array of prop names that
|
|
101
|
+
should be omitted from being applied to the component. This is useful when you
|
|
102
|
+
want to prevent certain props from being passed down, such as props used only
|
|
103
|
+
for internal logic or props that shouldn't be spread onto the underlying
|
|
104
|
+
DOM element.
|
|
105
|
+
|
|
106
|
+
```javascript
|
|
107
|
+
// Apply all props
|
|
108
|
+
const appliedProps = apply({ className: 'my-class', onClick: handleClick });
|
|
109
|
+
|
|
110
|
+
// Apply props while omitting specific ones
|
|
111
|
+
const appliedProps = apply({ className: 'my-class', onClick: handleClick }, ['onClick']);
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The `apply` function ensures that all props are properly handled, including:
|
|
115
|
+
- Regular props
|
|
116
|
+
- Render props (functions that return prop values)
|
|
117
|
+
- Props that might be overridden by slots
|
|
118
|
+
- Props that need to be merged with existing values
|
|
119
|
+
|
|
120
|
+
This makes it the recommended way to apply any props to your components, as it
|
|
121
|
+
handles all the necessary prop management internally.
|
|
122
|
+
|
|
123
|
+
<Source language='tsx' code={ SourceBasic } />
|
|
124
|
+
|
|
125
|
+
<Source language='tsx' code={ SourceNestedSlots } />
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bento/use-props",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Context aware props transformation for Bento",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"dev": "tsup-node --watch",
|
|
11
11
|
"lint": "biome lint && tsc --noEmit",
|
|
12
12
|
"posttest": "npm run lint",
|
|
13
|
+
"prepublishOnly": "node ../../scripts/compile-readme.ts",
|
|
13
14
|
"pretest": "npm run build",
|
|
14
15
|
"test": "vitest --run",
|
|
15
16
|
"test:watch": "vitest"
|
|
@@ -40,8 +41,8 @@
|
|
|
40
41
|
"package.json"
|
|
41
42
|
],
|
|
42
43
|
"dependencies": {
|
|
43
|
-
"@bento/box": "^0.1.
|
|
44
|
-
"@bento/internal-props": "^0.1.
|
|
44
|
+
"@bento/box": "^0.1.1",
|
|
45
|
+
"@bento/internal-props": "^0.1.1",
|
|
45
46
|
"@bento/types": "^0.1.0"
|
|
46
47
|
},
|
|
47
48
|
"peerDependencies": {
|