@mkbabb/glass-ui 2.0.0 → 3.0.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/LICENSE +21 -0
- package/README.md +9 -0
- package/dist/{CommandShortcut-_INFUMu6.js → CommandShortcut-BNDzfFnB.js} +2 -2
- package/dist/{ContextMenuSubContent-DCkweFW9.js → ContextMenuSubContent-DLEyeqbh.js} +3 -3
- package/dist/{DialogContent-CmCijgX9.js → DialogContent-DSo7PKlU.js} +1 -1
- package/dist/{DialogFooter-DRdaCok0.js → DialogFooter-D5KY6sCX.js} +1 -1
- package/dist/{Notification-DrI1DT2v.js → Notification-D97JO0fK.js} +2 -2
- package/dist/{SelectScrollDownButton-yu8EYUnu.js → SelectScrollDownButton-BwTexKeY.js} +2 -2
- package/dist/{Toaster-DY8_jtHv.js → Toaster-CY8gJu9E.js} +69 -58
- package/dist/animated-digit.js +1 -1
- package/dist/aurora.js +100 -87
- package/dist/carousel.js +4 -4
- package/dist/{check-dwgetki8.js → check-Nuw7H9Yh.js} +1 -1
- package/dist/{chevron-down-DILQA1t6.js → chevron-down-Du2b9vY_.js} +1 -1
- package/dist/{chevron-right-fS7fal2t.js → chevron-right-CtDxpE3w.js} +1 -1
- package/dist/{chevron-up-BtYjYQOS.js → chevron-up-CenYokvI.js} +1 -1
- package/dist/command.js +1 -1
- package/dist/components/custom/aurora/composables/runtime.d.ts +24 -1
- package/dist/components/custom/sortable-list/SortableHandle.vue.d.ts +1 -1
- package/dist/components/custom/toggle-chip/ToggleChip.vue.d.ts +6 -4
- package/dist/components/custom/typewriter/TypewriterText.vue.d.ts +1 -1
- package/dist/components/ui/drawer/Drawer.vue.d.ts +25 -2
- package/dist/components/ui/drawer/DrawerContent.vue.d.ts +12 -1
- package/dist/components/ui/drawer/index.d.ts +9 -0
- package/dist/components/ui/toast/Toaster.vue.d.ts +7 -1
- package/dist/components/ui/toast/index.d.ts +1 -0
- package/dist/components/ui/toast/use-toast.d.ts +14 -1
- package/dist/composables/dark/index.d.ts +1 -0
- package/dist/composables/dom/index.d.ts +1 -0
- package/dist/composables/dom/useIdleReady.d.ts +63 -0
- package/dist/composables/index.d.ts +1 -0
- package/dist/composables/motion/core/index.d.ts +6 -0
- package/dist/composables/motion/index.d.ts +0 -7
- package/dist/configurator.js +1 -1
- package/dist/confirm-dialog.js +1 -1
- package/dist/constants-D-8FN28s.js +13 -0
- package/dist/context-menu.js +1 -1
- package/dist/{createLucideIcon-Bn9a1b70.js → createLucideIcon-rHu18UQW.js} +2 -2
- package/dist/dark.d.ts +1 -1
- package/dist/dark.js +12 -1
- package/dist/dialog.js +2 -2
- package/dist/dock.js +1 -1
- package/dist/dom.js +2 -2
- package/dist/{dropdown-menu-2K-SGkZU.js → dropdown-menu-gHSkffW7.js} +2 -2
- package/dist/dropdown-menu.js +1 -1
- package/dist/expandable-container.js +2 -2
- package/dist/forms.js +2 -2
- package/dist/glass-ui.css +1 -1
- package/dist/glass-ui.js +139 -115
- package/dist/icon-tooltip.js +1 -1
- package/dist/keyboard.js +1 -1
- package/dist/labeled-field.js +3 -3
- package/dist/{minimize-2-LsCJ_eNt.js → minimize-2-C_oyKVwZ.js} +1 -1
- package/dist/motion-core.d.ts +1 -0
- package/dist/motion-core.js +192 -0
- package/dist/motion.js +25 -227
- package/dist/notification.js +1 -1
- package/dist/responsive-tabs.js +1 -1
- package/dist/{search-ocd8tmL9.js → search-7XEx_6hq.js} +1 -1
- package/dist/search.js +4 -4
- package/dist/select.js +1 -1
- package/dist/{sheet-CLVkb3AO.js → sheet-BsBdO5jq.js} +1 -1
- package/dist/sheet.js +1 -1
- package/dist/sortable-list.js +6 -3
- package/dist/status-dot.js +16 -13
- package/dist/styles/dock.css +72 -95
- package/dist/styles/drawer.css +138 -0
- package/dist/styles/index.css +18 -2
- package/dist/styles/instrument-chassis.css +28 -1
- package/dist/styles/theme.css +3 -0
- package/dist/styles/tokens.css +109 -266
- package/dist/styles/typography.css +44 -131
- package/dist/styles/utilities.css +23 -58
- package/dist/toast.js +1 -1
- package/dist/{useAnimatedNumber-DcvTR9B4.js → useAnimatedNumber-2l13GibX.js} +9 -20
- package/dist/{useConfiguratorState-BlaevW0S.js → useConfiguratorState-BpZi8QJu.js} +5 -5
- package/dist/{useBreakpoint-BHlX-MhR.js → useIdleReady-DlzJicQH.js} +29 -1
- package/dist/{x-cdWAmO-q.js → x-Cb3NE2Ne.js} +1 -1
- package/package.json +12 -5
- package/src/styles/dock.css +72 -95
- package/src/styles/drawer.css +138 -0
- package/src/styles/index.css +14 -2
- package/src/styles/instrument-chassis.css +28 -1
- package/src/styles/theme.css +3 -0
- package/src/styles/tokens.css +109 -266
- package/src/styles/typography.css +44 -131
- package/src/styles/utilities.css +23 -58
- package/dist/composables/motion/useSpringOrchestrator.d.ts +0 -15
- /package/dist/{IconTooltip-ge_mBSWR.js → IconTooltip-GIeWdo64.js} +0 -0
- /package/dist/{Input-CbakTe3B.js → Input-CBvqW8kZ.js} +0 -0
- /package/dist/composables/{motion → dark}/installDarkModeSync.d.ts +0 -0
- /package/dist/{useKeyboardShortcuts-B1ev1YEC.js → useKeyboardShortcuts-CPO4AhLx.js} +0 -0
package/dist/styles/dock.css
CHANGED
|
@@ -22,6 +22,29 @@
|
|
|
22
22
|
--dock-motion-resize: var(--duration-normal) var(--spring-snappy);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/* Shared four-state contract — the focus-visible ring + disabled paint are
|
|
26
|
+
identical across every dock control, so they are expressed ONCE here as a
|
|
27
|
+
comma group over the control family rather than copied per rule-set. The
|
|
28
|
+
group keeps full class+pseudo specificity (NOT `:where()`, which would
|
|
29
|
+
zero the class and let a per-control :hover box-shadow override the focus
|
|
30
|
+
ring). Per-control transition extensions (the box-shadow fade on
|
|
31
|
+
focus-visible) stay with their own selectors below where they differ. */
|
|
32
|
+
.dock-icon-button:focus-visible,
|
|
33
|
+
.dock-tab-button:focus-visible,
|
|
34
|
+
.dock-select-trigger:focus-visible,
|
|
35
|
+
.dock-dropdown-trigger:focus-visible {
|
|
36
|
+
box-shadow: var(--focus-ring-shadow);
|
|
37
|
+
outline: none;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.dock-icon-button:disabled,
|
|
41
|
+
.dock-tab-button:disabled,
|
|
42
|
+
.dock-select-trigger:disabled,
|
|
43
|
+
.dock-dropdown-trigger:disabled {
|
|
44
|
+
opacity: var(--opacity-disabled);
|
|
45
|
+
cursor: not-allowed;
|
|
46
|
+
}
|
|
47
|
+
|
|
25
48
|
.glass-dock {
|
|
26
49
|
--dock-surface-blur: var(--glass-blur-dock, var(--glass-blur-wash));
|
|
27
50
|
/* J.W3.C — vertical-rail max-block + horizontal max-inline caps
|
|
@@ -68,6 +91,7 @@
|
|
|
68
91
|
--dock-trigger-padding-inline: var(--dock-density-compact-trigger-padding-inline, 0.4375rem);
|
|
69
92
|
--dock-tab-padding-block: var(--dock-density-compact-tab-padding-block, 0.3125rem);
|
|
70
93
|
--dock-tab-padding-inline: var(--dock-density-compact-tab-padding-inline, 0.625rem);
|
|
94
|
+
--dock-tab-h: 32px;
|
|
71
95
|
}
|
|
72
96
|
|
|
73
97
|
/* Comfortable density — the GlassDock default. Sits between compact
|
|
@@ -82,6 +106,7 @@
|
|
|
82
106
|
--dock-trigger-padding-inline: var(--dock-density-comfortable-trigger-padding-inline, 0.5rem);
|
|
83
107
|
--dock-tab-padding-block: var(--dock-density-comfortable-tab-padding-block, 0.4375rem);
|
|
84
108
|
--dock-tab-padding-inline: var(--dock-density-comfortable-tab-padding-inline, 0.75rem);
|
|
109
|
+
--dock-tab-h: 38px;
|
|
85
110
|
}
|
|
86
111
|
|
|
87
112
|
.glass-dock[data-density="spacious"] {
|
|
@@ -94,6 +119,7 @@
|
|
|
94
119
|
--dock-trigger-padding-inline: var(--dock-density-spacious-trigger-padding-inline, 0.625rem);
|
|
95
120
|
--dock-tab-padding-block: var(--dock-density-spacious-tab-padding-block, 0.5rem);
|
|
96
121
|
--dock-tab-padding-inline: var(--dock-density-spacious-tab-padding-inline, 0.875rem);
|
|
122
|
+
--dock-tab-h: 44px;
|
|
97
123
|
}
|
|
98
124
|
|
|
99
125
|
/* Audacious density — typography-forward chrome where the dock reads as
|
|
@@ -111,41 +137,13 @@
|
|
|
111
137
|
--dock-tab-padding-block: var(--dock-density-audacious-tab-padding-block, 0.5rem);
|
|
112
138
|
--dock-tab-padding-inline: var(--dock-density-audacious-tab-padding-inline, 1.5rem);
|
|
113
139
|
--dock-tab-min-height: var(--dock-density-audacious-tab-min-height, 3.5rem);
|
|
140
|
+
--dock-tab-h: var(--dock-density-audacious-tab-min-height, 3.5rem);
|
|
114
141
|
}
|
|
115
142
|
|
|
116
|
-
/*
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
height via `--dock-control-size` (set per density tier above);
|
|
121
|
-
DockTabButton's analogous `--dock-tab-h` knob lives in the same
|
|
122
|
-
density rungs so the tab-button row no longer free-floats to the
|
|
123
|
-
glyph + padding sum. Compact density lands at 32px to match the
|
|
124
|
-
deployed product's bottom-dock height. The `.dock-tab-button` rule
|
|
125
|
-
(further down this file) consumes `--dock-tab-h`. */
|
|
126
|
-
.glass-dock[data-density="compact"] {
|
|
127
|
-
--dock-tab-h-compact: 32px;
|
|
128
|
-
--dock-tab-h: var(--dock-tab-h-compact);
|
|
129
|
-
}
|
|
130
|
-
.glass-dock[data-density="comfortable"] {
|
|
131
|
-
--dock-tab-h-comfortable: 38px;
|
|
132
|
-
--dock-tab-h: var(--dock-tab-h-comfortable);
|
|
133
|
-
}
|
|
134
|
-
.glass-dock[data-density="spacious"] {
|
|
135
|
-
--dock-tab-h-spacious: 44px;
|
|
136
|
-
--dock-tab-h: var(--dock-tab-h-spacious);
|
|
137
|
-
}
|
|
138
|
-
.glass-dock[data-density="audacious"] {
|
|
139
|
-
--dock-tab-h-audacious: var(--dock-density-audacious-tab-min-height, 3.5rem);
|
|
140
|
-
--dock-tab-h: var(--dock-tab-h-audacious);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/* Density-audacious mobile carve (R3-spec / audit-D D-Rec-5;
|
|
144
|
-
consolidated into dock.css at Q.W3 Lane A). At narrow viewports
|
|
145
|
-
the audacious-dock label glyphs compress so the audacious chrome
|
|
146
|
-
doesn't overflow its host: `≤14px at <480` and `15px at 480–719`.
|
|
147
|
-
Consumer dock label spans bind `font-size: var(--dock-label-size)`
|
|
148
|
-
(typography.css `.dock-label` recipe is the canonical consumer). */
|
|
143
|
+
/* Density-audacious mobile carve — at narrow viewports the audacious-dock
|
|
144
|
+
label glyphs compress so the chrome doesn't overflow its host
|
|
145
|
+
(≤14px at <480, 15px at 480–719). Consumer dock label spans bind
|
|
146
|
+
`font-size: var(--dock-label-size)` (typography.css `.dock-label`). */
|
|
149
147
|
@media (max-width: 479px) {
|
|
150
148
|
.glass-dock[data-density="audacious"] {
|
|
151
149
|
--dock-label-size: 14px;
|
|
@@ -188,22 +186,11 @@
|
|
|
188
186
|
border-color var(--dock-motion-standard);
|
|
189
187
|
}
|
|
190
188
|
|
|
191
|
-
/*
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
`dock-wrap`) or to clamp via `--dock-max-block-size` and let the
|
|
197
|
-
cap fail visibly rather than mask the overflow as a scroll
|
|
198
|
-
affordance.
|
|
199
|
-
|
|
200
|
-
The edge-fade `mask-image` retired here in lockstep with the
|
|
201
|
-
horizontal `.dock-layers` rule. With grow-to-fit + visible
|
|
202
|
-
overflow the rail never scrolls, so a scroll-feather mask has
|
|
203
|
-
nothing to feather — it only bled a transparent ramp onto the
|
|
204
|
-
top and bottom rail items, casting a stray directional shadow
|
|
205
|
-
on those edge controls. J.W3.C's auto + mask-fade shape is fully
|
|
206
|
-
superseded: grow-to-fit is the whole contract, no feather. */
|
|
189
|
+
/* Vertical rails grow-to-fit + clamp, no scroll: descendants wrap to
|
|
190
|
+
multiple rows (opt-in via `dock-wrap`) or clamp via
|
|
191
|
+
`--dock-max-block-size`; the cap fails visibly rather than masking
|
|
192
|
+
overflow as a scroll affordance. No edge-fade mask — a rail that never
|
|
193
|
+
scrolls has nothing to feather. */
|
|
207
194
|
.glass-dock.vertical {
|
|
208
195
|
display: inline-flex;
|
|
209
196
|
flex-direction: column;
|
|
@@ -382,23 +369,11 @@
|
|
|
382
369
|
transition: width var(--dock-motion-resize);
|
|
383
370
|
}
|
|
384
371
|
|
|
385
|
-
/*
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
when it shouldn't" — the wrong escape valve.
|
|
391
|
-
|
|
392
|
-
The edge-fade `mask-image` retired here. Once Z.W2.T2 made the
|
|
393
|
-
dock grow-to-fit, content is never clipped and never scrolls, so
|
|
394
|
-
the mask had nothing left to feather — it was kept only "for
|
|
395
|
-
visual symmetry" with the vertical rule. In practice the 1rem
|
|
396
|
-
transparent ramp at each edge bled onto the first and last dock
|
|
397
|
-
items: the rightmost control (e.g. a settings cog) had its outer
|
|
398
|
-
edge faded into the glass backdrop, which read as a stray
|
|
399
|
-
directional shadow on that item. A scroll-affordance feather on
|
|
400
|
-
a surface that never scrolls is pure cosmetic damage, so it is
|
|
401
|
-
removed at the root rather than masked per-consumer. */
|
|
372
|
+
/* Horizontal dock content grows visibly when the active layer's natural
|
|
373
|
+
width exceeds the content area (grow-to-fit; consumers needing wrap opt
|
|
374
|
+
into `dock-wrap`). No edge-fade mask — content never clips or scrolls,
|
|
375
|
+
so a feather has nothing to feather and only bleeds a stray ramp onto
|
|
376
|
+
the edge controls. */
|
|
402
377
|
.glass-dock.expanded:not(.dock-wrap) > .dock-layers {
|
|
403
378
|
overflow-x: visible;
|
|
404
379
|
}
|
|
@@ -650,6 +625,23 @@
|
|
|
650
625
|
min-width: 0;
|
|
651
626
|
}
|
|
652
627
|
|
|
628
|
+
/* AP.W3 — axis-aware layer pane. The stack + `useLayerTransition` are
|
|
629
|
+
axis-aware, but the pane was hardcoded to a no-wrap ROW with
|
|
630
|
+
`width: max-content` — forcing a `vertical` group's content onto one
|
|
631
|
+
horizontal line that could not grow down (the vertical-overflow fight).
|
|
632
|
+
A vertical group stacks in a column, stretches, wraps, and block-sizes
|
|
633
|
+
to the height the stack animates. Horizontal byte-identical. */
|
|
634
|
+
.dock-layer-group.vertical .dock-layer-item-host {
|
|
635
|
+
flex-direction: column;
|
|
636
|
+
align-items: stretch;
|
|
637
|
+
white-space: normal;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
.dock-layer-group.vertical .dock-layer-item-host.is-active {
|
|
641
|
+
width: auto;
|
|
642
|
+
height: max-content;
|
|
643
|
+
}
|
|
644
|
+
|
|
653
645
|
.dock-icon-button {
|
|
654
646
|
display: inline-flex;
|
|
655
647
|
align-items: center;
|
|
@@ -693,9 +685,9 @@
|
|
|
693
685
|
outline: none;
|
|
694
686
|
}
|
|
695
687
|
|
|
688
|
+
/* focus-visible ring + disabled paint hoisted to the shared `:where()`
|
|
689
|
+
group at the top; this rule adds only the box-shadow fade transition. */
|
|
696
690
|
.dock-icon-button:focus-visible {
|
|
697
|
-
box-shadow: var(--focus-ring-shadow);
|
|
698
|
-
outline: none;
|
|
699
691
|
transition:
|
|
700
692
|
background-color var(--dock-motion-fast),
|
|
701
693
|
color var(--dock-motion-fast),
|
|
@@ -704,11 +696,6 @@
|
|
|
704
696
|
box-shadow var(--dock-motion-fast);
|
|
705
697
|
}
|
|
706
698
|
|
|
707
|
-
.dock-icon-button:disabled {
|
|
708
|
-
opacity: var(--opacity-disabled);
|
|
709
|
-
cursor: not-allowed;
|
|
710
|
-
}
|
|
711
|
-
|
|
712
699
|
/* O.W6 Lane B — token-ladder active paint. Defaults match the prior
|
|
713
700
|
hardcoded recipe (--muted bg + --foreground color, no transform / border
|
|
714
701
|
/ shadow). Consumers override the active variant via the
|
|
@@ -841,15 +828,8 @@
|
|
|
841
828
|
box-shadow: none;
|
|
842
829
|
}
|
|
843
830
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
outline: none;
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
.dock-tab-button:disabled {
|
|
850
|
-
opacity: var(--opacity-disabled);
|
|
851
|
-
cursor: not-allowed;
|
|
852
|
-
}
|
|
831
|
+
/* focus-visible ring + disabled paint hoisted to the shared `:where()`
|
|
832
|
+
group at the top. */
|
|
853
833
|
|
|
854
834
|
.dock-tab-button:is(.is-active, .active, [aria-current="page"], [aria-pressed="true"]) {
|
|
855
835
|
background: var(--surface-tint-10);
|
|
@@ -998,10 +978,10 @@
|
|
|
998
978
|
outline: none;
|
|
999
979
|
}
|
|
1000
980
|
|
|
981
|
+
/* focus-visible ring + disabled paint hoisted to the shared `:where()`
|
|
982
|
+
group at the top; this rule adds only the box-shadow fade transition. */
|
|
1001
983
|
.dock-select-trigger:focus-visible,
|
|
1002
984
|
.dock-dropdown-trigger:focus-visible {
|
|
1003
|
-
box-shadow: var(--focus-ring-shadow);
|
|
1004
|
-
outline: none;
|
|
1005
985
|
transition:
|
|
1006
986
|
background-color var(--dock-motion-fast),
|
|
1007
987
|
color var(--dock-motion-fast),
|
|
@@ -1010,12 +990,6 @@
|
|
|
1010
990
|
box-shadow var(--dock-motion-fast);
|
|
1011
991
|
}
|
|
1012
992
|
|
|
1013
|
-
.dock-select-trigger:disabled,
|
|
1014
|
-
.dock-dropdown-trigger:disabled {
|
|
1015
|
-
opacity: var(--opacity-disabled);
|
|
1016
|
-
cursor: not-allowed;
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
993
|
.dock-select-trigger:is(.is-active, .active, [aria-expanded="true"], [aria-pressed="true"]),
|
|
1020
994
|
.dock-dropdown-trigger:is(.is-active, .active, [aria-expanded="true"], [aria-pressed="true"]) {
|
|
1021
995
|
background: var(--muted);
|
|
@@ -1072,12 +1046,15 @@
|
|
|
1072
1046
|
that wires `var(--size-icon-btn)` for trigger sizing) inherit
|
|
1073
1047
|
the same floor.
|
|
1074
1048
|
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1049
|
+
AP.W3 R0G-6 — selector is `.glass-dock[data-density]`, not bare
|
|
1050
|
+
`.glass-dock`: the always-present density setter (0,2,0) shadowed a
|
|
1051
|
+
bare (0,1,0) coarse floor, pinning the touch box at 40px. The
|
|
1052
|
+
presence-selector (0,2,0) wins by source order, lifting
|
|
1053
|
+
`--dock-control-size` to 44px — read by both the button box and the
|
|
1054
|
+
dock width-math, so the slot reserves 44px (no overflow). Fine pointer
|
|
1055
|
+
byte-identical. Proof: design/W1.2-motion-carve-and-dock.md §B.2. */
|
|
1079
1056
|
@media (pointer: coarse) {
|
|
1080
|
-
.glass-dock {
|
|
1057
|
+
.glass-dock[data-density] {
|
|
1081
1058
|
--dock-control-size: var(--dock-touch-target, 2.75rem);
|
|
1082
1059
|
--size-icon-btn: var(--dock-touch-target, 2.75rem);
|
|
1083
1060
|
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* drawer.css — Detented bottom-sheet grammar (AN.W3).
|
|
3
|
+
*
|
|
4
|
+
* vaul-vue owns the snap math (the spring transform between snap-points, the
|
|
5
|
+
* drag-resistance overshoot, the `data-vaul-*` state attributes). glass-ui owns
|
|
6
|
+
* the LOOK: the glass sheet surface, the rounded peek handle, the snap-stop
|
|
7
|
+
* indicator rules, and the drag-resistance feel-tuning. This file is the
|
|
8
|
+
* substrate so a consumer mounting `<Drawer mode="live-behind">` does not
|
|
9
|
+
* re-author the three detents from scratch.
|
|
10
|
+
*
|
|
11
|
+
* Token-first — every visual axis reads a custom property. Consumers retune
|
|
12
|
+
* the sheet by overriding the rungs below, never by editing this file.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
:root {
|
|
16
|
+
/* Detent grammar knobs — overridable per-consumer */
|
|
17
|
+
--drawer-handle-w: 2.25rem;
|
|
18
|
+
--drawer-handle-h: 0.3125rem; /* 5px — vaul's hit-target rhythm */
|
|
19
|
+
--drawer-handle-color: var(--muted-foreground);
|
|
20
|
+
--drawer-handle-opacity: 0.45;
|
|
21
|
+
--drawer-handle-opacity-active: 0.85;
|
|
22
|
+
--drawer-snap-rule-color: color-mix(in srgb, var(--border) 60%, transparent);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/*
|
|
26
|
+
* The sheet surface. Replaces the prior inline-Tailwind triplet on
|
|
27
|
+
* DrawerContent.vue so the glass tier + the snap transform feel live in one
|
|
28
|
+
* token-driven place. The fixed/inset/z-index layout stays here too.
|
|
29
|
+
*
|
|
30
|
+
* NOTE: vaul-vue sets `transition: transform .5s cubic-bezier(.32,.72,0,1)` and
|
|
31
|
+
* `touch-action: none` on `[data-vaul-drawer]` from its injected stylesheet —
|
|
32
|
+
* that IS the drag-resistance spring curve. We do NOT override `transition` so
|
|
33
|
+
* the snap feel is preserved; we layer border-radius + glass surface on top.
|
|
34
|
+
*/
|
|
35
|
+
.glass-drawer {
|
|
36
|
+
position: fixed;
|
|
37
|
+
inset-inline: 0;
|
|
38
|
+
bottom: 0;
|
|
39
|
+
z-index: var(--z-modal);
|
|
40
|
+
display: flex;
|
|
41
|
+
flex-direction: column;
|
|
42
|
+
height: auto;
|
|
43
|
+
max-height: 97vh;
|
|
44
|
+
margin-top: 6rem;
|
|
45
|
+
border: 1px solid var(--border);
|
|
46
|
+
border-bottom: 0;
|
|
47
|
+
border-start-start-radius: var(--radius-panel);
|
|
48
|
+
border-start-end-radius: var(--radius-panel);
|
|
49
|
+
background-color: var(--background);
|
|
50
|
+
box-shadow: var(--shadow-2xl);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/*
|
|
54
|
+
* Detented (snap-point) sheets fill the viewport height. vaul positions the
|
|
55
|
+
* sheet by translating it DOWN by `innerHeight - (fraction * innerHeight)` —
|
|
56
|
+
* so for a snap fraction to read as that fraction OF THE VIEWPORT, the sheet's
|
|
57
|
+
* top must sit at the viewport top when fully open (offset 0). A `height: auto`
|
|
58
|
+
* content sheet would instead translate off-screen. vaul tags the snap case via
|
|
59
|
+
* `[data-vaul-snap-points=true]`; we fill height there and let the content
|
|
60
|
+
* scroll inside.
|
|
61
|
+
*/
|
|
62
|
+
.glass-drawer[data-vaul-snap-points="true"] {
|
|
63
|
+
height: 100%;
|
|
64
|
+
max-height: 100%;
|
|
65
|
+
margin-top: 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* Live-behind direction variants — vaul tags the root with the drag axis.
|
|
69
|
+
Bottom is the default + the F-side pattern; the others ride the same surface
|
|
70
|
+
so a top/side live-behind sheet inherits the grammar. */
|
|
71
|
+
.glass-drawer[data-vaul-drawer-direction="top"] {
|
|
72
|
+
bottom: auto;
|
|
73
|
+
top: 0;
|
|
74
|
+
margin-top: 0;
|
|
75
|
+
margin-bottom: 6rem;
|
|
76
|
+
border-top: 0;
|
|
77
|
+
border-bottom: 1px solid var(--border);
|
|
78
|
+
border-radius: 0 0 var(--radius-panel) var(--radius-panel);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/*
|
|
82
|
+
* Peek handle — the rounded grip at the top of the sheet. It is the visual
|
|
83
|
+
* affordance the user drags to cycle peek → half → full. vaul-vue intensifies
|
|
84
|
+
* the grip on `:active` via its own `[data-vaul-handle]` rules when the consumer
|
|
85
|
+
* uses `<DrawerHandle>`; this is the glass-ui default grip for the common case.
|
|
86
|
+
*/
|
|
87
|
+
.glass-drawer-handle {
|
|
88
|
+
flex-shrink: 0;
|
|
89
|
+
display: flex;
|
|
90
|
+
align-items: center;
|
|
91
|
+
justify-content: center;
|
|
92
|
+
padding-block: 0.75rem 0.5rem;
|
|
93
|
+
touch-action: none;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.glass-drawer-grip {
|
|
97
|
+
display: block;
|
|
98
|
+
width: var(--drawer-handle-w);
|
|
99
|
+
height: var(--drawer-handle-h);
|
|
100
|
+
border-radius: var(--radius-pill);
|
|
101
|
+
background-color: var(--drawer-handle-color);
|
|
102
|
+
opacity: var(--drawer-handle-opacity);
|
|
103
|
+
transition: opacity var(--duration-fast) var(--ease-out),
|
|
104
|
+
width var(--duration-fast) var(--ease-out);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* While the sheet is being dragged vaul exposes the gesture; intensify the grip
|
|
108
|
+
so the affordance reads as "live". `:active` covers the pointer-held case for
|
|
109
|
+
the default grip; consumers using vaul's `<DrawerHandle>` get its own active
|
|
110
|
+
rule in addition. */
|
|
111
|
+
.glass-drawer-handle:active .glass-drawer-grip,
|
|
112
|
+
.glass-drawer:hover .glass-drawer-grip {
|
|
113
|
+
opacity: var(--drawer-handle-opacity-active);
|
|
114
|
+
width: calc(var(--drawer-handle-w) * 1.15);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/*
|
|
118
|
+
* Snap-stop indicators — subtle full-width hairline rules that mark where the
|
|
119
|
+
* sheet content sections break across detents. A consumer opts in by adding
|
|
120
|
+
* `.glass-drawer-snap-rule` to a separator element inside the sheet; it reads as
|
|
121
|
+
* the detent boundary line without competing with the content. This is the
|
|
122
|
+
* "snap-stop visual indicator" the spec asks for, expressed as an opt-in class
|
|
123
|
+
* (the detents themselves are positional, owned by vaul; the RULE is the look).
|
|
124
|
+
*/
|
|
125
|
+
.glass-drawer-snap-rule {
|
|
126
|
+
height: 1px;
|
|
127
|
+
margin-inline: calc(var(--radius-panel) * -0.5);
|
|
128
|
+
border: 0;
|
|
129
|
+
background-color: var(--drawer-snap-rule-color);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Reduced-motion — vaul's transform transition is its own; we only suppress the
|
|
133
|
+
grip's affordance animation so the handle does not pulse for PRM users. */
|
|
134
|
+
@media (prefers-reduced-motion: reduce) {
|
|
135
|
+
.glass-drawer-grip {
|
|
136
|
+
transition: none;
|
|
137
|
+
}
|
|
138
|
+
}
|
package/dist/styles/index.css
CHANGED
|
@@ -4,9 +4,18 @@
|
|
|
4
4
|
* Import this in your project's main CSS file:
|
|
5
5
|
* @import "tailwindcss";
|
|
6
6
|
* @import "tw-animate-css";
|
|
7
|
-
* @import "@mkbabb/glass-ui/styles"; (
|
|
7
|
+
* @import "@mkbabb/glass-ui/styles"; (token cascade + SFC scoped CSS)
|
|
8
8
|
* @import "@mkbabb/glass-ui/styles/fonts"; (OFL woff2 corpus, loaded once)
|
|
9
9
|
* (then add your project-specific token overrides locally)
|
|
10
|
+
*
|
|
11
|
+
* AN.W1 — the single `@mkbabb/glass-ui/styles` import resolves the COMPLETE
|
|
12
|
+
* stylesheet: this @import cascade PLUS the per-component `<style scoped>`
|
|
13
|
+
* payload (Aurora grid layering, Progress/Slider/Notification/… scoped rules).
|
|
14
|
+
* The build folds the SFC bundle (`dist/glass-ui.css`) into the dist copy of
|
|
15
|
+
* this file (vite.config.ts `publishStyleAssets`), so a consumer never needs
|
|
16
|
+
* a second `@import "@mkbabb/glass-ui/styles.css"` line. The `./styles.css`
|
|
17
|
+
* export stays reachable as a transparent SFC-only entry (NOT a back-compat
|
|
18
|
+
* alias) for a cascade-free consumer.
|
|
10
19
|
*/
|
|
11
20
|
|
|
12
21
|
/*
|
|
@@ -69,8 +78,10 @@
|
|
|
69
78
|
* 14. glyph-face.css — P-tranche component CSS (cap + backplate).
|
|
70
79
|
* 15. disco-glyph.css — P-tranche component CSS (layered fills).
|
|
71
80
|
* 16. hover-popover.css — V.W3 popover-animation grammar.
|
|
81
|
+
* 17. drawer.css — AN.W3 detented bottom-sheet grammar (glass
|
|
82
|
+
* sheet surface + peek handle + snap-stop rules).
|
|
72
83
|
*
|
|
73
|
-
* Per-package component CSS lives at (12)-(
|
|
84
|
+
* Per-package component CSS lives at (12)-(17) (loaded after utilities so
|
|
74
85
|
* component-local recipes can override). New per-package CSS files append
|
|
75
86
|
* to that tail.
|
|
76
87
|
*/
|
|
@@ -90,7 +101,12 @@
|
|
|
90
101
|
@import "./glyph-face.css";
|
|
91
102
|
@import "./disco-glyph.css";
|
|
92
103
|
@import "./hover-popover.css";
|
|
104
|
+
@import "./drawer.css";
|
|
93
105
|
|
|
94
106
|
/* Ensure consumer's Tailwind scans glass-ui components for utility classes
|
|
95
107
|
(e.g. CVA button variants like text-destructive-foreground) */
|
|
108
|
+
/* AN.W1 — SFC scoped component CSS (folded so a single
|
|
109
|
+
@import "@mkbabb/glass-ui/styles" carries cascade + components) */
|
|
110
|
+
@import "../glass-ui.css";
|
|
111
|
+
|
|
96
112
|
@source "../components";
|
|
@@ -292,7 +292,34 @@
|
|
|
292
292
|
@media (max-width: 720px) {
|
|
293
293
|
.instrument-chassis .instrument-dial {
|
|
294
294
|
grid-template-columns: 1fr;
|
|
295
|
-
|
|
295
|
+
/* R0G-2 (AO.W3) — reserve the dial's FINAL box from frame 0. The
|
|
296
|
+
desktop axis is already CLS-clean (the 3-column `align-items:
|
|
297
|
+
center` grid reserves row height from intrinsic min + the AP-Pγ
|
|
298
|
+
transform-only idle recentre). The mobile reflow previously
|
|
299
|
+
collapsed to `grid-template-rows: auto auto auto`, which reserves
|
|
300
|
+
NO height — the meter row, divider, and readout column sit at
|
|
301
|
+
zero height until the consumer's meter <canvas> + readout
|
|
302
|
+
numbers hydrate, then grow collapsed → final and push everything
|
|
303
|
+
below down ~326-331px → mobile-390 CLS 0.32-0.38.
|
|
304
|
+
|
|
305
|
+
The fix pins the dial box from frame 0: the meter row carries the
|
|
306
|
+
dominant reserve (`minmax(0, 1fr)` — it expands to fill the
|
|
307
|
+
envelope the `min-height` establishes), divider + readout stay
|
|
308
|
+
intrinsic (`auto`). The load-bearing reserve is `min-height` —
|
|
309
|
+
it fixes the dial's outer box so the rows distribute WITHIN a
|
|
310
|
+
reserved envelope rather than growing it post-hydration.
|
|
311
|
+
|
|
312
|
+
Both knobs are CSS custom properties (token-first). The
|
|
313
|
+
`--instrument-dial-min-height-mobile` canonical rung lands in
|
|
314
|
+
tokens.css at AO.W4; until then the inline `24rem` fallback IS
|
|
315
|
+
the default and carries the contract. A consumer whose meter is
|
|
316
|
+
a different size retunes the token — a tuning knob, not a
|
|
317
|
+
workaround for a missing reserve. */
|
|
318
|
+
grid-template-rows:
|
|
319
|
+
var(--instrument-dial-meter-reserve-mobile, minmax(0, 1fr))
|
|
320
|
+
auto
|
|
321
|
+
auto;
|
|
322
|
+
min-height: var(--instrument-dial-min-height-mobile, 24rem);
|
|
296
323
|
gap: var(--instrument-dial-gap-mobile, 1.5rem);
|
|
297
324
|
}
|
|
298
325
|
|
package/dist/styles/theme.css
CHANGED
|
@@ -81,6 +81,9 @@
|
|
|
81
81
|
--color-card: var(--card);
|
|
82
82
|
--color-card-foreground: var(--card-foreground);
|
|
83
83
|
|
|
84
|
+
/* R0G-5 — bg-surface-public-data-panel utility. */
|
|
85
|
+
--color-surface-public-data-panel: var(--surface-public-data-panel);
|
|
86
|
+
|
|
84
87
|
--color-shadow: var(--shadow);
|
|
85
88
|
|
|
86
89
|
/* Semantic foregrounds — bg-{success,warning,info}-foreground +
|