Skip to content

feat(item-themes): merge neutral/secondary into clear/outline + isSel…#1179

Open
tenphi wants to merge 6 commits into
mainfrom
feat-item-themes-migration
Open

feat(item-themes): merge neutral/secondary into clear/outline + isSel…#1179
tenphi wants to merge 6 commits into
mainfrom
feat-item-themes-migration

Conversation

@tenphi
Copy link
Copy Markdown
Member

@tenphi tenphi commented May 19, 2026

…ected

  • Drop neutral and secondary from Button, ButtonSplit, Item, ItemAction, ItemBadge, ItemButton, and RadioGroup.buttonType. Migrate neutralclear, clearclear + isSelected, secondaryoutline + isSelected.
  • Default type for ItemAction / ItemBadge / ItemButton flips from neutral to clear. ItemBadge widens to 'primary' | 'outline' | 'clear' | 'link' and supports isSelected.
  • Rename Item.icon / ItemAction.icon / ItemBadge.icon special value 'checkbox''checkmark'; matching style modifier renamed too.
  • Realign DEFAULT_CLEAR_STYLES with DEFAULT_ITEM_STYLES so the non-selected pressed state and selected fill ramp behave consistently between the two.
  • Restructure state matrices in Button / ItemAction / Item / ItemButton / ButtonSplit stories to render selected variants in dedicated rows with consistent labels, switch row headers to Title, and fix MenuSelectableCheckboxes to pass icon="checkmark" explicitly.

Note

Medium Risk
Medium risk due to multiple breaking API changes (removing neutral/secondary types and renaming icon="checkbox" to "checkmark") across many UI components, plus non-trivial theme/style matrix refactors that could cause subtle visual regressions.

