@sveltia/ui 0.10.7 → 0.11.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 (49) hide show
  1. package/package/components/button/button-group.svelte +17 -0
  2. package/package/components/button/button-group.svelte.d.ts +29 -0
  3. package/package/components/button/button.svelte +1 -0
  4. package/package/components/button/button.svelte.d.ts +4 -2
  5. package/package/components/button/select-button-group.svelte.d.ts +2 -2
  6. package/package/components/button/select-button.svelte.d.ts +2 -2
  7. package/package/components/button/split-button.svelte.d.ts +2 -2
  8. package/package/components/checkbox/checkbox.svelte.d.ts +2 -2
  9. package/package/components/disclosure/disclosure.svelte.d.ts +2 -2
  10. package/package/components/divider/divider.svelte +4 -0
  11. package/package/components/drawer/drawer.svelte +0 -1
  12. package/package/components/listbox/listbox.svelte +22 -1
  13. package/package/components/listbox/listbox.svelte.d.ts +6 -2
  14. package/package/components/listbox/option-group.svelte.d.ts +2 -2
  15. package/package/components/listbox/option.svelte +15 -4
  16. package/package/components/listbox/option.svelte.d.ts +4 -2
  17. package/package/components/menu/menu-button.svelte.d.ts +2 -2
  18. package/package/components/menu/menu-item-checkbox.svelte.d.ts +2 -2
  19. package/package/components/menu/menu-item-group.svelte.d.ts +2 -2
  20. package/package/components/menu/menu-item-radio.svelte.d.ts +2 -2
  21. package/package/components/menu/menu-item.svelte.d.ts +2 -2
  22. package/package/components/radio/radio-group.svelte.d.ts +2 -2
  23. package/package/components/radio/radio.svelte.d.ts +2 -2
  24. package/package/components/select/combobox.svelte +71 -10
  25. package/package/components/select/combobox.svelte.d.ts +2 -2
  26. package/package/components/select/select.svelte.d.ts +2 -2
  27. package/package/components/slider/slider.svelte.d.ts +2 -2
  28. package/package/components/switch/switch.svelte.d.ts +2 -2
  29. package/package/components/text-field/markdown-editor.svelte.d.ts +2 -2
  30. package/package/components/text-field/number-input.svelte.d.ts +2 -2
  31. package/package/components/text-field/password-input.svelte.d.ts +2 -2
  32. package/package/components/text-field/search-bar.svelte.d.ts +2 -2
  33. package/package/components/text-field/text-area.svelte.d.ts +2 -2
  34. package/package/components/text-field/text-input.svelte.d.ts +2 -2
  35. package/package/components/toolbar/toolbar.svelte +8 -0
  36. package/package/components/util/app-shell.svelte +10 -10
  37. package/package/components/util/modal.svelte +1 -1
  38. package/package/components/util/popup.svelte +1 -1
  39. package/package/index.d.ts +1 -0
  40. package/package/index.js +1 -0
  41. package/package/locales/en.d.ts +2 -0
  42. package/package/locales/en.js +2 -0
  43. package/package/locales/ja.d.ts +2 -0
  44. package/package/locales/ja.js +2 -0
  45. package/package/services/events.js +8 -6
  46. package/package/services/group.d.ts +1 -1
  47. package/package/services/group.js +67 -18
  48. package/package/styles/variables.scss +5 -5
  49. package/package.json +20 -12
