useid-polyfill 1.0.3 → 1.1.0
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 +75 -1
- package/dist/auto.d.mts +2 -0
- package/dist/auto.d.ts +2 -0
- package/dist/auto.js +1 -0
- package/dist/auto.mjs +1 -0
- package/dist/chunk-5VLUJQZZ.mjs +1 -0
- package/dist/index.d.mts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +13 -1
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@ A React `useId` polyfill for React 16 and 17, with SSR support.
|
|
|
4
4
|
|
|
5
5
|
React 18 introduced `useId()` for generating unique, stable IDs — critical for accessibility (ARIA attributes, label associations). This package detects React 18+ and delegates to the native `useId`. On React 16/17, it provides a fallback that avoids hydration mismatches.
|
|
6
6
|
|
|
7
|
+
Need to support a third-party library that uses `useId` on React 16/17? See [Polyfilling Third-Party Libraries](#polyfilling-third-party-libraries).
|
|
8
|
+
|
|
7
9
|
## Installation
|
|
8
10
|
|
|
9
11
|
```bash
|
|
@@ -29,10 +31,15 @@ function FormField({ label }: { label: string }) {
|
|
|
29
31
|
|
|
30
32
|
## API
|
|
31
33
|
|
|
32
|
-
### `useId()
|
|
34
|
+
### `useId()`
|
|
33
35
|
|
|
34
36
|
Returns a unique, stable ID string. On React 18+, delegates to the native `React.useId()`.
|
|
35
37
|
|
|
38
|
+
TypeScript return type is conditional on your installed React typings:
|
|
39
|
+
|
|
40
|
+
- React 18+ typings: `string`
|
|
41
|
+
- React 16/17 typings: `string | undefined`
|
|
42
|
+
|
|
36
43
|
On React 16/17 during SSR, returns `undefined` on the initial server render and hydration pass, then resolves to a string ID after a layout effect. This avoids hydration mismatches.
|
|
37
44
|
|
|
38
45
|
## SSR Caveats
|
|
@@ -50,6 +57,73 @@ const id = useId();
|
|
|
50
57
|
return <input id={id ?? undefined} aria-describedby={id ? `${id}-help` : undefined} />;
|
|
51
58
|
```
|
|
52
59
|
|
|
60
|
+
## Polyfilling Third-Party Libraries
|
|
61
|
+
|
|
62
|
+
If you use React 16 or 17 and install a third-party library (e.g., MUI, Radix UI) that internally calls `React.useId`, it will crash because `React.useId` does not exist before React 18.
|
|
63
|
+
|
|
64
|
+
### Option 1: Auto-patching (recommended)
|
|
65
|
+
|
|
66
|
+
Import `useid-polyfill/auto` **once** at the very top of your app entry point, **before any other imports**:
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
// src/index.js — must be the first import
|
|
70
|
+
import 'useid-polyfill/auto';
|
|
71
|
+
|
|
72
|
+
import React from 'react';
|
|
73
|
+
import ReactDOM from 'react-dom';
|
|
74
|
+
import App from './App';
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
This patches `React.useId` globally so any library importing `useId` from `react` will get the polyfill. On React 18+, this is a no-op.
|
|
78
|
+
|
|
79
|
+
> **SSR note:** On React 16/17, the patched `useId` returns `undefined` during server rendering and hydration (same as the direct polyfill — see [SSR Caveats](#ssr-caveats)). Most libraries handle this gracefully, but if a third-party component breaks during hydration, this is likely why.
|
|
80
|
+
|
|
81
|
+
### Option 2: Bundler alias
|
|
82
|
+
|
|
83
|
+
If runtime patching does not work in your environment, you can configure your bundler to shim React.
|
|
84
|
+
|
|
85
|
+
Create a file `react-shim.js` at your project root:
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
const React = require('react');
|
|
89
|
+
if (!React.useId) {
|
|
90
|
+
const { useId } = require('useid-polyfill');
|
|
91
|
+
React.useId = useId;
|
|
92
|
+
}
|
|
93
|
+
module.exports = React;
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Webpack** — in `webpack.config.js`:
|
|
97
|
+
|
|
98
|
+
```js
|
|
99
|
+
module.exports = {
|
|
100
|
+
resolve: {
|
|
101
|
+
alias: {
|
|
102
|
+
react: require.resolve('./react-shim.js'),
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Vite** — in `vite.config.ts`:
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
import { defineConfig } from 'vite';
|
|
112
|
+
import path from 'path';
|
|
113
|
+
|
|
114
|
+
export default defineConfig({
|
|
115
|
+
resolve: {
|
|
116
|
+
alias: {
|
|
117
|
+
react: path.resolve(__dirname, './react-shim.js'),
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Option 3: patch-package
|
|
124
|
+
|
|
125
|
+
As a last resort, you can use [patch-package](https://www.npmjs.com/package/patch-package) to modify the offending library's source to import from `useid-polyfill` instead of `react`.
|
|
126
|
+
|
|
53
127
|
## How It Works
|
|
54
128
|
|
|
55
129
|
1. **React 18+ detection**: If `React.useId` exists, it is used directly
|
package/dist/auto.d.mts
ADDED
package/dist/auto.d.ts
ADDED
package/dist/auto.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var l=Object.create;var u=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var I=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var y=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of m(t))!g.call(e,s)&&s!==o&&u(e,s,{get:()=>t[s],enumerable:!(r=p(t,s))||r.enumerable});return e};var d=(e,t,o)=>(o=e!=null?l(I(e)):{},y(t||!e||!e.__esModule?u(o,"default",{value:e,enumerable:!0}):o,e));var C=d(require("react"));var R=d(require("react")),n=require("react"),b={...R},h=0,w=Math.random().toString(36).slice(2,6),a=()=>`uid-${w}${h++}`,v=typeof window!="undefined"?n.useLayoutEffect:n.useEffect,i=!1;function x(){let[e,t]=(0,n.useState)(()=>i?a():void 0);return v(()=>{e===void 0&&t(a())},[]),(0,n.useEffect)(()=>{i||(i=!0)},[]),e}var f=b.useId||x;var c=C;if(typeof c.useId!="function")try{Object.defineProperty(c,"useId",{value:f,writable:!0,configurable:!0,enumerable:!0})}catch(e){typeof console!="undefined"&&console.warn&&console.warn("[useid-polyfill/auto] Could not patch React.useId. Your environment may not support runtime patching. Consider using a bundler alias instead. See: https://github.com/dermyhughes/useid-polyfill#option-2-bundler-alias")}
|
package/dist/auto.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e}from"./chunk-5VLUJQZZ.mjs";import*as t from"react";var o=t;if(typeof o.useId!="function")try{Object.defineProperty(o,"useId",{value:e,writable:!0,configurable:!0,enumerable:!0})}catch(n){typeof console!="undefined"&&console.warn&&console.warn("[useid-polyfill/auto] Could not patch React.useId. Your environment may not support runtime patching. Consider using a bundler alias instead. See: https://github.com/dermyhughes/useid-polyfill#option-2-bundler-alias")}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import*as o from"react";import{useState as f,useEffect as s,useLayoutEffect as i}from"react";var r={...o},u=0,c=Math.random().toString(36).slice(2,6),n=()=>`uid-${c}${u++}`,a=typeof window!="undefined"?i:s,e=!1;function p(){let[t,d]=f(()=>e?n():void 0);return a(()=>{t===void 0&&d(n())},[]),s(()=>{e||(e=!0)},[]),t}var g=r.useId||p;export{g as a};
|
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var a=Object.create;var
|
|
1
|
+
"use strict";var a=Object.create;var o=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty;var l=(e,t)=>{for(var n in t)o(e,n,{get:t[n],enumerable:!0})},i=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let d of I(t))!m.call(e,d)&&d!==n&&o(e,d,{get:()=>t[d],enumerable:!(r=p(t,d))||r.enumerable});return e};var y=(e,t,n)=>(n=e!=null?a(g(e)):{},i(t||!e||!e.__esModule?o(n,"default",{value:e,enumerable:!0}):n,e)),R=e=>i(o({},"__esModule",{value:!0}),e);var L={};l(L,{useId:()=>c});module.exports=R(L);var x=y(require("react")),s=require("react"),E={...x},U=0,h=Math.random().toString(36).slice(2,6),u=()=>`uid-${h}${U++}`,v=typeof window!="undefined"?s.useLayoutEffect:s.useEffect,f=!1;function w(){let[e,t]=(0,s.useState)(()=>f?u():void 0);return v(()=>{e===void 0&&t(u())},[]),(0,s.useEffect)(()=>{f||(f=!0)},[]),e}var c=E.useId||w;0&&(module.exports={useId});
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import{a as e}from"./chunk-5VLUJQZZ.mjs";export{e as useId};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "useid-polyfill",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "React useId polyfill for React 16/17 with SSR support",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Dermot Hughes",
|
|
@@ -15,6 +15,18 @@
|
|
|
15
15
|
"types": "./dist/index.d.ts",
|
|
16
16
|
"import": "./dist/index.mjs",
|
|
17
17
|
"require": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./auto": {
|
|
20
|
+
"types": "./dist/auto.d.ts",
|
|
21
|
+
"import": "./dist/auto.mjs",
|
|
22
|
+
"require": "./dist/auto.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"typesVersions": {
|
|
26
|
+
"*": {
|
|
27
|
+
"auto": [
|
|
28
|
+
"./dist/auto.d.ts"
|
|
29
|
+
]
|
|
18
30
|
}
|
|
19
31
|
},
|
|
20
32
|
"files": [
|