@geoffcox/sterling-svelte 2.0.0 → 2.0.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.
Files changed (127) hide show
  1. package/package.json +21 -23
  2. package/.DS_Store +0 -0
  3. package/@types/clickOutside.d.ts +0 -15
  4. package/Button.svelte +0 -25
  5. package/Button.svelte.d.ts +0 -9
  6. package/Callout.svelte +0 -177
  7. package/Callout.svelte.d.ts +0 -15
  8. package/Callout.types.d.ts +0 -11
  9. package/Callout.types.js +0 -1
  10. package/Checkbox.svelte +0 -43
  11. package/Checkbox.svelte.d.ts +0 -10
  12. package/Dialog.svelte +0 -151
  13. package/Dialog.svelte.d.ts +0 -14
  14. package/Dropdown.svelte +0 -109
  15. package/Dropdown.svelte.d.ts +0 -18
  16. package/Input.svelte +0 -55
  17. package/Input.svelte.d.ts +0 -12
  18. package/Label.constants.d.ts +0 -2
  19. package/Label.constants.js +0 -2
  20. package/Label.svelte +0 -91
  21. package/Label.svelte.d.ts +0 -17
  22. package/Link.svelte +0 -25
  23. package/Link.svelte.d.ts +0 -12
  24. package/List.constants.d.ts +0 -1
  25. package/List.constants.js +0 -1
  26. package/List.svelte +0 -203
  27. package/List.svelte.d.ts +0 -20
  28. package/List.types.d.ts +0 -5
  29. package/List.types.js +0 -1
  30. package/ListItem.svelte +0 -49
  31. package/ListItem.svelte.d.ts +0 -13
  32. package/Menu.svelte +0 -83
  33. package/Menu.svelte.d.ts +0 -13
  34. package/MenuBar.constants.d.ts +0 -1
  35. package/MenuBar.constants.js +0 -1
  36. package/MenuBar.svelte +0 -113
  37. package/MenuBar.svelte.d.ts +0 -13
  38. package/MenuBar.types.d.ts +0 -4
  39. package/MenuBar.types.js +0 -1
  40. package/MenuButton.svelte +0 -116
  41. package/MenuButton.svelte.d.ts +0 -20
  42. package/MenuItem.constants.d.ts +0 -2
  43. package/MenuItem.constants.js +0 -2
  44. package/MenuItem.svelte +0 -342
  45. package/MenuItem.svelte.d.ts +0 -22
  46. package/MenuItem.types.d.ts +0 -20
  47. package/MenuItem.types.js +0 -1
  48. package/MenuItem.utils.d.ts +0 -7
  49. package/MenuItem.utils.js +0 -36
  50. package/MenuSeparator.svelte +0 -11
  51. package/MenuSeparator.svelte.d.ts +0 -6
  52. package/Popover.constants.d.ts +0 -1
  53. package/Popover.constants.js +0 -14
  54. package/Popover.svelte +0 -121
  55. package/Popover.svelte.d.ts +0 -15
  56. package/Popover.types.d.ts +0 -4
  57. package/Popover.types.js +0 -1
  58. package/Portal.constants.d.ts +0 -2
  59. package/Portal.constants.js +0 -2
  60. package/Portal.types.d.ts +0 -6
  61. package/Portal.types.js +0 -1
  62. package/Progress.constants.d.ts +0 -1
  63. package/Progress.constants.js +0 -1
  64. package/Progress.svelte +0 -36
  65. package/Progress.svelte.d.ts +0 -12
  66. package/Progress.types.d.ts +0 -4
  67. package/Progress.types.js +0 -1
  68. package/Radio.svelte +0 -53
  69. package/Radio.svelte.d.ts +0 -13
  70. package/Select.svelte +0 -196
  71. package/Select.svelte.d.ts +0 -20
  72. package/Slider.svelte +0 -133
  73. package/Slider.svelte.d.ts +0 -19
  74. package/Switch.svelte +0 -61
  75. package/Switch.svelte.d.ts +0 -21
  76. package/Tab.svelte +0 -51
  77. package/Tab.svelte.d.ts +0 -12
  78. package/TabList.constants.d.ts +0 -1
  79. package/TabList.constants.js +0 -1
  80. package/TabList.svelte +0 -202
  81. package/TabList.svelte.d.ts +0 -18
  82. package/TabList.types.d.ts +0 -5
  83. package/TabList.types.js +0 -1
  84. package/TextArea.constants.d.ts +0 -1
  85. package/TextArea.constants.js +0 -1
  86. package/TextArea.svelte +0 -74
  87. package/TextArea.svelte.d.ts +0 -19
  88. package/TextArea.types.d.ts +0 -4
  89. package/TextArea.types.js +0 -1
  90. package/Tooltip.svelte +0 -63
  91. package/Tooltip.svelte.d.ts +0 -10
  92. package/Tree.constants.d.ts +0 -1
  93. package/Tree.constants.js +0 -1
  94. package/Tree.svelte +0 -53
  95. package/Tree.svelte.d.ts +0 -15
  96. package/Tree.types.d.ts +0 -5
  97. package/Tree.types.js +0 -1
  98. package/TreeChevron.svelte +0 -27
  99. package/TreeChevron.svelte.d.ts +0 -9
  100. package/TreeItem.constants.d.ts +0 -1
  101. package/TreeItem.constants.js +0 -1
  102. package/TreeItem.svelte +0 -329
  103. package/TreeItem.svelte.d.ts +0 -22
  104. package/TreeItem.types.d.ts +0 -4
  105. package/TreeItem.types.js +0 -1
  106. package/actions/applyLightDarkMode.d.ts +0 -10
  107. package/actions/applyLightDarkMode.js +0 -36
  108. package/actions/clickOutside.d.ts +0 -15
  109. package/actions/clickOutside.js +0 -28
  110. package/actions/extraClass.d.ts +0 -8
  111. package/actions/extraClass.js +0 -14
  112. package/actions/forwardEvents.d.ts +0 -12
  113. package/actions/forwardEvents.js +0 -32
  114. package/actions/portal.d.ts +0 -8
  115. package/actions/portal.js +0 -19
  116. package/actions/trapKeyboardFocus.d.ts +0 -3
  117. package/actions/trapKeyboardFocus.js +0 -52
  118. package/idGenerator.d.ts +0 -4
  119. package/idGenerator.js +0 -10
  120. package/index.d.ts +0 -59
  121. package/index.js +0 -54
  122. package/mediaQueries/prefersColorSchemeDark.d.ts +0 -2
  123. package/mediaQueries/prefersColorSchemeDark.js +0 -14
  124. package/mediaQueries/prefersReducedMotion.d.ts +0 -2
  125. package/mediaQueries/prefersReducedMotion.js +0 -14
  126. package/mediaQueries/usingKeyboard.d.ts +0 -2
  127. package/mediaQueries/usingKeyboard.js +0 -17
