sheer-ui 0.4.2 → 0.4.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/lib/components/avatar/avatar.svelte.ts +34 -37
- package/src/lib/components/avatar/components/avatar-fallback.svelte +9 -6
- package/src/lib/components/avatar/components/avatar-image.svelte +18 -9
- package/src/lib/components/avatar/components/avatar.svelte +20 -16
- package/src/lib/components/checkbox/checkbox.svelte.ts +45 -55
- package/src/lib/components/checkbox/components/checkbox-group-label.svelte +9 -6
- package/src/lib/components/checkbox/components/checkbox-group.svelte +25 -16
- package/src/lib/components/checkbox/components/checkbox.svelte +39 -25
- package/src/lib/components/dialog/components/dialog-close.svelte +13 -8
- package/src/lib/components/dialog/components/dialog-content-headless.svelte +14 -11
- package/src/lib/components/dialog/components/dialog-description.svelte +9 -6
- package/src/lib/components/dialog/components/dialog-overlay.svelte +10 -7
- package/src/lib/components/dialog/components/dialog-title.svelte +12 -7
- package/src/lib/components/dialog/components/dialog-trigger.svelte +12 -7
- package/src/lib/components/dialog/components/dialog.svelte +10 -4
- package/src/lib/components/dialog/components/modal-surface.svelte +11 -8
- package/src/lib/components/dialog/dialog.svelte.ts +73 -61
- package/src/lib/components/drawer/drawer.svelte +8 -3
- package/src/lib/components/link-preview/components/link-preview-content.svelte +15 -8
- package/src/lib/components/link-preview/components/link-preview-trigger.svelte +9 -6
- package/src/lib/components/link-preview/components/link-preview.svelte +19 -11
- package/src/lib/components/link-preview/link-preview.svelte.ts +42 -43
- package/src/lib/components/menu/menu.svelte.ts +20 -1
- package/src/lib/components/meter/components/meter.svelte +18 -9
- package/src/lib/components/meter/meter.svelte.ts +15 -18
- package/src/lib/components/popover/components/popover-close.svelte +9 -6
- package/src/lib/components/popover/components/popover-content.svelte +12 -7
- package/src/lib/components/popover/components/popover-trigger.svelte +21 -10
- package/src/lib/components/popover/components/popover.svelte +9 -8
- package/src/lib/components/popover/popover.svelte.ts +68 -74
- package/src/lib/components/progress/components/progress.svelte +18 -9
- package/src/lib/components/progress/progress.svelte.ts +14 -17
- package/src/lib/components/separator/components/separator.svelte +15 -8
- package/src/lib/components/separator/separator.svelte.ts +12 -15
- package/src/lib/components/sidebar/sidebar-mobile-surface.svelte +8 -4
- package/src/lib/components/toggle/components/toggle.svelte +19 -14
- package/src/lib/components/toggle/toggle.svelte.ts +15 -20
- package/src/lib/components/tooltip/components/tooltip-content.svelte +15 -8
- package/src/lib/components/tooltip/components/tooltip-provider.svelte +18 -7
- package/src/lib/components/tooltip/components/tooltip-trigger.svelte +21 -10
- package/src/lib/components/tooltip/components/tooltip.svelte +34 -21
- package/src/lib/components/tooltip/tooltip.svelte.ts +96 -99
- package/src/lib/internal/escape-layer/use-escape-layer.svelte.ts +13 -29
- package/src/lib/internal/group-value.svelte.ts +11 -10
- package/src/lib/internal/native-popover.svelte.ts +6 -6
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import { createContext, untrack } from 'svelte';
|
|
2
|
-
import {
|
|
3
|
-
type ReadableBox,
|
|
4
|
-
type ReadableBoxedValues,
|
|
5
|
-
type WritableBoxedValues,
|
|
6
|
-
attachRef,
|
|
7
|
-
boxWith,
|
|
8
|
-
} from '../../internal/tools/index.js';
|
|
2
|
+
import { attachRef } from '../../internal/tools/index.js';
|
|
9
3
|
import { kbd } from '../../internal/kbd.js';
|
|
10
4
|
import { createBitsAttrs, boolToStr, getDataOpenClosed } from '../../internal/attrs.js';
|
|
11
5
|
import type {
|
|
@@ -15,7 +9,7 @@ import type {
|
|
|
15
9
|
BitsPointerEvent,
|
|
16
10
|
OnChangeFn,
|
|
17
11
|
RefAttachment,
|
|
18
|
-
|
|
12
|
+
RefOpts,
|
|
19
13
|
} from '../../internal/types.js';
|
|
20
14
|
import { isElement } from '../../internal/tools/utils/dom.js';
|
|
21
15
|
import type { Measurable } from '../../internal/floating-layer/index.js';
|
|
@@ -30,14 +24,10 @@ const popoverAttrs = createBitsAttrs({
|
|
|
30
24
|
|
|
31
25
|
const [getPopoverRoot, setPopoverRoot] = createContext<PopoverRootState>();
|
|
32
26
|
|
|
33
|
-
interface PopoverRootStateOpts
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}>,
|
|
38
|
-
ReadableBoxedValues<{
|
|
39
|
-
onOpenChangeComplete: OnChangeFn<boolean>;
|
|
40
|
-
}> {}
|
|
27
|
+
interface PopoverRootStateOpts {
|
|
28
|
+
open: boolean;
|
|
29
|
+
readonly onOpenChangeComplete: OnChangeFn<boolean>;
|
|
30
|
+
}
|
|
41
31
|
|
|
42
32
|
export class PopoverRootState {
|
|
43
33
|
static create(opts: PopoverRootStateOpts) {
|
|
@@ -52,11 +42,11 @@ export class PopoverRootState {
|
|
|
52
42
|
openedViaHover = $state(false);
|
|
53
43
|
hasInteractedWithContent = $state(false);
|
|
54
44
|
hoverCooldown = $state(false);
|
|
55
|
-
|
|
56
|
-
|
|
45
|
+
// The trigger installs its closeDelay here; a getter so the read tracks the trigger's prop.
|
|
46
|
+
#closeDelaySource: () => number = $state.raw(() => 0);
|
|
57
47
|
#closeTimer = createEffectTimeout(() => {
|
|
58
48
|
if (this.openedViaHover && !this.hasInteractedWithContent) {
|
|
59
|
-
this.opts.open
|
|
49
|
+
this.opts.open = false;
|
|
60
50
|
}
|
|
61
51
|
}, () => this.closeDelay);
|
|
62
52
|
|
|
@@ -64,7 +54,7 @@ export class PopoverRootState {
|
|
|
64
54
|
this.opts = opts;
|
|
65
55
|
|
|
66
56
|
$effect(() => {
|
|
67
|
-
const isOpen = this.opts.open
|
|
57
|
+
const isOpen = this.opts.open;
|
|
68
58
|
untrack(() => {
|
|
69
59
|
if (!isOpen) {
|
|
70
60
|
this.openedViaHover = false;
|
|
@@ -75,43 +65,47 @@ export class PopoverRootState {
|
|
|
75
65
|
});
|
|
76
66
|
}
|
|
77
67
|
|
|
78
|
-
|
|
68
|
+
get closeDelay() {
|
|
69
|
+
return this.#closeDelaySource();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
setCloseDelaySource(source: () => number) {
|
|
79
73
|
this.#closeDelaySource = source;
|
|
80
74
|
}
|
|
81
75
|
|
|
82
76
|
toggleOpen() {
|
|
83
77
|
this.#closeTimer.stop();
|
|
84
|
-
this.opts.open
|
|
78
|
+
this.opts.open = !this.opts.open;
|
|
85
79
|
}
|
|
86
80
|
|
|
87
81
|
handleClose() {
|
|
88
82
|
this.#closeTimer.stop();
|
|
89
|
-
if (!this.opts.open
|
|
90
|
-
this.opts.open
|
|
83
|
+
if (!this.opts.open) return;
|
|
84
|
+
this.opts.open = false;
|
|
91
85
|
}
|
|
92
86
|
|
|
93
87
|
handleHoverOpen() {
|
|
94
88
|
this.#closeTimer.stop();
|
|
95
|
-
if (this.opts.open
|
|
89
|
+
if (this.opts.open) return;
|
|
96
90
|
this.openedViaHover = true;
|
|
97
|
-
this.opts.open
|
|
91
|
+
this.opts.open = true;
|
|
98
92
|
}
|
|
99
93
|
|
|
100
94
|
handleHoverClose() {
|
|
101
|
-
if (!this.opts.open
|
|
95
|
+
if (!this.opts.open) return;
|
|
102
96
|
// only close if opened via hover and user hasn't interacted with content
|
|
103
97
|
if (this.openedViaHover && !this.hasInteractedWithContent) {
|
|
104
|
-
this.opts.open
|
|
98
|
+
this.opts.open = false;
|
|
105
99
|
}
|
|
106
100
|
}
|
|
107
101
|
|
|
108
102
|
handleDelayedHoverClose() {
|
|
109
|
-
if (!this.opts.open
|
|
103
|
+
if (!this.opts.open) return;
|
|
110
104
|
if (!this.openedViaHover || this.hasInteractedWithContent) return;
|
|
111
105
|
|
|
112
106
|
if (this.closeDelay <= 0) {
|
|
113
107
|
this.#closeTimer.stop();
|
|
114
|
-
this.opts.open
|
|
108
|
+
this.opts.open = false;
|
|
115
109
|
return;
|
|
116
110
|
}
|
|
117
111
|
|
|
@@ -128,15 +122,12 @@ export class PopoverRootState {
|
|
|
128
122
|
}
|
|
129
123
|
}
|
|
130
124
|
|
|
131
|
-
interface PopoverTriggerStateOpts
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
openDelay: number;
|
|
138
|
-
closeDelay: number;
|
|
139
|
-
}> {}
|
|
125
|
+
interface PopoverTriggerStateOpts extends RefOpts {
|
|
126
|
+
readonly disabled: boolean;
|
|
127
|
+
readonly openOnHover: boolean;
|
|
128
|
+
readonly openDelay: number;
|
|
129
|
+
readonly closeDelay: number;
|
|
130
|
+
}
|
|
140
131
|
|
|
141
132
|
export class PopoverTriggerState {
|
|
142
133
|
static create(opts: PopoverTriggerStateOpts) {
|
|
@@ -147,14 +138,17 @@ export class PopoverTriggerState {
|
|
|
147
138
|
readonly root: PopoverRootState;
|
|
148
139
|
readonly attachment: RefAttachment;
|
|
149
140
|
|
|
150
|
-
#openTimer = createEffectTimeout(() => this.root.handleHoverOpen(), () => this.opts.openDelay
|
|
141
|
+
#openTimer = createEffectTimeout(() => this.root.handleHoverOpen(), () => this.opts.openDelay);
|
|
151
142
|
#isHovering = $state(false);
|
|
152
143
|
#wasOpenOnPointerDown = false;
|
|
153
144
|
|
|
154
145
|
constructor(opts: PopoverTriggerStateOpts, root: PopoverRootState) {
|
|
155
146
|
this.opts = opts;
|
|
156
147
|
this.root = root;
|
|
157
|
-
this.attachment = attachRef(
|
|
148
|
+
this.attachment = attachRef<HTMLElement>(
|
|
149
|
+
(v) => (opts.ref = v),
|
|
150
|
+
(v) => (this.root.triggerNode = v),
|
|
151
|
+
);
|
|
158
152
|
|
|
159
153
|
this.onclick = this.onclick.bind(this);
|
|
160
154
|
this.onkeydown = this.onkeydown.bind(this);
|
|
@@ -162,20 +156,20 @@ export class PopoverTriggerState {
|
|
|
162
156
|
this.onpointerenter = this.onpointerenter.bind(this);
|
|
163
157
|
this.onpointerleave = this.onpointerleave.bind(this);
|
|
164
158
|
|
|
165
|
-
this.root.setCloseDelaySource(
|
|
159
|
+
this.root.setCloseDelaySource(() => opts.closeDelay);
|
|
166
160
|
}
|
|
167
161
|
|
|
168
162
|
onpointerenter(e: BitsPointerEvent) {
|
|
169
|
-
if (this.opts.disabled
|
|
170
|
-
if (!this.opts.openOnHover
|
|
163
|
+
if (this.opts.disabled) return;
|
|
164
|
+
if (!this.opts.openOnHover) return;
|
|
171
165
|
if (e.pointerType === 'touch') return;
|
|
172
166
|
|
|
173
167
|
this.#isHovering = true;
|
|
174
168
|
this.root.cancelDelayedClose();
|
|
175
169
|
|
|
176
|
-
if (this.root.opts.open
|
|
170
|
+
if (this.root.opts.open || this.root.hoverCooldown) return;
|
|
177
171
|
|
|
178
|
-
if (this.opts.openDelay
|
|
172
|
+
if (this.opts.openDelay <= 0) {
|
|
179
173
|
this.root.handleHoverOpen();
|
|
180
174
|
return;
|
|
181
175
|
}
|
|
@@ -184,8 +178,8 @@ export class PopoverTriggerState {
|
|
|
184
178
|
}
|
|
185
179
|
|
|
186
180
|
onpointerleave(e: BitsPointerEvent) {
|
|
187
|
-
if (this.opts.disabled
|
|
188
|
-
if (!this.opts.openOnHover
|
|
181
|
+
if (this.opts.disabled) return;
|
|
182
|
+
if (!this.opts.openOnHover) return;
|
|
189
183
|
if (e.pointerType === 'touch') return;
|
|
190
184
|
|
|
191
185
|
this.#isHovering = false;
|
|
@@ -197,24 +191,24 @@ export class PopoverTriggerState {
|
|
|
197
191
|
}
|
|
198
192
|
|
|
199
193
|
onpointerdown(_: BitsPointerEvent) {
|
|
200
|
-
this.#wasOpenOnPointerDown = this.root.opts.open
|
|
194
|
+
this.#wasOpenOnPointerDown = this.root.opts.open;
|
|
201
195
|
}
|
|
202
196
|
|
|
203
197
|
onclick(e: BitsMouseEvent) {
|
|
204
|
-
if (this.opts.disabled
|
|
198
|
+
if (this.opts.disabled) return;
|
|
205
199
|
if (e.button !== 0) return;
|
|
206
200
|
|
|
207
201
|
this.#openTimer.stop();
|
|
208
202
|
|
|
209
203
|
// On engines without showPopover({source})'s invoker exemption, the UA light-dismisses the auto
|
|
210
204
|
// popover at pointerdown — before this click — and the toggle below would instantly reopen it.
|
|
211
|
-
if (this.#wasOpenOnPointerDown && !this.root.opts.open
|
|
205
|
+
if (this.#wasOpenOnPointerDown && !this.root.opts.open) {
|
|
212
206
|
this.#wasOpenOnPointerDown = false;
|
|
213
207
|
return;
|
|
214
208
|
}
|
|
215
209
|
|
|
216
210
|
// if clicked while hovering and popover is open, convert to click-based open
|
|
217
|
-
if (this.#isHovering && this.root.opts.open
|
|
211
|
+
if (this.#isHovering && this.root.opts.open && this.root.openedViaHover) {
|
|
218
212
|
this.root.openedViaHover = false;
|
|
219
213
|
this.root.hasInteractedWithContent = true;
|
|
220
214
|
return;
|
|
@@ -222,12 +216,12 @@ export class PopoverTriggerState {
|
|
|
222
216
|
|
|
223
217
|
// if closing while hovering with openOnHover enabled, set cooldown to prevent
|
|
224
218
|
// immediate re-open via hover
|
|
225
|
-
if (this.#isHovering && this.opts.openOnHover
|
|
219
|
+
if (this.#isHovering && this.opts.openOnHover && this.root.opts.open) {
|
|
226
220
|
this.root.hoverCooldown = true;
|
|
227
221
|
}
|
|
228
222
|
|
|
229
223
|
// if clicking to open while in cooldown, reset cooldown (explicit open)
|
|
230
|
-
if (this.root.hoverCooldown && !this.root.opts.open
|
|
224
|
+
if (this.root.hoverCooldown && !this.root.opts.open) {
|
|
231
225
|
this.root.hoverCooldown = false;
|
|
232
226
|
}
|
|
233
227
|
|
|
@@ -235,7 +229,7 @@ export class PopoverTriggerState {
|
|
|
235
229
|
}
|
|
236
230
|
|
|
237
231
|
onkeydown(e: BitsKeyboardEvent) {
|
|
238
|
-
if (this.opts.disabled
|
|
232
|
+
if (this.opts.disabled) return;
|
|
239
233
|
if (!(e.key === kbd.ENTER || e.key === kbd.SPACE)) return;
|
|
240
234
|
e.preventDefault();
|
|
241
235
|
this.#openTimer.stop();
|
|
@@ -243,7 +237,7 @@ export class PopoverTriggerState {
|
|
|
243
237
|
}
|
|
244
238
|
|
|
245
239
|
#getAriaControls(): string | undefined {
|
|
246
|
-
if (this.root.opts.open
|
|
240
|
+
if (this.root.opts.open && this.root.contentNode?.id) {
|
|
247
241
|
return this.root.contentNode?.id;
|
|
248
242
|
}
|
|
249
243
|
}
|
|
@@ -251,13 +245,13 @@ export class PopoverTriggerState {
|
|
|
251
245
|
readonly props = $derived.by(
|
|
252
246
|
() =>
|
|
253
247
|
({
|
|
254
|
-
id: this.opts.id
|
|
248
|
+
id: this.opts.id,
|
|
255
249
|
'aria-haspopup': 'dialog',
|
|
256
|
-
'aria-expanded': boolToStr(this.root.opts.open
|
|
257
|
-
'data-state': getDataOpenClosed(this.root.opts.open
|
|
250
|
+
'aria-expanded': boolToStr(this.root.opts.open),
|
|
251
|
+
'data-state': getDataOpenClosed(this.root.opts.open),
|
|
258
252
|
'aria-controls': this.#getAriaControls(),
|
|
259
253
|
[popoverAttrs.trigger]: '',
|
|
260
|
-
disabled: this.opts.disabled
|
|
254
|
+
disabled: this.opts.disabled,
|
|
261
255
|
//
|
|
262
256
|
onkeydown: this.onkeydown,
|
|
263
257
|
onclick: this.onclick,
|
|
@@ -269,12 +263,9 @@ export class PopoverTriggerState {
|
|
|
269
263
|
);
|
|
270
264
|
}
|
|
271
265
|
|
|
272
|
-
interface PopoverContentStateOpts
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
ReadableBoxedValues<{
|
|
276
|
-
customAnchor: string | HTMLElement | null | Measurable;
|
|
277
|
-
}> {}
|
|
266
|
+
interface PopoverContentStateOpts extends RefOpts {
|
|
267
|
+
readonly customAnchor: string | HTMLElement | null | Measurable;
|
|
268
|
+
}
|
|
278
269
|
|
|
279
270
|
export class PopoverContentState {
|
|
280
271
|
static create(opts: PopoverContentStateOpts) {
|
|
@@ -288,7 +279,10 @@ export class PopoverContentState {
|
|
|
288
279
|
constructor(opts: PopoverContentStateOpts, root: PopoverRootState) {
|
|
289
280
|
this.opts = opts;
|
|
290
281
|
this.root = root;
|
|
291
|
-
this.attachment = attachRef(
|
|
282
|
+
this.attachment = attachRef<HTMLElement>(
|
|
283
|
+
(v) => (opts.ref = v),
|
|
284
|
+
(v) => (this.root.contentNode = v),
|
|
285
|
+
);
|
|
292
286
|
|
|
293
287
|
this.onpointerdown = this.onpointerdown.bind(this);
|
|
294
288
|
this.onfocusin = this.onfocusin.bind(this);
|
|
@@ -298,7 +292,7 @@ export class PopoverContentState {
|
|
|
298
292
|
new SafePolygon({
|
|
299
293
|
triggerNode: () => this.root.triggerNode,
|
|
300
294
|
contentNode: () => this.root.contentNode,
|
|
301
|
-
enabled: () => this.root.opts.open
|
|
295
|
+
enabled: () => this.root.opts.open && this.root.openedViaHover && !this.root.hasInteractedWithContent,
|
|
302
296
|
onPointerExit: () => {
|
|
303
297
|
this.root.handleDelayedHoverClose();
|
|
304
298
|
},
|
|
@@ -331,14 +325,14 @@ export class PopoverContentState {
|
|
|
331
325
|
this.root.handleClose();
|
|
332
326
|
};
|
|
333
327
|
|
|
334
|
-
readonly snippetProps = $derived.by(() => ({ open: this.root.opts.open
|
|
328
|
+
readonly snippetProps = $derived.by(() => ({ open: this.root.opts.open }));
|
|
335
329
|
|
|
336
330
|
readonly props = $derived.by(
|
|
337
331
|
() =>
|
|
338
332
|
({
|
|
339
|
-
id: this.opts.id
|
|
333
|
+
id: this.opts.id,
|
|
340
334
|
tabindex: -1,
|
|
341
|
-
'data-state': getDataOpenClosed(this.root.opts.open
|
|
335
|
+
'data-state': getDataOpenClosed(this.root.opts.open),
|
|
342
336
|
[popoverAttrs.content]: '',
|
|
343
337
|
onpointerdown: this.onpointerdown,
|
|
344
338
|
onfocusin: this.onfocusin,
|
|
@@ -349,7 +343,7 @@ export class PopoverContentState {
|
|
|
349
343
|
);
|
|
350
344
|
}
|
|
351
345
|
|
|
352
|
-
interface PopoverCloseStateOpts extends
|
|
346
|
+
interface PopoverCloseStateOpts extends RefOpts {}
|
|
353
347
|
|
|
354
348
|
export class PopoverCloseState {
|
|
355
349
|
static create(opts: PopoverCloseStateOpts) {
|
|
@@ -363,7 +357,7 @@ export class PopoverCloseState {
|
|
|
363
357
|
constructor(opts: PopoverCloseStateOpts, root: PopoverRootState) {
|
|
364
358
|
this.opts = opts;
|
|
365
359
|
this.root = root;
|
|
366
|
-
this.attachment = attachRef(
|
|
360
|
+
this.attachment = attachRef<HTMLElement>((v) => (opts.ref = v));
|
|
367
361
|
this.onclick = this.onclick.bind(this);
|
|
368
362
|
this.onkeydown = this.onkeydown.bind(this);
|
|
369
363
|
}
|
|
@@ -381,7 +375,7 @@ export class PopoverCloseState {
|
|
|
381
375
|
readonly props = $derived.by(
|
|
382
376
|
() =>
|
|
383
377
|
({
|
|
384
|
-
id: this.opts.id
|
|
378
|
+
id: this.opts.id,
|
|
385
379
|
onclick: this.onclick,
|
|
386
380
|
onkeydown: this.onkeydown,
|
|
387
381
|
type: 'button',
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { boxWith } from '../../../internal/tools/index.js';
|
|
3
2
|
import { mergeProps } from '../../../internal/merge-props.js';
|
|
4
3
|
import type { ProgressRootProps } from '../types.js';
|
|
5
4
|
import { getProgressPercent, ProgressRootState } from '../progress.svelte.js';
|
|
@@ -19,14 +18,24 @@
|
|
|
19
18
|
}: ProgressRootProps = $props();
|
|
20
19
|
|
|
21
20
|
const rootState = ProgressRootState.create({
|
|
22
|
-
value
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
21
|
+
get value() {
|
|
22
|
+
return value;
|
|
23
|
+
},
|
|
24
|
+
get max() {
|
|
25
|
+
return max;
|
|
26
|
+
},
|
|
27
|
+
get min() {
|
|
28
|
+
return min;
|
|
29
|
+
},
|
|
30
|
+
get id() {
|
|
31
|
+
return id;
|
|
32
|
+
},
|
|
33
|
+
get ref() {
|
|
34
|
+
return ref;
|
|
35
|
+
},
|
|
36
|
+
set ref(v) {
|
|
37
|
+
ref = v;
|
|
38
|
+
},
|
|
30
39
|
});
|
|
31
40
|
|
|
32
41
|
const mergedProps = $derived(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { attachRef
|
|
1
|
+
import { attachRef } from '../../internal/tools/index.js';
|
|
2
2
|
import { createBitsAttrs } from '../../internal/attrs.js';
|
|
3
|
-
import type { RefAttachment,
|
|
3
|
+
import type { RefAttachment, RefOpts } from '../../internal/types.js';
|
|
4
4
|
|
|
5
5
|
const progressAttrs = createBitsAttrs({
|
|
6
6
|
component: 'progress',
|
|
@@ -14,14 +14,11 @@ export function getProgressPercent(value: number | null, min: number, max: numbe
|
|
|
14
14
|
return Math.min(100, Math.max(0, ((value - min) / range) * 100));
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
interface ProgressRootStateOpts
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
max: number;
|
|
23
|
-
min: number;
|
|
24
|
-
}> {}
|
|
17
|
+
interface ProgressRootStateOpts extends RefOpts {
|
|
18
|
+
readonly value: number | null;
|
|
19
|
+
readonly max: number;
|
|
20
|
+
readonly min: number;
|
|
21
|
+
}
|
|
25
22
|
|
|
26
23
|
export class ProgressRootState {
|
|
27
24
|
static create(opts: ProgressRootStateOpts) {
|
|
@@ -33,23 +30,23 @@ export class ProgressRootState {
|
|
|
33
30
|
|
|
34
31
|
constructor(opts: ProgressRootStateOpts) {
|
|
35
32
|
this.opts = opts;
|
|
36
|
-
this.attachment = attachRef(
|
|
33
|
+
this.attachment = attachRef<HTMLElement>((v) => (opts.ref = v));
|
|
37
34
|
}
|
|
38
35
|
|
|
39
36
|
readonly props = $derived.by(() => {
|
|
40
|
-
const value = this.opts
|
|
41
|
-
const percent = getProgressPercent(value,
|
|
37
|
+
const { value, min, max } = this.opts;
|
|
38
|
+
const percent = getProgressPercent(value, min, max);
|
|
42
39
|
const isIndeterminate = value === null;
|
|
43
40
|
return {
|
|
44
41
|
role: 'progressbar',
|
|
45
42
|
value,
|
|
46
|
-
'aria-valuemin':
|
|
47
|
-
'aria-valuemax':
|
|
43
|
+
'aria-valuemin': min,
|
|
44
|
+
'aria-valuemax': max,
|
|
48
45
|
'aria-valuenow': isIndeterminate ? undefined : value,
|
|
49
46
|
'data-value': isIndeterminate ? undefined : value,
|
|
50
47
|
'data-state': value === null ? 'indeterminate' : percent === 100 ? 'loaded' : 'loading',
|
|
51
|
-
'data-max':
|
|
52
|
-
'data-min':
|
|
48
|
+
'data-max': max,
|
|
49
|
+
'data-min': min,
|
|
53
50
|
'data-indeterminate': isIndeterminate ? '' : undefined,
|
|
54
51
|
[progressAttrs.root]: '',
|
|
55
52
|
...this.attachment,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { boxWith } from '../../../internal/tools/index.js';
|
|
3
2
|
import { mergeProps } from '../../../internal/merge-props.js';
|
|
4
3
|
import { SeparatorRootState } from '../separator.svelte.js';
|
|
5
4
|
import type { SeparatorRootProps } from '../types.js';
|
|
@@ -18,13 +17,21 @@
|
|
|
18
17
|
}: SeparatorRootProps = $props();
|
|
19
18
|
|
|
20
19
|
const rootState = SeparatorRootState.create({
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
orientation
|
|
20
|
+
get id() {
|
|
21
|
+
return id;
|
|
22
|
+
},
|
|
23
|
+
get decorative() {
|
|
24
|
+
return decorative;
|
|
25
|
+
},
|
|
26
|
+
get orientation() {
|
|
27
|
+
return orientation;
|
|
28
|
+
},
|
|
29
|
+
get ref() {
|
|
30
|
+
return ref;
|
|
31
|
+
},
|
|
32
|
+
set ref(v) {
|
|
33
|
+
ref = v;
|
|
34
|
+
},
|
|
28
35
|
});
|
|
29
36
|
|
|
30
37
|
const mergedProps = $derived(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { attachRef
|
|
1
|
+
import { attachRef } from '../../internal/tools/index.js';
|
|
2
2
|
import { createBitsAttrs, boolToStrTrueOrUndef } from '../../internal/attrs.js';
|
|
3
|
-
import type { RefAttachment,
|
|
3
|
+
import type { RefAttachment, RefOpts } from '../../internal/types.js';
|
|
4
4
|
import type { Orientation } from '../../internal/index.js';
|
|
5
5
|
|
|
6
6
|
const separatorAttrs = createBitsAttrs({
|
|
@@ -8,13 +8,10 @@ const separatorAttrs = createBitsAttrs({
|
|
|
8
8
|
parts: ['root'],
|
|
9
9
|
});
|
|
10
10
|
|
|
11
|
-
interface SeparatorRootStateOpts
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
orientation: Orientation;
|
|
16
|
-
decorative: boolean;
|
|
17
|
-
}> {}
|
|
11
|
+
interface SeparatorRootStateOpts extends RefOpts {
|
|
12
|
+
readonly orientation: Orientation;
|
|
13
|
+
readonly decorative: boolean;
|
|
14
|
+
}
|
|
18
15
|
|
|
19
16
|
export class SeparatorRootState {
|
|
20
17
|
static create(opts: SeparatorRootStateOpts) {
|
|
@@ -25,17 +22,17 @@ export class SeparatorRootState {
|
|
|
25
22
|
|
|
26
23
|
constructor(opts: SeparatorRootStateOpts) {
|
|
27
24
|
this.opts = opts;
|
|
28
|
-
this.attachment = attachRef(opts.ref);
|
|
25
|
+
this.attachment = attachRef<HTMLElement>((v) => (opts.ref = v));
|
|
29
26
|
}
|
|
30
27
|
|
|
31
28
|
readonly props = $derived.by(
|
|
32
29
|
() =>
|
|
33
30
|
({
|
|
34
|
-
id: this.opts.id
|
|
35
|
-
role: this.opts.decorative
|
|
36
|
-
'aria-orientation': this.opts.orientation
|
|
37
|
-
'aria-hidden': boolToStrTrueOrUndef(this.opts.decorative
|
|
38
|
-
'data-orientation': this.opts.orientation
|
|
31
|
+
id: this.opts.id,
|
|
32
|
+
role: this.opts.decorative ? 'none' : 'separator',
|
|
33
|
+
'aria-orientation': this.opts.orientation,
|
|
34
|
+
'aria-hidden': boolToStrTrueOrUndef(this.opts.decorative),
|
|
35
|
+
'data-orientation': this.opts.orientation,
|
|
39
36
|
[separatorAttrs.root]: '',
|
|
40
37
|
...this.attachment,
|
|
41
38
|
}) as const,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { untrack } from 'svelte';
|
|
3
3
|
import * as Sheet from '../sheet/index.js';
|
|
4
|
-
import { boxWith } from '../../internal/tools/index.js';
|
|
5
4
|
import { DialogRootState, DialogState } from '../dialog/dialog.svelte.js';
|
|
6
5
|
import { join } from 'overrule';
|
|
7
6
|
import { SIDEBAR_WIDTH_MOBILE } from './constants.js';
|
|
@@ -32,9 +31,14 @@
|
|
|
32
31
|
});
|
|
33
32
|
|
|
34
33
|
DialogRootState.create({
|
|
35
|
-
variant:
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
variant: 'dialog',
|
|
35
|
+
get open() {
|
|
36
|
+
return sheetCell.open;
|
|
37
|
+
},
|
|
38
|
+
set open(v) {
|
|
39
|
+
sheetCell.open = v;
|
|
40
|
+
},
|
|
41
|
+
onOpenChangeComplete: () => {},
|
|
38
42
|
});
|
|
39
43
|
</script>
|
|
40
44
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { boxWith } from '../../../internal/tools/index.js';
|
|
3
2
|
import { mergeProps } from '../../../internal/merge-props.js';
|
|
4
3
|
import type { ToggleRootProps } from '../types.js';
|
|
5
4
|
import { ToggleRootState } from '../toggle.svelte.js';
|
|
@@ -26,19 +25,25 @@
|
|
|
26
25
|
} = $props();
|
|
27
26
|
|
|
28
27
|
const toggleState = ToggleRootState.create({
|
|
29
|
-
pressed
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
disabled
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
28
|
+
get pressed() {
|
|
29
|
+
return pressed;
|
|
30
|
+
},
|
|
31
|
+
set pressed(v) {
|
|
32
|
+
pressed = v;
|
|
33
|
+
onPressedChange(v);
|
|
34
|
+
},
|
|
35
|
+
get disabled() {
|
|
36
|
+
return disabled ?? false;
|
|
37
|
+
},
|
|
38
|
+
get id() {
|
|
39
|
+
return id;
|
|
40
|
+
},
|
|
41
|
+
get ref() {
|
|
42
|
+
return ref;
|
|
43
|
+
},
|
|
44
|
+
set ref(v) {
|
|
45
|
+
ref = v;
|
|
46
|
+
},
|
|
42
47
|
});
|
|
43
48
|
|
|
44
49
|
const mergedProps = $derived(
|
|
@@ -1,21 +1,16 @@
|
|
|
1
|
-
import { attachRef
|
|
1
|
+
import { attachRef } from '../../internal/tools/index.js';
|
|
2
2
|
import { createBitsAttrs, boolToStr, boolToEmptyStrOrUndef, boolToTrueOrUndef } from '../../internal/attrs.js';
|
|
3
|
-
import type { BitsMouseEvent, RefAttachment,
|
|
3
|
+
import type { BitsMouseEvent, RefAttachment, RefOpts } from '../../internal/types.js';
|
|
4
4
|
|
|
5
5
|
export const toggleAttrs = createBitsAttrs({
|
|
6
6
|
component: 'toggle',
|
|
7
7
|
parts: ['root'],
|
|
8
8
|
});
|
|
9
9
|
|
|
10
|
-
interface ToggleRootStateOpts
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
disabled: boolean;
|
|
15
|
-
}>,
|
|
16
|
-
WritableBoxedValues<{
|
|
17
|
-
pressed: boolean;
|
|
18
|
-
}> {}
|
|
10
|
+
interface ToggleRootStateOpts extends RefOpts {
|
|
11
|
+
readonly disabled: boolean;
|
|
12
|
+
pressed: boolean;
|
|
13
|
+
}
|
|
19
14
|
|
|
20
15
|
export class ToggleRootState {
|
|
21
16
|
static create(opts: ToggleRootStateOpts) {
|
|
@@ -26,28 +21,28 @@ export class ToggleRootState {
|
|
|
26
21
|
|
|
27
22
|
constructor(opts: ToggleRootStateOpts) {
|
|
28
23
|
this.opts = opts;
|
|
29
|
-
this.attachment = attachRef(
|
|
24
|
+
this.attachment = attachRef<HTMLElement>((v) => (opts.ref = v));
|
|
30
25
|
this.onclick = this.onclick.bind(this);
|
|
31
26
|
}
|
|
32
27
|
|
|
33
28
|
onclick(_: BitsMouseEvent) {
|
|
34
|
-
if (this.opts.disabled
|
|
35
|
-
this.opts.pressed
|
|
29
|
+
if (this.opts.disabled) return;
|
|
30
|
+
this.opts.pressed = !this.opts.pressed;
|
|
36
31
|
}
|
|
37
32
|
|
|
38
33
|
readonly snippetProps = $derived.by(() => ({
|
|
39
|
-
pressed: this.opts.pressed
|
|
34
|
+
pressed: this.opts.pressed,
|
|
40
35
|
}));
|
|
41
36
|
|
|
42
37
|
readonly props = $derived.by(
|
|
43
38
|
() =>
|
|
44
39
|
({
|
|
45
40
|
[toggleAttrs.root]: '',
|
|
46
|
-
id: this.opts.id
|
|
47
|
-
'data-disabled': boolToEmptyStrOrUndef(this.opts.disabled
|
|
48
|
-
'aria-pressed': boolToStr(this.opts.pressed
|
|
49
|
-
'data-state': getToggleDataState(this.opts.pressed
|
|
50
|
-
disabled: boolToTrueOrUndef(this.opts.disabled
|
|
41
|
+
id: this.opts.id,
|
|
42
|
+
'data-disabled': boolToEmptyStrOrUndef(this.opts.disabled),
|
|
43
|
+
'aria-pressed': boolToStr(this.opts.pressed),
|
|
44
|
+
'data-state': getToggleDataState(this.opts.pressed),
|
|
45
|
+
disabled: boolToTrueOrUndef(this.opts.disabled),
|
|
51
46
|
onclick: this.onclick,
|
|
52
47
|
...this.attachment,
|
|
53
48
|
}) as const,
|