react-polymorphic 1.0.0 → 1.0.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.
Files changed (2) hide show
  1. package/README.md +55 -55
  2. package/package.json +79 -82
package/README.md CHANGED
@@ -12,11 +12,11 @@ A single component factory function for polymorphic React components. Built for
12
12
  import { createPolymorph } from 'react-polymorphic';
13
13
 
14
14
  const Button = createPolymorph<'button'>(({ as: Tag = 'button', ...rest }) => {
15
- return <Tag {...rest} />
15
+ return <Tag {...rest} />
16
16
  })
17
17
 
18
18
  const App = () => {
19
- return <Button as="a" href="/">Home</Button>
19
+ return <Button as="a" href="/">Home</Button>
20
20
  }
21
21
  ```
22
22
 
@@ -70,7 +70,7 @@ Polymorphic components let you keep one consistent API while swapping the render
70
70
  `InferPolymorphElement`, `InferPolymorphProps`, and `InferPolymorphConfig` for advanced typing workflows.
71
71
 
72
72
  - **TypeScript 7 Ready**
73
- Compatible with TypeScript 5.4+ and optimized for TypeScript 7.
73
+ Compatible with TypeScript 5.4+ and optimized for TypeScript 7.
74
74
 
75
75
  - **Built for React 19+**
76
76
  Leverages React 19's handling of `ref`, eliminating `forwardRef` and convoluted type gymnastics.
@@ -96,23 +96,23 @@ Most polymorphic components are simple wrappers that combine custom props with i
96
96
  import { createPolymorph } from 'react-polymorphic';
97
97
 
98
98
  type Props = {
99
- variant: 'primary' | 'secondary';
99
+ variant: 'primary' | 'secondary';
100
100
  }
101
101
 
102
102
  const Pane = createPolymorph<'div', Props>((props) => {
103
- const { as: Tag = 'div', variant, className, ...rest } = props;
104
- const variantClasses = variant === 'primary' ? 'bg-white' : 'bg-blue-50';
103
+ const { as: Tag = 'div', variant, className, ...rest } = props;
104
+ const variantClasses = variant === 'primary' ? 'bg-white' : 'bg-blue-50';
105
105
 
106
- return <Tag className={`p-4 ${variantClasses} ${className}`} {...rest} />
106
+ return <Tag className={`p-4 ${variantClasses} ${className}`} {...rest} />
107
107
  })
108
108
 
109
109
  const App = () => {
110
- return (
111
- <>
112
- <Pane as="section" variant="primary" aria-label="...">...</Pane>
113
- <Pane as="aside" variant="secondary" aria-label="...">...</Pane>
114
- </>
115
- )
110
+ return (
111
+ <>
112
+ <Pane as="section" variant="primary" aria-label="...">...</Pane>
113
+ <Pane as="aside" variant="secondary" aria-label="...">...</Pane>
114
+ </>
115
+ )
116
116
  }
117
117
  ```
118
118
 
@@ -127,20 +127,20 @@ import { useRef } from 'react';
127
127
  import { createPolymorph } from 'react-polymorphic';
128
128
 
129
129
  const Component = createPolymorph<'div'>((props) => {
130
- const { as: Tag = 'div', ...rest } = props;
131
- return <Tag {...rest} />
130
+ const { as: Tag = 'div', ...rest } = props;
131
+ return <Tag {...rest} />
132
132
  })
133
133
 
134
134
  const App = () => {
135
- const ref = useRef<HTMLDivElement>(null);
136
- const aRef = useRef<HTMLAnchorElement>(null);
137
-
138
- return (
139
- <>
140
- <Component ref={ref} />
141
- <Component as="a" ref={aRef} />
142
- </>
143
- )
135
+ const ref = useRef<HTMLDivElement>(null);
136
+ const aRef = useRef<HTMLAnchorElement>(null);
137
+
138
+ return (
139
+ <>
140
+ <Component ref={ref} />
141
+ <Component as="a" ref={aRef} />
142
+ </>
143
+ )
144
144
  }
