From 2760f679f8e921dd99bbaae4a132c51d1fe6d3f8 Mon Sep 17 00:00:00 2001 From: jaymantri Date: Thu, 26 Feb 2026 21:55:14 -0800 Subject: [PATCH 1/3] Refactor token architecture for clarity and consistency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BREAKING CHANGE: 20 tokens removed, 12 added, values changed on --border-primary. ## Token Rename Map Old Token → New Token --border-tertiary → --border-primary --border-inverted → --border-inverse --surface-inverted → --surface-inverse --surface-inverted-hover → --surface-inverse-hover --surface-strong → --surface-neutral --surface-elevated → --surface-panel --surface-sunken → --surface-secondary --text-surface → --text-inverse --icon-surface → --icon-inverse --icon-inverted → --icon-inverse --input-focus (color) → --state-focus --input-focus-critical (color) → --state-focus-critical Note: --input-focus/--input-focus-critical in _effects.scss (full box-shadow values) are unchanged. Only the color tokens moved to state-*. ## New Tokens --border-focus Solid border for focus outlines (split from old --border-primary) --stroke-primary Solid stroke for charts/data visualization only --surface-panel Background for floating UI: dialogs, tooltips, popovers, action bars --text-link Link text color ## Removed Tokens (no replacement) --border-hover, --text-muted, --surface-active, --surface-selected, --surface-inverted-backdrop, --icon-info-inverted, --icon-success-inverted, --icon-warning-inverted, --icon-critical-inverted ## Silent Value Change: --border-primary --border-primary still exists but changed value from solid to alpha: - Light: #1A1A1A → rgba(38, 38, 35, 0.10) - Dark: #F8F8F7 → rgba(244, 244, 245, 0.10) This will NOT surface as a build error. Consumers using --border-primary directly should audit: - Focus outlines → switch to --border-focus - Chart strokes → switch to --stroke-primary - Default UI borders (dividers, card edges) → no action, alpha is correct ## Dark Mode Surface Recalibration --surface-panel: #111111 → #212121 (lifts panels above --surface-primary) --surface-secondary: #282828 → #111111 (recedes behind --surface-primary) ## Consumer Migration No sequencing required. Bump Origin, find-and-replace old token names, audit --border-primary and --input-focus usage, test dark mode. Made-with: Cursor --- .../Accordion/Accordion.module.scss | 4 +- .../ActionBar/ActionBar.module.scss | 4 +- src/components/Alert/Alert.module.scss | 6 +- .../AlertDialog/AlertDialog.module.scss | 2 +- .../Autocomplete/Autocomplete.module.scss | 6 +- src/components/Avatar/Avatar.module.scss | 18 +- src/components/Badge/Badge.module.scss | 18 +- .../Breadcrumb/Breadcrumb.module.scss | 4 +- src/components/Button/Button.module.scss | 24 +- .../ButtonGroup/ButtonGroup.module.scss | 8 +- src/components/Card/Card.module.scss | 4 +- src/components/Chart/Chart.module.scss | 12 +- src/components/Chart/LiveChart.tsx | 2 +- src/components/Chart/types.ts | 2 +- src/components/Checkbox/Checkbox.module.scss | 6 +- src/components/Chip/Chip.module.scss | 10 +- src/components/Combobox/Combobox.module.scss | 10 +- src/components/Command/Command.module.scss | 8 +- src/components/Dialog/Dialog.module.scss | 4 +- src/components/Input/Input.module.scss | 2 +- .../InputGroup/InputGroup.module.scss | 14 +- src/components/InputGroup/InputGroup.test.tsx | 2 +- src/components/Item/Item.module.scss | 2 +- src/components/Logo/Logo.module.scss | 2 +- src/components/Logo/Logo.tsx | 2 +- src/components/Menu/Menu.module.scss | 6 +- src/components/Meter/Meter.module.scss | 2 +- .../NavigationMenu/NavigationMenu.module.scss | 14 +- .../Pagination/Pagination.module.scss | 4 +- .../PhoneInput/PhoneInput.module.scss | 8 +- src/components/Popover/Popover.module.scss | 4 +- src/components/Progress/Progress.module.scss | 2 +- src/components/Radio/Radio.module.scss | 4 +- src/components/Select/Select.module.scss | 10 +- .../Separator/Separator.module.scss | 2 +- src/components/Sidebar/Sidebar.module.scss | 22 +- src/components/Switch/Switch.module.scss | 4 +- src/components/Table/Table.module.scss | 10 +- src/components/Tabs/Tabs.module.scss | 10 +- src/components/Textarea/Textarea.module.scss | 2 +- .../TextareaGroup/TextareaGroup.module.scss | 2 +- src/components/Toast/Toast.module.scss | 6 +- src/components/Toggle/Toggle.module.scss | 6 +- src/components/Tooltip/Tooltip.module.scss | 8 +- src/tokens/_typography.scss | 6 +- src/tokens/_variables.scss | 172 +++--- tokens/figma/origin/Dark.tokens.json | 499 ++++++----------- tokens/figma/origin/Light.tokens.json | 501 ++++++------------ 48 files changed, 529 insertions(+), 951 deletions(-) diff --git a/src/components/Accordion/Accordion.module.scss b/src/components/Accordion/Accordion.module.scss index 6bf085f..8204203 100644 --- a/src/components/Accordion/Accordion.module.scss +++ b/src/components/Accordion/Accordion.module.scss @@ -14,7 +14,7 @@ overflow: hidden; &:not(:last-child) { - border-bottom: var(--stroke-sm) solid var(--border-tertiary); + border-bottom: var(--stroke-sm) solid var(--border-primary); } } @@ -36,7 +36,7 @@ text-align: left; &:focus-visible { - outline: 2px solid var(--input-focus); + outline: 2px solid var(--state-focus); outline-offset: -2px; } } diff --git a/src/components/ActionBar/ActionBar.module.scss b/src/components/ActionBar/ActionBar.module.scss index 540575c..639e25a 100644 --- a/src/components/ActionBar/ActionBar.module.scss +++ b/src/components/ActionBar/ActionBar.module.scss @@ -10,8 +10,8 @@ min-width: 320px; max-width: 420px; padding: var(--spacing-xs) var(--spacing-xs) var(--spacing-xs) var(--spacing-md); // 8px 8px 8px 16px - background-color: var(--surface-elevated); - border: var(--stroke-xs) solid var(--border-tertiary); + background-color: var(--surface-panel); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(10px); box-shadow: var(--shadow-lg); } diff --git a/src/components/Alert/Alert.module.scss b/src/components/Alert/Alert.module.scss index 1e3ddf1..cdfb368 100644 --- a/src/components/Alert/Alert.module.scss +++ b/src/components/Alert/Alert.module.scss @@ -41,7 +41,7 @@ .default { background-color: var(--surface-primary); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); padding: var(--spacing-sm) var(--spacing-md); .iconWrapper { @@ -59,7 +59,7 @@ .warning { background-color: var(--surface-yellow); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); padding: var(--spacing-sm) var(--spacing-md); .iconWrapper { @@ -77,7 +77,7 @@ .critical { background-color: var(--surface-red); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); padding: var(--spacing-sm) var(--spacing-3xl) var(--spacing-sm) var(--spacing-md); .iconWrapper { diff --git a/src/components/AlertDialog/AlertDialog.module.scss b/src/components/AlertDialog/AlertDialog.module.scss index cfb1b6e..18a6b97 100644 --- a/src/components/AlertDialog/AlertDialog.module.scss +++ b/src/components/AlertDialog/AlertDialog.module.scss @@ -34,7 +34,7 @@ width: 360px; max-width: calc(100vw - var(--spacing-2xl)); overflow: clip; - background-color: var(--surface-elevated); + background-color: var(--surface-panel); border: var(--stroke-xs) solid var(--border-secondary); @include smooth-corners(var(--corner-radius-md)); box-shadow: var(--shadow-lg); diff --git a/src/components/Autocomplete/Autocomplete.module.scss b/src/components/Autocomplete/Autocomplete.module.scss index 2112752..1a1554a 100644 --- a/src/components/Autocomplete/Autocomplete.module.scss +++ b/src/components/Autocomplete/Autocomplete.module.scss @@ -12,7 +12,7 @@ height: 36px; box-sizing: border-box; padding-inline: var(--spacing-sm); - border: var(--stroke-sm) solid var(--border-tertiary); + border: var(--stroke-sm) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); color: var(--text-primary); outline: none; @@ -54,7 +54,7 @@ max-width: var(--available-width); overflow: hidden; background: var(--surface-primary); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); box-shadow: var(--shadow-lg); outline: 0; @@ -152,7 +152,7 @@ left: 0; right: 0; height: var(--stroke-xs); - background-color: var(--border-tertiary); + background-color: var(--border-primary); } } diff --git a/src/components/Avatar/Avatar.module.scss b/src/components/Avatar/Avatar.module.scss index 06d0b3d..96003db 100644 --- a/src/components/Avatar/Avatar.module.scss +++ b/src/components/Avatar/Avatar.module.scss @@ -11,7 +11,7 @@ flex-shrink: 0; user-select: none; vertical-align: middle; - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); } // Sizes @@ -107,7 +107,7 @@ } .gray { - background-color: var(--surface-strong); + background-color: var(--surface-neutral); } // Image - fades in when loaded via Base UI transition attributes @@ -130,7 +130,7 @@ justify-content: center; width: 100%; height: 100%; - color: var(--text-surface); + color: var(--text-inverse); text-align: center; font-weight: var(--font-weight-book); transition: opacity 200ms ease; @@ -142,31 +142,31 @@ // Typography scales with avatar size .size16 & { @include label-xs; - color: var(--text-surface); + color: var(--text-inverse); } .size20 & { @include label-sm; - color: var(--text-surface); + color: var(--text-inverse); } .size24 & { @include label-sm; - color: var(--text-surface); + color: var(--text-inverse); } .size32 & { @include label-sm; - color: var(--text-surface); + color: var(--text-inverse); } .size40 & { @include label; - color: var(--text-surface); + color: var(--text-inverse); } .size48 & { @include label-lg; - color: var(--text-surface); + color: var(--text-inverse); } } diff --git a/src/components/Badge/Badge.module.scss b/src/components/Badge/Badge.module.scss index ce82983..3e2c14b 100644 --- a/src/components/Badge/Badge.module.scss +++ b/src/components/Badge/Badge.module.scss @@ -18,8 +18,8 @@ color: var(--text-primary); &.vibrant { - background-color: var(--surface-strong); - color: var(--text-surface); + background-color: var(--surface-neutral); + color: var(--text-inverse); } } @@ -29,7 +29,7 @@ &.vibrant { background-color: var(--surface-purple-strong); - color: var(--text-surface); + color: var(--text-inverse); } } @@ -39,7 +39,7 @@ &.vibrant { background-color: var(--surface-blue-strong); - color: var(--text-surface); + color: var(--text-inverse); } } @@ -49,7 +49,7 @@ &.vibrant { background-color: var(--surface-sky-strong); - color: var(--text-surface); + color: var(--text-inverse); } } @@ -59,7 +59,7 @@ &.vibrant { background-color: var(--surface-pink-strong); - color: var(--text-surface); + color: var(--text-inverse); } } @@ -69,7 +69,7 @@ &.vibrant { background-color: var(--surface-green-strong); - color: var(--text-surface); + color: var(--text-inverse); } } @@ -79,7 +79,7 @@ &.vibrant { background-color: var(--surface-yellow-strong); - color: var(--text-surface); + color: var(--text-inverse); } } @@ -89,6 +89,6 @@ &.vibrant { background-color: var(--surface-red-strong); - color: var(--text-surface); + color: var(--text-inverse); } } diff --git a/src/components/Breadcrumb/Breadcrumb.module.scss b/src/components/Breadcrumb/Breadcrumb.module.scss index 70233e6..0f0c32a 100644 --- a/src/components/Breadcrumb/Breadcrumb.module.scss +++ b/src/components/Breadcrumb/Breadcrumb.module.scss @@ -49,7 +49,7 @@ &:focus-visible { outline: none; - box-shadow: 0 0 0 2px var(--input-focus); + box-shadow: 0 0 0 2px var(--state-focus); @include smooth-corners(var(--corner-radius-xs)); } @@ -81,7 +81,7 @@ &:focus-visible { outline: none; - box-shadow: 0 0 0 2px var(--input-focus); + box-shadow: 0 0 0 2px var(--state-focus); } @media (prefers-reduced-motion: reduce) { diff --git a/src/components/Button/Button.module.scss b/src/components/Button/Button.module.scss index bbd609e..1b9f5e0 100644 --- a/src/components/Button/Button.module.scss +++ b/src/components/Button/Button.module.scss @@ -18,7 +18,7 @@ &:focus-visible { outline: none; - box-shadow: 0 0 0 3px var(--input-focus); + box-shadow: 0 0 0 3px var(--state-focus); } &[data-disabled] { @@ -70,13 +70,13 @@ } .filled { - background-color: var(--surface-inverted); - color: var(--text-surface); + background-color: var(--surface-inverse); + color: var(--text-inverse); @media (hover: hover) { &:hover:not([data-disabled]) { - background-color: var(--surface-inverted); - background-image: linear-gradient(var(--surface-inverted-hover), var(--surface-inverted-hover)); + background-color: var(--surface-inverse); + background-image: linear-gradient(var(--surface-inverse-hover), var(--surface-inverse-hover)); } } @@ -100,7 +100,7 @@ &:focus-visible { border-color: var(--border-secondary); - box-shadow: 0 0 0 3px var(--input-focus); + box-shadow: 0 0 0 3px var(--state-focus); } &[data-disabled] { @@ -111,7 +111,7 @@ .outline { background-color: var(--surface-primary); color: var(--text-primary); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.08); @media (hover: hover) { @@ -121,7 +121,7 @@ } &:focus-visible { - box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.08), 0 0 0 3px var(--input-focus); + box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.08), 0 0 0 3px var(--state-focus); } &[data-disabled] { @@ -133,7 +133,7 @@ box-shadow: none; &:focus-visible { - box-shadow: 0 0 0 3px var(--input-focus); + box-shadow: 0 0 0 3px var(--state-focus); } } } @@ -155,17 +155,17 @@ .critical { background-color: var(--surface-red-strong); - color: var(--text-surface); + color: var(--text-inverse); @media (hover: hover) { &:hover:not([data-disabled]) { background-color: var(--surface-red-strong); - background-image: linear-gradient(var(--surface-inverted-hover), var(--surface-inverted-hover)); + background-image: linear-gradient(var(--surface-inverse-hover), var(--surface-inverse-hover)); } } &:focus-visible { - box-shadow: 0 0 0 3px var(--input-focus-critical); + box-shadow: 0 0 0 3px var(--state-focus-critical); } &[data-disabled] { diff --git a/src/components/ButtonGroup/ButtonGroup.module.scss b/src/components/ButtonGroup/ButtonGroup.module.scss index faa5009..addc010 100644 --- a/src/components/ButtonGroup/ButtonGroup.module.scss +++ b/src/components/ButtonGroup/ButtonGroup.module.scss @@ -30,7 +30,7 @@ } // -- Filled variant ---------------------------------------------------------- -// Buttons sit flush; thin separators between them use --border-inverted. +// Buttons sit flush; thin separators between them use --border-inverse. .filled { > * { @@ -46,7 +46,7 @@ bottom: 0; left: 0; width: var(--stroke-xs); - background-color: var(--border-inverted); + background-color: var(--border-inverse); } } @@ -66,7 +66,7 @@ // -- Secondary variant -------------------------------------------------------- // No container shadow or border-radius. Thin separators between buttons -// using --border-tertiary, same pseudo-element technique as filled. +// using --border-primary, same pseudo-element technique as filled. .secondary { > * { @@ -82,7 +82,7 @@ bottom: 0; left: 0; width: var(--stroke-xs); - background-color: var(--border-tertiary); + background-color: var(--border-primary); } } diff --git a/src/components/Card/Card.module.scss b/src/components/Card/Card.module.scss index 29a1970..7419896 100644 --- a/src/components/Card/Card.module.scss +++ b/src/components/Card/Card.module.scss @@ -12,7 +12,7 @@ // Structured variant - has card surface .structured { background-color: var(--surface-primary); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-xl)); overflow: clip; } @@ -49,7 +49,7 @@ height: 32px; padding: 0; background-color: var(--surface-primary); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); box-shadow: var(--shadow-sm); color: var(--text-primary); diff --git a/src/components/Chart/Chart.module.scss b/src/components/Chart/Chart.module.scss index e5ae1dd..3182704 100644 --- a/src/components/Chart/Chart.module.scss +++ b/src/components/Chart/Chart.module.scss @@ -72,8 +72,8 @@ flex-direction: column; gap: var(--spacing-4xs); padding: var(--spacing-3xs) var(--spacing-2xs); - background-color: var(--surface-elevated); - border: var(--stroke-xs) solid var(--border-tertiary); + background-color: var(--surface-panel); + border: var(--stroke-xs) solid var(--border-primary); border-radius: var(--corner-radius-xs); box-shadow: 0 1px 3px rgba(0, 0, 0, var(--chart-tooltip-shadow-opacity, 0.06)); z-index: 10; @@ -98,7 +98,7 @@ color: var(--text-secondary); padding-bottom: var(--spacing-3xs); margin-bottom: var(--spacing-4xs); - border-bottom: var(--stroke-xs) solid var(--border-tertiary); + border-bottom: var(--stroke-xs) solid var(--border-primary); margin-inline: calc(-1 * var(--spacing-2xs)); padding-inline: var(--spacing-2xs); } @@ -136,7 +136,7 @@ } .tooltipFooter { - border-top: var(--stroke-xs) solid var(--border-tertiary); + border-top: var(--stroke-xs) solid var(--border-primary); margin: var(--spacing-4xs) calc(-1 * var(--spacing-2xs)) 0; padding: var(--spacing-3xs) var(--spacing-2xs) 0; } @@ -258,7 +258,7 @@ &:focus-visible { outline: none; - box-shadow: 0 0 0 2px var(--input-focus); + box-shadow: 0 0 0 2px var(--state-focus); @include smooth-corners(var(--corner-radius-xs)); } } @@ -469,7 +469,7 @@ .gaugeMarker { width: 2px; - background-color: var(--border-primary); + background-color: var(--stroke-primary); flex: 1; } diff --git a/src/components/Chart/LiveChart.tsx b/src/components/Chart/LiveChart.tsx index a5c81dd..a49437f 100644 --- a/src/components/Chart/LiveChart.tsx +++ b/src/components/Chart/LiveChart.tsx @@ -137,7 +137,7 @@ export const Live = React.forwardRef( { data, value, - color = 'var(--border-primary)', + color = 'var(--stroke-primary)', window: windowSecs = 30, grid = true, fill = true, diff --git a/src/components/Chart/types.ts b/src/components/Chart/types.ts index 7217a5c..1876d47 100644 --- a/src/components/Chart/types.ts +++ b/src/components/Chart/types.ts @@ -42,7 +42,7 @@ export type TooltipProp = export type TooltipMode = 'off' | 'simple' | 'compact' | 'detailed' | 'custom'; export const SERIES_COLORS = [ - 'var(--border-primary)', + 'var(--stroke-primary)', 'var(--text-secondary)', 'var(--surface-blue-strong)', 'var(--surface-purple-strong)', diff --git a/src/components/Checkbox/Checkbox.module.scss b/src/components/Checkbox/Checkbox.module.scss index ff3c7bb..429c713 100644 --- a/src/components/Checkbox/Checkbox.module.scss +++ b/src/components/Checkbox/Checkbox.module.scss @@ -78,7 +78,7 @@ padding: var(--spacing-md); padding-right: var(--spacing-3xl); @include surface-with-hover(var(--surface-secondary)); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-md)); overflow: hidden; @@ -114,14 +114,14 @@ // When used inside Checkbox.Item .item[data-checked] &, .item[data-indeterminate] & { - background-color: var(--surface-inverted); + background-color: var(--surface-inverse); border-color: transparent; } // When used standalone (Checkbox.Indicator) &[data-checked], &[data-indeterminate] { - background-color: var(--surface-inverted); + background-color: var(--surface-inverse); border-color: transparent; } diff --git a/src/components/Chip/Chip.module.scss b/src/components/Chip/Chip.module.scss index 34f189d..9a90b92 100644 --- a/src/components/Chip/Chip.module.scss +++ b/src/components/Chip/Chip.module.scss @@ -6,7 +6,7 @@ .root { display: inline-flex; align-items: center; - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); background-color: var(--surface-secondary); @@ -40,7 +40,7 @@ padding: 0 var(--spacing-3xs); height: 100%; border: none; - border-left: var(--stroke-xs) solid var(--border-tertiary); + border-left: var(--stroke-xs) solid var(--border-primary); background: transparent; color: var(--text-secondary); cursor: pointer; @@ -52,7 +52,7 @@ } &:focus-visible { - outline: 2px solid var(--border-primary); + outline: 2px solid var(--border-focus); outline-offset: -2px; } @@ -72,7 +72,7 @@ justify-content: center; padding: 0 var(--spacing-xs); height: 100%; - border-right: var(--stroke-xs) solid var(--border-tertiary); + border-right: var(--stroke-xs) solid var(--border-primary); &:last-of-type { border-right: none; @@ -96,6 +96,6 @@ .dismiss { padding: 0 var(--spacing-2xs); - border-left: var(--stroke-xs) solid var(--border-tertiary); + border-left: var(--stroke-xs) solid var(--border-primary); } } diff --git a/src/components/Combobox/Combobox.module.scss b/src/components/Combobox/Combobox.module.scss index eba1b4d..7b0c76f 100644 --- a/src/components/Combobox/Combobox.module.scss +++ b/src/components/Combobox/Combobox.module.scss @@ -13,7 +13,7 @@ min-height: 36px; padding: var(--spacing-2xs) calc(var(--spacing-xs) + 20px) var(--spacing-2xs) var(--spacing-sm); background: transparent; - border: var(--stroke-sm) solid var(--border-tertiary); + border: var(--stroke-sm) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); transition: border-color 150ms ease, @@ -106,7 +106,7 @@ } &:focus-visible { - outline: 2px solid var(--border-primary); + outline: 2px solid var(--border-focus); outline-offset: -2px; } @@ -148,7 +148,7 @@ } &:focus-visible { - outline: 2px solid var(--border-primary); + outline: 2px solid var(--border-focus); outline-offset: -2px; } @@ -174,7 +174,7 @@ max-width: var(--available-width); overflow: hidden; background: var(--surface-primary); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); box-shadow: var(--shadow-lg); outline: 0; @@ -303,7 +303,7 @@ left: 0; right: 0; height: var(--stroke-xs); - background-color: var(--border-tertiary); + background-color: var(--border-primary); } } diff --git a/src/components/Command/Command.module.scss b/src/components/Command/Command.module.scss index 8abd333..1f20c31 100644 --- a/src/components/Command/Command.module.scss +++ b/src/components/Command/Command.module.scss @@ -30,7 +30,7 @@ max-width: calc(100vw - 48px); max-height: min(420px, 70vh); background-color: var(--surface-primary); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-md)); box-shadow: var(--shadow-lg); overflow: hidden; @@ -54,7 +54,7 @@ display: flex; flex-direction: column; flex-shrink: 0; - border-bottom: var(--stroke-xs) solid var(--border-tertiary); + border-bottom: var(--stroke-xs) solid var(--border-primary); } .input { @@ -95,7 +95,7 @@ } &:not([data-empty]) { - border-bottom: var(--stroke-xs) solid var(--border-tertiary); + border-bottom: var(--stroke-xs) solid var(--border-primary); } } @@ -206,5 +206,5 @@ .separator { height: var(--stroke-xs); margin-block: var(--spacing-3xs); - background-color: var(--border-tertiary); + background-color: var(--border-primary); } diff --git a/src/components/Dialog/Dialog.module.scss b/src/components/Dialog/Dialog.module.scss index 13c4e0c..c5ddbe3 100644 --- a/src/components/Dialog/Dialog.module.scss +++ b/src/components/Dialog/Dialog.module.scss @@ -39,7 +39,7 @@ width: var(--dialog-width, 420px); max-width: calc(100vw - var(--spacing-2xl)); overflow: clip; - background-color: var(--surface-elevated); + background-color: var(--surface-panel); border: var(--stroke-xs) solid var(--border-secondary); @include smooth-corners(var(--corner-radius-md)); box-shadow: var(--shadow-lg); @@ -135,7 +135,7 @@ } &:focus-visible { - outline: 2px solid var(--input-focus); + outline: 2px solid var(--state-focus); outline-offset: -2px; } diff --git a/src/components/Input/Input.module.scss b/src/components/Input/Input.module.scss index a4680ca..e5ce68d 100644 --- a/src/components/Input/Input.module.scss +++ b/src/components/Input/Input.module.scss @@ -10,7 +10,7 @@ height: 36px; box-sizing: border-box; padding-inline: var(--spacing-sm); - border: var(--stroke-sm) solid var(--border-tertiary); + border: var(--stroke-sm) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); color: var(--text-primary); outline: none; diff --git a/src/components/InputGroup/InputGroup.module.scss b/src/components/InputGroup/InputGroup.module.scss index 0084a36..954f2f5 100644 --- a/src/components/InputGroup/InputGroup.module.scss +++ b/src/components/InputGroup/InputGroup.module.scss @@ -10,7 +10,7 @@ align-items: center; height: 36px; background: transparent; - border: var(--stroke-sm) solid var(--border-tertiary); + border: var(--stroke-sm) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); // PhoneInput uses overflow: visible for dropdown positioning; safe here. overflow: hidden; @@ -82,11 +82,11 @@ display: flex; align-items: center; justify-content: center; - background: var(--surface-sunken); + background: var(--surface-secondary); padding: var(--spacing-none) var(--spacing-sm); @include input; color: var(--text-secondary); - border-right: var(--stroke-sm) solid var(--border-tertiary); + border-right: var(--stroke-sm) solid var(--border-primary); align-self: stretch; cursor: text; flex-shrink: 0; @@ -98,7 +98,7 @@ &:last-child { border-right: none; - border-left: var(--stroke-sm) solid var(--border-tertiary); + border-left: var(--stroke-sm) solid var(--border-primary); margin-left: calc(-1 * var(--_gap)); margin-right: 0; } @@ -167,7 +167,7 @@ .buttonOutline { background: var(--surface-primary); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); box-shadow: var(--shadow-sm); } @@ -193,7 +193,7 @@ &:focus-visible { background: var(--surface-hover); border: var(--stroke-xs) solid var(--border-secondary); - box-shadow: 0 0 0 3px var(--input-focus); + box-shadow: 0 0 0 3px var(--state-focus); outline: none; } @@ -209,7 +209,7 @@ .selectTriggerOutline { background: var(--surface-primary); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); box-shadow: var(--shadow-sm); } diff --git a/src/components/InputGroup/InputGroup.test.tsx b/src/components/InputGroup/InputGroup.test.tsx index d738841..ccb2a6a 100644 --- a/src/components/InputGroup/InputGroup.test.tsx +++ b/src/components/InputGroup/InputGroup.test.tsx @@ -325,7 +325,7 @@ test.describe('InputGroup', () => { getComputedStyle(el).borderColor ); // The exact color depends on --border-secondary token - // Just verify it changed from the default --border-tertiary + // Just verify it changed from the default --border-primary expect(borderColor).toBeTruthy(); }); }); diff --git a/src/components/Item/Item.module.scss b/src/components/Item/Item.module.scss index ad05984..f348062 100644 --- a/src/components/Item/Item.module.scss +++ b/src/components/Item/Item.module.scss @@ -26,7 +26,7 @@ &:focus-visible { outline: none; - box-shadow: 0 0 0 2px var(--input-focus); + box-shadow: 0 0 0 2px var(--state-focus); } @media (prefers-reduced-motion: reduce) { diff --git a/src/components/Logo/Logo.module.scss b/src/components/Logo/Logo.module.scss index fd5cd65..7d4b8c0 100644 --- a/src/components/Logo/Logo.module.scss +++ b/src/components/Logo/Logo.module.scss @@ -3,5 +3,5 @@ .root { display: block; flex-shrink: 0; - color: var(--surface-inverted); + color: var(--surface-inverse); } diff --git a/src/components/Logo/Logo.tsx b/src/components/Logo/Logo.tsx index 248fe31..a8717cb 100644 --- a/src/components/Logo/Logo.tsx +++ b/src/components/Logo/Logo.tsx @@ -21,7 +21,7 @@ export interface LogoProps extends Omit, 'children height?: number; /** * Logo color. Accepts any CSS color value or token. - * @default 'var(--surface-inverted)' + * @default 'var(--surface-inverse)' */ color?: string; /** Required for accessibility. Describes the logo for screen readers. */ diff --git a/src/components/Menu/Menu.module.scss b/src/components/Menu/Menu.module.scss index 5af7d69..fb84564 100644 --- a/src/components/Menu/Menu.module.scss +++ b/src/components/Menu/Menu.module.scss @@ -16,7 +16,7 @@ gap: var(--spacing-4xs); padding: var(--spacing-3xs); background-color: var(--surface-primary); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); box-shadow: var(--shadow-lg); outline: 0; @@ -170,7 +170,7 @@ left: 0; right: 0; height: var(--stroke-xs); - background-color: var(--border-tertiary); + background-color: var(--border-primary); } } @@ -230,7 +230,7 @@ .arrow { display: flex; fill: var(--surface-primary); - stroke: var(--border-tertiary); + stroke: var(--border-primary); stroke-width: var(--stroke-xs); } diff --git a/src/components/Meter/Meter.module.scss b/src/components/Meter/Meter.module.scss index b8f035b..69f623e 100644 --- a/src/components/Meter/Meter.module.scss +++ b/src/components/Meter/Meter.module.scss @@ -35,7 +35,7 @@ .indicator { height: 100%; - background: var(--surface-inverted); + background: var(--surface-inverse); transition: width 200ms ease-out; @media (prefers-reduced-motion: reduce) { diff --git a/src/components/NavigationMenu/NavigationMenu.module.scss b/src/components/NavigationMenu/NavigationMenu.module.scss index 065bb42..5af43af 100644 --- a/src/components/NavigationMenu/NavigationMenu.module.scss +++ b/src/components/NavigationMenu/NavigationMenu.module.scss @@ -42,7 +42,7 @@ &:focus-visible { background-color: var(--surface-secondary); border-color: var(--border-secondary); - box-shadow: 0 0 0 3px var(--input-focus); + box-shadow: 0 0 0 3px var(--state-focus); outline: none; } @@ -91,7 +91,7 @@ &:focus-visible { background-color: var(--surface-secondary); border-color: var(--border-secondary); - box-shadow: 0 0 0 3px var(--input-focus); + box-shadow: 0 0 0 3px var(--state-focus); outline: none; } @@ -139,7 +139,7 @@ &:focus-visible { background-color: var(--surface-secondary); border-color: var(--border-secondary); - box-shadow: 0 0 0 3px var(--input-focus); + box-shadow: 0 0 0 3px var(--state-focus); outline: none; } @@ -197,7 +197,7 @@ &:focus-visible { background-color: var(--surface-secondary); border-color: var(--border-secondary); - box-shadow: 0 0 0 3px var(--input-focus); + box-shadow: 0 0 0 3px var(--state-focus); outline: none; } @@ -309,7 +309,7 @@ display: flex; flex-direction: column; background-color: var(--surface-primary); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); box-shadow: var(--shadow-lg); outline: 0; @@ -393,7 +393,7 @@ .arrow { display: flex; fill: var(--surface-primary); - stroke: var(--border-tertiary); + stroke: var(--border-primary); stroke-width: var(--stroke-xs); } @@ -464,6 +464,6 @@ left: 0; right: 0; height: var(--stroke-xs); - background-color: var(--border-tertiary); + background-color: var(--border-primary); } } diff --git a/src/components/Pagination/Pagination.module.scss b/src/components/Pagination/Pagination.module.scss index a083147..bcb07dd 100644 --- a/src/components/Pagination/Pagination.module.scss +++ b/src/components/Pagination/Pagination.module.scss @@ -36,7 +36,7 @@ width: 24px; height: 24px; padding: 0; - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); background-color: var(--surface-primary); color: var(--icon-primary); cursor: pointer; @@ -70,7 +70,7 @@ &:focus-visible { outline: none; border-color: var(--border-secondary); - box-shadow: 0 0 0 3px var(--input-focus); + box-shadow: 0 0 0 3px var(--state-focus); // Ensure focus ring appears above adjacent button position: relative; z-index: 1; diff --git a/src/components/PhoneInput/PhoneInput.module.scss b/src/components/PhoneInput/PhoneInput.module.scss index 4b682d6..a6c9d2a 100644 --- a/src/components/PhoneInput/PhoneInput.module.scss +++ b/src/components/PhoneInput/PhoneInput.module.scss @@ -8,7 +8,7 @@ align-items: center; height: 36px; background: transparent; - border: var(--stroke-sm) solid var(--border-tertiary); + border: var(--stroke-sm) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); overflow: visible; transition: @@ -45,7 +45,7 @@ height: 100%; padding-left: var(--spacing-xs); padding-right: var(--spacing-3xs); - border-right: var(--stroke-sm) solid var(--border-tertiary); + border-right: var(--stroke-sm) solid var(--border-primary); flex-shrink: 0; &[data-disabled] { @@ -70,7 +70,7 @@ flex-shrink: 0; width: 18px; height: 18px; - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); border-radius: var(--corner-radius-round); overflow: clip; @@ -139,7 +139,7 @@ max-height: min(23rem, var(--available-height)); overflow: hidden; background: var(--surface-primary); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); box-shadow: var(--shadow-lg); outline: 0; diff --git a/src/components/Popover/Popover.module.scss b/src/components/Popover/Popover.module.scss index e4270c6..5e63ff0 100644 --- a/src/components/Popover/Popover.module.scss +++ b/src/components/Popover/Popover.module.scss @@ -8,7 +8,7 @@ .popup { background-color: var(--surface-primary); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); box-shadow: var(--shadow-lg); overflow: clip; @@ -59,7 +59,7 @@ height: 8px; transform: rotate(45deg); background-color: var(--surface-primary); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); &[data-side='top'] { bottom: -4px; diff --git a/src/components/Progress/Progress.module.scss b/src/components/Progress/Progress.module.scss index 284f712..04118e8 100644 --- a/src/components/Progress/Progress.module.scss +++ b/src/components/Progress/Progress.module.scss @@ -21,7 +21,7 @@ .indicator { height: 100%; - background: var(--surface-inverted); + background: var(--surface-inverse); transition: width 200ms ease-out; @media (prefers-reduced-motion: reduce) { diff --git a/src/components/Radio/Radio.module.scss b/src/components/Radio/Radio.module.scss index 8c147f8..6b00d3e 100644 --- a/src/components/Radio/Radio.module.scss +++ b/src/components/Radio/Radio.module.scss @@ -78,7 +78,7 @@ padding: var(--spacing-md); padding-right: var(--spacing-3xl); @include surface-with-hover(var(--surface-secondary)); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-md)); overflow: hidden; @@ -112,7 +112,7 @@ } .item[data-checked] & { - background-color: var(--surface-inverted); + background-color: var(--surface-inverse); border-color: transparent; } diff --git a/src/components/Select/Select.module.scss b/src/components/Select/Select.module.scss index bd8f6de..119f01e 100644 --- a/src/components/Select/Select.module.scss +++ b/src/components/Select/Select.module.scss @@ -10,7 +10,7 @@ height: 36px; padding-inline-start: var(--spacing-sm); padding-inline-end: var(--spacing-xs); - border: var(--stroke-sm) solid var(--border-tertiary); + border: var(--stroke-sm) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); color: var(--text-primary); cursor: pointer; @@ -179,7 +179,7 @@ .triggerHybrid:focus-visible:not([data-disabled]) & { border-color: var(--border-secondary); - box-shadow: 0 0 0 3px var(--input-focus); + box-shadow: 0 0 0 3px var(--state-focus); } .triggerHybrid[data-popup-open] & { @@ -202,7 +202,7 @@ .popup { background-color: var(--surface-primary); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); box-shadow: var(--shadow-lg); outline: 0; @@ -308,7 +308,7 @@ flex-shrink: 0; width: 22px; height: 22px; - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); border-radius: var(--corner-radius-round); overflow: clip; @@ -331,7 +331,7 @@ left: 0; right: 0; height: var(--stroke-xs); - background-color: var(--border-tertiary); + background-color: var(--border-primary); } } diff --git a/src/components/Separator/Separator.module.scss b/src/components/Separator/Separator.module.scss index ad032e5..208c2c2 100644 --- a/src/components/Separator/Separator.module.scss +++ b/src/components/Separator/Separator.module.scss @@ -2,7 +2,7 @@ .root { border: 0; - background-color: var(--border-tertiary); + background-color: var(--border-primary); flex-shrink: 0; } diff --git a/src/components/Sidebar/Sidebar.module.scss b/src/components/Sidebar/Sidebar.module.scss index 17c407d..eafcf02 100644 --- a/src/components/Sidebar/Sidebar.module.scss +++ b/src/components/Sidebar/Sidebar.module.scss @@ -6,7 +6,7 @@ .root { display: flex; flex-direction: column; - border-right: var(--stroke-xs) solid var(--border-tertiary); + border-right: var(--stroke-xs) solid var(--border-primary); height: 100%; overflow: hidden; transition: width 200ms ease; @@ -26,7 +26,7 @@ flex-shrink: 0; overflow: hidden; padding: var(--sidebar-header-padding, 0 var(--spacing-sm)); - border-bottom: var(--sidebar-header-border, var(--stroke-xs) solid var(--border-tertiary)); + border-bottom: var(--sidebar-header-border, var(--stroke-xs) solid var(--border-primary)); [data-collapsed='true'] & { justify-content: center; @@ -58,7 +58,7 @@ flex-shrink: 0; overflow: hidden; padding: var(--sidebar-footer-padding, var(--spacing-xs)); - border-top: var(--sidebar-footer-border, var(--stroke-xs) solid var(--border-tertiary)); + border-top: var(--sidebar-footer-border, var(--stroke-xs) solid var(--border-primary)); [data-collapsed='true'] & { align-items: center; @@ -143,7 +143,7 @@ } &:focus-visible { - outline: 2px solid var(--border-primary); + outline: 2px solid var(--border-focus); outline-offset: -2px; } @@ -202,7 +202,7 @@ } &:focus-visible { - outline: 2px solid var(--border-primary); + outline: 2px solid var(--border-focus); outline-offset: -2px; } } @@ -269,7 +269,7 @@ top: 0; bottom: 0; width: var(--stroke-sm); - background-color: var(--border-tertiary); + background-color: var(--border-primary); z-index: 0; } } @@ -289,7 +289,7 @@ transition: background-color 150ms ease; &:focus-visible { - outline: 2px solid var(--border-primary); + outline: 2px solid var(--border-focus); outline-offset: -2px; } @@ -382,7 +382,7 @@ } &:focus-visible { - outline: 2px solid var(--border-primary); + outline: 2px solid var(--border-focus); outline-offset: -2px; } } @@ -405,7 +405,7 @@ } &:focus-visible { - outline: 2px solid var(--border-primary); + outline: 2px solid var(--border-focus); outline-offset: -2px; } } @@ -436,7 +436,7 @@ } &:focus-visible { - outline: 2px solid var(--border-primary); + outline: 2px solid var(--border-focus); outline-offset: -2px; } @@ -501,7 +501,7 @@ width: 100%; height: var(--stroke-xs); margin-block: var(--separator-margin-block); - background-color: var(--border-tertiary); + background-color: var(--border-primary); border: none; } diff --git a/src/components/Switch/Switch.module.scss b/src/components/Switch/Switch.module.scss index 66c0f39..be9f76c 100644 --- a/src/components/Switch/Switch.module.scss +++ b/src/components/Switch/Switch.module.scss @@ -11,7 +11,7 @@ transition: background-color 150ms ease; &[data-checked] { - background-color: var(--color-green-600); + background-color: var(--surface-green-strong); } &[data-disabled] { @@ -35,7 +35,7 @@ .thumb { display: block; - background-color: var(--surface-base); + background-color: var(--surface-panel); border-radius: var(--corner-radius-round); box-shadow: var(--shadow-sm); transition: transform 150ms ease; diff --git a/src/components/Table/Table.module.scss b/src/components/Table/Table.module.scss index 48e0ae6..7ec47ca 100644 --- a/src/components/Table/Table.module.scss +++ b/src/components/Table/Table.module.scss @@ -37,7 +37,7 @@ padding: 0 var(--spacing-md); text-align: left; color: var(--text-secondary); - border-bottom: var(--stroke-xs) solid var(--border-tertiary); + border-bottom: var(--stroke-xs) solid var(--border-primary); font-weight: normal; vertical-align: middle; position: relative; @@ -61,7 +61,7 @@ &:focus-visible { outline: none; - box-shadow: 0 0 0 2px var(--input-focus); + box-shadow: 0 0 0 2px var(--state-focus); @include smooth-corners(var(--corner-radius-xs)); } } @@ -125,7 +125,7 @@ &:focus-visible { outline: none; - box-shadow: inset 0 0 0 2px var(--input-focus); + box-shadow: inset 0 0 0 2px var(--state-focus); } } @@ -146,7 +146,7 @@ padding: 0 var(--spacing-md); text-align: left; color: var(--text-primary); - border-bottom: var(--stroke-xs) solid var(--border-tertiary); + border-bottom: var(--stroke-xs) solid var(--border-primary); vertical-align: middle; overflow: hidden; white-space: nowrap; @@ -239,7 +239,7 @@ justify-content: flex-end; height: 40px; padding: var(--spacing-xs) var(--spacing-md); - border-top: var(--stroke-xs) solid var(--border-tertiary); + border-top: var(--stroke-xs) solid var(--border-primary); &[data-size='compact'] { height: 32px; diff --git a/src/components/Tabs/Tabs.module.scss b/src/components/Tabs/Tabs.module.scss index 5393c84..3ab656d 100644 --- a/src/components/Tabs/Tabs.module.scss +++ b/src/components/Tabs/Tabs.module.scss @@ -22,7 +22,7 @@ padding: var(--spacing-3xs); // TODO: [A11y] text/secondary on surface/sunken = 3.7:1 contrast (needs 4.5:1) // Flag for token audit - consider darker text or lighter surface - background: var(--surface-sunken); + background: var(--surface-secondary); } .list.minimal { @@ -37,8 +37,8 @@ left: var(--active-tab-left); width: var(--active-tab-width); height: var(--active-tab-height); - background: var(--surface-elevated); - border: var(--stroke-xs) solid var(--border-tertiary); + background: var(--surface-panel); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-xs)); box-shadow: var(--shadow-sm); transition: top, left, width, height; @@ -70,7 +70,7 @@ // Focused state (keyboard navigation) &:focus-visible { - background: var(--surface-elevated); + background: var(--surface-panel); border-color: var(--border-secondary); outline: none; box-shadow: var(--input-focus); @@ -104,7 +104,7 @@ width: 100%; padding: var(--spacing-4xl) 0; overflow: clip; - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); &[data-hidden] { diff --git a/src/components/Textarea/Textarea.module.scss b/src/components/Textarea/Textarea.module.scss index 28ee36b..ac390ac 100644 --- a/src/components/Textarea/Textarea.module.scss +++ b/src/components/Textarea/Textarea.module.scss @@ -16,7 +16,7 @@ width: 100%; min-height: 66px; padding: var(--spacing-sm); - border: var(--stroke-sm) solid var(--border-tertiary); + border: var(--stroke-sm) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); color: var(--text-primary); outline: none; diff --git a/src/components/TextareaGroup/TextareaGroup.module.scss b/src/components/TextareaGroup/TextareaGroup.module.scss index 7f9191f..cef9449 100644 --- a/src/components/TextareaGroup/TextareaGroup.module.scss +++ b/src/components/TextareaGroup/TextareaGroup.module.scss @@ -8,7 +8,7 @@ min-height: 64px; max-height: var(--_textarea-group-max-height, none); background: transparent; - border: var(--stroke-sm) solid var(--border-tertiary); + border: var(--stroke-sm) solid var(--border-primary); @include smooth-corners(var(--corner-radius-lg)); // clip instead of hidden: avoids creating a scroll context so the // textarea can own its own overflow-y scrolling independently. diff --git a/src/components/Toast/Toast.module.scss b/src/components/Toast/Toast.module.scss index 633e44e..5dc2d4f 100644 --- a/src/components/Toast/Toast.module.scss +++ b/src/components/Toast/Toast.module.scss @@ -23,7 +23,7 @@ width: 320px; padding: var(--spacing-md); background-color: var(--surface-primary); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-md)); box-shadow: var(--shadow-lg); outline: none; @@ -129,7 +129,7 @@ height: 20px; padding: 0; background-color: var(--surface-primary); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); border-radius: var(--corner-radius-round); box-shadow: none; cursor: pointer; @@ -141,7 +141,7 @@ } &:focus-visible { - outline: 2px solid var(--border-primary); + outline: 2px solid var(--border-focus); outline-offset: 2px; } diff --git a/src/components/Toggle/Toggle.module.scss b/src/components/Toggle/Toggle.module.scss index e356ee1..843ea20 100644 --- a/src/components/Toggle/Toggle.module.scss +++ b/src/components/Toggle/Toggle.module.scss @@ -10,7 +10,7 @@ height: 32px; min-width: 32px; padding: 0 var(--spacing-xs); - border: var(--stroke-xs) solid var(--border-tertiary); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-xs)); background-color: var(--surface-primary); box-shadow: var(--shadow-sm); @@ -25,7 +25,7 @@ outline: none; background-color: var(--surface-hover); border-color: var(--border-secondary); - box-shadow: var(--shadow-sm), 0 0 0 3px var(--input-focus); + box-shadow: var(--shadow-sm), 0 0 0 3px var(--state-focus); } @media (hover: hover) { @@ -73,7 +73,7 @@ // Keep focus ring visible above siblings position: relative; z-index: 1; - box-shadow: 0 0 0 3px var(--input-focus); + box-shadow: 0 0 0 3px var(--state-focus); } &:first-child { diff --git a/src/components/Tooltip/Tooltip.module.scss b/src/components/Tooltip/Tooltip.module.scss index e7063c8..ca16246 100644 --- a/src/components/Tooltip/Tooltip.module.scss +++ b/src/components/Tooltip/Tooltip.module.scss @@ -9,8 +9,8 @@ .popup { max-width: 240px; padding: var(--spacing-2xs) var(--spacing-sm); - background-color: var(--surface-elevated); - border: var(--stroke-xs) solid var(--border-tertiary); + background-color: var(--surface-panel); + border: var(--stroke-xs) solid var(--border-primary); @include smooth-corners(var(--corner-radius-sm)); box-shadow: var(--shadow-sm); @include body; @@ -40,8 +40,8 @@ width: 8px; height: 8px; transform: rotate(45deg); - background-color: var(--surface-elevated); - border: var(--stroke-xs) solid var(--border-tertiary); + background-color: var(--surface-panel); + border: var(--stroke-xs) solid var(--border-primary); &[data-side='top'] { bottom: -4px; diff --git a/src/tokens/_typography.scss b/src/tokens/_typography.scss index 9da9af9..ba6ead7 100644 --- a/src/tokens/_typography.scss +++ b/src/tokens/_typography.scss @@ -24,6 +24,6 @@ .btn { @include btn; } .btn-sm { @include btn-sm; } -.link-lg { @include link-lg; } -.link { @include link; } -.link-sm { @include link-sm; } +.link-lg { @include link-lg; color: var(--text-link); text-decoration: underline; } +.link { @include link; color: var(--text-link); text-decoration: underline; } +.link-sm { @include link-sm; color: var(--text-link); text-decoration: underline; } diff --git a/src/tokens/_variables.scss b/src/tokens/_variables.scss index 51af7fa..518b359 100644 --- a/src/tokens/_variables.scss +++ b/src/tokens/_variables.scss @@ -269,199 +269,175 @@ --font-weight-semibold: 600; --font-weight-bold: 700; --font-weight-black: 900; - --border-primary: #1A1A1A; - --border-secondary: #C1C0B8; - --border-tertiary: rgba(0, 0, 0, 0.10); - --border-hover: rgba(0, 0, 0, 0.30); - --border-inverted: rgba(255, 255, 255, 0.20); + --border-primary: rgba(38, 38, 35, 0.10); + --border-secondary: rgba(35, 35, 33, 0.30); + --border-focus: #1A1A1A; + --border-inverse: rgba(255, 255, 255, 0.20); --border-critical: #CC0909; --border-warning: #FCBA02; + --stroke-primary: #1A1A1A; --icon-primary: #1A1A1A; --icon-secondary: #7C7C7C; --icon-tertiary: #C1C0B8; - --icon-surface: #F8F8F7; + --icon-inverse: #F8F8F7; --icon-info: #0072DB; --icon-success: #11A967; --icon-warning: #E09000; --icon-critical: #CC0909; - --icon-info-inverted: #EBFEFF; - --icon-success-inverted: #F0FDF7; - --icon-warning-inverted: #FFFDEA; - --icon-critical-inverted: #FFF1F1; - --input-focus: rgba(38, 38, 35, 0.10); - --input-focus-critical: #FFC4C4; + --state-focus: rgba(38, 38, 35, 0.10); + --state-focus-critical: #FFC4C4; --surface-base: #FFFFFF; --surface-primary: #F8F8F7; --surface-secondary: #F0F0EE; --surface-tertiary: #C1C0B8; - --surface-strong: #989898; - --surface-elevated: #FAFAF9; - --surface-sunken: #F4F4F3; + --surface-neutral: #989898; + --surface-panel: #FAFAF9; --surface-hover: rgba(42, 42, 37, 0.04); - --surface-selected: rgba(40, 40, 36, 0.06); - --surface-active: rgba(42, 42, 37, 0.04); - --surface-inverted: #1A1A1A; - --surface-inverted-hover: rgba(255, 255, 255, 0.04); - --surface-inverted-backdrop: rgba(248, 248, 247, 0.80); + --surface-inverse: #1A1A1A; + --surface-inverse-hover: rgba(255, 255, 255, 0.04); --surface-backdrop: rgba(38, 38, 35, 0.10); - --surface-purple: #FAF8FC; + --surface-purple: #F2EEF9; --surface-purple-strong: #754EA2; - --surface-blue: #EEF7FF; + --surface-blue: #DDEFFF; --surface-blue-strong: #0072DB; - --surface-sky: #EBFEFF; + --surface-sky: #CCF9FF; --surface-sky-strong: #00B3E0; - --surface-pink: #FFF2FB; + --surface-pink: #FFE3F9; --surface-pink-strong: #FF00D4; - --surface-green: #F0FDF7; + --surface-green: #DBFDEE; --surface-green-strong: #11A967; - --surface-yellow: #FFFDEA; + --surface-yellow: #FFFAC5; --surface-yellow-strong: #FCBA02; - --surface-red: #FFF1F1; + --surface-red: #FFC4C4; --surface-red-strong: #CC0909; --text-primary: #1A1A1A; --text-secondary: #7C7C7C; --text-tertiary: #989898; - --text-muted: var(--text-secondary); - --text-surface: #F8F8F7; + --text-inverse: #F8F8F7; + --text-link: #1A1A1A; --text-critical: #CC0909; --text-purple: #754EA2; --text-blue: #005AB1; - --text-sky: #00B3E0; - --text-pink: #FF00D4; - --text-green: #11A967; - --text-yellow: #E09000; - --text-red: #EF0D0D; + --text-sky: #067198; + --text-pink: #CF00A7; + --text-green: #118453; + --text-yellow: #BA6603; + --text-red: #CC0909; } [data-theme="dark"], .dark { - --border-primary: #F8F8F7; - --border-secondary: #464646; - --border-tertiary: rgba(255, 255, 255, 0.10); - --border-hover: rgba(255, 255, 255, 0.30); - --border-inverted: rgba(0, 0, 0, 0.20); + --border-primary: rgba(244, 244, 245, 0.10); + --border-secondary: rgba(245, 245, 245, 0.30); + --border-focus: #F8F8F7; + --border-inverse: rgba(0, 0, 0, 0.20); --border-critical: #EF0D0D; --border-warning: #FCBA02; + --stroke-primary: #F8F8F7; --icon-primary: #F8F8F7; --icon-secondary: #7C7C7C; --icon-tertiary: #464646; - --icon-surface: #1A1A1A; + --icon-inverse: #1A1A1A; --icon-info: #0072DB; --icon-success: #11A967; --icon-warning: #FCBA02; --icon-critical: #EF0D0D; - --icon-info-inverted: #124C67; - --icon-success-inverted: #12553A; - --icon-warning-inverted: #7C400B; - --icon-critical-inverted: #8B1111; - --input-focus: rgba(244, 244, 245, 0.10); - --input-focus-critical: #A80C0C; + --state-focus: rgba(244, 244, 245, 0.10); + --state-focus-critical: #A80C0C; --surface-base: #000000; --surface-primary: #1A1A1A; - --surface-secondary: #282828; - --surface-tertiary: #3D3D3D; - --surface-strong: #656565; - --surface-elevated: #111111; - --surface-sunken: #212121; + --surface-secondary: #111111; + --surface-tertiary: #282828; + --surface-neutral: #3D3D3D; + --surface-panel: #212121; --surface-hover: rgba(243, 243, 245, 0.04); - --surface-selected: rgba(243, 243, 245, 0.06); - --surface-active: rgba(243, 243, 245, 0.04); - --surface-inverted: #F8F8F7; - --surface-inverted-hover: rgba(0, 0, 0, 0.04); - --surface-inverted-backdrop: rgba(28, 28, 27, 0.80); + --surface-inverse: #F8F8F7; + --surface-inverse-hover: rgba(0, 0, 0, 0.04); --surface-backdrop: rgba(29, 29, 28, 0.70); --surface-purple: #754EA2; --surface-purple-strong: #8A62BB; - --surface-blue: #0072DB; + --surface-blue: #005AB1; --surface-blue-strong: #0072DB; - --surface-sky: #008DBC; - --surface-sky-strong: #00B3E0; - --surface-pink: #FF00D4; + --surface-sky: #067198; + --surface-sky-strong: #008DBC; + --surface-pink: #CF00A7; --surface-pink-strong: #FF00D4; --surface-green: #118453; --surface-green-strong: #11A967; --surface-yellow: #BA6603; - --surface-yellow-strong: #FCBA02; + --surface-yellow-strong: #E09000; --surface-red: #CC0909; --surface-red-strong: #EF0D0D; --text-primary: #F0F0EE; --text-secondary: #7C7C7C; --text-tertiary: #656565; - --text-muted: var(--text-secondary); - --text-surface: #1A1A1A; + --text-inverse: #1A1A1A; + --text-link: #F0F0EE; --text-critical: #EF0D0D; --text-purple: #D6C7EB; --text-blue: #70C8FF; --text-sky: #00B3E0; --text-pink: #FF99E5; - --text-green: #11A967; - --text-yellow: #FCBA02; - --text-red: #EF0D0D; + --text-green: #82F3C1; + --text-yellow: #FFEA47; + --text-red: #FF9A9A; } @media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { - --border-primary: #F8F8F7; - --border-secondary: #464646; - --border-tertiary: rgba(255, 255, 255, 0.10); - --border-hover: rgba(255, 255, 255, 0.30); - --border-inverted: rgba(0, 0, 0, 0.20); + --border-primary: rgba(244, 244, 245, 0.10); + --border-secondary: rgba(245, 245, 245, 0.30); + --border-focus: #F8F8F7; + --border-inverse: rgba(0, 0, 0, 0.20); --border-critical: #EF0D0D; --border-warning: #FCBA02; + --stroke-primary: #F8F8F7; --icon-primary: #F8F8F7; --icon-secondary: #7C7C7C; --icon-tertiary: #464646; - --icon-surface: #1A1A1A; + --icon-inverse: #1A1A1A; --icon-info: #0072DB; --icon-success: #11A967; --icon-warning: #FCBA02; --icon-critical: #EF0D0D; - --icon-info-inverted: #124C67; - --icon-success-inverted: #12553A; - --icon-warning-inverted: #7C400B; - --icon-critical-inverted: #8B1111; - --input-focus: rgba(244, 244, 245, 0.10); - --input-focus-critical: #A80C0C; + --state-focus: rgba(244, 244, 245, 0.10); + --state-focus-critical: #A80C0C; --surface-base: #000000; --surface-primary: #1A1A1A; - --surface-secondary: #282828; - --surface-tertiary: #3D3D3D; - --surface-strong: #656565; - --surface-elevated: #111111; - --surface-sunken: #212121; + --surface-secondary: #111111; + --surface-tertiary: #282828; + --surface-neutral: #3D3D3D; + --surface-panel: #212121; --surface-hover: rgba(243, 243, 245, 0.04); - --surface-selected: rgba(243, 243, 245, 0.06); - --surface-active: rgba(243, 243, 245, 0.04); - --surface-inverted: #F8F8F7; - --surface-inverted-hover: rgba(0, 0, 0, 0.04); - --surface-inverted-backdrop: rgba(28, 28, 27, 0.80); + --surface-inverse: #F8F8F7; + --surface-inverse-hover: rgba(0, 0, 0, 0.04); --surface-backdrop: rgba(29, 29, 28, 0.70); --surface-purple: #754EA2; --surface-purple-strong: #8A62BB; - --surface-blue: #0072DB; + --surface-blue: #005AB1; --surface-blue-strong: #0072DB; - --surface-sky: #008DBC; - --surface-sky-strong: #00B3E0; - --surface-pink: #FF00D4; + --surface-sky: #067198; + --surface-sky-strong: #008DBC; + --surface-pink: #CF00A7; --surface-pink-strong: #FF00D4; --surface-green: #118453; --surface-green-strong: #11A967; --surface-yellow: #BA6603; - --surface-yellow-strong: #FCBA02; + --surface-yellow-strong: #E09000; --surface-red: #CC0909; --surface-red-strong: #EF0D0D; --text-primary: #F0F0EE; --text-secondary: #7C7C7C; --text-tertiary: #656565; - --text-muted: var(--text-secondary); - --text-surface: #1A1A1A; + --text-inverse: #1A1A1A; + --text-link: #F0F0EE; --text-critical: #EF0D0D; --text-purple: #D6C7EB; --text-blue: #70C8FF; --text-sky: #00B3E0; --text-pink: #FF99E5; - --text-green: #11A967; - --text-yellow: #FCBA02; - --text-red: #EF0D0D; + --text-green: #82F3C1; + --text-yellow: #FFEA47; + --text-red: #FF9A9A; } } diff --git a/tokens/figma/origin/Dark.tokens.json b/tokens/figma/origin/Dark.tokens.json index 1ab36dc..28c3b9c 100644 --- a/tokens/figma/origin/Dark.tokens.json +++ b/tokens/figma/origin/Dark.tokens.json @@ -5,21 +5,21 @@ "$value": { "colorSpace": "srgb", "components": [ - 0.9725490212440491, - 0.9725490212440491, - 0.9686274528503418 + 0.95686274766922, + 0.95686274766922, + 0.9607843160629272 ], - "alpha": 1, - "hex": "#F8F8F7" + "alpha": 0.10000000149011612, + "hex": "#F4F4F5" }, "$extensions": { - "com.figma.variableId": "VariableID:2134:336", + "com.figma.variableId": "VariableID:2004:352", "com.figma.scopes": [ "STROKE" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:7e4bcc3763b8db1d601b4b96415731b56ca90b8e/-1:-1", - "targetVariableName": "color/gray/050", + "targetVariableId": "VariableID:d0c604ac3d3b0606b77d67bd7f8a4f4982037e42/-1:-1", + "targetVariableName": "color/alpha/temp-white/10", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -31,12 +31,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 0.27450981736183167, - 0.27450981736183167, - 0.27450981736183167 + 0.9607843160629272, + 0.9607843160629272, + 0.9607843160629272 ], - "alpha": 1, - "hex": "#464646" + "alpha": 0.30000001192092896, + "hex": "#F5F5F5" }, "$extensions": { "com.figma.variableId": "VariableID:2007:561", @@ -44,67 +44,41 @@ "STROKE" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:f5d48982e8bd755388656f89b73f3d1a09df82b8/-1:-1", - "targetVariableName": "color/gray/700", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } - }, - "tertiary": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 1, - 1, - 1 - ], - "alpha": 0.10000000149011612, - "hex": "#FFFFFF" - }, - "$extensions": { - "com.figma.variableId": "VariableID:2004:352", - "com.figma.scopes": [ - "STROKE" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:43d601095f45abae8e6f6845e30b28056f288ff6/-1:-1", - "targetVariableName": "color/alpha/white/10", + "targetVariableId": "VariableID:f93c95186853ac4ddd534a4fe0f9b9637acf69c9/-1:-1", + "targetVariableName": "color/alpha/temp-white/30", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, "com.figma.isOverride": true } }, - "hover": { + "focus": { "$type": "color", "$value": { "colorSpace": "srgb", "components": [ - 1, - 1, - 1 + 0.9725490212440491, + 0.9725490212440491, + 0.9686274528503418 ], - "alpha": 0.30000001192092896, - "hex": "#FFFFFF" + "alpha": 1, + "hex": "#F8F8F7" }, "$extensions": { - "com.figma.variableId": "VariableID:5807:51", + "com.figma.variableId": "VariableID:2134:336", "com.figma.scopes": [ "STROKE" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:47100d9ee86fe416d640e3829dccf9d1fd680bcf/-1:-1", - "targetVariableName": "color/alpha/white/30", + "targetVariableId": "VariableID:7e4bcc3763b8db1d601b4b96415731b56ca90b8e/-1:-1", + "targetVariableName": "color/gray/050", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, "com.figma.isOverride": true } }, - "inverted": { + "inverse": { "$type": "color", "$value": { "colorSpace": "srgb", @@ -183,6 +157,34 @@ } } }, + "stroke": { + "primary": { + "$type": "color", + "$value": { + "colorSpace": "srgb", + "components": [ + 0.9725490212440491, + 0.9725490212440491, + 0.9686274528503418 + ], + "alpha": 1, + "hex": "#F8F8F7" + }, + "$extensions": { + "com.figma.variableId": "VariableID:6484:4712", + "com.figma.scopes": [ + "STROKE" + ], + "com.figma.aliasData": { + "targetVariableId": "VariableID:7e4bcc3763b8db1d601b4b96415731b56ca90b8e/-1:-1", + "targetVariableName": "color/gray/050", + "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", + "targetVariableSetName": "primitives" + }, + "com.figma.isOverride": true + } + } + }, "icon": { "primary": { "$type": "color", @@ -268,7 +270,7 @@ "com.figma.isOverride": true } }, - "surface": { + "inverse": { "$type": "color", "$value": { "colorSpace": "srgb", @@ -281,7 +283,7 @@ "hex": "#1A1A1A" }, "$extensions": { - "com.figma.variableId": "VariableID:2030:244", + "com.figma.variableId": "VariableID:6485:4717", "com.figma.scopes": [ "FRAME_FILL", "SHAPE_FILL", @@ -407,117 +409,9 @@ }, "com.figma.isOverride": true } - }, - "info-inverted": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 0.07058823853731155, - 0.2980392277240753, - 0.40392157435417175 - ], - "alpha": 1, - "hex": "#124C67" - }, - "$extensions": { - "com.figma.variableId": "VariableID:3153:2799", - "com.figma.scopes": [ - "FRAME_FILL", - "SHAPE_FILL" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:2048070002952b420ba0d97b83538927d6ed1ee0/-1:-1", - "targetVariableName": "color/sky/900", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } - }, - "success-inverted": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 0.07058823853731155, - 0.3333333432674408, - 0.22745098173618317 - ], - "alpha": 1, - "hex": "#12553A" - }, - "$extensions": { - "com.figma.variableId": "VariableID:3153:2798", - "com.figma.scopes": [ - "FRAME_FILL", - "SHAPE_FILL" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:68e28fef5de93581eadd43e51ddee83e454fd827/-1:-1", - "targetVariableName": "color/green/900", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } - }, - "warning-inverted": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 0.48627451062202454, - 0.250980406999588, - 0.04313725605607033 - ], - "alpha": 1, - "hex": "#7C400B" - }, - "$extensions": { - "com.figma.variableId": "VariableID:3153:2797", - "com.figma.scopes": [ - "FRAME_FILL", - "SHAPE_FILL" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:e14374a74b8e0e2a91323ae096be34069d927ba0/-1:-1", - "targetVariableName": "color/yellow/900", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } - }, - "critical-inverted": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 0.545098066329956, - 0.06666667014360428, - 0.06666667014360428 - ], - "alpha": 1, - "hex": "#8B1111" - }, - "$extensions": { - "com.figma.variableId": "VariableID:3153:2796", - "com.figma.scopes": [ - "FRAME_FILL", - "SHAPE_FILL" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:e7f45095ed5b1bb6bee0df2d9c1312b9c2395f3c/-1:-1", - "targetVariableName": "color/red/900", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } } }, - "input": { + "state": { "focus": { "$type": "color", "$value": { @@ -631,12 +525,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 0.1568627506494522, - 0.1568627506494522, - 0.1568627506494522 + 0.06666667014360428, + 0.06666667014360428, + 0.06666667014360428 ], "alpha": 1, - "hex": "#282828" + "hex": "#111111" }, "$extensions": { "com.figma.variableId": "VariableID:2004:345", @@ -645,8 +539,8 @@ "SHAPE_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:937e85be7e92da997173e54ee725a51e35d3a1e7/-1:-1", - "targetVariableName": "color/gray/900", + "targetVariableId": "VariableID:c9e680d26570e06b982ded6dabbc291afdb9ce5c/-1:-1", + "targetVariableName": "color/gray/975", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -658,12 +552,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 0.2392157018184662, - 0.2392157018184662, - 0.2392157018184662 + 0.1568627506494522, + 0.1568627506494522, + 0.1568627506494522 ], "alpha": 1, - "hex": "#3D3D3D" + "hex": "#282828" }, "$extensions": { "com.figma.variableId": "VariableID:2004:346", @@ -672,25 +566,25 @@ "SHAPE_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:c98f70c0d43f49db09a36473679a541b9e1d02e0/-1:-1", - "targetVariableName": "color/gray/800", + "targetVariableId": "VariableID:937e85be7e92da997173e54ee725a51e35d3a1e7/-1:-1", + "targetVariableName": "color/gray/900", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, "com.figma.isOverride": true } }, - "strong": { + "neutral": { "$type": "color", "$value": { "colorSpace": "srgb", "components": [ - 0.39411765336990356, - 0.39411765336990356, - 0.39411765336990356 + 0.2392157018184662, + 0.2392157018184662, + 0.2392157018184662 ], "alpha": 1, - "hex": "#656565" + "hex": "#3D3D3D" }, "$extensions": { "com.figma.variableId": "VariableID:5826:3148", @@ -699,42 +593,15 @@ "SHAPE_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:26119033358fc6f6b53c71c7aa2b14904b8e8e94/-1:-1", - "targetVariableName": "color/gray/600", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } - }, - "elevated": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 0.06666667014360428, - 0.06666667014360428, - 0.06666667014360428 - ], - "alpha": 1, - "hex": "#111111" - }, - "$extensions": { - "com.figma.variableId": "VariableID:2466:13", - "com.figma.scopes": [ - "FRAME_FILL", - "SHAPE_FILL" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:c9e680d26570e06b982ded6dabbc291afdb9ce5c/-1:-1", - "targetVariableName": "color/gray/975", + "targetVariableId": "VariableID:c98f70c0d43f49db09a36473679a541b9e1d02e0/-1:-1", + "targetVariableName": "color/gray/800", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, "com.figma.isOverride": true } }, - "sunken": { + "panel": { "$type": "color", "$value": { "colorSpace": "srgb", @@ -747,7 +614,7 @@ "hex": "#212121" }, "$extensions": { - "com.figma.variableId": "VariableID:2829:672", + "com.figma.variableId": "VariableID:6486:5661", "com.figma.scopes": [ "FRAME_FILL", "SHAPE_FILL" @@ -788,61 +655,7 @@ "com.figma.isOverride": true } }, - "selected": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 0.9529411792755127, - 0.9529411792755127, - 0.9607843160629272 - ], - "alpha": 0.05999999865889549, - "hex": "#F3F3F5" - }, - "$extensions": { - "com.figma.variableId": "VariableID:6468:22", - "com.figma.scopes": [ - "FRAME_FILL", - "SHAPE_FILL" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:ebd1fb7ca8eba565dc36df8260272034d7dd0a00/-1:-1", - "targetVariableName": "color/alpha/temp-white/06", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } - }, - "active": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 0.9529411792755127, - 0.9529411792755127, - 0.9607843160629272 - ], - "alpha": 0.03999999910593033, - "hex": "#F3F3F5" - }, - "$extensions": { - "com.figma.variableId": "VariableID:2785:292", - "com.figma.scopes": [ - "FRAME_FILL", - "SHAPE_FILL" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:0ce4b76aebf3b94a35cee5d62e39c42612556f00/-1:-1", - "targetVariableName": "color/alpha/temp-white/04", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } - }, - "inverted": { + "inverse": { "$type": "color", "$value": { "colorSpace": "srgb", @@ -869,7 +682,7 @@ "com.figma.isOverride": true } }, - "inverted-hover": { + "inverse-hover": { "$type": "color", "$value": { "colorSpace": "srgb", @@ -896,33 +709,6 @@ "com.figma.isOverride": true } }, - "inverted-backdrop": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 0.10980392247438431, - 0.10980392247438431, - 0.10588235408067703 - ], - "alpha": 0.800000011920929, - "hex": "#1C1C1B" - }, - "$extensions": { - "com.figma.variableId": "VariableID:2746:7325", - "com.figma.scopes": [ - "FRAME_FILL", - "SHAPE_FILL" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:ddddc9a05d8abbf20b08764e0b63cc6f1f641e69/-1:-1", - "targetVariableName": "color/alpha/temp-black/80", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } - }, "backdrop": { "$type": "color", "$value": { @@ -1010,11 +796,11 @@ "colorSpace": "srgb", "components": [ 0, - 0.4470588266849518, - 0.8588235378265381 + 0.3529411852359772, + 0.6941176652908325 ], "alpha": 1, - "hex": "#0072DB" + "hex": "#005AB1" }, "$extensions": { "com.figma.variableId": "VariableID:2239:1134", @@ -1023,8 +809,8 @@ "SHAPE_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:698be47ec3d46a209dde801dc11a00aa9aa8e40e/-1:-1", - "targetVariableName": "color/blue/600", + "targetVariableId": "VariableID:c4809d37606c3dffdaedab8b4401e74c0bb2d708/-1:-1", + "targetVariableName": "color/blue/700", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1064,12 +850,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 0, - 0.5529412031173706, - 0.7372549176216125 + 0.0235294122248888, + 0.4431372582912445, + 0.5960784554481506 ], "alpha": 1, - "hex": "#008DBC" + "hex": "#067198" }, "$extensions": { "com.figma.variableId": "VariableID:5827:3167", @@ -1078,8 +864,8 @@ "SHAPE_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:9fd865ff6f23d3a7029b39fdde137a96c974cdc5/-1:-1", - "targetVariableName": "color/sky/600", + "targetVariableId": "VariableID:bb4581a61df584180c284899ef1be68bb1bebde3/-1:-1", + "targetVariableName": "color/sky/700", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1092,11 +878,11 @@ "colorSpace": "srgb", "components": [ 0, - 0.7019608020782471, - 0.8784313797950745 + 0.5529412031173706, + 0.7372549176216125 ], "alpha": 1, - "hex": "#00B3E0" + "hex": "#008DBC" }, "$extensions": { "com.figma.variableId": "VariableID:5827:3168", @@ -1106,8 +892,8 @@ "STROKE" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:8ffaeea2190d3b2de7a38673ab54c0c41740a68f/-1:-1", - "targetVariableName": "color/sky/500", + "targetVariableId": "VariableID:9fd865ff6f23d3a7029b39fdde137a96c974cdc5/-1:-1", + "targetVariableName": "color/sky/600", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1119,12 +905,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 1, + 0.8117647171020508, 0, - 0.8313725590705872 + 0.6549019813537598 ], "alpha": 1, - "hex": "#FF00D4" + "hex": "#CF00A7" }, "$extensions": { "com.figma.variableId": "VariableID:5826:2575", @@ -1133,8 +919,8 @@ "SHAPE_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:a1c73e35a815cb36eccb3ed82a16da66a186ef3c/-1:-1", - "targetVariableName": "color/pink/600", + "targetVariableId": "VariableID:8329de404aa92e82ab800d8fb1f0d4104cc27ffb/-1:-1", + "targetVariableName": "color/pink/700", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1255,12 +1041,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 0.9882352948188782, - 0.729411780834198, - 0.007843137718737125 + 0.8784313797950745, + 0.5647059082984924, + 0 ], "alpha": 1, - "hex": "#FCBA02" + "hex": "#E09000" }, "$extensions": { "com.figma.variableId": "VariableID:5153:20443", @@ -1270,8 +1056,8 @@ "STROKE" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:ec20ecabb72415dc74b582e48619de110d966721/-1:-1", - "targetVariableName": "color/yellow/500", + "targetVariableId": "VariableID:748def0ea8b2301a3a8d95cd01a792c896620bbc/-1:-1", + "targetVariableName": "color/yellow/600", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1412,37 +1198,52 @@ "com.figma.isOverride": true } }, - "muted": { + "inverse": { "$type": "color", - "$value": "{text.secondary}", + "$value": { + "colorSpace": "srgb", + "components": [ + 0.10196078568696976, + 0.10196078568696976, + 0.10196078568696976 + ], + "alpha": 1, + "hex": "#1A1A1A" + }, "$extensions": { - "com.figma.variableId": "VariableID:2240:1241", + "com.figma.variableId": "VariableID:2240:1242", "com.figma.scopes": [ "TEXT_FILL" ], + "com.figma.aliasData": { + "targetVariableId": "VariableID:c665b8dd84425c623e5e4882391ed1d1af732d5b/-1:-1", + "targetVariableName": "color/gray/950", + "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", + "targetVariableSetName": "primitives" + }, "com.figma.isOverride": true } }, - "surface": { + "link": { "$type": "color", "$value": { "colorSpace": "srgb", "components": [ - 0.10196078568696976, - 0.10196078568696976, - 0.10196078568696976 + 0.9411764740943909, + 0.9411764740943909, + 0.9333333373069763 ], "alpha": 1, - "hex": "#1A1A1A" + "hex": "#F0F0EE" }, "$extensions": { - "com.figma.variableId": "VariableID:2240:1242", + "com.figma.variableId": "VariableID:6479:4042", "com.figma.scopes": [ "TEXT_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:c665b8dd84425c623e5e4882391ed1d1af732d5b/-1:-1", - "targetVariableName": "color/gray/950", + "targetVariableId": "VariableID:d2a32c5e61d9ac7d573f0374630508bcdeafb5a1/-1:-1", + "targetVariableName": "color/gray/100", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1584,12 +1385,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 0.06666667014360428, - 0.6627451181411743, - 0.40392157435417175 + 0.5098039507865906, + 0.9529411792755127, + 0.7568627595901489 ], "alpha": 1, - "hex": "#11A967" + "hex": "#82F3C1" }, "$extensions": { "com.figma.variableId": "VariableID:2073:412", @@ -1597,8 +1398,8 @@ "TEXT_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:f1a551855c4076c85898ee9c0068d1420bb04a65/-1:-1", - "targetVariableName": "color/green/600", + "targetVariableId": "VariableID:32676ffcf503fa5c5b7ba44ecc2753414ea1b261/-1:-1", + "targetVariableName": "color/green/300", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1610,12 +1411,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 0.9882352948188782, - 0.729411780834198, - 0.007843137718737125 + 1, + 0.9176470637321472, + 0.27843138575553894 ], "alpha": 1, - "hex": "#FCBA02" + "hex": "#FFEA47" }, "$extensions": { "com.figma.variableId": "VariableID:2239:613", @@ -1623,8 +1424,8 @@ "TEXT_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:ec20ecabb72415dc74b582e48619de110d966721/-1:-1", - "targetVariableName": "color/yellow/500", + "targetVariableId": "VariableID:157cdfbe24dd1eca87bffdd02b199e6995520534/-1:-1", + "targetVariableName": "color/yellow/300", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1636,12 +1437,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 0.9372549057006836, - 0.05098039284348488, - 0.05098039284348488 + 1, + 0.6039215922355652, + 0.6039215922355652 ], "alpha": 1, - "hex": "#EF0D0D" + "hex": "#FF9A9A" }, "$extensions": { "com.figma.variableId": "VariableID:5898:1434", @@ -1649,8 +1450,8 @@ "TEXT_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:987371c0427533fbdfa373c77ead556c26f02c40/-1:-1", - "targetVariableName": "color/red/600", + "targetVariableId": "VariableID:3632fb3c653e982281b840f0f9b8f2993417f88d/-1:-1", + "targetVariableName": "color/red/300", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, diff --git a/tokens/figma/origin/Light.tokens.json b/tokens/figma/origin/Light.tokens.json index c3e280e..aeaa124 100644 --- a/tokens/figma/origin/Light.tokens.json +++ b/tokens/figma/origin/Light.tokens.json @@ -5,21 +5,21 @@ "$value": { "colorSpace": "srgb", "components": [ - 0.10196078568696976, - 0.10196078568696976, - 0.10196078568696976 + 0.14901961386203766, + 0.14901961386203766, + 0.13725490868091583 ], - "alpha": 1, - "hex": "#1A1A1A" + "alpha": 0.10000000149011612, + "hex": "#262623" }, "$extensions": { - "com.figma.variableId": "VariableID:2134:336", + "com.figma.variableId": "VariableID:2004:352", "com.figma.scopes": [ "STROKE" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:c665b8dd84425c623e5e4882391ed1d1af732d5b/-1:-1", - "targetVariableName": "color/gray/950", + "targetVariableId": "VariableID:a4b2cf4e68304ea3fab2ba83b116851a626d70f3/-1:-1", + "targetVariableName": "color/alpha/temp-black/10", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -31,12 +31,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 0.7568627595901489, - 0.7529411911964417, - 0.7215686440467834 + 0.13725490868091583, + 0.13725490868091583, + 0.12941177189350128 ], - "alpha": 1, - "hex": "#C1C0B8" + "alpha": 0.30000001192092896, + "hex": "#232321" }, "$extensions": { "com.figma.variableId": "VariableID:2007:561", @@ -44,67 +44,41 @@ "STROKE" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:578b25ffa2de6df71ceaa98597c65309d914804c/-1:-1", - "targetVariableName": "color/gray/300", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } - }, - "tertiary": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 0, - 0, - 0 - ], - "alpha": 0.10000000149011612, - "hex": "#000000" - }, - "$extensions": { - "com.figma.variableId": "VariableID:2004:352", - "com.figma.scopes": [ - "STROKE" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:45d02e24ccf305b1ab6131c9bb43cbf71c455522/-1:-1", - "targetVariableName": "color/alpha/black/10", + "targetVariableId": "VariableID:3fa774f09e09ed4c1e7bab325f7a2da923e1f612/-1:-1", + "targetVariableName": "color/alpha/temp-black/30", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, "com.figma.isOverride": true } }, - "hover": { + "focus": { "$type": "color", "$value": { "colorSpace": "srgb", "components": [ - 0, - 0, - 0 + 0.10196078568696976, + 0.10196078568696976, + 0.10196078568696976 ], - "alpha": 0.30000001192092896, - "hex": "#000000" + "alpha": 1, + "hex": "#1A1A1A" }, "$extensions": { - "com.figma.variableId": "VariableID:5807:51", + "com.figma.variableId": "VariableID:2134:336", "com.figma.scopes": [ "STROKE" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:f00911dd36cbedcde1f67c3df33728b09a9a4d82/-1:-1", - "targetVariableName": "color/alpha/black/30", + "targetVariableId": "VariableID:c665b8dd84425c623e5e4882391ed1d1af732d5b/-1:-1", + "targetVariableName": "color/gray/950", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, "com.figma.isOverride": true } }, - "inverted": { + "inverse": { "$type": "color", "$value": { "colorSpace": "srgb", @@ -183,6 +157,34 @@ } } }, + "stroke": { + "primary": { + "$type": "color", + "$value": { + "colorSpace": "srgb", + "components": [ + 0.10196078568696976, + 0.10196078568696976, + 0.10196078568696976 + ], + "alpha": 1, + "hex": "#1A1A1A" + }, + "$extensions": { + "com.figma.variableId": "VariableID:6484:4712", + "com.figma.scopes": [ + "STROKE" + ], + "com.figma.aliasData": { + "targetVariableId": "VariableID:c665b8dd84425c623e5e4882391ed1d1af732d5b/-1:-1", + "targetVariableName": "color/gray/950", + "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", + "targetVariableSetName": "primitives" + }, + "com.figma.isOverride": true + } + } + }, "icon": { "primary": { "$type": "color", @@ -268,7 +270,7 @@ "com.figma.isOverride": true } }, - "surface": { + "inverse": { "$type": "color", "$value": { "colorSpace": "srgb", @@ -281,7 +283,7 @@ "hex": "#F8F8F7" }, "$extensions": { - "com.figma.variableId": "VariableID:2030:244", + "com.figma.variableId": "VariableID:6485:4717", "com.figma.scopes": [ "FRAME_FILL", "SHAPE_FILL", @@ -407,117 +409,9 @@ }, "com.figma.isOverride": true } - }, - "info-inverted": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 0.9215686321258545, - 0.9960784316062927, - 1 - ], - "alpha": 1, - "hex": "#EBFEFF" - }, - "$extensions": { - "com.figma.variableId": "VariableID:3153:2799", - "com.figma.scopes": [ - "FRAME_FILL", - "SHAPE_FILL" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:b315b03dc082341c309e52b504ae5ab48c2531a1/-1:-1", - "targetVariableName": "color/sky/050", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } - }, - "success-inverted": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 0.9411764740943909, - 0.9921568632125854, - 0.9686274528503418 - ], - "alpha": 1, - "hex": "#F0FDF7" - }, - "$extensions": { - "com.figma.variableId": "VariableID:3153:2798", - "com.figma.scopes": [ - "FRAME_FILL", - "SHAPE_FILL" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:a2e53f7bc4c4e351a830507b4485f5587bbe6883/-1:-1", - "targetVariableName": "color/green/050", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } - }, - "warning-inverted": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 1, - 0.9921568632125854, - 0.9176470637321472 - ], - "alpha": 1, - "hex": "#FFFDEA" - }, - "$extensions": { - "com.figma.variableId": "VariableID:3153:2797", - "com.figma.scopes": [ - "FRAME_FILL", - "SHAPE_FILL" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:fbccdf24a56637771457eb25529abf02f49e1cc0/-1:-1", - "targetVariableName": "color/yellow/050", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } - }, - "critical-inverted": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 1, - 0.9450980424880981, - 0.9450980424880981 - ], - "alpha": 1, - "hex": "#FFF1F1" - }, - "$extensions": { - "com.figma.variableId": "VariableID:3153:2796", - "com.figma.scopes": [ - "FRAME_FILL", - "SHAPE_FILL" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:257b1c38d63cbce623169b09083361c42061247e/-1:-1", - "targetVariableName": "color/red/050", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } } }, - "input": { + "state": { "focus": { "$type": "color", "$value": { @@ -680,7 +574,7 @@ "com.figma.isOverride": true } }, - "strong": { + "neutral": { "$type": "color", "$value": { "colorSpace": "srgb", @@ -707,7 +601,7 @@ "com.figma.isOverride": true } }, - "elevated": { + "panel": { "$type": "color", "$value": { "colorSpace": "srgb", @@ -720,7 +614,7 @@ "hex": "#FAFAF9" }, "$extensions": { - "com.figma.variableId": "VariableID:2466:13", + "com.figma.variableId": "VariableID:6486:5661", "com.figma.scopes": [ "FRAME_FILL", "SHAPE_FILL" @@ -734,33 +628,6 @@ "com.figma.isOverride": true } }, - "sunken": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 0.95686274766922, - 0.95686274766922, - 0.9529411792755127 - ], - "alpha": 1, - "hex": "#F4F4F3" - }, - "$extensions": { - "com.figma.variableId": "VariableID:2829:672", - "com.figma.scopes": [ - "FRAME_FILL", - "SHAPE_FILL" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:61b52ae1800461efd58637e2884fc5b77e0781c6/-1:-1", - "targetVariableName": "color/gray/075", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } - }, "hover": { "$type": "color", "$value": { @@ -788,61 +655,7 @@ "com.figma.isOverride": true } }, - "selected": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 0.1568627506494522, - 0.1568627506494522, - 0.1411764770746231 - ], - "alpha": 0.05999999865889549, - "hex": "#282824" - }, - "$extensions": { - "com.figma.variableId": "VariableID:6468:22", - "com.figma.scopes": [ - "FRAME_FILL", - "SHAPE_FILL" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:9f65c876c307e2f724b19f0497cc76fd77b4c432/-1:-1", - "targetVariableName": "color/alpha/temp-black/06", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } - }, - "active": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 0.16470588743686676, - 0.16470588743686676, - 0.14509804546833038 - ], - "alpha": 0.03999999910593033, - "hex": "#2A2A25" - }, - "$extensions": { - "com.figma.variableId": "VariableID:2785:292", - "com.figma.scopes": [ - "FRAME_FILL", - "SHAPE_FILL" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:c5ae94e6257cacf90eff1dcea87506d73192f284/-1:-1", - "targetVariableName": "color/alpha/temp-black/04", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } - }, - "inverted": { + "inverse": { "$type": "color", "$value": { "colorSpace": "srgb", @@ -869,7 +682,7 @@ "com.figma.isOverride": true } }, - "inverted-hover": { + "inverse-hover": { "$type": "color", "$value": { "colorSpace": "srgb", @@ -896,33 +709,6 @@ "com.figma.isOverride": true } }, - "inverted-backdrop": { - "$type": "color", - "$value": { - "colorSpace": "srgb", - "components": [ - 0.9725490212440491, - 0.9725490212440491, - 0.9686274528503418 - ], - "alpha": 0.800000011920929, - "hex": "#F8F8F7" - }, - "$extensions": { - "com.figma.variableId": "VariableID:2746:7325", - "com.figma.scopes": [ - "FRAME_FILL", - "SHAPE_FILL" - ], - "com.figma.aliasData": { - "targetVariableId": "VariableID:266d3da38b2173de5ee129e528db76e5cccc6dd1/-1:-1", - "targetVariableName": "color/alpha/temp-white/80", - "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", - "targetVariableSetName": "primitives" - }, - "com.figma.isOverride": true - } - }, "backdrop": { "$type": "color", "$value": { @@ -955,12 +741,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 0.9803921580314636, - 0.9725490212440491, - 0.9882352948188782 + 0.9490196108818054, + 0.9333333373069763, + 0.9764705896377563 ], "alpha": 1, - "hex": "#FAF8FC" + "hex": "#F2EEF9" }, "$extensions": { "com.figma.variableId": "VariableID:5826:2577", @@ -969,8 +755,8 @@ "SHAPE_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:074271b995f26a1712595e6bfc0e1da73db49d75/-1:-1", - "targetVariableName": "color/purple/050", + "targetVariableId": "VariableID:de8d3a9233f6d4cfdf2aa170f20fab6ae099f8c5/-1:-1", + "targetVariableName": "color/purple/100", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1009,12 +795,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 0.9333333373069763, - 0.9686274528503418, + 0.8666666746139526, + 0.9372549057006836, 1 ], "alpha": 1, - "hex": "#EEF7FF" + "hex": "#DDEFFF" }, "$extensions": { "com.figma.variableId": "VariableID:2239:1134", @@ -1023,8 +809,8 @@ "SHAPE_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:445cfaa3ddb2545b8dec69b89102ca220a6c37ab/-1:-1", - "targetVariableName": "color/blue/050", + "targetVariableId": "VariableID:f9b13dc5cf590a8fff89d88f8161678d713bf810/-1:-1", + "targetVariableName": "color/blue/100", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1064,12 +850,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 0.9215686321258545, - 0.9960784316062927, + 0.800000011920929, + 0.9764705896377563, 1 ], "alpha": 1, - "hex": "#EBFEFF" + "hex": "#CCF9FF" }, "$extensions": { "com.figma.variableId": "VariableID:5827:3167", @@ -1078,8 +864,8 @@ "SHAPE_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:b315b03dc082341c309e52b504ae5ab48c2531a1/-1:-1", - "targetVariableName": "color/sky/050", + "targetVariableId": "VariableID:6c7d0a9fbbf8c2a25a5a7018433a41e13412da0e/-1:-1", + "targetVariableName": "color/sky/100", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1120,11 +906,11 @@ "colorSpace": "srgb", "components": [ 1, - 0.9490196108818054, - 0.9843137264251709 + 0.8901960849761963, + 0.9764705896377563 ], "alpha": 1, - "hex": "#FFF2FB" + "hex": "#FFE3F9" }, "$extensions": { "com.figma.variableId": "VariableID:5826:2575", @@ -1133,8 +919,8 @@ "SHAPE_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:8457ecd5987aed0565cb7956a98ba13a44678714/-1:-1", - "targetVariableName": "color/pink/050", + "targetVariableId": "VariableID:5451c8ea50acb7399aa79d30db50e849548c96cf/-1:-1", + "targetVariableName": "color/pink/100", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1173,12 +959,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 0.9411764740943909, + 0.8588235378265381, 0.9921568632125854, - 0.9686274528503418 + 0.9333333373069763 ], "alpha": 1, - "hex": "#F0FDF7" + "hex": "#DBFDEE" }, "$extensions": { "com.figma.variableId": "VariableID:2239:604", @@ -1187,8 +973,8 @@ "SHAPE_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:a2e53f7bc4c4e351a830507b4485f5587bbe6883/-1:-1", - "targetVariableName": "color/green/050", + "targetVariableId": "VariableID:ebb4d29e20e7d5256b12c8973c20fd79b7c963e9/-1:-1", + "targetVariableName": "color/green/100", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1229,11 +1015,11 @@ "colorSpace": "srgb", "components": [ 1, - 0.9921568632125854, - 0.9176470637321472 + 0.9803921580314636, + 0.772549033164978 ], "alpha": 1, - "hex": "#FFFDEA" + "hex": "#FFFAC5" }, "$extensions": { "com.figma.variableId": "VariableID:2239:605", @@ -1242,8 +1028,8 @@ "SHAPE_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:fbccdf24a56637771457eb25529abf02f49e1cc0/-1:-1", - "targetVariableName": "color/yellow/050", + "targetVariableId": "VariableID:979cecd8c4d4b18cdcc1a0383d7a7c8b23c801e4/-1:-1", + "targetVariableName": "color/yellow/100", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1284,11 +1070,11 @@ "colorSpace": "srgb", "components": [ 1, - 0.9450980424880981, - 0.9450980424880981 + 0.7686274647712708, + 0.7686274647712708 ], "alpha": 1, - "hex": "#FFF1F1" + "hex": "#FFC4C4" }, "$extensions": { "com.figma.variableId": "VariableID:2239:606", @@ -1297,8 +1083,8 @@ "SHAPE_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:257b1c38d63cbce623169b09083361c42061247e/-1:-1", - "targetVariableName": "color/red/050", + "targetVariableId": "VariableID:4866205f0dacbcbce03132030e7c66ffbfbac714/-1:-1", + "targetVariableName": "color/red/200", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1412,37 +1198,52 @@ "com.figma.isOverride": true } }, - "muted": { + "inverse": { "$type": "color", - "$value": "{text.secondary}", + "$value": { + "colorSpace": "srgb", + "components": [ + 0.9725490212440491, + 0.9725490212440491, + 0.9686274528503418 + ], + "alpha": 1, + "hex": "#F8F8F7" + }, "$extensions": { - "com.figma.variableId": "VariableID:2240:1241", + "com.figma.variableId": "VariableID:2240:1242", "com.figma.scopes": [ "TEXT_FILL" ], + "com.figma.aliasData": { + "targetVariableId": "VariableID:7e4bcc3763b8db1d601b4b96415731b56ca90b8e/-1:-1", + "targetVariableName": "color/gray/050", + "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", + "targetVariableSetName": "primitives" + }, "com.figma.isOverride": true } }, - "surface": { + "link": { "$type": "color", "$value": { "colorSpace": "srgb", "components": [ - 0.9725490212440491, - 0.9725490212440491, - 0.9686274528503418 + 0.10196078568696976, + 0.10196078568696976, + 0.10196078568696976 ], "alpha": 1, - "hex": "#F8F8F7" + "hex": "#1A1A1A" }, "$extensions": { - "com.figma.variableId": "VariableID:2240:1242", + "com.figma.variableId": "VariableID:6479:4042", "com.figma.scopes": [ "TEXT_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:7e4bcc3763b8db1d601b4b96415731b56ca90b8e/-1:-1", - "targetVariableName": "color/gray/050", + "targetVariableId": "VariableID:c665b8dd84425c623e5e4882391ed1d1af732d5b/-1:-1", + "targetVariableName": "color/gray/950", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1532,12 +1333,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 0, - 0.7019608020782471, - 0.8784313797950745 + 0.0235294122248888, + 0.4431372582912445, + 0.5960784554481506 ], "alpha": 1, - "hex": "#00B3E0" + "hex": "#067198" }, "$extensions": { "com.figma.variableId": "VariableID:5827:3169", @@ -1545,8 +1346,8 @@ "TEXT_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:8ffaeea2190d3b2de7a38673ab54c0c41740a68f/-1:-1", - "targetVariableName": "color/sky/500", + "targetVariableId": "VariableID:bb4581a61df584180c284899ef1be68bb1bebde3/-1:-1", + "targetVariableName": "color/sky/700", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1558,12 +1359,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 1, + 0.8117647171020508, 0, - 0.8313725590705872 + 0.6549019813537598 ], "alpha": 1, - "hex": "#FF00D4" + "hex": "#CF00A7" }, "$extensions": { "com.figma.variableId": "VariableID:2029:234", @@ -1571,8 +1372,8 @@ "TEXT_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:a1c73e35a815cb36eccb3ed82a16da66a186ef3c/-1:-1", - "targetVariableName": "color/pink/600", + "targetVariableId": "VariableID:8329de404aa92e82ab800d8fb1f0d4104cc27ffb/-1:-1", + "targetVariableName": "color/pink/700", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1585,11 +1386,11 @@ "colorSpace": "srgb", "components": [ 0.06666667014360428, - 0.6627451181411743, - 0.40392157435417175 + 0.5176470875740051, + 0.32549020648002625 ], "alpha": 1, - "hex": "#11A967" + "hex": "#118453" }, "$extensions": { "com.figma.variableId": "VariableID:2073:412", @@ -1597,8 +1398,8 @@ "TEXT_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:f1a551855c4076c85898ee9c0068d1420bb04a65/-1:-1", - "targetVariableName": "color/green/600", + "targetVariableId": "VariableID:88ae130206d1865f3ab670c3fac48af48a2f2b33/-1:-1", + "targetVariableName": "color/green/700", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1610,12 +1411,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 0.8784313797950745, - 0.5647059082984924, - 0 + 0.729411780834198, + 0.4000000059604645, + 0.0117647061124444 ], "alpha": 1, - "hex": "#E09000" + "hex": "#BA6603" }, "$extensions": { "com.figma.variableId": "VariableID:2239:613", @@ -1623,8 +1424,8 @@ "TEXT_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:748def0ea8b2301a3a8d95cd01a792c896620bbc/-1:-1", - "targetVariableName": "color/yellow/600", + "targetVariableId": "VariableID:2b510fa1b6bd2ce897b5093aa705d574d99aa3d9/-1:-1", + "targetVariableName": "color/yellow/700", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, @@ -1636,12 +1437,12 @@ "$value": { "colorSpace": "srgb", "components": [ - 0.9372549057006836, - 0.05098039284348488, - 0.05098039284348488 + 0.800000011920929, + 0.03529411926865578, + 0.03529411926865578 ], "alpha": 1, - "hex": "#EF0D0D" + "hex": "#CC0909" }, "$extensions": { "com.figma.variableId": "VariableID:5898:1434", @@ -1649,8 +1450,8 @@ "TEXT_FILL" ], "com.figma.aliasData": { - "targetVariableId": "VariableID:987371c0427533fbdfa373c77ead556c26f02c40/-1:-1", - "targetVariableName": "color/red/600", + "targetVariableId": "VariableID:75c28b199c2fc26651a0286dc72377b2616886ad/-1:-1", + "targetVariableName": "color/red/700", "targetVariableSetId": "VariableCollectionId:adf8a2cf9464a08e3c0fc9ba15cff9e85ce1d417/-1:-1", "targetVariableSetName": "primitives" }, From 7dc110e9a6d06f7eb69cd471fa75f7e6ae224ee6 Mon Sep 17 00:00:00 2001 From: jaymantri Date: Thu, 26 Feb 2026 22:30:00 -0800 Subject: [PATCH 2/3] Add Collapsible component wrapping Base UI primitive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Single-panel show/hide component — simpler alternative to Accordion for standalone sections like advanced settings or optional details. - Root, Trigger, Panel parts following compound component pattern - Default chevron icon with hideIcon and icon override props - Animated height transition matching Accordion (200ms ease-out) - Reduced motion support - Analytics tracking via analyticsName prop - 12 Playwright CT tests covering core, keyboard, controlled, disabled - Storybook stories for all variants - Exported from package index Made-with: Cursor --- .../Collapsible/Collapsible.module.scss | 80 ++++++++++ .../Collapsible/Collapsible.stories.tsx | 88 +++++++++++ .../Collapsible/Collapsible.test-stories.tsx | 55 +++++++ .../Collapsible/Collapsible.test.tsx | 139 ++++++++++++++++++ src/components/Collapsible/index.ts | 9 ++ src/components/Collapsible/parts.tsx | 73 +++++++++ src/index.ts | 6 + 7 files changed, 450 insertions(+) create mode 100644 src/components/Collapsible/Collapsible.module.scss create mode 100644 src/components/Collapsible/Collapsible.stories.tsx create mode 100644 src/components/Collapsible/Collapsible.test-stories.tsx create mode 100644 src/components/Collapsible/Collapsible.test.tsx create mode 100644 src/components/Collapsible/index.ts create mode 100644 src/components/Collapsible/parts.tsx diff --git a/src/components/Collapsible/Collapsible.module.scss b/src/components/Collapsible/Collapsible.module.scss new file mode 100644 index 0000000..9693516 --- /dev/null +++ b/src/components/Collapsible/Collapsible.module.scss @@ -0,0 +1,80 @@ +@use '../../tokens/text-styles' as *; + +.root { + display: flex; + flex-direction: column; + width: 100%; +} + +.trigger { + display: flex; + align-items: center; + gap: var(--spacing-xs); + width: 100%; + padding: var(--spacing-md) 0; + background: transparent; + border: none; + cursor: pointer; + text-align: left; + + &:focus-visible { + outline: 2px solid var(--state-focus); + outline-offset: -2px; + } + + &[data-disabled] { + cursor: default; + opacity: 0.5; + } +} + +.label { + flex: 1; + @include label; + color: var(--text-primary); +} + +@media (hover: hover) { + .trigger:not([data-disabled]):hover .label { + text-decoration: underline; + } +} + +.icon { + flex-shrink: 0; + display: flex; + width: 24px; + height: 24px; + color: var(--icon-primary); + transition: transform 200ms ease; + + @media (prefers-reduced-motion: reduce) { + transition: none; + } +} + +.root[data-open] .icon { + transform: rotate(180deg); +} + +.panel { + width: 100%; + height: var(--collapsible-panel-height); + overflow: hidden; + transition: height 200ms ease-out; + + &[data-starting-style], + &[data-ending-style] { + height: 0; + } + + @media (prefers-reduced-motion: reduce) { + transition: none; + } +} + +.content { + padding-bottom: var(--spacing-sm); + @include body; + color: var(--text-primary); +} diff --git a/src/components/Collapsible/Collapsible.stories.tsx b/src/components/Collapsible/Collapsible.stories.tsx new file mode 100644 index 0000000..12a5932 --- /dev/null +++ b/src/components/Collapsible/Collapsible.stories.tsx @@ -0,0 +1,88 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { useState } from 'react'; +import { Collapsible } from './index'; +import { CentralIcon } from '../Icon'; + +const meta: Meta = { + title: 'Components/Collapsible', + component: Collapsible.Root, +}; + +export default meta; + +export const Default: StoryObj = { + render: () => ( + + Advanced settings + + These settings are for experienced users. Adjust with caution. + + + ), +}; + +export const DefaultOpen: StoryObj = { + render: () => ( + + Details + + This panel starts open by default. + + + ), +}; + +export const Disabled: StoryObj = { + render: () => ( + + Cannot toggle + + This content is locked. + + + ), +}; + +export const HideIcon: StoryObj = { + render: () => ( + + Show more + + The trigger has no chevron icon. + + + ), +}; + +export const CustomIcon: StoryObj = { + render: () => ( + + }> + Expand section + + + A custom icon replaces the default chevron. + + + ), +}; + +export const Controlled: StoryObj = { + render: function Render() { + const [open, setOpen] = useState(false); + + return ( +
+
+ State: {open ? 'open' : 'closed'} +
+ + Controlled collapsible + + The open state is controlled externally. + + +
+ ); + }, +}; diff --git a/src/components/Collapsible/Collapsible.test-stories.tsx b/src/components/Collapsible/Collapsible.test-stories.tsx new file mode 100644 index 0000000..641c19b --- /dev/null +++ b/src/components/Collapsible/Collapsible.test-stories.tsx @@ -0,0 +1,55 @@ +import { useState } from 'react'; +import { Collapsible } from './index'; + +export const TestDefault = () => ( + + Toggle content + Panel content + +); + +export const TestDefaultOpen = () => ( + + Toggle content + Panel content + +); + +export const TestDisabled = () => ( + + Toggle content + Should not open + +); + +export const TestHideIcon = () => ( + + Toggle content + Panel content + +); + +export const TestCustomIcon = () => ( + + +}> + Toggle content + + Panel content + +); + +export const TestControlled = ({ onChange }: { onChange?: (open: boolean) => void }) => { + const [open, setOpen] = useState(false); + return ( + { + setOpen(v); + onChange?.(v); + }} + > + Toggle content + Panel content + + ); +}; diff --git a/src/components/Collapsible/Collapsible.test.tsx b/src/components/Collapsible/Collapsible.test.tsx new file mode 100644 index 0000000..3496d9b --- /dev/null +++ b/src/components/Collapsible/Collapsible.test.tsx @@ -0,0 +1,139 @@ +import { test, expect } from '@playwright/experimental-ct-react'; +import { + TestDefault, + TestDefaultOpen, + TestDisabled, + TestHideIcon, + TestCustomIcon, + TestControlled, +} from './Collapsible.test-stories'; + +test.describe('Collapsible', () => { + test.describe('Core', () => { + test('has no accessibility violations', async ({ mount, page }) => { + await mount(); + const AxeBuilder = (await import('@axe-core/playwright')).default; + const results = await new AxeBuilder({ page }) + .exclude('html') + .disableRules(['landmark-one-main', 'page-has-heading-one', 'region']) + .analyze(); + expect(results.violations).toEqual([]); + }); + + test('renders closed by default', async ({ mount }) => { + const component = await mount(); + const trigger = component.getByRole('button', { name: 'Toggle content' }); + const panel = component.getByText('Panel content'); + + await expect(trigger).toBeVisible(); + await expect(panel).toBeHidden(); + }); + + test('opens panel on click', async ({ mount }) => { + const component = await mount(); + const trigger = component.getByRole('button', { name: 'Toggle content' }); + const panel = component.getByText('Panel content'); + + await trigger.click(); + await expect(panel).toBeVisible(); + }); + + test('closes panel on second click', async ({ mount }) => { + const component = await mount(); + const trigger = component.getByRole('button', { name: 'Toggle content' }); + const panel = component.getByText('Panel content'); + + await trigger.click(); + await expect(panel).toBeVisible(); + await trigger.click(); + await expect(panel).toBeHidden(); + }); + + test('respects prefers-reduced-motion', async ({ mount, page }) => { + await page.emulateMedia({ reducedMotion: 'reduce' }); + const component = await mount(); + const iconWrapper = component.locator('button span').last(); + const transition = await iconWrapper.evaluate((el) => + window.getComputedStyle(el).transition + ); + expect(transition).toMatch(/none|all 0s/); + }); + }); + + test.describe('defaultOpen', () => { + test('renders open on mount', async ({ mount }) => { + const component = await mount(); + const panel = component.getByText('Panel content'); + + await expect(panel).toBeVisible(); + }); + }); + + test.describe('disabled', () => { + test('cannot be expanded', async ({ mount }) => { + const component = await mount(); + const trigger = component.getByRole('button', { name: 'Toggle content' }); + const panel = component.getByText('Should not open'); + + await trigger.click({ force: true }); + await expect(panel).toBeHidden(); + }); + }); + + test.describe('hideIcon', () => { + test('hides the default chevron', async ({ mount }) => { + const component = await mount(); + const trigger = component.getByRole('button', { name: 'Toggle content' }); + const svg = trigger.locator('svg'); + + await expect(svg).toHaveCount(0); + }); + }); + + test.describe('custom icon', () => { + test('renders custom icon instead of chevron', async ({ mount }) => { + const component = await mount(); + const customIcon = component.getByTestId('custom-icon'); + + await expect(customIcon).toBeVisible(); + }); + }); + + test.describe('Keyboard', () => { + test('Enter toggles panel', async ({ mount, page }) => { + const component = await mount(); + const trigger = component.getByRole('button', { name: 'Toggle content' }); + const panel = component.getByText('Panel content'); + + await trigger.focus(); + await page.keyboard.press('Enter'); + await expect(panel).toBeVisible(); + }); + + test('Space toggles panel', async ({ mount, page }) => { + const component = await mount(); + const trigger = component.getByRole('button', { name: 'Toggle content' }); + const panel = component.getByText('Panel content'); + + await trigger.focus(); + await page.keyboard.press('Space'); + await expect(panel).toBeVisible(); + }); + }); + + test.describe('controlled mode', () => { + test('open/onOpenChange controls state', async ({ mount }) => { + let lastOpen: boolean = false; + const component = await mount( + (lastOpen = v)} /> + ); + const trigger = component.getByRole('button', { name: 'Toggle content' }); + const panel = component.getByText('Panel content'); + + await expect(panel).toBeHidden(); + await trigger.click(); + await expect(panel).toBeVisible(); + expect(lastOpen).toBe(true); + }); + }); +}); diff --git a/src/components/Collapsible/index.ts b/src/components/Collapsible/index.ts new file mode 100644 index 0000000..84d25f0 --- /dev/null +++ b/src/components/Collapsible/index.ts @@ -0,0 +1,9 @@ +import * as Collapsible from './parts'; + +export { Collapsible }; + +export type { + RootProps as CollapsibleRootProps, + TriggerProps as CollapsibleTriggerProps, + PanelProps as CollapsiblePanelProps, +} from './parts'; diff --git a/src/components/Collapsible/parts.tsx b/src/components/Collapsible/parts.tsx new file mode 100644 index 0000000..9adcf40 --- /dev/null +++ b/src/components/Collapsible/parts.tsx @@ -0,0 +1,73 @@ +'use client'; + +import * as React from 'react'; +import { Collapsible as BaseCollapsible } from '@base-ui/react/collapsible'; +import { CentralIcon } from '../Icon'; +import { useTrackedCallback } from '../Analytics/useTrackedCallback'; +import clsx from 'clsx'; +import styles from './Collapsible.module.scss'; + +export interface RootProps extends BaseCollapsible.Root.Props { + analyticsName?: string; +} + +export const Root = React.forwardRef( + function Root({ className, analyticsName, onOpenChange, ...props }, ref) { + const trackedChange = useTrackedCallback( + analyticsName, + 'Collapsible', + 'change', + onOpenChange, + (open: unknown) => ({ open }), + ); + + return ( + + ); + } +); + +export interface TriggerProps extends BaseCollapsible.Trigger.Props { + hideIcon?: boolean; + icon?: React.ReactNode; +} + +export const Trigger = React.forwardRef( + function Trigger({ className, children, hideIcon, icon, ...props }, ref) { + return ( + + {children} + {!hideIcon && ( + + {icon ?? } + + )} + + ); + } +); + +export interface PanelProps extends BaseCollapsible.Panel.Props {} + +export const Panel = React.forwardRef( + function Panel({ className, children, ...props }, ref) { + return ( + +
{children}
+
+ ); + } +); diff --git a/src/index.ts b/src/index.ts index 3d547ab..5d34999 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,6 +16,12 @@ export { AlertDialog } from './components/AlertDialog'; export { Autocomplete } from './components/Autocomplete'; export { Breadcrumb } from './components/Breadcrumb'; export { Card } from './components/Card'; +export { Collapsible } from './components/Collapsible'; +export type { + CollapsibleRootProps, + CollapsibleTriggerProps, + CollapsiblePanelProps, +} from './components/Collapsible'; export { Checkbox } from './components/Checkbox'; export { Command } from './components/Command'; export { Combobox } from './components/Combobox'; From 787c93de0e579a8c1421e661b98e5439202f804e Mon Sep 17 00:00:00 2001 From: jaymantri Date: Thu, 26 Feb 2026 23:24:05 -0800 Subject: [PATCH 3/3] Add Drawer and PreviewCard components wrapping Base UI primitives Both follow the compound component pattern with analytics tracking, display names, and direction-aware CSS (Drawer handles bottom/left/right via data-swipe-direction). Demo page sections alphabetized. Code review fixes: unified index.ts namespace pattern across all three components, added Collapsible displayName and useTrackedOpenChange, removed no-op box-shadow transition from Drawer, added JSDoc to Collapsible.Trigger documenting inner span structure, made PreviewCard max-width configurable via --preview-card-max-width custom property. Made-with: Cursor --- src/app/page.tsx | 2572 +++++++++-------- src/components/Collapsible/parts.tsx | 27 +- src/components/Drawer/Drawer.module.scss | 159 + src/components/Drawer/Drawer.stories.tsx | 87 + src/components/Drawer/Drawer.test-stories.tsx | 88 + src/components/Drawer/Drawer.test.tsx | 102 + src/components/Drawer/index.ts | 63 + src/components/Drawer/parts.tsx | 186 ++ .../PreviewCard/PreviewCard.module.scss | 65 + .../PreviewCard/PreviewCard.stories.tsx | 98 + .../PreviewCard/PreviewCard.test-stories.tsx | 58 + .../PreviewCard/PreviewCard.test.tsx | 67 + src/components/PreviewCard/index.ts | 35 + src/components/PreviewCard/parts.tsx | 82 + src/index.ts | 25 + 15 files changed, 2477 insertions(+), 1237 deletions(-) create mode 100644 src/components/Drawer/Drawer.module.scss create mode 100644 src/components/Drawer/Drawer.stories.tsx create mode 100644 src/components/Drawer/Drawer.test-stories.tsx create mode 100644 src/components/Drawer/Drawer.test.tsx create mode 100644 src/components/Drawer/index.ts create mode 100644 src/components/Drawer/parts.tsx create mode 100644 src/components/PreviewCard/PreviewCard.module.scss create mode 100644 src/components/PreviewCard/PreviewCard.stories.tsx create mode 100644 src/components/PreviewCard/PreviewCard.test-stories.tsx create mode 100644 src/components/PreviewCard/PreviewCard.test.tsx create mode 100644 src/components/PreviewCard/index.ts create mode 100644 src/components/PreviewCard/parts.tsx diff --git a/src/app/page.tsx b/src/app/page.tsx index f175318..c0675ed 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -3,11 +3,13 @@ import * as React from 'react'; import { matchSorter } from 'match-sorter'; import { Accordion } from '@/components/Accordion'; +import { Collapsible } from '@/components/Collapsible'; import { ActionBar, ActionBarLabel, ActionBarActions } from '@/components/ActionBar'; import { Autocomplete } from '@/components/Autocomplete'; import { Alert } from '@/components/Alert'; import { AlertDialog } from '@/components/AlertDialog'; import { Dialog } from '@/components/Dialog'; +import { Drawer } from '@/components/Drawer'; import { Badge } from '@/components/Badge'; import { Breadcrumb } from '@/components/Breadcrumb'; import { Button } from '@/components/Button'; @@ -56,6 +58,7 @@ import { import { Toast, ToastVariant } from '@/components/Toast'; import { Tooltip } from '@/components/Tooltip'; import { Popover } from '@/components/Popover'; +import { PreviewCard } from '@/components/PreviewCard'; import { Logo } from '@/components/Logo'; import { Toggle, ToggleGroup } from '@/components/Toggle'; // Data for combobox examples @@ -1536,6 +1539,92 @@ function LiveDemo() { ); } +const drawerRequests = [ + { id: 'ck8qs-177', method: 'GET', path: '/customers', status: 200, duration: '314ms', host: 'grid-k507nwxq0.vercel.app', cache: 'HIT' }, + { id: 'ck8qs-178', method: 'POST', path: '/transactions', status: 201, duration: '892ms', host: 'grid-k507nwxq0.vercel.app', cache: 'MISS' }, + { id: 'ck8qs-179', method: 'GET', path: '/fees', status: 200, duration: '156ms', host: 'grid-k507nwxq0.vercel.app', cache: 'HIT' }, +]; + +function DrawerDemo() { + const [selected, setSelected] = React.useState(null); + + return ( +
+ + + + + + + + + + + {drawerRequests.map((req) => ( + setSelected(req)} + style={{ borderBottom: 'var(--stroke-xs) solid var(--border-primary)', cursor: 'pointer' }} + onMouseOver={(e) => { e.currentTarget.style.backgroundColor = 'var(--surface-hover)'; }} + onMouseOut={(e) => { e.currentTarget.style.backgroundColor = ''; }} + > + + + + + + ))} + +
MethodPathStatusDuration
{req.method}{req.path} + {req.status} + {req.duration}
+ + { if (!open) setSelected(null); }} swipeDirection="right"> + + + + + {selected && ( + <> +
+ + {selected.method} {selected.path} + +
+ {selected.status} + }> + + +
+
+ +
+
+ {[ + ['Request ID', selected.id], + ['Path', selected.path], + ['Host', selected.host], + ['Duration', selected.duration], + ['Cache', selected.cache], + ].map(([label, value]) => ( +
+ {label} + {value} +
+ ))} +
+
+
+ + )} +
+
+
+
+
+ ); +} + export default function Home() { return (
@@ -1577,7 +1666,6 @@ export default function Home() { -

Action Bar Component

@@ -1605,7 +1693,6 @@ export default function Home() {
-

Alert Component

@@ -1614,7 +1701,6 @@ export default function Home() {
-

Alert Dialog Component

@@ -1664,76 +1750,9 @@ export default function Home() {
- -

Dialog Component

- -
- - }> - Open Dialog - - - - - - - Dialog Title - - This is a description of the dialog content. - - - -

- Dialog content goes here. This area can contain forms, text, or any other content. -

-
- - }> - Cancel - - - -
-
-
- - - }> - Without Close Button - - - - - - No Close Button - - This dialog does not have an X close button. - - - -

- The user must use the footer buttons or press Escape to close. -

-
- - }> - Cancel - - }> - Done - - -
-
-
-
-

Autocomplete Component

-

Badge Component

@@ -1760,7 +1779,6 @@ export default function Home() { Label
-

Breadcrumb Component

@@ -1818,7 +1836,6 @@ export default function Home() {
-

Button Component

{/* Variants */} @@ -1871,7 +1888,6 @@ export default function Home() { -

Button Group

@@ -1933,247 +1949,462 @@ export default function Home() {
+

Card Component

+ +
+ + + + Structured + With card surface + + + +

Body content with sectioned layout.

+
+ + + +
-

Textarea

+ + + Simple + No card surface + + +

Body content with uniform padding.

+
+ +
+
+

Charts

-
-
- - Default - -