@fluixi-ui/tokens 0.4.0-alpha.0 → 0.4.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -42,20 +42,21 @@
42
42
  :where([data-navigation-menu-trigger]:focus-visible, [data-navigation-menu-link]:focus-visible) {
43
43
  box-shadow: var(--flx-ui-ctl-ring);
44
44
  }
45
- /* The chevron affordance: rotates when the panel opens. */
45
+ /* The chevron affordance: the shared theme chevron, flipping 180° when open. */
46
46
  :where([data-navigation-menu-trigger])::after {
47
47
  content: '';
48
- width: 0.55em;
49
- height: 0.55em;
48
+ width: 1em;
49
+ height: 1em;
50
+ flex: none;
50
51
  margin-inline-start: var(--flx-ui-space-1);
51
- border-right: 1.5px solid currentColor;
52
- border-bottom: 1.5px solid currentColor;
53
- transform: rotate(45deg) translateY(-0.1em);
52
+ background: currentColor;
54
53
  opacity: 0.6;
54
+ -webkit-mask: var(--flx-ui-chevron-down) center / contain no-repeat;
55
+ mask: var(--flx-ui-chevron-down) center / contain no-repeat;
55
56
  transition: transform var(--flx-ui-duration-fast) var(--flx-ui-ease-standard);
56
57
  }
57
58
  :where([data-navigation-menu-trigger][data-state='open'])::after {
58
- transform: rotate(225deg) translateY(-0.1em);
59
+ transform: rotate(180deg);
59
60
  }
60
61
 
61
62
  :where([data-navigation-menu-content]) {
@@ -11,7 +11,7 @@
11
11
  font-size: var(--flx-ui-font-size-sm);
12
12
  font-weight: var(--flx-ui-font-weight-medium);
13
13
  color: var(--flx-ui-color-fg);
14
- line-height: var(--flx-ui-leading-none);
14
+ line-height: var(--flx-ui-line-height-none);
15
15
  }
16
16
  :where([data-number-field-label][data-disabled]) {
17
17
  color: var(--flx-ui-color-fg-subtle);
@@ -61,8 +61,8 @@
61
61
  color: var(--flx-ui-color-fg-muted);
62
62
  cursor: pointer;
63
63
  font-size: var(--flx-ui-font-size-sm);
64
- transition: background var(--flx-ui-duration-fast) var(--flx-ui-easing-standard),
65
- color var(--flx-ui-duration-fast) var(--flx-ui-easing-standard);
64
+ transition: background var(--flx-ui-duration-fast) var(--flx-ui-ease-standard),
65
+ color var(--flx-ui-duration-fast) var(--flx-ui-ease-standard);
66
66
  }
67
67
  :where([data-number-field-decrement]) {
68
68
  border-right: 1px solid var(--flx-ui-color-border);
@@ -31,9 +31,9 @@
31
31
  border-radius: var(--flx-ui-radius-md);
32
32
  cursor: pointer;
33
33
  user-select: none;
34
- transition: background var(--flx-ui-duration-fast) var(--flx-ui-easing-standard),
35
- color var(--flx-ui-duration-fast) var(--flx-ui-easing-standard),
36
- border-color var(--flx-ui-duration-fast) var(--flx-ui-easing-standard);
34
+ transition: background var(--flx-ui-duration-fast) var(--flx-ui-ease-standard),
35
+ color var(--flx-ui-duration-fast) var(--flx-ui-ease-standard),
36
+ border-color var(--flx-ui-duration-fast) var(--flx-ui-ease-standard);
37
37
  }
38
38
  :where([data-pagination-page]:hover:not([disabled])),
39
39
  :where([data-pagination-prev]:hover:not([disabled])),
@@ -33,9 +33,13 @@
33
33
  box-shadow: var(--flx-ui-ctl-ring);
34
34
  }
35
35
  :where(button[role='combobox'])::after {
36
- content: '▾';
37
- color: var(--flx-ui-color-fg-muted);
38
- font-size: 0.8em;
36
+ content: '';
37
+ width: 1.15em;
38
+ height: 1.15em;
39
+ flex: none;
40
+ background: var(--flx-ui-color-fg-muted);
41
+ -webkit-mask: var(--flx-ui-chevron-down) center / contain no-repeat;
42
+ mask: var(--flx-ui-chevron-down) center / contain no-repeat;
39
43
  }
