53 lines
2.0 KiB
JavaScript
53 lines
2.0 KiB
JavaScript
import * as React from 'react';
|
|
import { defaultSSRContextValue, useSSRContext } from '../ssr/index';
|
|
const IdPrefixContext = React.createContext(undefined);
|
|
/**
|
|
* Allows to define a prefix that will be used for all IDs generated by useId() hook. It's useful to avoid collisions
|
|
* between different bundles.
|
|
*/ export const IdPrefixProvider = IdPrefixContext.Provider;
|
|
function useIdPrefix() {
|
|
return React.useContext(IdPrefixContext) || '';
|
|
}
|
|
/**
|
|
* Resets generated IDs, should be used only in tests.
|
|
*/ export function resetIdsForTests() {
|
|
defaultSSRContextValue.current = 0;
|
|
}
|
|
/**
|
|
* Hook to generate a unique ID.
|
|
*
|
|
* @param prefix - Optional prefix for the ID. Defaults to 'fui-'.
|
|
* @param providedId - Optional id provided by a parent component. Defaults to the provided value if present,
|
|
* without conditioning the hook call
|
|
* @returns The ID
|
|
*/ export function useId(prefix = 'fui-', providedId) {
|
|
'use no memo';
|
|
const contextValue = useSSRContext();
|
|
const idPrefix = useIdPrefix();
|
|
// Checking if useId is available on React, if it is, we use it to generate the id. String concatenation is used to
|
|
// prevent bundlers from complaining with older versions of React.
|
|
const _useId = React['use' + 'Id'];
|
|
if (_useId) {
|
|
const generatedId = _useId();
|
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
const escapedId = React.useMemo(()=>generatedId.replace(/:/g, ''), [
|
|
generatedId
|
|
]);
|
|
return providedId || `${idPrefix}${prefix}${escapedId}`;
|
|
}
|
|
// Hooks appear to be running conditionally, but they will always run in the same order since it's based on
|
|
// the version of React being used. This is safe to ignore.
|
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
return React.useMemo(()=>{
|
|
if (providedId) {
|
|
return providedId;
|
|
}
|
|
return `${idPrefix}${prefix}${++contextValue.current}`;
|
|
}, [
|
|
idPrefix,
|
|
prefix,
|
|
providedId,
|
|
contextValue
|
|
]);
|
|
}
|