diff --git a/src/internal/index.ts b/src/internal/index.ts index 7aab1e2..a1da11f 100644 --- a/src/internal/index.ts +++ b/src/internal/index.ts @@ -38,3 +38,4 @@ export { default as handleKey } from './utils/handle-key'; export { default as circleIndex } from './utils/circle-index'; export { default as Portal, PortalProps } from './portal'; export { useMergeRefs } from './use-merge-refs'; +export { useRandomId, useUniqueId } from './use-unique-id'; diff --git a/src/internal/use-unique-id/__tests__/use-unique-id.test.tsx b/src/internal/use-unique-id/__tests__/use-unique-id.test.tsx new file mode 100644 index 0000000..f48ec24 --- /dev/null +++ b/src/internal/use-unique-id/__tests__/use-unique-id.test.tsx @@ -0,0 +1,37 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import React from 'react'; +import { render } from '@testing-library/react'; + +import { useUniqueId, useRandomId } from '../index'; + +function DemoRandomIdComponent() { + const id = useRandomId(); + return
{id}
; +} + +function DemoUniqueIdComponent({ prefix }: { prefix: string }) { + const id = useUniqueId(prefix); + return
{id}
; +} + +it('generates random ID per component', () => { + const component1 = render(); + const textContent1 = component1.container.textContent; + + const component2 = render(); + const textContent2 = component2.container.textContent; + + expect(textContent1).not.toBe(''); + expect(textContent1).not.toBe(textContent2); + + component1.rerender(); + expect(component1.container.textContent).toBe(textContent1); +}); + +it('creates unique ID with given prefix', () => { + const component = render(); + + expect(component.container.textContent).toContain('prefix-'); +}); diff --git a/src/internal/use-unique-id/index.ts b/src/internal/use-unique-id/index.ts new file mode 100644 index 0000000..75146f3 --- /dev/null +++ b/src/internal/use-unique-id/index.ts @@ -0,0 +1,19 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import React, { useRef } from 'react'; + +let counter = 0; +export const useRandomId = () => { + const idRef = useRef(null); + if (!idRef.current) { + idRef.current = `${counter++}-${Date.now()}-${Math.round(Math.random() * 10000)}`; + } + return idRef.current; +}; + +const useId: typeof useRandomId = (React as any).useId ?? useRandomId; + +export function useUniqueId(prefix?: string) { + return `${prefix ? prefix : ''}` + useId(); +}