40
44
  :where([data-select-value][data-placeholder]) {
41
45
  color: var(--flx-ui-color-fg-muted);
@@ -65,12 +69,23 @@
65
69
  color: var(--flx-ui-color-fg-muted);
66
70
  }
67
71
  :where([data-combobox-control] > button) {
72
+ display: inline-flex;
73
+ align-items: center;
74
+ justify-content: center;
68
75
  border: none;
69
76
  background: none;
70
77
  cursor: pointer;
71
78
  color: var(--flx-ui-color-fg-muted);
72
79
  padding: 0 var(--flx-ui-space-1);
73
- font-size: 0.8em;
74
80
  border-radius: var(--flx-ui-radius-sm);
75
81
  }
82
+ /* When the trigger has no custom content, show the shared theme chevron. */
83
+ :where([data-combobox-control] > button:empty)::after {
84
+ content: '';
85
+ width: 1.15em;
86
+ height: 1.15em;
87
+ background: currentColor;
88
+ -webkit-mask: var(--flx-ui-chevron-down) center / contain no-repeat;
89
+ mask: var(--flx-ui-chevron-down) center / contain no-repeat;
90
+ }
76
91
  }
@@ -66,9 +66,9 @@
66
66
  font-size: var(--flx-ui-font-size-sm);
67
67
  font-weight: var(--flx-ui-font-weight-medium);
68
68
  line-height: 1;
69
- transition: background var(--flx-ui-duration-fast) var(--flx-ui-easing-standard),
70
- border-color var(--flx-ui-duration-fast) var(--flx-ui-easing-standard),
71
- color var(--flx-ui-duration-fast) var(--flx-ui-easing-standard);
69
+ transition: background var(--flx-ui-duration-fast) var(--flx-ui-ease-standard),
70
+ border-color var(--flx-ui-duration-fast) var(--flx-ui-ease-standard),
71
+ color var(--flx-ui-duration-fast) var(--flx-ui-ease-standard);
72
72
  }
73
73
  :where([data-stepper-indicator][data-state='active']) {
74
74
  border-color: var(--flx-ui-color-primary);
@@ -0,0 +1,71 @@
1
+ @layer flx.components {
2
+ /* ----------------------------------------------------------------------------
3
+ * Surface — an elevated container primitive. Background + radius are always set;
4
+ * elevation (shadow) and border are opt-in via data attributes, so it backs
5
+ * everything from a flat panel to a raised card or floating sheet.
6
+ * ------------------------------------------------------------------------- */
7
+ :where([data-surface]) {
8
+ background: var(--flx-ui-color-bg);
9
+ color: var(--flx-ui-color-fg);
10
+ border-radius: var(--flx-ui-radius-lg);
11
+ transition:
12
+ box-shadow var(--flx-ui-duration-fast) var(--flx-ui-ease-standard),
13
+ border-color var(--flx-ui-duration-fast) var(--flx-ui-ease-standard);
14
+ }
15
+ :where([data-surface][data-bordered]) {
16
+ border: var(--flx-ui-border-width-thin) solid var(--flx-ui-color-border);
17
+ }
18
+
19
+ :where([data-surface][data-radius='none']) {
20
+ border-radius: 0;
21
+ }
22
+ :where([data-surface][data-radius='sm']) {
23
+ border-radius: var(--flx-ui-radius-sm);
24
+ }
25
+ :where([data-surface][data-radius='md']) {
26
+ border-radius: var(--flx-ui-radius-md);
27
+ }
28
+ :where([data-surface][data-radius='lg']) {
29
+ border-radius: var(--flx-ui-radius-lg);
30
+ }
31
+ :where([data-surface][data-radius='xl']) {
32
+ border-radius: var(--flx-ui-radius-xl);
33
+ }
34
+ :where([data-surface][data-radius='full']) {
35
+ border-radius: var(--flx-ui-radius-full);
36
+ }
37
+
38
+ :where([data-surface][data-elevation='0']) {
39
+ box-shadow: none;
40
+ }
41
+ :where([data-surface][data-elevation='1']) {
42
+ box-shadow: var(--flx-ui-shadow-sm);
43
+ }
44
+ :where([data-surface][data-elevation='2']) {
45
+ box-shadow: var(--flx-ui-shadow-md);
46
+ }
47
+ :where([data-surface][data-elevation='3']) {
48
+ box-shadow: var(--flx-ui-shadow-lg);
49
+ }
50
+ :where([data-surface][data-elevation='4']) {
51
+ box-shadow: var(--flx-ui-shadow-xl);
52
+ }
53
+
54
+ /* In dark, shadows barely read on a near-black page, so elevation is tonal — the
55
+ surface lightens as it rises — with a hairline edge for definition. */
56
+ [data-theme='dark'] :where([data-surface][data-elevation='1']) {
57
+ background: var(--flx-ui-gray-2);
58
+ }
59
+ [data-theme='dark'] :where([data-surface][data-elevation='2']) {
60
+ background: var(--flx-ui-gray-3);
61
+ }
62
+ [data-theme='dark'] :where([data-surface][data-elevation='3']) {
63
+ background: var(--flx-ui-gray-4);
64
+ }
65
+ [data-theme='dark'] :where([data-surface][data-elevation='4']) {
66
+ background: var(--flx-ui-gray-5);
67
+ }
68
+ [data-theme='dark'] :where([data-surface]:not([data-elevation='0']):not([data-bordered])) {
69
+ border: var(--flx-ui-border-width-thin) solid var(--flx-ui-color-border);
70
+ }
71
+ }
@@ -30,4 +30,16 @@
30
30
  :where([role='switch'][data-state='checked'])::after {
31
31
  transform: translateX(16px);
32
32
  }
33
+ :where([role='switch']:hover:not([data-disabled])) {
34
+ background: var(--flx-ui-color-border-strong);
35
+ filter: brightness(0.97);
36
+ }
37
+ :where([role='switch']:focus-visible) {
38
+ outline: none;
39
+ box-shadow: var(--flx-ui-ctl-ring);
40
+ }
41
+ :where([role='switch'][data-disabled]) {
42
+ opacity: var(--flx-ui-opacity-disabled);
43
+ cursor: not-allowed;
44
+ }
33
45
  }
