Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/hooks/useId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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, '-');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current regex allows . and : characters in the generated ID. While valid in HTML IDs, these characters have special meaning in CSS selectors and can cause bugs (e.g., #my.id selects an element with id="my" and class="id").

To create safer IDs that are easier to use with tools like querySelector, I suggest replacing these special characters as well.

Note: This is a potentially breaking change and would require updating tests that expect . and : to be preserved (like on line 675 of tests/hooks.test.tsx). You would also need to update the comment on line 32 to reflect this change.

Suggested change
const sanitizedKey = keyStr.replace(/[^a-zA-Z0-9_.:-]/g, '-');
const sanitizedKey = keyStr.replace(/[^a-zA-Z0-9_-]/g, '-');


return `${prefix}-${sanitizedKey}`;
}
Expand Down
3 changes: 3 additions & 0 deletions tests/hooks.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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');
});
});

Expand Down
Loading