diff --git a/.claude/rules/emcn-components.md b/.claude/rules/emcn-components.md index 8c8b468d246..0342cadb8cb 100644 --- a/.claude/rules/emcn-components.md +++ b/.claude/rules/emcn-components.md @@ -24,10 +24,10 @@ The menu surface intentionally diverges from the pill: `dropdown-menu.tsx` items - **`Chip` / `ChipLink`** — the pill button (`} + orientation={orientation} + value='Review' + onChange={() => {}} + required + error='Enter a valid name' + hint='Hidden while invalid' + /> + ) + const input = container!.querySelector('input')! + expect(input.labels?.[0].textContent).toBe('Name*') + expect(input.getAttribute('aria-required')).toBe('true') + expect(input.getAttribute('aria-invalid')).toBe('true') + const error = document.getElementById(input.getAttribute('aria-describedby')!)! + expect(error.textContent).toBe('Enter a valid name') + expect(error.getAttribute('role')).toBe('alert') + expect(container!.textContent).not.toContain('Hidden while invalid') + expect(input.labels?.[0].contains(buttonByText('Help'))).toBe(false) + act(() => input.focus()) + expect(document.activeElement).toBe(input) + } + ) + + it('forwards monospace and height settings to a labeled textarea', () => { + mount( + {}} + mono + minHeight={120} + rows={4} + hint='Enter JSON' + /> + ) + const textarea = container!.querySelector('textarea')! + expect(textarea.labels?.[0].textContent).toBe('JSON') + expect(textarea.className).toContain('font-mono') + expect(textarea.style.minHeight).toBe('120px') + expect(textarea.rows).toBe(4) + expect(document.getElementById(textarea.getAttribute('aria-describedby')!)?.textContent).toBe( + 'Enter JSON' + ) + }) +}) + describe('ChipModalField file actions', () => { it('names each upload action with its field title', () => { mount( @@ -501,7 +556,13 @@ describe('ChipModal default actions', () => { {}} srTitle='Visible action'> {}}>Visible action - {}} /> + {}} + />