@24vlh/vds 0.1.1 → 0.1.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.
@@ -1 +1,307 @@
1
- .vds-tabs,[data-vds-tabs]{--tabs-component-disabled-opacity:0.48}.tabs{display:flex;flex-direction:column;gap:var(--space-3);width:100%}.tabs--center{align-items:center}.tabs--right{align-items:flex-end}.tab-list{border-bottom:var(--border-width) solid var(--color-border-subtle);display:inline-flex;flex-wrap:nowrap;gap:0;position:relative;width:100%}.tabs--inline .tab-list{width:auto}.tabs--stretch .tab-list{width:100%}.tabs--stretch .tab{flex:1 1 0}.tab{background:none;border:none;border-radius:0;color:var(--color-text-muted);cursor:pointer;font-size:var(--text-sm);font-weight:var(--font-weight-medium);letter-spacing:var(--letter-normal);line-height:1.2;padding:var(--space-2) var(--space-3);position:relative;transition:color var(--transition-normal),background-color var(--transition-normal),box-shadow var(--transition-normal);white-space:nowrap}.tab,.tab__icon{align-items:center;display:inline-flex;justify-content:center}.tab__icon{height:var(--icon-sm);margin-right:var(--space-2);width:var(--icon-sm)}.tab__badge{background-color:var(--color-muted-bg);border-radius:var(--radius-full);color:var(--color-text-soft);font-size:var(--text-xxs);margin-left:var(--space-2);padding:0 var(--space-2)}.tab:hover{background-color:var(--color-surface-subtle);color:var(--color-text)}.tab:focus-visible{box-shadow:0 var(--tab-indicator-height) 0 0 var(--focus-ring-color);color:var(--color-text);outline:none}.tab--disabled,.tab[disabled]{background:none;box-shadow:none;cursor:not-allowed;opacity:var(--tabs-component-disabled-opacity)}.tab--active{box-shadow:0 var(--tab-indicator-height) 0 0 var(--color-accent);color:var(--color-text);font-weight:var(--font-weight-semibold)}.tabs--on-muted .tab--active{box-shadow:0 var(--tab-indicator-height) 0 0 var(--color-accent-strong)}.tab--active:hover{background-color:transparent}.tabs--a .tab{font-size:var(--text-md);padding:var(--space-3) var(--space-4)}.tabs--c .tab{font-size:var(--text-xs);padding:var(--space-1_5) var(--space-2)}.tabs--vertical{align-items:flex-start;flex-direction:row;gap:var(--space-6)}.tabs--vertical .tab-list{align-items:stretch;border-bottom:none;border-right:var(--border-width) solid var(--color-border-subtle);flex-direction:column;min-width:var(--sidebar-width-md);width:auto}.tabs--vertical .tab{justify-content:flex-start;padding:var(--space-2) var(--space-3);text-align:left;width:100%}.tabs--vertical .tab--active{box-shadow:var(--tab-indicator-height) 0 0 0 var(--color-accent)}.tabs--vertical .tab:focus-visible{box-shadow:var(--tab-indicator-height) 0 0 0 var(--focus-ring-color)}.tabs--vertical.tabs--c .tab{padding:var(--space-1_5) var(--space-2)}.tabs--vertical.tabs--a .tab{padding:var(--space-3) var(--space-4)}.tab-panel{padding-top:var(--space-2);width:100%}.tab-panel.is-hidden,.tab-panel[hidden]{display:none}.tab-panel--padded{padding-top:var(--space-4)}.tabs--vertical .tab-panel,.tabs--vertical .tab-panels{flex:1 1 0}.tab-panels{padding-top:var(--space-2);width:100%}@media (max-width:768px){.tab-list{-webkit-overflow-scrolling:touch;overflow-x:auto;scrollbar-width:thin}.tab-list::-webkit-scrollbar{height:6px}.tabs--vertical{flex-direction:column;gap:var(--space-3)}.tabs--vertical .tab-list{border-bottom:var(--border-width) solid var(--color-border-subtle);border-right:none;flex-direction:row;min-width:0;width:100%}.tabs--vertical .tab{justify-content:center;text-align:center}.tabs--vertical .tab--active{box-shadow:0 var(--tab-indicator-height) 0 0 var(--color-accent)}.tabs--vertical .tab:focus-visible{box-shadow:0 var(--tab-indicator-height) 0 0 var(--focus-ring-color)}}
1
+ /************************************************************
2
+ * VLAH DESIGN SYSTEM (VDS) - Tabs System
3
+ *
4
+ * Responsibilities:
5
+ * - Provide horizontal and vertical tab interfaces with full tab-list,
6
+ * tab, and tab-panel architecture
7
+ * - Implement underline indicator active state, icon and badge support,
8
+ * and alignment modes (inline / center / right / stretch)
9
+ * - Support density variants (A / default / C) and optional muted-surface
10
+ * colour adaptations
11
+ * - Enable responsive horizontal scroll for overflowed tab-lists
12
+ * - Ensure accessible focus-visible states, disabled states, and hidden
13
+ * panel behaviour
14
+ *
15
+ * System Notes:
16
+ * - Fully token-driven: spacing, text scales, indicator height, transitions
17
+ * - Pure CSS; JS only toggles tab--active and associated tab-panel visibility
18
+ * - Namespace and behaviour are isolated from navigation.css tab-like
19
+ * patterns to avoid collisions
20
+ ************************************************************/
21
+
22
+ /* ---------------------------------------------------------
23
+ 1. TABS TOKEN DEFINITIONS
24
+ --------------------------------------------------------- */
25
+
26
+ [data-vds-tabs],
27
+ .vds-tabs {
28
+ --tabs-component-disabled-opacity: 0.48;
29
+ }
30
+
31
+ /* ---------------------------------------------------------
32
+ 2. TABS CONTAINER
33
+ --------------------------------------------------------- */
34
+
35
+ .tabs {
36
+ display: flex;
37
+ flex-direction: column;
38
+ gap: var(--space-3);
39
+ width: 100%;
40
+ }
41
+
42
+ .tabs--center {
43
+ align-items: center;
44
+ }
45
+
46
+ .tabs--right {
47
+ align-items: flex-end;
48
+ }
49
+
50
+ /* ---------------------------------------------------------
51
+ 3. TAB LIST (HORIZONTAL UNDERLINE BASELINE)
52
+ --------------------------------------------------------- */
53
+
54
+ .tab-list {
55
+ position: relative;
56
+ display: inline-flex;
57
+ flex-wrap: nowrap;
58
+ gap: 0;
59
+ border-bottom: var(--border-width) solid var(--color-border-subtle);
60
+ width: 100%;
61
+ }
62
+
63
+ .tabs--inline .tab-list {
64
+ width: auto;
65
+ }
66
+
67
+ .tabs--stretch .tab-list {
68
+ width: 100%;
69
+ }
70
+
71
+ .tabs--stretch .tab {
72
+ flex: 1 1 0;
73
+ }
74
+
75
+ /* ---------------------------------------------------------
76
+ 4. TAB (BASE)
77
+ Pattern: <button class="tab">Label</button>
78
+ --------------------------------------------------------- */
79
+
80
+ .tab {
81
+ position: relative;
82
+ display: inline-flex;
83
+ align-items: center;
84
+ justify-content: center;
85
+
86
+ padding-left: var(--space-3);
87
+
88
+ padding-right: var(--space-3);
89
+ padding-top: var(--space-2);
90
+ padding-bottom: var(--space-2);
91
+
92
+ font-size: var(--text-sm);
93
+ font-weight: var(--font-weight-medium);
94
+ line-height: 1.2;
95
+ letter-spacing: var(--letter-normal);
96
+
97
+ border: none;
98
+ border-radius: 0;
99
+ background: none;
100
+ color: var(--color-text-muted);
101
+
102
+ cursor: pointer;
103
+ white-space: nowrap;
104
+
105
+ transition: color var(--transition-normal), background-color var(--transition-normal), box-shadow var(--transition-normal);
106
+ }
107
+
108
+ .tab__icon {
109
+ width: var(--icon-sm);
110
+ height: var(--icon-sm);
111
+ margin-right: var(--space-2);
112
+ display: inline-flex;
113
+ align-items: center;
114
+ justify-content: center;
115
+ }
116
+
117
+ .tab__badge {
118
+ margin-left: var(--space-2);
119
+ font-size: var(--text-xxs);
120
+ padding: 0 var(--space-2);
121
+ border-radius: var(--radius-full);
122
+ background-color: var(--color-muted-bg);
123
+ color: var(--color-text-soft);
124
+ }
125
+
126
+ .tab:hover {
127
+ color: var(--color-text);
128
+ background-color: var(--color-surface-subtle);
129
+ }
130
+
131
+ .tab:focus-visible {
132
+ outline: none;
133
+ color: var(--color-text);
134
+ box-shadow: 0 var(--tab-indicator-height) 0 0 var(--focus-ring-color);
135
+ }
136
+
137
+ .tab[disabled],
138
+ .tab--disabled {
139
+ cursor: not-allowed;
140
+ opacity: var(--tabs-component-disabled-opacity);
141
+ box-shadow: none;
142
+ background: none;
143
+ }
144
+
145
+ /* ---------------------------------------------------------
146
+ 5. ACTIVE STATE - UNDERLINE INDICATOR
147
+ --------------------------------------------------------- */
148
+
149
+ .tab--active {
150
+ color: var(--color-text);
151
+ font-weight: var(--font-weight-semibold);
152
+ box-shadow: 0 var(--tab-indicator-height) 0 0 var(--color-accent);
153
+ }
154
+
155
+ .tabs--on-muted .tab--active {
156
+ box-shadow: 0 var(--tab-indicator-height) 0 0 var(--color-accent-strong);
157
+ }
158
+
159
+ .tab--active:hover {
160
+ background-color: transparent;
161
+ }
162
+
163
+ /* ---------------------------------------------------------
164
+ 6. DENSITY VARIANTS (A / default / C)
165
+ --------------------------------------------------------- */
166
+
167
+ .tabs--a .tab {
168
+ padding-left: var(--space-4);
169
+ padding-right: var(--space-4);
170
+ padding-top: var(--space-3);
171
+ padding-bottom: var(--space-3);
172
+ font-size: var(--text-md);
173
+ }
174
+
175
+ .tabs--c .tab {
176
+ padding-left: var(--space-2);
177
+ padding-right: var(--space-2);
178
+ padding-top: var(--space-1_5);
179
+ padding-bottom: var(--space-1_5);
180
+ font-size: var(--text-xs);
181
+ }
182
+
183
+ /* ---------------------------------------------------------
184
+ 7. VERTICAL ORIENTATION
185
+ Pattern:
186
+ <div class="tabs tabs--vertical">
187
+ <div class="tab-list">...</div>
188
+ <div class="tab-panel">...</div>
189
+ </div>
190
+ --------------------------------------------------------- */
191
+
192
+ .tabs--vertical {
193
+ flex-direction: row;
194
+ align-items: flex-start;
195
+ gap: var(--space-6);
196
+ }
197
+
198
+ .tabs--vertical .tab-list {
199
+ flex-direction: column;
200
+ align-items: stretch;
201
+ border-bottom: none;
202
+ border-right: var(--border-width) solid var(--color-border-subtle);
203
+ width: auto;
204
+ min-width: var(--sidebar-width-md);
205
+ }
206
+
207
+ .tabs--vertical .tab {
208
+ justify-content: flex-start;
209
+ text-align: left;
210
+ width: 100%;
211
+ padding-left: var(--space-3);
212
+ padding-right: var(--space-3);
213
+ padding-top: var(--space-2);
214
+ padding-bottom: var(--space-2);
215
+ }
216
+
217
+ .tabs--vertical .tab--active {
218
+ box-shadow: var(--tab-indicator-height) 0 0 0 var(--color-accent);
219
+ }
220
+
221
+ .tabs--vertical .tab:focus-visible {
222
+ box-shadow: var(--tab-indicator-height) 0 0 0 var(--focus-ring-color);
223
+ }
224
+
225
+ .tabs--vertical.tabs--c .tab {
226
+ padding-left: var(--space-2);
227
+ padding-right: var(--space-2);
228
+ padding-top: var(--space-1_5);
229
+ padding-bottom: var(--space-1_5);
230
+ }
231
+
232
+ .tabs--vertical.tabs--a .tab {
233
+ padding-left: var(--space-4);
234
+ padding-right: var(--space-4);
235
+ padding-top: var(--space-3);
236
+ padding-bottom: var(--space-3);
237
+ }
238
+
239
+ /* ---------------------------------------------------------
240
+ 8. TAB PANELS
241
+ --------------------------------------------------------- */
242
+
243
+ .tab-panel {
244
+ width: 100%;
245
+ padding-top: var(--space-2);
246
+ }
247
+
248
+ .tab-panel[hidden],
249
+ .tab-panel.is-hidden {
250
+ display: none;
251
+ }
252
+
253
+ .tab-panel--padded {
254
+ padding-top: var(--space-4);
255
+ }
256
+
257
+ .tabs--vertical .tab-panel,
258
+ .tabs--vertical .tab-panels {
259
+ flex: 1 1 0;
260
+ }
261
+
262
+ .tab-panels {
263
+ width: 100%;
264
+ padding-top: var(--space-2);
265
+ }
266
+
267
+ /* ---------------------------------------------------------
268
+ 9. RESPONSIVE BEHAVIOUR
269
+ --------------------------------------------------------- */
270
+
271
+ @media (max-width: 768px) {
272
+ .tab-list {
273
+ overflow-x: auto;
274
+ scrollbar-width: thin;
275
+ -webkit-overflow-scrolling: touch;
276
+ }
277
+
278
+ .tab-list::-webkit-scrollbar {
279
+ height: 6px;
280
+ }
281
+
282
+ .tabs--vertical {
283
+ flex-direction: column;
284
+ gap: var(--space-3);
285
+ }
286
+
287
+ .tabs--vertical .tab-list {
288
+ flex-direction: row;
289
+ width: 100%;
290
+ min-width: 0;
291
+ border-right: none;
292
+ border-bottom: var(--border-width) solid var(--color-border-subtle);
293
+ }
294
+
295
+ .tabs--vertical .tab {
296
+ justify-content: center;
297
+ text-align: center;
298
+ }
299
+
300
+ .tabs--vertical .tab--active {
301
+ box-shadow: 0 var(--tab-indicator-height) 0 0 var(--color-accent);
302
+ }
303
+
304
+ .tabs--vertical .tab:focus-visible {
305
+ box-shadow: 0 var(--tab-indicator-height) 0 0 var(--focus-ring-color);
306
+ }
307
+ }