Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/mosaic-color-adoption.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@clerk/mosaic': patch
---

Controls such as inputs, selects, checkboxes, radios and outline buttons keep the stronger `--cl-color-border`, while containers and dividers (cards, sections, tables, menus, the profile nav) use `--cl-color-border-subtle`. Outline buttons fill with the surface color and lay their hover and pressed tint over it, so the tint works on the page, the surface or a faded fill. Banners, badges, toasts and the tag-input error use the `-subtle` and `-border` tokens, and the neutral badge and banner use `--cl-color-neutral-subtle`. The negative color is slightly deeper in light mode for contrast.
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const styles = stylex.create({
marginBlock: space['1'],
marginInline: space['0.5'],
alignSelf: 'stretch',
backgroundColor: colorVars['--cl-color-border'],
backgroundColor: colorVars['--cl-color-border-subtle'],
width: '1px',
},
});
2 changes: 1 addition & 1 deletion packages/mosaic/src/components/avatar/avatar.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export const styles = stylex.create({
},

icon: {
borderColor: colorVars['--cl-color-border'],
borderColor: colorVars['--cl-color-border-subtle'],
borderRadius: radiusVars['--cl-radius-full'],
borderStyle: 'solid',
borderWidth: '1px',
Expand Down
11 changes: 4 additions & 7 deletions packages/mosaic/src/components/badge/badge.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@ import * as stylex from '@stylexjs/stylex';

import { colorVars, fontFamilyVars, fontWeightVars, radiusVars, space, typeScaleVars } from '../../tokens.stylex';

// warning/negative/positive fill with the subtle surface and use the saturated token as text;
// primary fills with the solid token and uses its `-foreground` for text.
//
// Neutral has no subtle surface to fill — `--cl-color-foreground-secondary` is a text gray, and its
// `-foreground` is a text color rather than an on-fill one, so it is unreadable against the solid
// 900. It rides the same neutral scrim the button's neutral fill does.
// Every color but primary fills with its `-subtle` token and uses the saturated token as text;
// primary fills with the solid token and uses its `-foreground` for text. Every `-subtle` is a
// wash, so the chip stays visible on the page, the surface and the faded surface alike.
export const styles = stylex.create({
base: {
borderRadius: radiusVars['--cl-radius-full'],
Expand All @@ -33,7 +30,7 @@ export const colors = stylex.create({
color: colorVars['--cl-color-brand-foreground'],
},
neutral: {
backgroundColor: colorVars['--cl-color-neutral-alpha-100'],
backgroundColor: colorVars['--cl-color-neutral-subtle'],
color: colorVars['--cl-color-foreground'],
},
warning: {
Expand Down
2 changes: 1 addition & 1 deletion packages/mosaic/src/components/banner/banner.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const styles = stylex.create({
export const rootColors = stylex.create({
neutral: {
borderColor: colorVars['--cl-color-border'],
backgroundColor: colorVars['--cl-color-neutral-alpha-100'],
backgroundColor: colorVars['--cl-color-neutral-subtle'],
},
warning: {
borderColor: colorVars['--cl-color-warning-border'],
Expand Down
51 changes: 30 additions & 21 deletions packages/mosaic/src/components/button/button.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,20 @@ import {
import { iconScope } from '../icon/icon.markers.stylex';

// Neutral fills are the three neutral alpha steps, shared across variants:
// 100 — `filled-neutral` rest, `outline-*`/`ghost-*` hover
// 200 — `filled-neutral` hover, `outline-*`/`ghost-*` pressed
// 100 — `filled-neutral` rest, `ghost-*` hover
// 200 — `filled-neutral` hover, `ghost-*` pressed
// 300 — `filled-neutral` pressed

// Opaque fills blend toward their own on-fill at the same 12%/18%. Neutral has no fill
// to blend from, so it rides the opacity ramp above.
// Outline variants keep the surface as their fill and lay the hover and pressed wash over it as an
// inset shadow, so the state tint works on any backdrop and still transitions.
const primaryHover = `color-mix(in oklab, ${colorVars['--cl-color-brand']}, ${colorVars['--cl-color-brand-foreground']} 12%)`;
const primaryActive = `color-mix(in oklab, ${colorVars['--cl-color-brand']}, ${colorVars['--cl-color-brand-foreground']} 18%)`;
const neutralHoverWash = `inset 0 0 0 100vmax ${colorVars['--cl-color-neutral-alpha-100']}`;
const neutralPressedWash = `inset 0 0 0 100vmax ${colorVars['--cl-color-neutral-alpha-200']}`;
const negativeHoverWash = `inset 0 0 0 100vmax ${colorVars['--cl-color-negative-alpha-200']}`;
const negativePressedWash = `inset 0 0 0 100vmax ${colorVars['--cl-color-negative-alpha-300']}`;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

hmm, not sure we want to be doing this for a hover effect. any strong reason not to use color mix to achieve this hover state?

const negativeHover = `color-mix(in oklab, ${colorVars['--cl-color-negative']}, ${colorVars['--cl-color-negative-foreground']} 12%)`;
const negativeActive = `color-mix(in oklab, ${colorVars['--cl-color-negative']}, ${colorVars['--cl-color-negative-foreground']} 18%)`;

Expand Down Expand Up @@ -75,7 +81,7 @@ export const styles = stylex.create({
':not([data-disabled]):active': durationVars['--cl-duration-instant'],
':not([data-disabled]):hover': durationVars['--cl-duration-instant'],
},
transitionProperty: 'background-color, border-color, color, opacity, text-decoration-color',
transitionProperty: 'background-color, border-color, box-shadow, color, opacity, text-decoration-color',
// Linear, not `--cl-ease-default`: nothing here moves. An ease on already non-uniform
// color interpolation just drags the midpoint, and the house curve's overshoot would
// extrapolate past the target color.
Expand Down Expand Up @@ -181,39 +187,42 @@ export const variants = stylex.create({
// fill, and leaves it independently themeable.
'outline-primary': {
borderColor: colorVars['--cl-color-border'],
backgroundColor: {
default: 'transparent',
':not([data-disabled]):active': colorVars['--cl-color-neutral-alpha-200'],
':not([data-disabled])[data-open]': colorVars['--cl-color-neutral-alpha-200'],
backgroundColor: colorVars['--cl-color-surface'],
boxShadow: {
default: null,
':not([data-disabled]):active': neutralPressedWash,
':not([data-disabled])[data-open]': neutralPressedWash,
'@media (hover: hover)': {
default: null,
':not([data-disabled]):hover:not(:active):not([data-open])': colorVars['--cl-color-neutral-alpha-100'],
':not([data-disabled]):hover:not(:active):not([data-open])': neutralHoverWash,
},
},
color: colorVars['--cl-color-brand'],
},
'outline-neutral': {
borderColor: colorVars['--cl-color-border'],
backgroundColor: {
default: 'transparent',
':not([data-disabled]):active': colorVars['--cl-color-neutral-alpha-200'],
':not([data-disabled])[data-open]': colorVars['--cl-color-neutral-alpha-200'],
backgroundColor: colorVars['--cl-color-surface'],
boxShadow: {
default: null,
':not([data-disabled]):active': neutralPressedWash,
':not([data-disabled])[data-open]': neutralPressedWash,
'@media (hover: hover)': {
default: null,
':not([data-disabled]):hover:not(:active):not([data-open])': colorVars['--cl-color-neutral-alpha-100'],
':not([data-disabled]):hover:not(:active):not([data-open])': neutralHoverWash,
},
},
color: colorVars['--cl-color-foreground'],
},
'outline-negative': {
borderColor: colorVars['--cl-color-border'],
backgroundColor: {
default: 'transparent',
':not([data-disabled]):active': colorVars['--cl-color-neutral-alpha-200'],
':not([data-disabled])[data-open]': colorVars['--cl-color-neutral-alpha-200'],
backgroundColor: colorVars['--cl-color-surface'],
boxShadow: {
default: null,
':not([data-disabled]):active': negativePressedWash,
':not([data-disabled])[data-open]': negativePressedWash,
'@media (hover: hover)': {
default: null,
':not([data-disabled]):hover:not(:active):not([data-open])': colorVars['--cl-color-neutral-alpha-100'],
':not([data-disabled]):hover:not(:active):not([data-open])': negativeHoverWash,
},
},
color: colorVars['--cl-color-negative'],
Expand Down Expand Up @@ -248,11 +257,11 @@ export const variants = stylex.create({
'ghost-negative': {
backgroundColor: {
default: 'transparent',
':not([data-disabled]):active': `color-mix(in oklab, ${colorVars['--cl-color-negative-subtle']}, ${colorVars['--cl-color-negative']} 8%)`,
':not([data-disabled])[data-open]': `color-mix(in oklab, ${colorVars['--cl-color-negative-subtle']}, ${colorVars['--cl-color-negative']} 8%)`,
':not([data-disabled]):active': colorVars['--cl-color-negative-alpha-300'],
':not([data-disabled])[data-open]': colorVars['--cl-color-negative-alpha-300'],
'@media (hover: hover)': {
default: null,
':not([data-disabled]):hover:not(:active):not([data-open])': colorVars['--cl-color-negative-subtle'],
':not([data-disabled]):hover:not(:active):not([data-open])': colorVars['--cl-color-negative-alpha-200'],
},
},
color: colorVars['--cl-color-negative'],
Expand Down
4 changes: 2 additions & 2 deletions packages/mosaic/src/components/card/card.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ export const footer = stylex.create({
flexShrink: 0,
gridTemplateColumns: { [compactCard]: 'minmax(0, 1fr)', default: null },
justifyContent: 'space-between',
borderTopColor: colorVars['--cl-color-border'],
borderTopColor: colorVars['--cl-color-border-subtle'],
borderTopStyle: 'solid',
borderTopWidth: {
default: '0px',
Expand All @@ -202,7 +202,7 @@ export const branding = stylex.create({
base: {
paddingBlock: space['3'],
paddingInline: space['6'],
borderBlockStartColor: colorVars['--cl-color-border'],
borderBlockStartColor: colorVars['--cl-color-border-subtle'],
borderBlockStartStyle: 'solid',
borderBlockStartWidth: '1px',
display: 'flex',
Expand Down
4 changes: 2 additions & 2 deletions packages/mosaic/src/components/data-list/data-list.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { colorVars, fontWeightVars, radiusVars, space, typeScaleVars } from '../

export const list = stylex.create({
base: {
borderColor: colorVars['--cl-color-border'],
borderColor: colorVars['--cl-color-border-subtle'],
borderRadius: radiusVars['--cl-radius-lg'],
borderStyle: 'solid',
borderWidth: '1px',
Expand All @@ -25,7 +25,7 @@ export const item = stylex.create({
justifyContent: 'space-between',
},
divided: {
borderBlockEndColor: colorVars['--cl-color-border'],
borderBlockEndColor: colorVars['--cl-color-border-subtle'],
borderBlockEndStyle: 'solid',
borderBlockEndWidth: {
default: '1px',
Expand Down
4 changes: 2 additions & 2 deletions packages/mosaic/src/components/drawer/drawer.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ export const styles = stylex.create({
// the pointer is captured on it, so `:active` survives the drag. A press elsewhere in the sheet
// is not a press on the handle, and leaves it alone.
'--_cl-grip-color': {
default: colorVars['--cl-color-border'],
':active': `color-mix(in oklab, ${colorVars['--cl-color-border']}, ${colorVars['--cl-color-foreground-secondary']} 35%)`,
default: colorVars['--cl-color-border-subtle'],
':active': `color-mix(in oklab, ${colorVars['--cl-color-border-subtle']}, ${colorVars['--cl-color-foreground-secondary']} 35%)`,
},
placeItems: 'center',
display: 'grid',
Expand Down
6 changes: 4 additions & 2 deletions packages/mosaic/src/components/icon/icon-frame.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import * as stylex from '@stylexjs/stylex';

import { colorVars, radiusVars, space } from '../../tokens.stylex';

const filledWash = `light-dark(color-mix(in oklab, ${colorVars['--cl-color-neutral']} 3.5%, transparent), color-mix(in oklab, ${colorVars['--cl-color-neutral']} 4.5%, transparent))`;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

was hopeful to reduce spreading different opacity usages like this through the implementations. was pat of the goal of the alphas. non-blocking if we think we need this custom here though.


export const styles = stylex.create({
base: {
borderColor: 'transparent',
Expand All @@ -17,10 +19,10 @@ export const styles = stylex.create({
justifyContent: 'center',
},
bordered: {
borderColor: colorVars['--cl-color-border'],
borderColor: colorVars['--cl-color-border-subtle'],
},
filled: {
backgroundColor: colorVars['--cl-color-neutral-alpha-100'],
backgroundColor: filledWash,
},
});

Expand Down
2 changes: 1 addition & 1 deletion packages/mosaic/src/components/item/item.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export const item = stylex.create({
},

outline: {
borderColor: colorVars['--cl-color-border'],
borderColor: colorVars['--cl-color-border-subtle'],
borderStyle: 'solid',
borderWidth: '1px',
},
Expand Down
2 changes: 1 addition & 1 deletion packages/mosaic/src/components/menu/menu.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export const separator = stylex.create({
// Full-bleed across the popup: cancel the viewport's inline padding.
marginBlock: space['0.5'],
marginInline: `calc(-1 * ${space['0.5']})`,
backgroundColor: colorVars['--cl-color-border'],
backgroundColor: colorVars['--cl-color-border-subtle'],
blockSize: '1px',
flexShrink: 0,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const styles = stylex.create({
controls: {
gap: space['1'],
alignItems: 'center',
borderBlockStartColor: colorVars['--cl-color-border'],
borderBlockStartColor: colorVars['--cl-color-border-subtle'],
borderBlockStartStyle: 'solid',
borderBlockStartWidth: { [compact]: '1px', default: 0 },
display: { [compact]: 'grid', default: 'flex' },
Expand All @@ -55,7 +55,7 @@ export const styles = stylex.create({
whiteSpace: 'nowrap',
},
divider: {
backgroundColor: colorVars['--cl-color-border'],
backgroundColor: colorVars['--cl-color-border-subtle'],
display: { [compact]: 'none', default: 'block' },
height: '1.25rem',
width: '1px',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const styles = stylex.create({
width: space['4'],
},
divider: {
backgroundColor: colorVars['--cl-color-border'],
backgroundColor: colorVars['--cl-color-border-subtle'],
flexShrink: 0,
height: space['3.5'],
width: '1px',
Expand All @@ -73,7 +73,7 @@ export const styles = stylex.create({
countrySearchRow: {
gap: space['1'],
alignItems: 'center',
borderBlockEndColor: colorVars['--cl-color-border'],
borderBlockEndColor: colorVars['--cl-color-border-subtle'],
borderBlockEndStyle: 'solid',
borderBlockEndWidth: '1px',
display: 'flex',
Expand Down
4 changes: 2 additions & 2 deletions packages/mosaic/src/components/profile/profile.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const styles = stylex.create({

// A fixed height so switching pages never resizes the surface.
layout: {
borderColor: colorVars['--cl-color-border'],
borderColor: colorVars['--cl-color-border-subtle'],
borderRadius: {
[compact]: 0,
default: radiusVars['--cl-radius-xl'],
Expand Down Expand Up @@ -129,7 +129,7 @@ export const styles = stylex.create({

nav: {
padding: space['4'],
borderInlineEndColor: colorVars['--cl-color-border'],
borderInlineEndColor: colorVars['--cl-color-border-subtle'],
borderInlineEndStyle: 'solid',
borderInlineEndWidth: '1px',
// Hidden in CSS too, so the column never shows on a phone before measuring.
Expand Down
6 changes: 3 additions & 3 deletions packages/mosaic/src/components/section/section.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const styles = stylex.create({
maxWidth: 'none',
},
body: {
borderColor: colorVars['--cl-color-border'],
borderColor: colorVars['--cl-color-border-subtle'],
borderRadius: radiusVars['--cl-radius-xl'],
borderStyle: 'solid',
borderWidth: '1px',
Expand All @@ -56,7 +56,7 @@ export const styles = stylex.create({
},
row: {
paddingBlock: space['4'],
borderBlockStartColor: colorVars['--cl-color-border'],
borderBlockStartColor: colorVars['--cl-color-border-subtle'],
borderBlockStartStyle: 'solid',
borderBlockStartWidth: {
default: '1px',
Expand Down Expand Up @@ -89,7 +89,7 @@ export const styles = stylex.create({
},
nestedItem: {
paddingBlock: space['4'],
borderBlockStartColor: colorVars['--cl-color-border'],
borderBlockStartColor: colorVars['--cl-color-border-subtle'],
borderBlockStartStyle: 'solid',
borderBlockStartWidth: {
default: '0px',
Expand Down
4 changes: 2 additions & 2 deletions packages/mosaic/src/components/table/table.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const styles = stylex.create({
search: { maxWidth: '100%', width: '17rem' },
noWrap: { whiteSpace: 'nowrap' },
shell: {
borderColor: colorVars['--cl-color-border'],
borderColor: colorVars['--cl-color-border-subtle'],
borderRadius: radiusVars['--cl-radius-xl'],
borderStyle: 'solid',
borderWidth: '1px',
Expand Down Expand Up @@ -72,7 +72,7 @@ export const styles = stylex.create({
':where([data-actionable]:not([data-selected]):hover)': colorVars['--cl-color-surface-subtle'],
},
},
borderBlockStartColor: colorVars['--cl-color-border'],
borderBlockStartColor: colorVars['--cl-color-border-subtle'],
borderBlockStartStyle: 'solid',
borderBlockStartWidth: '1px',
cursor: { default: null, ':where([data-actionable])': 'pointer' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const styles = stylex.create({
minWidth: 0,
},
tagInvalid: {
backgroundColor: colorVars['--cl-color-negative-alpha-100'],
backgroundColor: colorVars['--cl-color-negative-subtle'],
color: colorVars['--cl-color-negative'],
},
tagLabel: {
Expand Down
4 changes: 2 additions & 2 deletions packages/mosaic/src/components/toast/toast.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,11 @@ export const styles = stylex.create({

export const iconColors = stylex.create({
success: {
backgroundColor: colorVars['--cl-color-positive-alpha-200'],
backgroundColor: colorVars['--cl-color-positive-subtle'],
color: colorVars['--cl-color-positive'],
},
error: {
backgroundColor: colorVars['--cl-color-negative-alpha-200'],
backgroundColor: colorVars['--cl-color-negative-subtle'],
color: colorVars['--cl-color-negative'],
},
loading: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const styles = stylex.create({
lineHeight: typeScaleVars['--cl-text-xs-leading'],
},
pageSizeSelect: {
borderColor: colorVars['--cl-color-border'],
borderColor: colorVars['--cl-color-border-subtle'],
borderRadius: radiusVars['--cl-radius-md'],
borderStyle: 'solid',
borderWidth: '1px',
Expand All @@ -82,7 +82,7 @@ export const styles = stylex.create({
paddingBlock: space['2'],
paddingInline: space['3'],
alignItems: 'center',
borderBlockStartColor: colorVars['--cl-color-border'],
borderBlockStartColor: colorVars['--cl-color-border-subtle'],
borderBlockStartStyle: 'solid',
borderBlockStartWidth: '1px',
display: 'flex',
Expand All @@ -94,7 +94,7 @@ export const styles = stylex.create({
display: 'flex',
},
row: {
borderBlockStartColor: colorVars['--cl-color-border'],
borderBlockStartColor: colorVars['--cl-color-border-subtle'],
borderBlockStartStyle: 'solid',
borderBlockStartWidth: '1px',
},
Expand Down
Loading
Loading