@geoffcox/sterling-svelte 0.0.16 → 0.0.18

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 (119) hide show
  1. package/{buttons/Button.svelte → Button.svelte} +27 -27
  2. package/{inputs/Checkbox.svelte → Checkbox.svelte} +26 -21
  3. package/{inputs/Checkbox.svelte.d.ts → Checkbox.svelte.d.ts} +2 -1
  4. package/{surfaces/Dialog.svelte → Dialog.svelte} +34 -21
  5. package/Field.svelte +257 -0
  6. package/Field.svelte.d.ts +63 -0
  7. package/Field.types.d.ts +1 -0
  8. package/Input.svelte +115 -0
  9. package/{inputs/Input.svelte.d.ts → Input.svelte.d.ts} +8 -3
  10. package/Label.svelte +51 -0
  11. package/Label.svelte.d.ts +41 -0
  12. package/List.constants.d.ts +1 -0
  13. package/List.constants.js +1 -0
  14. package/List.svelte +293 -0
  15. package/List.svelte.d.ts +63 -0
  16. package/List.types.d.ts +6 -0
  17. package/ListItem.svelte +89 -0
  18. package/ListItem.svelte.d.ts +51 -0
  19. package/{containers/Menu.svelte → Menu.svelte} +42 -27
  20. package/{containers/MenuBar.svelte → MenuBar.svelte} +13 -13
  21. package/{buttons/MenuButton.svelte → MenuButton.svelte} +17 -17
  22. package/{buttons/MenuButton.svelte.d.ts → MenuButton.svelte.d.ts} +1 -1
  23. package/{containers/MenuItem.svelte → MenuItem.svelte} +42 -54
  24. package/{containers/MenuItem.svelte.d.ts → MenuItem.svelte.d.ts} +2 -2
  25. package/{containers/MenuSeparator.svelte → MenuSeparator.svelte} +2 -2
  26. package/Menus.types.d.ts +22 -0
  27. package/{containers/Menus.utils.d.ts → Menus.utils.d.ts} +2 -2
  28. package/{containers/Menus.utils.js → Menus.utils.js} +6 -6
  29. package/{display/Progress.svelte → Progress.svelte} +28 -52
  30. package/{display/Progress.svelte.d.ts → Progress.svelte.d.ts} +1 -3
  31. package/Progress.types.d.ts +1 -0
  32. package/{inputs/Radio.svelte → Radio.svelte} +34 -29
  33. package/{inputs/Radio.svelte.d.ts → Radio.svelte.d.ts} +7 -2
  34. package/{inputs/Select.svelte → Select.svelte} +112 -130
  35. package/Select.svelte.d.ts +53 -0
  36. package/{inputs/Slider.svelte → Slider.svelte} +90 -86
  37. package/Slider.svelte.d.ts +51 -0
  38. package/{inputs/Switch.svelte → Switch.svelte} +43 -41
  39. package/Tab.svelte +181 -0
  40. package/{containers/Tab.svelte.d.ts → Tab.svelte.d.ts} +12 -15
  41. package/TabList.svelte +247 -0
  42. package/{containers/TabList.svelte.d.ts → TabList.svelte.d.ts} +21 -21
  43. package/TabList.types.d.ts +7 -0
  44. package/TextArea.svelte +113 -0
  45. package/{inputs/TextArea.svelte.d.ts → TextArea.svelte.d.ts} +3 -6
  46. package/TextArea.types.js +1 -0
  47. package/Tooltip.svelte +182 -0
  48. package/Tooltip.svelte.d.ts +24 -0
  49. package/Tooltip.types.d.ts +3 -0
  50. package/Tooltip.types.js +1 -0
  51. package/Tree.constants.d.ts +2 -0
  52. package/Tree.constants.js +2 -0
  53. package/Tree.svelte +114 -0
  54. package/Tree.svelte.d.ts +24 -0
  55. package/Tree.types.d.ts +28 -0
  56. package/Tree.types.js +1 -0
  57. package/{containers/TreeChevron.svelte → TreeChevron.svelte} +3 -3
  58. package/TreeItem.svelte +276 -0
  59. package/TreeItem.svelte.d.ts +65 -0
  60. package/{containers/TreeItem.svelte → TreeItemDisplay.svelte} +18 -18
  61. package/{containers/TreeItem.svelte.d.ts → TreeItemDisplay.svelte.d.ts} +11 -14
  62. package/{forwardEvents.js → actions/forwardEvents.js} +0 -2
  63. package/index.d.ts +44 -31
  64. package/index.js +40 -25
  65. package/package.json +45 -41
  66. package/theme/darkTheme.js +73 -74
  67. package/theme/lightTheme.js +76 -77
  68. package/containers/List.svelte +0 -249
  69. package/containers/List.svelte.d.ts +0 -68
  70. package/containers/ListItem.svelte +0 -48
  71. package/containers/ListItem.svelte.d.ts +0 -26
  72. package/containers/Menus.types.d.ts +0 -22
  73. package/containers/Tab.svelte +0 -327
  74. package/containers/TabList.svelte +0 -126
  75. package/containers/Tabs.types.d.ts +0 -12
  76. package/containers/Tree.constants.d.ts +0 -2
  77. package/containers/Tree.constants.js +0 -2
  78. package/containers/Tree.svelte +0 -222
  79. package/containers/Tree.svelte.d.ts +0 -50
  80. package/containers/Tree.types.d.ts +0 -47
  81. package/containers/TreeNode.svelte +0 -266
  82. package/containers/TreeNode.svelte.d.ts +0 -43
  83. package/display/Label.svelte +0 -27
  84. package/display/Label.svelte.d.ts +0 -20
  85. package/display/Progress.types.d.ts +0 -1
  86. package/inputs/Input.svelte +0 -129
  87. package/inputs/Select.svelte.d.ts +0 -62
  88. package/inputs/Slider.svelte.d.ts +0 -28
  89. package/inputs/TextArea.svelte +0 -154
  90. package/surfaces/CloseX.svelte +0 -5
  91. package/surfaces/CloseX.svelte.d.ts +0 -23
  92. package/surfaces/Portal.svelte +0 -14
  93. package/surfaces/Portal.svelte.d.ts +0 -21
  94. /package/{buttons/Button.svelte.d.ts → Button.svelte.d.ts} +0 -0
  95. /package/{buttons/Button.types.d.ts → Button.types.d.ts} +0 -0
  96. /package/{buttons/Button.types.js → Button.types.js} +0 -0
  97. /package/{surfaces/Dialog.svelte.d.ts → Dialog.svelte.d.ts} +0 -0
  98. /package/{containers/Menus.types.js → Field.types.js} +0 -0
  99. /package/{containers/Tabs.types.js → List.types.js} +0 -0
  100. /package/{containers/Menu.svelte.d.ts → Menu.svelte.d.ts} +0 -0
  101. /package/{containers/MenuBar.svelte.d.ts → MenuBar.svelte.d.ts} +0 -0
  102. /package/{containers/MenuItemDisplay.svelte → MenuItemDisplay.svelte} +0 -0
  103. /package/{containers/MenuItemDisplay.svelte.d.ts → MenuItemDisplay.svelte.d.ts} +0 -0
  104. /package/{containers/MenuSeparator.svelte.d.ts → MenuSeparator.svelte.d.ts} +0 -0
  105. /package/{containers/Menus.constants.d.ts → Menus.constants.d.ts} +0 -0
  106. /package/{containers/Menus.constants.js → Menus.constants.js} +0 -0
  107. /package/{containers/Tree.types.js → Menus.types.js} +0 -0
  108. /package/{display/Progress.types.js → Progress.types.js} +0 -0
  109. /package/{inputs/Switch.svelte.d.ts → Switch.svelte.d.ts} +0 -0
  110. /package/{containers/Tabs.constants.d.ts → TabList.constants.d.ts} +0 -0
  111. /package/{containers/Tabs.constants.js → TabList.constants.js} +0 -0
  112. /package/{inputs/TextArea.types.js → TabList.types.js} +0 -0
  113. /package/{inputs/TextArea.types.d.ts → TextArea.types.d.ts} +0 -0
  114. /package/{containers/TreeChevron.svelte.d.ts → TreeChevron.svelte.d.ts} +0 -0
  115. /package/{clickOutside.d.ts → actions/clickOutside.d.ts} +0 -0
  116. /package/{clickOutside.js → actions/clickOutside.js} +0 -0
  117. /package/{forwardEvents.d.ts → actions/forwardEvents.d.ts} +0 -0
  118. /package/{portal.d.ts → actions/portal.d.ts} +0 -0
  119. /package/{portal.js → actions/portal.js} +0 -0
