Skip to content

select: migrate to TUI Select / MultiSelect - #81

Merged
nicolas-jaussaud merged 9 commits into
mainfrom
feat/select-tui-migration
Aug 14, 2026
Merged

select: migrate to TUI Select / MultiSelect#81
nicolas-jaussaud merged 9 commits into
mainfrom
feat/select-tui-migration

Conversation

@juliacanzani

Copy link
Copy Markdown
Contributor

Stacked on #78 (the ^0.2.0 bump). Base is feat/tui-0.2.0-bump; retargets to main once #78 merges. Independent of the combo-box migration (#80) — different field dir.

Replaces the select field's react-aria/react-stately internals with TUI's Select (single) and MultiSelect (multiple), in the TUI Field idiom. The non-searchable sibling of #80 — static-only, so no async/label-map.

Contract preserved — verified live

ModeValue
singlehidden input = the key ("test1")
multiplehidden input = "a,b,c"; onChange([...keys]) (array, as before)

Confirmed in Storybook + Playwright: single picks show the label in the trigger, multiple renders the shared chips, grouped choices + disabledKeys work.

Structure

  • Single.tsx — TUI Select + a hidden input for form submission (replaces react-aria's HiddenSelect).
  • Multiple.tsx — TUI MultiSelect (display="chips").
  • renderOptions.tsx — flat/grouped/disabledKeys renderer.
  • Removed MultipleSelect.tsx.

⚠️ Note: select/Select.tsx is KEPT

The react-aria Select component stays — it's still an internal building block for the gradient / dimensions / simple-dimension fields. Only the select field type stops using it. Its .tf-select styles remain; the migrated field uses a distinct .tf-select-field class.

tsc improves 422 → 414; rebuilt bundle.

🤖 Generated with Claude Code

juliacanzaniand others added 2 commits July 30, 2026 20:35
Picks up MultiCombobox (searchable multi-select — needed for the combo-box
field migration's multiple+async case), Chip onRemove, and the Combobox
aria-describedby/invalid/required forwarding fix.
Compat: TUI 0.2.0's Button dropped the `iconSize` prop (icons size
intrinsically now) — removed it from the base Button wrapper + its story.
tsc error count unchanged from 0.1.x (422 pre-existing); rebuilt bundle.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the react-aria/react-stately select-field internals with TUI's Select
(single) and MultiSelect (multiple), in the TUI Field idiom. Static-only
(select has no async), so the contract is simple and preserved — verified live:
- single: hidden input = the key
- multiple: hidden input = "a,b,c"; onChange([...keys]) (array, as before)
New: Single.tsx (TUI Select + hidden input for form submission, replacing
react-aria HiddenSelect), Multiple.tsx (TUI MultiSelect, display=chips),
renderOptions.tsx (flat/grouped/disabledKeys). Removed MultipleSelect.tsx.
Note: select/Select.tsx (the react-aria Select) is KEPT — it's still an internal
building block for the gradient / dimensions / simple-dimension fields; only the
select FIELD TYPE stops using it. Its .tf-select styles stay; the migrated field
uses a distinct .tf-select-field class.
tsc 422 -> 414; rebuilt bundle.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@nicolas-jaussaud
nicolas-jaussaud changed the base branch from feat/tui-0.2.0-bump to mainAugust 3, 2026 16:22
@nicolas-jaussaud
nicolas-jaussaud merged commit 3d3bc8a into mainAug 14, 2026
2 checks passed
juliacanzani added a commit that referenced this pull request Aug 15, 2026
Matches the follow-up pattern from the other TUI migrations (#81, #82):
isDisabled || readOnly both disable the control, and the built assets
ship with the PR.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
nicolas-jaussaud added a commit that referenced this pull request Aug 17, 2026
* color: migrate to TUI ColorField (with opt-in gradient mode)
Color field -> TUI ColorField (swatch trigger + popover picker), in the
Field idiom. Requires @tangible/ui ^0.2.5.
Value contract preserved: CSS color strings in/out, legacy { value }
objects unwrapped, empty/invalid values default to #FFFFFF (the old
react-aria impl emitted #FFFFFFFF - TUI hex omits the alpha byte when
fully opaque). Legacy config mapped: hasAlpha -> alpha, react-stately
format names (hexa/rgba/hsla/...) -> TUI formats. var(--x) values pass
through verbatim.
New opt-in: gradient: true adds Solid|Gradient tabs to the popover and
lets the value be a CSS gradient string (the Figma Color Selector).
Explicit aria-label like the date field - Field.Control's labelledby
injection lands on FieldWrapper, which doesn't forward it. Dynamic
values preserved via FieldWrapper (hidden input lives with the picker).
Old react-aria components move to deprecated/fields/color, registered
as deprecated-color-picker; the (still-legacy) gradient field keeps
using the deprecated ColorPicker until its own migration. Existing jest
tests migrated to deprecated-controls; new tests cover value contract,
popover edit commit, var() passthrough, and gradient tabs. Verified
live (gradient story: tabs render, edits flow to the hidden input).
jest 518 pass, tsc 424 -> 424.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Color: Keep support for isDisabled for legacy reason; rebuild bundle
Matches the follow-up pattern from the other TUI migrations (#81, #82):
isDisabled || readOnly both disable the control, and the built assets
ship with the PR.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Deprecated color: Make sure deprecated style is being applied correctly
* Color and gradient: Make sure to use consistent border radius in wp context
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Nicolas Jaussaud <hi@nicolasjaussaud.me>
Sign up for freeto 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.

2 participants

@juliacanzani@nicolas-jaussaud