diff --git a/src/hooks/useId.ts b/src/hooks/useId.ts index 1b6a0e6d..d58a9588 100644 --- a/src/hooks/useId.ts +++ b/src/hooks/useId.ts @@ -25,10 +25,13 @@ export function resetUuid() { * @param key - The key from React element, may contain spaces or invalid characters * @returns A valid HTML id string */ -export function getId(prefix: string, key: string): string { +export function getId(prefix: string, key: React.Key): string { + // React.Key can be string | number, convert to string first + const keyStr = String(key); + // Valid id characters: letters, digits, hyphen, underscore, colon, period // Replace all invalid characters (including spaces) with hyphens to preserve length - const sanitizedKey = key.replace(/[^a-zA-Z0-9_.:-]/g, '-'); + const sanitizedKey = keyStr.replace(/[^a-zA-Z0-9_.:-]/g, '-'); return `${prefix}-${sanitizedKey}`; } diff --git a/tests/hooks.test.tsx b/tests/hooks.test.tsx index 86125daa..f8004eb5 100644 --- a/tests/hooks.test.tsx +++ b/tests/hooks.test.tsx @@ -675,6 +675,9 @@ describe('hooks', () => { expect(getId('btn', 'valid-key_123:456.789')).toBe( 'btn-valid-key_123:456.789', ); + expect(getId('item', 1)).toBe('item-1'); + expect(getId('tab', 123)).toBe('tab-123'); + expect(getId('panel', 0)).toBe('panel-0'); }); });