@mks2508/mks-ui 0.5.2 → 0.5.4
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/react-ui/index.js +8 -3
- package/dist/react-ui/primitives/index.js +5 -0
- package/dist/react-ui/primitives/waapi/Gooey/Gooey.types.d.ts +103 -0
- package/dist/react-ui/primitives/waapi/Gooey/Gooey.types.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.d.ts +10 -0
- package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.js +59 -0
- package/dist/react-ui/primitives/waapi/Gooey/GooeyFilter.d.ts +7 -0
- package/dist/react-ui/primitives/waapi/Gooey/GooeyFilter.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Gooey/GooeyFilter.js +78 -0
- package/dist/react-ui/primitives/waapi/Gooey/MorphPath.d.ts +7 -0
- package/dist/react-ui/primitives/waapi/Gooey/MorphPath.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Gooey/MorphPath.js +51 -0
- package/dist/react-ui/primitives/waapi/Gooey/gooey-utils.d.ts +87 -0
- package/dist/react-ui/primitives/waapi/Gooey/gooey-utils.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Gooey/gooey-utils.js +177 -0
- package/dist/react-ui/primitives/waapi/Gooey/index.d.ts +28 -0
- package/dist/react-ui/primitives/waapi/Gooey/index.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Gooey/index.js +5 -0
- package/dist/react-ui/primitives/waapi/Gooey/useMorphPath.d.ts +7 -0
- package/dist/react-ui/primitives/waapi/Gooey/useMorphPath.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Gooey/useMorphPath.js +47 -0
- package/dist/react-ui/primitives/waapi/index.d.ts +2 -0
- package/dist/react-ui/primitives/waapi/index.d.ts.map +1 -1
- package/dist/react-ui/primitives/waapi/index.js +6 -0
- package/dist/react-ui/ui/DataCard/DataCard.styles.d.ts +26 -16
- package/dist/react-ui/ui/DataCard/DataCard.styles.d.ts.map +1 -1
- package/dist/react-ui/ui/DataCard/DataCard.styles.js +36 -74
- package/dist/react-ui/ui/DataCard/DataCard.types.d.ts +50 -70
- package/dist/react-ui/ui/DataCard/DataCard.types.d.ts.map +1 -1
- package/dist/react-ui/ui/DataCard/index.d.ts +24 -93
- package/dist/react-ui/ui/DataCard/index.d.ts.map +1 -1
- package/dist/react-ui/ui/DataCard/index.js +76 -118
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle-Cm6-VceQ.css +304 -0
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.css +303 -0
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.js +0 -0
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.d.ts +20 -8
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.d.ts.map +1 -1
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.js +55 -27
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.types.d.ts +63 -14
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.types.d.ts.map +1 -1
- package/dist/react-ui/ui/DynamicToggle/index.d.ts +22 -20
- package/dist/react-ui/ui/DynamicToggle/index.d.ts.map +1 -1
- package/dist/react-ui/ui/DynamicToggle/index.js +115 -96
- package/dist/react-ui/ui/Switch/index.js +1 -1
- package/dist/react-ui/ui/index.js +2 -2
- package/package.json +2 -2
- package/src/css.d.ts +1 -0
- package/src/react-ui/primitives/waapi/Gooey/Gooey.types.ts +123 -0
- package/src/react-ui/primitives/waapi/Gooey/GooeyCanvas.tsx +80 -0
- package/src/react-ui/primitives/waapi/Gooey/GooeyFilter.tsx +77 -0
- package/src/react-ui/primitives/waapi/Gooey/MorphPath.tsx +58 -0
- package/src/react-ui/primitives/waapi/Gooey/gooey-utils.ts +244 -0
- package/src/react-ui/primitives/waapi/Gooey/index.ts +50 -0
- package/src/react-ui/primitives/waapi/Gooey/useMorphPath.ts +48 -0
- package/src/react-ui/primitives/waapi/index.ts +23 -0
- package/src/react-ui/ui/DataCard/DataCard.styles.ts +45 -101
- package/src/react-ui/ui/DataCard/DataCard.types.ts +52 -73
- package/src/react-ui/ui/DataCard/index.tsx +118 -184
- package/src/react-ui/ui/DynamicToggle/DynamicToggle.css +244 -91
- package/src/react-ui/ui/DynamicToggle/DynamicToggle.styles.ts +60 -40
- package/src/react-ui/ui/DynamicToggle/DynamicToggle.types.ts +95 -14
- package/src/react-ui/ui/DynamicToggle/index.tsx +150 -96
- package/src/react-ui/ui/DynamicToggle/prototype-v7.html +615 -0
- package/src/react-ui/ui/DynamicToggle/prototype.html +419 -0
- package/src/react-ui/ui/Switch/index.tsx +1 -1
- /package/dist/react-ui/blocks/Terminal/panel/{terminal-filter-dropdown.module-DAcl_XQZ.css → terminal-filter-dropdown.module-C6oDcFBS.css} +0 -0
- /package/dist/react-ui/blocks/Terminal/panel/{terminal-session-tabs.module-DNAop5e3.css → terminal-session-tabs.module-D_-sgyza.css} +0 -0
- /package/dist/react-ui/components/MorphingPopover/{morphing-popover.module-BJrjXisF.css → morphing-popover.module-B1ftlaYj.css} +0 -0
|
@@ -1,150 +1,303 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* DynamicToggle — CSS
|
|
2
|
+
* DynamicToggle — CSS state transitions.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Rules requiring :has(), container queries, clip-path, or pseudo-elements.
|
|
5
|
+
* Layout, colors, sizing in Tailwind (DynamicToggle.styles.ts).
|
|
6
|
+
*
|
|
7
|
+
* @import '@mks2508/mks-ui/dist/react-ui/ui/DynamicToggle/DynamicToggle.css';
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
/* ── Variables ── */
|
|
11
|
+
[data-slot="dt-root"] {
|
|
12
|
+
--dt-dur: 0.22s;
|
|
11
13
|
--dt-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
|
|
12
|
-
--dt-
|
|
14
|
+
--dt-fade: 0.45;
|
|
13
15
|
}
|
|
14
16
|
|
|
15
|
-
/* ── Track
|
|
16
|
-
[data-slot="dt-track"] {
|
|
17
|
-
grid-template-
|
|
17
|
+
/* ── Track: explicit row prevents h-full items from overflowing container ── */
|
|
18
|
+
[data-slot="dt-root"] [data-slot="dt-track"] {
|
|
19
|
+
grid-template-rows: minmax(0, 1fr);
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
[data-slot="dt-
|
|
22
|
+
/* ── Top-level option spans 2 grid cols ── */
|
|
23
|
+
[data-slot="dt-root"] [data-slot="dt-track"] > label {
|
|
22
24
|
grid-column: span 2;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
/* ── Main indicator slide ── */
|
|
26
|
-
[data-slot="dt-indicator"] {
|
|
27
|
-
transition: translate var(--dt-
|
|
28
|
+
[data-slot="dt-root"] [data-slot="dt-indicator"] {
|
|
29
|
+
transition: translate var(--dt-dur) var(--dt-ease);
|
|
30
|
+
translate: 100% 0;
|
|
28
31
|
}
|
|
29
|
-
|
|
30
|
-
/* When primary (non-group) is checked → indicator on left */
|
|
31
|
-
[data-slot="dt-track"]:has(> input:checked) [data-slot="dt-indicator"] {
|
|
32
|
+
[data-slot="dt-root"] [data-slot="dt-track"]:has(> input:checked) [data-slot="dt-indicator"] {
|
|
32
33
|
translate: 0 0;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
/* When nothing in track is checked → group is active → indicator slides right */
|
|
36
|
-
[data-slot="dt-track"]:not(:has(> input:checked)) [data-slot="dt-indicator"] {
|
|
37
|
-
translate: 100% 0;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
36
|
/* ── Primary option text ── */
|
|
41
|
-
[data-slot="dt-track"]:has(> input:checked) > label {
|
|
37
|
+
[data-slot="dt-root"] [data-slot="dt-track"]:has(> input:checked) > label {
|
|
42
38
|
color: var(--card);
|
|
39
|
+
z-index: 2;
|
|
43
40
|
}
|
|
44
|
-
|
|
45
|
-
[data-slot="dt-track"]:not(:has(> input:checked)) > label {
|
|
41
|
+
[data-slot="dt-root"] [data-slot="dt-track"]:not(:has(> input:checked)) > label {
|
|
46
42
|
color: var(--foreground);
|
|
47
|
-
opacity: var(--dt-
|
|
43
|
+
opacity: var(--dt-fade);
|
|
48
44
|
}
|
|
49
45
|
|
|
50
|
-
/* ── Group container ── */
|
|
51
|
-
[data-slot="dt-group"] {
|
|
46
|
+
/* ── Group: container queries ── */
|
|
47
|
+
[data-slot="dt-root"] [data-slot="dt-group"] {
|
|
52
48
|
container-type: size;
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/* ── Group collapsed label ("Changes") ── */
|
|
57
|
-
[data-slot="dt-group-label"] {
|
|
58
|
-
translate: -50% -80%;
|
|
59
|
-
transition: translate var(--dt-duration) var(--dt-ease),
|
|
60
|
-
scale var(--dt-duration) var(--dt-ease);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/* When group is active → label moves up and shrinks */
|
|
64
|
-
[data-slot="dt-group"]:has(input:checked) [data-slot="dt-group-label"] {
|
|
65
|
-
translate: -50% -250%;
|
|
66
|
-
scale: 0.85;
|
|
49
|
+
overflow: hidden;
|
|
67
50
|
}
|
|
68
51
|
|
|
69
|
-
/* ── Group
|
|
70
|
-
[data-slot="dt-group-indicator"] {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
52
|
+
/* ── Group indicator: clip-path reveal ── */
|
|
53
|
+
[data-slot="dt-root"] [data-slot="dt-group-indicator"] {
|
|
54
|
+
pointer-events: none;
|
|
55
|
+
transition:
|
|
56
|
+
translate var(--dt-dur) var(--dt-ease),
|
|
57
|
+
clip-path var(--dt-dur) var(--dt-ease),
|
|
58
|
+
background var(--dt-dur) var(--dt-ease);
|
|
59
|
+
clip-path: inset(
|
|
60
|
+
73cqh calc(50% + 1px) calc(27cqh - 2px) calc(50% - 3px)
|
|
61
|
+
round var(--dt-radius, 9999px)
|
|
62
|
+
);
|
|
76
63
|
translate: -50% 0;
|
|
77
|
-
background: var(--foreground);
|
|
78
64
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
65
|
+
[data-slot="dt-root"] [data-slot="dt-track"]:has(> input:checked) [data-slot="dt-group-indicator"] {
|
|
66
|
+
background: transparent;
|
|
67
|
+
}
|
|
68
|
+
[data-slot="dt-root"] [data-slot="dt-group"]:has(input:checked) [data-slot="dt-group-indicator"] {
|
|
82
69
|
background: var(--card);
|
|
83
|
-
clip-path: inset(0 0 0 0 round
|
|
70
|
+
clip-path: inset(0 0 0 0 round var(--dt-radius, 9999px));
|
|
84
71
|
}
|
|
85
|
-
|
|
86
|
-
/* First sub-option checked → indicator left */
|
|
87
|
-
[data-slot="dt-group"]:has(input:nth-of-type(1):checked) [data-slot="dt-group-indicator"] {
|
|
72
|
+
[data-slot="dt-root"] [data-slot="dt-group"]:has(input:nth-of-type(1):checked) [data-slot="dt-group-indicator"] {
|
|
88
73
|
translate: -100% 0;
|
|
89
74
|
}
|
|
90
|
-
|
|
91
|
-
/* Second sub-option checked → indicator right */
|
|
92
|
-
[data-slot="dt-group"]:has(input:nth-of-type(2):checked) [data-slot="dt-group-indicator"] {
|
|
75
|
+
[data-slot="dt-root"] [data-slot="dt-group"]:has(input:nth-of-type(2):checked) [data-slot="dt-group-indicator"] {
|
|
93
76
|
translate: 0 0;
|
|
94
77
|
}
|
|
95
78
|
|
|
96
|
-
/*
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
79
|
+
/* ══════════════════════════════════════════════════════════
|
|
80
|
+
* GROUP COLLAPSED STATE
|
|
81
|
+
*
|
|
82
|
+
* ::before = title text (via data-label attr)
|
|
83
|
+
* ::after = combined opts text (via data-opts attr)
|
|
84
|
+
* <label>s = controlled by data-collapsed mode
|
|
85
|
+
*
|
|
86
|
+
* 3 modes: title | opts | title-opts (default)
|
|
87
|
+
* ══════════════════════════════════════════════════════════ */
|
|
88
|
+
|
|
89
|
+
/* ── ::before — group title ── */
|
|
90
|
+
[data-slot="dt-group"]::before {
|
|
91
|
+
content: attr(data-label);
|
|
92
|
+
position: absolute;
|
|
93
|
+
left: 50%;
|
|
94
|
+
top: 50%;
|
|
95
|
+
translate: -50% -80%;
|
|
96
|
+
color: var(--foreground);
|
|
97
|
+
font-size: inherit;
|
|
98
|
+
font-weight: 500;
|
|
99
|
+
z-index: 2;
|
|
100
|
+
white-space: nowrap;
|
|
101
|
+
pointer-events: none;
|
|
102
|
+
transition:
|
|
103
|
+
scale var(--dt-dur) var(--dt-ease),
|
|
104
|
+
translate var(--dt-dur) var(--dt-ease),
|
|
105
|
+
opacity var(--dt-dur) var(--dt-ease);
|
|
101
106
|
}
|
|
102
107
|
|
|
103
|
-
|
|
104
|
-
|
|
108
|
+
/* ── ::after — combined opts text ── */
|
|
109
|
+
[data-slot="dt-group"]::after {
|
|
110
|
+
content: attr(data-opts);
|
|
111
|
+
position: absolute;
|
|
112
|
+
left: 50%;
|
|
113
|
+
top: 50%;
|
|
114
|
+
translate: -50% 20%;
|
|
115
|
+
color: var(--muted-foreground);
|
|
116
|
+
font-size: 0.85em;
|
|
117
|
+
opacity: 0.6;
|
|
118
|
+
z-index: 2;
|
|
119
|
+
white-space: nowrap;
|
|
120
|
+
pointer-events: none;
|
|
121
|
+
transition: opacity var(--dt-dur) var(--dt-ease);
|
|
122
|
+
}
|
|
123
|
+
[data-slot="dt-group"]:not([data-opts])::after {
|
|
124
|
+
content: none;
|
|
105
125
|
}
|
|
106
126
|
|
|
107
|
-
/*
|
|
108
|
-
[data-slot="dt-
|
|
127
|
+
/* ── Group labels — transition props ── */
|
|
128
|
+
[data-slot="dt-root"] [data-slot="dt-group"] label {
|
|
109
129
|
color: var(--muted-foreground);
|
|
130
|
+
cursor: pointer;
|
|
131
|
+
z-index: 2;
|
|
132
|
+
transition:
|
|
133
|
+
color var(--dt-dur) var(--dt-ease),
|
|
134
|
+
opacity var(--dt-dur) var(--dt-ease),
|
|
135
|
+
translate var(--dt-dur) var(--dt-ease);
|
|
136
|
+
}
|
|
137
|
+
[data-slot="dt-root"] [data-slot="dt-group"] label span {
|
|
138
|
+
display: grid;
|
|
139
|
+
place-items: center;
|
|
140
|
+
height: 100%;
|
|
141
|
+
width: 100%;
|
|
142
|
+
border-radius: var(--dt-radius, 9999px);
|
|
143
|
+
transition: scale var(--dt-dur) var(--dt-ease);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/* ── Collapsed mode: "title" — only ::before, labels slide+scale out ── */
|
|
147
|
+
[data-slot="dt-group"][data-collapsed="title"]::before {
|
|
148
|
+
translate: -50% -50%;
|
|
149
|
+
}
|
|
150
|
+
[data-slot="dt-group"][data-collapsed="title"]::after {
|
|
151
|
+
display: none;
|
|
152
|
+
}
|
|
153
|
+
[data-slot="dt-group"][data-collapsed="title"]:not(:has(input:checked)) label {
|
|
154
|
+
opacity: 0;
|
|
155
|
+
translate: 0 30%;
|
|
156
|
+
}
|
|
157
|
+
[data-slot="dt-group"][data-collapsed="title"]:not(:has(input:checked)) label span {
|
|
158
|
+
scale: 0.5;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* ── Collapsed mode: "opts" — only ::after, labels slide+scale out ── */
|
|
162
|
+
[data-slot="dt-group"][data-collapsed="opts"]::before {
|
|
163
|
+
display: none;
|
|
164
|
+
}
|
|
165
|
+
[data-slot="dt-group"][data-collapsed="opts"]::after {
|
|
166
|
+
translate: -50% -50%;
|
|
167
|
+
font-size: inherit;
|
|
168
|
+
opacity: 0.7;
|
|
169
|
+
}
|
|
170
|
+
[data-slot="dt-group"][data-collapsed="opts"]:not(:has(input:checked)) label {
|
|
171
|
+
opacity: 0;
|
|
172
|
+
translate: 0 30%;
|
|
173
|
+
}
|
|
174
|
+
[data-slot="dt-group"][data-collapsed="opts"]:not(:has(input:checked)) label span {
|
|
175
|
+
scale: 0.5;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/* ── Collapsed mode: "title-opts" — WIP: disabled, falls back to "title" behavior ── */
|
|
179
|
+
/* TODO: title-opts needs a redesign — title (::before) and scaled labels overlap
|
|
180
|
+
at all container sizes. The codepen original morph relied on specific dimensions
|
|
181
|
+
that don't translate to the component's size variants. Needs a different approach
|
|
182
|
+
(e.g., crossfade, flex layout, or JS-measured positions). */
|
|
183
|
+
[data-slot="dt-group"][data-collapsed="title-opts"]::after {
|
|
184
|
+
content: none;
|
|
185
|
+
}
|
|
186
|
+
[data-slot="dt-group"][data-collapsed="title-opts"]::before {
|
|
187
|
+
translate: -50% -50%;
|
|
188
|
+
}
|
|
189
|
+
[data-slot="dt-group"][data-collapsed="title-opts"]:not(:has(input:checked)) label {
|
|
190
|
+
opacity: 0;
|
|
191
|
+
translate: 0 30%;
|
|
110
192
|
}
|
|
111
193
|
|
|
112
|
-
/* When group
|
|
194
|
+
/* ── When group expanded ── */
|
|
195
|
+
[data-slot="dt-group"]:has(input:checked)::before {
|
|
196
|
+
translate: -50% -250%;
|
|
197
|
+
scale: 0.85;
|
|
198
|
+
}
|
|
199
|
+
[data-slot="dt-group"]:has(input:checked)::after {
|
|
200
|
+
opacity: 0;
|
|
201
|
+
}
|
|
113
202
|
[data-slot="dt-group"]:has(input:checked) label {
|
|
114
|
-
color: var(--muted-foreground);
|
|
115
203
|
opacity: 0.75;
|
|
204
|
+
color: var(--muted-foreground);
|
|
205
|
+
translate: 0 0;
|
|
206
|
+
}
|
|
207
|
+
[data-slot="dt-group"]:has(input:checked) label span {
|
|
208
|
+
scale: 1;
|
|
116
209
|
}
|
|
117
|
-
|
|
118
210
|
[data-slot="dt-group"]:has(input:nth-of-type(1):checked) label:nth-of-type(1),
|
|
119
211
|
[data-slot="dt-group"]:has(input:nth-of-type(2):checked) label:nth-of-type(2) {
|
|
120
212
|
color: var(--foreground);
|
|
121
213
|
opacity: 1;
|
|
122
214
|
}
|
|
123
215
|
|
|
124
|
-
/*
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
216
|
+
/* ══════════════════════════════════════════════════════════
|
|
217
|
+
* GROUP LABEL (above/below the pill)
|
|
218
|
+
*
|
|
219
|
+
* Replaces the old "bubble" element. Positioned via CSS grid.
|
|
220
|
+
* In filter/path morph modes, rendered inside GooeyCanvas.
|
|
221
|
+
* In none mode, simple CSS-driven show/hide.
|
|
222
|
+
* ══════════════════════════════════════════════════════════ */
|
|
223
|
+
|
|
224
|
+
[data-slot="dt-group-label"] {
|
|
225
|
+
display: grid;
|
|
226
|
+
grid-template-rows: 0fr;
|
|
227
|
+
left: 20%;
|
|
228
|
+
right: 20%;
|
|
229
|
+
transition:
|
|
230
|
+
grid-template-rows calc(var(--dt-dur) * 1.5) var(--dt-ease),
|
|
231
|
+
opacity var(--dt-dur) var(--dt-ease);
|
|
232
|
+
opacity: 0;
|
|
233
|
+
background: var(--card);
|
|
234
|
+
border: 1px solid var(--border);
|
|
235
|
+
z-index: 3;
|
|
236
|
+
}
|
|
237
|
+
[data-slot="dt-group-label"] > span {
|
|
238
|
+
overflow: hidden;
|
|
239
|
+
min-height: 0;
|
|
240
|
+
display: flex;
|
|
241
|
+
align-items: center;
|
|
242
|
+
justify-content: center;
|
|
243
|
+
padding: 0 0.75em;
|
|
244
|
+
height: calc(var(--dt-h, 38px) * 0.4);
|
|
245
|
+
box-sizing: border-box;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/* Top position */
|
|
249
|
+
[data-slot="dt-group-label"][data-position="top"] {
|
|
250
|
+
bottom: 100%;
|
|
251
|
+
border-radius: calc(var(--dt-h, 38px) * 0.2) calc(var(--dt-h, 38px) * 0.2) 0 0;
|
|
252
|
+
border-bottom: none;
|
|
253
|
+
margin-bottom: -1px;
|
|
128
254
|
}
|
|
129
255
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
256
|
+
/* Bottom position */
|
|
257
|
+
[data-slot="dt-group-label"][data-position="bottom"] {
|
|
258
|
+
top: 100%;
|
|
259
|
+
border-radius: 0 0 calc(var(--dt-h, 38px) * 0.2) calc(var(--dt-h, 38px) * 0.2);
|
|
260
|
+
border-top: none;
|
|
261
|
+
margin-top: -1px;
|
|
133
262
|
}
|
|
134
263
|
|
|
135
|
-
|
|
264
|
+
/* When group active → group label grows */
|
|
265
|
+
[data-slot="dt-root"]:not(:has([data-slot="dt-track"] > input:checked)) [data-slot="dt-group-label"] {
|
|
266
|
+
grid-template-rows: 1fr;
|
|
267
|
+
opacity: 1;
|
|
268
|
+
}
|
|
269
|
+
[data-slot="dt-root"]:not(:has([data-slot="dt-track"] > input:checked)) [data-slot="dt-group-label"] > span {
|
|
270
|
+
padding: 0.35em 0.75em;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/* ── Filter morph mode ── */
|
|
274
|
+
[data-slot="dt-root"][data-morph="filter"] {
|
|
275
|
+
background: transparent;
|
|
276
|
+
border-color: transparent;
|
|
277
|
+
box-shadow: none;
|
|
278
|
+
overflow: visible;
|
|
279
|
+
}
|
|
280
|
+
[data-slot="dt-root"][data-morph="filter"] [data-slot="dt-group-label"] {
|
|
281
|
+
border: none;
|
|
282
|
+
}
|
|
283
|
+
[data-slot="dt-root"][data-morph="filter"] [data-slot="dt-track"] {
|
|
284
|
+
position: relative;
|
|
285
|
+
z-index: 1;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/* ── Filter morph: ::before hides on expand, gooey canvas handles junction ── */
|
|
289
|
+
[data-slot="dt-root"][data-morph="filter"] [data-slot="dt-group"]:has(input:checked)::before {
|
|
290
|
+
opacity: 0;
|
|
291
|
+
translate: -50% -80%;
|
|
136
292
|
scale: 1;
|
|
137
293
|
}
|
|
138
294
|
|
|
139
|
-
/* ──
|
|
140
|
-
[data-slot="dt-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
clip: rect(0, 0, 0, 0);
|
|
148
|
-
white-space: nowrap;
|
|
149
|
-
border-width: 0;
|
|
295
|
+
/* ── Path morph mode ── */
|
|
296
|
+
[data-slot="dt-root"][data-morph="path"] {
|
|
297
|
+
background: transparent;
|
|
298
|
+
border-color: transparent;
|
|
299
|
+
}
|
|
300
|
+
[data-slot="dt-root"][data-morph="path"] [data-slot="dt-track"] {
|
|
301
|
+
position: relative;
|
|
302
|
+
z-index: 1;
|
|
150
303
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* DynamicToggle style slots
|
|
2
|
+
* DynamicToggle style slots + CVA variants.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Layout via Tailwind. State animations via CSS file (`:has()`, `clip-path`).
|
|
5
|
+
* Shape propagated to indicators via `--dt-radius` CSS variable.
|
|
6
6
|
*
|
|
7
7
|
* @module @mks2508/mks-ui/react/ui/DynamicToggle
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
10
11
|
import type { StyleSlots } from '@/core/types';
|
|
11
12
|
|
|
12
13
|
/** Slot names for DynamicToggle */
|
|
@@ -16,50 +17,69 @@ export type DynamicToggleSlot =
|
|
|
16
17
|
| 'option'
|
|
17
18
|
| 'indicator'
|
|
18
19
|
| 'group'
|
|
19
|
-
| '
|
|
20
|
-
| '
|
|
20
|
+
| 'groupIndicator'
|
|
21
|
+
| 'groupLabel';
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Default styles for each DynamicToggle slot.
|
|
24
25
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* <DynamicToggle slots={{ root: 'w-72', indicator: 'bg-primary' }}>
|
|
28
|
-
* ...
|
|
29
|
-
* </DynamicToggle>
|
|
30
|
-
* ```
|
|
26
|
+
* Width is set by size variants — required because indicator uses `width: 50%`
|
|
27
|
+
* and clip-path uses container query units. Override: `slots={{ root: 'w-80' }}`.
|
|
31
28
|
*/
|
|
32
29
|
export const dynamicToggleStyles: StyleSlots<DynamicToggleSlot> = {
|
|
33
|
-
root: [
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
'w-full h-full',
|
|
40
|
-
].join(' '),
|
|
41
|
-
option: [
|
|
42
|
-
'inline-grid place-items-center cursor-pointer',
|
|
43
|
-
'text-xs font-medium z-[2] h-full w-full',
|
|
44
|
-
'transition-[color,opacity] duration-[220ms]',
|
|
45
|
-
].join(' '),
|
|
46
|
-
indicator: [
|
|
47
|
-
'absolute w-1/2 left-0 top-0 bottom-0',
|
|
48
|
-
'bg-foreground rounded-full',
|
|
49
|
-
'pointer-events-none z-0',
|
|
50
|
-
].join(' '),
|
|
51
|
-
group: [
|
|
52
|
-
'relative w-full h-full grid',
|
|
53
|
-
'border border-transparent',
|
|
54
|
-
].join(' '),
|
|
30
|
+
root: 'relative border p-[2px] select-none',
|
|
31
|
+
track: 'relative grid grid-cols-[repeat(4,1fr)] place-items-center w-full h-full',
|
|
32
|
+
option: 'inline-grid place-items-center cursor-pointer font-medium z-[2] h-full w-full whitespace-nowrap',
|
|
33
|
+
indicator: 'absolute w-1/2 left-0 top-0 bottom-0 bg-foreground rounded-[var(--dt-radius,9999px)] pointer-events-none z-0',
|
|
34
|
+
group: 'col-span-2 relative w-full h-full grid grid-cols-2',
|
|
35
|
+
groupIndicator: 'absolute left-1/2 top-0 bottom-0 w-1/2 bg-foreground rounded-[var(--dt-radius,9999px)] pointer-events-none z-0',
|
|
55
36
|
groupLabel: [
|
|
56
|
-
'absolute
|
|
57
|
-
'
|
|
37
|
+
'absolute',
|
|
38
|
+
'flex items-center justify-center',
|
|
39
|
+
'text-muted-foreground font-medium whitespace-nowrap',
|
|
58
40
|
'pointer-events-none',
|
|
59
41
|
].join(' '),
|
|
60
|
-
groupIndicator: [
|
|
61
|
-
'absolute left-1/2 top-0 bottom-0',
|
|
62
|
-
'bg-foreground rounded-full',
|
|
63
|
-
'pointer-events-none z-0',
|
|
64
|
-
].join(' '),
|
|
65
42
|
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* CVA variants for DynamicToggle root.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```tsx
|
|
49
|
+
* <DynamicToggle size="sm" variant="outline" shape="rounded">
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export const dynamicToggleVariants = cva(dynamicToggleStyles.root, {
|
|
53
|
+
variants: {
|
|
54
|
+
/** Visual variant — background and border */
|
|
55
|
+
variant: {
|
|
56
|
+
default: 'bg-card border-border shadow-sm',
|
|
57
|
+
ghost: 'bg-transparent border-transparent',
|
|
58
|
+
muted: 'bg-muted border-muted',
|
|
59
|
+
outline: 'bg-transparent border-border',
|
|
60
|
+
},
|
|
61
|
+
/**
|
|
62
|
+
* Size — height, width, and font size.
|
|
63
|
+
* Width is required for the 50% indicator and cqh clip-path.
|
|
64
|
+
*/
|
|
65
|
+
size: {
|
|
66
|
+
sm: 'h-[30px] w-[210px] text-[10px] [--dt-h:30px]',
|
|
67
|
+
default: 'h-[38px] w-[260px] text-xs [--dt-h:38px]',
|
|
68
|
+
lg: 'h-[44px] w-80 text-sm [--dt-h:44px]',
|
|
69
|
+
},
|
|
70
|
+
/** Shape — border radius propagated to indicators via --dt-radius */
|
|
71
|
+
shape: {
|
|
72
|
+
pill: 'rounded-full [--dt-radius:9999px]',
|
|
73
|
+
rounded: 'rounded-xl [--dt-radius:0.75rem]',
|
|
74
|
+
square: 'rounded-md [--dt-radius:0.375rem]',
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
defaultVariants: {
|
|
78
|
+
variant: 'default',
|
|
79
|
+
size: 'default',
|
|
80
|
+
shape: 'pill',
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
/** Variant props extracted from CVA */
|
|
85
|
+
export type DynamicToggleVariantProps = VariantProps<typeof dynamicToggleVariants>;
|