fix(react): pin and upgrade @telegraph/combobox to 0.6.0 - #1068
Conversation
@knocklabs/react declared "@telegraph/combobox": ">=0.5.0", so every consumer resolved to whatever was latest on npm — including 0.6.0, the Base UI rewrite, against code only ever tested on 0.5.0. Pin the range to ^0.6.0 across the workspace, bump the lockfile, and take the upgrade deliberately. Two things the upgrade needed: - SlackChannelCombobox renders an icon beside each channel name, so its options have element children. 0.6.0 resolves an option's label as `label || children || value` and falls back to `value` whenever the label is not a string, so the trigger announced the raw Slack channel id. Each option now passes an explicit `label`. - 0.6.0 tightened Combobox.Root's `value` type, which no longer accepts `(string | undefined)[]`. Both multi-select call sites now narrow. Add coverage for all three comboboxes, which had none, and polyfill ResizeObserver and scrollIntoView so Base UI can mount under jsdom.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: 668e839 The changes in this PR will be included in the next version bump. This PR includes changesets to release 5 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Bundle ReportChanges will increase total bundle size by 1.73kB (0.29%) ⬆️. This is within the configured threshold ✅ Detailed changes
Affected Assets, Files, and Routes:view changes for bundle: @knocklabs/react-react-esmAssets Changed:
Files in
Files in
Files in
view changes for bundle: @knocklabs/react-react-cjsAssets Changed:
Files in
Files in
Files in
|
useMsTeamsChannels returns a reference straight into SWR's cache, so sorting in place reordered the cached array for every other reader of that key — including apps that call the hook themselves, since both MS Teams hooks are public exports. Copy first, matching the Slack helper, and take a readonly parameter so a bare .sort() no longer compiles.
Combobox.Option renders `label || children || value`, so the string label added for the accessible name stopped the option's children rendering. That silently dropped the hash/lock icon from both the dropdown row and the selected tags, and it is the only place a channel's private/public state is shown. Move the icon into the option's trailing icon slot. The leading slot is not available: OptionItemLeading returns the selection check early for any selectable combobox, so `leadingIcon` and `leadingComponent` are both ignored there. The icon now sits at the right edge of the row rather than beside the name, and the trigger's tags still show the name alone, because TriggerTagText renders `label || value` and never sees the icon.
Every other @telegraph/* dependency was still an open >= range, so an install resolved to whatever npm had newest rather than something this package was built against — the same problem the combobox pin fixed. The one with a real consequence was @telegraph/select, stuck on 0.1.0, which hard-pins @telegraph/combobox at 0.5.0. Consumers were getting two copies of the combobox. 0.2.0 depends on 0.6.0, so the lockfile now carries a single entry.
Earlier commits fixed the trigger's accessible name by giving each option a string `label`. An option renders `label || children || value`, so that also stopped the children rendering and cost the hash/lock icon; routing it through `trailingIcon` got it back but moved it to the right edge, and the trigger's tags lost it entirely. Combobox.Trigger spreads consumer props over its own `aria-label`, so the name can be set directly and the markup left alone. The options go back to exactly what main renders, and the icon returns to its old position in both the dropdown and the tags. The option's own name in the listbox needs nothing: its icon is aria-hidden, so the name already resolves from its text.
currentConnectedChannels and triggerLabel each built their own Map over slackChannels, so every render paid for two passes over a list that can hold a thousand channels. Lift one memoized map and read both from it.
The combobox entry described the accessible-name bug but, once the fix moved to an aria-label on the trigger, no longer described the fix — and its other half repeated the dependency pin that the telegraph entry already covers. Consumers would have read both twice, one of them as an unresolved defect.
Both "ignores connections that are no longer available / belong to another team" cases asserted only on the trigger's accessible name. A selected id with no matching option resolves to undefined and is filtered out of that name, so removing the guard each test exists to cover left the name unchanged and both passed regardless. The stray id does render a tag, since the trigger falls back to the raw value when no option matches, so assert the tag is absent instead.
Three branches added by this PR had no test behind them: connected channels arriving undefined before the first load, a connection with no channel id at all, and the trigger label falling through to "" when nothing is connected and the error state carries no label to show. That last one is the reason the label is built as a string rather than left undefined, so it is worth pinning down.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1068 +/- ##
==========================================
+ Coverage 73.13% 75.38% +2.24%
==========================================
Files 139 139
Lines 4366 4371 +5
Branches 1283 1283
==========================================
+ Hits 3193 3295 +102
+ Misses 1056 976 -80
+ Partials 117 100 -17
|
Description
@knocklabs/reactdeclared">=0.5.0"for@telegraph/combobox, so every install already resolved to 0.6.0. that release is a Base UI rewrite, and our code was only ever tested on 0.5.0. this pins the range to^0.6.0and takes the upgrade deliberately.C0123ABCaria-labelfrom us instead, which leaves the icon and the layout untouchedvalue, which 0.6.0 rejects as(string | undefined)[]sortByDisplayNamecopies before sorting, so it stops reordering SWR's cached channels@telegraph/*range is pinned too, andselect@0.2.0drops the duplicate combobox 0.5.0nothing renders differently: the diff against main changes no markup in any of the three comboboxes.