@sveltia/ui 0.78.4 → 0.79.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.
Files changed (181) hide show
  1. package/dist/components/alert/alert-content.svelte +51 -0
  2. package/dist/components/alert/alert-content.svelte.d.ts +39 -0
  3. package/dist/components/alert/alert.d.ts +3 -0
  4. package/dist/components/alert/alert.js +21 -0
  5. package/dist/components/alert/alert.svelte +6 -30
  6. package/dist/components/alert/infobar.svelte +7 -21
  7. package/dist/components/alert/infobar.svelte.d.ts +2 -2
  8. package/dist/components/button/button.svelte +11 -11
  9. package/dist/components/button/button.svelte.d.ts +2 -2
  10. package/dist/components/button/select-button.svelte +1 -1
  11. package/dist/components/button/select-button.svelte.d.ts +2 -2
  12. package/dist/components/button/split-button.svelte +1 -1
  13. package/dist/components/button/split-button.svelte.d.ts +3 -3
  14. package/dist/components/calendar/calendar.d.ts +2 -0
  15. package/dist/components/calendar/calendar.js +34 -0
  16. package/dist/components/calendar/calendar.svelte +49 -5
  17. package/dist/components/checkbox/checkbox.svelte +11 -4
  18. package/dist/components/checkbox/checkbox.svelte.d.ts +2 -2
  19. package/dist/components/dialog/alert-dialog.svelte +1 -1
  20. package/dist/components/dialog/alert-dialog.svelte.d.ts +2 -2
  21. package/dist/components/dialog/confirmation-dialog.svelte +1 -1
  22. package/dist/components/dialog/confirmation-dialog.svelte.d.ts +2 -2
  23. package/dist/components/dialog/dialog.svelte +8 -18
  24. package/dist/components/dialog/dialog.svelte.d.ts +2 -2
  25. package/dist/components/dialog/modal-close-button.svelte +50 -0
  26. package/dist/components/dialog/modal-close-button.svelte.d.ts +43 -0
  27. package/dist/components/dialog/prompt-dialog.svelte +1 -1
  28. package/dist/components/dialog/prompt-dialog.svelte.d.ts +4 -4
  29. package/dist/components/disclosure/disclosure.svelte +1 -1
  30. package/dist/components/drawer/drawer.svelte +12 -34
  31. package/dist/components/drawer/drawer.svelte.d.ts +1 -1
  32. package/dist/components/emoji/caret.d.ts +1 -1
  33. package/dist/components/emoji/caret.js +1 -1
  34. package/dist/components/emoji/emoji-suggestions.svelte +1 -1
  35. package/dist/components/emoji/emoji-suggestions.svelte.d.ts +3 -3
  36. package/dist/components/emoji/emoji.d.ts +2 -2
  37. package/dist/components/emoji/emoji.js +1 -1
  38. package/dist/components/emoji/position.d.ts +2 -2
  39. package/dist/components/emoji/position.js +1 -1
  40. package/dist/components/grid/grid-body.svelte +6 -2
  41. package/dist/components/grid/grid-cell.svelte +3 -9
  42. package/dist/components/grid/grid-col-header.svelte +3 -9
  43. package/dist/components/grid/grid-foot.svelte +4 -11
  44. package/dist/components/grid/grid-head.svelte +4 -11
  45. package/dist/components/grid/grid-row-header.svelte +3 -10
  46. package/dist/components/grid/grid-row.svelte +3 -16
  47. package/dist/components/listbox/listbox.svelte +1 -1
  48. package/dist/components/listbox/listbox.svelte.d.ts +1 -1
  49. package/dist/components/listbox/option.svelte +1 -1
  50. package/dist/components/listbox/option.svelte.d.ts +2 -2
  51. package/dist/components/menu/menu-button.svelte +2 -2
  52. package/dist/components/menu/menu-button.svelte.d.ts +4 -4
  53. package/dist/components/menu/menu-item-checkable.svelte +71 -0
  54. package/dist/components/menu/menu-item-checkable.svelte.d.ts +25 -0
  55. package/dist/components/menu/menu-item-checkbox.svelte +3 -36
  56. package/dist/components/menu/menu-item-checkbox.svelte.d.ts +3 -3
  57. package/dist/components/menu/menu-item-group.svelte +8 -5
  58. package/dist/components/menu/menu-item-group.svelte.d.ts +9 -1
  59. package/dist/components/menu/menu-item-radio.svelte +3 -36
  60. package/dist/components/menu/menu-item-radio.svelte.d.ts +3 -3
  61. package/dist/components/menu/menu-item.svelte +22 -6
  62. package/dist/components/menu/menu-item.svelte.d.ts +4 -4
  63. package/dist/components/radio/radio.svelte +12 -1
  64. package/dist/components/resizable-pane/resizable-handle.svelte +14 -18
  65. package/dist/components/resizable-pane/resizable-pane-group.svelte +9 -6
  66. package/dist/components/resizable-pane/resizable-pane.svelte +4 -4
  67. package/dist/components/resizable-pane/resizable-pane.svelte.d.ts +7 -6
  68. package/dist/components/resizable-pane/sizing.d.ts +5 -4
  69. package/dist/components/resizable-pane/sizing.js +84 -25
  70. package/dist/components/scroll/infinite-scroll.svelte +16 -21
  71. package/dist/components/select/combobox.svelte +43 -52
  72. package/dist/components/select/combobox.svelte.d.ts +2 -2
  73. package/dist/components/select/select-tags.svelte +7 -1
  74. package/dist/components/select/select.svelte +2 -22
  75. package/dist/components/select/select.svelte.d.ts +1 -1
  76. package/dist/components/slider/slider.d.ts +6 -0
  77. package/dist/components/slider/slider.js +55 -2
  78. package/dist/components/slider/slider.svelte +63 -32
  79. package/dist/components/table/table-cell.svelte +3 -9
  80. package/dist/components/table/table-col-header.svelte +3 -9
  81. package/dist/components/table/table-foot.svelte +4 -11
  82. package/dist/components/table/table-head.svelte +4 -11
  83. package/dist/components/table/table-part.svelte +69 -0
  84. package/dist/components/table/table-part.svelte.d.ts +48 -0
  85. package/dist/components/table/table-row-header.svelte +3 -10
  86. package/dist/components/table/table-row.svelte +3 -10
  87. package/dist/components/tabs/tab-list.svelte +12 -0
  88. package/dist/components/tabs/tab.svelte +1 -1
  89. package/dist/components/tabs/tab.svelte.d.ts +2 -2
  90. package/dist/components/text-editor/constants.d.ts +5 -5
  91. package/dist/components/text-editor/constants.js +1 -1
  92. package/dist/components/text-editor/core.d.ts +4 -5
  93. package/dist/components/text-editor/core.js +372 -285
  94. package/dist/components/text-editor/emoji-autocomplete.svelte +1 -1
  95. package/dist/components/text-editor/lexical-root.svelte +1 -1
  96. package/dist/components/text-editor/raw-markdown.d.ts +6 -33
  97. package/dist/components/text-editor/raw-markdown.js +63 -8
  98. package/dist/components/text-editor/shiki/facade.d.ts +1 -1
  99. package/dist/components/text-editor/shiki/facade.js +63 -48
  100. package/dist/components/text-editor/shiki/generated.d.ts +1 -1
  101. package/dist/components/text-editor/shiki/generated.js +1 -1
  102. package/dist/components/text-editor/shiki/highlighter.d.ts +6 -1
  103. package/dist/components/text-editor/shiki/highlighter.js +3 -4
  104. package/dist/components/text-editor/shiki/loader.d.ts +1 -1
  105. package/dist/components/text-editor/shiki/loader.js +1 -1
  106. package/dist/components/text-editor/shiki/version.d.ts +1 -1
  107. package/dist/components/text-editor/shiki/version.js +1 -1
  108. package/dist/components/text-editor/store.svelte.d.ts +1 -1
  109. package/dist/components/text-editor/store.svelte.js +5 -2
  110. package/dist/components/text-editor/text-editor.svelte +2 -2
  111. package/dist/components/text-editor/text-editor.svelte.d.ts +3 -3
  112. package/dist/components/text-editor/toolbar/code-language-switcher.svelte +24 -16
  113. package/dist/components/text-editor/toolbar/format-text-button.svelte +7 -31
  114. package/dist/components/text-editor/toolbar/format-text-button.svelte.d.ts +1 -1
  115. package/dist/components/text-editor/toolbar/insert-component.d.ts +3 -0
  116. package/dist/components/text-editor/toolbar/insert-component.js +34 -0
  117. package/dist/components/text-editor/toolbar/insert-item-button.svelte +4 -24
  118. package/dist/components/text-editor/toolbar/insert-item-button.svelte.d.ts +1 -1
  119. package/dist/components/text-editor/toolbar/insert-link-button.svelte +9 -25
  120. package/dist/components/text-editor/toolbar/insert-menu-button.svelte +4 -24
  121. package/dist/components/text-editor/toolbar/insert-menu-button.svelte.d.ts +1 -1
  122. package/dist/components/text-editor/toolbar/text-editor-toolbar.svelte +1 -1
  123. package/dist/components/text-editor/toolbar/toggle-block-menu-item.svelte +31 -35
  124. package/dist/components/text-editor/toolbar/toggle-block-menu-item.svelte.d.ts +1 -1
  125. package/dist/components/text-editor/toolbar/toolbar-wrapper.svelte +0 -10
  126. package/dist/components/text-editor/toolbar/toolbar-wrapper.svelte.d.ts +1 -11
  127. package/dist/components/text-editor/transformers/table.d.ts +0 -1
  128. package/dist/components/text-editor/transformers/table.js +1 -2
  129. package/dist/components/text-field/emoji-autocomplete.svelte +1 -1
  130. package/dist/components/text-field/masked-input.svelte +179 -0
  131. package/dist/components/text-field/masked-input.svelte.d.ts +42 -0
  132. package/dist/components/text-field/number-input.js +7 -1
  133. package/dist/components/text-field/number-input.svelte +13 -5
  134. package/dist/components/text-field/number-input.svelte.d.ts +3 -3
  135. package/dist/components/text-field/password-input.svelte +3 -116
  136. package/dist/components/text-field/password-input.svelte.d.ts +3 -3
  137. package/dist/components/text-field/search-bar.svelte +1 -1
  138. package/dist/components/text-field/search-bar.svelte.d.ts +3 -3
  139. package/dist/components/text-field/secret-input.svelte +3 -119
  140. package/dist/components/text-field/secret-input.svelte.d.ts +3 -3
  141. package/dist/components/text-field/text-area.svelte +1 -1
  142. package/dist/components/text-field/text-area.svelte.d.ts +3 -3
  143. package/dist/components/text-field/text-input.svelte +1 -1
  144. package/dist/components/text-field/text-input.svelte.d.ts +3 -3
  145. package/dist/components/toast/toast.svelte +11 -20
  146. package/dist/components/toast/toast.svelte.d.ts +1 -1
  147. package/dist/components/tree/tree-item.svelte +1 -1
  148. package/dist/components/tree/tree-item.svelte.d.ts +1 -1
  149. package/dist/components/tree/tree.svelte +1 -1
  150. package/dist/components/tree/tree.svelte.d.ts +1 -1
  151. package/dist/components/util/font-links.svelte +1 -0
  152. package/dist/components/util/modal.svelte +37 -1
  153. package/dist/components/util/modal.svelte.d.ts +1 -1
  154. package/dist/components/util/popup.svelte +2 -5
  155. package/dist/components/util/popup.svelte.d.ts +2 -2
  156. package/dist/components/util/visibility-observer.svelte +1 -0
  157. package/dist/locales/ar.yaml +1 -1
  158. package/dist/locales/sk.yaml +136 -0
  159. package/dist/services/group.svelte.d.ts +10 -1
  160. package/dist/services/group.svelte.js +361 -251
  161. package/dist/services/navigation.d.ts +19 -0
  162. package/dist/services/navigation.js +84 -0
  163. package/dist/services/popup-position.d.ts +90 -0
  164. package/dist/services/popup-position.js +275 -0
  165. package/dist/services/popup.svelte.d.ts +16 -17
  166. package/dist/services/popup.svelte.js +25 -169
  167. package/dist/services/scroll.d.ts +1 -0
  168. package/dist/services/scroll.js +17 -0
  169. package/dist/services/select.svelte.d.ts +2 -2
  170. package/dist/services/select.svelte.js +1 -1
  171. package/dist/services/text.d.ts +2 -0
  172. package/dist/services/text.js +28 -0
  173. package/dist/services/tree.svelte.d.ts +3 -11
  174. package/dist/services/tree.svelte.js +35 -77
  175. package/dist/services/type-ahead.d.ts +0 -4
  176. package/dist/services/type-ahead.js +3 -1
  177. package/dist/services/widget.d.ts +8 -0
  178. package/dist/services/widget.js +39 -0
  179. package/dist/shiki-engine.js +15 -15
  180. package/dist/styles/mixins.scss +126 -0
  181. package/package.json +24 -20
