fluentui-svelte 0.2.0 → 0.3.0
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/auto-suggest-box/auto-suggest-box.svelte +68 -56
- package/dist/components/auto-suggest-box/docs/llms.md +46 -14
- package/dist/components/auto-suggest-box/option.svelte +2 -1
- package/dist/components/avatar/docs/llms.md +20 -14
- package/dist/components/badge/docs/llms.md +29 -16
- package/dist/components/button/button.svelte +11 -5
- package/dist/components/button/docs/llms.md +33 -24
- package/dist/components/calendar-date-picker/docs/llms.md +17 -7
- package/dist/components/calendar-view/calendar-view-header.svelte +2 -2
- package/dist/components/calendar-view/calendar-view-header.svelte.d.ts +2 -17
- package/dist/components/calendar-view/calendar-view-months.svelte +1 -1
- package/dist/components/calendar-view/calendar-view-years.svelte +1 -1
- package/dist/components/calendar-view/calendar-view.svelte +66 -52
- package/dist/components/calendar-view/docs/llms.md +42 -30
- package/dist/components/card/docs/llms.md +54 -34
- package/dist/components/checkbox/docs/llms.md +18 -12
- package/dist/components/date-picker/docs/llms.md +25 -15
- package/dist/components/dialog/dialog-surface.svelte +8 -8
- package/dist/components/dialog/dialog.svelte +41 -39
- package/dist/components/dialog/docs/llms.md +59 -34
- package/dist/components/divider/docs/llms.md +14 -9
- package/dist/components/dropdown/docs/llms.md +34 -15
- package/dist/components/dropdown/dropdown.svelte +4 -2
- package/dist/components/dropdown-select/docs/llms.md +28 -14
- package/dist/components/expander/docs/llms.md +19 -12
- package/dist/components/flyout/docs/llms.md +17 -11
- package/dist/components/hyperlink/docs/llms.md +11 -7
- package/dist/components/info-bar/docs/llms.md +15 -9
- package/dist/components/label/docs/llms.md +15 -11
- package/dist/components/list-view/docs/llms.md +34 -24
- package/dist/components/list-view/list-view-item.svelte +10 -4
- package/dist/components/list-view/list-view.svelte +68 -63
- package/dist/components/menu/context-menu-trigger.svelte +45 -40
- package/dist/components/menu/docs/llms.md +63 -34
- package/dist/components/menu/menu-item-checkbox.svelte +3 -1
- package/dist/components/menu/menu-item-radio.svelte +3 -1
- package/dist/components/menu/menu-item-switch.svelte +3 -1
- package/dist/components/menu/menu-item.svelte +5 -1
- package/dist/components/menu/menu-popover.svelte +21 -10
- package/dist/components/menu/menu-trigger.svelte +22 -9
- package/dist/components/menu/menu.svelte +98 -87
- package/dist/components/number-box/docs/llms.md +10 -6
- package/dist/components/persona/docs/llms.md +19 -14
- package/dist/components/progress-bar/docs/llms.md +18 -10
- package/dist/components/progress-ring/docs/llms.md +19 -12
- package/dist/components/radio-button/docs/llms.md +13 -8
- package/dist/components/skeleton/docs/llms.md +13 -8
- package/dist/components/slider/docs/llms.md +33 -21
- package/dist/components/slider/slider.svelte +13 -11
- package/dist/components/table/docs/llms.md +531 -0
- package/dist/components/table/table-body.svelte +31 -0
- package/dist/components/table/table-body.svelte.d.ts +25 -0
- package/dist/components/table/table-cell-actions.svelte +48 -0
- package/dist/components/table/table-cell-actions.svelte.d.ts +17 -0
- package/dist/components/table/table-cell-layout.svelte +88 -0
- package/dist/components/table/table-cell-layout.svelte.d.ts +14 -0
- package/dist/components/table/table-cell.svelte +74 -0
- package/dist/components/table/table-cell.svelte.d.ts +25 -0
- package/dist/components/table/table-header-cell.svelte +257 -0
- package/dist/components/table/table-header-cell.svelte.d.ts +25 -0
- package/dist/components/table/table-header.svelte +28 -0
- package/dist/components/table/table-header.svelte.d.ts +25 -0
- package/dist/components/table/table-row.svelte +57 -0
- package/dist/components/table/table-row.svelte.d.ts +25 -0
- package/dist/components/table/table-selection-cell.svelte +89 -0
- package/dist/components/table/table-selection-cell.svelte.d.ts +25 -0
- package/dist/components/table/table.svelte +189 -0
- package/dist/components/table/table.svelte.d.ts +49 -0
- package/dist/components/table/table.svelte.js +138 -0
- package/dist/components/table/types.d.ts +287 -0
- package/dist/components/table/types.js +1 -0
- package/dist/components/text-box/docs/llms.md +23 -17
- package/dist/components/textarea/docs/llms.md +16 -7
- package/dist/components/time-picker/docs/llms.md +20 -10
- package/dist/components/toggle-switch/docs/llms.md +13 -9
- package/dist/components/tooltip/docs/llms.md +24 -10
- package/dist/components/tree-view/docs/llms.md +53 -35
- package/dist/components/tree-view/tree-view-item-content.svelte +1 -1
- package/dist/components/tree-view/tree-view-item.svelte +3 -3
- package/dist/components/tree-view/tree-view.svelte +89 -93
- package/dist/index.d.ts +9 -0
- package/dist/index.js +11 -0
- package/dist/providers/fluentui-svelte/fluentui-svelte.svelte +15 -15
- package/package.json +1 -1
|
@@ -16,8 +16,14 @@
|
|
|
16
16
|
...attributes
|
|
17
17
|
}: ListViewProps<Tag> = $props();
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
/**
|
|
20
|
+
* The tag the invariant rules over. The markup renders it through here, so it is checked
|
|
21
|
+
* during SSR and on every prop update rather than only once on mount.
|
|
22
|
+
*/
|
|
23
|
+
const _as = $derived.by(() => {
|
|
24
|
+
if (!TAG.includes(as)) throw new Error(`Invalid tag: ${as}. Must be one of ${TAG.join(', ')}`);
|
|
25
|
+
return as;
|
|
26
|
+
});
|
|
21
27
|
|
|
22
28
|
const ROLE = $derived(getRole(as, selectionMode, navigationMode));
|
|
23
29
|
|
|
@@ -44,76 +50,75 @@
|
|
|
44
50
|
disabled: boolean;
|
|
45
51
|
}[] = $state([]);
|
|
46
52
|
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const _state: ListViewContext['state'] = {
|
|
52
|
-
get selectedItems() {
|
|
53
|
-
return selectedItems;
|
|
54
|
-
},
|
|
55
|
-
set selectedItems(v) {
|
|
56
|
-
selectedItems = v;
|
|
57
|
-
},
|
|
58
|
-
get anchorIndex() {
|
|
59
|
-
return anchorIndex;
|
|
60
|
-
},
|
|
61
|
-
set anchorIndex(v) {
|
|
62
|
-
anchorIndex = v;
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
let methods: ListViewContext['methods'] = {
|
|
67
|
-
handleSelection: (e: MouseEvent, value: string) => {
|
|
68
|
-
if (selectionMode === 'none') return;
|
|
69
|
-
|
|
70
|
-
const itemIndex = items.findIndex((item) => item.value === value);
|
|
71
|
-
if (itemIndex === -1) return;
|
|
72
|
-
|
|
73
|
-
const item = items[itemIndex];
|
|
74
|
-
if (item.disabled) return;
|
|
75
|
-
|
|
76
|
-
if (selectionMode === 'extended' && e.shiftKey && anchorIndex !== null) {
|
|
77
|
-
const start = Math.min(anchorIndex, itemIndex);
|
|
78
|
-
const end = Math.max(anchorIndex, itemIndex);
|
|
79
|
-
const rangeValues = items
|
|
80
|
-
.slice(start, end + 1)
|
|
81
|
-
.filter((i) => !i.disabled)
|
|
82
|
-
.map((i) => i.value);
|
|
83
|
-
const newSelectedItems = Array.from(new Set([..._state.selectedItems, ...rangeValues]));
|
|
84
|
-
_state.selectedItems = newSelectedItems;
|
|
85
|
-
} else if (MULTISELECTABLE && (e.ctrlKey || e.metaKey)) {
|
|
86
|
-
_state.selectedItems = _state.selectedItems.includes(value)
|
|
87
|
-
? _state.selectedItems.filter((v) => v !== value)
|
|
88
|
-
: [..._state.selectedItems, value];
|
|
89
|
-
_state.anchorIndex = itemIndex;
|
|
90
|
-
} else {
|
|
91
|
-
_state.selectedItems = [value];
|
|
92
|
-
_state.anchorIndex = itemIndex;
|
|
53
|
+
const CONTEXT: ListViewContext = $state({
|
|
54
|
+
config: {
|
|
55
|
+
get shape() {
|
|
56
|
+
return shape;
|
|
93
57
|
}
|
|
94
|
-
onSelectionChange?.(e, _state.selectedItems);
|
|
95
58
|
},
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
59
|
+
state: {
|
|
60
|
+
get selectedItems() {
|
|
61
|
+
return selectedItems;
|
|
62
|
+
},
|
|
63
|
+
set selectedItems(v) {
|
|
64
|
+
selectedItems = v;
|
|
65
|
+
},
|
|
66
|
+
get anchorIndex() {
|
|
67
|
+
return anchorIndex;
|
|
68
|
+
},
|
|
69
|
+
set anchorIndex(v) {
|
|
70
|
+
anchorIndex = v;
|
|
71
|
+
}
|
|
101
72
|
},
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
73
|
+
events: null,
|
|
74
|
+
methods: {
|
|
75
|
+
handleSelection: (e: MouseEvent, value: string) => {
|
|
76
|
+
if (selectionMode === 'none') return;
|
|
77
|
+
|
|
78
|
+
const itemIndex = items.findIndex((item) => item.value === value);
|
|
79
|
+
if (itemIndex === -1) return;
|
|
80
|
+
|
|
81
|
+
const item = items[itemIndex];
|
|
82
|
+
if (item.disabled) return;
|
|
83
|
+
|
|
84
|
+
if (selectionMode === 'extended' && e.shiftKey && anchorIndex !== null) {
|
|
85
|
+
const start = Math.min(anchorIndex, itemIndex);
|
|
86
|
+
const end = Math.max(anchorIndex, itemIndex);
|
|
87
|
+
const rangeValues = items
|
|
88
|
+
.slice(start, end + 1)
|
|
89
|
+
.filter((i) => !i.disabled)
|
|
90
|
+
.map((i) => i.value);
|
|
91
|
+
selectedItems = Array.from(new Set([...selectedItems, ...rangeValues]));
|
|
92
|
+
} else if (MULTISELECTABLE && (e.ctrlKey || e.metaKey)) {
|
|
93
|
+
selectedItems = selectedItems.includes(value)
|
|
94
|
+
? selectedItems.filter((v) => v !== value)
|
|
95
|
+
: [...selectedItems, value];
|
|
96
|
+
anchorIndex = itemIndex;
|
|
97
|
+
} else {
|
|
98
|
+
selectedItems = [value];
|
|
99
|
+
anchorIndex = itemIndex;
|
|
100
|
+
}
|
|
101
|
+
onSelectionChange?.(e, selectedItems);
|
|
102
|
+
},
|
|
103
|
+
registerItem: (id: string, value: string, disabled: boolean) => {
|
|
104
|
+
items.push({ id, value, disabled });
|
|
105
|
+
},
|
|
106
|
+
unregisterItem: (id: string) => {
|
|
107
|
+
items = items.filter((item) => item.id !== id);
|
|
108
|
+
},
|
|
109
|
+
getChildrenRole: (_tag: 'li' | 'a' | 'div') => {
|
|
110
|
+
if (ROLE === 'grid') return 'row';
|
|
111
|
+
if (ROLE === 'listbox') return 'option';
|
|
112
|
+
return _tag !== 'li' ? 'listitem' : undefined;
|
|
113
|
+
}
|
|
106
114
|
}
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
// svelte-ignore state_referenced_locally
|
|
110
|
-
const CONTEXT: ListViewContext = { config, state: _state, events: null, methods };
|
|
115
|
+
});
|
|
111
116
|
|
|
112
117
|
setListViewContext(CONTEXT);
|
|
113
118
|
</script>
|
|
114
119
|
|
|
115
120
|
<svelte:element
|
|
116
|
-
this={
|
|
121
|
+
this={_as}
|
|
117
122
|
bind:this={ref as ListViewDOM[Tag]}
|
|
118
123
|
class="fs-list-view"
|
|
119
124
|
role={ROLE}
|
|
@@ -24,52 +24,57 @@
|
|
|
24
24
|
|
|
25
25
|
const { toggle, close } = context.methods;
|
|
26
26
|
|
|
27
|
-
const
|
|
27
|
+
const id = $derived(context.config.id);
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const debounced = useDebounce(async (e: MouseEvent) => {
|
|
32
|
-
if (disabled) return;
|
|
33
|
-
|
|
34
|
-
const { clientX, clientY } = e;
|
|
35
|
-
|
|
36
|
-
_state.ref = {
|
|
37
|
-
getBoundingClientRect() {
|
|
38
|
-
return {
|
|
39
|
-
width: 0,
|
|
40
|
-
height: 0,
|
|
41
|
-
x: clientX,
|
|
42
|
-
y: clientY,
|
|
43
|
-
top: clientY,
|
|
44
|
-
right: clientX,
|
|
45
|
-
bottom: clientY,
|
|
46
|
-
left: clientX
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
// Add event to check if user click outside the menu to close it
|
|
52
|
-
offClick ??= on(document, 'click', (e) => {
|
|
53
|
-
const clickTarget = e.target as HTMLElement;
|
|
29
|
+
const openingDelay = $derived(context.config.openingDelay);
|
|
54
30
|
|
|
55
|
-
|
|
56
|
-
_state.locked = false;
|
|
57
|
-
close(e);
|
|
58
|
-
offClick?.();
|
|
59
|
-
offClick = null;
|
|
60
|
-
}
|
|
61
|
-
});
|
|
31
|
+
let offClick: (() => void) | null = $state(null);
|
|
62
32
|
|
|
63
|
-
|
|
64
|
-
|
|
33
|
+
const debounced = useDebounce(
|
|
34
|
+
async (e: MouseEvent) => {
|
|
35
|
+
if (disabled) return;
|
|
36
|
+
|
|
37
|
+
const { clientX, clientY } = e;
|
|
38
|
+
|
|
39
|
+
_state.ref = {
|
|
40
|
+
getBoundingClientRect() {
|
|
41
|
+
return {
|
|
42
|
+
width: 0,
|
|
43
|
+
height: 0,
|
|
44
|
+
x: clientX,
|
|
45
|
+
y: clientY,
|
|
46
|
+
top: clientY,
|
|
47
|
+
right: clientX,
|
|
48
|
+
bottom: clientY,
|
|
49
|
+
left: clientX
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// Add event to check if user click outside the menu to close it
|
|
55
|
+
offClick ??= on(document, 'click', (e) => {
|
|
56
|
+
const clickTarget = e.target as HTMLElement;
|
|
57
|
+
|
|
58
|
+
if (!clickTarget.closest(`#fs-menu-popover-${id}`)) {
|
|
59
|
+
_state.locked = false;
|
|
60
|
+
close(e);
|
|
61
|
+
offClick?.();
|
|
62
|
+
offClick = null;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
65
|
|
|
66
|
-
// When requesting to open the context menu when is already open, we need to wait for the toggle to finish before allowing it to be toggled again
|
|
67
|
-
if (!_state.open) {
|
|
68
|
-
await tick();
|
|
69
66
|
_state.locked = !_state.locked;
|
|
70
67
|
toggle(e);
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
|
|
69
|
+
// When requesting to open the context menu when is already open, we need to wait for the toggle to finish before allowing it to be toggled again
|
|
70
|
+
if (!_state.open) {
|
|
71
|
+
await tick();
|
|
72
|
+
_state.locked = !_state.locked;
|
|
73
|
+
toggle(e);
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
() => openingDelay || 0
|
|
77
|
+
);
|
|
73
78
|
|
|
74
79
|
onMount(() => {
|
|
75
80
|
_state.ref ??= VIRTUAL_ELEMENT;
|
|
@@ -121,49 +121,78 @@ This variant of the `MenuTrigger` component allows you to create context menus t
|
|
|
121
121
|
|
|
122
122
|
## Component Props (Menu)
|
|
123
123
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
|
128
|
-
|
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
| `
|
|
133
|
-
| `
|
|
134
|
-
| `
|
|
135
|
-
| `
|
|
124
|
+
<!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
|
|
125
|
+
<!-- props:MenuProps -->
|
|
126
|
+
|
|
127
|
+
| Name | Type | Default | Description |
|
|
128
|
+
| ------------------------- | ------------------------------------------------------------- | ------- | -------------------------------------------------------------------------- |
|
|
129
|
+
| `positionConfig` | `ComputePositionConfig` | | The position configuration handed over to floating-ui. |
|
|
130
|
+
| `hasIcons` | `boolean` | | Reserves the room every item needs for an icon, so the labels line up. |
|
|
131
|
+
| `hasCheckmarks` | `boolean` | | Reserves the room every item needs for a checkmark, so the labels line up. |
|
|
132
|
+
| `open` | `boolean` | | Controls the open state of the menu. |
|
|
133
|
+
| `onOpenChange` | `(e: Event, open: boolean) => void` | | Called whenever the menu opens or closes. |
|
|
134
|
+
| `checkedValues` | `Record<string, string[]>` | `{}` | The checked values of the menu, grouped by the `name` of each item. |
|
|
135
|
+
| `onCheckedValueChange` | `(e: Event, checkedValues: Record<string, string[]>) => void` | | Called whenever a checkbox or radio item changes. |
|
|
136
|
+
| `openOnHover` | `boolean` | `false` | Opens the menu on hover instead of on click. |
|
|
137
|
+
| `openingDelay` | `number` | `0` | How long to wait, in milliseconds, before opening the menu. |
|
|
138
|
+
| `persistOnItemActivation` | `boolean` | `false` | Keeps the menu open after an item is activated. |
|
|
139
|
+
| `children` | `Snippet` | | The parts of the menu: a trigger and a popover. |
|
|
140
|
+
|
|
141
|
+
<!-- /props:MenuProps -->
|
|
136
142
|
|
|
137
143
|
## Component Props (MenuTrigger)
|
|
138
144
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
|
143
|
-
|
|
|
145
|
+
<!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
|
|
146
|
+
<!-- props:MenuTriggerProps -->
|
|
147
|
+
|
|
148
|
+
| Name | Type | Default | Description |
|
|
149
|
+
| ---------- | ------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------- |
|
|
150
|
+
| `disabled` | `boolean` | | Disables the user interaction. |
|
|
151
|
+
| `shape` | `'circular'` | `'rounded'` | `'square'` | | The trigger can be rounded, circular, or square. |
|
|
152
|
+
| `icon` | `Snippet` | `Component` | | An optional icon for the trigger. |
|
|
153
|
+
| `children` | `Snippet` | | A custom trigger. It receives the menu state and the props to spread on your own buttons. |
|
|
154
|
+
|
|
155
|
+
<!-- /props:MenuTriggerProps -->
|
|
144
156
|
|
|
145
157
|
## Component Props (MenuItem)
|
|
146
158
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
|
151
|
-
|
|
|
152
|
-
| `
|
|
153
|
-
| `
|
|
154
|
-
| `
|
|
159
|
+
<!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
|
|
160
|
+
<!-- props:MenuItemProps -->
|
|
161
|
+
|
|
162
|
+
| Name | Type | Default | Description |
|
|
163
|
+
| ------------------ | ---------------------------- | ------- | ------------------------------------------------ |
|
|
164
|
+
| `icon` | `Snippet` | `Component` | | The icon to display before the label. |
|
|
165
|
+
| `secondaryContent` | `string` | | Right aligned text, usually a keyboard shortcut. |
|
|
166
|
+
| `disabled` | `boolean` | | Disables the user interaction. |
|
|
167
|
+
| `subText` | `string` | | A second line of text below the label. |
|
|
168
|
+
| `href` | `string` | | Renders the item as a link pointing to this URL. |
|
|
169
|
+
|
|
170
|
+
<!-- /props:MenuItemProps -->
|
|
155
171
|
|
|
156
172
|
## Component Props (MenuItemCheckbox/Switch/Radio)
|
|
157
173
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
|
162
|
-
|
|
|
163
|
-
| `
|
|
174
|
+
<!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
|
|
175
|
+
<!-- props:MenuItemActionableProps -->
|
|
176
|
+
|
|
177
|
+
| Name | Type | Default | Description |
|
|
178
|
+
| -------------------------------------- | --------- | ------- | ------------------------------------------------------------------------------------------ |
|
|
179
|
+
| `checked` _bindable_ | `boolean` | | Whether the item is checked. |
|
|
180
|
+
| `value` | `string` | `id` | The value reported to the menu when the item is checked. Falls back to the id of the item. |
|
|
181
|
+
| `name` | `string` | `id` | The group of items this one belongs to. Falls back to the id of the item. |
|
|
182
|
+
| `MenuItemProps` without `href` | | | |
|
|
183
|
+
| `ComponentProps<typeof Button<'div'>>` | | | |
|
|
184
|
+
|
|
185
|
+
<!-- /props:MenuItemActionableProps -->
|
|
164
186
|
|
|
165
187
|
## Component Props (MenuGroup)
|
|
166
188
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
189
|
+
<!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
|
|
190
|
+
<!-- props:MenuGroupProps -->
|
|
191
|
+
|
|
192
|
+
| Name | Type | Default | Description |
|
|
193
|
+
| ---------------- | ---------------- | ------- | --------------------------------------- |
|
|
194
|
+
| `ref` _bindable_ | `HTMLDivElement` | | The DOM reference of the group element. |
|
|
195
|
+
| `header` | `string` | | The label of the group. |
|
|
196
|
+
| `children` | `Snippet` | | The items of the group. |
|
|
197
|
+
|
|
198
|
+
<!-- /props:MenuGroupProps -->
|
|
@@ -31,7 +31,9 @@
|
|
|
31
31
|
|
|
32
32
|
if (!context) throw new Error(`No MenuContext found for ${MENU_COMPONENT_NAME}.`);
|
|
33
33
|
|
|
34
|
-
const
|
|
34
|
+
const hasIcons = $derived(context.config.hasIcons);
|
|
35
|
+
|
|
36
|
+
const hasCheckmarks = $derived(context.config.hasCheckmarks);
|
|
35
37
|
|
|
36
38
|
const { toggleCheckbox } = context.methods;
|
|
37
39
|
|
|
@@ -31,7 +31,9 @@
|
|
|
31
31
|
|
|
32
32
|
if (!context) throw new Error(`No MenuContext found for ${MENU_COMPONENT_NAME}.`);
|
|
33
33
|
|
|
34
|
-
const
|
|
34
|
+
const hasIcons = $derived(context.config.hasIcons);
|
|
35
|
+
|
|
36
|
+
const persistOnItemActivation = $derived(context.config.persistOnItemActivation);
|
|
35
37
|
|
|
36
38
|
const { toggleRadio, toggle } = context.methods;
|
|
37
39
|
|
|
@@ -30,7 +30,9 @@
|
|
|
30
30
|
|
|
31
31
|
if (!context) throw new Error(`No MenuContext found for ${MENU_COMPONENT_NAME}.`);
|
|
32
32
|
|
|
33
|
-
const
|
|
33
|
+
const hasIcons = $derived(context.config.hasIcons);
|
|
34
|
+
|
|
35
|
+
const hasCheckmarks = $derived(context.config.hasCheckmarks);
|
|
34
36
|
|
|
35
37
|
const { toggleCheckbox } = context.methods;
|
|
36
38
|
|
|
@@ -29,7 +29,11 @@
|
|
|
29
29
|
|
|
30
30
|
if (!context) throw new Error(`No MenuContext found for ${MENU_COMPONENT_NAME}.`);
|
|
31
31
|
|
|
32
|
-
const
|
|
32
|
+
const hasIcons = $derived(context.config.hasIcons);
|
|
33
|
+
|
|
34
|
+
const hasCheckmarks = $derived(context.config.hasCheckmarks);
|
|
35
|
+
|
|
36
|
+
const persistOnItemActivation = $derived(context.config.persistOnItemActivation);
|
|
33
37
|
|
|
34
38
|
const { toggle } = context.methods;
|
|
35
39
|
|
|
@@ -33,7 +33,15 @@
|
|
|
33
33
|
|
|
34
34
|
const reducedMotion = getReducedMotion();
|
|
35
35
|
|
|
36
|
-
const
|
|
36
|
+
const positionConfig = $derived(context.config.positionConfig);
|
|
37
|
+
|
|
38
|
+
const id = $derived(context.config.id);
|
|
39
|
+
|
|
40
|
+
const isSubMenu = $derived(context.config.isSubMenu);
|
|
41
|
+
|
|
42
|
+
const openOnHover = $derived(context.config.openOnHover);
|
|
43
|
+
|
|
44
|
+
const openingDelay = $derived(context.config.openingDelay);
|
|
37
45
|
|
|
38
46
|
const { close } = context.methods;
|
|
39
47
|
|
|
@@ -56,16 +64,19 @@
|
|
|
56
64
|
|
|
57
65
|
let element: HTMLElement | null = $state(null);
|
|
58
66
|
|
|
59
|
-
const debounced = useDebounce(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
const debounced = useDebounce(
|
|
68
|
+
(e: MouseEvent) => {
|
|
69
|
+
// Where the mouse is moving to
|
|
70
|
+
const to = e.relatedTarget as HTMLElement | null;
|
|
71
|
+
const isPopover = to?.id === `fs-menu-popover-${id}` || to?.closest(`#fs-menu-popover-${id}`);
|
|
72
|
+
const isTrigger =
|
|
73
|
+
to?.id === `fs-${isSubMenu ? 'submenu' : 'menu'}-trigger-${id}` ||
|
|
74
|
+
to?.closest(`#fs-${isSubMenu ? 'submenu' : 'menu'}-trigger-${id}`);
|
|
66
75
|
|
|
67
|
-
|
|
68
|
-
|
|
76
|
+
if (to && !isPopover && !isTrigger && !_state.locked) close(e);
|
|
77
|
+
},
|
|
78
|
+
() => openingDelay || 0
|
|
79
|
+
);
|
|
69
80
|
|
|
70
81
|
$effect.pre(() => {
|
|
71
82
|
duration = getCSSDuration('--fs-normal-duration') || 333;
|
|
@@ -19,20 +19,33 @@
|
|
|
19
19
|
|
|
20
20
|
const { toggle, open, close } = context.methods;
|
|
21
21
|
|
|
22
|
-
const
|
|
22
|
+
const id = $derived(context.config.id);
|
|
23
|
+
|
|
24
|
+
const isSubMenu = $derived(context.config.isSubMenu);
|
|
25
|
+
|
|
26
|
+
const openOnHover = $derived(context.config.openOnHover);
|
|
27
|
+
|
|
28
|
+
const openingDelay = $derived(context.config.openingDelay);
|
|
29
|
+
|
|
30
|
+
const parentHasCheckmarks = $derived(context.config.parentHasCheckmarks);
|
|
31
|
+
|
|
32
|
+
const parentHasIcons = $derived(context.config.parentHasIcons);
|
|
23
33
|
|
|
24
34
|
const paddingLeft = $derived(1.25 * (+!!(parentHasIcons && !Icon) + +!!parentHasCheckmarks) + 0.9);
|
|
25
35
|
|
|
26
|
-
const debounced = useDebounce(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
36
|
+
const debounced = useDebounce(
|
|
37
|
+
(e: MouseEvent) => {
|
|
38
|
+
if (e.type === 'mouseover' && !_state.open) {
|
|
39
|
+
return open(e);
|
|
40
|
+
}
|
|
30
41
|
|
|
31
|
-
|
|
32
|
-
|
|
42
|
+
// Where the mouse is moving to
|
|
43
|
+
const to = e.relatedTarget as HTMLElement | null;
|
|
33
44
|
|
|
34
|
-
|
|
35
|
-
|
|
45
|
+
if (to && !to.closest(`#fs-menu-popover-${id}`) && to.parentElement !== _state.ref && !_state.locked) close(e);
|
|
46
|
+
},
|
|
47
|
+
() => openingDelay || 0
|
|
48
|
+
);
|
|
36
49
|
|
|
37
50
|
onMount(() => {
|
|
38
51
|
const off = on(document, 'click', async (e: MouseEvent) => {
|