UNPKG

@carbon/react

Version:

React components for the Carbon Design System

84 lines (75 loc) 2.57 kB
/** * Copyright IBM Corp. 2016, 2023 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ import React, { useState, useEffect, useLayoutEffect } from 'react'; import { setupGetInstanceId } from '../tools/setupGetInstanceId.js'; import { canUseDOM } from './environment.js'; import { useIdPrefix } from './useIdPrefix.js'; // This file was heavily inspired by: // This tricks bundlers so they can't statically analyze this and produce // compilation warnings/errors. // https://github.com/webpack/webpack/issues/14814 // https://github.com/mui/material-ui/issues/41190 const _React = { ...React }; const instanceId = setupGetInstanceId(); const useIsomorphicLayoutEffect = canUseDOM ? useLayoutEffect : useEffect; let serverHandoffCompleted = false; const defaultId = 'id'; /** * Generate a unique ID for React <=17 with an optional prefix prepended to it. * This is an internal utility, not intended for public usage. * @param {string} [prefix] * @returns {string} */ function useCompatibleId(prefix = defaultId) { const contextPrefix = useIdPrefix(); const [id, setId] = useState(() => { if (serverHandoffCompleted) { return `${contextPrefix ? `${contextPrefix}-` : ``}${prefix}-${instanceId()}`; } return null; }); useIsomorphicLayoutEffect(() => { if (id === null) { setId(`${contextPrefix ? `${contextPrefix}-` : ``}${prefix}-${instanceId()}`); } }, [instanceId]); useEffect(() => { if (serverHandoffCompleted === false) { serverHandoffCompleted = true; } }, []); return id; } /** * Generate a unique ID for React >=18 with an optional prefix prepended to it. * This is an internal utility, not intended for public usage. * @param {string} [prefix] * @returns {string} */ function useReactId(prefix = defaultId) { const contextPrefix = useIdPrefix(); return `${contextPrefix ? `${contextPrefix}-` : ``}${prefix}-${_React.useId()}`; } /** * Uses React 18's built-in `useId()` when available, or falls back to a * slightly less performant (requiring a double render) implementation for * earlier React versions. */ const useId = _React.useId ? useReactId : useCompatibleId; /** * Generate a unique id if a given `id` is not provided * This is an internal utility, not intended for public usage. * @param {string|undefined} id * @returns {string} */ function useFallbackId(id) { const fallback = useId(); return id ?? fallback; } export { useCompatibleId, useFallbackId, useId };