@@ -9,10 +9,10 @@ type MenuButton = {
9
9
  * A button to open a `<Menu>` widget.
10
10
  * @see https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/
11
11
  */
12
- declare const MenuButton: import("svelte").Component<ButtonProps & import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").PointerEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & {
12
+ declare const MenuButton: import("svelte").Component<ButtonProps & import("../../typedefs.js").KeyboardEventHandlers & import("../../typedefs.js").MouseEventHandlers & import("../../typedefs.js").PointerEventHandlers & import("../../typedefs.js").FocusEventHandlers & import("../../typedefs.js").DragEventHandlers & {
13
13
  /**
14
14
  * The base element of {@link popupPosition}.
15
- * If omitted, this will be {@link buttonComponent}.
15
+ * If omitted, this will be the button itself.
16
16
  */
17
17
  popupPositionBaseElement?: HTMLElement | undefined;
18
18
  } & Record<string, any>, {
@@ -21,8 +21,8 @@ declare const MenuButton: import("svelte").Component<ButtonProps & import("../..
21
21
  type Props = {
22
22
  /**
23
23
  * The base element of {@link popupPosition}.
24
- * If omitted, this will be {@link buttonComponent}.
24
+ * If omitted, this will be the button itself.
25
25
  */
26
26
  popupPositionBaseElement?: HTMLElement | undefined;
27
27
  };
28
- import type { ButtonProps } from '../../typedefs';
28
+ import type { ButtonProps } from '../../typedefs.js';
@@ -0,0 +1,71 @@
1
+ <!--
2
+ @component
3
+ The checkable menu item behind `<MenuItemCheckbox>` and `<MenuItemRadio>`, which only differ in
4
+ their role. Internal; not exported.
5
+ @see https://w3c.github.io/aria/#menuitemcheckbox
6
+ @see https://w3c.github.io/aria/#menuitemradio
7
+ -->
8
+ <script>
9
+ import Icon from '../icon/icon.svelte';
10
+ import MenuItem from './menu-item.svelte';
11
+
12
+ /**
13
+ * @import { ButtonProps, CommonEventHandlers, MenuItemProps } from '../../typedefs.js';
14
+ */
15
+
16
+ /**
17
+ * @typedef {object} Props
18
+ * @property {'menuitemcheckbox' | 'menuitemradio'} role The `role` attribute on the item.
19
+ */
20
+
21
+ /**
22
+ * @type {ButtonProps & MenuItemProps & CommonEventHandlers & Props & Record<string, any>}
23
+ */
24
+ let {
25
+ /* eslint-disable prefer-const */
26
+ role,
27
+ checked = $bindable(),
28
+ class: className,
29
+ hidden = false,
30
+ disabled = false,
31
+ label = '',
32
+ children: _children,
33
+ startIcon: _startIcon,
34
+ onChange,
35
+ ...restProps
36
+ /* eslint-enable prefer-const */
37
+ } = $props();
38
+
39
+ /**
40
+ * The class name for the role, e.g. `menu-item-checkbox`.
41
+ */
42
+ const roleClass = $derived(role === 'menuitemradio' ? 'menu-item-radio' : 'menu-item-checkbox');
43
+ </script>
44
+
45
+ <MenuItem
46
+ {...restProps}
47
+ {role}
48
+ class="sui {roleClass} {className}"
49
+ {label}
50
+ {hidden}
51
+ {disabled}
52
+ aria-checked={checked}
53
+ onChange={(event) => {
54
+ // Update the state first, so the handler sees the new value through a bound `checked`
55
+ checked = event.detail.checked;
56
+ onChange?.(event);
57
+ }}
58
+ >
59
+ {#snippet startIcon()}
60
+ {@render _startIcon?.()}
61
+ {/snippet}
62
+ <!-- eslint-disable-next-line svelte/no-useless-children-snippet -->
63
+ {#snippet children()}
64
+ {@render _children?.()}
65
+ {/snippet}
66
+ {#snippet endIcon()}
67
+ {#if checked}
68
+ <Icon name="check" />
69
+ {/if}
70
+ {/snippet}
71
+ </MenuItem>
@@ -0,0 +1,25 @@
1
+ export default MenuItemCheckable;
2
+ type MenuItemCheckable = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<ButtonProps & MenuItemProps & KeyboardEventHandlers & MouseEventHandlers & PointerEventHandlers & FocusEventHandlers & DragEventHandlers & Props & Record<string, any>>): void;
5
+ };
6
+ /**
7
+ * The checkable menu item behind `<MenuItemCheckbox>` and `<MenuItemRadio>`, which only differ in
8
+ * their role. Internal; not exported.
9
+ * @see https://w3c.github.io/aria/#menuitemcheckbox
10
+ * @see https://w3c.github.io/aria/#menuitemradio
11
+ */
12
+ declare const MenuItemCheckable: import("svelte").Component<ButtonProps & MenuItemProps & import("../../typedefs.js").KeyboardEventHandlers & import("../../typedefs.js").MouseEventHandlers & import("../../typedefs.js").PointerEventHandlers & import("../../typedefs.js").FocusEventHandlers & import("../../typedefs.js").DragEventHandlers & {
13
+ /**
14
+ * The `role` attribute on the item.
15
+ */
16
+ role: "menuitemcheckbox" | "menuitemradio";
17
+ } & Record<string, any>, {}, "checked">;
18
+ type Props = {
19
+ /**
20
+ * The `role` attribute on the item.
21
+ */
22
+ role: "menuitemcheckbox" | "menuitemradio";
23
+ };
24
+ import type { ButtonProps } from '../../typedefs.js';
25
+ import type { MenuItemProps } from '../../typedefs.js';
@@ -4,11 +4,10 @@
4
4
  @see https://w3c.github.io/aria/#menuitemcheckbox
5
5
  -->
6
6
  <script>
7
- import Icon from '../icon/icon.svelte';
8
- import MenuItem from './menu-item.svelte';
7
+ import MenuItemCheckable from './menu-item-checkable.svelte';
9
8
 
10
9
  /**
11
- * @import { ButtonProps, CommonEventHandlers, MenuItemProps } from '../../typedefs';
10
+ * @import { ButtonProps, CommonEventHandlers, MenuItemProps } from '../../typedefs.js';
12
11
  */
13
12
 
14
13
  /**
@@ -17,41 +16,9 @@
17
16
  let {
18
17
  /* eslint-disable prefer-const */
19
18
  checked = $bindable(),
20
- class: className,
21
- hidden = false,
22
- disabled = false,
23
- label = '',
24
- children: _children,
25
- startIcon: _startIcon,
26
- onChange,
27
19
  ...restProps
28
20
  /* eslint-enable prefer-const */
29
21
  } = $props();
30
22
  </script>
31
23
 
32
- <MenuItem
33
- {...restProps}
34
- role="menuitemcheckbox"
35
- class="sui menu-item-checkbox {className}"
36
- {label}
37
- {hidden}
38
- {disabled}
39
- aria-checked={checked}
40
- onChange={(event) => {
41
- onChange?.(event);
42
- checked = event.detail.checked;
43
- }}
44
- >
45
- {#snippet startIcon()}
46
- {@render _startIcon?.()}
47
- {/snippet}
48
- <!-- eslint-disable-next-line svelte/no-useless-children-snippet -->
49
- {#snippet children()}
50
- {@render _children?.()}
51
- {/snippet}
52
- {#snippet endIcon()}
53
- {#if checked}
54
- <Icon name="check" />
55
- {/if}
56
- {/snippet}
57
- </MenuItem>
24
+ <MenuItemCheckable {...restProps} bind:checked role="menuitemcheckbox" />
@@ -7,6 +7,6 @@ type MenuItemCheckbox = {
7
7
  * A menu item widget with a checkbox.
8
8
  * @see https://w3c.github.io/aria/#menuitemcheckbox
9
9
  */
10
- declare const MenuItemCheckbox: import("svelte").Component<ButtonProps & MenuItemProps & import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").PointerEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & Record<string, any>, {}, "checked">;
11
- import type { ButtonProps } from '../../typedefs';
12
- import type { MenuItemProps } from '../../typedefs';
10
+ declare const MenuItemCheckbox: import("svelte").Component<ButtonProps & MenuItemProps & import("../../typedefs.js").KeyboardEventHandlers & import("../../typedefs.js").MouseEventHandlers & import("../../typedefs.js").PointerEventHandlers & import("../../typedefs.js").FocusEventHandlers & import("../../typedefs.js").DragEventHandlers & Record<string, any>, {}, "checked">;
11
+ import type { ButtonProps } from '../../typedefs.js';
12
+ import type { MenuItemProps } from '../../typedefs.js';
@@ -6,7 +6,7 @@
6
6
  import { _ } from '@sveltia/i18n';
7
7
 
8
8
  /**
9
- * @import { CommonEventHandlers } from '../../typedefs';
9
+ * @import { CommonEventHandlers } from '../../typedefs.js';
10
10
  */
11
11
 
12
12
  /**
@@ -16,7 +16,8 @@
16
16
  * attribute.
17
17
  * @property {boolean} [disabled] Whether to disable the widget. An alias of the `aria-disabled`
18
18
  * attribute.
19
- * @property {string} [title] Text label displayed above the group items.
19
+ * @property {string} [label] Text label displayed above the group items.
20
+ * @property {string} [title] Deprecated: use `label` instead.
20
21
  */
21
22
 
22
23
  /**
@@ -27,6 +28,7 @@
27
28
  class: className,
28
29
  hidden = false,
29
30
  disabled = false,
31
+ label = '',
30
32
  title = '',
31
33
  children,
32
34
  ...restProps
@@ -34,6 +36,7 @@
34
36
  } = $props();
35
37
 
36
38
  const id = $props.id();
39
+ const groupLabel = $derived(label || title);
37
40
  </script>
38
41
 
39
42
  <div
@@ -44,11 +47,11 @@
44
47
  {hidden}
45
48
  aria-hidden={hidden}
46
49
  aria-disabled={disabled}
47
- aria-labelledby={title ? `${id}-title` : undefined}
50
+ aria-labelledby={groupLabel ? `${id}-title` : undefined}
48
51
  aria-roledescription={_('_sui.role_descriptions.menu_item_group')}
49
52
  >
50
- {#if title}
51
- <div role="none" class="title" id="{id}-title">{title}</div>
53
+ {#if groupLabel}
54
+ <div role="none" class="title" id="{id}-title">{groupLabel}</div>
52
55
  {/if}
53
56
  <div role="none" class="inner" inert={disabled}>
54
57
  {@render children?.()}
@@ -4,7 +4,7 @@ type MenuItemGroup = {
4
4
  $set?(props: Partial<KeyboardEventHandlers & MouseEventHandlers & PointerEventHandlers & FocusEventHandlers & DragEventHandlers & Props & Record<string, any>>): void;
5
5
  };
6
6
  /** A menu item group. */
7
- declare const MenuItemGroup: import("svelte").Component<import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").PointerEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & {
7
+ declare const MenuItemGroup: import("svelte").Component<import("../../typedefs.js").KeyboardEventHandlers & import("../../typedefs.js").MouseEventHandlers & import("../../typedefs.js").PointerEventHandlers & import("../../typedefs.js").FocusEventHandlers & import("../../typedefs.js").DragEventHandlers & {
8
8
  /**
9
9
  * The `class` attribute on the wrapper element.
10
10
  */
@@ -22,6 +22,10 @@ declare const MenuItemGroup: import("svelte").Component<import("../../typedefs")
22
22
  /**
23
23
  * Text label displayed above the group items.
24
24
  */
25
+ label?: string | undefined;
26
+ /**
27
+ * Deprecated: use `label` instead.
28
+ */
25
29
  title?: string | undefined;
26
30
  } & Record<string, any>, {}, "">;
27
31
  type Props = {
@@ -42,5 +46,9 @@ type Props = {
42
46
  /**
43
47
  * Text label displayed above the group items.
44
48
  */
49
+ label?: string | undefined;
50
+ /**
51
+ * Deprecated: use `label` instead.
52
+ */
45
53
  title?: string | undefined;
46
54
  };
@@ -5,11 +5,10 @@
5
5
  @see https://w3c.github.io/aria/#menuitemradio
6
6
  -->
7
7
  <script>
8
- import Icon from '../icon/icon.svelte';
9
- import MenuItem from './menu-item.svelte';
8
+ import MenuItemCheckable from './menu-item-checkable.svelte';
10
9
 
11
10
  /**
12
- * @import { ButtonProps, CommonEventHandlers, MenuItemProps } from '../../typedefs';
11
+ * @import { ButtonProps, CommonEventHandlers, MenuItemProps } from '../../typedefs.js';
13
12
  */
14
13
 
15
14
  /**
@@ -18,41 +17,9 @@
18
17
  let {
19
18
  /* eslint-disable prefer-const */
20
19
  checked = $bindable(),
21
- class: className,
22
- hidden = false,
23
- disabled = false,
24
- label = '',
25
- children: _children,
26
- startIcon: _startIcon,
27
- onChange,
28
20
  ...restProps
29
21
  /* eslint-enable prefer-const */
30
22
  } = $props();
31
23
  </script>
32
24
 
33
- <MenuItem
34
- {...restProps}
35
- role="menuitemradio"
36
- class="sui menu-item-radio {className}"
37
- {label}
38
- {hidden}
39
- {disabled}
40
- aria-checked={checked}
41
- onChange={(event) => {
42
- onChange?.(event);
43
- checked = event.detail.checked;
44
- }}
45
- >
46
- {#snippet startIcon()}
47
- {@render _startIcon?.()}
48
- {/snippet}
49
- <!-- eslint-disable-next-line svelte/no-useless-children-snippet -->
50
- {#snippet children()}
51
- {@render _children?.()}
52
- {/snippet}
53
- {#snippet endIcon()}
54
- {#if checked}
55
- <Icon name="check" />
56
- {/if}
57
- {/snippet}
58
- </MenuItem>
25
+ <MenuItemCheckable {...restProps} bind:checked role="menuitemradio" />
@@ -8,6 +8,6 @@ type MenuItemRadio = {
8
8
  * `<MenuItemGroup>` component.
9
9
  * @see https://w3c.github.io/aria/#menuitemradio
10
10
  */
11
- declare const MenuItemRadio: import("svelte").Component<ButtonProps & MenuItemProps & import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").PointerEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & Record<string, any>, {}, "checked">;
12
- import type { ButtonProps } from '../../typedefs';
13
- import type { MenuItemProps } from '../../typedefs';
11
+ declare const MenuItemRadio: import("svelte").Component<ButtonProps & MenuItemProps & import("../../typedefs.js").KeyboardEventHandlers & import("../../typedefs.js").MouseEventHandlers & import("../../typedefs.js").PointerEventHandlers & import("../../typedefs.js").FocusEventHandlers & import("../../typedefs.js").DragEventHandlers & Record<string, any>, {}, "checked">;
12
+ import type { ButtonProps } from '../../typedefs.js';
13
+ import type { MenuItemProps } from '../../typedefs.js';
@@ -17,7 +17,7 @@
17
17
  * CommonEventHandlers,
18
18
  * MenuItemProps,
19
19
  * PopupPosition,
20
- * } from '../../typedefs';
20
+ * } from '../../typedefs.js';
21
21
  */
22
22
 
23
23
  /**
@@ -54,6 +54,8 @@
54
54
 
55
55
  let isPopupOpen = $state(false);
56
56
  let isPopupHovered = $state(false);
57
+ /** @type {number | undefined} */
58
+ let hoverTimer;
57
59
 
58
60
  /**
59
61
  * Reference to the `<button>` element.
@@ -62,15 +64,29 @@
62
64
  let buttonElement = $state();
63
65
 
64
66
  /**
65
- * Reference to the `<button>` element.
67
+ * Reference to the `<dialog>` element the menu is in, if any.
66
68
  * @type {HTMLDialogElement | undefined}
67
69
  */
68
70
  let dialogElement = $state();
69
71
 
70
72
  const hasItems = $derived(role === 'menuitem' && !!items);
71
73
 
74
+ /**
75
+ * Open or close the submenu after a short delay, cancelling any pending change, so that quickly
76
+ * moving the pointer in and out doesn’t leave a stale timer to act on the state later.
77
+ * @param {() => void} callback Function to run after the delay.
78
+ */
79
+ const scheduleHoverChange = (callback) => {
80
+ window.clearTimeout(hoverTimer);
81
+ hoverTimer = window.setTimeout(callback, 200);
82
+ };
83
+
72
84
  onMount(() => {
73
85
  dialogElement = buttonElement?.closest('dialog') ?? undefined;
86
+
87
+ return () => {
88
+ window.clearTimeout(hoverTimer);
89
+ };
74
90
  });
75
91
  </script>
76
92
 
@@ -85,20 +101,20 @@
85
101
  aria-expanded={hasItems ? isPopupOpen : undefined}
86
102
  onmouseenter={(event) => {
87
103
  if (hasItems) {
88
- window.setTimeout(() => {
104
+ scheduleHoverChange(() => {
89
105
  isPopupOpen = true;
90
- }, 200);
106
+ });
91
107
  }
92
108
 
93
109
  onmouseenter?.(event);
94
110
  }}
95
111
  onmouseleave={(event) => {
96
112
  if (hasItems) {
97
- window.setTimeout(() => {
113
+ scheduleHoverChange(() => {
98
114
  if (!isPopupHovered) {
99
115
  isPopupOpen = false;
100
116
  }
101
- }, 200);
117
+ });
102
118
  }
103
119
 
104
120
  onmouseleave?.(event);
@@ -7,7 +7,7 @@ type MenuItem = {
7
7
  * A menu item widget.
8
8
  * @see https://w3c.github.io/aria/#menuitem
9
9
  */
10
- declare const MenuItem: import("svelte").Component<ButtonProps & MenuItemProps & import("../../typedefs").KeyboardEventHandlers & import("../../typedefs").MouseEventHandlers & import("../../typedefs").PointerEventHandlers & import("../../typedefs").FocusEventHandlers & import("../../typedefs").DragEventHandlers & {
10
+ declare const MenuItem: import("svelte").Component<ButtonProps & MenuItemProps & import("../../typedefs.js").KeyboardEventHandlers & import("../../typedefs.js").MouseEventHandlers & import("../../typedefs.js").PointerEventHandlers & import("../../typedefs.js").FocusEventHandlers & import("../../typedefs.js").DragEventHandlers & {
11
11
  /**
12
12
  * Where to show the dropdown menu.
13
13
  */
@@ -19,6 +19,6 @@ type Props = {
19
19
  */
20
20
  popupPosition?: PopupPosition | undefined;
21
21
  };
22
- import type { ButtonProps } from '../../typedefs';
23
- import type { MenuItemProps } from '../../typedefs';
24
- import type { PopupPosition } from '../../typedefs';
22
+ import type { ButtonProps } from '../../typedefs.js';
23
+ import type { MenuItemProps } from '../../typedefs.js';
24
+ import type { PopupPosition } from '../../typedefs.js';
@@ -138,7 +138,18 @@
138
138
  group = value;
139
139
  }
140
140
  }}
141
- {onChange}
141
+ onChange={(/** @type {CustomEvent} */ event) => {
142
+ // The group checks and unchecks the radio buttons by itself, as the arrow keys move, so keep
143
+ // the state in step; otherwise a radio button unchecked that way would still think it’s
144
+ // checked and ignore the next click
145
+ checked = event.detail.checked;
146
+
147
+ if (checked && typeof group === 'string') {
148
+ group = value;
149
+ }
150
+
151
+ onChange?.(event);
152
+ }}
142
153
  {onSelect}
143
154
  />
144
155
  {#if children || label}
@@ -57,25 +57,15 @@
57
57
  // The value reported via aria-valuenow is the size of the pane immediately before this handle
58
58
  const currentPaneSize = $derived(sizes[handleIndex] ?? 0);
59
59
  const currentPaneConstraints = $derived(ctx.getPaneConstraints(handleIndex));
60
+ const nextPaneConstraints = $derived(ctx.getPaneConstraints(handleIndex + 1));
61
+ // The handle only moves space between the panes either side of it, so its range is bound by
62
+ // what those two panes can take
63
+ const pairSize = $derived(currentPaneSize + (sizes[handleIndex + 1] ?? 0));
60
64
  const currentPaneMin = $derived(
61
- Math.max(
62
- currentPaneConstraints.minSize,
63
- 100 -
64
- ctx.paneDefs.reduce(
65
- (sum, _pane, i) => sum + (i !== handleIndex ? ctx.getPaneConstraints(i).maxSize : 0),
66
- 0,
67
- ),
68
- ),
65
+ Math.max(currentPaneConstraints.minSize, pairSize - nextPaneConstraints.maxSize),
69
66
  );
70
67
  const currentPaneMax = $derived(
71
- Math.min(
72
- currentPaneConstraints.maxSize,
73
- 100 -
74
- ctx.paneDefs.reduce(
75
- (sum, _pane, i) => sum + (i !== handleIndex ? ctx.getPaneConstraints(i).minSize : 0),
76
- 0,
77
- ),
78
- ),
68
+ Math.min(currentPaneConstraints.maxSize, pairSize - nextPaneConstraints.minSize),
79
69
  );
80
70
 
81
71
  /**
@@ -85,6 +75,12 @@
85
75
  let element = $state();
86
76
  let dragging = $state(false);
87
77
  let startScreenPos = $state(0);
78
+ /**
79
+ * Size of the pane before the handle when the drag began. Each move sets the pane to this plus
80
+ * the distance from where the drag began, rather than adding the latest step to the current
81
+ * size, so the handle stays under the pointer after it has been held back at a limit.
82
+ */
83
+ let startPaneSize = 0;
88
84
  let targetPointerId = $state(0);
89
85
  /**
90
86
  * Whether the handle is being resized via keyboard (at least one step fired).
@@ -126,8 +122,7 @@
126
122
  percentDelta = -percentDelta;
127
123
  }
128
124
 
129
- startScreenPos = screenPos;
130
- ctx.resize(handleIndex, percentDelta);
125
+ ctx.resize(handleIndex, startPaneSize + percentDelta - (sizes[handleIndex] ?? 0));
131
126
  };
132
127
 
133
128
  /**
@@ -165,6 +160,7 @@
165
160
 
166
161
  dragging = true;
167
162
  startScreenPos = isHorizontal ? screenX : screenY;
163
+ startPaneSize = sizes[handleIndex] ?? 0;
168
164
  targetPointerId = pointerId;
169
165
  containerSize = ctx.measurePaneSpace();
170
166
  element?.setPointerCapture(pointerId);
@@ -15,7 +15,7 @@
15
15
 
16
16
  /**
17
17
  * @import { Snippet } from 'svelte';
18
- * @import { PaneGroupContext } from '../../typedefs.js';
18
+ * @import { PaneGroupContext, ResizablePaneSize } from '../../typedefs.js';
19
19
  */
20
20
 
21
21
  /**
@@ -30,9 +30,9 @@
30
30
  /**
31
31
  * @typedef {{
32
32
  * id: string,
33
- * defaultSize: number | string | undefined,
34
- * minSize: number | string,
35
- * maxSize: number | string,
33
+ * defaultSize: ResizablePaneSize | undefined,
34
+ * minSize: ResizablePaneSize,
35
+ * maxSize: ResizablePaneSize,
36
36
  * }} PaneDef
37
37
  */
38
38
 
@@ -121,7 +121,8 @@
121
121
 
122
122
  /**
123
123
  * Initialize pane sizes from `defaultSize` props. Called once all panes have registered. Panes
124
- * without `defaultSize` share the remaining space equally.
124
+ * without `defaultSize` share the remaining space equally, and every size is kept within its
125
+ * pane’s `minSize` and `maxSize`.
125
126
  */
126
127
  const initSizes = () => {
127
128
  // Only called once panes have registered; see the effect below
@@ -135,7 +136,9 @@
135
136
  p.defaultSize === undefined ? NaN : resolveToPercent(p.defaultSize, NaN, env),
136
137
  );
137
138
 
138
- sizes.splice(0, sizes.length, ...getInitialSizes(resolvedDefaults));
139
+ const constraints = _paneDefs.map((p) => resolvePaneConstraints(p, env));
140
+
141
+ sizes.splice(0, sizes.length, ...getInitialSizes(resolvedDefaults, constraints));
139
142
  };
140
143
 
141
144
  /**
@@ -8,18 +8,18 @@
8
8
 
9
9
  /**
10
10
  * @import { Snippet } from 'svelte';
11
- * @import { PaneGroupContext } from '../../typedefs.js';
11
+ * @import { PaneGroupContext, ResizablePaneSize } from '../../typedefs.js';
12
12
  */
13
13
 
14
14
  /**
15
15
  * @typedef {object} Props
16
- * @property {number | string} [defaultSize] Default size. Numbers are percentages (0-100) of
16
+ * @property {ResizablePaneSize} [defaultSize] Default size. Numbers are percentages (0-100) of
17
17
  * the space the panes share, which is the group less its handles; strings can be any CSS
18
18
  * length/percentage such as `240px`, `20%` or `20dvw`. Panes without `defaultSize` share the
19
19
  * remaining space equally.
20
- * @property {number | string} [minSize] Minimum size. Numbers are percentages, strings are CSS
20
+ * @property {ResizablePaneSize} [minSize] Minimum size. Numbers are percentages, strings are CSS
21
21
  * lengths. Defaults to `0`.
22
- * @property {number | string} [maxSize] Maximum size. Numbers are percentages, strings are CSS
22
+ * @property {ResizablePaneSize} [maxSize] Maximum size. Numbers are percentages, strings are CSS
23
23
  * lengths. Defaults to `100`.
24
24
  * @property {string} [class] The `class` attribute on the wrapper element.
25
25
  * @property {Snippet} [children] Primary slot content.
@@ -14,17 +14,17 @@ declare const ResizablePane: import("svelte").Component<{
14
14
  * length/percentage such as `240px`, `20%` or `20dvw`. Panes without `defaultSize` share the
15
15
  * remaining space equally.
16
16
  */
17
- defaultSize?: string | number | undefined;
17
+ defaultSize?: ResizablePaneSize | undefined;
18
18
  /**
19
19
  * Minimum size. Numbers are percentages, strings are CSS
20
20
  * lengths. Defaults to `0`.
21
21
  */
22
- minSize?: string | number | undefined;
22
+ minSize?: ResizablePaneSize | undefined;
23
23
  /**
24
24
  * Maximum size. Numbers are percentages, strings are CSS
25
25
  * lengths. Defaults to `100`.
26
26
  */
27
- maxSize?: string | number | undefined;
27
+ maxSize?: ResizablePaneSize | undefined;
28
28
  /**
29
29
  * The `class` attribute on the wrapper element.
30
30
  */
@@ -48,17 +48,17 @@ type Props = {
48
48
  * length/percentage such as `240px`, `20%` or `20dvw`. Panes without `defaultSize` share the
49
49
  * remaining space equally.
50
50
  */
51
- defaultSize?: string | number | undefined;
51
+ defaultSize?: ResizablePaneSize | undefined;
52
52
  /**
53
53
  * Minimum size. Numbers are percentages, strings are CSS
54
54
  * lengths. Defaults to `0`.
55
55
  */
56
- minSize?: string | number | undefined;
56
+ minSize?: ResizablePaneSize | undefined;
57
57
  /**
58
58
  * Maximum size. Numbers are percentages, strings are CSS
59
59
  * lengths. Defaults to `100`.
60
60
  */
61
- maxSize?: string | number | undefined;
61
+ maxSize?: ResizablePaneSize | undefined;
62
62
  /**
63
63
  * The `class` attribute on the wrapper element.
64
64
  */
@@ -75,4 +75,5 @@ type Props = {
75
75
  size: number;
76
76
  }) => void) | undefined;
77
77
  };
78
+ import type { ResizablePaneSize } from '../../typedefs.js';
78
79
  import type { Snippet } from 'svelte';
@@ -1,9 +1,9 @@
1
- export function resolveToPercent(value: number | string | undefined, fallback: number, env: SizeEnvironment): number;
1
+ export function resolveToPercent(value: ResizablePaneSize | undefined, fallback: number, env: SizeEnvironment): number;
2
2
  export function resolvePaneConstraints(paneDef: {
3
- minSize: number | string;
4
- maxSize: number | string;
3
+ minSize: ResizablePaneSize;
4
+ maxSize: ResizablePaneSize;
5
5
  } | undefined, env: SizeEnvironment): PaneConstraints;
6
- export function getInitialSizes(resolvedDefaults: number[]): number[];
6
+ export function getInitialSizes(resolvedDefaults: number[], constraints?: PaneConstraints[]): number[];
7
7
  export function clampResizeDelta(deltaPercent: number, { sizeBefore, sizeAfter, constraintsBefore, constraintsAfter }: {
8
8
  sizeBefore: number;
9
9
  sizeAfter: number;
@@ -46,3 +46,4 @@ export type PaneConstraints = {
46
46
  */
47
47
  maxSize: number;
48
48
  };
49
+ import type { ResizablePaneSize } from '../../typedefs.js';