package/Tooltip.svelte ADDED
@@ -0,0 +1,182 @@
1
+ <script>import { portal } from "./actions/portal";
2
+ import { arrow, autoUpdate, computePosition, flip, offset } from "@floating-ui/dom";
3
+ import { onMount } from "svelte";
4
+ import { fade } from "svelte/transition";
5
+ export let autoShow = void 0;
6
+ export let hoverDelayMilliseconds = 1e3;
7
+ export let open = false;
8
+ export let placement = "top";
9
+ export let portalTarget = void 0;
10
+ let anchorRef;
11
+ let tooltipRef;
12
+ let arrowRef;
13
+ let position = void 0;
14
+ $:
15
+ reference = $$slots.default ? anchorRef?.previousElementSibling : void 0;
16
+ const computeTooltipPosition = async () => {
17
+ if (reference && tooltipRef && arrowRef) {
18
+ const floatingOffset = Math.sqrt(2 * arrowRef.offsetWidth ** 2) / 2;
19
+ const middleware = [
20
+ offset(floatingOffset),
21
+ flip({ fallbackPlacements: ["top", "bottom", "right", "left"] }),
22
+ arrow({
23
+ element: arrowRef
24
+ })
25
+ ];
26
+ console.log(placement);
27
+ position = await computePosition(reference, tooltipRef, {
28
+ placement,
29
+ middleware
30
+ });
31
+ } else {
32
+ position = void 0;
33
+ }
34
+ };
35
+ let cleanupAutoUpdate = () => {
36
+ };
37
+ const autoUpdateTooltipPosition = () => {
38
+ cleanupAutoUpdate();
39
+ cleanupAutoUpdate = () => {
40
+ };
41
+ if (reference && tooltipRef) {
42
+ cleanupAutoUpdate = autoUpdate(reference, tooltipRef, computeTooltipPosition);
43
+ }
44
+ };
45
+ $:
46
+ reference, tooltipRef, autoUpdateTooltipPosition();
47
+ $:
48
+ open, placement, computeTooltipPosition();
49
+ $:
50
+ tipStyle = position ? `left:${position.x}px; top:${position.y}px;` : "";
51
+ const getArrowPlacementStyle = (position2) => {
52
+ if (position2?.placement) {
53
+ switch (position2.placement) {
54
+ case "top":
55
+ case "top-start":
56
+ case "top-end":
57
+ return `bottom: -${arrowRef.offsetWidth}px;transform:translate(0, -50%) rotate(135deg);`;
58
+ case "right":
59
+ case "right-start":
60
+ case "right-end":
61
+ return `left: -${arrowRef.offsetWidth}px;transform:translate(50%, 0) rotate(225deg);`;
62
+ case "bottom":
63
+ case "bottom-start":
64
+ case "bottom-end":
65
+ return `top: -${arrowRef.offsetWidth}px;transform:translate(0, 50%) rotate(-45deg);`;
66
+ case "left":
67
+ case "left-start":
68
+ case "left-end":
69
+ return `right: -${arrowRef.offsetWidth}px;transform:translate(-50%, 0) rotate(45deg);`;
70
+ }
71
+ }
72
+ return "";
73
+ };
74
+ const getArrowOffsetStyle = (position2) => {
75
+ const arrow2 = position2?.middlewareData?.arrow;
76
+ if (arrow2) {
77
+ if (arrow2.x !== null && arrow2.x !== void 0) {
78
+ return `left: ${arrow2.x}px;`;
79
+ } else if (arrow2.y !== null && arrow2.y !== void 0) {
80
+ return `top: ${arrow2.y}px;`;
81
+ }
82
+ }
83
+ return "";
84
+ };
85
+ $:
86
+ arrowStyle = getArrowPlacementStyle(position) + getArrowOffsetStyle(position);
87
+ const show = () => open = true;
88
+ const hide = () => open = false;
89
+ const toggle = () => open = !open;
90
+ const delayShow = () => {
91
+ hoverDelayMilliseconds === 0 ? show() : setTimeout(() => {
92
+ show();
93
+ }, hoverDelayMilliseconds);
94
+ };
95
+ let cleanupAutoShowUpdate = () => {
96
+ };
97
+ const autoShowUpdate = () => {
98
+ cleanupAutoShowUpdate();
99
+ cleanupAutoShowUpdate = () => {
100
+ };
101
+ const element = reference;
102
+ if (element) {
103
+ switch (autoShow) {
104
+ case "click":
105
+ element.addEventListener("click", toggle);
106
+ cleanupAutoShowUpdate = () => element.removeEventListener("click", toggle);
107
+ break;
108
+ case "hover":
109
+ element.addEventListener("mouseenter", delayShow);
110
+ element.addEventListener("mouseleave", hide);
111
+ cleanupAutoShowUpdate = () => {
112
+ element.removeEventListener("mouseenter", delayShow);
113
+ element.removeEventListener("mouseleave", hide);
114
+ };
115
+ }
116
+ }
117
+ };
118
+ $:
119
+ reference, autoShow, autoShowUpdate();
120
+ let mounted = false;
121
+ onMount(() => {
122
+ mounted = true;
123
+ portalTarget = portalTarget || document.body;
124
+ autoUpdateTooltipPosition();
125
+ computeTooltipPosition();
126
+ autoShowUpdate();
127
+ });
128
+ </script>
129
+
130
+ <slot />
131
+ <div class="sterling-tooltip-anchor" bind:this={anchorRef} />
132
+
133
+ {#if open}
134
+ <div
135
+ class="sterling-tooltip-portal"
136
+ use:portal={{ target: document.body }}
137
+ transition:fade={{ duration: 250 }}
138
+ >
139
+ <div bind:this={tooltipRef} class="sterling-tooltip" style={tipStyle}>
140
+ <div class="arrow" bind:this={arrowRef} style={arrowStyle} />
141
+ <slot name="tip" />
142
+ </div>
143
+ </div>
144
+ {/if}
145
+
146
+ <style>
147
+ .sterling-tooltip-anchor {
148
+ display: none;
149
+ width: 0;
150
+ height: 0;
151
+ }
152
+
153
+ .sterling-tooltip-portal {
154
+ position: relative;
155
+ overflow: visible;
156
+ }
157
+
158
+ .sterling-tooltip {
159
+ background-color: var(--stsv-Common__background-color);
160
+ border-color: var(--stsv-Common__border-color);
161
+ border-radius: var(--stsv-Common__border-radius);
162
+ border-style: var(--stsv-Common__border-style);
163
+ border-width: var(--stsv-Common__border-width);
164
+ color: var(--stsv-Common__color);
165
+ position: absolute;
166
+ overflow: visible;
167
+ box-shadow: rgba(0, 0, 0, 0.4) 2px 2px 4px -1px;
168
+ z-index: 4;
169
+ }
170
+
171
+ .arrow {
172
+ position: absolute;
173
+ width: 10px;
174
+ height: 10px;
175
+ background-color: var(--stsv-Common__background-color);
176
+ border-color: var(--stsv-Common__border-color);
177
+ border-radius: var(--stsv-Common__border-radius);
178
+ border-style: var(--stsv-Common__border-style);
179
+ border-width: var(--stsv-Common__border-width);
180
+ clip-path: polygon(0% 1%, 100% 1%, 100% 100%, 0% 1%);
181
+ }
182
+ </style>
@@ -0,0 +1,24 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import type { TooltipAutoShow } from './Tooltip.types';
3
+ declare const __propDef: {
4
+ props: {
5
+ autoShow?: TooltipAutoShow | undefined;
6
+ hoverDelayMilliseconds?: number | undefined;
7
+ open?: boolean | undefined;
8
+ placement?: import("@floating-ui/core").Placement | undefined;
9
+ portalTarget?: HTMLElement | undefined;
10
+ };
11
+ events: {
12
+ [evt: string]: CustomEvent<any>;
13
+ };
14
+ slots: {
15
+ default: {};
16
+ tip: {};
17
+ };
18
+ };
19
+ export type TooltipProps = typeof __propDef.props;
20
+ export type TooltipEvents = typeof __propDef.events;
21
+ export type TooltipSlots = typeof __propDef.slots;
22
+ export default class Tooltip extends SvelteComponentTyped<TooltipProps, TooltipEvents, TooltipSlots> {
23
+ }
24
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { Placement } from '@floating-ui/dom';
2
+ export type TooltipAutoShow = 'hover' | 'click';
3
+ export type TooltipPlacement = Placement;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export declare const treeContextKey = "sterlingTree";
2
+ export declare const treeItemContextKey = "sterlingTreeItem";
@@ -0,0 +1,2 @@
1
+ export const treeContextKey = 'sterlingTree';
2
+ export const treeItemContextKey = 'sterlingTreeItem';
package/Tree.svelte ADDED
@@ -0,0 +1,114 @@
1
+ <script>import { createKeyborg } from "keyborg";
2
+ import { createEventDispatcher, onMount, setContext } from "svelte";
3
+ import { writable } from "svelte/store";
4
+ import { treeContextKey } from "./Tree.constants";
5
+ export let composed = false;
6
+ export let disabled = false;
7
+ export let selectedValue = void 0;
8
+ export let expandedValues = [];
9
+ const selectedValueStore = writable(selectedValue);
10
+ const expandedValuesStore = writable(expandedValues);
11
+ const disabledStore = writable(disabled);
12
+ setContext(treeContextKey, {
13
+ expandedValues: expandedValuesStore,
14
+ selectedValue: selectedValueStore,
15
+ disabled: disabledStore
16
+ });
17
+ const dispatch = createEventDispatcher();
18
+ const raiseExpandCollapse = (expandedValues2) => {
19
+ dispatch("expandCollapse", { expandedValues: expandedValues2 });
20
+ };
21
+ const raiseSelect = (selectedValue2) => {
22
+ dispatch("select", { selectedValue: selectedValue2 });
23
+ };
24
+ let keyborg = createKeyborg(window);
25
+ let usingKeyboard = keyborg.isNavigatingWithKeyboard();
26
+ const keyborgHandler = (value) => {
27
+ usingKeyboard = value;
28
+ };
29
+ $: {
30
+ selectedValueStore.set(selectedValue);
31
+ }
32
+ $: {
33
+ selectedValue = $selectedValueStore;
34
+ raiseSelect($selectedValueStore);
35
+ }
36
+ $: {
37
+ expandedValuesStore.set(expandedValues);
38
+ }
39
+ $: {
40
+ expandedValues = $expandedValuesStore;
41
+ raiseExpandCollapse($expandedValuesStore);
42
+ }
43
+ $: {
44
+ disabledStore.set(disabled);
45
+ }
46
+ onMount(() => {
47
+ keyborg.subscribe(keyborgHandler);
48
+ return () => {
49
+ keyborg.unsubscribe(keyborgHandler);
50
+ };
51
+ });
52
+ </script>
53
+
54
+ <!-- svelte-ignore a11y-no-noninteractive-tabindex -->
55
+ <div
56
+ aria-disabled={disabled}
57
+ class="sterling-tree"
58
+ class:composed
59
+ class:disabled
60
+ class:using-keyboard={usingKeyboard}
61
+ role="tree"
62
+ >
63
+ <slot />
64
+ </div>
65
+
66
+ <style>
67
+ .sterling-tree {
68
+ background-color: var(--stsv-Common__background-color);
69
+ border-color: var(--stsv-Common__border-color);
70
+ border-radius: var(--stsv-Common__border-radius);
71
+ border-style: var(--stsv-Common__border-style);
72
+ border-width: var(--stsv-Common__border-width);
73
+ box-sizing: border-box;
74
+ color: var(--stsv-Common__color);
75
+ display: flex;
76
+ flex-direction: column;
77
+ flex-wrap: nowrap;
78
+ height: 100%;
79
+ overflow-x: hidden;
80
+ overflow-y: scroll;
81
+ margin: 0;
82
+ position: relative;
83
+ transition: background-color 250ms, color 250ms, border-color 250ms;
84
+ }
85
+
86
+ .sterling-tree:hover {
87
+ border-color: var(--stsv-Common__border-color--hover);
88
+ color: var(--stsv-Common__color--hover);
89
+ }
90
+
91
+ .sterling-tree.using-keyboard:focus-within {
92
+ border-color: var(--stsv-Button__border-color--focus);
93
+ color: var(--stsv-Common__color--focus);
94
+ outline-color: var(--stsv-Common__outline-color);
95
+ outline-offset: var(--stsv-Common__outline-offset);
96
+ outline-style: var(--stsv-Common__outline-style);
97
+ outline-width: var(--stsv-Common__outline-width);
98
+ }
99
+
100
+ .sterling-tree.disabled {
101
+ background-color: var(--stsv-Common__background-color--disabled);
102
+ border-color: var(--stsv--Common__border-color--disabled);
103
+ color: var(--stsv-Common__color--disabled);
104
+ cursor: not-allowed;
105
+ }
106
+
107
+ .sterling-tree.composed,
108
+ .sterling-tree.composed:hover,
109
+ .sterling-tree.composed.using-keyboard:focus-visible,
110
+ .sterling-tree.composed.disabled {
111
+ border: none;
112
+ outline: none;
113
+ }
114
+ </style>
@@ -0,0 +1,24 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ composed?: boolean | undefined;
5
+ disabled?: boolean | undefined;
6
+ selectedValue?: string | undefined;
7
+ expandedValues?: string[] | undefined;
8
+ };
9
+ events: {
10
+ expandCollapse: CustomEvent<any>;
11
+ select: CustomEvent<any>;
12
+ } & {
13
+ [evt: string]: CustomEvent<any>;
14
+ };
15
+ slots: {
16
+ default: {};
17
+ };
18
+ };
19
+ export type TreeProps = typeof __propDef.props;
20
+ export type TreeEvents = typeof __propDef.events;
21
+ export type TreeSlots = typeof __propDef.slots;
22
+ export default class Tree extends SvelteComponentTyped<TreeProps, TreeEvents, TreeSlots> {
23
+ }
24
+ export {};
@@ -0,0 +1,28 @@
1
+ import type { Readable, Writable } from 'svelte/store';
2
+ /**
3
+ * Context for a Tree and its tree items.
4
+ */
5
+ export type TreeContext = {
6
+ /**
7
+ * The IDs of the expanded ttree tree items.
8
+ */
9
+ expandedValues: Writable<string[]>;
10
+ /**
11
+ * The ID of the selected tree tree item.
12
+ */
13
+ selectedValue: Writable<string | undefined>;
14
+ /** If the tree is disabled */
15
+ disabled: Readable<boolean>;
16
+ };
17
+ /**
18
+ * The context for a tree item.
19
+ */
20
+ export type TreeItemContext = {
21
+ /**
22
+ * How many levels deep this tree item is in the tree hierarchy.
23
+ * A top level item's depth is zero.
24
+ */
25
+ depth: number;
26
+ /** If the tree item is disabled */
27
+ disabled: Readable<boolean>;
28
+ };
package/Tree.types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -1,7 +1,7 @@
1
1
  <script>import { onMount } from "svelte";
