Skip to content

Latest commit

 

History

History
57 lines (48 loc) · 3.19 KB

File metadata and controls

57 lines (48 loc) · 3.19 KB
@astryxdesign/core patch

[feat] Tokenizer fits the pointer: a scrolling chip row and a suggestion sheet on a finger, the inline field on a mouse

Tokenizer has always been a control for a mouse. You type between the chips, in an input that shares a line with them, and you remove the last one with Backspace on an empty input. Both of those need a hardware keyboard. On a phone, focusing that input raises the virtual keyboard over the bottom half of the screen — which is where the suggestion popover opens — and every chip added grows the field by a line and pushes the page under your thumb.

The same component now renders a second surface where the primary pointer is a finger (pointer: coarse): the chips sit on one sideways-scrolling line, so the field is exactly one line tall however many there are and nothing below it moves; an Add button at the trailing edge, outside the scroller so it is in the same place with two chips or twenty, opens a pinned-tall sheet; and the sheet puts its search field at the top where the keyboard cannot cover it, over full-width rows a thumb can hit. Tapping a row adds that token and leaves the sheet up for the next one, so building a set of five is five taps. The list is populated before anything is typed — in a sheet the list is the content, and a search box over an empty pane is a dead end.

Nothing changes at the call site. It is one component with two surfaces, not two components — same props, same values, no new import, no media query to write. With a mouse the rendered output is the control that was always there.

The switch is the pointer alone, deliberately with no width bound. pointer means the PRIMARY device, so a touchscreen laptop reports fine and keeps the typable field (its keyboard is right there), while a narrowed desktop window is still a mouse. Adding a width test would only re-exclude tablets, which have the same thumb and more room to use it.

Every prop keeps its meaning, and the two that gain one say so in the docs: placeholder also becomes the sheet search field's placeholder, so write it as a search hint; maxEntries disables Add at the cap, and the token that reaches it closes the sheet. hasCreate, renderItem, renderToken, maxMenuItems, debounceMs, htmlName, hasClear, status, and the disabled-reason tooltip all behave as they do on the pointer surface, because the selection logic is now one shared hook rather than two copies — including the "Create X" sentinel, which is the part that must not fork.

The public surface barely moves: one new export, TokenizerTouchSurface, the touch half with the pointer test skipped, so a Storybook story or a handset-only app can render it directly, plus three @astryx.tokenizer.* catalog keys for the Add button and the sheet's search field. The plus glyph is drawn in the component rather than registered as an icon name — it is structural, the way CheckboxIndicator draws its own tick, and registering a name would put every theme on the hook for an icon.

Costs 16.4 KB gzipped on top of Tokenizer's 58.6 KB — mostly BottomSheet and List, which most apps already ship — for every consumer including desktop-only ones, since the choice is made at runtime.

@imdreamrunner