Version Packages - #1278
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
🧪 Storybook is successfully deployed!
|
Contributor
🏋️ Size limit report
Click here if you want to find out what is changed in this build |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@cube-dev/ui-kit@0.153.0
Minor Changes
#1277
1de5e56fThanks @tenphi! - Make the color palette tunable at runtime.Hue is split into two zones:
huedrives the accent zone (theaccent-*family,primary/purple/special, plusfocus, the loading faces and the disabled chip) andbaseHuedrives the base zone (the neutral chrome —surfaceand its ladder, thesurface-text*ramp,border,placeholder).baseHueinheritshue, so the chrome keeps its faint brand tint unless you decouple it. Only thedefaulttheme is affected; a colored theme's tintedsurfacedeliberately follows its own hue, because a danger banner should read as red.Saturation is deliberately not split: it is one seed per theme, and each color's
saturationis a 0–1 factor of it, so moving it rescales the palette while keeping the designed proportions between a subtle surface tint and a saturated accent.Each status theme (
success/danger/warning/note) re-seeds hue and saturation independently.pastelandcontrastLevelare global.setPaletteConfig()replaces, likeuseState— the config you pass is the config, resolved against the shipped defaults. Nothing accumulates, so removing a customization means removing it from the object, re-applying the same config twice does the same thing as once, and<Root palette>can un-set a field by no longer passing it. To change one field of the config already in place, pass an updater; it receives the config as written, sparse, so spreading it preserves what inherits:New exports:
setPaletteConfig,getPaletteConfig,getPaletteConfigInput,resolvePaletteConfig,resetPaletteConfig,subscribePaletteConfig,invalidatePaletteTokens,usePaletteConfig,usePaletteVersion,getPalette,DEFAULT_PALETTE_CONFIG, and the typesPaletteConfig/ResolvedPaletteConfig/PaletteThemeSeed/PaletteCodeSeed/PaletteThemeName, plusgetCodeTheme.<Root>gains an equivalentpaletteprop, applied during render so the first paint is already correct.Inherited vs pinned. Unset fields inherit, so
baseHuetrackshueandthemes.<status>.saturationtrackssaturationuntil something writes them — they are not linked, they just have no value of their own yet. Writing the field pins it; leaving it out unpins it.getPaletteConfig()resolves everything and so cannot tell you which is which;getPaletteConfigInput()returns the sparse config as set, for settings UIs that need to show an inherited value as inherited — and it is what asetPaletteConfigupdater is handed.Region previews.
renderColorTokens({ …config, scheme, highContrast })resolves the palette for one config and one scheme into flat literal values, ready to apply to a subtree through a tastytokensprop:The document palette emits state maps (
@dark/@hc), so a page can only ever show one scheme at a time; collapsing it to a chosen scheme is what lets several themes coexist — a theme picker, or a dark panel in a light page. Config fields layer over the current config — the one place that differs fromsetPaletteConfig— so{ scheme: 'dark' }previews the active theme in dark. A preview means "the theme in use, but in dark", so the fields it does not mention come from the live palette rather than from the defaults.resolvePaletteConfig()layers the same way. Nothing is applied globally. Aliases, shadow tokens and scrollbar colors ride along by reference so they re-resolve against the region rather than freezing to the outer theme.renderPaletteTokensis the same without those, andresolvePaletteConfigresolves a partial without applying it.A mounted
<Root>re-injects the token block automatically when the config changes — no component re-render is involved, since every color compiles to a CSS custom property.This refactor changes no colors. Turning the palette into a function of its seeds is output-neutral: with no config set, every token resolves exactly as it did, and a new snapshot test (156 tokens × 4 scheme variants) enforces it. The surface-ladder and themed-border retune in this release is the only intentional color movement.
Notes:
bodyrule), so<Root palette>is a convenience wrapper oversetPaletteConfig(), not a per-tree scope. Under SSR, apply it in code that runs on both server and client — per-request palettes are not supported.code-*syntax family is now its own Glaze theme with its own seed, so neither the brand hue nor the palette saturation reaches it. Everycode-*hue is absolute (a re-seeded brand can no longer collide string literals with#code-numberat 156°), and the saturation is fixed at80rather than inheritingsaturation, so muting the palette cannot wash out a code block. Tune it withthemes.code.saturation; the tokens stay adaptive, keeping their['AA','AAA']floor against the real surface in every scheme. Resolved values at the default config are unchanged.contrastLevelremoves the high-contrast tier entirely, so<html data-contrast="high">andprefers-contrast: morestop having an effect while one is set.pastel: truechanges every resolved color by design. Both are documented in the newGetting Started/Themingpage.Patch Changes
#1277
1de5e56fThanks @tenphi! - Update@tenphi/glaze1.2.0 → 1.3.0. Resolved colors are unchanged: every token was dumped in all four scheme variants ('',@dark,@hc,@dark & @hc) and diffed against 1.2.0 — byte-identical.1.3.0 adds the
contrastLevelconfig field (a manual 0–100 contrast level replacing the two-tier high-contrast model, where levels 0 and 100 reproduce the normal and high-contrast output exactly), theresolveContrastForLevel()export, and thepreferInitialcontrast-solver option. Nothing existing changed behavior.A new snapshot spec (
src/tokens/palette.test.ts) pins the resolved palette — 156 tokens across four scheme variants — so a future Glaze bump or seed retune cannot move colors silently.#1277
1de5e56fThanks @tenphi! - Update@tenphi/tasty2.11.0 → 2.11.2, which fixes global-style hook behavior.useGlobalStylesnow keys its injection slots per root instead of in one module-level map, and the SSR / RSC collectors treat anid-keyed entry as replaceable rather than deduplicating it by content.That matters for the runtime-tunable palette:
<Root>injects the token block asuseGlobalStyles('body', …, { id: 'cube-ui-kit-tokens' }), so re-seeding the palette now replaces the previous block correctly on the server and in shadow roots, not just on the client.The bump adds ~400 B to the tree-shaken
Buttonentry, so itssize-limitbudget moved 118 kB → 119 kB.#1277
1de5e56fThanks @tenphi! - Add an optionalschemeprop toCubeLogo/CubeFullLogo.The mark is two drawings swapped by the
@darkstate, which is resolved against the document.scheme="light" | "dark"pins one of them for cases where the background is known but the document scheme does not describe it — a fixed-dark panel in a light app, an exported image, or a region themed throughtokens(which overrides token values, and so cannot reach a state). Omitting it keeps today's behaviour: the CSS swap, with no re-render and correct SSR.#1277
1de5e56fThanks @tenphi! - Retune the surface ladder, the themed borders and the radio mark.#surface-2,#surface-3and#surface-4gain wider high-contrast tone pairs (['-2','-4'],['-4','-8'],['-6','-12']), so nested panels stay distinguishable when a user asks for more contrast. The tinted<theme>-surfacewidens the same way.#borderdeepens in high contrast too (['-10','-30']).<theme>-borderused by OUTLINE-variant items drops fromsaturation: 0.5to0.3and takes the same wider HC pair, so a themed border reads as a border rather than a second accent.Radiomark moves from#primaryto#primary-text, matching the#danger-text/#success-textits own invalid and valid states already used.#primaryis a fixed brand fill that barely moves between schemes;#primary-textis contrast-solved against the surface, so the dot lightens in dark (L 0.54 → 0.76) and in high contrast instead of staying a mid-tone purple.Alertborders now use#<theme>-borderinstead of a 20%-alpha accent fill, which is what makes the themed borders consistent between alerts and outline items. Thespecialalert border moves to#primary-borderfor the same reason.Scope, measured across all 156 tokens in all four scheme variants: 68 tokens moved — 68 in
@dark & @hcand 62 in@hc. Only six move in the normal and dark schemes, and they are exactly the themed borders (#primary-border,#purple-border,#success-border,#danger-border,#warning-border,#note-border), from the saturation change. Everything else is high-contrast only. No token was added or removed, and thecode-*family does not move at all.#1277
1de5e56fThanks @tenphi! - FixonChangeonSwitchandCheckboxnot typechecking in controlled mode.CubeSwitchProps/CubeCheckboxPropswere missingonChange,isSelectedanddefaultSelectedentirely, so every controlled call site needed a@ts-expect-error. Root cause:tsconfig.jsonsetspreserveSymlinks: true, so TypeScript resolvesreact-aria's type re-exports from the symlink path and never finds the@react-aria/*subpackages (they are not direct dependencies);skipLibCheckthen hides the failure and everyAria*Propssilently becomesany. Extending ananybase contributes no members, which is why exactly these props vanished.The selection contract is now declared explicitly as
ToggleSelectionProps(src/shared/form.ts) and mixed into both components, restoring real type checking — a wrong handler signature now fails again. Four@ts-expect-errorsuppressions were removed (DisclosureandTreeinternals plus the theming stories), andCheckboxno longer types its non-DOMonChangeonto the<label>element it spreads props onto.Radiodeliberately keeps noonChange: in React Aria a single radio has none — selection is owned byRadio.Group.Removing
preserveSymlinksis the real fix, but it surfaces ~320 previously-hidden type errors across ~60 files, so it needs its own migration. The cause is documented inAGENTS.mdandtsconfig.jsonso the next person does not re-diagnose it.