145
145
  ```
146
146
 
@@ -155,34 +155,34 @@ import { createPolymorph } from 'react-polymorphic';
155
155
  import type { PolymorphicConfig, Unset, Inherit } from 'react-polymorphic';
156
156
 
157
157
  type Props = {
158
- loading: boolean;
158
+ loading: boolean;
159
159
  }
160
160
 
161
161
  type Config = PolymorphicConfig<'button', {
162
- 'aria-loading': Unset;
163
- children: string;
164
- href: string;
165
- target?: '_blank';
166
- type: Inherit;
162
+ 'aria-loading': Unset;
163
+ children: string;
164
+ href: string;
165
+ target?: '_blank';
166
+ type: Inherit;
167
167
  }>;
168
168
 
169
169
  const Button = createPolymorph<'button', Props, Config>((props) => {
170
- const { as: Tag = 'button', children, loading, ...rest } = props;
170
+ const { as: Tag = 'button', children, loading, ...rest } = props;
171
171
 
172
- return (
173
- <Tag aria-loading={loading} {...rest}>
174
- {loading ? 'Loading...' : children}
175
- </Tag>
176
- )
172
+ return (
173
+ <Tag aria-loading={loading} {...rest}>
174
+ {loading ? 'Loading...' : children}
175
+ </Tag>
176
+ )
177
177
  })
178
178
 
179
179
  const App = () => {
180
- return (
181
- <>
182
- <Button type="button">Calculate</Button>
183
- <Button as="a" href="/">Back to home</Button>
184
- </>
185
- )
180
+ return (
181
+ <>
182
+ <Button type="button">Calculate</Button>
183
+ <Button as="a" href="/">Back to home</Button>
184
+ </>
185
+ )
186
186
  }
187
187
  ```
188
188
 
@@ -201,12 +201,12 @@ import { createPolymorph } from 'react-polymorphic';
201
201
  const OtherComponent = createPolymorph<'div'>(...);
202
202
 
203
203
  const Component = createPolymorph<'div'>((props) => {
204
- const { as: Tag = 'div', ...rest } = props;
205
- return <Tag {...rest} />
204
+ const { as: Tag = 'div', ...rest } = props;
205
+ return <Tag {...rest} />
206
206
  });
207
207
 
208
208
  const App = () => {
209
- return <Component as={OtherComponent} root="section" />
209
+ return <Component as={OtherComponent} root="section" />
210
210
  }
211
211
  ```
212
212
 
@@ -219,9 +219,9 @@ You can extract generics from existing polymorphic components and reuse them whe
219
219
  ```tsx
220
220
  import { createPolymorph } from 'react-polymorphic';
221
221
  import type {
222
- InferPolymorphElement,
223
- InferPolymorphProps,
224
- InferPolymorphConfig
222
+ InferPolymorphElement,
223
+ InferPolymorphProps,
224
+ InferPolymorphConfig
225
225
  } from 'react-polymorphic';
226
226
  import { TheirButton } from 'some-library';
227
227
 
@@ -237,8 +237,8 @@ type TheirConfig = InferPolymorphConfig<typeof TheirButton>;
237
237
  type Props = { ... }
238
238
 
239
239
  const OurButton = createPolymorph<typeof TheirButton, Props>((props) => {
240
- const { as: Tag = TheirButton, ...rest } = props;
241
- return <Tag {...rest} />
240
+ const { as: Tag = TheirButton, ...rest } = props;
241
+ return <Tag {...rest} />
242
242
  })
243
243
  ```
244
244
 
@@ -248,14 +248,14 @@ If swapping out the base would break core behavior, preserve the base and expose
248
248
 
249
249
  ```tsx
250
250
  const OurButton = createPolymorph<TheirElement, Props & TheirProps, TheirConfig>(
251
- (props) => {
252
- const { as = 'button', ...rest } = props;
253
- return <TheirButton as={as} {...rest} />
254
- }
251
+ (props) => {
252
+ const { as = 'button', ...rest } = props;
253
+ return <TheirButton as={as} {...rest} />
254
+ }
255
255
  )
256
256
 
257
257
  const App = () => {
258
- return <OurButton as="a" />
258
+ return <OurButton as="a" />
259
259
  }