package/MenuItem.utils.js DELETED
@@ -1,36 +0,0 @@
1
- export const focusPreviousChild = (children, currentValue) => {
2
- const index = children?.findIndex((menuItem) => menuItem.value === currentValue);
3
- if (index !== -1) {
4
- const focusIndex = index === 0 ? children.length - 1 : index - 1;
5
- children[focusIndex].focus();
6
- }
7
- };
8
- export const focusNextChild = (children, currentValue) => {
9
- const index = children?.findIndex((menuItem) => menuItem.value === currentValue);
10
- if (index !== -1) {
11
- const focusIndex = (index + 1) % children.length;
12
- children[focusIndex].focus();
13
- }
14
- };
15
- export const focusFirstChild = (children) => {
16
- children?.[0]?.focus();
17
- };
18
- export const focusLastChild = (children) => {
19
- children?.[children.length - 1]?.focus();
20
- };
21
- export const isElementMenuItem = (candidate) => {
22
- if (!candidate)
23
- return false;
24
- const dataValue = candidate?.getAttribute('data-value');
25
- const role = candidate?.getAttribute('role');
26
- return ((role === 'menuitem' || role === 'menuitemcheckbox' || role === 'menuitemradio') &&
27
- dataValue !== null &&
28
- dataValue !== undefined);
29
- };
30
- export const isElementEnabledMenuItem = (candidate) => {
31
- if (!isElementMenuItem(candidate)) {
32
- return false;
33
- }
34
- const disabled = candidate?.getAttribute('disabled');
35
- return disabled === null || disabled === 'false';
36
- };
@@ -1,11 +0,0 @@
1
- <svelte:options runes={true} />
2
-
3
- <script lang="ts">let { class: _class, ...rest } = $props();
4
- export {};
5
- </script>
6
-
7
- <div
8
- class={['sterling-menu-separator', _class].filter(Boolean).join(' ')}
9
- role="separator"
10
- {...rest}
11
- ></div>
@@ -1,6 +0,0 @@
1
- /// <reference types="svelte" />
2
- import type { HTMLAttributes } from 'svelte/elements';
3
- type Props = HTMLAttributes<HTMLDivElement>;
4
- declare const MenuSeparator: import("svelte").Component<Props, {}, "">;
5
- type MenuSeparator = ReturnType<typeof MenuSeparator>;
6
- export default MenuSeparator;
@@ -1 +0,0 @@
1
- export declare const POPOVER_PLACEMENTS: string[];
@@ -1,14 +0,0 @@
1
- export const POPOVER_PLACEMENTS = [
2
- 'top-start',
3
- 'top',
4
- 'top-end',
5
- 'right-start',
6
- 'right',
7
- 'right-end',
8
- 'bottom-end',
9
- 'bottom',
10
- 'bottom-start',
11
- 'left-end',
12
- 'left',
13
- 'left-start'
14
- ];
package/Popover.svelte DELETED
@@ -1,121 +0,0 @@
1
- <svelte:options runes={true} />
2
-
3
- <script lang="ts">import { getContext, onMount, tick } from 'svelte';
4
- import { autoUpdate, computePosition, flip, offset } from '@floating-ui/dom';
5
- import { portal } from './actions/portal';
6
- import { STERLING_PORTAL_HOST_ID, STERLING_PORTAL_CONTEXT_ID } from './Portal.constants';
7
- let { children, conditionalRender = $bindable(true), crossAxisOffset = $bindable(0), mainAxisOffset = $bindable(0), open = $bindable(false), placement = $bindable('top-start'), portalHost, reference, class: _class, ...rest } = $props();
8
- let popupRef = $state(undefined);
9
- let popupPosition = $state({ x: 0, y: 0 });
10
- let floatingUIPlacement = $derived(placement);
11
- let bodyHeight = $state(0);
12
- let resizeObserver = undefined;
13
- const { portalHost: contextPortalHost } = getContext(STERLING_PORTAL_CONTEXT_ID) || {
14
- portalHost: undefined
15
- };
16
- // ----- Portal Host ----- //
17
- const ensurePortalHost = async () => {
18
- await tick();
19
- // use the host set from context, usually set from a Dialog
20
- let host = $contextPortalHost;
21
- // use or create the sterling portal host
22
- if (!host && globalThis?.document) {
23
- host = globalThis.document.querySelector(`#${STERLING_PORTAL_HOST_ID}`);
24
- // fallback to creating the sterling portal host
25
- if (!host) {
26
- host = globalThis.document.createElement('div');
27
- host.id = STERLING_PORTAL_HOST_ID;
28
- host.style.overflow = 'visible';
29
- globalThis.document.body.append(host);
30
- }
31
- }
32
- portalHost = host;
33
- };
34
- // ----- Position ----- //
35
- let middleware = $derived([
36
- offset({ mainAxis: mainAxisOffset, crossAxis: crossAxisOffset }),
37
- flip()
38
- ]);
39
- const computePopoverPosition = async () => {
40
- if (reference && popupRef) {
41
- popupPosition = await computePosition(reference, popupRef, {
42
- placement: floatingUIPlacement,
43
- middleware
44
- });
45
- }
46
- else {
47
- popupPosition = { x: 0, y: 0 };
48
- }
49
- };
50
- // whenever a positioned element is portaled it needs resubscription to auto-update
51
- let cleanupAutoUpdate = () => { };
52
- const autoUpdatePopoverPosition = () => {
53
- cleanupAutoUpdate();
54
- if (reference && popupRef) {
55
- cleanupAutoUpdate = autoUpdate(reference, popupRef, computePopoverPosition);
56
- }
57
- };
58
- $effect(() => {
59
- autoUpdatePopoverPosition();
60
- return () => {
61
- cleanupAutoUpdate();
62
- cleanupAutoUpdate = () => { };
63
- };
64
- });
65
- $effect(() => {
66
- bodyHeight;
67
- computePopoverPosition();
68
- });
69
- // ----- EventHandlers ----- //
70
- $effect(() => {
71
- ensurePortalHost();
72
- resizeObserver = new ResizeObserver((entries) => {
73
- bodyHeight = entries[0].target.clientHeight;
74
- });
75
- // start observing a DOM node
76
- resizeObserver.observe(document.body);
77
- return () => {
78
- resizeObserver?.unobserve(document.body);
79
- resizeObserver?.disconnect();
80
- resizeObserver = undefined;
81
- };
82
- });
83
- const onKeydown = (event) => {
84
- if (event.key === 'Escape') {
85
- open = false;
86
- }
87
- rest.onkeydown?.(event);
88
- };
89
- //TODO: Is this necessary?
90
- ensurePortalHost();
91
- </script>
92
-
93
- {#if open || !conditionalRender}
94
- <div use:portal={{ target: portalHost }} class="sterling-popover-portal">
95
- <!-- svelte-ignore a11y_no_static_element_interactions -->
96
- <div
97
- bind:this={popupRef}
98
- class={['sterling-popover', _class].filter(Boolean).join(' ')}
99
- class:open
100
- class:top={popupPosition.placement === 'top'}
101
- class:top-start={popupPosition.placement === 'top-start'}
102
- class:top-end={popupPosition.placement === 'top-end'}
103
- class:right={popupPosition.placement === 'right'}
104
- class:right-start={popupPosition.placement === 'right-start'}
105
- class:right-end={popupPosition.placement === 'right-end'}
106
- class:bottom={popupPosition.placement === 'bottom'}
107
- class:bottom-start={popupPosition.placement === 'bottom-start'}
108
- class:bottom-end={popupPosition.placement === 'bottom-end'}
109
- class:left={popupPosition.placement === 'left'}
110
- class:left-start={popupPosition.placement === 'left-start'}
111
- class:left-end={popupPosition.placement === 'left-end'}
112
- {...rest}
113
- onkeydown={onKeydown}
114
- style="left:{popupPosition.x}px; top:{popupPosition.y}px"
115
- >
116
- {#if children}
117
- {@render children()}
118
- {/if}
119
- </div>
120
- </div>
121
- {/if}
@@ -1,15 +0,0 @@
1
- /// <reference types="svelte" />
2
- import type { PopoverPlacement } from './Popover.types';
3
- import type { HTMLAttributes } from 'svelte/elements';
4
- type Props = HTMLAttributes<HTMLDivElement> & {
5
- conditionalRender?: boolean;
6
- crossAxisOffset?: number;
7
- mainAxisOffset?: number;
8
- open?: boolean | null;
9
- placement?: PopoverPlacement;
10
- portalHost?: HTMLElement;
11
- reference?: HTMLElement;
12
- };
13
- declare const Popover: import("svelte").Component<Props, {}, "conditionalRender" | "crossAxisOffset" | "mainAxisOffset" | "open" | "placement">;
14
- type Popover = ReturnType<typeof Popover>;
15
- export default Popover;
@@ -1,4 +0,0 @@
1
- import type { POPOVER_PLACEMENTS } from './Popover.constants';
2
- type PopoverPlacementTuple = typeof POPOVER_PLACEMENTS;
3
- export type PopoverPlacement = PopoverPlacementTuple[number];
4
- export {};
package/Popover.types.js DELETED
@@ -1 +0,0 @@
1
- export {};
@@ -1,2 +0,0 @@
1
- export declare const STERLING_PORTAL_HOST_ID = "SterlingPortalHost";
2
- export declare const STERLING_PORTAL_CONTEXT_ID = "SterlingPortalContext";
@@ -1,2 +0,0 @@
1
- export const STERLING_PORTAL_HOST_ID = 'SterlingPortalHost';
2
- export const STERLING_PORTAL_CONTEXT_ID = 'SterlingPortalContext';
package/Portal.types.d.ts DELETED
@@ -1,6 +0,0 @@
1
- /// <reference types="svelte" />
2
- import type { Readable } from 'svelte/store';
3
- export type PortalContext = {
4
- /** The portal host for usePortal */
5
- portalHost: Readable<HTMLElement | undefined>;
6
- };
package/Portal.types.js DELETED
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export declare const PROGRESS_ORIENTATIONS: string[];
@@ -1 +0,0 @@
1
- export const PROGRESS_ORIENTATIONS = ['horizontal', 'vertical'];
package/Progress.svelte DELETED
@@ -1,36 +0,0 @@
1
- <svelte:options runes={true} />
2
-
3
- <script lang="ts">let { class: _class, disabled = false, max = 100, percent = $bindable(0), //readonly
4
- value = $bindable(0), vertical, ...rest } = $props();
5
- //----- State ----- //
6
- let clientHeight = $state(0);
7
- let clientWidth = $state(0);
8
- let clampMax = $derived(Math.max(1, max));
9
- let clampValue = $derived(Math.max(0, Math.min(value, clampMax)));
10
- let ratio = $derived(clampValue / clampMax);
11
- $effect(() => {
12
- percent = Math.round(ratio * 100);
13
- });
14
- let percentHeight = $derived(clientHeight * ratio);
15
- let percentWidth = $derived(clientWidth * ratio);
16
- let indicatorStyle = $derived(vertical ? `height: ${percentHeight}px` : `width: ${percentWidth}px`);
17
- export {};
18
- </script>
19
-
20
- <!-- svelte-ignore a11y_role_supports_aria_props -->
21
- <div
22
- aria-orientation={vertical ? 'vertical' : 'horizontal'}
23
- class={['sterling-progress', _class].filter(Boolean).join(' ')}
24
- class:disabled
25
- class:horizontal={!vertical}
26
- class:vertical
27
- data-progress-percent={percent}
28
- data-progress-max={max}
29
- data-progress-value={value}
30
- role="progressbar"
31
- {...rest}
32
- >
33
- <div class="container" bind:clientWidth bind:clientHeight>
34
- <div class="indicator" style={indicatorStyle}></div>
35
- </div>
36
- </div>
@@ -1,12 +0,0 @@
1
- /// <reference types="svelte" />
2
- import type { HTMLAttributes } from 'svelte/elements';
3
- type Props = HTMLAttributes<HTMLDivElement> & {
4
- disabled?: boolean | null;
5
- max?: number;
6
- percent?: number;
7
- value?: number;
8
- vertical?: boolean | null;
9
- };
10
- declare const Progress: import("svelte").Component<Props, {}, "value" | "percent">;
11
- type Progress = ReturnType<typeof Progress>;
12
- export default Progress;
@@ -1,4 +0,0 @@
1
- import type { PROGRESS_ORIENTATIONS } from './Progress.constants';
2
- type ProgressOrientationTuple = typeof PROGRESS_ORIENTATIONS;
3
- export type ProgressOrientation = ProgressOrientationTuple[number];
4
- export {};
package/Progress.types.js DELETED
@@ -1 +0,0 @@
1
- export {};
package/Radio.svelte DELETED
@@ -1,53 +0,0 @@
1
- <svelte:options runes={true} />
2
-
3
- <script lang="ts">import { idGenerator } from './idGenerator';
4
- import { usingKeyboard } from './mediaQueries/usingKeyboard';
5
- let { id, children, checked = $bindable(false), class: _class, disabled = false, group = $bindable(), ...rest } = $props();
6
- let inputRef;
7
- $effect(() => {
8
- if (children && id === undefined) {
9
- id = idGenerator.nextId('Radio');
10
- }
11
- });
12
- // ----- Methods ----- //
13
- export const blur = () => {
14
- inputRef?.blur();
15
- };
16
- export const click = () => {
17
- inputRef?.click();
18
- };
19
- export const focus = (options) => {
20
- inputRef?.focus(options);
21
- };
22
- // ----- Event Handlers ----- //
23
- const onChange = (e) => {
24
- console.log('onChange', e);
25
- // if ((e.currentTarget && e.currentTarget.checked) || (e.target && e.target.checked)) {
26
- // group = value;
27
- // }
28
- };
29
- $effect(() => {
30
- console.log(id, '-checked', checked);
31
- });
32
- </script>
33
-
34
- <!--
35
- @component
36
- A styled HTML input type=radio element with optional label.
37
- -->
38
- <div
39
- class={`sterling-radio ${_class}`}
40
- class:checked
41
- class:disabled
42
- class:using-keyboard={$usingKeyboard}
43
- >
44
- <div class="container">
45
- <input bind:this={inputRef} checked {disabled} bind:group {id} type="radio" {...rest} />
46
- <div class="indicator"></div>
47
- </div>
48
- {#if children}
49
- <label for={id}>
50
- {@render children()}
51
- </label>
52
- {/if}
53
- </div>
package/Radio.svelte.d.ts DELETED
@@ -1,13 +0,0 @@
1
- /// <reference types="svelte" />
2
- import type { HTMLInputAttributes } from 'svelte/elements';
3
- type Props = HTMLInputAttributes & {
4
- group?: any | null;
5
- };
6
- /** A styled HTML input type=radio element with optional label. */
7
- declare const Radio: import("svelte").Component<Props, {
8
- blur: () => void;
9
- click: () => void;
10
- focus: (options?: FocusOptions) => void;
11
- }, "group" | "checked">;
12
- type Radio = ReturnType<typeof Radio>;
13
- export default Radio;
package/Select.svelte DELETED
@@ -1,196 +0,0 @@
1
- <svelte:options runes={true} />
2
-
3
- <script lang="ts">import { tick } from 'svelte';
4
- import { clickOutside } from './actions/clickOutside';
5
- import { idGenerator } from './idGenerator';
6
- import List from './List.svelte';
7
- import Popover from './Popover.svelte';
8
- let { buttonSnippet, children, class: _class, disabled = false, open = $bindable(false), onSelect, onPending, selectedValue = $bindable(), listClass, valueSnippet, ...rest } = $props();
9
- const popupId = idGenerator.nextId('Select-popup');
10
- // ----- State ----- //
11
- // Tracks the pending selected index
12
- let pendingSelectedValue = $state(selectedValue);
13
- // svelte-ignore non_reactive_update
14
- let selectRef = $state(undefined);
15
- let listRef;
16
- // ----- Reactions ----- //
17
- $effect(() => {
18
- pendingSelectedValue = selectedValue;
19
- });
20
- $effect(() => {
21
- onSelect?.(selectedValue);
22
- });
23
- $effect(() => {
24
- if (open) {
25
- onPending?.(pendingSelectedValue);
26
- }
27
- });
28
- $effect(() => {
29
- if (open) {
30
- tick().then(() => {
31
- setTimeout(() => {
32
- listRef?.focus();
33
- listRef?.scrollToSelectedItem();
34
- }, 10);
35
- });
36
- }
37
- });
38
- $effect(() => {
39
- if (!open) {
40
- tick().then(() => selectRef?.focus());
41
- }
42
- });
43
- // ----- Methods ----- //
44
- export const blur = () => {
45
- selectRef?.blur();
46
- };
47
- export const click = () => {
48
- selectRef?.click();
49
- };
50
- export const focus = (options) => {
51
- selectRef?.focus();
52
- };
53
- export const scrollToSelectedItem = () => {
54
- if (open) {
55
- listRef?.scrollToSelectedItem();
56
- }
57
- };
58
- // ----- Event Handlers ----- //
59
- const onSelectClick = (event) => {
60
- if (!disabled) {
61
- open = !open;
62
- event.preventDefault();
63
- event.stopPropagation();
64
- }
65
- rest.onclick?.(event);
66
- };
67
- const onSelectKeydown = (event) => {
68
- if (!disabled && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey) {
69
- switch (event.key) {
70
- case ' ':
71
- {
72
- if (!open) {
73
- open = true;
74
- }
75
- event.preventDefault();
76
- event.stopPropagation();
77
- return false;
78
- }
79
- break;
80
- case 'ArrowUp':
81
- {
82
- if (selectedValue) {
83
- listRef?.selectPreviousItem();
84
- }
85
- else {
86
- listRef?.selectLastItem();
87
- }
88
- event.preventDefault();
89
- event.stopPropagation();
90
- return false;
91
- }
92
- break;
93
- case 'ArrowDown':
94
- {
95
- if (selectedValue) {
96
- listRef?.selectNextItem();
97
- }
98
- else {
99
- listRef?.selectFirstItem();
100
- }
101
- event.preventDefault();
102
- event.stopPropagation();
103
- return false;
104
- }
105
- break;
106
- }
107
- }
108
- rest.onkeydown?.(event);
109
- };
110
- const onListKeydown = (event) => {
111
- if (!disabled && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey) {
112
- switch (event.key) {
113
- case 'Enter':
114
- {
115
- selectedValue = pendingSelectedValue;
116
- open = !open;
117
- event.preventDefault();
118
- event.stopPropagation();
119
- return false;
120
- }
121
- break;
122
- case 'Escape':
123
- {
124
- pendingSelectedValue = selectedValue;
125
- open = !open;
126
- event.preventDefault();
127
- event.stopPropagation();
128
- return false;
129
- }
130
- break;
131
- }
132
- }
133
- };
134
- const onListClick = (event) => {
135
- open = false;
136
- event.preventDefault();
137
- event.stopPropagation();
138
- return false;
139
- };
140
- const onListSelect = (value) => {
141
- pendingSelectedValue = value;
142
- if (!open) {
143
- selectedValue = pendingSelectedValue;
144
- }
145
- };
146
- </script>
147
-
148
- <div
149
- bind:this={selectRef}
150
- aria-controls={popupId}
151
- aria-haspopup="listbox"
152
- aria-expanded={open}
153
- class={['sterling-select', _class].filter(Boolean).join(' ')}
154
- class:disabled
155
- role="combobox"
156
- tabindex="0"
157
- use:clickOutside={{ onclickoutside: () => (open = false) }}
158
- {...rest}
159
- onclick={onSelectClick}
160
- onkeydown={onSelectKeydown}
161
- >
162
- <div class="value">
163
- {#if valueSnippet}
164
- {@render valueSnippet(selectedValue)}
165
- {:else if selectedValue}
166
- {selectedValue}
167
- {:else}
168
- <span>&nbsp;</span>
169
- {/if}
170
- </div>
171
- <div class="button">
172
- {#if buttonSnippet}
173
- {@render buttonSnippet()}
174
- {:else}
175
- <div class="chevron"></div>
176
- {/if}
177
- </div>
178
- <Popover reference={selectRef} bind:open id={popupId} conditionalRender={false}>
179
- <div class={['sterling-select-popup-content', _class].filter(Boolean).join(' ')}>
180
- <List
181
- bind:this={listRef}
182
- {disabled}
183
- selectedValue={pendingSelectedValue}
184
- onclick={onListClick}
185
- onkeydown={onListKeydown}
186
- onSelect={onListSelect}
187
- tabindex={open ? 0 : -1}
188
- class={`composed ${listClass}`}
189
- >
190
- {#if children}
191
- {@render children()}
192
- {/if}
193
- </List>
194
- </div>
195
- </Popover>
196
- </div>
@@ -1,20 +0,0 @@
1
- import { type Snippet } from 'svelte';
2
- import type { HTMLAttributes } from 'svelte/elements';
3
- type Props = HTMLAttributes<HTMLDivElement> & {
4
- buttonSnippet?: Snippet;
5
- disabled?: boolean | null;
6
- listClass?: string;
7
- onPending?: (value?: string) => void;
8
- onSelect?: (value?: string) => void;
9
- open?: boolean | null;
10
- selectedValue?: string;
11
- valueSnippet?: Snippet<[string | undefined]>;
12
- };
13
- declare const Select: import("svelte").Component<Props, {
14
- blur: () => void;
15
- click: () => void;
16
- focus: (options?: FocusOptions) => void;
17
- scrollToSelectedItem: () => void;
18
- }, "open" | "selectedValue">;
19
- type Select = ReturnType<typeof Select>;
20
- export default Select;