Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Twilio-labs/paste/llms.txt
Use this file to discover all available pages before exploring further.
The UID Library provides React hooks for generating unique identifiers. These IDs are essential for creating accessible forms and UI components that properly associate labels with inputs, ARIA attributes with elements, and more.
Installation
Install the package along with React:
yarn add @twilio-paste/uid-library
Or using npm:
npm install @twilio-paste/uid-library
Why Use UIDs?
Unique IDs are crucial for web accessibility:
- Form accessibility: Associate labels with inputs using
htmlFor and id
- ARIA relationships: Link elements with
aria-labelledby, aria-describedby, etc.
- Avoid conflicts: Prevent ID collisions when components are reused
- Server-side rendering: Generate consistent IDs across server and client
- Stable IDs: IDs remain consistent across re-renders
API Reference
useUID
Generates a single unique ID.
const id = useUID(): string
Returns: A unique string ID that’s stable across re-renders
Example:
import { useUID } from '@twilio-paste/uid-library';
const MyInput = () => {
const id = useUID();
return (
<div>
<label htmlFor={id}>Email</label>
<input id={id} type="email" />
</div>
);
};
useUIDSeed
Generates a seed function that creates multiple related IDs with a common prefix.
const seed = useUIDSeed(): (suffix: string) => string
Returns: A function that takes a suffix and returns a unique ID
Example:
import { useUIDSeed } from '@twilio-paste/uid-library';
const MyForm = () => {
const seed = useUIDSeed();
return (
<form>
<div>
<label htmlFor={seed('email')}>Email</label>
<input id={seed('email')} type="email" />
<span id={seed('email-help')}>We'll never share your email</span>
</div>
<div>
<label htmlFor={seed('password')}>Password</label>
<input
id={seed('password')}
type="password"
aria-describedby={seed('password-help')}
/>
<span id={seed('password-help')}>At least 8 characters</span>
</div>
</form>
);
};
UIDFork
Creates a boundary for generating UIDs in isolated component trees.
<UIDFork>
{children}
</UIDFork>
Useful for:
- Portals and modals
- Isolated component trees
- Testing scenarios
Example:
import { UIDFork, useUID } from '@twilio-paste/uid-library';
import { createPortal } from 'react-dom';
const Modal = ({ children }) => {
return createPortal(
<UIDFork>
{children}
</UIDFork>,
document.body
);
};
uid
A utility function for generating unique IDs outside of React components.
const id = uid(item: any): string
Parameters:
item - Any value to generate a UID for
Returns: A unique string ID
Note: Use hooks (useUID or useUIDSeed) inside React components instead.
Common Patterns
Form Inputs with Labels
Associate labels with inputs for accessibility:
import { useUID } from '@twilio-paste/uid-library';
import { Label } from '@twilio-paste/core/label';
import { Input } from '@twilio-paste/core/input';
const FormField = ({ label, ...props }) => {
const id = useUID();
return (
<>
<Label htmlFor={id}>{label}</Label>
<Input id={id} {...props} />
</>
);
};
// Usage
<FormField label="Username" type="text" />
Help Text with ARIA
Associate help text with form fields:
import { useUIDSeed } from '@twilio-paste/uid-library';
import { Label } from '@twilio-paste/core/label';
import { Input } from '@twilio-paste/core/input';
import { HelpText } from '@twilio-paste/core/help-text';
const FormFieldWithHelp = ({ label, helpText, ...props }) => {
const seed = useUIDSeed();
return (
<>
<Label htmlFor={seed('input')}>{label}</Label>
<Input
id={seed('input')}
aria-describedby={seed('help')}
{...props}
/>
<HelpText id={seed('help')}>{helpText}</HelpText>
</>
);
};
// Usage
<FormFieldWithHelp
label="Password"
helpText="Must be at least 8 characters"
type="password"
/>
Error Messages
Associate error messages with form fields:
import { useUIDSeed } from '@twilio-paste/uid-library';
import { Label } from '@twilio-paste/core/label';
import { Input } from '@twilio-paste/core/input';
import { HelpText } from '@twilio-paste/core/help-text';
const FormFieldWithError = ({ label, error, ...props }) => {
const seed = useUIDSeed();
const hasError = Boolean(error);
return (
<>
<Label htmlFor={seed('input')}>{label}</Label>
<Input
id={seed('input')}
aria-describedby={hasError ? seed('error') : undefined}
aria-invalid={hasError}
{...props}
/>
{hasError && (
<HelpText id={seed('error')} variant="error">
{error}
</HelpText>
)}
</>
);
};
// Usage
<FormFieldWithError
label="Email"
error="Please enter a valid email address"
type="email"
/>
Lists with ARIA Labels
Label lists with headings:
import { useUIDSeed } from '@twilio-paste/uid-library';
const LabeledList = ({ title, items }) => {
const seed = useUIDSeed();
return (
<div>
<h3 id={seed('title')}>{title}</h3>
<ul aria-labelledby={seed('title')}>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
);
};
Tabs with ARIA
Create accessible tab interfaces:
import { useUIDSeed } from '@twilio-paste/uid-library';
import { useState } from 'react';
const Tabs = ({ tabs }) => {
const [activeTab, setActiveTab] = useState(0);
const seed = useUIDSeed();
return (
<div>
<div role="tablist">
{tabs.map((tab, index) => (
<button
key={index}
role="tab"
id={seed(`tab-${index}`)}
aria-selected={activeTab === index}
aria-controls={seed(`panel-${index}`)}
onClick={() => setActiveTab(index)}
>
{tab.label}
</button>
))}
</div>
{tabs.map((tab, index) => (
<div
key={index}
role="tabpanel"
id={seed(`panel-${index}`)}
aria-labelledby={seed(`tab-${index}`)}
hidden={activeTab !== index}
>
{tab.content}
</div>
))}
</div>
);
};
Modal Dialogs
Create accessible modals:
import { useUIDSeed, UIDFork } from '@twilio-paste/uid-library';
import { createPortal } from 'react-dom';
const Modal = ({ title, children, onClose }) => {
const seed = useUIDSeed();
return createPortal(
<UIDFork>
<div
role="dialog"
aria-labelledby={seed('title')}
aria-modal="true"
>
<h2 id={seed('title')}>{title}</h2>
<div>{children}</div>
<button onClick={onClose}>Close</button>
</div>
</UIDFork>,
document.body
);
};
Combobox/Autocomplete
Create accessible combobox components:
import { useUIDSeed } from '@twilio-paste/uid-library';
import { useState } from 'react';
const Combobox = ({ label, options }) => {
const [isOpen, setIsOpen] = useState(false);
const seed = useUIDSeed();
return (
<div>
<label id={seed('label')} htmlFor={seed('input')}>
{label}
</label>
<input
id={seed('input')}
role="combobox"
aria-expanded={isOpen}
aria-controls={seed('listbox')}
aria-labelledby={seed('label')}
onFocus={() => setIsOpen(true)}
/>
{isOpen && (
<ul
id={seed('listbox')}
role="listbox"
aria-labelledby={seed('label')}
>
{options.map((option, index) => (
<li
key={index}
id={seed(`option-${index}`)}
role="option"
>
{option}
</li>
))}
</ul>
)}
</div>
);
};
React 18+ Support
The UID Library automatically uses React’s built-in useId hook when available (React 18+), providing:
- Better server-side rendering support
- Improved hydration handling
- Native React performance optimizations
For React 17 and below, it falls back to the react-uid library.
No code changes are needed - the library handles this automatically.
TypeScript Support
The library is fully typed:
import { useUID, useUIDSeed } from '@twilio-paste/uid-library';
const MyComponent: React.FC = () => {
const id: string = useUID();
const seed: (suffix: string) => string = useUIDSeed();
return (
<input id={id} aria-describedby={seed('help')} />
);
};
Best Practices
- Use
useUID for single IDs in a component
- Use
useUIDSeed when you need multiple related IDs
- Always associate labels with form inputs
- Use ARIA attributes to create relationships between elements
- Use
UIDFork for portals and isolated trees
Don’t
- Don’t hardcode IDs in reusable components
- Don’t generate IDs outside of hooks in React components
- Don’t create new hooks on every render (hooks should be at the top level)
- Don’t use generic IDs like “input-1” that might conflict
Performance Considerations
Memoization
UIDs are stable across re-renders, so you don’t need to memoize them:
// ✅ Good - ID is stable
const MyComponent = () => {
const id = useUID();
return <input id={id} />;
};
// ❌ Unnecessary - ID is already stable
const MyComponent = () => {
const id = useMemo(() => useUID(), []); // Don't do this
return <input id={id} />;
};
Multiple Components
Each component instance gets unique IDs automatically:
const FormField = () => {
const id = useUID();
return <input id={id} />;
};
// Each FormField gets a unique ID
<>
<FormField /> {/* id: "uid-1" */}
<FormField /> {/* id: "uid-2" */}
<FormField /> {/* id: "uid-3" */}
</>
Version
Current version: 3.0.1
Dependencies
react-uid (2.3.3) - Fallback for React versions below 18
Related Resources