@@ -0,0 +1,17 @@
1
+ <script>
2
+ /**
3
+ * The `class` attribute on the wrapper element.
4
+ * @type {string}
5
+ */
6
+ let className = '';
7
+ export { className as class };
8
+ </script>
9
+
10
+ <div role="group" class="sui button-group {className}" {...$$restProps}>
11
+ <slot />
12
+ </div>
13
+
14
+ <style>.button-group {
15
+ display: inline-flex;
16
+ align-items: center;
17
+ }</style>
@@ -0,0 +1,29 @@
1
+ /** @typedef {typeof __propDef.props} ButtonGroupProps */
2
+ /** @typedef {typeof __propDef.events} ButtonGroupEvents */
3
+ /** @typedef {typeof __propDef.slots} ButtonGroupSlots */
4
+ export default class ButtonGroup extends SvelteComponent<{
5
+ [x: string]: any;
6
+ class?: string | undefined;
7
+ }, {
8
+ [evt: string]: CustomEvent<any>;
9
+ }, {
10
+ default: {};
11
+ }> {
12
+ }
13
+ export type ButtonGroupProps = typeof __propDef.props;
14
+ export type ButtonGroupEvents = typeof __propDef.events;
15
+ export type ButtonGroupSlots = typeof __propDef.slots;
16
+ import { SvelteComponent } from "svelte";
17
+ declare const __propDef: {
18
+ props: {
19
+ [x: string]: any;
20
+ class?: string | undefined;
21
+ };
22
+ events: {
23
+ [evt: string]: CustomEvent<any>;
24
+ };
25
+ slots: {
26
+ default: {};
27
+ };
28
+ };
29
+ export {};
@@ -153,6 +153,7 @@
153
153
  on:change={(/** @type {CustomEvent} */ event) => {
154
154
  dispatch('change', event.detail);
155
155
  }}
156
+ on:toggle
156
157
  >
157
158
  <slot name="start-icon" />
