@zvndev/yable-themes 0.1.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.
@@ -0,0 +1,517 @@
1
+ /* ============================================================================
2
+ @zvndev/yable-themes — Utility Classes
3
+ Modifier classes for common table configurations.
4
+ Apply these on the .yable container element.
5
+
6
+ Categories:
7
+ 1. Density Modifiers — compact, comfortable, dense
8
+ 2. Visual Modifiers — striped, bordered, borderless, rounded, flat, elevated
9
+ 3. Hover Control — hoverable (default), no-hover
10
+ 4. Layout Modifiers — full-width, wrap, scrollable, plain-headers
11
+ 5. Animation Utilities — animate-rows, row-enter, row-exit, cell flash
12
+ 6. Scrollbar Styling — custom scrollbar appearance
13
+ 7. Focus Utilities — focus-within, cell focus-visible
14
+ 8. Responsive Behavior — mobile-first responsive adaptations
15
+ 9. Print Utilities — print-optimized rendering
16
+ ============================================================================ */
17
+
18
+
19
+ /* ============================================================================
20
+ 1. DENSITY MODIFIERS
21
+ Control padding, font size, and row height for different data densities.
22
+ ============================================================================ */
23
+
24
+ /* ── Compact ─────────────────────────────────────────────────────────────── */
25
+
26
+ .yable--compact {
27
+ --yable-cell-padding-x: 8px;
28
+ --yable-cell-padding-y: 4px;
29
+ --yable-header-padding-x: 8px;
30
+ --yable-header-padding-y: 4px;
31
+ --yable-row-min-height: 32px;
32
+ --yable-header-min-height: 32px;
33
+ --yable-font-size: 12px;
34
+ --yable-font-size-header: 11px;
35
+ }
36
+
37
+ /* ── Comfortable ─────────────────────────────────────────────────────────── */
38
+
39
+ .yable--comfortable {
40
+ --yable-cell-padding-x: 20px;
41
+ --yable-cell-padding-y: 14px;
42
+ --yable-header-padding-x: 20px;
43
+ --yable-header-padding-y: 14px;
44
+ --yable-row-min-height: 48px;
45
+ --yable-header-min-height: 48px;
46
+ --yable-font-size: 14px;
47
+ --yable-font-size-header: 13px;
48
+ }
49
+
50
+ /* ── Relaxed (alias for comfortable — preserve backward compat) ──────────── */
51
+
52
+ .yable--relaxed {
53
+ --yable-cell-padding-x: 20px;
54
+ --yable-cell-padding-y: 14px;
55
+ --yable-header-padding-x: 20px;
56
+ --yable-header-padding-y: 14px;
57
+ --yable-row-min-height: 52px;
58
+ --yable-header-min-height: 52px;
59
+ }
60
+
61
+ /* ── Dense — Maximum data density ────────────────────────────────────────── */
62
+
63
+ .yable--dense {
64
+ --yable-cell-padding-x: 6px;
65
+ --yable-cell-padding-y: 2px;
66
+ --yable-header-padding-x: 6px;
67
+ --yable-header-padding-y: 2px;
68
+ --yable-row-min-height: 24px;
69
+ --yable-header-min-height: 24px;
70
+ --yable-font-size: 11px;
71
+ --yable-font-size-header: 10px;
72
+ --yable-line-height: 1.35;
73
+ }
74
+
75
+ .yable--dense .yable-th {
76
+ letter-spacing: 0;
77
+ }
78
+
79
+
80
+ /* ============================================================================
81
+ 2. VISUAL MODIFIERS
82
+ Control borders, backgrounds, corners, and shadows.
83
+ ============================================================================ */
84
+
85
+ /* ── Striped Rows ────────────────────────────────────────────────────────── */
86
+
87
+ .yable--striped .yable-tbody .yable-tr:nth-child(even) {
88
+ background: var(--yable-bg-row-alt);
89
+ }
90
+
91
+ .yable--striped .yable-tbody .yable-tr:nth-child(even):hover {
92
+ background: var(--yable-bg-row-hover);
93
+ }
94
+
95
+ /* Selected state takes precedence over striped */
96
+ .yable--striped .yable-tbody .yable-tr[data-selected="true"]:nth-child(even) {
97
+ background: var(--yable-bg-row-selected);
98
+ }
99
+
100
+ /* ── Bordered — Full cell borders (horizontal + vertical) ────────────────── */
101
+
102
+ .yable--bordered .yable-th,
103
+ .yable--bordered .yable-td {
104
+ border-right: var(--yable-border-width) solid var(--yable-border-color);
105
+ }
106
+
107
+ .yable--bordered .yable-th:last-child,
108
+ .yable--bordered .yable-td:last-child {
109
+ border-right: none;
110
+ }
111
+
112
+ /* ── Borderless — No borders at all, rely on spacing ─────────────────────── */
113
+
114
+ .yable--borderless {
115
+ border: none;
116
+ box-shadow: none;
117
+ }
118
+
119
+ .yable--borderless .yable-th {
120
+ border-bottom-color: transparent;
121
+ }
122
+
123
+ .yable--borderless .yable-tr:not(:last-child) .yable-td {
124
+ border-bottom-color: transparent;
125
+ }
126
+
127
+ /* ── Rounded — Extra rounded corners ─────────────────────────────────────── */
128
+
129
+ .yable--rounded {
130
+ --yable-border-radius: 12px;
131
+ border-radius: var(--yable-border-radius);
132
+ overflow: hidden;
133
+ }
134
+
135
+ /* ── Flat — No radius, no shadow (ideal for embedding) ───────────────────── */
136
+
137
+ .yable--flat {
138
+ border-radius: 0;
139
+ box-shadow: none;
140
+ }
141
+
142
+ /* ── Elevated — Extra shadow for standalone placement ────────────────────── */
143
+
144
+ .yable--elevated {
145
+ box-shadow: var(--yable-shadow-lg, 0 4px 12px rgba(0, 0, 0, 0.08));
146
+ }
147
+
148
+
149
+ /* ============================================================================
150
+ 3. HOVER CONTROL
151
+ Row hover is on by default in base.css. These classes opt out.
152
+ ============================================================================ */
153
+
154
+ /* ── Hoverable — Explicit opt-in (for clarity, matches base default) ─────── */
155
+
156
+ .yable--hoverable .yable-tr:hover {
157
+ background: var(--yable-bg-row-hover);
158
+ }
159
+
160
+ /* ── No Hover — Disable row hover highlight ──────────────────────────────── */
161
+
162
+ .yable--no-hover .yable-tr:hover {
163
+ background: var(--yable-bg-row);
164
+ }
165
+
166
+ /* Preserve striped pattern when hover is disabled */
167
+ .yable--no-hover.yable--striped .yable-tbody .yable-tr:nth-child(even):hover {
168
+ background: var(--yable-bg-row-alt);
169
+ }
170
+
171
+ /* Preserve selected state when hover is disabled */
172
+ .yable--no-hover .yable-tr[data-selected="true"]:hover {
173
+ background: var(--yable-bg-row-selected);
174
+ }
175
+
176
+
177
+ /* ============================================================================
178
+ 4. LAYOUT MODIFIERS
179
+ Control table layout, text wrapping, and scroll behavior.
180
+ ============================================================================ */
181
+
182
+ /* ── Full Width — Auto table layout ──────────────────────────────────────── */
183
+
184
+ .yable--full-width .yable-table {
185
+ table-layout: auto;
186
+ }
187
+
188
+ /* ── Wrap — Allow text wrapping in cells ─────────────────────────────────── */
189
+
190
+ .yable--wrap .yable-td,
191
+ .yable--wrap .yable-th {
192
+ white-space: normal;
193
+ overflow: visible;
194
+ text-overflow: unset;
195
+ }
196
+
197
+ /* ── Scrollable — Fixed height with vertical scroll ──────────────────────── */
198
+
199
+ .yable--scrollable {
200
+ max-height: var(--yable-max-height, 600px);
201
+ overflow-y: auto;
202
+ }
203
+
204
+ /* ── Plain Headers — No uppercase, smaller weight ────────────────────────── */
205
+
206
+ .yable--plain-headers .yable-th {
207
+ text-transform: none;
208
+ letter-spacing: normal;
209
+ font-weight: var(--yable-font-weight-medium);
210
+ font-size: var(--yable-font-size);
211
+ }
212
+
213
+
214
+ /* ============================================================================
215
+ 5. ANIMATION UTILITIES
216
+ Opt-in animations for row mount/unmount and cell value changes.
217
+ ============================================================================ */
218
+
219
+ /* ── Animate Rows — Fade-in on row mount ─────────────────────────────────── */
220
+
221
+ .yable--animate-rows .yable-tbody .yable-tr {
222
+ animation: yable-row-fade-in var(--yable-transition-slow, 250ms) ease both;
223
+ }
224
+
225
+ /* Stagger child rows for a cascade effect */
226
+ .yable--animate-rows .yable-tbody .yable-tr:nth-child(1) { animation-delay: 0ms; }
227
+ .yable--animate-rows .yable-tbody .yable-tr:nth-child(2) { animation-delay: 20ms; }
228
+ .yable--animate-rows .yable-tbody .yable-tr:nth-child(3) { animation-delay: 40ms; }
229
+ .yable--animate-rows .yable-tbody .yable-tr:nth-child(4) { animation-delay: 60ms; }
230
+ .yable--animate-rows .yable-tbody .yable-tr:nth-child(5) { animation-delay: 80ms; }
231
+ .yable--animate-rows .yable-tbody .yable-tr:nth-child(n+6) { animation-delay: 100ms; }
232
+
233
+ /* ── Row Enter / Exit — Applied programmatically by the core engine ──────── */
234
+
235
+ .yable-row-enter {
236
+ animation: yable-row-fade-in var(--yable-transition-slow, 250ms) ease both;
237
+ }
238
+
239
+ .yable-row-exit {
240
+ animation: yable-row-fade-out var(--yable-transition-slow, 250ms) ease both;
241
+ pointer-events: none;
242
+ }
243
+
244
+ /* ── Cell Flash — Value-change indicators ────────────────────────────────── */
245
+
246
+ .yable-cell-flash-up {
247
+ animation: yable-flash-up var(--yable-flash-duration, 700ms) ease-out both;
248
+ }
249
+
250
+ .yable-cell-flash-down {
251
+ animation: yable-flash-down var(--yable-flash-duration, 700ms) ease-out both;
252
+ }
253
+
254
+ .yable-cell-flash-change {
255
+ animation: yable-flash-change var(--yable-flash-duration, 700ms) ease-out both;
256
+ }
257
+
258
+ /* Reduced motion: disable all table animations */
259
+ @media (prefers-reduced-motion: reduce) {
260
+ .yable--animate-rows .yable-tbody .yable-tr,
261
+ .yable-row-enter,
262
+ .yable-row-exit,
263
+ .yable-cell-flash-up,
264
+ .yable-cell-flash-down,
265
+ .yable-cell-flash-change {
266
+ animation: none;
267
+ }
268
+ }
269
+
270
+
271
+ /* ============================================================================
272
+ 6. SCROLLBAR STYLING
273
+ Custom scrollbar appearance for Webkit/Blink browsers.
274
+ Uses CSS variables so themes can override.
275
+ ============================================================================ */
276
+
277
+ .yable::-webkit-scrollbar {
278
+ width: 6px;
279
+ height: 6px;
280
+ }
281
+
282
+ .yable::-webkit-scrollbar-track {
283
+ background: var(--yable-scrollbar-track, transparent);
284
+ }
285
+
286
+ .yable::-webkit-scrollbar-thumb {
287
+ background: var(--yable-scrollbar-thumb, rgba(0, 0, 0, 0.15));
288
+ border-radius: 3px;
289
+ }
290
+
291
+ .yable::-webkit-scrollbar-thumb:hover {
292
+ background: var(--yable-scrollbar-thumb-hover, rgba(0, 0, 0, 0.25));
293
+ }
294
+
295
+ /* Firefox scrollbar styling */
296
+ .yable {
297
+ scrollbar-width: thin;
298
+ scrollbar-color: var(--yable-scrollbar-thumb, rgba(0, 0, 0, 0.15))
299
+ var(--yable-scrollbar-track, transparent);
300
+ }
301
+
302
+ /* ── Scrollbar corner (where h + v scrollbars meet) ──────────────────────── */
303
+
304
+ .yable::-webkit-scrollbar-corner {
305
+ background: var(--yable-scrollbar-track, transparent);
306
+ }
307
+
308
+
309
+ /* ============================================================================
310
+ 7. FOCUS UTILITIES
311
+ Keyboard navigation and accessibility focus indicators.
312
+ ============================================================================ */
313
+
314
+ /* ── Table focus ring — Subtle outline when table has focus ──────────────── */
315
+
316
+ .yable:focus-within {
317
+ outline: 2px solid var(--yable-accent-light, rgba(37, 99, 235, 0.08));
318
+ outline-offset: -2px;
319
+ }
320
+
321
+ /* Do not show focus ring when interacting with mouse */
322
+ .yable:focus-within:not(:has(:focus-visible)) {
323
+ outline: none;
324
+ }
325
+
326
+ /* ── Cell focus — Clear ring for keyboard navigation ─────────────────────── */
327
+
328
+ .yable-td:focus-visible,
329
+ .yable-th:focus-visible {
330
+ outline: 2px solid var(--yable-accent, #2563eb);
331
+ outline-offset: -2px;
332
+ z-index: 1;
333
+ }
334
+
335
+ /* ── Input focus within cells — Prevent double ring ──────────────────────── */
336
+
337
+ .yable-td:focus-within:not(:focus-visible) {
338
+ outline: none;
339
+ }
340
+
341
+
342
+ /* ============================================================================
343
+ 8. RESPONSIVE BEHAVIOR
344
+ Mobile-first responsive adaptations.
345
+ ============================================================================ */
346
+
347
+ /* ── Small screens (tablets and below) ───────────────────────────────────── */
348
+
349
+ @media (max-width: 768px) {
350
+ /* Tighter spacing on all tables */
351
+ .yable {
352
+ --yable-cell-padding-x: 10px;
353
+ --yable-cell-padding-y: 6px;
354
+ --yable-header-padding-x: 10px;
355
+ --yable-header-padding-y: 6px;
356
+ --yable-font-size: 12px;
357
+ --yable-font-size-header: 11px;
358
+ }
359
+
360
+ /* Responsive modifier: force horizontal scroll with minimum column widths */
361
+ .yable--responsive {
362
+ overflow-x: auto;
363
+ -webkit-overflow-scrolling: touch;
364
+ }
365
+
366
+ .yable--responsive .yable-table {
367
+ min-width: var(--yable-responsive-min-width, 640px);
368
+ }
369
+
370
+ .yable--responsive .yable-th,
371
+ .yable--responsive .yable-td {
372
+ min-width: var(--yable-responsive-min-col-width, 80px);
373
+ }
374
+
375
+ /* Simplify pagination: hide page numbers, show only prev/next */
376
+ .yable-pagination-pages .yable-pagination-btn:not(:first-child):not(:last-child) {
377
+ display: none;
378
+ }
379
+
380
+ /* Collapse pagination info to a single line */
381
+ .yable-pagination {
382
+ flex-wrap: wrap;
383
+ gap: 8px;
384
+ }
385
+
386
+ .yable-pagination-info {
387
+ font-size: var(--yable-font-size-sm, 12px);
388
+ width: 100%;
389
+ text-align: center;
390
+ }
391
+
392
+ /* Reduce status bar density */
393
+ .yable-status-bar {
394
+ flex-wrap: wrap;
395
+ gap: 8px;
396
+ padding: 6px 10px;
397
+ font-size: 11px;
398
+ }
399
+
400
+ /* Sidebar takes full width on mobile */
401
+ .yable-sidebar {
402
+ width: 100% !important;
403
+ max-width: none;
404
+ }
405
+ }
406
+
407
+ /* ── Extra small screens (phones) ────────────────────────────────────────── */
408
+
409
+ @media (max-width: 480px) {
410
+ .yable {
411
+ --yable-cell-padding-x: 8px;
412
+ --yable-cell-padding-y: 4px;
413
+ --yable-header-padding-x: 8px;
414
+ --yable-header-padding-y: 4px;
415
+ --yable-font-size: 11px;
416
+ --yable-font-size-header: 10px;
417
+ }
418
+
419
+ /* Stack pagination controls vertically */
420
+ .yable-pagination {
421
+ flex-direction: column;
422
+ align-items: center;
423
+ }
424
+
425
+ /* Hide sort badges on very small screens */
426
+ .yable-sort-badge {
427
+ display: none;
428
+ }
429
+ }
430
+
431
+
432
+ /* ============================================================================
433
+ 9. PRINT UTILITIES
434
+ Optimized rendering for print output.
435
+ ============================================================================ */
436
+
437
+ @media print {
438
+ /* Hide interactive-only UI elements */
439
+ .yable-pagination,
440
+ .yable-global-filter,
441
+ .yable-sidebar,
442
+ .yable-ctx-menu,
443
+ .yable-status-bar,
444
+ .yable-overlay-loading,
445
+ .yable-resize-handle,
446
+ .yable-fill-handle,
447
+ .yable-tooltip,
448
+ .yable-expand-toggle {
449
+ display: none !important;
450
+ }
451
+
452
+ /* Clean table appearance */
453
+ .yable {
454
+ border: none !important;
455
+ box-shadow: none !important;
456
+ overflow: visible !important;
457
+ max-height: none !important;
458
+ background: #ffffff !important;
459
+ color: #000000 !important;
460
+ }
461
+
462
+ .yable-table {
463
+ width: 100% !important;
464
+ }
465
+
466
+ /* Solid borders for print clarity */
467
+ .yable-th,
468
+ .yable-td {
469
+ border: 1px solid #cccccc !important;
470
+ background: #ffffff !important;
471
+ color: #000000 !important;
472
+ padding: 6px 8px !important;
473
+ }
474
+
475
+ .yable-th {
476
+ background: #f0f0f0 !important;
477
+ font-weight: 600 !important;
478
+ }
479
+
480
+ /* Remove sticky positioning for print flow */
481
+ .yable-th,
482
+ .yable-td {
483
+ position: static !important;
484
+ }
485
+
486
+ /* Ensure header repeats on every page */
487
+ .yable-thead {
488
+ display: table-header-group;
489
+ }
490
+
491
+ .yable-tbody {
492
+ display: table-row-group;
493
+ }
494
+
495
+ /* Remove row hover/selection highlights */
496
+ .yable-tr {
497
+ background: none !important;
498
+ }
499
+
500
+ .yable-tr:nth-child(even) {
501
+ background: #f8f8f8 !important;
502
+ }
503
+
504
+ /* Remove animations */
505
+ .yable *,
506
+ .yable *::before,
507
+ .yable *::after {
508
+ animation: none !important;
509
+ transition: none !important;
510
+ }
511
+
512
+ /* Avoid page breaks inside rows */
513
+ .yable-tr {
514
+ page-break-inside: avoid;
515
+ break-inside: avoid;
516
+ }
517
+ }
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@zvndev/yable-themes",
3
+ "version": "0.1.0",
4
+ "description": "CSS design token system and themes for Yable data tables",
5
+ "keywords": ["table", "themes", "css", "design-tokens", "dark-mode", "yable"],
6
+ "license": "MIT",
7
+ "author": "ZVN DEV",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/ZVN-DEV/table.git",
11
+ "directory": "packages/themes"
12
+ },
13
+ "homepage": "https://github.com/ZVN-DEV/table#readme",
14
+ "type": "module",
15
+ "main": "./dist/index.css",
16
+ "exports": {
17
+ ".": "./dist/index.css",
18
+ "./default.css": "./dist/themes/default.css",
19
+ "./stripe.css": "./dist/themes/stripe.css",
20
+ "./compact.css": "./dist/themes/compact.css",
21
+ "./midnight.css": "./dist/themes/midnight.css",
22
+ "./ocean.css": "./dist/themes/ocean.css",
23
+ "./rose.css": "./dist/themes/rose.css",
24
+ "./forest.css": "./dist/themes/forest.css",
25
+ "./mono.css": "./dist/themes/mono.css",
26
+ "./tokens.css": "./dist/tokens.css",
27
+ "./rtl.css": "./dist/rtl.css",
28
+ "./tailwind.css": "./dist/tailwind.css",
29
+ "./tailwind-preset": "./src/tailwind-preset.ts",
30
+ "./createTheme": "./src/createTheme.ts"
31
+ },
32
+ "files": ["dist", "src/tailwind-preset.ts"],
33
+ "scripts": {
34
+ "build": "node build.mjs",
35
+ "dev": "node build.mjs --watch",
36
+ "clean": "rm -rf dist"
37
+ }
38
+ }
@@ -0,0 +1,80 @@
1
+ // @zvndev/yable-themes — Tailwind v3 preset
2
+ //
3
+ // Usage:
4
+ //
5
+ // // tailwind.config.ts
6
+ // import yablePreset from '@zvndev/yable-themes/tailwind-preset'
7
+ //
8
+ // export default {
9
+ // presets: [yablePreset],
10
+ // content: ['./src/**/*.{ts,tsx}', './node_modules/@zvndev/yable-react/dist/**/*.js'],
11
+ // }
12
+ //
13
+ // All token utilities resolve to the live CSS variable, so they automatically
14
+ // follow whatever Yable theme is active on the surrounding container.
15
+
16
+ const cssVar = (name: string) => `var(--${name})`
17
+
18
+ const yableTailwindPreset = {
19
+ theme: {
20
+ extend: {
21
+ colors: {
22
+ yable: {
23
+ DEFAULT: cssVar('yable-bg'),
24
+ bg: cssVar('yable-bg'),
25
+ 'bg-header': cssVar('yable-bg-header'),
26
+ 'bg-footer': cssVar('yable-bg-footer'),
27
+ 'bg-row': cssVar('yable-bg-row'),
28
+ 'bg-row-alt': cssVar('yable-bg-row-alt'),
29
+ 'bg-row-hover': cssVar('yable-bg-row-hover'),
30
+ 'bg-row-selected': cssVar('yable-bg-row-selected'),
31
+ 'bg-row-expanded': cssVar('yable-bg-row-expanded'),
32
+ 'bg-cell-editing': cssVar('yable-bg-cell-editing'),
33
+ 'bg-pinned': cssVar('yable-bg-pinned'),
34
+
35
+ text: cssVar('yable-text-primary'),
36
+ 'text-secondary': cssVar('yable-text-secondary'),
37
+ 'text-tertiary': cssVar('yable-text-tertiary'),
38
+ 'text-header': cssVar('yable-text-header'),
39
+ 'text-disabled': cssVar('yable-text-disabled'),
40
+ 'text-link': cssVar('yable-text-link'),
41
+ 'text-placeholder': cssVar('yable-text-placeholder'),
42
+
43
+ border: cssVar('yable-border-color'),
44
+ 'border-strong': cssVar('yable-border-color-strong'),
45
+
46
+ accent: cssVar('yable-accent'),
47
+ 'accent-hover': cssVar('yable-accent-hover'),
48
+ 'accent-light': cssVar('yable-accent-light'),
49
+ 'accent-text': cssVar('yable-accent-text'),
50
+ 'focus-ring': cssVar('yable-focus-ring'),
51
+ },
52
+ },
53
+ spacing: {
54
+ 'yable-cell-x': cssVar('yable-cell-padding-x'),
55
+ 'yable-cell-y': cssVar('yable-cell-padding-y'),
56
+ 'yable-header-x': cssVar('yable-header-padding-x'),
57
+ 'yable-header-y': cssVar('yable-header-padding-y'),
58
+ },
59
+ borderRadius: {
60
+ yable: cssVar('yable-border-radius'),
61
+ 'yable-sm': cssVar('yable-border-radius-sm'),
62
+ 'yable-lg': cssVar('yable-border-radius-lg'),
63
+ },
64
+ fontFamily: {
65
+ yable: [cssVar('yable-font-family')],
66
+ },
67
+ fontSize: {
68
+ yable: [cssVar('yable-font-size'), { lineHeight: cssVar('yable-line-height') }],
69
+ 'yable-sm': [cssVar('yable-font-size-sm'), { lineHeight: cssVar('yable-line-height') }],
70
+ 'yable-header': [
71
+ cssVar('yable-font-size-header'),
72
+ { lineHeight: cssVar('yable-line-height') },
73
+ ],
74
+ },
75
+ },
76
+ },
77
+ }
78
+
79
+ export default yableTailwindPreset
80
+ export { yableTailwindPreset }