@llui/components 0.0.6 → 0.0.8
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/components/date-picker.d.ts +12 -0
- package/dist/components/date-picker.d.ts.map +1 -1
- package/dist/components/date-picker.js +18 -1
- package/dist/components/file-upload.d.ts +1 -0
- package/dist/components/file-upload.d.ts.map +1 -1
- package/dist/components/file-upload.js +1 -0
- package/dist/components/form.d.ts +115 -0
- package/dist/components/form.d.ts.map +1 -0
- package/dist/components/form.js +102 -0
- package/dist/components/hover-card.d.ts +0 -1
- package/dist/components/hover-card.d.ts.map +1 -1
- package/dist/components/hover-card.js +0 -1
- package/dist/components/index.d.ts +9 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +6 -0
- package/dist/components/scroll-area.d.ts +1 -0
- package/dist/components/scroll-area.d.ts.map +1 -1
- package/dist/components/scroll-area.js +1 -0
- package/dist/components/sortable.d.ts +146 -0
- package/dist/components/sortable.d.ts.map +1 -0
- package/dist/components/sortable.js +311 -0
- package/dist/components/tags-input.d.ts +0 -1
- package/dist/components/tags-input.d.ts.map +1 -1
- package/dist/components/tags-input.js +0 -1
- package/dist/components/theme-switch.d.ts +89 -0
- package/dist/components/theme-switch.d.ts.map +1 -0
- package/dist/components/theme-switch.js +96 -0
- package/dist/components/toggle-group.d.ts +0 -1
- package/dist/components/toggle-group.d.ts.map +1 -1
- package/dist/components/toggle-group.js +0 -1
- package/dist/styles/classes/listbox.js +1 -1
- package/dist/styles/classes/select.js +1 -1
- package/dist/styles/theme-dark.css +2 -0
- package/dist/styles/theme.css +3 -3
- package/dist/utils/validators.d.ts +34 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/utils/validators.js +83 -0
- package/package.json +4 -3
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
export function init() {
|
|
2
|
+
return { dragging: null };
|
|
3
|
+
}
|
|
4
|
+
export function update(state, msg) {
|
|
5
|
+
switch (msg.type) {
|
|
6
|
+
case 'start':
|
|
7
|
+
return [
|
|
8
|
+
{
|
|
9
|
+
dragging: {
|
|
10
|
+
id: msg.id,
|
|
11
|
+
startIndex: msg.index,
|
|
12
|
+
currentIndex: msg.index,
|
|
13
|
+
fromContainer: msg.container,
|
|
14
|
+
toContainer: msg.container,
|
|
15
|
+
startY: msg.y,
|
|
16
|
+
currentY: msg.y,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
[],
|
|
20
|
+
];
|
|
21
|
+
case 'move': {
|
|
22
|
+
if (!state.dragging)
|
|
23
|
+
return [state, []];
|
|
24
|
+
if (state.dragging.currentIndex === msg.index &&
|
|
25
|
+
state.dragging.toContainer === msg.container &&
|
|
26
|
+
state.dragging.currentY === msg.y) {
|
|
27
|
+
return [state, []];
|
|
28
|
+
}
|
|
29
|
+
return [
|
|
30
|
+
{
|
|
31
|
+
dragging: {
|
|
32
|
+
...state.dragging,
|
|
33
|
+
currentIndex: msg.index,
|
|
34
|
+
toContainer: msg.container,
|
|
35
|
+
currentY: msg.y,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
[],
|
|
39
|
+
];
|
|
40
|
+
}
|
|
41
|
+
case 'drop':
|
|
42
|
+
return state.dragging ? [{ dragging: null }, []] : [state, []];
|
|
43
|
+
case 'cancel':
|
|
44
|
+
return state.dragging ? [{ dragging: null }, []] : [state, []];
|
|
45
|
+
case 'toggleGrab':
|
|
46
|
+
if (state.dragging) {
|
|
47
|
+
// Already dragging — drop at current position
|
|
48
|
+
return [{ dragging: null }, []];
|
|
49
|
+
}
|
|
50
|
+
// Pick up (keyboard — no pointer position)
|
|
51
|
+
return [
|
|
52
|
+
{
|
|
53
|
+
dragging: {
|
|
54
|
+
id: msg.id,
|
|
55
|
+
startIndex: msg.index,
|
|
56
|
+
currentIndex: msg.index,
|
|
57
|
+
fromContainer: msg.container,
|
|
58
|
+
toContainer: msg.container,
|
|
59
|
+
startY: 0,
|
|
60
|
+
currentY: 0,
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
[],
|
|
64
|
+
];
|
|
65
|
+
case 'moveBy': {
|
|
66
|
+
if (!state.dragging)
|
|
67
|
+
return [state, []];
|
|
68
|
+
const next = Math.max(0, state.dragging.currentIndex + msg.delta);
|
|
69
|
+
if (next === state.dragging.currentIndex)
|
|
70
|
+
return [state, []];
|
|
71
|
+
return [{ dragging: { ...state.dragging, currentIndex: next } }, []];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export function connect(get, send, opts) {
|
|
76
|
+
// The connect's `id` doubles as the cross-container identifier
|
|
77
|
+
const containerId = opts.id;
|
|
78
|
+
const snapshots = new Map();
|
|
79
|
+
function snapshotContainer(rootEl, cid) {
|
|
80
|
+
const items = rootEl.querySelectorAll('[data-scope="sortable"][data-part="item"]');
|
|
81
|
+
// Read rects once — they're pre-transform (no drag shifts yet)
|
|
82
|
+
const mids = [];
|
|
83
|
+
const idToIndex = new Map();
|
|
84
|
+
items.forEach((item, i) => {
|
|
85
|
+
const r = item.getBoundingClientRect();
|
|
86
|
+
mids.push(r.top + r.height / 2);
|
|
87
|
+
const itemId = item.dataset.id;
|
|
88
|
+
if (itemId !== undefined)
|
|
89
|
+
idToIndex.set(itemId, i);
|
|
90
|
+
});
|
|
91
|
+
snapshots.set(cid, { mids, idToIndex });
|
|
92
|
+
}
|
|
93
|
+
function snapshotAll() {
|
|
94
|
+
const roots = document.querySelectorAll('[data-scope="sortable"][data-part="root"]');
|
|
95
|
+
for (const root of roots) {
|
|
96
|
+
const cid = root.dataset.containerId;
|
|
97
|
+
if (cid)
|
|
98
|
+
snapshotContainer(root, cid);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Find the target index under the pointer using the drag-start snapshot.
|
|
102
|
+
// Picks the index whose midpoint is closest to the pointer Y — stable
|
|
103
|
+
// against items being visually transformed during the drag.
|
|
104
|
+
function findTargetAt(e) {
|
|
105
|
+
// Find which sortable root the pointer is over (using getBoundingClientRect
|
|
106
|
+
// on roots, which are not transformed during drag).
|
|
107
|
+
const roots = document.querySelectorAll('[data-scope="sortable"][data-part="root"]');
|
|
108
|
+
for (const root of roots) {
|
|
109
|
+
const r = root.getBoundingClientRect();
|
|
110
|
+
if (e.clientX < r.left || e.clientX > r.right)
|
|
111
|
+
continue;
|
|
112
|
+
if (e.clientY < r.top || e.clientY > r.bottom)
|
|
113
|
+
continue;
|
|
114
|
+
const cid = root.dataset.containerId;
|
|
115
|
+
if (!cid)
|
|
116
|
+
continue;
|
|
117
|
+
const snap = snapshots.get(cid);
|
|
118
|
+
if (!snap || snap.mids.length === 0)
|
|
119
|
+
return { container: cid, index: 0 };
|
|
120
|
+
const mids = snap.mids;
|
|
121
|
+
// Find the index whose midpoint is closest to clientY
|
|
122
|
+
let bestIdx = 0;
|
|
123
|
+
let bestDist = Math.abs(e.clientY - mids[0]);
|
|
124
|
+
for (let i = 1; i < mids.length; i++) {
|
|
125
|
+
const d = Math.abs(e.clientY - mids[i]);
|
|
126
|
+
if (d < bestDist) {
|
|
127
|
+
bestDist = d;
|
|
128
|
+
bestIdx = i;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return { container: cid, index: bestIdx };
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
root: {
|
|
137
|
+
'data-scope': 'sortable',
|
|
138
|
+
'data-part': 'root',
|
|
139
|
+
'data-container-id': containerId,
|
|
140
|
+
'data-dragging': (s) => (get(s).dragging ? '' : undefined),
|
|
141
|
+
onPointerMove: (e) => {
|
|
142
|
+
if (!e.buttons)
|
|
143
|
+
return;
|
|
144
|
+
const hit = findTargetAt(e);
|
|
145
|
+
if (hit !== null)
|
|
146
|
+
send({ type: 'move', index: hit.index, container: hit.container, y: e.clientY });
|
|
147
|
+
},
|
|
148
|
+
onPointerUp: () => {
|
|
149
|
+
snapshots.clear();
|
|
150
|
+
send({ type: 'drop' });
|
|
151
|
+
},
|
|
152
|
+
onPointerCancel: () => {
|
|
153
|
+
snapshots.clear();
|
|
154
|
+
send({ type: 'cancel' });
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
item: (id, index) => ({
|
|
158
|
+
'data-scope': 'sortable',
|
|
159
|
+
'data-part': 'item',
|
|
160
|
+
'data-index': String(index),
|
|
161
|
+
'data-id': id,
|
|
162
|
+
'data-dragging': (s) => {
|
|
163
|
+
const d = get(s).dragging;
|
|
164
|
+
return d?.id === id && d?.fromContainer === containerId ? '' : undefined;
|
|
165
|
+
},
|
|
166
|
+
'data-over': (s) => {
|
|
167
|
+
const d = get(s).dragging;
|
|
168
|
+
if (!d || d.toContainer !== containerId)
|
|
169
|
+
return undefined;
|
|
170
|
+
// Look up this item's CURRENT DOM index via the drag-start snapshot.
|
|
171
|
+
// The `index` closed over here is frozen at initial render and goes
|
|
172
|
+
// stale after each() reconciles a reorder.
|
|
173
|
+
const snap = snapshots.get(containerId);
|
|
174
|
+
const liveIndex = snap?.idToIndex.get(id) ?? index;
|
|
175
|
+
return d.currentIndex === liveIndex ? '' : undefined;
|
|
176
|
+
},
|
|
177
|
+
// Shift direction for items BETWEEN the source and target (excluding the
|
|
178
|
+
// dragged item itself). 'down' = item should translate down to make room;
|
|
179
|
+
// 'up' = item should translate up. CSS controls the actual displacement.
|
|
180
|
+
'data-shift': (s) => {
|
|
181
|
+
const d = get(s).dragging;
|
|
182
|
+
if (!d || d.fromContainer !== containerId || d.toContainer !== containerId)
|
|
183
|
+
return undefined;
|
|
184
|
+
if (d.id === id)
|
|
185
|
+
return undefined;
|
|
186
|
+
if (d.startIndex === d.currentIndex)
|
|
187
|
+
return undefined;
|
|
188
|
+
// Look up this item's live DOM index — see note on data-over.
|
|
189
|
+
const snap = snapshots.get(containerId);
|
|
190
|
+
const liveIndex = snap?.idToIndex.get(id) ?? index;
|
|
191
|
+
if (d.startIndex < d.currentIndex) {
|
|
192
|
+
// Dragging down: items between start+1 and current shift up
|
|
193
|
+
if (liveIndex > d.startIndex && liveIndex <= d.currentIndex)
|
|
194
|
+
return 'up';
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
// Dragging up: items between current and start-1 shift down
|
|
198
|
+
if (liveIndex >= d.currentIndex && liveIndex < d.startIndex)
|
|
199
|
+
return 'down';
|
|
200
|
+
}
|
|
201
|
+
return undefined;
|
|
202
|
+
},
|
|
203
|
+
// The dragged item follows the pointer via translateY(deltaY). Other
|
|
204
|
+
// items have no transform override — data-shift CSS handles them.
|
|
205
|
+
'style.transform': (s) => {
|
|
206
|
+
const d = get(s).dragging;
|
|
207
|
+
if (!d || d.id !== id || d.fromContainer !== containerId)
|
|
208
|
+
return undefined;
|
|
209
|
+
const deltaY = d.currentY - d.startY;
|
|
210
|
+
return `translateY(${deltaY}px)`;
|
|
211
|
+
},
|
|
212
|
+
'style.zIndex': (s) => {
|
|
213
|
+
const d = get(s).dragging;
|
|
214
|
+
if (!d || d.id !== id || d.fromContainer !== containerId)
|
|
215
|
+
return undefined;
|
|
216
|
+
return '10';
|
|
217
|
+
},
|
|
218
|
+
}),
|
|
219
|
+
handle: (id, index) => ({
|
|
220
|
+
'data-scope': 'sortable',
|
|
221
|
+
'data-part': 'handle',
|
|
222
|
+
role: 'button',
|
|
223
|
+
tabIndex: 0,
|
|
224
|
+
'aria-grabbed': (s) => {
|
|
225
|
+
const d = get(s).dragging;
|
|
226
|
+
return d?.id === id && d?.fromContainer === containerId;
|
|
227
|
+
},
|
|
228
|
+
'aria-label': 'Drag handle. Press space to pick up, arrow keys to move, space again to drop, escape to cancel.',
|
|
229
|
+
onPointerDown: (e) => {
|
|
230
|
+
e.preventDefault();
|
|
231
|
+
const target = e.currentTarget;
|
|
232
|
+
if (target && 'setPointerCapture' in target) {
|
|
233
|
+
try {
|
|
234
|
+
;
|
|
235
|
+
target.setPointerCapture(e.pointerId);
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
// Ignore — not all elements support pointer capture
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// Compute the CURRENT DOM index of this handle's item — the captured
|
|
242
|
+
// `index` param is stale after a reorder (each() moves keyed nodes
|
|
243
|
+
// without re-running render, so the closure's index is frozen at
|
|
244
|
+
// initial mount). Walk up to find the containing item, then count its
|
|
245
|
+
// position among sibling items.
|
|
246
|
+
let currentIndex = index;
|
|
247
|
+
if (target) {
|
|
248
|
+
const itemEl = target.closest('[data-scope="sortable"][data-part="item"]');
|
|
249
|
+
const rootEl = target.closest('[data-scope="sortable"][data-part="root"]');
|
|
250
|
+
if (itemEl && rootEl) {
|
|
251
|
+
const items = rootEl.querySelectorAll('[data-scope="sortable"][data-part="item"]');
|
|
252
|
+
for (let i = 0; i < items.length; i++) {
|
|
253
|
+
if (items[i] === itemEl) {
|
|
254
|
+
currentIndex = i;
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
// Snapshot positions BEFORE the drag starts, so subsequent pointermove
|
|
261
|
+
// events can resolve the target index against stable (pre-transform)
|
|
262
|
+
// positions. Otherwise items shifting via CSS would cause the target
|
|
263
|
+
// to oscillate as elementFromPoint hits different items.
|
|
264
|
+
snapshotAll();
|
|
265
|
+
send({ type: 'start', id, index: currentIndex, container: containerId, y: e.clientY });
|
|
266
|
+
},
|
|
267
|
+
onKeyDown: (e) => {
|
|
268
|
+
switch (e.key) {
|
|
269
|
+
case ' ':
|
|
270
|
+
case 'Enter':
|
|
271
|
+
e.preventDefault();
|
|
272
|
+
send({ type: 'toggleGrab', id, index, container: containerId });
|
|
273
|
+
return;
|
|
274
|
+
case 'Escape':
|
|
275
|
+
e.preventDefault();
|
|
276
|
+
send({ type: 'cancel' });
|
|
277
|
+
return;
|
|
278
|
+
case 'ArrowDown':
|
|
279
|
+
case 'ArrowRight':
|
|
280
|
+
e.preventDefault();
|
|
281
|
+
send({ type: 'moveBy', delta: 1 });
|
|
282
|
+
return;
|
|
283
|
+
case 'ArrowUp':
|
|
284
|
+
case 'ArrowLeft':
|
|
285
|
+
e.preventDefault();
|
|
286
|
+
send({ type: 'moveBy', delta: -1 });
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
},
|
|
290
|
+
}),
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
// ── Reorder utility ────────────────────────────────────────────
|
|
294
|
+
/**
|
|
295
|
+
* Move an item in an array from one index to another, returning a new array.
|
|
296
|
+
* Out-of-range indices are clamped to array bounds.
|
|
297
|
+
*/
|
|
298
|
+
export function reorder(arr, from, to) {
|
|
299
|
+
const len = arr.length;
|
|
300
|
+
if (len === 0)
|
|
301
|
+
return [];
|
|
302
|
+
const f = Math.max(0, Math.min(len - 1, from));
|
|
303
|
+
const t = Math.max(0, Math.min(len - 1, to));
|
|
304
|
+
if (f === t)
|
|
305
|
+
return arr.slice();
|
|
306
|
+
const result = arr.slice();
|
|
307
|
+
const [item] = result.splice(f, 1);
|
|
308
|
+
result.splice(t, 0, item);
|
|
309
|
+
return result;
|
|
310
|
+
}
|
|
311
|
+
export const sortable = { init, update, connect, reorder };
|
|
@@ -50,7 +50,6 @@ export declare function init(opts?: TagsInputInit): TagsInputState;
|
|
|
50
50
|
export declare function update(state: TagsInputState, msg: TagsInputMsg): [TagsInputState, never[]];
|
|
51
51
|
export interface TagItemParts<S> {
|
|
52
52
|
root: {
|
|
53
|
-
role: 'button';
|
|
54
53
|
tabIndex: (s: S) => number;
|
|
55
54
|
'data-scope': 'tags-input';
|
|
56
55
|
'data-part': 'tag';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tags-input.d.ts","sourceRoot":"","sources":["../../src/components/tags-input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAMrC;;;;GAIG;AAEH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,OAAO,CAAA;IACjB,wCAAwC;IACxC,GAAG,EAAE,MAAM,CAAA;IACX,gCAAgC;IAChC,MAAM,EAAE,OAAO,CAAA;IACf,4CAA4C;IAC5C,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAA;AAExB,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,wBAAgB,IAAI,CAAC,IAAI,GAAE,aAAkB,GAAG,cAAc,CAS7D;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,YAAY,GAAG,CAAC,cAAc,EAAE,KAAK,EAAE,CAAC,CAwC1F;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,IAAI,EAAE;QACJ,
|
|
1
|
+
{"version":3,"file":"tags-input.d.ts","sourceRoot":"","sources":["../../src/components/tags-input.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { Send } from '@llui/dom';
|
|
2
|
+
/**
|
|
3
|
+
* Theme Switch — light/dark/system theme toggle.
|
|
4
|
+
*
|
|
5
|
+
* State machine tracks the user's explicit preference (`light`, `dark`, or
|
|
6
|
+
* `system`). Use `resolveTheme()` to compute the effective theme (reading
|
|
7
|
+
* `prefers-color-scheme` when `system`), and `applyTheme()` to set
|
|
8
|
+
* `data-theme` on `<html>` so CSS selectors like `[data-theme='dark']` work.
|
|
9
|
+
*
|
|
10
|
+
* Typically wired via `onMount` or in app init:
|
|
11
|
+
* ```ts
|
|
12
|
+
* onMount(() => {
|
|
13
|
+
* applyTheme(resolveTheme(state.theme.theme))
|
|
14
|
+
* })
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* For persistence, the app reducer reads/writes `localStorage.theme` in its
|
|
18
|
+
* `init`/`update` — the state machine itself is storage-agnostic.
|
|
19
|
+
*/
|
|
20
|
+
export type Theme = 'light' | 'dark' | 'system';
|
|
21
|
+
export type ResolvedTheme = 'light' | 'dark';
|
|
22
|
+
export interface ThemeSwitchState {
|
|
23
|
+
theme: Theme;
|
|
24
|
+
}
|
|
25
|
+
export type ThemeSwitchMsg = {
|
|
26
|
+
type: 'setTheme';
|
|
27
|
+
theme: Theme;
|
|
28
|
+
} | {
|
|
29
|
+
type: 'toggle';
|
|
30
|
+
};
|
|
31
|
+
export declare function init(theme?: Theme): ThemeSwitchState;
|
|
32
|
+
export declare function update(state: ThemeSwitchState, msg: ThemeSwitchMsg): [ThemeSwitchState, never[]];
|
|
33
|
+
/**
|
|
34
|
+
* Resolve a theme preference to the actual theme to apply. Returns 'dark' or
|
|
35
|
+
* 'light' based on the user's setting, consulting `prefers-color-scheme` for
|
|
36
|
+
* 'system'.
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveTheme(theme: Theme): ResolvedTheme;
|
|
39
|
+
/**
|
|
40
|
+
* Set `data-theme="light"` or `data-theme="dark"` on `<html>`. CSS selectors
|
|
41
|
+
* like `[data-theme='dark'] { ... }` will then take effect.
|
|
42
|
+
*/
|
|
43
|
+
export declare function applyTheme(resolved: ResolvedTheme): void;
|
|
44
|
+
/**
|
|
45
|
+
* Listen for system theme changes (when user has selected 'system'). Returns
|
|
46
|
+
* a cleanup function. Call this in `onMount` and dispatch `setTheme` on
|
|
47
|
+
* change if you want the UI to auto-follow OS settings.
|
|
48
|
+
*/
|
|
49
|
+
export declare function watchSystemTheme(callback: (theme: ResolvedTheme) => void): () => void;
|
|
50
|
+
export interface ThemeSwitchParts<S> {
|
|
51
|
+
root: {
|
|
52
|
+
'data-scope': 'theme-switch';
|
|
53
|
+
'data-part': 'root';
|
|
54
|
+
role: 'group';
|
|
55
|
+
'aria-label': string;
|
|
56
|
+
};
|
|
57
|
+
option: (theme: Theme) => {
|
|
58
|
+
type: 'button';
|
|
59
|
+
'data-scope': 'theme-switch';
|
|
60
|
+
'data-part': 'option';
|
|
61
|
+
'data-theme': Theme;
|
|
62
|
+
'aria-pressed': (s: S) => boolean;
|
|
63
|
+
'aria-label': string;
|
|
64
|
+
onClick: (e: MouseEvent) => void;
|
|
65
|
+
};
|
|
66
|
+
toggle: {
|
|
67
|
+
type: 'button';
|
|
68
|
+
'data-scope': 'theme-switch';
|
|
69
|
+
'data-part': 'toggle';
|
|
70
|
+
'data-theme': (s: S) => Theme;
|
|
71
|
+
'aria-label': string;
|
|
72
|
+
onClick: (e: MouseEvent) => void;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export interface ConnectOptions {
|
|
76
|
+
id: string;
|
|
77
|
+
/** Accessible label for the theme group (default: 'Theme'). */
|
|
78
|
+
label?: string;
|
|
79
|
+
}
|
|
80
|
+
export declare function connect<S>(get: (s: S) => ThemeSwitchState, send: Send<ThemeSwitchMsg>, opts: ConnectOptions): ThemeSwitchParts<S>;
|
|
81
|
+
export declare const themeSwitch: {
|
|
82
|
+
init: typeof init;
|
|
83
|
+
update: typeof update;
|
|
84
|
+
connect: typeof connect;
|
|
85
|
+
resolveTheme: typeof resolveTheme;
|
|
86
|
+
applyTheme: typeof applyTheme;
|
|
87
|
+
watchSystemTheme: typeof watchSystemTheme;
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=theme-switch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-switch.d.ts","sourceRoot":"","sources":["../../src/components/theme-switch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAErC;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,MAAM,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAA;AAC/C,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,MAAM,CAAA;AAE5C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,KAAK,CAAA;CACb;AAED,MAAM,MAAM,cAAc,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAA;AAEpF,wBAAgB,IAAI,CAAC,KAAK,GAAE,KAAgB,GAAG,gBAAgB,CAE9D;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,cAAc,GAAG,CAAC,gBAAgB,EAAE,KAAK,EAAE,CAAC,CAYhG;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,aAAa,CAOxD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAGxD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,MAAM,IAAI,CAQrF;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,IAAI,EAAE;QACJ,YAAY,EAAE,cAAc,CAAA;QAC5B,WAAW,EAAE,MAAM,CAAA;QACnB,IAAI,EAAE,OAAO,CAAA;QACb,YAAY,EAAE,MAAM,CAAA;KACrB,CAAA;IACD,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK;QACxB,IAAI,EAAE,QAAQ,CAAA;QACd,YAAY,EAAE,cAAc,CAAA;QAC5B,WAAW,EAAE,QAAQ,CAAA;QACrB,YAAY,EAAE,KAAK,CAAA;QACnB,cAAc,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,CAAA;QACjC,YAAY,EAAE,MAAM,CAAA;QACpB,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAA;KACjC,CAAA;IACD,MAAM,EAAE;QACN,IAAI,EAAE,QAAQ,CAAA;QACd,YAAY,EAAE,cAAc,CAAA;QAC5B,WAAW,EAAE,QAAQ,CAAA;QACrB,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,KAAK,CAAA;QAC7B,YAAY,EAAE,MAAM,CAAA;QACpB,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAA;KACjC,CAAA;CACF;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAQD,wBAAgB,OAAO,CAAC,CAAC,EACvB,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,gBAAgB,EAC/B,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,EAC1B,IAAI,EAAE,cAAc,GACnB,gBAAgB,CAAC,CAAC,CAAC,CA2BrB;AAED,eAAO,MAAM,WAAW;;;;;;;CAOvB,CAAA"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
export function init(theme = 'system') {
|
|
2
|
+
return { theme };
|
|
3
|
+
}
|
|
4
|
+
export function update(state, msg) {
|
|
5
|
+
switch (msg.type) {
|
|
6
|
+
case 'setTheme':
|
|
7
|
+
if (state.theme === msg.theme)
|
|
8
|
+
return [state, []];
|
|
9
|
+
return [{ theme: msg.theme }, []];
|
|
10
|
+
case 'toggle': {
|
|
11
|
+
// light → dark → system → light
|
|
12
|
+
const next = state.theme === 'light' ? 'dark' : state.theme === 'dark' ? 'system' : 'light';
|
|
13
|
+
return [{ theme: next }, []];
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Resolve a theme preference to the actual theme to apply. Returns 'dark' or
|
|
19
|
+
* 'light' based on the user's setting, consulting `prefers-color-scheme` for
|
|
20
|
+
* 'system'.
|
|
21
|
+
*/
|
|
22
|
+
export function resolveTheme(theme) {
|
|
23
|
+
if (theme === 'dark')
|
|
24
|
+
return 'dark';
|
|
25
|
+
if (theme === 'light')
|
|
26
|
+
return 'light';
|
|
27
|
+
if (typeof window !== 'undefined' && window.matchMedia) {
|
|
28
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
29
|
+
}
|
|
30
|
+
return 'light';
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Set `data-theme="light"` or `data-theme="dark"` on `<html>`. CSS selectors
|
|
34
|
+
* like `[data-theme='dark'] { ... }` will then take effect.
|
|
35
|
+
*/
|
|
36
|
+
export function applyTheme(resolved) {
|
|
37
|
+
if (typeof document === 'undefined')
|
|
38
|
+
return;
|
|
39
|
+
document.documentElement.dataset.theme = resolved;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Listen for system theme changes (when user has selected 'system'). Returns
|
|
43
|
+
* a cleanup function. Call this in `onMount` and dispatch `setTheme` on
|
|
44
|
+
* change if you want the UI to auto-follow OS settings.
|
|
45
|
+
*/
|
|
46
|
+
export function watchSystemTheme(callback) {
|
|
47
|
+
if (typeof window === 'undefined' || !window.matchMedia)
|
|
48
|
+
return () => { };
|
|
49
|
+
const mq = window.matchMedia('(prefers-color-scheme: dark)');
|
|
50
|
+
const handler = (e) => {
|
|
51
|
+
callback(e.matches ? 'dark' : 'light');
|
|
52
|
+
};
|
|
53
|
+
mq.addEventListener('change', handler);
|
|
54
|
+
return () => mq.removeEventListener('change', handler);
|
|
55
|
+
}
|
|
56
|
+
const LABELS = {
|
|
57
|
+
light: 'Light theme',
|
|
58
|
+
dark: 'Dark theme',
|
|
59
|
+
system: 'Use system theme',
|
|
60
|
+
};
|
|
61
|
+
export function connect(get, send, opts) {
|
|
62
|
+
const label = opts.label ?? 'Theme';
|
|
63
|
+
return {
|
|
64
|
+
root: {
|
|
65
|
+
'data-scope': 'theme-switch',
|
|
66
|
+
'data-part': 'root',
|
|
67
|
+
role: 'group',
|
|
68
|
+
'aria-label': label,
|
|
69
|
+
},
|
|
70
|
+
option: (theme) => ({
|
|
71
|
+
type: 'button',
|
|
72
|
+
'data-scope': 'theme-switch',
|
|
73
|
+
'data-part': 'option',
|
|
74
|
+
'data-theme': theme,
|
|
75
|
+
'aria-pressed': (s) => get(s).theme === theme,
|
|
76
|
+
'aria-label': LABELS[theme],
|
|
77
|
+
onClick: () => send({ type: 'setTheme', theme }),
|
|
78
|
+
}),
|
|
79
|
+
toggle: {
|
|
80
|
+
type: 'button',
|
|
81
|
+
'data-scope': 'theme-switch',
|
|
82
|
+
'data-part': 'toggle',
|
|
83
|
+
'data-theme': (s) => get(s).theme,
|
|
84
|
+
'aria-label': 'Toggle theme',
|
|
85
|
+
onClick: () => send({ type: 'toggle' }),
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
export const themeSwitch = {
|
|
90
|
+
init,
|
|
91
|
+
update,
|
|
92
|
+
connect,
|
|
93
|
+
resolveTheme,
|
|
94
|
+
applyTheme,
|
|
95
|
+
watchSystemTheme,
|
|
96
|
+
};
|
|
@@ -62,7 +62,6 @@ export interface ToggleGroupItemParts<S> {
|
|
|
62
62
|
export interface ToggleGroupParts<S> {
|
|
63
63
|
root: {
|
|
64
64
|
role: 'group';
|
|
65
|
-
'aria-orientation': (s: S) => Orientation;
|
|
66
65
|
'aria-disabled': (s: S) => 'true' | undefined;
|
|
67
66
|
'data-scope': 'toggle-group';
|
|
68
67
|
'data-part': 'root';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggle-group.d.ts","sourceRoot":"","sources":["../../src/components/toggle-group.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAGrC;;;;GAIG;AAEH,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,UAAU,CAAA;AAEnD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAA;IAC3B,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,QAAQ,EAAE,OAAO,CAAA;IACjB,WAAW,EAAE,WAAW,CAAA;IACxB,iEAAiE;IACjE,YAAY,EAAE,OAAO,CAAA;CACtB;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvC,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAA;IAC5B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,wBAAgB,IAAI,CAAC,IAAI,GAAE,eAAoB,GAAG,gBAAgB,CAUjE;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,cAAc,GAAG,CAAC,gBAAgB,EAAE,KAAK,EAAE,CAAC,CA8BhG;AAED,MAAM,WAAW,oBAAoB,CAAC,CAAC;IACrC,IAAI,EAAE;QACJ,IAAI,EAAE,QAAQ,CAAA;QACd,IAAI,EAAE,QAAQ,CAAA;QACd,cAAc,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,CAAA;QACjC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,GAAG,SAAS,CAAA;QAC7C,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,CAAA;QAC3B,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,GAAG,KAAK,CAAA;QACpC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,SAAS,CAAA;QACzC,YAAY,EAAE,cAAc,CAAA;QAC5B,WAAW,EAAE,MAAM,CAAA;QACnB,YAAY,EAAE,MAAM,CAAA;QACpB,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAA;QAChC,SAAS,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,CAAA;KACtC,CAAA;CACF;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,IAAI,EAAE;QACJ,IAAI,EAAE,OAAO,CAAA;QACb,
|
|
1
|
+
{"version":3,"file":"toggle-group.d.ts","sourceRoot":"","sources":["../../src/components/toggle-group.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ const rootVariants = createVariants({
|
|
|
11
11
|
defaultVariants: { size: 'md' },
|
|
12
12
|
});
|
|
13
13
|
const itemVariants = createVariants({
|
|
14
|
-
base: 'flex items-center cursor-pointer transition-colors duration-fast data-[highlighted]:bg-surface-hover data-[state=
|
|
14
|
+
base: 'flex items-center cursor-pointer transition-colors duration-fast data-[highlighted]:bg-surface-hover data-[state=selected]:bg-surface-active data-[state=selected]:text-primary data-[disabled]:opacity-50 data-[disabled]:cursor-not-allowed',
|
|
15
15
|
variants: {
|
|
16
16
|
size: {
|
|
17
17
|
sm: 'px-2 py-1 text-sm',
|
|
@@ -22,7 +22,7 @@ const contentVariants = createVariants({
|
|
|
22
22
|
defaultVariants: { size: 'md' },
|
|
23
23
|
});
|
|
24
24
|
const itemVariants = createVariants({
|
|
25
|
-
base: 'flex items-center cursor-pointer transition-colors duration-fast data-[highlighted]:bg-surface-hover data-[state=
|
|
25
|
+
base: 'flex items-center cursor-pointer transition-colors duration-fast data-[highlighted]:bg-surface-hover data-[state=selected]:bg-surface-active data-[state=selected]:text-primary data-[disabled]:opacity-50 data-[disabled]:cursor-not-allowed',
|
|
26
26
|
variants: {
|
|
27
27
|
size: {
|
|
28
28
|
sm: 'px-2 py-1 text-sm',
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
@media (prefers-color-scheme: dark) {
|
|
15
15
|
:root:not([data-theme='light']) {
|
|
16
|
+
color-scheme: dark;
|
|
16
17
|
--color-surface: #0f172a;
|
|
17
18
|
--color-surface-muted: #1e293b;
|
|
18
19
|
--color-surface-hover: #1e293b;
|
|
@@ -35,6 +36,7 @@
|
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
[data-theme='dark'] {
|
|
39
|
+
color-scheme: dark;
|
|
38
40
|
--color-surface: #0f172a;
|
|
39
41
|
--color-surface-muted: #1e293b;
|
|
40
42
|
--color-surface-hover: #1e293b;
|
package/dist/styles/theme.css
CHANGED
|
@@ -649,7 +649,7 @@
|
|
|
649
649
|
justify-content: center;
|
|
650
650
|
font-size: 1rem;
|
|
651
651
|
font-weight: 600;
|
|
652
|
-
color: var(--color-text
|
|
652
|
+
color: var(--color-text);
|
|
653
653
|
}
|
|
654
654
|
|
|
655
655
|
/* ─── Pagination ─── */
|
|
@@ -1315,7 +1315,7 @@
|
|
|
1315
1315
|
padding: var(--space-1) var(--space-2);
|
|
1316
1316
|
border: 0;
|
|
1317
1317
|
background: var(--color-surface-hover);
|
|
1318
|
-
color: var(--color-text
|
|
1318
|
+
color: var(--color-text);
|
|
1319
1319
|
font-size: 0.75rem;
|
|
1320
1320
|
font-weight: 600;
|
|
1321
1321
|
cursor: pointer;
|
|
@@ -1532,7 +1532,7 @@
|
|
|
1532
1532
|
background: var(--color-surface-hover);
|
|
1533
1533
|
}
|
|
1534
1534
|
|
|
1535
|
-
[data-scope='listbox'][data-part='item'][data-state='
|
|
1535
|
+
[data-scope='listbox'][data-part='item'][data-state='selected'] {
|
|
1536
1536
|
background: color-mix(in srgb, var(--color-primary) 15%, transparent);
|
|
1537
1537
|
color: var(--color-primary-active);
|
|
1538
1538
|
}
|