Overview
Introduces a new type="outline-2" for Button/Item-based components (base fill over #surface-3), exporting new *_OUTLINE_2_STYLES theme constants and falling back to outline for theme="special".

Makes breaking API changes by removing neutral/secondary from type (and RadioGroup.buttonType) and expressing those looks via clear/outline combined with isSelected; defaults for ItemAction, ItemBadge, and ItemButton shift to clear.

Renames the special selection icon string from "checkbox" to "checkmark" (and the corresponding style modifier) throughout Item/ItemAction/ItemBadge/Menu/ListBox etc., and updates story/docs usage.

Refactors item-themes color usage to palette tokens and adjusts fill/border state maps (including new opaque #<theme>-border for selected outline) to prevent transition flashes and improve grouped RadioGroup type="button" styling (ButtonSplit-like border overlap + z-index stacking).

Reviewed by Cursor Bugbot for commit 4876919. Bugbot is set up for automated code reviews on this repo. Configure here.

…ected

- Drop `neutral` and `secondary` from `Button`, `ButtonSplit`, `Item`,
  `ItemAction`, `ItemBadge`, `ItemButton`, and `RadioGroup.buttonType`.
  Migrate `neutral` → `clear`, `clear` → `clear` + `isSelected`,
  `secondary` → `outline` + `isSelected`.
- Default `type` for `ItemAction` / `ItemBadge` / `ItemButton` flips
  from `neutral` to `clear`. `ItemBadge` widens to
  `'primary' | 'outline' | 'clear' | 'link'` and supports `isSelected`.
- Rename `Item.icon` / `ItemAction.icon` / `ItemBadge.icon` special
  value `'checkbox'` → `'checkmark'`; matching style modifier renamed
  too.
- Realign `DEFAULT_CLEAR_STYLES` with `DEFAULT_ITEM_STYLES` so the
  non-selected pressed state and selected fill ramp behave consistently
  between the two.
- Restructure state matrices in Button / ItemAction / Item / ItemButton
  / ButtonSplit stories to render selected variants in dedicated rows
  with consistent labels, switch row headers to `Title`, and fix
  `MenuSelectableCheckboxes` to pass `icon="checkmark"` explicitly.

Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 19, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cube-ui-kit Ready Ready Preview, Comment May 19, 2026 4:08pm

Request Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 19, 2026

🦋 Changeset detected

Latest commit: 4876919

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@cube-dev/ui-kit Minor

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 19, 2026

📦 NPM canary release

Deployed canary version 0.0.0-canary-ddbecd9.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 19, 2026

🏋️ Size limit report

Name Size Passed?
All 394.31 KB (+0.09% 🔺) Yes 🎉
Tree shaking (just a Button) 112.63 KB (+0.14% 🔺) Yes 🎉

Click here if you want to find out what is changed in this build

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 19, 2026

🧪 Storybook is successfully deployed!

Comment thread src/components/content/Layout/Layout.stories.tsx
Comment thread src/components/fields/FilterPicker/FilterPicker.stories.tsx Outdated
`outline-2` mirrors `outline` but paints over `#surface-3` instead of
`#surface-2`, so it stays visually distinct when placed inside a
`#surface-2` container. Wired into Button (props, ButtonVariant, Tasty
variants map, button-split margin rule) with theme constants for
default/danger/success/warning/note. Special theme has no `outline-2`
counterpart and `theme="special" + type="outline-2"` falls back to
`outline`. Button states stories now render the `outline-2` rows
inside a `#surface-2` card and the special-theme matrix filters it
out.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread src/components/overlays/Toast/Toast.stories.tsx
Comment thread src/components/fields/FilterPicker/FilterPicker.stories.tsx Outdated
Missed during the initial migration sweep:
- Layout.stories: type="neutral" → type="clear"
- RadioGroup.stories: buttonType="neutral" → "clear", argTypes updated
- FilterPicker.stories: Badge type="neutral" → "disabled", argTypes
  updated
- Select.stories: argTypes options updated
- Toast.stories: type="secondary" → type="outline"

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread src/components/actions/ButtonSplit/ButtonSplit.stories.tsx
buttonType="clear"
defaultValue="yes"
label="Neutral"
label="Clear"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate RadioGroup story after neutral→clear migration

Low Severity

Migrating buttonType="neutral" to buttonType="clear" in the CustomButtonTypes story created a duplicate of the already-existing buttonType="clear" radio group directly below it. The story now renders two identical "Clear" sections.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 17255c7. Configure here.

Group `RadioGroup type="button"` like `ButtonSplit`: zero gap, shared corner
radius, overlapping borders, and the selected button bumped above siblings via
z-index so its brand border reads from all four sides. Hover and focus-visible
bump higher still so they always sit on top of the selected highlight.

Replace the alpha-blended `#<theme>-text.15` outline border (which double-stacked
at every overlap into a darker stripe) with a new opaque `#<theme>-border` token.
The token re-resolves the existing neutral `border` ramp per colored theme at
`saturation: 0.5` via `TINTED_SURFACE_OVERRIDE`, so each theme gets a subtly
hue-tinted border without any extra palette bookkeeping.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread src/data/item-themes.ts Outdated
Each `fill` state map now uses the same 2-layer shape (opaque base + tint
overlay) across non-selected, selected, and disabled states. tasty renders
1-color and 2-color fills via different CSS properties (`background-color`
alone vs. `background-color` + `--tasty-second-fill-color` +
`background-image: linear-gradient(...)`); transitioning between shapes
caused the gradient overlay to snap on/off while `background-color`
interpolated, briefly exposing the base layer and producing a visible flash
(noticeable in `RadioGroup type="button"` selection toggles and in primary
buttons toggling `isDisabled` on form submit).

The brand-tinted overlays now composite over each variant's own base
(`#surface` / `#surface-2` / `#surface-3` / `#special-surface`) instead of
the body surface; the resulting visual shift is sub-1 OKHSL point and
imperceptible side-by-side. Also folds `RadioGroup`'s tab-selected element
into the base `RadioButtonElement` via mod-driven `selected & tabs` state
rules so the button-mode grouping uses the simpler `!tabs &` selectors
instead of the `@parent(radio-button-group, >)` chain.

Co-authored-by: Cursor <cursoragent@cursor.com>
},
zIndex: {
'!tabs & selected': 1,
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Radio button missing hover/focus z-index elevation

Medium Severity

The inline comment on lines 48–55 explicitly states "Hover / focus-visible bump higher still so they always read on top of the selected highlight," mirroring ButtonSplit behavior. However, the zIndex styles only define '!tabs & selected': 1 — there are no hover or focus-visible z-index rules. When a user hovers a non-selected radio adjacent to a selected one, the hovered button's border will be partially clipped by the selected sibling's z-index: 1. Compare with Button.tsx which correctly defines ':hover': 1 and ':focus-visible': 2 for the ButtonSplit context.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 961c191. Configure here.

… to Item

- Migrated every color in `src/data/item-themes.ts` to Glaze palette tokens,
  removing the legacy alias indirection from `src/tokens/colors.ts`
  (`#dark` → `#surface-text`, `#dark-02` → `#surface-text-soft`,
  `#primary-text` → `#primary-accent-text`, `#primary-hover` →
  `#primary-accent-surface-hover`, `#primary` brand fill →
  `#primary-accent-surface`, `#light` → `#surface-3`, `#clear` →
  `transparent`, plus matching ramps for danger / success / warning / note).
  Resolved values are unchanged.
- Wired `outline-2` into `Item` (previously it only existed on `Button`),
  with the same `theme="special"` → `outline` fallback as `Button`. Every
  component that flows through `Item` (`ItemButton`, `Select`,
  `FilterPicker`, `Picker`, `Menu`, `RadioGroup`, etc.) now renders
  `type="outline-2"` correctly. Updated the corresponding `*.docs.mdx`
  files and `Select` / `FilterPicker` story argTypes.
- Removed migration duplicates left over after `secondary → outline` /
  `neutral → clear` (`Button.Split` Variants story + docs example,
  `RadioGroup` `CustomButtonTypes` story).
- `Radio.tsx`: gated the item-shadow on `tabs & selected`, gave the
  wrapper a focus-visible outline ring + radius so keyboard focus is
  visible on the radio label.

Co-authored-by: Cursor <cursoragent@cursor.com>
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 3 total unresolved issues (including 2 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 4876919. Configure here.

? 'clear'
: type,
? 'clear'
: type,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

outline-2 type not mapped in ItemActionContext

Medium Severity

The ItemActionContext maps 'item', 'outline', 'header', and 'card' to 'clear' for child actions, but the newly added 'outline-2' type is missing from this mapping. When an Item or ItemButton uses type="outline-2", the context passes 'outline-2' through to child ItemAction and ItemBadge components. Neither component has an 'outline-2' variant (they only support primary, outline, clear), so actions will render without any variant-specific fill, border, or color styles.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 4876919. Configure here.

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