2
2
  export let expanded = false;
3
3
  export let hasChildren = false;
4
- let lastValue = expanded;
4
+ let previousExpanded = expanded;
5
5
  let mounted = false;
6
6
  onMount(() => {
7
7
  setTimeout(() => {
@@ -10,10 +10,10 @@ onMount(() => {
10
10
  });
11
11
  let animate = false;
12
12
  $: {
13
- if (expanded !== lastValue && mounted) {
13
+ if (expanded !== previousExpanded && mounted) {
14
14
  animate = true;
15
15
  }
16
- lastValue = expanded;
16
+ previousExpanded = expanded;
17
17
  }
18
18
  </script>
19
19
 
@@ -0,0 +1,276 @@
1
+ <script>import { getContext, setContext } from "svelte";
2
+ import { slide } from "svelte/transition";
3
+ import { treeContextKey, treeItemContextKey } from "./Tree.constants";
4
+ import TreeItemDisplay from "./TreeItemDisplay.svelte";
5
+ import { writable } from "svelte/store";
6
+ export let disabled = false;
7
+ export let value;
8
+ const {
9
+ expandedValues,
10
+ selectedValue,
11
+ disabled: treeDisabled
12
+ } = getContext(treeContextKey);
13
+ const { depth = 0, disabled: parentDisabled } = getContext(treeItemContextKey) || {};
14
+ let treeItemRef;
15
+ $:
16
+ hasChildren = $$slots.default;
17
+ $:
18
+ expanded = $expandedValues.includes(value);
19
+ $:
20
+ selected = $selectedValue === value;
21
+ $:
22
+ _disabled = disabled || $parentDisabled || $treeDisabled;
23
+ const disabledStore = writable(_disabled);
24
+ $: {
25
+ disabledStore.set(_disabled);
26
+ }
27
+ const collapseItem = (index) => {
28
+ if (!disabled) {
29
+ index = index ?? $expandedValues.findIndex((id) => id === value);
30
+ if (index !== -1) {
31
+ expandedValues.set([
32
+ ...$expandedValues.slice(0, index),
33
+ ...$expandedValues.slice(index + 1)
34
+ ]);
35
+ return true;
36
+ }
37
+ }
38
+ return false;
39
+ };
40
+ const expandItem = (index) => {
41
+ if (!disabled) {
42
+ index = index ?? $expandedValues.findIndex((id) => id === value);
43
+ if (index === -1) {
44
+ expandedValues.set([...$expandedValues, value]);
45
+ return true;
46
+ }
47
+ }
48
+ return false;
49
+ };
50
+ const toggleExpanded = () => {
51
+ if (!disabled) {
52
+ const index = $expandedValues.findIndex((id) => id === value);
53
+ return index !== -1 ? collapseItem(index) : expandItem(index);
54
+ }
55
+ return false;
56
+ };
57
+ const focusItem = (treeItemElement) => {
58
+ if (!_disabled) {
59
+ const item = treeItemElement.querySelector(".item");
60
+ item?.focus();
61
+ }
62
+ };
63
+ const selectItemById = (value2) => {
64
+ if (!_disabled) {
65
+ selectedValue.set(value2);
66
+ }
67
+ };
68
+ export const selectItem = () => {
69
+ if (!_disabled) {
70
+ selectItemById(value);
71
+ }
72
+ };
73
+ const selectParentItem = () => {
74
+ if (!_disabled) {
75
+ let candidate = treeItemRef.parentElement?.closest('[role="treeitem"][data-value]');
76
+ let candidateValue = candidate?.getAttribute("data-value");
77
+ if (candidateValue && candidate) {
78
+ selectItemById(candidateValue);
79
+ focusItem(candidate);
80
+ return true;
81
+ }
82
+ }
83
+ return false;
84
+ };
85
+ const selectNextItem = () => {
86
+ if (!_disabled) {
87
+ let candidateValue = void 0;
88
+ let candidate = treeItemRef.querySelector('[role="treeitem"][data-value]');
89
+ candidateValue = candidate?.getAttribute("data-value");
90
+ if (!candidateValue) {
91
+ candidate = treeItemRef.nextElementSibling;
92
+ while (candidate && candidate.getAttribute("data-value") === null) {
93
+ candidate = candidate.nextElementSibling;
94
+ }
95
+ candidateValue = candidate?.getAttribute("data-value");
96
+ }
97
+ if (!candidateValue) {
98
+ let ancestor = treeItemRef.parentElement?.closest(
99
+ '[role="treeitem"][data-value]'
100
+ );
101
+ while (ancestor && !candidateValue) {
102
+ candidate = ancestor?.nextElementSibling;
103
+ candidateValue = candidate?.getAttribute("data-value");
104
+ ancestor = ancestor.parentElement?.closest('[role="treeitem"][data-value]');
105
+ }
106
+ }
107
+ if (candidateValue && candidate) {
108
+ selectItemById(candidateValue);
109
+ focusItem(candidate);
110
+ return true;
111
+ }
112
+ }
113
+ return false;
114
+ };
115
+ const selectPreviousItem = () => {
116
+ if (!_disabled) {
117
+ let candidate = void 0;
118
+ let candidateValue = void 0;
119
+ const previousSibling = treeItemRef?.previousElementSibling;
120
+ if (previousSibling) {
121
+ const decendants = previousSibling.querySelectorAll('[role="treeitem"][data-value]');
122
+ if (decendants) {
123
+ candidate = decendants[decendants.length - 1];
124
+ candidateValue = candidate?.getAttribute("data-value");
125
+ }
126
+ if (!candidateValue) {
127
+ candidate = previousSibling;
128
+ candidateValue = candidate?.getAttribute("data-value");
129
+ }
130
+ }
131
+ if (!candidateValue) {
132
+ candidate = treeItemRef.parentElement?.closest('[role="treeitem"][data-value]');
133
+ candidateValue = candidate?.getAttribute("data-value");
134
+ }
135
+ if (candidateValue && candidate) {
136
+ selectItemById(candidateValue);
137
+ focusItem(candidate);
138
+ return true;
139
+ }
140
+ }
141
+ return false;
142
+ };
143
+ const onClick = () => {
144
+ if (!_disabled) {
145
+ toggleExpanded();
146
+ selectItem();
147
+ }
148
+ };
149
+ const onKeydown = (event) => {
150
+ if (!event.altKey && !event.ctrlKey && !event.shiftKey) {
151
+ switch (event.key) {
152
+ case "Enter":
153
+ case " ":
154
+ if (toggleExpanded()) {
155
+ event.preventDefault();
156
+ event.stopPropagation();
157
+ return false;
158
+ }
159
+ break;
160
+ case "ArrowRight":
161
+ if (hasChildren) {
162
+ if (expanded) {
163
+ if (selectNextItem()) {
164
+ event.preventDefault();
165
+ event.stopPropagation();
166
+ return false;
167
+ }
168
+ } else if (expandItem()) {
169
+ event.preventDefault();
170
+ event.stopPropagation();
171
+ return false;
172
+ }
173
+ }
174
+ break;
175
+ case "ArrowLeft":
176
+ if (hasChildren && expanded) {
177
+ if (collapseItem()) {
178
+ event.preventDefault();
179
+ event.stopPropagation();
180
+ return false;
181
+ }
182
+ } else if (selectParentItem()) {
183
+ event.preventDefault();
184
+ event.stopPropagation();
185
+ return false;
186
+ }
187
+ break;
188
+ case "ArrowUp":
189
+ if (selectPreviousItem()) {
190
+ event.preventDefault();
191
+ event.stopPropagation();
192
+ return false;
193
+ }
194
+ break;
195
+ case "ArrowDown":
196
+ if (selectNextItem()) {
197
+ event.preventDefault();
198
+ event.stopPropagation();
199
+ return false;
200
+ }
201
+ break;
202
+ }
203
+ }
204
+ };
205
+ setContext(treeItemContextKey, { depth: depth + 1, disabled: disabledStore });
206
+ </script>
207
+
208
+ <!--
209
+ @component
210
+ A item in a Tree displaying the item and children.
211
+ -->
212
+ <div
213
+ aria-selected={selected ? true : undefined}
214
+ aria-expanded={expanded}
215
+ bind:this={treeItemRef}
216
+ class="sterling-tree-item"
217
+ class:disabled={_disabled}
218
+ data-value={value}
219
+ role="treeitem"
220
+ on:blur
221
+ on:click
222
+ on:dblclick
223
+ on:focus
224
+ on:focusin
225
+ on:focusout
226
+ on:keydown
227
+ on:keypress
228
+ on:keyup
229
+ on:mousedown
230
+ on:mouseenter
231
+ on:mouseleave
232
+ on:mousemove
233
+ on:mouseover
234
+ on:mouseout
235
+ on:mouseup
236
+ on:pointercancel
237
+ on:pointerdown
238
+ on:pointerenter
239
+ on:pointerleave
240
+ on:pointermove
241
+ on:pointerover
242
+ on:pointerout
243
+ on:pointerup
244
+ on:wheel
245
+ {...$$restProps}
246
+ >
247
+ <!-- svelte-ignore a11y-no-noninteractive-tabindex -->
248
+ <div
249
+ class="item"
250
+ class:selected
251
+ tabindex={selected ? 0 : -1}
252
+ on:click={onClick}
253
+ on:keydown={onKeydown}
254
+ >
255
+ <slot name="item" {depth} disabled={_disabled} {expanded} {hasChildren} {selected} {value}>
256
+ <TreeItemDisplay {depth} disabled={_disabled} {expanded} {hasChildren} {selected} {value}>
257
+ <svelte:fragment let:depth let:disabled let:expanded let:hasChildren let:selected let:value>
258
+ <slot name="label" {depth} {disabled} {expanded} {hasChildren} {selected} {value}
259
+ >{value}</slot
260
+ >
261
+ </svelte:fragment>
262
+ </TreeItemDisplay>
263
+ </slot>
264
+ </div>
265
+ {#if expanded && hasChildren}
266
+ <div class="children" transition:slide={{ duration: 200 }} role="group">
267
+ <slot />
268
+ </div>
269
+ {/if}
270
+ </div>
271
+
272
+ <style>
273
+ .item {
274
+ outline: none;
275
+ }
276
+ </style>