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
38 changes: 38 additions & 0 deletions packages/emcn/src/components/chip-input/chip-input.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* @vitest-environment jsdom
*/
import { act } from 'react'
import { createRoot, type Root } from 'react-dom/client'
import { afterEach, describe, expect, it } from 'vitest'
import { ChipInput } from './chip-input'

let root: Root | null = null
let container: HTMLDivElement | null = null

function mount(): HTMLInputElement {
;(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true
container = document.createElement('div')
document.body.appendChild(container)
root = createRoot(container)
act(() => root?.render(<ChipInput aria-label='Search' />))

const input = container.querySelector<HTMLInputElement>('input')
if (!input) throw new Error('ChipInput did not render an input')
return input
}

afterEach(() => {
if (root) act(() => root?.unmount())
container?.remove()
root = null
container = null
})

describe('ChipInput', () => {
it('reserves paintable clearance for a leading glyph without shifting its alignment', () => {
const input = mount()

expect(input.className).toContain('-ml-1')
expect(input.className).toContain('indent-1')
})
})
11 changes: 6 additions & 5 deletions packages/emcn/src/components/chip-input/chip-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
*
* The chrome lives on the wrapper so a leading `icon` and a trailing
* `endAdornment` (reveal / copy buttons) sit flush next to a transparent inner
* `<input>`. The leading icon uses the same 1.5 gap as `Chip`. It shares the
* chip-field chrome with {@link ChipTextarea}, shows no focus ring — keep the
* surface calm and rely on the caret for focus. Pass `error` to swap the border
* to the error token.
* `<input>`. Matching negative margin and text indent give leading glyphs paint
* clearance without moving their visual alignment. The leading icon uses the
* same 1.5 gap as `Chip`. It shares the chip-field chrome with
* {@link ChipTextarea}, shows no focus ring — keep the surface calm and rely on
* the caret for focus. Pass `error` to swap the border to the error token.
*
* @example
* ```tsx
Expand Down Expand Up @@ -77,7 +78,7 @@ export const ChipInput = React.forwardRef<HTMLInputElement, ChipInputProps>(
type={type}
disabled={disabled}
className={cn(
'h-full w-full bg-transparent disabled:cursor-not-allowed',
'-ml-1 h-full w-full bg-transparent indent-1 disabled:cursor-not-allowed',
chipFieldTextClass,
inputClassName
)}
Expand Down
Loading