sheer-ui 0.3.1 → 0.4.2
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/accordion/components/accordion-item.svelte +3 -3
- package/src/lib/components/accordion/components/accordion.svelte +29 -13
- package/src/lib/components/accordion/types.ts +3 -3
- package/src/lib/components/checkbox/components/checkbox-group.svelte +7 -5
- package/src/lib/components/checkbox/components/checkbox.svelte +12 -8
- package/src/lib/components/combobox/components/combobox.svelte +2 -2
- package/src/lib/components/combobox/select/components/select.svelte +2 -2
- package/src/lib/components/context-menu/components/context-menu-trigger.svelte +1 -1
- package/src/lib/components/data-table/table-faceted-filter.svelte +2 -2
- package/src/lib/components/data-table/table-toolbar.svelte +5 -5
- package/src/lib/components/date-field/date-field.svelte.ts +2 -3
- package/src/lib/components/menu/components/menu-checkbox-group.svelte +6 -4
- package/src/lib/components/menu/components/menu-checkbox-item.svelte +11 -7
- package/src/lib/components/menu/menu.svelte.ts +9 -18
- package/src/lib/components/menubar/menubar.svelte.ts +7 -6
- package/src/lib/components/navigation-menu/components/navigation-menu-content.svelte +1 -1
- package/src/lib/components/navigation-menu/components/navigation-menu-indicator.svelte +2 -2
- package/src/lib/components/navigation-menu/components/navigation-menu-trigger.svelte +1 -1
- package/src/lib/components/navigation-menu/navigation-menu.svelte.ts +57 -60
- package/src/lib/components/pagination/components/pagination-next-button.svelte +12 -7
- package/src/lib/components/pagination/components/pagination-page.svelte +15 -8
- package/src/lib/components/pagination/components/pagination-prev-button.svelte +12 -7
- package/src/lib/components/pagination/components/pagination.svelte +31 -18
- package/src/lib/components/pagination/pagination.svelte.ts +48 -64
- package/src/lib/components/pin-input/pin-input.svelte.ts +7 -8
- package/src/lib/components/pin-input/usePasswordManager.svelte.ts +2 -2
- package/src/lib/components/scroll-area/scroll-area.svelte.ts +9 -10
- package/src/lib/components/slider/components/slider.svelte +2 -1
- package/src/lib/components/tabs/components/tabs-content.svelte +12 -7
- package/src/lib/components/tabs/components/tabs-list.svelte +9 -6
- package/src/lib/components/tabs/components/tabs-trigger.svelte +15 -8
- package/src/lib/components/tabs/components/tabs.svelte +28 -17
- package/src/lib/components/tabs/tabs.svelte.ts +51 -67
- package/src/lib/components/time-field/time-field.svelte.ts +2 -2
- package/src/lib/components/toggle-group/components/toggle-group-item.svelte +15 -8
- package/src/lib/components/toggle-group/components/toggle-group.svelte +28 -16
- package/src/lib/components/toggle-group/toggle-group.svelte.ts +33 -35
- package/src/lib/components/toolbar/components/toolbar-group-item.svelte +15 -8
- package/src/lib/components/toolbar/components/toolbar-group.svelte +19 -14
- package/src/lib/components/toolbar/toolbar.svelte.ts +28 -30
- package/src/lib/components/tooltip/tooltip.svelte.ts +6 -27
- package/src/lib/internal/dismissible-layer/use-dismissable-layer.svelte.ts +3 -4
- package/src/lib/internal/floating-layer/use-floating-layer.svelte.ts +26 -30
- package/src/lib/internal/{roving-focus-group.ts → roving-focus-group.svelte.ts} +17 -19
- package/src/lib/internal/roving-focus-item.svelte.ts +12 -17
- package/src/lib/internal/selection.svelte.ts +55 -41
- package/src/lib/internal/{state-machine.ts → state-machine.svelte.ts} +6 -8
- package/src/lib/internal/table/table.svelte.ts +23 -43
- package/src/lib/internal/timeout-fn.svelte.ts +6 -4
- package/src/lib/internal/tools/box.svelte.ts +5 -114
- package/src/lib/internal/tools/index.ts +1 -11
- package/src/lib/internal/tools/types.ts +0 -3
- package/src/lib/internal/typeahead.svelte.ts +9 -13
- package/src/lib/internal/types.ts +6 -0
- package/src/lib/internal/vaul/use-drawer-content.svelte.ts +2 -2
- package/src/lib/internal/vaul/use-drawer-root.svelte.ts +12 -7
- package/src/lib/components/accordion/accordion.svelte.ts +0 -43
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { join } from 'overrule';
|
|
3
3
|
import { createSettleRunner } from '../../../internal/animations-settled.svelte.js';
|
|
4
|
-
import { useAccordion } from '
|
|
4
|
+
import { useAccordion } from './accordion.svelte';
|
|
5
5
|
import type { AccordionItemProps } from '../types.js';
|
|
6
6
|
|
|
7
7
|
let { value, disabled = false, class: className, ref = $bindable(null), children, ...restProps }: AccordionItemProps = $props();
|
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
const summary = (e.target as HTMLElement).closest('summary');
|
|
47
47
|
if (!summary || summary.closest('details') !== e.currentTarget) return;
|
|
48
48
|
e.preventDefault();
|
|
49
|
-
accordion.
|
|
49
|
+
accordion.value = accordion.with(value, !open);
|
|
50
50
|
}}
|
|
51
51
|
ontoggle={(e) => {
|
|
52
52
|
// Native toggles that bypass the click path (find-in-page, hash reveal).
|
|
53
53
|
if (e.currentTarget.open === rendered) return;
|
|
54
|
-
accordion.
|
|
54
|
+
accordion.value = accordion.with(value, e.currentTarget.open);
|
|
55
55
|
}}
|
|
56
56
|
bind:this={ref}>
|
|
57
57
|
{@render children?.()}
|
|
@@ -1,21 +1,37 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import { createContext } from 'svelte';
|
|
3
|
+
import { SelectionValue, emptySelection } from '../../../internal/selection.svelte.js';
|
|
4
|
+
|
|
5
|
+
export const [useAccordion, setAccordion] = createContext<SelectionValue>();
|
|
6
|
+
</script>
|
|
7
|
+
|
|
1
8
|
<script lang="ts">
|
|
2
|
-
import {
|
|
9
|
+
import { repairBindable } from '../../../internal/tools/index.js';
|
|
3
10
|
import type { AccordionRootProps } from '../types.js';
|
|
4
11
|
|
|
5
|
-
let {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
let { type = 'single', value = $bindable(), ref = $bindable(null), children, ...restProps }: AccordionRootProps = $props();
|
|
13
|
+
|
|
14
|
+
// Mode is fixed at mount, like the selection groups: `value` keeps the shape it was declared with.
|
|
15
|
+
// svelte-ignore state_referenced_locally
|
|
16
|
+
const valueType = type;
|
|
17
|
+
|
|
18
|
+
repairBindable(
|
|
19
|
+
() => value,
|
|
20
|
+
() => {
|
|
21
|
+
if (value === undefined) value = emptySelection(valueType);
|
|
22
|
+
},
|
|
23
|
+
);
|
|
12
24
|
|
|
25
|
+
// Each item is a `<details>`; this holds the open set (bindable `value`) and single-type
|
|
26
|
+
// exclusivity — not the native `name` attribute, which would unrender a force-closed sibling
|
|
27
|
+
// before its closing transition can play. Items intercept summary clicks and report intent
|
|
28
|
+
// here; the grid-track animation lives in ui.css.
|
|
13
29
|
setAccordion(
|
|
14
|
-
new
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
30
|
+
new SelectionValue(
|
|
31
|
+
valueType,
|
|
32
|
+
() => value ?? emptySelection(valueType),
|
|
33
|
+
(v) => (value = v),
|
|
34
|
+
),
|
|
19
35
|
);
|
|
20
36
|
</script>
|
|
21
37
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { HTMLAttributes, SvelteHTMLElements } from 'svelte/elements';
|
|
2
2
|
import type { WithElementRef } from '../../internal/utils.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { SelectionType } from '../../internal/selection.svelte.js';
|
|
4
4
|
|
|
5
5
|
export type AccordionRootProps = WithElementRef<HTMLAttributes<HTMLDivElement>, HTMLDivElement> & {
|
|
6
|
-
/** 'single'
|
|
7
|
-
type?:
|
|
6
|
+
/** 'single' keeps one item open: opening an item closes the open one. Fixed at mount. */
|
|
7
|
+
type?: SelectionType;
|
|
8
8
|
/** The open item value(s) — string for single, string[] for multiple. Bindable. */
|
|
9
9
|
value?: string | string[];
|
|
10
10
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { boxWith } from '../../../internal/tools/index.js';
|
|
3
3
|
import { mergeProps } from '../../../internal/merge-props.js';
|
|
4
4
|
import type { CheckboxGroupProps } from '../types.js';
|
|
5
5
|
import { CheckboxGroupState } from '../checkbox.svelte.js';
|
|
@@ -22,17 +22,19 @@
|
|
|
22
22
|
|
|
23
23
|
const groupState = CheckboxGroupState.create({
|
|
24
24
|
id: boxWith(() => id),
|
|
25
|
-
ref:
|
|
25
|
+
ref: boxWith(
|
|
26
26
|
() => ref,
|
|
27
27
|
(v) => (ref = v),
|
|
28
28
|
),
|
|
29
29
|
disabled: boxWith(() => Boolean(disabled)),
|
|
30
30
|
required: boxWith(() => Boolean(required)),
|
|
31
31
|
readonly: boxWith(() => Boolean(readonly)),
|
|
32
|
-
value:
|
|
32
|
+
value: boxWith(
|
|
33
33
|
() => $state.snapshot(value),
|
|
34
|
-
(v) =>
|
|
35
|
-
|
|
34
|
+
(v) => {
|
|
35
|
+
value = $state.snapshot(v);
|
|
36
|
+
onValueChange(v);
|
|
37
|
+
},
|
|
36
38
|
),
|
|
37
39
|
});
|
|
38
40
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Checkbox (button): controlled / headless. A <button role=checkbox> for table
|
|
3
3
|
// select-all, JS-owned state, and Checkbox.Group. It does NOT submit in a form;
|
|
4
4
|
// use `CheckboxNative` (name/value) for form fields.
|
|
5
|
-
import {
|
|
5
|
+
import { boxWith, repairBindable } from '../../../internal/tools/index.js';
|
|
6
6
|
import { mergeProps } from '../../../internal/merge-props.js';
|
|
7
7
|
import type { CheckboxRootProps } from '../types.js';
|
|
8
8
|
import { CheckboxRootState } from '../checkbox.svelte.js';
|
|
@@ -30,23 +30,27 @@
|
|
|
30
30
|
}: CheckboxRootProps = $props();
|
|
31
31
|
|
|
32
32
|
const rootState = CheckboxRootState.create({
|
|
33
|
-
checked:
|
|
33
|
+
checked: boxWith(
|
|
34
34
|
() => checked,
|
|
35
|
-
(v) =>
|
|
36
|
-
|
|
35
|
+
(v) => {
|
|
36
|
+
checked = v;
|
|
37
|
+
onCheckedChange?.(v);
|
|
38
|
+
},
|
|
37
39
|
),
|
|
38
40
|
disabled: boxWith(() => disabled ?? false),
|
|
39
41
|
required: boxWith(() => required),
|
|
40
42
|
value: boxWith(() => value),
|
|
41
43
|
id: boxWith(() => id),
|
|
42
|
-
ref:
|
|
44
|
+
ref: boxWith(
|
|
43
45
|
() => ref,
|
|
44
46
|
(v) => (ref = v),
|
|
45
47
|
),
|
|
46
|
-
indeterminate:
|
|
48
|
+
indeterminate: boxWith(
|
|
47
49
|
() => indeterminate,
|
|
48
|
-
(v) =>
|
|
49
|
-
|
|
50
|
+
(v) => {
|
|
51
|
+
indeterminate = v;
|
|
52
|
+
onIndeterminateChange?.(v);
|
|
53
|
+
},
|
|
50
54
|
),
|
|
51
55
|
type: boxWith(() => type),
|
|
52
56
|
readonly: boxWith(() => Boolean(readonly)),
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { untrack } from 'svelte';
|
|
3
2
|
import { type WritableBox, boxWith, repairBindable } from '../../../internal/tools/index.js';
|
|
4
3
|
import { OpenCell } from '../../../internal/open-cell.svelte.js';
|
|
5
4
|
import type { ComboboxRootProps } from '../types.js';
|
|
@@ -41,7 +40,8 @@
|
|
|
41
40
|
const cell = givenCell ?? new OpenCell(() => open);
|
|
42
41
|
|
|
43
42
|
const rootState = SelectRootState.create({
|
|
44
|
-
|
|
43
|
+
// svelte-ignore state_referenced_locally
|
|
44
|
+
type,
|
|
45
45
|
value: boxWith(
|
|
46
46
|
() => value!,
|
|
47
47
|
(v) => {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { untrack } from 'svelte';
|
|
3
2
|
import FloatingLayer from '../../../../internal/floating-layer/components/floating-layer.svelte';
|
|
4
3
|
import { type WritableBox, boxWith, repairBindable } from '../../../../internal/tools/index.js';
|
|
5
4
|
import { OpenCell } from '../../../../internal/open-cell.svelte.js';
|
|
@@ -46,7 +45,8 @@
|
|
|
46
45
|
const select = givenCell ?? new OpenCell(() => open);
|
|
47
46
|
|
|
48
47
|
const rootState = SelectRootState.create({
|
|
49
|
-
|
|
48
|
+
// svelte-ignore state_referenced_locally
|
|
49
|
+
type,
|
|
50
50
|
value: boxWith(
|
|
51
51
|
() => value!,
|
|
52
52
|
(v) => {
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
selectedValues.add(option.value);
|
|
75
75
|
}
|
|
76
76
|
const filterValues = Array.from(selectedValues);
|
|
77
|
-
column
|
|
77
|
+
column.filterValue = filterValues.length ? filterValues : undefined;
|
|
78
78
|
}}>
|
|
79
79
|
<div
|
|
80
80
|
class={[
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
{#if selectedValues.size > 0}
|
|
101
101
|
<Command.Separator />
|
|
102
102
|
<Command.Group>
|
|
103
|
-
<Command.Item onSelect={() => column
|
|
103
|
+
<Command.Item onSelect={() => (column.filterValue = undefined)} class="justify-center text-center">Clear filters</Command.Item>
|
|
104
104
|
</Command.Group>
|
|
105
105
|
{/if}
|
|
106
106
|
</Command.List>
|
|
@@ -25,16 +25,16 @@
|
|
|
25
25
|
} = $props();
|
|
26
26
|
|
|
27
27
|
const isFiltered = $derived(table.columnFilters.length > 0);
|
|
28
|
+
const search = $derived(searchColumn === undefined ? undefined : table.column(searchColumn));
|
|
28
29
|
</script>
|
|
29
30
|
|
|
30
31
|
<div class="flex items-center justify-between">
|
|
31
|
-
{#if
|
|
32
|
+
{#if search}
|
|
32
33
|
<Input
|
|
33
34
|
{disabled}
|
|
34
35
|
placeholder={searchPlaceholder ?? 'Filter...'}
|
|
35
|
-
value={(
|
|
36
|
-
oninput={(e) =>
|
|
37
|
-
onchange={(e) => table.column(searchColumn)?.setFilterValue(e.currentTarget.value)}
|
|
36
|
+
value={(search.filterValue as string) ?? ''}
|
|
37
|
+
oninput={(e) => (search.filterValue = e.currentTarget.value)}
|
|
38
38
|
class="h-8 w-37.5 lg:w-62.5" />
|
|
39
39
|
{/if}
|
|
40
40
|
<div class="flex items-center space-x-2">
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
{/each}
|
|
47
47
|
|
|
48
48
|
{#if isFiltered}
|
|
49
|
-
<Button variant="ghost" {disabled} onclick={() => table.
|
|
49
|
+
<Button variant="ghost" {disabled} onclick={() => (table.columnFilters = [])} class="h-8! px-2! lg:px-3!">
|
|
50
50
|
Reset
|
|
51
51
|
<XIcon />
|
|
52
52
|
</Button>
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
DOMContext,
|
|
9
9
|
type ReadableBoxedValues,
|
|
10
10
|
type WritableBoxedValues,
|
|
11
|
-
simpleBox,
|
|
12
11
|
} from '../../internal/tools/index.js';
|
|
13
12
|
import { createContext, onMount, untrack } from 'svelte';
|
|
14
13
|
import type { DateRangeFieldRootState } from '../date-range-field/date-range-field.svelte.js';
|
|
@@ -193,7 +192,7 @@ export class DateFieldRootState {
|
|
|
193
192
|
states = initSegmentStates();
|
|
194
193
|
dayPeriodNode = $state<HTMLElement | null>(null);
|
|
195
194
|
rangeRoot: DateRangeFieldRootState | undefined = undefined;
|
|
196
|
-
#nameSource: ReadableBox<string> =
|
|
195
|
+
#nameSource: ReadableBox<string> = boxWith(() => '');
|
|
197
196
|
get name() {
|
|
198
197
|
return this.#nameSource.current;
|
|
199
198
|
}
|
|
@@ -209,7 +208,7 @@ export class DateFieldRootState {
|
|
|
209
208
|
*/
|
|
210
209
|
this.value = props.value;
|
|
211
210
|
this.placeholder = rangeRoot ? rangeRoot.opts.placeholder : props.placeholder;
|
|
212
|
-
this.validate = rangeRoot ?
|
|
211
|
+
this.validate = rangeRoot ? boxWith(() => undefined) : props.validate;
|
|
213
212
|
this.minValue = rangeRoot ? rangeRoot.opts.minValue : props.minValue;
|
|
214
213
|
this.maxValue = rangeRoot ? rangeRoot.opts.maxValue : props.maxValue;
|
|
215
214
|
this.disabled = rangeRoot ? rangeRoot.opts.disabled : props.disabled;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { boxWith } from '../../../internal/tools/index.js';
|
|
3
3
|
import { mergeProps } from '../../../internal/merge-props.js';
|
|
4
4
|
import type { MenuCheckboxGroupProps } from '../types.js';
|
|
5
5
|
import { MenuCheckboxGroupState } from '../menu.svelte.js';
|
|
@@ -18,10 +18,12 @@
|
|
|
18
18
|
}: MenuCheckboxGroupProps = $props();
|
|
19
19
|
|
|
20
20
|
const checkboxGroupState = MenuCheckboxGroupState.create({
|
|
21
|
-
value:
|
|
21
|
+
value: boxWith(
|
|
22
22
|
() => $state.snapshot(value),
|
|
23
|
-
(v) =>
|
|
24
|
-
|
|
23
|
+
(v) => {
|
|
24
|
+
value = $state.snapshot(v);
|
|
25
|
+
onValueChange(v);
|
|
26
|
+
},
|
|
25
27
|
),
|
|
26
28
|
ref: boxWith(
|
|
27
29
|
() => ref,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { join } from 'overrule';
|
|
3
|
-
import {
|
|
3
|
+
import { boxWith, repairBindable } from '../../../internal/tools/index.js';
|
|
4
4
|
import { mergeProps } from '../../../internal/merge-props.js';
|
|
5
5
|
import type { MenuCheckboxItemProps } from '../types.js';
|
|
6
6
|
import { MenuCheckboxItemState } from '../menu.svelte.js';
|
|
@@ -26,10 +26,12 @@
|
|
|
26
26
|
}: MenuCheckboxItemProps = $props();
|
|
27
27
|
|
|
28
28
|
const checkboxItemState = MenuCheckboxItemState.create({
|
|
29
|
-
checked:
|
|
29
|
+
checked: boxWith(
|
|
30
30
|
() => checked,
|
|
31
|
-
(v) =>
|
|
32
|
-
|
|
31
|
+
(v) => {
|
|
32
|
+
checked = v;
|
|
33
|
+
onCheckedChange(v);
|
|
34
|
+
},
|
|
33
35
|
),
|
|
34
36
|
id: boxWith(() => id),
|
|
35
37
|
disabled: boxWith(() => disabled),
|
|
@@ -38,10 +40,12 @@
|
|
|
38
40
|
() => ref,
|
|
39
41
|
(v) => (ref = v),
|
|
40
42
|
),
|
|
41
|
-
indeterminate:
|
|
43
|
+
indeterminate: boxWith(
|
|
42
44
|
() => indeterminate,
|
|
43
|
-
(v) =>
|
|
44
|
-
|
|
45
|
+
(v) => {
|
|
46
|
+
indeterminate = v;
|
|
47
|
+
onIndeterminateChange(v);
|
|
48
|
+
},
|
|
45
49
|
),
|
|
46
50
|
value: boxWith(() => value),
|
|
47
51
|
});
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
getWindow,
|
|
5
5
|
type ReadableBoxedValues,
|
|
6
6
|
type WritableBoxedValues,
|
|
7
|
-
simpleBox,
|
|
8
7
|
boxWith,
|
|
9
8
|
type ReadableBox,
|
|
10
9
|
} from '../../internal/tools/index.js';
|
|
11
10
|
import { mergeProps } from '../../internal/merge-props.js';
|
|
11
|
+
import type { Measurable } from '../../internal/floating-layer/index.js';
|
|
12
12
|
import { createContext, onDestroy, tick, untrack } from 'svelte';
|
|
13
13
|
import { SUB_OPEN_KEYS, getCheckedState, isMouseEvent } from './utils.js';
|
|
14
14
|
import { focusFirst } from '../../internal/focus.js';
|
|
@@ -35,7 +35,7 @@ import type { Direction } from '../../internal/index.js';
|
|
|
35
35
|
import { getTabbableFrom, isTabbable } from '../../internal/tabbable.js';
|
|
36
36
|
import type { KeyboardEventHandler, PointerEventHandler, MouseEventHandler } from 'svelte/elements';
|
|
37
37
|
import { Typeahead, textContentOf } from '../../internal/typeahead.svelte.js';
|
|
38
|
-
import { RovingFocusGroup } from '../../internal/roving-focus-group.js';
|
|
38
|
+
import { RovingFocusGroup } from '../../internal/roving-focus-group.svelte.js';
|
|
39
39
|
import { useOpenChangeComplete } from '../../internal/animations-settled.svelte.js';
|
|
40
40
|
import { joinGroup } from '../../internal/group-value.svelte.js';
|
|
41
41
|
import { createEffectTimeout } from '../../internal/timeout-fn.svelte.js';
|
|
@@ -601,10 +601,10 @@ export class MenuContentState {
|
|
|
601
601
|
getWindow: () => this.domContext.getWindow(),
|
|
602
602
|
});
|
|
603
603
|
this.rovingFocusGroup = new RovingFocusGroup({
|
|
604
|
-
rootNode:
|
|
604
|
+
rootNode: () => this.parentMenu.contentNode,
|
|
605
605
|
candidateSelector: this.#candidateSelector,
|
|
606
|
-
loop: this.opts.loop,
|
|
607
|
-
orientation:
|
|
606
|
+
loop: () => this.opts.loop.current,
|
|
607
|
+
orientation: () => 'vertical',
|
|
608
608
|
});
|
|
609
609
|
|
|
610
610
|
$effect(() => {
|
|
@@ -1461,11 +1461,11 @@ export class ContextMenuTriggerState {
|
|
|
1461
1461
|
readonly opts: ContextMenuTriggerStateOpts;
|
|
1462
1462
|
readonly parentMenu: MenuMenuState;
|
|
1463
1463
|
readonly attachment: RefAttachment;
|
|
1464
|
-
#point = $state({ x: 0, y: 0 });
|
|
1465
|
-
|
|
1466
|
-
virtualElement =
|
|
1464
|
+
#point = $state.raw({ x: 0, y: 0 });
|
|
1465
|
+
// One stable Measurable: readers that measure inside a derived track `#point` through it.
|
|
1466
|
+
readonly virtualElement: Measurable = {
|
|
1467
1467
|
getBoundingClientRect: () => DOMRect.fromRect({ width: 0, height: 0, ...this.#point }),
|
|
1468
|
-
}
|
|
1468
|
+
};
|
|
1469
1469
|
#longPressTimer = createEffectTimeout((e: BitsPointerEvent) => this.#handleOpen(e), () => 700);
|
|
1470
1470
|
|
|
1471
1471
|
constructor(opts: ContextMenuTriggerStateOpts, parentMenu: MenuMenuState) {
|
|
@@ -1478,15 +1478,6 @@ export class ContextMenuTriggerState {
|
|
|
1478
1478
|
this.onpointercancel = this.onpointercancel.bind(this);
|
|
1479
1479
|
this.onpointerup = this.onpointerup.bind(this);
|
|
1480
1480
|
|
|
1481
|
-
$effect(() => {
|
|
1482
|
-
const point = this.#point;
|
|
1483
|
-
untrack(() => {
|
|
1484
|
-
this.virtualElement.current = {
|
|
1485
|
-
getBoundingClientRect: () => DOMRect.fromRect({ width: 0, height: 0, ...point }),
|
|
1486
|
-
};
|
|
1487
|
-
});
|
|
1488
|
-
});
|
|
1489
|
-
|
|
1490
1481
|
$effect(() => {
|
|
1491
1482
|
const isDisabled = this.opts.disabled.current;
|
|
1492
1483
|
untrack(() => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ReadableBox,
|
|
1
|
+
import { type ReadableBox, attachRef, type ReadableBoxedValues, type WritableBoxedValues } from '../../internal/tools/index.js';
|
|
2
2
|
import type { InteractOutsideBehaviorType } from '../../internal/dismissible-layer/types.js';
|
|
3
3
|
import type { Direction } from '../../internal/index.js';
|
|
4
4
|
import { createBitsAttrs, boolToStr, boolToEmptyStrOrUndef, getDataOpenClosed } from '../../internal/attrs.js';
|
|
@@ -7,7 +7,7 @@ import type { OnChangeFn, RefAttachment, WithRefOpts } from '../../internal/type
|
|
|
7
7
|
import { createContext, onMount, tick, untrack } from 'svelte';
|
|
8
8
|
import type { FocusEventHandler, KeyboardEventHandler, PointerEventHandler } from 'svelte/elements';
|
|
9
9
|
import { getFloatingContentCSSVars } from '../../internal/floating-layer/index.js';
|
|
10
|
-
import { RovingFocusGroup } from '../../internal/roving-focus-group.js';
|
|
10
|
+
import { RovingFocusGroup } from '../../internal/roving-focus-group.svelte.js';
|
|
11
11
|
import { RovingFocusItem } from '../../internal/roving-focus-item.svelte.js';
|
|
12
12
|
|
|
13
13
|
const menubarAttrs = createBitsAttrs({
|
|
@@ -45,10 +45,10 @@ export class MenubarRootState {
|
|
|
45
45
|
this.opts = opts;
|
|
46
46
|
this.attachment = attachRef(this.opts.ref);
|
|
47
47
|
this.rovingFocusGroup = new RovingFocusGroup({
|
|
48
|
-
rootNode: this.opts.ref,
|
|
48
|
+
rootNode: () => this.opts.ref.current,
|
|
49
49
|
candidateAttr: menubarAttrs.trigger,
|
|
50
|
-
loop: this.opts.loop,
|
|
51
|
-
orientation:
|
|
50
|
+
loop: () => this.opts.loop.current,
|
|
51
|
+
orientation: () => 'horizontal',
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
54
|
|
|
@@ -203,7 +203,8 @@ export class MenubarTriggerState {
|
|
|
203
203
|
this.root = menu.root;
|
|
204
204
|
this.rovingItem = new RovingFocusItem({
|
|
205
205
|
group: this.root.rovingFocusGroup,
|
|
206
|
-
ref: this.opts.ref,
|
|
206
|
+
ref: () => this.opts.ref.current,
|
|
207
|
+
setRef: (v) => (this.opts.ref.current = v),
|
|
207
208
|
onRefChange: (v) => (this.menu.triggerNode = v),
|
|
208
209
|
});
|
|
209
210
|
|
|
@@ -53,6 +53,6 @@
|
|
|
53
53
|
);
|
|
54
54
|
</script>
|
|
55
55
|
|
|
56
|
-
<Portal to={contentState.context.viewportRef
|
|
56
|
+
<Portal to={contentState.context.viewportRef || undefined} disabled={!contentState.context.viewportRef}>
|
|
57
57
|
<NavigationMenuContentImpl {...mergedProps} {children} {child} />
|
|
58
58
|
</Portal>
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
);
|
|
42
42
|
</script>
|
|
43
43
|
|
|
44
|
-
{#if indicatorState.context.indicatorTrackRef
|
|
45
|
-
<Portal to={indicatorState.context.indicatorTrackRef
|
|
44
|
+
{#if indicatorState.context.indicatorTrackRef}
|
|
45
|
+
<Portal to={indicatorState.context.indicatorTrackRef}>
|
|
46
46
|
<NavigationMenuIndicatorImpl {...mergedProps} {id} bind:ref {child}>
|
|
47
47
|
{#snippet children()}
|
|
48
48
|
{#if children}
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
<!-- focus proxy: visually hidden (the sr-only utility) but focusable, for nav-menu focus management -->
|
|
75
75
|
<span {...mergeProps(triggerState.focusProxyProps, mounted, { class: 'sr-only' })}></span>
|
|
76
76
|
|
|
77
|
-
{#if triggerState.context.viewportRef
|
|
77
|
+
{#if triggerState.context.viewportRef}
|
|
78
78
|
<span aria-owns={triggerState.itemContext.contentId ?? undefined}></span>
|
|
79
79
|
{/if}
|
|
80
80
|
{/if}
|