158
159
  {#if variant === 'link'}
@@ -10,8 +10,8 @@ export default class Button extends SvelteComponent<{
10
10
  [x: string]: any;
11
11
  class?: string | undefined;
12
12
  name?: string | undefined;
13
- label?: string | undefined;
14
13
  disabled?: boolean | undefined;
14
+ label?: string | undefined;
15
15
  size?: "small" | "medium" | "large" | undefined;
16
16
  type?: "reset" | "submit" | "button" | undefined;
17
17
  value?: string | undefined;
@@ -41,6 +41,7 @@ export default class Button extends SvelteComponent<{
41
41
  keypress: KeyboardEvent;
42
42
  focus: FocusEvent;
43
43
  blur: FocusEvent;
44
+ toggle: Event;
44
45
  select: CustomEvent<any>;
45
46
  change: CustomEvent<any>;
46
47
  } & {
@@ -118,8 +119,8 @@ declare const __propDef: {
118
119
  [x: string]: any;
119
120
  class?: string | undefined;
120
121
  name?: string | undefined;
121
- label?: string | undefined;
122
122
  disabled?: boolean | undefined;
123
+ label?: string | undefined;
123
124
  size?: 'small' | 'medium' | 'large' | undefined;
124
125
  type?: "reset" | "submit" | "button" | undefined;
125
126
  value?: string | undefined;
@@ -150,6 +151,7 @@ declare const __propDef: {
150
151
  keypress: KeyboardEvent;
151
152
  focus: FocusEvent;
152
153
  blur: FocusEvent;
154
+ toggle: Event;
153
155
  select: CustomEvent<any>;
154
156
  change: CustomEvent<any>;
155
157
  } & {
@@ -9,8 +9,8 @@
9
9
  export default class SelectButtonGroup extends SvelteComponent<{
10
10
  [x: string]: any;
11
11
  class?: string | undefined;
12
- invalid?: boolean | undefined;
13
12
  disabled?: boolean | undefined;
13
+ invalid?: boolean | undefined;
14
14
  required?: boolean | undefined;
15
15
  hidden?: boolean | undefined;
16
16
  readonly?: boolean | undefined;
@@ -30,8 +30,8 @@ declare const __propDef: {
30
30
  props: {
31
31
  [x: string]: any;
32
32
  class?: string | undefined;
33
- invalid?: boolean | undefined;
34
33
  disabled?: boolean | undefined;
34
+ invalid?: boolean | undefined;
35
35
  required?: boolean | undefined;
36
36
  hidden?: boolean | undefined;
37
37
  readonly?: boolean | undefined;
@@ -9,8 +9,8 @@
9
9
  export default class SelectButton extends SvelteComponent<{
10
10
  [x: string]: any;
11
11
  class?: string | undefined;
12
- label?: string | undefined;
13
12
  disabled?: boolean | undefined;
13
+ label?: string | undefined;
14
14
  size?: "small" | "medium" | "large" | undefined;
15
15
  value?: string | undefined;
16
16
  hidden?: boolean | undefined;
@@ -42,8 +42,8 @@ declare const __propDef: {
42
42
  props: {
43
43
  [x: string]: any;
44
44
  class?: string | undefined;
45
- label?: string | undefined;
46
45
  disabled?: boolean | undefined;
46
+ label?: string | undefined;
47
47
  size?: "small" | "medium" | "large" | undefined;
48
48
  value?: string | undefined;
49
49
  hidden?: boolean | undefined;
@@ -10,8 +10,8 @@
10
10
  export default class SplitButton extends SvelteComponent<{
11
11
  [x: string]: any;
12
12
  class?: string | undefined;
13
- label?: string | undefined;
14
13
  disabled?: boolean | undefined;
14
+ label?: string | undefined;
15
15
  size?: "small" | "medium" | "large" | undefined;
16
16
  hidden?: boolean | undefined;
17
17
  variant?: "primary" | "secondary" | "tertiary" | "ghost" | undefined;
@@ -41,8 +41,8 @@ declare const __propDef: {
41
41
  props: {
42
42
  [x: string]: any;
43
43
  class?: string | undefined;
44
- label?: string | undefined;
45
44
  disabled?: boolean | undefined;
45
+ label?: string | undefined;
46
46
  size?: 'small' | 'medium' | 'large' | undefined;
47
47
  hidden?: boolean | undefined;
48
48
  variant?: 'primary' | 'secondary' | 'tertiary' | 'ghost' | undefined;
@@ -11,10 +11,10 @@ export default class Checkbox extends SvelteComponent<{
11
11
  [x: string]: any;
12
12
  class?: string | undefined;
13
13
  name?: string | undefined;
14
+ disabled?: boolean | undefined;
14
15
  invalid?: boolean | undefined;
15
16
  label?: string | undefined;
16
17
  checked?: boolean | "mixed" | undefined;
17
- disabled?: boolean | undefined;
18
18
  required?: boolean | undefined;
19
19
  value?: string | undefined;
20
20
  hidden?: boolean | undefined;
@@ -39,10 +39,10 @@ declare const __propDef: {
39
39
  [x: string]: any;
40
40
  class?: string | undefined;
41
41
  name?: string | undefined;
42
+ disabled?: boolean | undefined;
42
43
  invalid?: boolean | undefined;
43
44
  label?: string | undefined;
44
45
  checked?: boolean | "mixed" | undefined;
45
- disabled?: boolean | undefined;
46
46
  required?: boolean | undefined;
47
47
  value?: string | undefined;
48
48
  hidden?: boolean | undefined;
@@ -9,8 +9,8 @@
9
9
  export default class Disclosure extends SvelteComponent<{
10
10
  [x: string]: any;
11
11
  class?: string | undefined;
12
- label?: string | undefined;
13
12
  disabled?: boolean | undefined;
13
+ label?: string | undefined;
14
14
  hidden?: boolean | undefined;
15
15
  expanded?: boolean | undefined;
16
16
  }, {
@@ -47,8 +47,8 @@ declare const __propDef: {
47
47
  props: {
48
48
  [x: string]: any;
49
49
  class?: string | undefined;
50
- label?: string | undefined;
51
50
  disabled?: boolean | undefined;
51
+ label?: string | undefined;
52
52
  hidden?: boolean | undefined;
53
53
  expanded?: boolean | undefined;
54
54
  };
@@ -36,8 +36,12 @@
36
36
  background-color: var(--sui-secondary-border-color);
37
37
  }
38
38
  .divider[aria-orientation=horizontal] {
39
+ margin: 8px 0;
40
+ width: 100%;
39
41
  height: 1px;
40
42
  }
41
43
  .divider[aria-orientation=vertical] {
44
+ margin: 0 8px;
42
45
  width: 1px;
46
+ height: 100%;
43
47
  }</style>
@@ -150,7 +150,6 @@
150
150
  position: absolute;
151
151
  display: flex;
152
152
  flex-direction: column;
153
- overflow: hidden;
154
153
  max-width: 100dvw;
155
154
  max-height: 100dvh;
156
155
  background-color: var(--sui-secondary-background-color-translucent);
@@ -46,6 +46,16 @@
46
46
  * @type {boolean}
47
47
  */
48
48
  export let multiple = false;
49
+ /**
50
+ * Search terms to be used to filter the items.
51
+ * @type {string}
52
+ */
53
+ export let searchTerms = '';
54
+
55
+ /**
56
+ * @type {boolean}
57
+ */
58
+ let filtered = false;
49
59
 
50
60
  const dispatch = createEventDispatcher();
51
61
  </script>
@@ -53,6 +63,7 @@
53
63
  <div
54
64
  role="listbox"
55
65
  class="sui listbox {className}"
66
+ class:filtered
56
67
  tabindex={disabled ? -1 : 0}
57
68
  hidden={hidden || undefined}
58
69
  aria-hidden={hidden}
@@ -62,11 +73,15 @@
62
73
  aria-invalid={invalid}
63
74
  aria-multiselectable={multiple}
64
75
  {...$$restProps}
65
- use:activateGroup
76
+ use:activateGroup={{ searchTerms }}
66
77
  on:click
67
78
  on:change={(/** @type {CustomEvent} */ event) => {
68
79
  dispatch('change', event.detail);
69
80
  }}
81
+ on:filter
82
+ on:filter={(/** @type {CustomEvent} */ { detail: { matched, total } }) => {
83
+ filtered = matched !== total;
84
+ }}
70
85
  >
71
86
  <div role="none" class="inner" inert={disabled}>
72
87
  <slot />
@@ -113,6 +128,12 @@
113
128
  [role=listbox]:global(.tabs) :global(.option button[aria-selected="true"]) {
114
129
  border-color: var(--sui-primary-accent-color-light);
115
130
  }
131
+ [role=listbox].in-combobox:focus-visible {
132
+ outline-color: transparent;
133
+ }
134
+ [role=listbox].filtered :global([role="separator"]) {
135
+ display: none;
136
+ }
116
137
 
117
138
  .inner {
118
139
  display: contents;
@@ -10,14 +10,16 @@
10
10
  export default class Listbox extends SvelteComponent<{
11
11
  [x: string]: any;
12
12
  class?: string | undefined;
13
- invalid?: boolean | undefined;
14
13
  disabled?: boolean | undefined;
14
+ invalid?: boolean | undefined;
15
15
  multiple?: boolean | undefined;
16
16
  required?: boolean | undefined;
17
17
  hidden?: boolean | undefined;
18
18
  readonly?: boolean | undefined;
19
+ searchTerms?: string | undefined;
19
20
  }, {
20
21
  click: MouseEvent;
22
+ filter: Event | KeyboardEvent | UIEvent | ErrorEvent | AnimationEvent | MouseEvent | InputEvent | FocusEvent | CompositionEvent | ClipboardEvent | DragEvent | FormDataEvent | PointerEvent | ProgressEvent<EventTarget> | SecurityPolicyViolationEvent | SubmitEvent | TouchEvent | TransitionEvent | WheelEvent;
21
23
  change: CustomEvent<any>;
22
24
  } & {
23
25
  [evt: string]: CustomEvent<any>;
@@ -33,15 +35,17 @@ declare const __propDef: {
33
35
  props: {
34
36
  [x: string]: any;
35
37
  class?: string | undefined;
36
- invalid?: boolean | undefined;
37
38
  disabled?: boolean | undefined;
39
+ invalid?: boolean | undefined;
38
40
  multiple?: boolean | undefined;
39
41
  required?: boolean | undefined;
40
42
  hidden?: boolean | undefined;
41
43
  readonly?: boolean | undefined;
44
+ searchTerms?: string | undefined;
42
45
  };
43
46
  events: {
44
47
  click: MouseEvent;
48
+ filter: Event | KeyboardEvent | UIEvent | ErrorEvent | AnimationEvent | MouseEvent | InputEvent | FocusEvent | CompositionEvent | ClipboardEvent | DragEvent | FormDataEvent | PointerEvent | ProgressEvent<EventTarget> | SecurityPolicyViolationEvent | SubmitEvent | TouchEvent | TransitionEvent | WheelEvent;
45
49
  change: CustomEvent<any>;
46
50
  } & {
47
51
  [evt: string]: CustomEvent<any>;
@@ -11,8 +11,8 @@
11
11
  export default class OptionGroup extends SvelteComponent<{
12
12
  [x: string]: any;
13
13
  class?: string | undefined;
14
- label?: string | undefined;
15
14
  disabled?: boolean | undefined;
15
+ label?: string | undefined;
16
16
  hidden?: boolean | undefined;
17
17
  }, {
18
18
  [evt: string]: CustomEvent<any>;
@@ -28,8 +28,8 @@ declare const __propDef: {
28
28
  props: {
29
29
  [x: string]: any;
30
30
  class?: string | undefined;
31
- label?: string | undefined;
32
31
  disabled?: boolean | undefined;
32
+ label?: string | undefined;
33
33
  hidden?: boolean | undefined;
34
34
  };
35
35
  events: {
@@ -31,14 +31,19 @@
31
31
  export let disabled = false;
32
32
  /**
33
33
  * Text label displayed on the item.
34
- * @type {string | undefined}
34
+ * @type {string}
35
35
  */
36
- export let label = '';
36
+ export let label;
37
37
  /**
38
38
  * The `value` attribute on the `<button>` element.
39
- * @type {string | undefined}
39
+ * @type {string}
40
+ */
41
+ export let value = label;
42
+ /**
43
+ * The value to be searched.
44
+ * @type {string}
40
45
  */
41
- export let value = undefined;
46
+ export let searchValue = label;
42
47
  </script>
43
48
 
44
49
  <div role="none" class="sui option {className}" hidden={hidden || undefined}>
@@ -51,6 +56,8 @@
51
56
  {hidden}
52
57
  {disabled}
53
58
  data-type={typeof value}
59
+ data-label={label}
60
+ data-search-value={searchValue}
54
61
  {...$$restProps}
55
62
  on:click
56
63
  on:dblclick
@@ -65,6 +72,10 @@
65
72
  on:change={(event) => {
66
73
  selected = event.detail.selected;
67
74
  }}
75
+ on:toggle={(event) => {
76
+ hidden = /** @type {CustomEvent} */ (event).detail.hidden;
77
+ selected = false;
78
+ }}
68
79
  >
69
80
  {#if selected}
70
81
  <slot name="check-icon">
@@ -8,12 +8,13 @@
8
8
  */
9
9
  export default class Option extends SvelteComponent<{
10
10
  [x: string]: any;
11
+ label: string;
11
12
  class?: string | undefined;
12
- label?: string | undefined;
13
13
  disabled?: boolean | undefined;
14
14
  value?: string | undefined;
15
15
  hidden?: boolean | undefined;
16
16
  selected?: boolean | undefined;
17
+ searchValue?: string | undefined;
17
18
  }, {
18
19
  click: MouseEvent;
19
20
  dblclick: MouseEvent;
@@ -45,12 +46,13 @@ import { SvelteComponent } from "svelte";
45
46
  declare const __propDef: {
46
47
  props: {
47
48
  [x: string]: any;
49
+ label: string;
48
50
  class?: string | undefined;
49
- label?: string | undefined;
50
51
  disabled?: boolean | undefined;
51
52
  value?: string | undefined;
52
53
  hidden?: boolean | undefined;
53
54
  selected?: boolean | undefined;
55
+ searchValue?: string | undefined;
54
56
  };
55
57
  events: {
56
58
  click: MouseEvent;
@@ -8,9 +8,9 @@
8
8
  export default class MenuButton extends SvelteComponent<{
9
9
  [x: string]: any;
10
10
  class?: string | undefined;
11
+ disabled?: boolean | undefined;
11
12
  focus?: (() => void) | undefined;
12
13
  label?: string | undefined;
13
- disabled?: boolean | undefined;
14
14
  size?: "small" | "medium" | "large" | undefined;
15
15
  hidden?: boolean | undefined;
16
16
  variant?: "link" | "primary" | "secondary" | "tertiary" | "ghost" | undefined;
@@ -40,9 +40,9 @@ declare const __propDef: {
40
40
  props: {
41
41
  [x: string]: any;
42
42
  class?: string | undefined;
43
+ disabled?: boolean | undefined;
43
44
  focus?: (() => void) | undefined;
44
45
  label?: string | undefined;
45
- disabled?: boolean | undefined;
46
46
  size?: "small" | "medium" | "large" | undefined;
47
47
  hidden?: boolean | undefined;
48
48
  variant?: 'primary' | 'secondary' | 'tertiary' | 'ghost' | 'link' | undefined;
@@ -8,9 +8,9 @@
8
8
  export default class MenuItemCheckbox extends SvelteComponent<{
9
9
  [x: string]: any;
10
10
  class?: string | undefined;
11
+ disabled?: boolean | undefined;
11
12
  label?: string | undefined;
12
13
  checked?: boolean | undefined;
13
- disabled?: boolean | undefined;
14
14
  hidden?: boolean | undefined;
15
15
  iconName?: string | undefined;
16
16
  iconLabel?: string | undefined;
@@ -32,9 +32,9 @@ declare const __propDef: {
32
32
  props: {
33
33
  [x: string]: any;
34
34
  class?: string | undefined;
35
+ disabled?: boolean | undefined;
35
36
  label?: string | undefined;
36
37
  checked?: boolean | undefined;
37
- disabled?: boolean | undefined;
38
38
  hidden?: boolean | undefined;
39
39
  iconName?: string | undefined;
40
40
  iconLabel?: string | undefined;
@@ -5,8 +5,8 @@
5
5
  export default class MenuItemGroup extends SvelteComponent<{
6
6
  [x: string]: any;
7
7
  class?: string | undefined;
8
- title?: string | undefined;
9
8
  disabled?: boolean | undefined;
9
+ title?: string | undefined;
10
10
  hidden?: boolean | undefined;
11
11
  }, {
12
12
  [evt: string]: CustomEvent<any>;
@@ -22,8 +22,8 @@ declare const __propDef: {
22
22
  props: {
23
23
  [x: string]: any;
24
24
  class?: string | undefined;
25
- title?: string | undefined;
26
25
  disabled?: boolean | undefined;
26
+ title?: string | undefined;
27
27
  hidden?: boolean | undefined;
28
28
  };
29
29
  events: {
@@ -9,9 +9,9 @@
9
9
  export default class MenuItemRadio extends SvelteComponent<{
10
10
  [x: string]: any;
11
11
  class?: string | undefined;
12
+ disabled?: boolean | undefined;
12
13
  label?: string | undefined;
13
14
  checked?: boolean | undefined;
14
- disabled?: boolean | undefined;
15
15
  hidden?: boolean | undefined;
16
16
  iconName?: string | undefined;
17
17
  iconLabel?: string | undefined;
@@ -33,9 +33,9 @@ declare const __propDef: {
33
33
  props: {
34
34
  [x: string]: any;
35
35
  class?: string | undefined;
36
+ disabled?: boolean | undefined;
36
37
  label?: string | undefined;
37
38
  checked?: boolean | undefined;
38
- disabled?: boolean | undefined;
39
39
  hidden?: boolean | undefined;
40
40
  iconName?: string | undefined;
41
41
  iconLabel?: string | undefined;
@@ -8,8 +8,8 @@
8
8
  export default class MenuItem extends SvelteComponent<{
9
9
  [x: string]: any;
10
10
  class?: string | undefined;
11
- label?: string | undefined;
12
11
  disabled?: boolean | undefined;
12
+ label?: string | undefined;
13
13
  role?: "menuitem" | "menuitemcheckbox" | "menuitemradio" | undefined;
14
14
  hidden?: boolean | undefined;
15
15
  iconName?: string | undefined;
@@ -42,8 +42,8 @@ declare const __propDef: {
42
42
  props: {
43
43
  [x: string]: any;
44
44
  class?: string | undefined;
45
- label?: string | undefined;
46
45
  disabled?: boolean | undefined;
46
+ label?: string | undefined;
47
47
  role?: "menuitem" | "menuitemcheckbox" | "menuitemradio" | undefined;
48
48
  hidden?: boolean | undefined;
49
49
  iconName?: string | undefined;
@@ -9,8 +9,8 @@
9
9
  export default class RadioGroup extends SvelteComponent<{
10
10
  [x: string]: any;
11
11
  class?: string | undefined;
12
- invalid?: boolean | undefined;
13
12
  disabled?: boolean | undefined;
13
+ invalid?: boolean | undefined;
14
14
  required?: boolean | undefined;
15
15
  hidden?: boolean | undefined;
16
16
  readonly?: boolean | undefined;
@@ -31,8 +31,8 @@ declare const __propDef: {
31
31
  props: {
32
32
  [x: string]: any;
33
33
  class?: string | undefined;
34
- invalid?: boolean | undefined;
35
34
  disabled?: boolean | undefined;
35
+ invalid?: boolean | undefined;
36
36
  required?: boolean | undefined;
37
37
  hidden?: boolean | undefined;
38
38
  readonly?: boolean | undefined;
@@ -11,9 +11,9 @@ export default class Radio extends SvelteComponent<{
11
11
  [x: string]: any;
12
12
  class?: string | undefined;
13
13
  name?: string | undefined;
14
+ disabled?: boolean | undefined;
14
15
  label?: string | undefined;
15
16
  checked?: boolean | undefined;
16
- disabled?: boolean | undefined;
17
17
  value?: string | undefined;
18
18
  hidden?: boolean | undefined;
19
19
  }, {
@@ -36,9 +36,9 @@ declare const __propDef: {
36
36
  [x: string]: any;
37
37
  class?: string | undefined;
38
38
  name?: string | undefined;
39
+ disabled?: boolean | undefined;
39
40
  label?: string | undefined;
40
41
  checked?: boolean | undefined;
41
- disabled?: boolean | undefined;
42
42
  value?: string | undefined;
43
43
  hidden?: boolean | undefined;
44
44
  };
@@ -13,6 +13,7 @@
13
13
  import Button from '../button/button.svelte';
14
14
  import Icon from '../icon/icon.svelte';
15
15
  import Listbox from '../listbox/listbox.svelte';
16
+ import SearchBar from '../text-field/search-bar.svelte';
16
17
  import TextInput from '../text-field/text-input.svelte';
17
18
  import Popup from '../util/popup.svelte';
18
19
 
@@ -74,6 +75,12 @@
74
75
  let isPopupOpen = writable(false);
75
76
  /** @type {string} */
76
77
  let label = '';
78
+ /** @type {boolean} */
79
+ let showFilter = false;
80
+ /** @type {string} */
81
+ let searchTerms = '';
82
+ /** @type {boolean} */
83
+ let hasMatchingOptions = true;
77
84
 
78
85
  /**
79
86
  * Update the {@link label} and selected option when the {@link value} is changed.
@@ -86,7 +93,7 @@
86
93
  );
87
94
 
88
95
  if (target) {
89
- label = target.querySelector('.label')?.textContent || target.textContent || target.value;
96
+ label = target.dataset.label || target.textContent || target.value;
90
97
 
91
98
  if (selected !== target) {
92
99
  selected?.setAttribute('aria-selected', 'false');
@@ -200,16 +207,49 @@
200
207
  touchOptimized={true}
201
208
  bind:open={isPopupOpen}
202
209
  bind:this={popupComponent}
210
+ on:open={() => {
211
+ showFilter = (popupComponent?.content?.querySelectorAll('[role="option"]')?.length ?? 0) > 5;
212
+ searchTerms = '';
213
+ }}
203
214
  >
204
- <Listbox
205
- on:click={(event) => {
206
- if (/** @type {HTMLElement} */ (event.target).matches('[role="option"]')) {
207
- onSelect(/** @type {HTMLButtonElement} */ (event.target));
208
- }
209
- }}
210
- >
211
- <slot />
212
- </Listbox>
215
+ <div role="none" class="combobox-inner">
216
+ {#if showFilter}
217
+ <SearchBar
218
+ flex
219
+ aria-label={$_('_sui.combobox.filter_options')}
220
+ aria-controls="{id}-listbox"
221
+ bind:value={searchTerms}
222
+ on:keydown={(event) => {
223
+ if (['ArrowUp', 'ArrowDown', 'Enter'].includes(event.key)) {
224
+ event.preventDefault();
225
+ popupComponent?.content
226
+ ?.querySelector('.sui.listbox')
227
+ ?.dispatchEvent(new KeyboardEvent('keydown', event));
228
+ }
229
+ }}
230
+ />
231
+ {/if}
232
+ <Listbox
233
+ id="{id}-listbox"
234
+ class="in-combobox"
235
+ {searchTerms}
236
+ on:click={(event) => {
237
+ if (/** @type {HTMLElement} */ (event.target).matches('[role="option"]')) {
238
+ onSelect(/** @type {HTMLButtonElement} */ (event.target));
239
+ }
240
+ }}
241
+ on:filter={(event) => {
242
+ hasMatchingOptions = !!(/** @type {CustomEvent} */ (event).detail.matched);
243
+ }}
244
+ >
245
+ <slot />
246
+ </Listbox>
247
+ {#if !hasMatchingOptions}
248
+ <div role="alert" class="no-options">
249
+ {$_('_sui.combobox.no_matching_options')}
250
+ </div>
251
+ {/if}
252
+ </div>
213
253
  </Popup>
214
254
 
215
255
  <style>.combobox {
@@ -297,4 +337,25 @@
297
337
  .combobox + :global([role="listbox"]:not(.open)) {
298
338
  opacity: 0;
299
339
  pointer-events: none;
340
+ }
341
+
342
+ .combobox-inner {
343
+ display: flex;
344
+ flex-direction: column;
345
+ overflow: hidden;
346
+ }
347
+ .combobox-inner :global(.sui.search-bar) {
348
+ flex: none;
349
+ }
350
+ .combobox-inner :global(.sui.listbox) {
351
+ flex: auto;
352
+ overflow-y: auto;
353
+ }
354
+ .combobox-inner .no-options {
355
+ flex: none;
356
+ display: flex;
357
+ align-items: center;
358
+ padding: var(--sui-option-padding);
359
+ height: var(--sui-option-height);
360
+ color: var(--sui-tertiary-foreground-color);
300
361
  }</style>