@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.
Files changed (70) hide show
  1. package/package.json +1 -1
  2. package/src/accordion/accordion.css +68 -0
  3. package/src/action-sheet/action-sheet.css +79 -0
  4. package/src/alert/alert.css +133 -0
  5. package/src/avatar/avatar.css +93 -0
  6. package/src/badge/badge.css +59 -0
  7. package/src/breadcrumb/breadcrumb.css +145 -0
  8. package/src/button/button.css +295 -0
  9. package/src/button-group/button-group.css +114 -0
  10. package/src/calendar/calendar.css +129 -0
  11. package/src/card/card.css +120 -0
  12. package/src/carousel/carousel.css +181 -0
  13. package/src/cascade-select/cascade-select.css +120 -0
  14. package/src/chart/chart.css +26 -0
  15. package/src/chat/chat-ai.css +352 -0
  16. package/src/chat/chat.css +231 -0
  17. package/src/checkbox/checkbox.css +74 -0
  18. package/src/color-picker/color-picker.css +183 -0
  19. package/src/combobox/combobox.css +101 -0
  20. package/src/command-palette/command-palette.css +234 -0
  21. package/src/confirm-popup/confirm-popup.css +47 -0
  22. package/src/date-picker/date-picker.css +61 -0
  23. package/src/date-range-presets/date-range-presets.css +49 -0
  24. package/src/datetime-picker/datetime-picker.css +84 -0
  25. package/src/dialog/dialog.css +56 -0
  26. package/src/direction-toggle/direction-toggle.css +55 -0
  27. package/src/divider/divider.css +93 -0
  28. package/src/drawer/drawer.css +130 -0
  29. package/src/dropdown-menu/dropdown-menu.css +108 -0
  30. package/src/editor/editor.css +140 -0
  31. package/src/empty-state/empty-state.css +114 -0
  32. package/src/field/field.css +148 -0
  33. package/src/file-upload/file-upload.css +207 -0
  34. package/src/form/form.css +63 -0
  35. package/src/input/input.css +70 -0
  36. package/src/input-group/input-group.css +125 -0
  37. package/src/input-mask/input-mask.css +39 -0
  38. package/src/input-otp/input-otp.css +87 -0
  39. package/src/kbd/kbd.css +67 -0
  40. package/src/link/link.css +104 -0
  41. package/src/list/list.css +166 -0
  42. package/src/menubar/menubar.css +62 -0
  43. package/src/number-input/number-input.css +115 -0
  44. package/src/overflow/overflow.css +43 -0
  45. package/src/overlay/overlay.css +45 -0
  46. package/src/overlay-badge/overlay-badge.css +118 -0
  47. package/src/pagination/pagination.css +146 -0
  48. package/src/password-input/password-input.css +155 -0
  49. package/src/popover/popover.css +71 -0
  50. package/src/progress-bar/progress-bar.css +113 -0
  51. package/src/radio/radio.css +58 -0
  52. package/src/rich-text/rich-text-editor.css +351 -0
  53. package/src/select/select.css +91 -0
  54. package/src/sheet/sheet.css +121 -0
  55. package/src/skeleton/skeleton.css +111 -0
  56. package/src/skip-link/skip-link.css +58 -0
  57. package/src/slider/slider.css +172 -0
  58. package/src/speed-dial/speed-dial.css +137 -0
  59. package/src/spinner/spinner.css +161 -0
  60. package/src/stepper/stepper.css +147 -0
  61. package/src/table/table-filters/filters.css +53 -0
  62. package/src/table/table.css +509 -0
  63. package/src/tabs/tabs.css +162 -0
  64. package/src/tag/tag.css +183 -0
  65. package/src/textarea/textarea.css +117 -0
  66. package/src/time-picker/time-picker.css +126 -0
  67. package/src/toast/toast.css +115 -0
  68. package/src/toggle/toggle.css +123 -0
  69. package/src/tooltip/tooltip.css +61 -0
  70. package/src/tree-select/tree-select.css +220 -0