package/dist/css/tabs.css CHANGED
@@ -19,13 +19,22 @@
19
19
  margin-bottom: -1px;
20
20
  transition: color var(--flx-ui-duration-fast) var(--flx-ui-ease-standard);
21
21
  }
22
- :where([role='tab']:hover) {
22
+ :where([role='tab']:hover:not([data-disabled])) {
23
23
  color: var(--flx-ui-color-fg);
24
24
  }
25
+ :where([role='tab']:focus-visible) {
26
+ outline: none;
27
+ border-radius: var(--flx-ui-radius-sm);
28
+ box-shadow: var(--flx-ui-ctl-ring);
29
+ }
25
30
  :where([role='tab'][data-state='active']) {
26
31
  color: var(--flx-ui-color-primary-active);
27
32
  border-bottom-color: var(--flx-ui-color-primary);
28
33
  }
34
+ :where([role='tab'][data-disabled]) {
35
+ opacity: var(--flx-ui-opacity-disabled);
36
+ cursor: not-allowed;
37
+ }
29
38
  :where([role='tabpanel']) {
30
39
  padding: var(--flx-ui-space-4) 0;
31
40
  }
@@ -34,6 +34,12 @@
34
34
  border-color: var(--flx-ui-color-primary);
35
35
  color: var(--flx-ui-color-primary-active);
36
36
  }
37
+ :where([aria-pressed]:focus-visible) {
38
+ outline: none;
39
+ position: relative;
40
+ z-index: 2;
41
+ box-shadow: var(--flx-ui-ctl-ring);
42
+ }
37
43
  :where([aria-pressed][data-disabled]) {
38
44
  opacity: var(--flx-ui-opacity-disabled);
39
45
  pointer-events: none;
@@ -9,12 +9,6 @@ export declare const TOKEN_PREFIX = "flx-ui";
9
9
  export declare const LAYER_ORDER = "@layer flx.tokens, flx.components, flx.skin;";
10
10
  export declare function cssVar(name: string): string;
11
11
  export declare function cssVarRef(name: string): string;
12
- /**
13
- * Generate the full token stylesheet: static reference tokens and the light
14
- * scales plus semantic aliases on `:root`, with dark and high-contrast themes
15
- * overriding only the scales (and a few semantics). Dark also applies
16
- * automatically via `prefers-color-scheme` when no explicit theme is set.
17
- */
18
12
  export declare function generateTokensCss(): string;
19
13
  export declare const tokensCss: string;
20
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/css/index.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,YAAY,WAAW,CAAC;AAErC;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,iDAAiD,CAAC;AAE1E,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AA4FD;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAkC1C;AAED,eAAO,MAAM,SAAS,EAAE,MAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/css/index.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,YAAY,WAAW,CAAC;AAErC;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,iDAAiD,CAAC;AAE1E,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AA4GD,wBAAgB,iBAAiB,IAAI,MAAM,CAmC1C;AAED,eAAO,MAAM,SAAS,EAAE,MAA4B,CAAC"}
@@ -105,6 +105,15 @@ function accentBlocks(name, preset) {
105
105
  * overriding only the scales (and a few semantics). Dark also applies
106
106
  * automatically via `prefers-color-scheme` when no explicit theme is set.
107
107
  */
108
+ // A dark shadow on a dark surface is nearly invisible, so dark mode needs its
109
+ // own elevation: pure black at a much higher alpha with more spread, which reads
110
+ // as a halo of shade around a raised surface instead of a faint drop.
111
+ const darkShadows = {
112
+ [cssVar('shadow-sm')]: '0 1px 2px rgba(0, 0, 0, 0.4)',
113
+ [cssVar('shadow-md')]: '0 2px 6px rgba(0, 0, 0, 0.44), 0 1px 2px rgba(0, 0, 0, 0.3)',
114
+ [cssVar('shadow-lg')]: '0 8px 20px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.36)',
115
+ [cssVar('shadow-xl')]: '0 16px 36px rgba(0, 0, 0, 0.6), 0 4px 12px rgba(0, 0, 0, 0.42)',
116
+ };
108
117
  export function generateTokensCss() {
109
118
  const root = block(":root, [data-theme='light']", {
110
119
  ...staticVars(),
@@ -118,13 +127,14 @@ export function generateTokensCss() {
118
127
  ...scaleVars('dark'),
119
128
  ...semanticVars(),
120
129
  ...overrideVars('dark'),
130
+ ...darkShadows,
121
131
  });
122
132
  const highContrast = block("[data-theme='high-contrast']", {
123
133
  ...scaleVars('high-contrast'),
124
134
  ...semanticVars(),
125
135
  ...overrideVars('high-contrast'),
126
136
  });
127
- const autoDark = `@media (prefers-color-scheme: dark) {\n${block(':root:not([data-theme])', { ...scaleVars('dark'), ...semanticVars(), ...overrideVars('dark') })
137
+ const autoDark = `@media (prefers-color-scheme: dark) {\n${block(':root:not([data-theme])', { ...scaleVars('dark'), ...semanticVars(), ...overrideVars('dark'), ...darkShadows })
128
138
  .split('\n')
129
139
  .map((line) => ` ${line}`)
130
140
  .join('\n')}\n}`;
@@ -104,7 +104,7 @@ export const semanticColors = {
104
104
  'color-fg': 'var(--flx-ui-gray-12)',
105
105
  'color-fg-muted': 'var(--flx-ui-gray-11)',
106
106
  'color-border': 'var(--flx-ui-gray-6)',
107
- 'color-border-strong': 'var(--flx-ui-gray-8)',
107
+ 'color-border-strong': 'var(--flx-ui-gray-7)',
108
108
  'color-focus-ring': 'var(--flx-ui-accent-8)',
109
109
  'color-primary': 'var(--flx-ui-accent-9)',
110
110
  'color-primary-hover': 'var(--flx-ui-accent-10)',
package/dist/preset.css CHANGED
@@ -32,7 +32,9 @@
32
32
  @import './css/separator.css';
33
33
  @import './css/breadcrumb.css';
34
34
  @import './css/pagination.css';
35
+ @import './css/surface.css';
35
36
  @import './css/card.css';
37
+ @import './css/glow.css';
36
38
  @import './css/aspect-ratio.css';
37
39
  @import './css/stepper.css';
38
40
  @import './css/select-combobox.css';