@kouji-ui/components 0.9.2 → 0.9.3
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/package.json +1 -1
- package/src/accordion/accordion.css +68 -0
- package/src/action-sheet/action-sheet.css +79 -0
- package/src/alert/alert.css +133 -0
- package/src/avatar/avatar.css +93 -0
- package/src/badge/badge.css +59 -0
- package/src/breadcrumb/breadcrumb.css +145 -0
- package/src/button/button.css +295 -0
- package/src/button-group/button-group.css +114 -0
- package/src/calendar/calendar.css +129 -0
- package/src/card/card.css +120 -0
- package/src/carousel/carousel.css +181 -0
- package/src/cascade-select/cascade-select.css +120 -0
- package/src/chart/chart.css +26 -0
- package/src/chat/chat-ai.css +352 -0
- package/src/chat/chat.css +231 -0
- package/src/checkbox/checkbox.css +74 -0
- package/src/color-picker/color-picker.css +183 -0
- package/src/combobox/combobox.css +101 -0
- package/src/command-palette/command-palette.css +234 -0
- package/src/confirm-popup/confirm-popup.css +47 -0
- package/src/date-picker/date-picker.css +61 -0
- package/src/date-range-presets/date-range-presets.css +49 -0
- package/src/datetime-picker/datetime-picker.css +84 -0
- package/src/dialog/dialog.css +56 -0
- package/src/direction-toggle/direction-toggle.css +55 -0
- package/src/divider/divider.css +93 -0
- package/src/drawer/drawer.css +130 -0
- package/src/dropdown-menu/dropdown-menu.css +108 -0
- package/src/editor/editor.css +140 -0
- package/src/empty-state/empty-state.css +114 -0
- package/src/field/field.css +148 -0
- package/src/file-upload/file-upload.css +207 -0
- package/src/form/form.css +63 -0
- package/src/input/input.css +70 -0
- package/src/input-group/input-group.css +125 -0
- package/src/input-mask/input-mask.css +39 -0
- package/src/input-otp/input-otp.css +87 -0
- package/src/kbd/kbd.css +67 -0
- package/src/link/link.css +104 -0
- package/src/list/list.css +166 -0
- package/src/menubar/menubar.css +62 -0
- package/src/number-input/number-input.css +115 -0
- package/src/overflow/overflow.css +43 -0
- package/src/overlay/overlay.css +45 -0
- package/src/overlay-badge/overlay-badge.css +118 -0
- package/src/pagination/pagination.css +146 -0
- package/src/password-input/password-input.css +155 -0
- package/src/popover/popover.css +71 -0
- package/src/progress-bar/progress-bar.css +113 -0
- package/src/radio/radio.css +58 -0
- package/src/rich-text/rich-text-editor.css +351 -0
- package/src/select/select.css +91 -0
- package/src/sheet/sheet.css +121 -0
- package/src/skeleton/skeleton.css +111 -0
- package/src/skip-link/skip-link.css +58 -0
- package/src/slider/slider.css +172 -0
- package/src/speed-dial/speed-dial.css +137 -0
- package/src/spinner/spinner.css +161 -0
- package/src/stepper/stepper.css +147 -0
- package/src/table/table-filters/filters.css +53 -0
- package/src/table/table.css +509 -0
- package/src/tabs/tabs.css +162 -0
- package/src/tag/tag.css +183 -0
- package/src/textarea/textarea.css +117 -0
- package/src/time-picker/time-picker.css +126 -0
- package/src/toast/toast.css +115 -0
- package/src/toggle/toggle.css +123 -0
- package/src/tooltip/tooltip.css +61 -0
- package/src/tree-select/tree-select.css +220 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
@layer kj.component {
|
|
2
|
+
.kj-toggle {
|
|
3
|
+
--kj-toggle-bg: var(--kj-bg-surface);
|
|
4
|
+
--kj-toggle-bg-pressed: var(--kj-bg-primary);
|
|
5
|
+
--kj-toggle-fg: var(--kj-fg-default);
|
|
6
|
+
--kj-toggle-fg-pressed: var(--kj-fg-on-primary);
|
|
7
|
+
--kj-toggle-radius: var(--kj-radius-field);
|
|
8
|
+
--kj-toggle-padding-x: var(--kj-space-md);
|
|
9
|
+
--kj-toggle-padding-y: var(--kj-space-sm);
|
|
10
|
+
--kj-toggle-font-size: var(--kj-text-sm);
|
|
11
|
+
|
|
12
|
+
display: inline-flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
gap: var(--kj-space-sm);
|
|
15
|
+
background: var(--kj-toggle-bg);
|
|
16
|
+
color: var(--kj-toggle-fg);
|
|
17
|
+
border: var(--kj-border) solid transparent;
|
|
18
|
+
border-radius: var(--kj-toggle-radius);
|
|
19
|
+
padding: var(--kj-toggle-padding-y) var(--kj-toggle-padding-x);
|
|
20
|
+
font: var(--kj-toggle-font-size) / 1.2 var(--kj-font-sans);
|
|
21
|
+
cursor: pointer;
|
|
22
|
+
transition: var(--kj-transition);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.kj-toggle[data-pressed] {
|
|
26
|
+
background: var(--kj-toggle-bg-pressed);
|
|
27
|
+
color: var(--kj-toggle-fg-pressed);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.kj-toggle[data-size="sm"] {
|
|
31
|
+
--kj-toggle-padding-x: var(--kj-space-sm);
|
|
32
|
+
--kj-toggle-padding-y: 0.25rem;
|
|
33
|
+
--kj-toggle-font-size: 0.8125rem;
|
|
34
|
+
}
|
|
35
|
+
.kj-toggle[data-size="lg"] {
|
|
36
|
+
--kj-toggle-padding-x: var(--kj-space-lg);
|
|
37
|
+
--kj-toggle-padding-y: 0.625rem;
|
|
38
|
+
--kj-toggle-font-size: 1rem;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.kj-toggle:hover { background: color-mix(in oklab, var(--kj-toggle-bg) 88%, black); }
|
|
42
|
+
.kj-toggle:focus-visible { outline: 2px solid var(--kj-bg-primary); outline-offset: 2px; }
|
|
43
|
+
.kj-toggle[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; pointer-events: none; }
|
|
44
|
+
|
|
45
|
+
/* ── Switch appearance — track + thumb sliding switch ────────────
|
|
46
|
+
Matches design-revamp/kouji-ui/project/app.css `.toggle` block
|
|
47
|
+
(lines 447–471): 44×24 rounded track, 18×18 thumb at top:2 left:2,
|
|
48
|
+
translateX(20px) on pressed. Tokenised throughout (no hex). */
|
|
49
|
+
.kj-toggle--switch {
|
|
50
|
+
--kj-switch-w: 44px;
|
|
51
|
+
--kj-switch-h: 24px;
|
|
52
|
+
--kj-switch-thumb: 18px;
|
|
53
|
+
--kj-switch-pad: 2px;
|
|
54
|
+
|
|
55
|
+
background: transparent;
|
|
56
|
+
border: 0;
|
|
57
|
+
padding: 0;
|
|
58
|
+
display: inline-flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
gap: 10px;
|
|
61
|
+
font-family: var(--kj-font-sans);
|
|
62
|
+
font-size: var(--kj-text-sm);
|
|
63
|
+
color: var(--kj-fg-default);
|
|
64
|
+
}
|
|
65
|
+
.kj-toggle--switch:hover { background: transparent; }
|
|
66
|
+
.kj-toggle--switch:focus-visible { outline: none; }
|
|
67
|
+
.kj-toggle--switch:focus-visible .kj-toggle__track {
|
|
68
|
+
outline: 2px solid var(--kj-bg-primary);
|
|
69
|
+
outline-offset: 2px;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* Track + thumb corner geometry follows the theme. kouji (radius 0)
|
|
73
|
+
renders a square track + square thumb; sakura/dune (large radii)
|
|
74
|
+
render fully pill; everyone in between scales. Falls back to the
|
|
75
|
+
pill-shape (radius = track height) when --kj-radius-selector
|
|
76
|
+
resolves to 0 only on themes where that's the brand decision. */
|
|
77
|
+
.kj-toggle--switch {
|
|
78
|
+
--kj-switch-track-radius: var(--kj-radius-selector, var(--kj-switch-h));
|
|
79
|
+
--kj-switch-thumb-radius: calc(var(--kj-switch-track-radius) - var(--kj-switch-pad));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.kj-toggle__track {
|
|
83
|
+
width: var(--kj-switch-w);
|
|
84
|
+
height: var(--kj-switch-h);
|
|
85
|
+
border-radius: var(--kj-switch-track-radius);
|
|
86
|
+
background-color: var(--kj-bg-surface);
|
|
87
|
+
border: var(--kj-border) solid var(--kj-border-default);
|
|
88
|
+
position: relative;
|
|
89
|
+
flex-shrink: 0;
|
|
90
|
+
transition: background-color 0.25s cubic-bezier(.34, 1.56, .64, 1);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.kj-toggle__thumb {
|
|
94
|
+
position: absolute;
|
|
95
|
+
top: var(--kj-switch-pad);
|
|
96
|
+
left: var(--kj-switch-pad);
|
|
97
|
+
width: var(--kj-switch-thumb);
|
|
98
|
+
height: var(--kj-switch-thumb);
|
|
99
|
+
/* Mirror the track's radius so square themes stay square, soft themes
|
|
100
|
+
stay round. `max(0, ...)` keeps the result non-negative on kouji
|
|
101
|
+
(radius 0). */
|
|
102
|
+
border-radius: max(0px, var(--kj-switch-thumb-radius));
|
|
103
|
+
background-color: var(--kj-fg-default);
|
|
104
|
+
transition: transform 0.25s cubic-bezier(.34, 1.56, .64, 1),
|
|
105
|
+
background-color 0.25s cubic-bezier(.34, 1.56, .64, 1);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.kj-toggle--switch[aria-pressed="true"] .kj-toggle__track,
|
|
109
|
+
.kj-toggle--switch[data-pressed] .kj-toggle__track {
|
|
110
|
+
background-color: var(--kj-bg-primary);
|
|
111
|
+
border-color: var(--kj-bg-primary);
|
|
112
|
+
}
|
|
113
|
+
.kj-toggle--switch[aria-pressed="true"] .kj-toggle__thumb,
|
|
114
|
+
.kj-toggle--switch[data-pressed] .kj-toggle__thumb {
|
|
115
|
+
transform: translateX(calc(var(--kj-switch-w) - var(--kj-switch-h)));
|
|
116
|
+
background-color: var(--kj-fg-on-primary);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@media (prefers-reduced-motion: reduce) {
|
|
120
|
+
.kj-toggle__track,
|
|
121
|
+
.kj-toggle__thumb { transition: none; }
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
@layer kj.component {
|
|
2
|
+
/* The wrapper hosts use display: contents — they don't add a box. */
|
|
3
|
+
|
|
4
|
+
.kj-tooltip-content {
|
|
5
|
+
--kj-tooltip-bg: var(--kj-fg-default);
|
|
6
|
+
--kj-tooltip-fg: var(--kj-bg-body);
|
|
7
|
+
--kj-tooltip-border-color: transparent;
|
|
8
|
+
--kj-tooltip-radius: var(--kj-radius-selector);
|
|
9
|
+
--kj-tooltip-padding-x: var(--kj-space-md);
|
|
10
|
+
--kj-tooltip-padding-y: var(--kj-space-xs);
|
|
11
|
+
--kj-tooltip-font-size: 0.8125rem;
|
|
12
|
+
--kj-tooltip-shadow: var(--kj-shadow-md, 0 4px 12px rgb(0 0 0 / 0.18));
|
|
13
|
+
--kj-tooltip-arrow-size: 6px;
|
|
14
|
+
|
|
15
|
+
/* Layout — the directive applies position: fixed and writes top/left. */
|
|
16
|
+
display: inline-flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
gap: 0.375rem;
|
|
19
|
+
max-width: min(20rem, calc(100vw - 1rem));
|
|
20
|
+
background: var(--kj-tooltip-bg);
|
|
21
|
+
color: var(--kj-tooltip-fg);
|
|
22
|
+
border: var(--kj-border) solid var(--kj-tooltip-border-color);
|
|
23
|
+
border-radius: var(--kj-tooltip-radius);
|
|
24
|
+
padding: var(--kj-tooltip-padding-y) var(--kj-tooltip-padding-x);
|
|
25
|
+
font: var(--kj-tooltip-font-size) / 1.4 var(--kj-font-sans);
|
|
26
|
+
box-shadow: var(--kj-tooltip-shadow);
|
|
27
|
+
pointer-events: auto;
|
|
28
|
+
z-index: var(--kj-overlay-z, 1000);
|
|
29
|
+
word-wrap: break-word;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* Closed: KjOverlayPanel sets `hidden` when state is closed — keep portaled panel out of layout.
|
|
33
|
+
Load this stylesheet globally when using KjTooltipTrigger + kj-tooltip-content from core
|
|
34
|
+
(see packages/core tooltip finance example; avoid duplicating `[hidden]` in app CSS). */
|
|
35
|
+
/* Must win over any app-level tooltip overrides (e.g. encapsulation + extra classes). */
|
|
36
|
+
.kj-tooltip-content[hidden] {
|
|
37
|
+
display: none !important;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* Arrow positioning relative to the content's resolved data-side. */
|
|
41
|
+
.kj-tooltip-arrow {
|
|
42
|
+
position: absolute;
|
|
43
|
+
width: var(--kj-tooltip-arrow-size);
|
|
44
|
+
height: var(--kj-tooltip-arrow-size);
|
|
45
|
+
background: var(--kj-tooltip-bg);
|
|
46
|
+
transform: rotate(45deg);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.kj-tooltip-content[data-side="top"] .kj-tooltip-arrow { bottom: calc(var(--kj-tooltip-arrow-size) / -2); left: 50%; margin-left: calc(var(--kj-tooltip-arrow-size) / -2); }
|
|
50
|
+
.kj-tooltip-content[data-side="bottom"] .kj-tooltip-arrow { top: calc(var(--kj-tooltip-arrow-size) / -2); left: 50%; margin-left: calc(var(--kj-tooltip-arrow-size) / -2); }
|
|
51
|
+
.kj-tooltip-content[data-side="left"] .kj-tooltip-arrow { right: calc(var(--kj-tooltip-arrow-size) / -2); top: 50%; margin-top: calc(var(--kj-tooltip-arrow-size) / -2); }
|
|
52
|
+
.kj-tooltip-content[data-side="right"] .kj-tooltip-arrow { left: calc(var(--kj-tooltip-arrow-size) / -2); top: 50%; margin-top: calc(var(--kj-tooltip-arrow-size) / -2); }
|
|
53
|
+
|
|
54
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
55
|
+
.kj-tooltip-content {
|
|
56
|
+
transition: opacity 120ms ease-out;
|
|
57
|
+
}
|
|
58
|
+
.kj-tooltip-content[data-state="closed"] { opacity: 0; }
|
|
59
|
+
.kj-tooltip-content[data-state="open"] { opacity: 1; }
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
@layer kj.component {
|
|
2
|
+
/* ── Root ──────────────────────────────────────────────────────────── */
|
|
3
|
+
.kj-tree-select {
|
|
4
|
+
position: relative;
|
|
5
|
+
display: inline-block;
|
|
6
|
+
min-width: 14rem;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/* ── Trigger ───────────────────────────────────────────────────────── */
|
|
10
|
+
.kj-tree-select-trigger {
|
|
11
|
+
width: 100%;
|
|
12
|
+
min-height: 2.75rem; /* WCAG 2.5.5 — 44px touch target */
|
|
13
|
+
display: inline-flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
justify-content: space-between;
|
|
16
|
+
gap: var(--kj-space-sm);
|
|
17
|
+
background: var(--kj-bg-body);
|
|
18
|
+
color: var(--kj-fg-default);
|
|
19
|
+
border: var(--kj-border) solid var(--kj-border-default);
|
|
20
|
+
border-radius: var(--kj-radius-field);
|
|
21
|
+
padding: var(--kj-space-sm) var(--kj-space-md);
|
|
22
|
+
font: 0.875rem var(--kj-font-sans);
|
|
23
|
+
cursor: pointer;
|
|
24
|
+
text-align: left;
|
|
25
|
+
}
|
|
26
|
+
.kj-tree-select-trigger:focus-visible {
|
|
27
|
+
outline: 2px solid var(--kj-bg-primary);
|
|
28
|
+
outline-offset: 2px;
|
|
29
|
+
}
|
|
30
|
+
.kj-tree-select[data-disabled] .kj-tree-select-trigger {
|
|
31
|
+
opacity: 0.45;
|
|
32
|
+
cursor: not-allowed;
|
|
33
|
+
pointer-events: none;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.kj-tree-select-trigger-label {
|
|
37
|
+
flex: 1;
|
|
38
|
+
overflow: hidden;
|
|
39
|
+
white-space: nowrap;
|
|
40
|
+
text-overflow: ellipsis;
|
|
41
|
+
}
|
|
42
|
+
/* Placeholder styling — when nothing is selected the label matches placeholder color */
|
|
43
|
+
.kj-tree-select[data-empty] .kj-tree-select-trigger-label,
|
|
44
|
+
.kj-tree-select:not([data-has-value]) .kj-tree-select-trigger-label {
|
|
45
|
+
color: color-mix(in oklab, var(--kj-fg-default) 55%, transparent);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.kj-tree-select-caret {
|
|
49
|
+
flex-shrink: 0;
|
|
50
|
+
color: color-mix(in oklab, var(--kj-fg-default) 60%, transparent);
|
|
51
|
+
font-size: 0.75rem;
|
|
52
|
+
transition: transform var(--kj-transition, 150ms ease);
|
|
53
|
+
}
|
|
54
|
+
.kj-tree-select[data-open] .kj-tree-select-caret {
|
|
55
|
+
transform: rotate(180deg);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* ── Panel ─────────────────────────────────────────────────────────── */
|
|
59
|
+
.kj-tree-select-panel {
|
|
60
|
+
box-sizing: border-box;
|
|
61
|
+
min-width: 14rem;
|
|
62
|
+
width: max-content;
|
|
63
|
+
background: var(--kj-bg-elevated);
|
|
64
|
+
border: var(--kj-border) solid var(--kj-border-default);
|
|
65
|
+
border-radius: var(--kj-radius-field);
|
|
66
|
+
box-shadow: var(--kj-shadow-md, 0 8px 24px rgb(0 0 0 / 0.12));
|
|
67
|
+
padding: 4px;
|
|
68
|
+
max-height: 18rem;
|
|
69
|
+
overflow: auto;
|
|
70
|
+
z-index: var(--kj-overlay-z, 100);
|
|
71
|
+
}
|
|
72
|
+
.kj-tree-select-panel[hidden] {
|
|
73
|
+
display: none;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.kj-tree-select-empty {
|
|
77
|
+
padding: var(--kj-space-sm) var(--kj-space-md);
|
|
78
|
+
color: color-mix(in oklab, var(--kj-fg-default) 55%, transparent);
|
|
79
|
+
font: 0.875rem var(--kj-font-sans);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* ── Node row ──────────────────────────────────────────────────────── */
|
|
83
|
+
.kj-tree-select-node {
|
|
84
|
+
display: flex;
|
|
85
|
+
align-items: center;
|
|
86
|
+
gap: var(--kj-space-xs);
|
|
87
|
+
border-radius: var(--kj-radius-selector);
|
|
88
|
+
cursor: pointer;
|
|
89
|
+
color: var(--kj-fg-default);
|
|
90
|
+
font: 0.875rem var(--kj-font-sans);
|
|
91
|
+
min-height: 2.25rem; /* WCAG 2.5.5 — 36px is acceptable within a scrollable list */
|
|
92
|
+
outline: none;
|
|
93
|
+
/* padding-inline-start is set via inline style per-level */
|
|
94
|
+
padding-block: var(--kj-space-xs);
|
|
95
|
+
padding-inline-end: var(--kj-space-md);
|
|
96
|
+
}
|
|
97
|
+
.kj-tree-select-node:hover {
|
|
98
|
+
background: var(--kj-bg-surface);
|
|
99
|
+
}
|
|
100
|
+
.kj-tree-select-node:focus-visible {
|
|
101
|
+
outline: 2px solid var(--kj-bg-primary);
|
|
102
|
+
outline-offset: -2px;
|
|
103
|
+
background: var(--kj-bg-surface);
|
|
104
|
+
}
|
|
105
|
+
.kj-tree-select-node[data-selected] {
|
|
106
|
+
background: color-mix(in oklab, var(--kj-bg-primary) 12%, transparent);
|
|
107
|
+
color: var(--kj-fg-primary);
|
|
108
|
+
}
|
|
109
|
+
.kj-tree-select-node[data-selected]:hover {
|
|
110
|
+
background: color-mix(in oklab, var(--kj-bg-primary) 18%, transparent);
|
|
111
|
+
}
|
|
112
|
+
.kj-tree-select-node[aria-disabled='true'] {
|
|
113
|
+
opacity: 0.45;
|
|
114
|
+
cursor: not-allowed;
|
|
115
|
+
pointer-events: none;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* Collapsed children are hidden via [hidden] attribute */
|
|
119
|
+
.kj-tree-select-node[hidden] {
|
|
120
|
+
display: none;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* ── Toggle button ─────────────────────────────────────────────────── */
|
|
124
|
+
.kj-tree-select-toggle {
|
|
125
|
+
flex-shrink: 0;
|
|
126
|
+
width: 1.25rem;
|
|
127
|
+
height: 1.25rem;
|
|
128
|
+
display: inline-flex;
|
|
129
|
+
align-items: center;
|
|
130
|
+
justify-content: center;
|
|
131
|
+
background: transparent;
|
|
132
|
+
border: 0;
|
|
133
|
+
padding: 0;
|
|
134
|
+
cursor: pointer;
|
|
135
|
+
color: color-mix(in oklab, var(--kj-fg-default) 60%, transparent);
|
|
136
|
+
border-radius: var(--kj-radius-selector);
|
|
137
|
+
}
|
|
138
|
+
.kj-tree-select-toggle:hover {
|
|
139
|
+
background: color-mix(in oklab, var(--kj-fg-default) 10%, transparent);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.kj-tree-select-toggle-icon {
|
|
143
|
+
display: inline-block;
|
|
144
|
+
width: 0;
|
|
145
|
+
height: 0;
|
|
146
|
+
border-style: solid;
|
|
147
|
+
/* Collapsed: right-pointing triangle */
|
|
148
|
+
border-width: 4px 0 4px 7px;
|
|
149
|
+
border-color: transparent transparent transparent currentColor;
|
|
150
|
+
transition: transform var(--kj-transition, 150ms ease);
|
|
151
|
+
}
|
|
152
|
+
.kj-tree-select-node[data-expanded='true'] .kj-tree-select-toggle-icon {
|
|
153
|
+
/* Expanded: downward triangle */
|
|
154
|
+
transform: rotate(90deg);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* Indent spacer for leaf nodes (keeps labels aligned with branch labels) */
|
|
158
|
+
.kj-tree-select-indent {
|
|
159
|
+
flex-shrink: 0;
|
|
160
|
+
width: 1.25rem;
|
|
161
|
+
height: 1.25rem;
|
|
162
|
+
display: inline-block;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.kj-tree-select-label {
|
|
166
|
+
flex: 1;
|
|
167
|
+
overflow: hidden;
|
|
168
|
+
white-space: nowrap;
|
|
169
|
+
text-overflow: ellipsis;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/* ── Checkbox (multi mode — tri-state via aria-checked) ─────────────── */
|
|
173
|
+
.kj-tree-select-checkbox {
|
|
174
|
+
flex-shrink: 0;
|
|
175
|
+
width: 1rem;
|
|
176
|
+
height: 1rem;
|
|
177
|
+
border: var(--kj-border) solid var(--kj-border-default);
|
|
178
|
+
border-radius: var(--kj-radius-selector);
|
|
179
|
+
display: inline-flex;
|
|
180
|
+
align-items: center;
|
|
181
|
+
justify-content: center;
|
|
182
|
+
font-size: 0.75rem;
|
|
183
|
+
line-height: 1;
|
|
184
|
+
/* Visual breathing room between the checkbox and the label so the
|
|
185
|
+
glyph never butts up against the text. The container's `gap`
|
|
186
|
+
handles the toggle ↔ checkbox spacing; this rule owns checkbox ↔
|
|
187
|
+
label specifically. */
|
|
188
|
+
margin-inline-end: var(--kj-space-sm);
|
|
189
|
+
}
|
|
190
|
+
/* Checked (cascade: all leaf descendants selected, or this is a
|
|
191
|
+
selected leaf). */
|
|
192
|
+
.kj-tree-select-node[aria-checked='true'] .kj-tree-select-checkbox {
|
|
193
|
+
background: var(--kj-bg-primary);
|
|
194
|
+
border-color: var(--kj-bg-primary);
|
|
195
|
+
color: var(--kj-fg-on-primary);
|
|
196
|
+
}
|
|
197
|
+
.kj-tree-select-node[aria-checked='true'] .kj-tree-select-checkbox::before {
|
|
198
|
+
content: '✓';
|
|
199
|
+
}
|
|
200
|
+
/* Indeterminate (cascade: some — but not all — leaf descendants
|
|
201
|
+
selected). Renders a dash glyph and keeps the primary fill so
|
|
202
|
+
screen-reader users hearing `aria-checked="mixed"` see the same
|
|
203
|
+
state visually. */
|
|
204
|
+
.kj-tree-select-node[aria-checked='mixed'] .kj-tree-select-checkbox {
|
|
205
|
+
background: var(--kj-bg-primary);
|
|
206
|
+
border-color: var(--kj-bg-primary);
|
|
207
|
+
color: var(--kj-fg-on-primary);
|
|
208
|
+
}
|
|
209
|
+
.kj-tree-select-node[aria-checked='mixed'] .kj-tree-select-checkbox::before {
|
|
210
|
+
content: '−'; /* U+2212 minus, not a hyphen */
|
|
211
|
+
}
|
|
212
|
+
/* Row highlight for fully checked branches/leaves in cascade mode. */
|
|
213
|
+
.kj-tree-select-node[aria-checked='true'] {
|
|
214
|
+
background: color-mix(in oklab, var(--kj-bg-primary) 12%, transparent);
|
|
215
|
+
color: var(--kj-fg-primary);
|
|
216
|
+
}
|
|
217
|
+
.kj-tree-select-node[aria-checked='true']:hover {
|
|
218
|
+
background: color-mix(in oklab, var(--kj-bg-primary) 18%, transparent);
|
|
219
|
+
}
|
|
220
|
+
}
|