260
260
  ```
261
261
 
package/package.json CHANGED
@@ -1,83 +1,80 @@
1
1
  {
2
- "name": "react-polymorphic",
3
- "version": "1.0.0",
4
- "description": "Create polymorphic React 19+ components with strong TypeScript inference.",
5
- "keywords": [
6
- "react",
7
- "typescript",
8
- "polymorphic",
9
- "component-library",
10
- "design-system",
11
- "as-prop",
12
- "headless-ui",
13
- "ui"
14
- ],
15
- "author": "Dashice",
16
- "license": "Apache-2.0",
17
- "repository": {
18
- "type": "git",
19
- "url": "git+https://github.com/Dashice/react-polymorphic.git"
20
- },
21
- "homepage": "https://github.com/Dashice/react-polymorphic#readme",
22
- "bugs": {
23
- "url": "https://github.com/Dashice/react-polymorphic/issues"
24
- },
25
- "type": "module",
26
- "types": "dist/index.d.ts",
27
- "files": [
28
- "dist",
29
- "README.md",
30
- "LICENSE",
31
- "NOTICE"
32
- ],
33
- "exports": {
34
- ".": {
35
- "types": "./dist/index.d.ts",
36
- "import": "./dist/index.js"
37
- }
38
- },
39
- "packageManager": "pnpm@10.20.0",
40
- "engines": {
41
- "node": ">=22.0.0"
42
- },
43
- "scripts": {
44
- "clean": "rm -rf dist",
45
- "build": "pnpm clean && tsup && tsc -p tsconfig.build.json",
46
- "prepack": "pnpm build",
47
- "format": "biome format . --write",
48
- "format:check": "biome format .",
49
- "lint": "biome lint .",
50
- "lint:fix": "biome lint . --write",
51
- "check": "biome check . --write",
52
- "test": "vitest",
53
- "test:run": "vitest run",
54
- "typecheck": "tsc -p tsconfig.json",
55
- "lint:staged": "lint-staged",
56
- "changeset": "changeset",
57
- "version:packages": "changeset version",
58
- "release": "changeset publish",
59
- "prepare": "husky"
60
- },
61
- "dependencies": {},
62
- "devDependencies": {
63
- "@biomejs/biome": "^2.4.16",
64
- "@changesets/cli": "^2.31.1",
65
- "@testing-library/dom": "^10.4.1",
66
- "@testing-library/react": "^16.3.2",
67
- "@types/node": "^24.0.0",
68
- "@types/react": "^19.2.15",
69
- "happy-dom": "^20.9.0",
70
- "husky": "^9.1.7",
71
- "lint-staged": "^17.2.0",
72
- "react": "^19.2.7",
73
- "react-dom": "^19.2.7",
74
- "tsup": "^8.5.1",
75
- "typescript": "^7.0.2",
76
- "vitest": "^2.1.9"
77
- },
78
- "peerDependencies": {
79
- "react": ">=19.0.0",
80
- "react-dom": ">=19.0.0",
81
- "typescript": ">=5.4.0"
82
- }
83
- }
2
+ "name": "react-polymorphic",
3
+ "version": "1.0.1",
4
+ "description": "Create polymorphic React 19+ components with strong TypeScript inference.",
5
+ "keywords": [
6
+ "react",
7
+ "typescript",
8
+ "polymorphic",
9
+ "component-library",
10
+ "design-system",
11
+ "as-prop",
12
+ "headless-ui",
13
+ "ui"
14
+ ],
15
+ "author": "Dashice",
16
+ "license": "Apache-2.0",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/Dashice/react-polymorphic.git"
20
+ },
21
+ "homepage": "https://github.com/Dashice/react-polymorphic#readme",
22
+ "bugs": {
23
+ "url": "https://github.com/Dashice/react-polymorphic/issues"
24
+ },
25
+ "type": "module",
26
+ "types": "dist/index.d.ts",
27
+ "files": [
28
+ "dist",
29
+ "README.md",
30
+ "LICENSE",
31
+ "NOTICE"
32
+ ],
33
+ "exports": {
34
+ ".": {
35
+ "types": "./dist/index.d.ts",
36
+ "import": "./dist/index.js"
37
+ }
38
+ },
39
+ "engines": {
40
+ "node": ">=22.0.0"
41
+ },
42
+ "devDependencies": {
43
+ "@biomejs/biome": "^2.5.6",
44
+ "@changesets/cli": "^2.31.1",
45
+ "@testing-library/dom": "^10.4.1",
46
+ "@testing-library/react": "^16.3.2",
47
+ "@types/node": "^24.0.0",
48
+ "@types/react": "^19.2.18",
49
+ "happy-dom": "^20.11.1",
50
+ "husky": "^9.1.7",
51
+ "lint-staged": "^17.3.0",
52
+ "react": "^19.2.8",
53
+ "react-dom": "^19.2.8",
54
+ "tsup": "^8.5.1",
55
+ "typescript": "^7.0.2",
56
+ "vite": "^8.2.0",
57
+ "vitest": "^4.1.10"
58
+ },
59
+ "peerDependencies": {
60
+ "react": ">=19.0.0",
61
+ "react-dom": ">=19.0.0",
62
+ "typescript": ">=5.4.0"
63
+ },
64
+ "scripts": {
65
+ "clean": "rm -rf dist",
66
+ "build": "pnpm clean && tsup && tsc -p tsconfig.build.json",
67
+ "format": "biome format . --write",
68
+ "format:check": "biome format .",
69
+ "lint": "biome lint .",
70
+ "lint:fix": "biome lint . --write",
71
+ "check": "biome check . --write",
72
+ "test": "vitest",
73
+ "test:run": "vitest run",
74
+ "typecheck": "tsc -p tsconfig.json",
75
+ "lint:staged": "lint-staged",
76
+ "changeset": "changeset",
77
+ "version:packages": "changeset version",
78
+ "release": "changeset publish"
79
+ }
80
+ }