Skip to content

Rebuild the form fields and add NumberField - #90

Draft
librowski wants to merge 2 commits into
ds2-buttonsfrom
ds2-form-fields
Draft

Rebuild the form fields and add NumberField#90
librowski wants to merge 2 commits into
ds2-buttonsfrom
ds2-form-fields

Conversation

@librowski

Copy link
Copy Markdown
Collaborator

Rebuilds Input and TextArea against the design system's field states and adds NumberField.

State instead of a booleanstate?: 'default' | 'critical' | 'success' | 'read-only' replaces error?: boolean. Hover, focus and filled stay visual states rather than props. read-only applies the native attribute, so the value stays focusable and copyable, while disabled stays out of the tab order — the distinction the design guidelines call for.

SlotsprefixIcon, suffixIcon and an optional onClear affordance, all ReactNode.

Sizes — letter-scaled l m s xs. Input row heights 42/36/32/28 with padding 11/10/8/6 vertical and 12 horizontal, gap 8, radius 8/6/6/6; the field composes a 16px label row, the input row and a 16px helper row with a 6px gap. TextArea minimum heights 120/100/80.

Colours — every surface, border and text colour binds to a field token. The hover border is deliberately lighter than the default one; that is what the design paints.

NumberField — new: an input with an always-visible stepper honouring min/max/step from both the buttons and the arrow keys, with accessible names on the stepper controls.

Call sites migrated in this PR (error={…}state, word sizes → letters).

Verified: ui/sdk lint + typecheck, build:ui, build:lib, stylelint, 62 test files / 479 tests, docs build, demo build — re-run after rebasing onto the Button layer.

Fields take an explicit state - default, critical, success or
read-only - in place of the error boolean, and sizes are letter-scaled.
Hover, focus and filled stay visual states rather than props. Read-only
keeps the field focusable and copyable through the native attribute,
while disabled stays out of the tab order.

Icons arrive as prefix and suffix slots with an optional clear
affordance. Heights, padding, gap, radius and the label roles come from
the design component set, and every surface, border and text colour
binds to its field token.

NumberField is new: an input with an always-visible stepper that
honours min, max and step from both the buttons and the arrow keys.
Fields render the measured composition again: a label row, the control
row and a helper row. The label is associated with the control, the
helper joins its accessible description, and the critical state marks
the control invalid, so validation text is announced instead of being
merely visible.

Focus is visible in every state, not only the default one.

Interactive adornments no longer go into the decorative icon slot,
which does not take pointer events - the datetime field renders its
variable-picker button beside the input, the way its sibling branches
already do.

NumberField now has a value contract: clearing is representable and
reported, a clamped value is emitted once, a controlled parent that
refuses an update wins, non-finite input never reaches a callback,
step=any keeps working, off-grid boundaries stay submittable, and
malformed paste is rejected rather than reinterpreted. Fifteen tests
pin those paths.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant