@floegence/floe-webapp-core 0.50.6 → 0.52.0
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.
- package/dist/components/chat/input/ChatInput.js +8 -8
- package/dist/components/ui/Button.js +16 -13
- package/dist/components/ui/Card.js +125 -119
- package/dist/components/ui/Checkbox.js +178 -132
- package/dist/components/ui/CommandPalette.js +10 -10
- package/dist/components/ui/Dialog.d.ts +7 -0
- package/dist/components/ui/Dialog.js +160 -114
- package/dist/components/ui/DirectoryInput.js +5 -5
- package/dist/components/ui/Dropdown.d.ts +2 -0
- package/dist/components/ui/Dropdown.js +183 -160
- package/dist/components/ui/FloatingWindow.js +211 -199
- package/dist/components/ui/HighlightBlock.js +8 -8
- package/dist/components/ui/Input.js +40 -40
- package/dist/components/ui/Pagination.js +90 -88
- package/dist/components/ui/ProcessingIndicator.js +1 -1
- package/dist/components/ui/Progress.js +99 -88
- package/dist/components/ui/QuoteBlock.js +9 -9
- package/dist/components/ui/Radio.js +151 -127
- package/dist/components/ui/SegmentedControl.js +26 -25
- package/dist/components/ui/Stepper.js +114 -112
- package/dist/components/ui/Switch.js +34 -33
- package/dist/components/ui/Tabs.js +153 -150
- package/dist/components/ui/Tag.js +24 -21
- package/dist/components/ui/Tooltip.js +10 -10
- package/dist/components/ui/floatingPresence.js +40 -30
- package/dist/components/workbench/WorkbenchHud.js +9 -9
- package/dist/components/workbench/WorkbenchLockButton.js +4 -4
- package/dist/components/workbench/WorkbenchWidget.js +46 -43
- package/dist/context/FloeConfigContext.d.ts +5 -1
- package/dist/context/FloeConfigContext.js +10 -9
- package/dist/context/ThemeContext.d.ts +3 -1
- package/dist/context/ThemeContext.js +78 -71
- package/dist/floe.css +32 -0
- package/dist/full.js +839 -836
- package/dist/hooks/useOverlayMask.js +95 -83
- package/dist/index.js +150 -147
- package/dist/input-focus.css +0 -1
- package/dist/styles/themes/index.d.ts +3 -0
- package/dist/styles/themes/index.js +40 -31
- package/dist/styles/tokens.d.ts +36 -0
- package/dist/styles/tokens.js +12 -5
- package/dist/styles.css +1 -1
- package/dist/surface.css +467 -0
- package/dist/themes.d.ts +1 -1
- package/dist/ui.css +9 -0
- package/package.json +1 -1
package/dist/surface.css
ADDED
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
/* Surface roles change decoration only. The existing element owns layout,
|
|
2
|
+
* input, portals, and focus. Unlayered rules replace component/utility shadows.
|
|
3
|
+
* Token fallbacks resolve on the surface, so local Workbench colors participate
|
|
4
|
+
* and root-level theme.tokens overrides remain authoritative. */
|
|
5
|
+
@property --floe-surface-decoration {
|
|
6
|
+
syntax: '*';
|
|
7
|
+
inherits: false;
|
|
8
|
+
initial-value: 0 0 transparent;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/* Only the visible boundary owns its resolved decoration. A hot shell must not
|
|
12
|
+
* propagate that private value through its editor/content descendants. */
|
|
13
|
+
/* Preblend quiet seams onto the carrying background. Opaque borders avoid an
|
|
14
|
+
* extra blending path when native editors repaint their text and caret. */
|
|
15
|
+
:root {
|
|
16
|
+
--floe-surface-edge: color-mix(in srgb, var(--border) 18%, var(--background));
|
|
17
|
+
--floe-surface-divider: color-mix(in srgb, var(--border) 12%, var(--background));
|
|
18
|
+
--floe-surface-highlight: rgb(255 255 255 / 50%);
|
|
19
|
+
--floe-surface-shade: rgb(0 0 0 / 12%);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* Keep dimensions and semantic palette tokens intact. Neutral boundaries become
|
|
23
|
+
* quiet seams; material and existing fills carry the grouping. High contrast
|
|
24
|
+
* retains the original boundaries. Explicit rich Card variants stay independent. */
|
|
25
|
+
@media (forced-colors: none) {
|
|
26
|
+
:root[data-floe-surface-style='soft-neumorphic']:not([data-floe-shell-theme='hc-light']) {
|
|
27
|
+
/* A uniform muted border keeps focus readable without a bright frame.
|
|
28
|
+
* Different colors per edge force a costlier native-editor raster path. */
|
|
29
|
+
--floe-input-focus-color: color-mix(in srgb, var(--muted-foreground) 88%, var(--card));
|
|
30
|
+
}
|
|
31
|
+
:where(:root[data-floe-surface-style='soft-neumorphic']:not([data-floe-shell-theme='hc-light']))
|
|
32
|
+
:is(
|
|
33
|
+
.border-border,
|
|
34
|
+
.border-input,
|
|
35
|
+
[class~='border-border/40'],
|
|
36
|
+
[data-floe-surface],
|
|
37
|
+
.workbench-hud,
|
|
38
|
+
.workbench-lock-button,
|
|
39
|
+
.workbench-overlay__frame
|
|
40
|
+
):not(
|
|
41
|
+
:where(
|
|
42
|
+
[aria-invalid='true'],
|
|
43
|
+
[data-floe-surface-part='tab'],
|
|
44
|
+
[data-floe-card-variant]:not([data-floe-card-variant='default'])
|
|
45
|
+
)
|
|
46
|
+
) {
|
|
47
|
+
border-color: var(--floe-surface-edge);
|
|
48
|
+
}
|
|
49
|
+
:where(:root[data-floe-surface-style='soft-neumorphic']:not([data-floe-shell-theme='hc-light']))
|
|
50
|
+
:is(
|
|
51
|
+
[data-floe-shell-slot],
|
|
52
|
+
.workbench-widget__header,
|
|
53
|
+
[data-floe-floating-window-titlebar],
|
|
54
|
+
.chat-input-toolbar,
|
|
55
|
+
.workbench-overlay__header,
|
|
56
|
+
[data-floe-surface-divider]
|
|
57
|
+
) {
|
|
58
|
+
--top-bar-border: var(--floe-surface-divider);
|
|
59
|
+
--bottom-bar-border: var(--floe-surface-divider);
|
|
60
|
+
--activity-bar-border: var(--floe-surface-divider);
|
|
61
|
+
--terminal-panel-border: var(--floe-surface-divider);
|
|
62
|
+
border-color: var(--floe-surface-divider);
|
|
63
|
+
}
|
|
64
|
+
:where(:root[data-floe-surface-style='soft-neumorphic']:not([data-floe-shell-theme='hc-light']))
|
|
65
|
+
:is(
|
|
66
|
+
.bg-border,
|
|
67
|
+
.workbench-dock__divider,
|
|
68
|
+
.workbench-hud__divider,
|
|
69
|
+
.workbench-context-menu__separator,
|
|
70
|
+
.workbench-overlay__header-separator,
|
|
71
|
+
[data-floe-surface-divider='fill']
|
|
72
|
+
) {
|
|
73
|
+
background-color: var(--floe-surface-divider);
|
|
74
|
+
}
|
|
75
|
+
:where(:root[data-floe-surface-style='soft-neumorphic']:not([data-floe-shell-theme='hc-light']))
|
|
76
|
+
.workbench-canvas__grid {
|
|
77
|
+
opacity: 0.35;
|
|
78
|
+
}
|
|
79
|
+
:root[data-floe-surface-style='soft-neumorphic']:not([data-floe-shell-theme='hc-light'])
|
|
80
|
+
[data-floe-surface-divider] {
|
|
81
|
+
border-color: var(--floe-surface-divider);
|
|
82
|
+
}
|
|
83
|
+
:root[data-floe-surface-style='soft-neumorphic']:not([data-floe-shell-theme='hc-light'])
|
|
84
|
+
.workbench-surface {
|
|
85
|
+
--wb-dock-material-border: var(--floe-surface-edge);
|
|
86
|
+
--wb-dock-material-border-top: var(--floe-surface-edge);
|
|
87
|
+
--wb-dock-material-shadow: var(
|
|
88
|
+
--floe-surface-shadow-raised,
|
|
89
|
+
0 2px 5px -2px var(--floe-surface-shade),
|
|
90
|
+
inset 0 1px 1px var(--floe-surface-highlight)
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
:root.dark {
|
|
95
|
+
--floe-surface-highlight: rgb(255 255 255 / 4%);
|
|
96
|
+
--floe-surface-shade: rgb(0 0 0 / 20%);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
[data-floe-surface-style='soft-neumorphic'] [data-floe-surface] {
|
|
100
|
+
--floe-surface-decoration: 0 0 transparent;
|
|
101
|
+
box-shadow: var(--floe-surface-decoration);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/* Material never owns movement. Keep the motion component's property list,
|
|
105
|
+
* duration and easing together instead of remapping its transition shorthand. */
|
|
106
|
+
[data-floe-surface-style='soft-neumorphic']
|
|
107
|
+
[data-floe-surface]:not(
|
|
108
|
+
:where(
|
|
109
|
+
.floe-floating-presence,
|
|
110
|
+
[data-floe-surface-part='switch-thumb'],
|
|
111
|
+
[data-floe-surface-part='radio-dot'],
|
|
112
|
+
[data-floe-surface-part='progress-fill']
|
|
113
|
+
)
|
|
114
|
+
) {
|
|
115
|
+
transition-property: color, background-color, border-color, opacity;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
[data-floe-surface-style='soft-neumorphic'] [data-floe-surface='raised'] {
|
|
119
|
+
--floe-surface-decoration: var(
|
|
120
|
+
--floe-surface-shadow-raised,
|
|
121
|
+
0 2px 5px -2px var(--floe-surface-shade),
|
|
122
|
+
inset 0 1px 1px var(--floe-surface-highlight)
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
[data-floe-surface-style='soft-neumorphic'] [data-floe-surface='inset'] {
|
|
126
|
+
--floe-surface-decoration: var(
|
|
127
|
+
--floe-surface-shadow-inset,
|
|
128
|
+
inset 0 1px 2px var(--floe-surface-shade),
|
|
129
|
+
inset 0 -1px 1px var(--floe-surface-highlight)
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
[data-floe-surface-style='soft-neumorphic'] [data-floe-surface='floating'] {
|
|
133
|
+
--floe-surface-decoration: var(
|
|
134
|
+
--floe-surface-shadow-floating,
|
|
135
|
+
0 8px 20px -6px var(--floe-surface-shade),
|
|
136
|
+
inset 0 1px 1px var(--floe-surface-highlight)
|
|
137
|
+
);
|
|
138
|
+
background-color: var(--card);
|
|
139
|
+
-webkit-backdrop-filter: none;
|
|
140
|
+
backdrop-filter: none;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* The geometry owner must not clip the moving panel's external shadow. Paint
|
|
144
|
+
* containment belongs on the existing panel that also owns content clipping. */
|
|
145
|
+
[data-floe-surface-style='soft-neumorphic'] [data-floe-geometry-surface='floating-window'] {
|
|
146
|
+
contain: layout style;
|
|
147
|
+
}
|
|
148
|
+
[data-floe-surface-style='soft-neumorphic'] [data-floe-floating-window-surface='true'] {
|
|
149
|
+
contain: paint;
|
|
150
|
+
}
|
|
151
|
+
[data-floe-surface-style='soft-neumorphic'] [data-floe-dialog-backdrop]:not(.floe-bottom-drawer-backdrop) {
|
|
152
|
+
background-color: rgb(0 0 0 / 16%);
|
|
153
|
+
-webkit-backdrop-filter: none;
|
|
154
|
+
backdrop-filter: none;
|
|
155
|
+
}
|
|
156
|
+
:root.dark[data-floe-surface-style='soft-neumorphic'] [data-floe-dialog-backdrop]:not(.floe-bottom-drawer-backdrop) {
|
|
157
|
+
background-color: rgb(0 0 0 / 36%);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/* A new selection is visible in its first painted frame. Fading the two faces
|
|
161
|
+
* leaves the old choice visually active after the native state has changed. */
|
|
162
|
+
[data-floe-surface-style='soft-neumorphic']
|
|
163
|
+
:is(
|
|
164
|
+
[data-floe-surface-part='choice'],
|
|
165
|
+
[data-floe-surface-part='indicator'],
|
|
166
|
+
[data-floe-surface-part='tab'],
|
|
167
|
+
[data-floe-surface-part='segment']
|
|
168
|
+
) {
|
|
169
|
+
transition: none;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/* A compound input has one decorative boundary, including host compositions
|
|
173
|
+
* that contain an Input component. Dense nested actions stay flat. */
|
|
174
|
+
[data-floe-surface-style='soft-neumorphic'] [data-floe-input-surface] [data-floe-surface],
|
|
175
|
+
[data-floe-surface-style='soft-neumorphic']
|
|
176
|
+
[data-floe-surface='raised']
|
|
177
|
+
[data-floe-surface='raised']:not([data-floe-surface-part]),
|
|
178
|
+
[data-floe-surface-style='soft-neumorphic'] [data-floe-surface='flat'] {
|
|
179
|
+
--floe-surface-decoration: 0 0 transparent;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* Decoration cannot replace independent keyboard indicators. Inputs, including
|
|
183
|
+
* button-based compound fields, continue to use input-focus.css exclusively. */
|
|
184
|
+
[data-floe-surface-style='soft-neumorphic']
|
|
185
|
+
[data-floe-surface]:focus-visible:not(
|
|
186
|
+
:where(input, textarea, select, [data-floe-input-surface], [data-floe-input-surface] *)
|
|
187
|
+
) {
|
|
188
|
+
box-shadow:
|
|
189
|
+
0 0 0 2px var(--background),
|
|
190
|
+
0 0 0 4px var(--ring),
|
|
191
|
+
var(--floe-surface-decoration);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
[data-floe-surface-style='soft-neumorphic'] .workbench-widget[data-floe-surface] {
|
|
195
|
+
/* Some local palettes use translucent body tints. Composite onto an opaque
|
|
196
|
+
* card base instead of reintroducing glass or letting content bleed through. */
|
|
197
|
+
background: linear-gradient(var(--wb-widget-body), var(--wb-widget-body)), var(--card);
|
|
198
|
+
}
|
|
199
|
+
[data-floe-surface-style='soft-neumorphic'] .workbench-widget.is-selected {
|
|
200
|
+
border-color: transparent;
|
|
201
|
+
}
|
|
202
|
+
[data-floe-surface-style='soft-neumorphic']
|
|
203
|
+
.workbench-widget.is-selected
|
|
204
|
+
.workbench-widget__header {
|
|
205
|
+
background: color-mix(in srgb, var(--wb-accent) 8%, var(--card));
|
|
206
|
+
color: var(--wb-accent);
|
|
207
|
+
}
|
|
208
|
+
[data-floe-surface-style='soft-neumorphic'] [data-floe-surface-interacting='true'] {
|
|
209
|
+
--floe-surface-decoration: var(
|
|
210
|
+
--floe-surface-shadow-interacting,
|
|
211
|
+
0 1px 2px var(--floe-surface-shade)
|
|
212
|
+
);
|
|
213
|
+
transition: none;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/* Compact controls use the same four roles at their existing visible boundary.
|
|
217
|
+
* Tight static highlights carry material without large soft shadows per item.
|
|
218
|
+
* Functional transforms, progress widths, and SVG strokes retain their motion. */
|
|
219
|
+
@media (forced-colors: none) {
|
|
220
|
+
:root[data-floe-surface-style='soft-neumorphic']:not([data-floe-shell-theme='hc-light']) {
|
|
221
|
+
--floe-surface-compact-raised:
|
|
222
|
+
0 1px 2px var(--floe-surface-shade), inset 0 1px 1px var(--floe-surface-highlight);
|
|
223
|
+
--floe-surface-compact-inset:
|
|
224
|
+
inset 0 1px 1px var(--floe-surface-shade), inset 0 -1px 1px var(--floe-surface-highlight);
|
|
225
|
+
}
|
|
226
|
+
:where(:root[data-floe-surface-style='soft-neumorphic']:not([data-floe-shell-theme='hc-light'])) {
|
|
227
|
+
& [data-floe-surface-part][data-floe-surface='raised'] {
|
|
228
|
+
--floe-surface-decoration: var(
|
|
229
|
+
--floe-surface-shadow-raised,
|
|
230
|
+
var(--floe-surface-compact-raised)
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
& [data-floe-surface-part][data-floe-surface='inset'] {
|
|
234
|
+
--floe-surface-decoration: var(
|
|
235
|
+
--floe-surface-shadow-inset,
|
|
236
|
+
var(--floe-surface-compact-inset)
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
& [data-floe-surface-part='badge'] {
|
|
240
|
+
/* These can repeat in dense lists. Keep lighting inside the painted box. */
|
|
241
|
+
--floe-surface-decoration: var(
|
|
242
|
+
--floe-surface-shadow-raised,
|
|
243
|
+
inset 0 1px 1px var(--floe-surface-highlight),
|
|
244
|
+
inset 0 -1px 1px var(--floe-surface-shade)
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
& [data-floe-surface-part='badge'][data-floe-surface='inset'],
|
|
248
|
+
& [data-floe-surface-part='progress-fill'][data-floe-surface='inset'] {
|
|
249
|
+
--floe-surface-decoration: var(
|
|
250
|
+
--floe-surface-shadow-inset,
|
|
251
|
+
var(--floe-surface-compact-inset)
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
&
|
|
255
|
+
:is(
|
|
256
|
+
[data-floe-surface-part='switch-thumb'],
|
|
257
|
+
[data-floe-surface-part='progress-fill']
|
|
258
|
+
)[data-floe-surface='raised'] {
|
|
259
|
+
/* Frequent travel and width updates must not repaint decorative shadows.
|
|
260
|
+
* The fixed track carries depth; explicit host shadow overrides still apply. */
|
|
261
|
+
--floe-surface-decoration: var(--floe-surface-shadow-raised, none);
|
|
262
|
+
}
|
|
263
|
+
& :is([data-floe-surface-part='rail'], [data-floe-surface-part='tab-rail']) {
|
|
264
|
+
background-color: color-mix(in srgb, var(--card) 65%, var(--muted));
|
|
265
|
+
}
|
|
266
|
+
/* Keep the existing box metrics, but let the carrying fill reach the edge.
|
|
267
|
+
* An opaque seam based on the page background becomes a dark frame here. */
|
|
268
|
+
&
|
|
269
|
+
:is(
|
|
270
|
+
[data-floe-card-variant='default'],
|
|
271
|
+
[data-floe-surface-part='choice'],
|
|
272
|
+
[data-floe-surface-part='indicator'],
|
|
273
|
+
[data-floe-surface-part='rail'],
|
|
274
|
+
[data-floe-surface-part='tab-rail'],
|
|
275
|
+
[data-floe-surface-part='segment'],
|
|
276
|
+
[data-floe-surface-part='badge']
|
|
277
|
+
)[data-floe-surface] {
|
|
278
|
+
border-color: transparent;
|
|
279
|
+
}
|
|
280
|
+
& [data-floe-surface-part='choice'] {
|
|
281
|
+
background-color: var(--card);
|
|
282
|
+
}
|
|
283
|
+
&
|
|
284
|
+
[data-floe-surface-part='choice']:not([data-floe-selected='true']):hover:not(
|
|
285
|
+
:has(:disabled)
|
|
286
|
+
) {
|
|
287
|
+
background-color: color-mix(in srgb, var(--primary) 3%, var(--card));
|
|
288
|
+
}
|
|
289
|
+
& [data-floe-surface-part='choice'][data-floe-selected='true'] {
|
|
290
|
+
background-color: color-mix(in srgb, var(--primary) 8%, var(--card));
|
|
291
|
+
}
|
|
292
|
+
& [data-floe-choice-variant='button'][data-floe-selected='true'] {
|
|
293
|
+
color: var(--foreground);
|
|
294
|
+
}
|
|
295
|
+
& [data-floe-surface-part='segment'][aria-checked='true'],
|
|
296
|
+
& [data-floe-surface-part='tab'][aria-selected='true'] {
|
|
297
|
+
background-color: color-mix(in srgb, var(--primary) 8%, var(--card));
|
|
298
|
+
color: var(--foreground);
|
|
299
|
+
}
|
|
300
|
+
& [data-floe-surface-part='segment'][aria-checked='false'] {
|
|
301
|
+
background-color: transparent;
|
|
302
|
+
}
|
|
303
|
+
& [data-floe-surface-part='tab'].border-primary {
|
|
304
|
+
border-color: color-mix(in srgb, var(--primary) 24%, var(--card));
|
|
305
|
+
}
|
|
306
|
+
& [data-floe-surface-part='indicator'] > svg {
|
|
307
|
+
animation: floe-choice-mark-in 100ms ease-out;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
& [data-floe-surface-part='progress-circle'] {
|
|
311
|
+
border-radius: 50%;
|
|
312
|
+
background-color: var(--card);
|
|
313
|
+
}
|
|
314
|
+
& [data-floe-surface-part='step'][data-floe-step-state='current'] {
|
|
315
|
+
background-color: color-mix(in srgb, var(--primary) 16%, var(--card));
|
|
316
|
+
color: var(--primary);
|
|
317
|
+
}
|
|
318
|
+
& [data-floe-surface-part='indicator']:not([data-floe-selected='true']),
|
|
319
|
+
& [data-floe-surface-part='switch-track']:not([data-floe-selected='true']) {
|
|
320
|
+
/* The control face, not a strong outline, supplies non-text contrast. */
|
|
321
|
+
background-color: var(--muted-foreground);
|
|
322
|
+
}
|
|
323
|
+
& [data-floe-surface-part='switch-thumb'][data-floe-surface='raised'] {
|
|
324
|
+
/* Retain the component's stable background fill in both states. Changing
|
|
325
|
+
* its paint while translating defeats cheap motion in dark palettes. */
|
|
326
|
+
transition: translate 140ms cubic-bezier(0.2, 0.8, 0.2, 1);
|
|
327
|
+
}
|
|
328
|
+
&
|
|
329
|
+
:is(
|
|
330
|
+
[data-floe-surface-part='indicator'],
|
|
331
|
+
[data-floe-surface-part='switch-track']
|
|
332
|
+
)[data-floe-surface='inset'] {
|
|
333
|
+
/* At 14–24 px, a one-pixel light edge and tight well stay legible at 1x.
|
|
334
|
+
* Broad opposing blurs make both the contour and the glyph look unfocused. */
|
|
335
|
+
--floe-surface-decoration: var(
|
|
336
|
+
--floe-surface-shadow-inset,
|
|
337
|
+
inset 0 1px 1px var(--floe-surface-shade),
|
|
338
|
+
inset 0 -1px 0 var(--floe-surface-highlight)
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
& [data-floe-surface-part='switch-track'] {
|
|
342
|
+
transition-duration: 140ms;
|
|
343
|
+
transition-timing-function: ease-out;
|
|
344
|
+
}
|
|
345
|
+
& [data-floe-surface-part='indicator']:has([data-floe-surface-part='radio-dot']) {
|
|
346
|
+
/* A hollow hairline keeps an unchecked radio quieter than its selected dot.
|
|
347
|
+
* Border-box dimensions and hit targets stay fixed; there is no blurred well. */
|
|
348
|
+
border-width: 1px;
|
|
349
|
+
border-color: color-mix(in srgb, var(--muted-foreground) 88%, var(--card));
|
|
350
|
+
background-color: transparent;
|
|
351
|
+
--floe-surface-decoration: var(--floe-surface-shadow-inset, none);
|
|
352
|
+
}
|
|
353
|
+
&
|
|
354
|
+
[data-floe-surface-part='indicator'][data-floe-selected='true']:has(
|
|
355
|
+
[data-floe-surface-part='radio-dot']
|
|
356
|
+
) {
|
|
357
|
+
background-color: color-mix(in srgb, var(--primary) 6%, var(--card));
|
|
358
|
+
}
|
|
359
|
+
& [data-floe-surface-part='radio-dot'] {
|
|
360
|
+
background-color: var(--foreground);
|
|
361
|
+
transition: scale 90ms ease-out;
|
|
362
|
+
}
|
|
363
|
+
& [data-floe-surface-part='progress-fill'] {
|
|
364
|
+
transition-property: width, background-color;
|
|
365
|
+
}
|
|
366
|
+
& [data-floe-surface-part='action']:active:not(:disabled) {
|
|
367
|
+
--floe-surface-decoration: var(
|
|
368
|
+
--floe-surface-shadow-inset,
|
|
369
|
+
var(--floe-surface-compact-inset)
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
/* Hidden native inputs delegate their indicator to the visible existing
|
|
373
|
+
* face. A pointer selection does not receive this keyboard-only outline. */
|
|
374
|
+
& [data-floe-surface-part='choice']:has([data-floe-choice-input]:focus-visible),
|
|
375
|
+
&
|
|
376
|
+
[data-floe-choice-input]:focus-visible
|
|
377
|
+
+ :is([data-floe-surface-part='indicator'], [data-floe-surface-part='switch-track']) {
|
|
378
|
+
outline: 2px solid var(--ring);
|
|
379
|
+
outline-offset: 3px;
|
|
380
|
+
box-shadow: var(--floe-surface-decoration);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
:where(
|
|
384
|
+
:root.dark[data-floe-surface-style='soft-neumorphic']:not([data-floe-shell-theme='hc-light'])
|
|
385
|
+
) {
|
|
386
|
+
/* A solid carrying plane avoids repainting a large gradient behind editors. */
|
|
387
|
+
& [data-floe-card-variant='default'][data-floe-surface='raised'] {
|
|
388
|
+
background-color: color-mix(in srgb, var(--card) 98%, white);
|
|
389
|
+
}
|
|
390
|
+
& [data-floe-surface='floating']:not(.workbench-widget) {
|
|
391
|
+
background-color: color-mix(in srgb, var(--card) 94%, white);
|
|
392
|
+
}
|
|
393
|
+
& [data-floe-input-surface],
|
|
394
|
+
& :is(input, textarea)[data-floe-surface='inset'] {
|
|
395
|
+
background-color: color-mix(in srgb, var(--card) 94%, black);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/* Explicit host opt-outs and compound input boundaries outrank compact states. */
|
|
401
|
+
:root[data-floe-surface-style='soft-neumorphic'] [data-floe-surface='flat'],
|
|
402
|
+
:root[data-floe-surface-style='soft-neumorphic'] [data-floe-input-surface] [data-floe-surface] {
|
|
403
|
+
--floe-surface-decoration: 0 0 transparent;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/* High contrast stays flat, with real boundaries and keyboard indicators. */
|
|
407
|
+
:root[data-floe-surface-style='soft-neumorphic'][data-floe-shell-theme='hc-light']
|
|
408
|
+
[data-floe-surface] {
|
|
409
|
+
--floe-surface-decoration: 0 0 transparent;
|
|
410
|
+
}
|
|
411
|
+
:root[data-floe-surface-style='soft-neumorphic'][data-floe-shell-theme='hc-light']
|
|
412
|
+
.workbench-widget.is-selected {
|
|
413
|
+
border-color: var(--wb-accent);
|
|
414
|
+
}
|
|
415
|
+
@media (forced-colors: active) {
|
|
416
|
+
[data-floe-surface-style='soft-neumorphic'] [data-floe-surface] {
|
|
417
|
+
--floe-surface-decoration: 0 0 transparent;
|
|
418
|
+
}
|
|
419
|
+
[data-floe-surface-style='soft-neumorphic']
|
|
420
|
+
[data-floe-surface]:focus-visible:not(
|
|
421
|
+
:where(input, textarea, select, [data-floe-input-surface], [data-floe-input-surface] *)
|
|
422
|
+
) {
|
|
423
|
+
outline: 2px solid Highlight;
|
|
424
|
+
outline-offset: 2px;
|
|
425
|
+
}
|
|
426
|
+
[data-floe-surface-style='soft-neumorphic'] .workbench-widget.is-selected {
|
|
427
|
+
border-color: Highlight;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
@media (prefers-reduced-motion: reduce) {
|
|
431
|
+
[data-floe-surface-style='soft-neumorphic'] [data-floe-surface] {
|
|
432
|
+
transition: none;
|
|
433
|
+
}
|
|
434
|
+
[data-floe-surface-style='soft-neumorphic'] [data-floe-surface-part='indicator'] > svg {
|
|
435
|
+
animation: none;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
@keyframes floe-choice-mark-in {
|
|
440
|
+
from {
|
|
441
|
+
opacity: 0.65;
|
|
442
|
+
transform: scale(0.9);
|
|
443
|
+
}
|
|
444
|
+
to {
|
|
445
|
+
opacity: 1;
|
|
446
|
+
transform: scale(1);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
:root[data-floe-surface-style='soft-neumorphic'][data-floe-shell-theme='hc-light']
|
|
451
|
+
[data-floe-surface-part='choice']:has([data-floe-choice-input]:focus-visible),
|
|
452
|
+
:root[data-floe-surface-style='soft-neumorphic'][data-floe-shell-theme='hc-light']
|
|
453
|
+
[data-floe-choice-input]:focus-visible
|
|
454
|
+
+ :is([data-floe-surface-part='indicator'], [data-floe-surface-part='switch-track']) {
|
|
455
|
+
outline: 2px solid var(--ring);
|
|
456
|
+
outline-offset: 3px;
|
|
457
|
+
}
|
|
458
|
+
@media (forced-colors: active) {
|
|
459
|
+
[data-floe-surface-style='soft-neumorphic']
|
|
460
|
+
[data-floe-surface-part='choice']:has([data-floe-choice-input]:focus-visible),
|
|
461
|
+
[data-floe-surface-style='soft-neumorphic']
|
|
462
|
+
[data-floe-choice-input]:focus-visible
|
|
463
|
+
+ :is([data-floe-surface-part='indicator'], [data-floe-surface-part='switch-track']) {
|
|
464
|
+
outline: 2px solid Highlight;
|
|
465
|
+
outline-offset: 3px;
|
|
466
|
+
}
|
|
467
|
+
}
|
package/dist/themes.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { BUILT_IN_SHELL_THEME_DEFAULTS, REQUIRED_SHELL_THEME_TOKENS, assertUniqueThemePresetNames, builtInShellThemePresets, getShellThemePresetsForMode, normalizeShellThemeSelection, presetSupportsMode, resolveShellThemePresetName, type FloeShellThemeDefaults, type FloeShellThemeMode, type FloeShellThemeSelection, } from './styles/themes/presets';
|
|
2
|
-
export type { FloeMonacoThemeDefinition, FloeMonacoTokenRule, FloeThemePreset, FloeThemePresetMode, FloeThemeTokenMap, FloeThemeTokenOverrides, } from './styles/themes';
|
|
2
|
+
export type { FloeSurfaceStyle, FloeMonacoThemeDefinition, FloeMonacoTokenRule, FloeThemePreset, FloeThemePresetMode, FloeThemeTokenMap, FloeThemeTokenOverrides, } from './styles/themes';
|
package/dist/ui.css
CHANGED
|
@@ -1816,3 +1816,12 @@
|
|
|
1816
1816
|
transform-origin: 0 0;
|
|
1817
1817
|
}
|
|
1818
1818
|
}
|
|
1819
|
+
|
|
1820
|
+
/* Field triggers use input-focus.css. Action triggers retain an independent
|
|
1821
|
+
* keyboard indicator without applying ring utilities to a conditional field. */
|
|
1822
|
+
@layer components {
|
|
1823
|
+
[data-floe-dropdown-trigger]:focus-visible:not([data-floe-input-surface]) {
|
|
1824
|
+
outline: 1px solid var(--ring);
|
|
1825
|
+
outline-offset: 0;
|
|
1826
|
+
}
|
|
1827
|
+
}
|