@@ -0,0 +1,231 @@
1
+ @layer kj.component {
2
+ /* ── Log container ───────────────────────────────────────── */
3
+ .kj-chat-log {
4
+ display: flex;
5
+ flex-direction: column;
6
+ gap: var(--kj-space-md);
7
+ padding: var(--kj-space-md);
8
+ background: var(--kj-bg-body);
9
+ color: var(--kj-fg-default);
10
+ border-radius: var(--kj-radius-box);
11
+ overflow-y: auto;
12
+ font-family: var(--kj-font-sans);
13
+ }
14
+
15
+ /* ── Row ─────────────────────────────────────────────────── */
16
+ .kj-chat {
17
+ --kj-chat-gap: var(--kj-space-sm);
18
+ --kj-chat-col-gap: 0.125rem;
19
+
20
+ display: grid;
21
+ grid-template-columns: auto 1fr;
22
+ grid-template-areas:
23
+ 'avatar header'
24
+ 'avatar bubble'
25
+ 'avatar footer';
26
+ column-gap: var(--kj-chat-gap);
27
+ row-gap: var(--kj-chat-col-gap);
28
+ align-items: end;
29
+ max-width: 100%;
30
+ }
31
+
32
+ .kj-chat[data-side='start'] {
33
+ justify-self: start;
34
+ margin-inline-end: auto;
35
+ }
36
+
37
+ .kj-chat[data-side='end'] {
38
+ justify-self: end;
39
+ margin-inline-start: auto;
40
+ grid-template-columns: 1fr auto;
41
+ grid-template-areas:
42
+ 'header avatar'
43
+ 'bubble avatar'
44
+ 'footer avatar';
45
+ text-align: end;
46
+ }
47
+
48
+ /* RTL flip is cascade-driven: `data-side` is logical, the cascade swaps
49
+ the physical column. */
50
+ [dir='rtl'] .kj-chat[data-side='start'] {
51
+ grid-template-columns: 1fr auto;
52
+ grid-template-areas:
53
+ 'header avatar'
54
+ 'bubble avatar'
55
+ 'footer avatar';
56
+ text-align: end;
57
+ }
58
+ [dir='rtl'] .kj-chat[data-side='end'] {
59
+ grid-template-columns: auto 1fr;
60
+ grid-template-areas:
61
+ 'avatar header'
62
+ 'avatar bubble'
63
+ 'avatar footer';
64
+ text-align: start;
65
+ }
66
+
67
+ /* Grouping suppresses avatar / header visibility but preserves layout
68
+ so the gap stays tight and consistent. */
69
+ .kj-chat[data-grouped] .kj-chat-avatar { visibility: hidden; }
70
+ .kj-chat[data-grouped] .kj-chat-header { display: none; }
71
+
72
+ /* ── Avatar slot ─────────────────────────────────────────── */
73
+ .kj-chat-avatar {
74
+ grid-area: avatar;
75
+ align-self: end;
76
+ width: 2.25rem;
77
+ height: 2.25rem;
78
+ display: inline-flex;
79
+ align-items: center;
80
+ justify-content: center;
81
+ flex: none;
82
+ user-select: none;
83
+ }
84
+
85
+ /* ── Header (name + time) ────────────────────────────────── */
86
+ .kj-chat-header {
87
+ grid-area: header;
88
+ font-size: 0.75rem;
89
+ color: var(--kj-fg-default);
90
+ opacity: 0.7;
91
+ display: inline-flex;
92
+ align-items: baseline;
93
+ gap: var(--kj-space-xs);
94
+ margin-bottom: 0.125rem;
95
+ }
96
+
97
+ .kj-chat-header time {
98
+ font-variant-numeric: tabular-nums;
99
+ opacity: 0.85;
100
+ }
101
+
102
+ /* ── Bubble body ─────────────────────────────────────────── */
103
+ .kj-chat-bubble {
104
+ --kj-chat-bubble-bg: var(--kj-bg-surface);
105
+ --kj-chat-bubble-fg: var(--kj-fg-default);
106
+ --kj-chat-bubble-radius: var(--kj-radius-box, 0.75rem);
107
+ --kj-chat-bubble-padding-x: var(--kj-space-md);
108
+ --kj-chat-bubble-padding-y: var(--kj-space-sm);
109
+ --kj-chat-bubble-font-size: 0.9375rem;
110
+
111
+ grid-area: bubble;
112
+ position: relative;
113
+ display: inline-block;
114
+ max-width: min(36rem, 100%);
115
+ background: var(--kj-chat-bubble-bg);
116
+ color: var(--kj-chat-bubble-fg);
117
+ padding: var(--kj-chat-bubble-padding-y) var(--kj-chat-bubble-padding-x);
118
+ border-radius: var(--kj-chat-bubble-radius);
119
+ font-size: var(--kj-chat-bubble-font-size);
120
+ line-height: 1.45;
121
+ word-wrap: break-word;
122
+ overflow-wrap: anywhere;
123
+ margin: 0;
124
+ }
125
+
126
+ /* Variant tokens. Each pairs background + readable foreground. */
127
+ .kj-chat-bubble[data-variant='primary'] {
128
+ --kj-chat-bubble-bg: var(--kj-bg-primary, #2563eb);
129
+ --kj-chat-bubble-fg: var(--kj-fg-on-primary, #ffffff);
130
+ }
131
+ .kj-chat-bubble[data-variant='secondary'] {
132
+ --kj-chat-bubble-bg: var(--kj-bg-field, var(--kj-bg-field));
133
+ --kj-chat-bubble-fg: var(--kj-fg-default, var(--kj-fg-default));
134
+ }
135
+ .kj-chat-bubble[data-variant='accent'] {
136
+ --kj-chat-bubble-bg: var(--kj-bg-accent, #a855f7);
137
+ --kj-chat-bubble-fg: var(--kj-fg-on-accent, #ffffff);
138
+ }
139
+ .kj-chat-bubble[data-variant='info'] {
140
+ --kj-chat-bubble-bg: var(--kj-bg-info, #0ea5e9);
141
+ --kj-chat-bubble-fg: var(--kj-fg-on-info, #ffffff);
142
+ }
143
+ .kj-chat-bubble[data-variant='success'] {
144
+ --kj-chat-bubble-bg: var(--kj-bg-success, #16a34a);
145
+ --kj-chat-bubble-fg: var(--kj-fg-on-success, #ffffff);
146
+ }
147
+ .kj-chat-bubble[data-variant='warning'] {
148
+ --kj-chat-bubble-bg: var(--kj-bg-warning, #f59e0b);
149
+ --kj-chat-bubble-fg: var(--kj-fg-on-warning, #1f1300);
150
+ }
151
+ .kj-chat-bubble[data-variant='error'] {
152
+ --kj-chat-bubble-bg: var(--kj-bg-danger, #dc2626);
153
+ --kj-chat-bubble-fg: var(--kj-fg-on-danger, #ffffff);
154
+ }
155
+
156
+ /* Sizes: padding + type-scale only — radius cascades through `em`. */
157
+ .kj-chat-bubble[data-size='sm'] {
158
+ --kj-chat-bubble-padding-x: var(--kj-space-sm);
159
+ --kj-chat-bubble-padding-y: 0.25rem;
160
+ --kj-chat-bubble-font-size: 0.8125rem;
161
+ }
162
+ .kj-chat-bubble[data-size='lg'] {
163
+ --kj-chat-bubble-padding-x: var(--kj-space-lg);
164
+ --kj-chat-bubble-padding-y: var(--kj-space-md);
165
+ --kj-chat-bubble-font-size: 1.0625rem;
166
+ }
167
+
168
+ /* Tail — drawn only when the bubble carries `data-tail`. */
169
+ .kj-chat-bubble[data-tail]::before {
170
+ content: '';
171
+ position: absolute;
172
+ bottom: 0;
173
+ width: 0.625rem;
174
+ height: 0.75rem;
175
+ background: var(--kj-chat-bubble-bg);
176
+ }
177
+
178
+ .kj-chat[data-side='start'] .kj-chat-bubble[data-tail]::before {
179
+ left: -0.375rem;
180
+ border-bottom-right-radius: 0.625rem;
181
+ clip-path: path('M 10 0 Q 0 4 0 12 L 10 12 Z');
182
+ }
183
+ .kj-chat[data-side='end'] .kj-chat-bubble[data-tail]::before {
184
+ right: -0.375rem;
185
+ border-bottom-left-radius: 0.625rem;
186
+ clip-path: path('M 0 0 Q 10 4 10 12 L 0 12 Z');
187
+ }
188
+ /* RTL: tails follow the visual side. */
189
+ [dir='rtl'] .kj-chat[data-side='start'] .kj-chat-bubble[data-tail]::before {
190
+ left: auto;
191
+ right: -0.375rem;
192
+ clip-path: path('M 0 0 Q 10 4 10 12 L 0 12 Z');
193
+ }
194
+ [dir='rtl'] .kj-chat[data-side='end'] .kj-chat-bubble[data-tail]::before {
195
+ right: auto;
196
+ left: -0.375rem;
197
+ clip-path: path('M 10 0 Q 0 4 0 12 L 10 12 Z');
198
+ }
199
+
200
+ /* ── Footer (read state) ─────────────────────────────────── */
201
+ .kj-chat-footer {
202
+ grid-area: footer;
203
+ font-size: 0.6875rem;
204
+ color: var(--kj-fg-default);
205
+ opacity: 0.6;
206
+ display: inline-flex;
207
+ align-items: center;
208
+ gap: 0.25rem;
209
+ margin-top: 0.125rem;
210
+ }
211
+
212
+ /* Glyphs keyed off `data-state`. CSS-only — uses unicode primitives so
213
+ no icon font is required. */
214
+ .kj-chat-footer[data-state]::before {
215
+ display: inline-flex;
216
+ align-items: center;
217
+ line-height: 1;
218
+ font-weight: 600;
219
+ }
220
+ .kj-chat-footer[data-state='sending']::before { content: '\025F7'; opacity: 0.7; }
221
+ .kj-chat-footer[data-state='sent']::before { content: '\02713'; }
222
+ .kj-chat-footer[data-state='delivered']::before { content: '\02713\02713'; letter-spacing: -0.15em; padding-inline-end: 0.15em; }
223
+ .kj-chat-footer[data-state='read']::before { content: '\02713\02713'; letter-spacing: -0.15em; padding-inline-end: 0.15em; color: var(--kj-fg-info, #0ea5e9); }
224
+ .kj-chat-footer[data-state='error']::before { content: '\0203C'; color: var(--kj-fg-danger, #dc2626); }
225
+
226
+ /* Reduced motion: the tail is static, so nothing here animates. The log's
227
+ scroll behaviour is the consumer's; this rule documents the contract. */
228
+ @media (prefers-reduced-motion: reduce) {
229
+ .kj-chat-log { scroll-behavior: auto; }
230
+ }
231
+ }
@@ -0,0 +1,74 @@
1
+ @layer kj.component {
2
+ /* Outer host. Acts as a single click target whose label area forwards to
3
+ the inner box. */
4
+ .kj-checkbox {
5
+ display: inline-flex;
6
+ }
7
+
8
+ .kj-checkbox-inner {
9
+ display: inline-flex;
10
+ align-items: center;
11
+ gap: var(--kj-space-sm);
12
+ cursor: pointer;
13
+ color: var(--kj-fg-default);
14
+ font: 0.875rem / 1.4 var(--kj-font-sans);
15
+ }
16
+ .kj-checkbox-label { user-select: none; }
17
+
18
+ /* The interactive box (carries the kjCheckbox directive). */
19
+ .kj-checkbox-box {
20
+ --kj-checkbox-size: 1rem;
21
+ --kj-checkbox-bg: var(--kj-bg-body);
22
+ --kj-checkbox-bg-checked: var(--kj-bg-primary);
23
+ --kj-checkbox-fg-checked: var(--kj-fg-on-primary);
24
+ --kj-checkbox-border: var(--kj-border-default);
25
+ --kj-checkbox-radius: var(--kj-radius-selector);
26
+
27
+ display: inline-flex;
28
+ align-items: center;
29
+ justify-content: center;
30
+ flex-shrink: 0;
31
+ width: var(--kj-checkbox-size);
32
+ height: var(--kj-checkbox-size);
33
+ background: var(--kj-checkbox-bg);
34
+ border: var(--kj-border) solid var(--kj-checkbox-border);
35
+ border-radius: var(--kj-checkbox-radius);
36
+ transition: var(--kj-transition);
37
+ }
38
+
39
+ .kj-checkbox-box[data-checked] {
40
+ background: var(--kj-checkbox-bg-checked);
41
+ border-color: var(--kj-checkbox-bg-checked);
42
+ }
43
+ .kj-checkbox-box[data-checked]::after {
44
+ content: '✓';
45
+ color: var(--kj-checkbox-fg-checked);
46
+ font-size: 0.75rem;
47
+ line-height: 1;
48
+ }
49
+
50
+ .kj-checkbox-box[data-indeterminate]::after {
51
+ content: '';
52
+ width: 60%;
53
+ height: 2px;
54
+ background: var(--kj-checkbox-fg-checked);
55
+ }
56
+ .kj-checkbox-box[data-indeterminate] {
57
+ background: var(--kj-checkbox-bg-checked);
58
+ border-color: var(--kj-checkbox-bg-checked);
59
+ }
60
+
61
+ .kj-checkbox-box[data-size="sm"] { --kj-checkbox-size: 0.875rem; }
62
+ .kj-checkbox-box[data-size="lg"] { --kj-checkbox-size: 1.25rem; }
63
+
64
+ .kj-checkbox-box:focus-visible { outline: 2px solid var(--kj-border-focus); outline-offset: 2px; }
65
+
66
+ /* Disabled — dim the whole checkbox (box + label text) for visual
67
+ consistency with native form controls. */
68
+ .kj-checkbox[data-disabled] .kj-checkbox-inner { cursor: not-allowed; }
69
+ .kj-checkbox[data-disabled] .kj-checkbox-box,
70
+ .kj-checkbox[data-disabled] .kj-checkbox-label {
71
+ opacity: 0.45;
72
+ }
73
+ .kj-checkbox[data-disabled] .kj-checkbox-box { pointer-events: none; }
74
+ }
@@ -0,0 +1,183 @@
1
+ @layer kj.component {
2
+ .kj-color-picker {
3
+ position: relative;
4
+ display: inline-block;
5
+ }
6
+
7
+ .kj-color-picker-trigger {
8
+ /* WCAG 2.5.5 — replaces the existing 44×32 native swatch that fails AAA. */
9
+ width: 44px;
10
+ height: 44px;
11
+ padding: 0;
12
+ border: var(--kj-border) solid var(--kj-border-default);
13
+ border-radius: var(--kj-radius-field);
14
+ cursor: pointer;
15
+ /* Checkerboard backdrop for translucent colors. The current color is
16
+ layered on top via the inline style hook. */
17
+ background:
18
+ linear-gradient(var(--kj-color-picker-current, #000), var(--kj-color-picker-current, #000)),
19
+ conic-gradient(#ccc 25%, #fff 0 50%, #ccc 0 75%, #fff 0) 0 0 / 12px 12px;
20
+ }
21
+ .kj-color-picker-trigger[data-disabled] {
22
+ cursor: not-allowed;
23
+ opacity: 0.5;
24
+ }
25
+ .kj-color-picker-trigger:focus-visible {
26
+ outline: 2px solid var(--kj-border-focus);
27
+ outline-offset: 2px;
28
+ }
29
+
30
+ .kj-color-picker-panel {
31
+ box-sizing: border-box;
32
+ z-index: var(--kj-overlay-z, 1000);
33
+ width: 280px;
34
+ padding: var(--kj-space-md);
35
+ background: var(--kj-bg-body);
36
+ border: var(--kj-border) solid var(--kj-border-default);
37
+ border-radius: var(--kj-radius-field);
38
+ box-shadow: var(--kj-shadow-md);
39
+ display: flex;
40
+ flex-direction: column;
41
+ gap: var(--kj-space-sm);
42
+ color: var(--kj-fg-default);
43
+ }
44
+ .kj-color-picker-panel[hidden] { display: none; }
45
+
46
+ /* 2-axis sat/value rectangle. Hue passed through as a hsl() wedge,
47
+ a horizontal white→saturated-color gradient, and a vertical
48
+ transparent→black gradient, layered to produce the standard square. */
49
+ .kj-color-picker-area {
50
+ position: relative;
51
+ width: 100%;
52
+ height: 160px;
53
+ border-radius: 4px;
54
+ cursor: crosshair;
55
+ background:
56
+ linear-gradient(to top, #000, transparent),
57
+ linear-gradient(to right, #fff, hsl(var(--kj-color-picker-hue, 0), 100%, 50%));
58
+ touch-action: none;
59
+ }
60
+ .kj-color-picker-area:focus-visible {
61
+ outline: 2px solid var(--kj-border-focus);
62
+ outline-offset: 2px;
63
+ }
64
+ .kj-color-picker-area::after {
65
+ content: '';
66
+ position: absolute;
67
+ width: 14px;
68
+ height: 14px;
69
+ margin: -7px 0 0 -7px;
70
+ /* Saturation drives x; (1 - value) drives y so visually high y = low value. */
71
+ left: calc(var(--kj-color-picker-x, 0) * 100%);
72
+ top: calc((1 - var(--kj-color-picker-y, 0)) * 100%);
73
+ border: 2px solid #fff;
74
+ box-shadow: 0 0 0 1px #000, 0 0 4px rgb(0 0 0 / 0.4);
75
+ border-radius: 50%;
76
+ pointer-events: none;
77
+ }
78
+
79
+ .kj-color-picker-hue-slider,
80
+ .kj-color-picker-alpha-slider {
81
+ width: 100%;
82
+ height: 16px;
83
+ margin: 0;
84
+ -webkit-appearance: none;
85
+ appearance: none;
86
+ background: transparent;
87
+ cursor: pointer;
88
+ }
89
+ .kj-color-picker-hue-slider::-webkit-slider-runnable-track {
90
+ height: 12px;
91
+ border-radius: 6px;
92
+ background: linear-gradient(to right,
93
+ #ff0000, #ffff00, #00ff00, #00ffff, #0000ff, #ff00ff, #ff0000);
94
+ }
95
+ .kj-color-picker-hue-slider::-moz-range-track {
96
+ height: 12px;
97
+ border-radius: 6px;
98
+ background: linear-gradient(to right,
99
+ #ff0000, #ffff00, #00ff00, #00ffff, #0000ff, #ff00ff, #ff0000);
100
+ }
101
+ .kj-color-picker-alpha-slider::-webkit-slider-runnable-track {
102
+ height: 12px;
103
+ border-radius: 6px;
104
+ background:
105
+ linear-gradient(to right, transparent, var(--kj-color-picker-current, #000)),
106
+ conic-gradient(#ccc 25%, #fff 0 50%, #ccc 0 75%, #fff 0) 0 0 / 8px 8px;
107
+ }
108
+ .kj-color-picker-alpha-slider::-moz-range-track {
109
+ height: 12px;
110
+ border-radius: 6px;
111
+ background:
112
+ linear-gradient(to right, transparent, var(--kj-color-picker-current, #000)),
113
+ conic-gradient(#ccc 25%, #fff 0 50%, #ccc 0 75%, #fff 0) 0 0 / 8px 8px;
114
+ }
115
+ .kj-color-picker-hue-slider::-webkit-slider-thumb,
116
+ .kj-color-picker-alpha-slider::-webkit-slider-thumb {
117
+ -webkit-appearance: none;
118
+ appearance: none;
119
+ width: 14px;
120
+ height: 14px;
121
+ border-radius: 50%;
122
+ background: #fff;
123
+ border: 2px solid #000;
124
+ margin-top: -1px;
125
+ }
126
+ .kj-color-picker-hue-slider::-moz-range-thumb,
127
+ .kj-color-picker-alpha-slider::-moz-range-thumb {
128
+ width: 14px;
129
+ height: 14px;
130
+ border-radius: 50%;
131
+ background: #fff;
132
+ border: 2px solid #000;
133
+ }
134
+ .kj-color-picker-hue-slider:focus-visible,
135
+ .kj-color-picker-alpha-slider:focus-visible {
136
+ outline: 2px solid var(--kj-border-focus);
137
+ outline-offset: 2px;
138
+ }
139
+
140
+ .kj-color-picker-input {
141
+ width: 100%;
142
+ box-sizing: border-box;
143
+ padding: var(--kj-space-xs) var(--kj-space-sm);
144
+ border: var(--kj-border) solid var(--kj-border-default);
145
+ border-radius: var(--kj-radius-field);
146
+ background: var(--kj-bg-body);
147
+ color: var(--kj-fg-default);
148
+ font: 0.8125rem var(--kj-font-mono, monospace);
149
+ }
150
+ .kj-color-picker-input[aria-invalid="true"] {
151
+ border-color: var(--kj-border-danger, #ef4444);
152
+ }
153
+
154
+ .kj-color-picker-presets {
155
+ display: grid;
156
+ grid-template-columns: repeat(8, 1fr);
157
+ gap: 6px;
158
+ }
159
+ .kj-color-picker-preset {
160
+ width: 24px;
161
+ height: 24px;
162
+ padding: 0;
163
+ border: var(--kj-border) solid var(--kj-border-default);
164
+ border-radius: 4px;
165
+ cursor: pointer;
166
+ }
167
+ .kj-color-picker-preset[aria-selected="true"] {
168
+ outline: 2px solid var(--kj-border-focus);
169
+ outline-offset: 1px;
170
+ }
171
+ .kj-color-picker-preset:focus-visible {
172
+ outline: 2px solid var(--kj-border-focus);
173
+ outline-offset: 2px;
174
+ }
175
+
176
+ @media (prefers-reduced-motion: reduce) {
177
+ .kj-color-picker-panel,
178
+ .kj-color-picker-trigger,
179
+ .kj-color-picker-area::after {
180
+ transition: none !important;
181
+ }
182
+ }
183
+ }
@@ -0,0 +1,101 @@
1
+ @layer kj.component {
2
+ .kj-combobox {
3
+ position: relative;
4
+ display: inline-block;
5
+ min-width: 16rem;
6
+ }
7
+
8
+ .kj-combobox-input {
9
+ width: 100%;
10
+ background: var(--kj-bg-field);
11
+ color: var(--kj-fg-default);
12
+ border: var(--kj-border) solid var(--kj-border-default);
13
+ border-radius: var(--kj-radius-field);
14
+ padding: var(--kj-space-sm) var(--kj-space-md);
15
+ font: 0.875rem var(--kj-font-sans);
16
+ }
17
+ .kj-combobox-input:focus-visible {
18
+ outline: 2px solid var(--kj-border-focus);
19
+ outline-offset: 2px;
20
+ }
21
+ .kj-combobox-input[aria-busy="true"] {
22
+ background-image: linear-gradient(
23
+ 90deg,
24
+ transparent 0%,
25
+ var(--kj-bg-surface) 50%,
26
+ transparent 100%
27
+ );
28
+ background-size: 200% 100%;
29
+ animation: kj-combobox-shimmer 1.4s linear infinite;
30
+ }
31
+ .kj-combobox[data-disabled] .kj-combobox-input {
32
+ opacity: 0.45;
33
+ cursor: not-allowed;
34
+ pointer-events: none;
35
+ }
36
+
37
+ .kj-combobox-listbox {
38
+ box-sizing: border-box;
39
+ min-width: 16rem;
40
+ width: max-content;
41
+ background: var(--kj-bg-elevated);
42
+ border: var(--kj-border) solid var(--kj-border-default);
43
+ border-radius: var(--kj-radius-field);
44
+ box-shadow: var(--kj-shadow-md);
45
+ padding: 4px;
46
+ max-height: 16rem;
47
+ overflow: auto;
48
+ z-index: var(--kj-overlay-z, 100);
49
+ display: flex;
50
+ flex-direction: column;
51
+ }
52
+ .kj-combobox-listbox[hidden] { display: none; }
53
+
54
+ .kj-combobox-option {
55
+ display: flex;
56
+ align-items: center;
57
+ gap: var(--kj-space-sm);
58
+ width: 100%;
59
+ text-align: left;
60
+ padding: var(--kj-space-sm) var(--kj-space-md);
61
+ border: none;
62
+ background: transparent;
63
+ color: var(--kj-fg-default);
64
+ border-radius: var(--kj-radius-selector);
65
+ cursor: pointer;
66
+ font: 0.875rem var(--kj-font-sans);
67
+ }
68
+ .kj-combobox-option:hover,
69
+ .kj-combobox-option[data-active] {
70
+ background: var(--kj-bg-surface);
71
+ }
72
+ .kj-combobox-option[aria-selected="true"] {
73
+ background: var(--kj-bg-surface);
74
+ font-weight: 600;
75
+ }
76
+ .kj-combobox-option[hidden] { display: none; }
77
+ .kj-combobox-option[aria-disabled="true"],
78
+ .kj-combobox-option[disabled] {
79
+ opacity: 0.45;
80
+ cursor: not-allowed;
81
+ }
82
+
83
+ .kj-combobox-empty,
84
+ .kj-combobox-loading {
85
+ padding: var(--kj-space-md);
86
+ color: var(--kj-fg-default);
87
+ opacity: 0.7;
88
+ font: 0.875rem var(--kj-font-sans);
89
+ text-align: center;
90
+ }
91
+ .kj-combobox-empty[hidden],
92
+ .kj-combobox-loading[hidden] { display: none; }
93
+
94
+ @keyframes kj-combobox-shimmer {
95
+ 0% { background-position: 200% 0; }
96
+ 100% { background-position: -200% 0; }
97
+ }
98
+ @media (prefers-reduced-motion: reduce) {
99
+ .kj-combobox-input[aria-busy="true"] { animation: none; }
100
+ }
101
+ }