@geoffcox/sterling-svelte 0.0.14 → 0.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/@types/clickOutside.d.ts +9 -3
- package/buttons/Button.svelte +1 -1
- package/buttons/Button.svelte.d.ts +4 -1
- package/buttons/MenuButton.svelte +102 -0
- package/buttons/MenuButton.svelte.d.ts +54 -0
- package/clickOutside.js +3 -1
- package/containers/List.svelte +1 -1
- package/containers/Menu.svelte +100 -0
- package/containers/Menu.svelte.d.ts +20 -0
- package/containers/MenuBar.svelte +97 -0
- package/containers/MenuBar.svelte.d.ts +43 -0
- package/containers/MenuItem.svelte +350 -0
- package/containers/MenuItem.svelte.d.ts +61 -0
- package/containers/MenuItemDisplay.svelte +97 -0
- package/containers/MenuItemDisplay.svelte.d.ts +21 -0
- package/containers/MenuSeparator.svelte +42 -0
- package/containers/MenuSeparator.svelte.d.ts +76 -0
- package/containers/Menus.constants.d.ts +2 -0
- package/containers/Menus.constants.js +2 -0
- package/containers/Menus.types.d.ts +22 -0
- package/containers/Menus.types.js +1 -0
- package/containers/Menus.utils.d.ts +5 -0
- package/containers/Menus.utils.js +20 -0
- package/containers/Tab.svelte +327 -0
- package/containers/Tab.svelte.d.ts +55 -0
- package/containers/TabList.svelte +126 -0
- package/containers/TabList.svelte.d.ts +56 -0
- package/containers/Tabs.constants.d.ts +1 -0
- package/containers/Tabs.constants.js +1 -0
- package/containers/Tabs.types.d.ts +12 -0
- package/containers/Tabs.types.js +1 -0
- package/containers/TreeNode.svelte +0 -1
- package/forwardEvents.d.ts +12 -0
- package/forwardEvents.js +34 -0
- package/index.d.ts +12 -2
- package/index.js +9 -1
- package/inputs/Checkbox.svelte +2 -2
- package/inputs/Checkbox.svelte.d.ts +4 -1
- package/inputs/Input.svelte +1 -1
- package/inputs/Select.svelte +5 -5
- package/inputs/TextArea.svelte +2 -2
- package/package.json +18 -1
- package/portal.d.ts +8 -0
- package/portal.js +19 -0
- package/surfaces/Portal.svelte +14 -0
- package/surfaces/Portal.svelte.d.ts +21 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
<script>import { getContext } from "svelte";
|
|
2
|
+
import { tabListContextKey } from "./Tabs.constants";
|
|
3
|
+
export let data = void 0;
|
|
4
|
+
export let disabled = false;
|
|
5
|
+
export let tabId = void 0;
|
|
6
|
+
export let text = void 0;
|
|
7
|
+
export let selected = false;
|
|
8
|
+
let tabRef;
|
|
9
|
+
const {
|
|
10
|
+
disabled: tabListDisabled,
|
|
11
|
+
selectedTabId,
|
|
12
|
+
selectionFollowsFocus,
|
|
13
|
+
vertical
|
|
14
|
+
} = getContext(tabListContextKey);
|
|
15
|
+
$:
|
|
16
|
+
_tabId = tabId || data?.tabId;
|
|
17
|
+
$:
|
|
18
|
+
_text = text || data?.text || _tabId;
|
|
19
|
+
$:
|
|
20
|
+
_disabled = $tabListDisabled || disabled || data?.disabled === true;
|
|
21
|
+
$: {
|
|
22
|
+
if (!_tabId) {
|
|
23
|
+
throw new Error("Both tabId and data.tabId are missing");
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
$: {
|
|
27
|
+
selected = $selectedTabId === _tabId;
|
|
28
|
+
}
|
|
29
|
+
$: {
|
|
30
|
+
if (selected) {
|
|
31
|
+
selectedTabId.set(_tabId);
|
|
32
|
+
tabRef?.focus();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const getFirstActiveTab = () => {
|
|
36
|
+
let foundTab = tabRef.parentElement?.firstElementChild;
|
|
37
|
+
while (foundTab) {
|
|
38
|
+
if (!foundTab.disabled && foundTab.getAttribute("data-tab-id")) {
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
foundTab = foundTab.nextElementSibling;
|
|
42
|
+
}
|
|
43
|
+
return foundTab;
|
|
44
|
+
};
|
|
45
|
+
const getLastActiveTab = () => {
|
|
46
|
+
let foundTab = tabRef.parentElement?.lastElementChild;
|
|
47
|
+
while (foundTab) {
|
|
48
|
+
if (!foundTab.disabled && foundTab.getAttribute("data-tab-id")) {
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
foundTab = foundTab.previousElementSibling;
|
|
52
|
+
}
|
|
53
|
+
return foundTab;
|
|
54
|
+
};
|
|
55
|
+
const getPreviousActiveTab = () => {
|
|
56
|
+
let foundTab = tabRef?.previousElementSibling;
|
|
57
|
+
while (foundTab) {
|
|
58
|
+
if (!foundTab.disabled && foundTab.getAttribute("data-tab-id")) {
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
foundTab = foundTab.previousElementSibling;
|
|
62
|
+
}
|
|
63
|
+
return foundTab;
|
|
64
|
+
};
|
|
65
|
+
const getNextActiveTab = () => {
|
|
66
|
+
let foundTab = tabRef?.nextElementSibling;
|
|
67
|
+
while (foundTab) {
|
|
68
|
+
if (!foundTab.disabled && foundTab.getAttribute("data-tab-id")) {
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
foundTab = foundTab.nextElementSibling;
|
|
72
|
+
}
|
|
73
|
+
return foundTab;
|
|
74
|
+
};
|
|
75
|
+
const focusFirstTab = () => {
|
|
76
|
+
if (!_disabled) {
|
|
77
|
+
let foundTab = getFirstActiveTab();
|
|
78
|
+
if (foundTab) {
|
|
79
|
+
foundTab.focus();
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
};
|
|
85
|
+
const focusLastTab = () => {
|
|
86
|
+
if (!_disabled) {
|
|
87
|
+
let foundTab = getLastActiveTab();
|
|
88
|
+
if (foundTab) {
|
|
89
|
+
foundTab.focus();
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return false;
|
|
94
|
+
};
|
|
95
|
+
const focusPreviousTab = () => {
|
|
96
|
+
if (!_disabled) {
|
|
97
|
+
let foundTab = getPreviousActiveTab();
|
|
98
|
+
if (foundTab) {
|
|
99
|
+
foundTab.focus();
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return false;
|
|
104
|
+
};
|
|
105
|
+
const focusNextTab = () => {
|
|
106
|
+
if (!_disabled) {
|
|
107
|
+
let foundTab = getNextActiveTab();
|
|
108
|
+
if (foundTab) {
|
|
109
|
+
foundTab.focus();
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return false;
|
|
114
|
+
};
|
|
115
|
+
const onClick = (event) => {
|
|
116
|
+
if (!_disabled) {
|
|
117
|
+
selectedTabId.set(_tabId);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
const onFocus = (event) => {
|
|
121
|
+
if (!_disabled && $selectionFollowsFocus) {
|
|
122
|
+
selectedTabId.set(_tabId);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
const onKeydown = (event) => {
|
|
126
|
+
if (!_disabled && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey) {
|
|
127
|
+
switch (event.key) {
|
|
128
|
+
case "Home":
|
|
129
|
+
if (focusFirstTab()) {
|
|
130
|
+
event.preventDefault();
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
break;
|
|
134
|
+
case "End":
|
|
135
|
+
if (focusLastTab()) {
|
|
136
|
+
event.preventDefault();
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
break;
|
|
140
|
+
case "ArrowLeft":
|
|
141
|
+
if (!$vertical && focusPreviousTab()) {
|
|
142
|
+
event.preventDefault();
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
break;
|
|
146
|
+
case "ArrowRight":
|
|
147
|
+
if (!$vertical && focusNextTab()) {
|
|
148
|
+
event.preventDefault();
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
break;
|
|
152
|
+
case "ArrowUp":
|
|
153
|
+
if ($vertical && focusPreviousTab()) {
|
|
154
|
+
event.preventDefault();
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
break;
|
|
158
|
+
case "ArrowDown":
|
|
159
|
+
if ($vertical && focusNextTab()) {
|
|
160
|
+
event.preventDefault();
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
break;
|
|
164
|
+
default:
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
</script>
|
|
170
|
+
|
|
171
|
+
<button
|
|
172
|
+
bind:this={tabRef}
|
|
173
|
+
class="sterling-tab"
|
|
174
|
+
disabled={_disabled}
|
|
175
|
+
class:selected
|
|
176
|
+
class:vertical={$vertical}
|
|
177
|
+
data-tab-id={_tabId}
|
|
178
|
+
role="tab"
|
|
179
|
+
tabindex={selected ? 0 : -1}
|
|
180
|
+
type="button"
|
|
181
|
+
on:blur
|
|
182
|
+
on:click
|
|
183
|
+
on:dblclick
|
|
184
|
+
on:focus
|
|
185
|
+
on:focusin
|
|
186
|
+
on:focusout
|
|
187
|
+
on:keydown
|
|
188
|
+
on:keypress
|
|
189
|
+
on:keyup
|
|
190
|
+
on:mousedown
|
|
191
|
+
on:mouseenter
|
|
192
|
+
on:mouseleave
|
|
193
|
+
on:mousemove
|
|
194
|
+
on:mouseover
|
|
195
|
+
on:mouseout
|
|
196
|
+
on:mouseup
|
|
197
|
+
on:pointercancel
|
|
198
|
+
on:pointerdown
|
|
199
|
+
on:pointerenter
|
|
200
|
+
on:pointerleave
|
|
201
|
+
on:pointermove
|
|
202
|
+
on:pointerover
|
|
203
|
+
on:pointerout
|
|
204
|
+
on:pointerup
|
|
205
|
+
on:wheel
|
|
206
|
+
on:click={onClick}
|
|
207
|
+
on:focus={onFocus}
|
|
208
|
+
on:keydown={onKeydown}
|
|
209
|
+
>
|
|
210
|
+
<div class="content">
|
|
211
|
+
<slot {data} disabled={_disabled} {selected} tabId={_tabId} text={_text}>
|
|
212
|
+
<div class="text">
|
|
213
|
+
{_text || _tabId}
|
|
214
|
+
</div>
|
|
215
|
+
</slot>
|
|
216
|
+
</div>
|
|
217
|
+
<div class="indicator" />
|
|
218
|
+
</button>
|
|
219
|
+
|
|
220
|
+
<style>
|
|
221
|
+
.sterling-tab {
|
|
222
|
+
align-content: center;
|
|
223
|
+
align-items: center;
|
|
224
|
+
background-color: var(--Common__background-color);
|
|
225
|
+
border-color: transparent;
|
|
226
|
+
border-radius: var(--Button__border-radius);
|
|
227
|
+
border-style: var(--Common__border-style);
|
|
228
|
+
border-width: 0;
|
|
229
|
+
box-sizing: border-box;
|
|
230
|
+
color: var(--Common__color);
|
|
231
|
+
cursor: pointer;
|
|
232
|
+
display: grid;
|
|
233
|
+
font: inherit;
|
|
234
|
+
overflow: hidden;
|
|
235
|
+
padding: 0.5em 1em 0.25em 1em;
|
|
236
|
+
text-decoration: none;
|
|
237
|
+
text-overflow: ellipsis;
|
|
238
|
+
transition: background-color 250ms, color 250ms, border-color 250ms;
|
|
239
|
+
white-space: nowrap;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.sterling-tab:not(.vertical) {
|
|
243
|
+
grid-template-columns: 1fr;
|
|
244
|
+
grid-template-rows: 1fr 1em;
|
|
245
|
+
justify-content: center;
|
|
246
|
+
justify-items: center;
|
|
247
|
+
row-gap: 0.15em;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.sterling-tab.vertical {
|
|
251
|
+
grid-template-columns: auto 1em;
|
|
252
|
+
grid-template-rows: 1fr;
|
|
253
|
+
align-content: center;
|
|
254
|
+
align-items: center;
|
|
255
|
+
justify-content: flex-end;
|
|
256
|
+
justify-items: flex-end;
|
|
257
|
+
column-gap: 0.15em;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.sterling-tab:hover {
|
|
261
|
+
background-color: var(--Common__background-color--hover);
|
|
262
|
+
color: var(--Common__color--hover);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.sterling-tab:active {
|
|
266
|
+
background-color: var(--Common__background-color--active);
|
|
267
|
+
color: var(--Common__color--active);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.sterling-tab:focus-visible {
|
|
271
|
+
outline-color: var(--Common__outline-color);
|
|
272
|
+
outline-offset: var(--Common__outline-offset);
|
|
273
|
+
outline-style: var(--Common__outline-style);
|
|
274
|
+
outline-width: var(--Common__outline-width);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.sterling-tab:disabled {
|
|
278
|
+
color: var(--Common__color--disabled);
|
|
279
|
+
cursor: not-allowed;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.content {
|
|
283
|
+
padding: 0 0.2em;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.sterling-tab.vertical .content .text {
|
|
287
|
+
padding-top: 0.25em;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.indicator {
|
|
291
|
+
background-color: transparent;
|
|
292
|
+
border-radius: 10000px;
|
|
293
|
+
transition: background-color 250ms;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.sterling-tab:not(.vertical) .indicator {
|
|
297
|
+
justify-self: stretch;
|
|
298
|
+
height: 0.4em;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.sterling-tab.vertical .indicator {
|
|
302
|
+
align-self: stretch;
|
|
303
|
+
width: 0.4em;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.sterling-tab:hover .indicator {
|
|
307
|
+
background-color: var(--Display__color--faint);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.sterling-tab:active .indicator {
|
|
311
|
+
background-color: var(--Button__border-color--hover);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.sterling-tab:disabled .indicator,
|
|
315
|
+
.sterling-tab:disabled:hover .indicator,
|
|
316
|
+
.sterling-tab:disabled:active .indicator {
|
|
317
|
+
background-color: transparent;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.sterling-tab.selected .indicator {
|
|
321
|
+
background-color: var(--Input__color);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.sterling-tab.selected:disabled .indicator {
|
|
325
|
+
background-color: var(--Input__color--disabled);
|
|
326
|
+
}
|
|
327
|
+
</style>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import type { TabData } from './Tabs.types';
|
|
3
|
+
declare class __sveltets_Render<T> {
|
|
4
|
+
props(): {
|
|
5
|
+
data?: TabData<T> | undefined;
|
|
6
|
+
disabled?: boolean | undefined;
|
|
7
|
+
tabId?: string | undefined;
|
|
8
|
+
text?: string | undefined;
|
|
9
|
+
selected?: boolean | undefined;
|
|
10
|
+
};
|
|
11
|
+
events(): {
|
|
12
|
+
blur: FocusEvent;
|
|
13
|
+
click: MouseEvent;
|
|
14
|
+
dblclick: MouseEvent;
|
|
15
|
+
focus: FocusEvent;
|
|
16
|
+
focusin: FocusEvent;
|
|
17
|
+
focusout: FocusEvent;
|
|
18
|
+
keydown: KeyboardEvent;
|
|
19
|
+
keypress: KeyboardEvent;
|
|
20
|
+
keyup: KeyboardEvent;
|
|
21
|
+
mousedown: MouseEvent;
|
|
22
|
+
mouseenter: MouseEvent;
|
|
23
|
+
mouseleave: MouseEvent;
|
|
24
|
+
mousemove: MouseEvent;
|
|
25
|
+
mouseover: MouseEvent;
|
|
26
|
+
mouseout: MouseEvent;
|
|
27
|
+
mouseup: MouseEvent;
|
|
28
|
+
pointercancel: PointerEvent;
|
|
29
|
+
pointerdown: PointerEvent;
|
|
30
|
+
pointerenter: PointerEvent;
|
|
31
|
+
pointerleave: PointerEvent;
|
|
32
|
+
pointermove: PointerEvent;
|
|
33
|
+
pointerover: PointerEvent;
|
|
34
|
+
pointerout: PointerEvent;
|
|
35
|
+
pointerup: PointerEvent;
|
|
36
|
+
wheel: WheelEvent;
|
|
37
|
+
} & {
|
|
38
|
+
[evt: string]: CustomEvent<any>;
|
|
39
|
+
};
|
|
40
|
+
slots(): {
|
|
41
|
+
default: {
|
|
42
|
+
data: TabData<T> | undefined;
|
|
43
|
+
disabled: boolean;
|
|
44
|
+
selected: boolean;
|
|
45
|
+
tabId: string | undefined;
|
|
46
|
+
text: string | undefined;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export type TabProps<T> = ReturnType<__sveltets_Render<T>['props']>;
|
|
51
|
+
export type TabEvents<T> = ReturnType<__sveltets_Render<T>['events']>;
|
|
52
|
+
export type TabSlots<T> = ReturnType<__sveltets_Render<T>['slots']>;
|
|
53
|
+
export default class Tab<T> extends SvelteComponentTyped<TabProps<T>, TabEvents<T>, TabSlots<T>> {
|
|
54
|
+
}
|
|
55
|
+
export {};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
<script>import { createEventDispatcher, setContext } from "svelte";
|
|
2
|
+
import Tab from "./Tab.svelte";
|
|
3
|
+
import { writable } from "svelte/store";
|
|
4
|
+
import { tabListContextKey } from "./Tabs.constants";
|
|
5
|
+
export let disabled = false;
|
|
6
|
+
export let tabs = [];
|
|
7
|
+
export let vertical = false;
|
|
8
|
+
export let selectedTabId = void 0;
|
|
9
|
+
export let selectionFollowsFocus = false;
|
|
10
|
+
export let selectedTab = void 0;
|
|
11
|
+
const selectedTabIdStore = writable(selectedTabId);
|
|
12
|
+
const selectionFollowsFocusStore = writable(selectionFollowsFocus);
|
|
13
|
+
const verticalStore = writable(vertical);
|
|
14
|
+
const disabledStore = writable(disabled);
|
|
15
|
+
setContext(tabListContextKey, {
|
|
16
|
+
disabled: disabledStore,
|
|
17
|
+
selectedTabId: selectedTabIdStore,
|
|
18
|
+
selectionFollowsFocus: selectionFollowsFocusStore,
|
|
19
|
+
vertical: verticalStore
|
|
20
|
+
});
|
|
21
|
+
const dispatch = createEventDispatcher();
|
|
22
|
+
const raiseSelected = (tabId, tab) => {
|
|
23
|
+
dispatch("select", { tabId, tab });
|
|
24
|
+
};
|
|
25
|
+
$:
|
|
26
|
+
disabledStore.set(disabled);
|
|
27
|
+
$:
|
|
28
|
+
selectedTabIdStore.set(selectedTabId);
|
|
29
|
+
$: {
|
|
30
|
+
selectedTabId = $selectedTabIdStore;
|
|
31
|
+
selectedTab = tabs.find((tab) => tab.tabId === selectedTabId);
|
|
32
|
+
raiseSelected(selectedTabId, selectedTab);
|
|
33
|
+
}
|
|
34
|
+
$:
|
|
35
|
+
selectionFollowsFocusStore.set(selectionFollowsFocus);
|
|
36
|
+
$:
|
|
37
|
+
verticalStore.set(vertical);
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<!--
|
|
41
|
+
@component
|
|
42
|
+
A list of items where a single item can be selected.
|
|
43
|
+
-->
|
|
44
|
+
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
|
45
|
+
<div
|
|
46
|
+
class="sterling-tab-list"
|
|
47
|
+
role="tablist"
|
|
48
|
+
class:vertical
|
|
49
|
+
class:disabled
|
|
50
|
+
on:blur
|
|
51
|
+
on:click
|
|
52
|
+
on:copy
|
|
53
|
+
on:cut
|
|
54
|
+
on:dblclick
|
|
55
|
+
on:focus
|
|
56
|
+
on:focusin
|
|
57
|
+
on:focusout
|
|
58
|
+
on:keydown
|
|
59
|
+
on:keypress
|
|
60
|
+
on:keyup
|
|
61
|
+
on:mousedown
|
|
62
|
+
on:mouseenter
|
|
63
|
+
on:mouseleave
|
|
64
|
+
on:mousemove
|
|
65
|
+
on:mouseover
|
|
66
|
+
on:mouseout
|
|
67
|
+
on:mouseup
|
|
68
|
+
on:scroll
|
|
69
|
+
on:wheel
|
|
70
|
+
on:paste
|
|
71
|
+
{...$$restProps}
|
|
72
|
+
>
|
|
73
|
+
{#each tabs as tab (tab.tabId)}
|
|
74
|
+
<Tab data={tab}>
|
|
75
|
+
<svelte:fragment let:data let:disabled let:selected let:tabId let:text>
|
|
76
|
+
<slot name="tabContent" {data} {disabled} {selected} {tabId} {text}>
|
|
77
|
+
<div class="text">
|
|
78
|
+
{text}
|
|
79
|
+
</div>
|
|
80
|
+
</slot>
|
|
81
|
+
</svelte:fragment>
|
|
82
|
+
</Tab>
|
|
83
|
+
{/each}
|
|
84
|
+
<slot />
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<style>
|
|
88
|
+
.sterling-tab-list {
|
|
89
|
+
box-sizing: border-box;
|
|
90
|
+
display: grid;
|
|
91
|
+
margin: 0;
|
|
92
|
+
padding: calc(2 * var(--Common__outline-width));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.sterling-tab-list:not(.vertical) {
|
|
96
|
+
column-gap: 0.5em;
|
|
97
|
+
grid-auto-flow: column;
|
|
98
|
+
grid-template-columns: repeat(auto-fill, auto);
|
|
99
|
+
grid-template-rows: 1fr;
|
|
100
|
+
overflow-x: scroll;
|
|
101
|
+
overflow-y: hidden;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.sterling-tab-list.vertical {
|
|
105
|
+
grid-auto-flow: row;
|
|
106
|
+
grid-template-rows: auto;
|
|
107
|
+
grid-template-columns: 1fr;
|
|
108
|
+
overflow-x: hidden;
|
|
109
|
+
overflow-y: scroll;
|
|
110
|
+
row-gap: 0.5em;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.sterling-tab-list:hover {
|
|
114
|
+
color: var(--Common__color--hover);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.sterling-tab-list.vertical .text {
|
|
118
|
+
padding-top: 0.25em;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@media (prefers-reduced-motion) {
|
|
122
|
+
.sterling-tab-list {
|
|
123
|
+
transition: none;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
</style>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import type { TabData } from './Tabs.types';
|
|
3
|
+
declare class __sveltets_Render<T> {
|
|
4
|
+
props(): {
|
|
5
|
+
[x: string]: any;
|
|
6
|
+
disabled?: boolean | undefined;
|
|
7
|
+
tabs?: TabData<T>[] | undefined;
|
|
8
|
+
vertical?: boolean | undefined;
|
|
9
|
+
selectedTabId?: string | undefined;
|
|
10
|
+
selectionFollowsFocus?: boolean | undefined;
|
|
11
|
+
selectedTab?: TabData<T> | undefined;
|
|
12
|
+
};
|
|
13
|
+
events(): {
|
|
14
|
+
blur: FocusEvent;
|
|
15
|
+
click: MouseEvent;
|
|
16
|
+
copy: ClipboardEvent;
|
|
17
|
+
cut: ClipboardEvent;
|
|
18
|
+
dblclick: MouseEvent;
|
|
19
|
+
focus: FocusEvent;
|
|
20
|
+
focusin: FocusEvent;
|
|
21
|
+
focusout: FocusEvent;
|
|
22
|
+
keydown: KeyboardEvent;
|
|
23
|
+
keypress: KeyboardEvent;
|
|
24
|
+
keyup: KeyboardEvent;
|
|
25
|
+
mousedown: MouseEvent;
|
|
26
|
+
mouseenter: MouseEvent;
|
|
27
|
+
mouseleave: MouseEvent;
|
|
28
|
+
mousemove: MouseEvent;
|
|
29
|
+
mouseover: MouseEvent;
|
|
30
|
+
mouseout: MouseEvent;
|
|
31
|
+
mouseup: MouseEvent;
|
|
32
|
+
scroll: Event;
|
|
33
|
+
wheel: WheelEvent;
|
|
34
|
+
paste: ClipboardEvent;
|
|
35
|
+
select: CustomEvent<any>;
|
|
36
|
+
} & {
|
|
37
|
+
[evt: string]: CustomEvent<any>;
|
|
38
|
+
};
|
|
39
|
+
slots(): {
|
|
40
|
+
tabContent: {
|
|
41
|
+
data: any;
|
|
42
|
+
disabled: boolean;
|
|
43
|
+
selected: any;
|
|
44
|
+
tabId: any;
|
|
45
|
+
text: any;
|
|
46
|
+
};
|
|
47
|
+
default: {};
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export type TabListProps<T> = ReturnType<__sveltets_Render<T>['props']>;
|
|
51
|
+
export type TabListEvents<T> = ReturnType<__sveltets_Render<T>['events']>;
|
|
52
|
+
export type TabListSlots<T> = ReturnType<__sveltets_Render<T>['slots']>;
|
|
53
|
+
/** A list of items where a single item can be selected. */
|
|
54
|
+
export default class TabList<T> extends SvelteComponentTyped<TabListProps<T>, TabListEvents<T>, TabListSlots<T>> {
|
|
55
|
+
}
|
|
56
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const tabListContextKey = "sterlingTabList";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const tabListContextKey = 'sterlingTabList';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Readable, Writable } from 'svelte/store';
|
|
2
|
+
export type TabData<T> = T & {
|
|
3
|
+
tabId: string;
|
|
4
|
+
text?: string;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export type TabListContext<T> = {
|
|
8
|
+
disabled: Readable<boolean>;
|
|
9
|
+
selectedTabId: Writable<string | undefined>;
|
|
10
|
+
selectionFollowsFocus: Readable<boolean>;
|
|
11
|
+
vertical: Readable<boolean>;
|
|
12
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const forwardEvents: (node: HTMLElement, params: {
|
|
2
|
+
target: HTMLElement;
|
|
3
|
+
events?: string[];
|
|
4
|
+
customEvents?: string[];
|
|
5
|
+
}) => {
|
|
6
|
+
update: (params: {
|
|
7
|
+
target: HTMLElement;
|
|
8
|
+
events?: string[];
|
|
9
|
+
customEvents?: [];
|
|
10
|
+
}) => void;
|
|
11
|
+
destroy(): void;
|
|
12
|
+
};
|
package/forwardEvents.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { custom_event } from 'svelte/internal';
|
|
2
|
+
export const forwardEvents = (node, params) => {
|
|
3
|
+
const addListeners = (node, target, events, customEvents) => {
|
|
4
|
+
let forward = (event) => {
|
|
5
|
+
console.log('forward', node, target, event);
|
|
6
|
+
target.dispatchEvent(event);
|
|
7
|
+
};
|
|
8
|
+
let forwardCustom = (event) => {
|
|
9
|
+
console.log('custom forward', node, target, event);
|
|
10
|
+
const customEvent = event;
|
|
11
|
+
target.dispatchEvent(custom_event(customEvent.type, customEvent.detail, {
|
|
12
|
+
bubbles: customEvent.bubbles,
|
|
13
|
+
cancelable: customEvent.cancelable
|
|
14
|
+
}));
|
|
15
|
+
};
|
|
16
|
+
events?.forEach((e) => node.addEventListener(e, forward));
|
|
17
|
+
customEvents?.forEach((e) => node.addEventListener(e, forwardCustom));
|
|
18
|
+
return () => {
|
|
19
|
+
events?.forEach((e) => node.removeEventListener(e, forward));
|
|
20
|
+
customEvents?.forEach((e) => node.removeEventListener(e, forwardCustom));
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
let unsubscribe = addListeners(node, params.target, params.events, params.customEvents);
|
|
24
|
+
const update = (params) => {
|
|
25
|
+
unsubscribe();
|
|
26
|
+
unsubscribe = addListeners(node, params.target, params.events, params.customEvents);
|
|
27
|
+
};
|
|
28
|
+
return {
|
|
29
|
+
update,
|
|
30
|
+
destroy() {
|
|
31
|
+
unsubscribe();
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
};
|
package/index.d.ts
CHANGED
|
@@ -6,24 +6,34 @@ export { darkTheme } from './theme/darkTheme';
|
|
|
6
6
|
export { lightTheme } from './theme/lightTheme';
|
|
7
7
|
export { neutrals } from './theme/colors';
|
|
8
8
|
export { toggleDarkTheme } from './theme/toggleDarkTheme';
|
|
9
|
+
export { clickOutside } from './clickOutside';
|
|
10
|
+
export { menuBarContextKey, menuItemContextKey } from './containers/Menus.constants';
|
|
9
11
|
export type { ButtonVariant, ButtonShape } from './buttons/Button.types';
|
|
12
|
+
export type { MenuItemRegistration, MenuBarContext, MenuItemContext } from './containers/Menus.types';
|
|
10
13
|
export type { ProgressColorful } from './display/Progress.types';
|
|
11
14
|
export type { TextAreaResize } from './inputs/TextArea.types';
|
|
15
|
+
export type { TabData } from './containers/Tabs.types';
|
|
12
16
|
export type { TreeNodeData } from './containers/Tree.types';
|
|
13
|
-
export { clickOutside } from './clickOutside';
|
|
14
17
|
import Button from './buttons/Button.svelte';
|
|
15
18
|
import Checkbox from './inputs/Checkbox.svelte';
|
|
16
19
|
import Dialog from './surfaces/Dialog.svelte';
|
|
17
20
|
import Input from './inputs/Input.svelte';
|
|
18
21
|
import Label from './display/Label.svelte';
|
|
19
22
|
import List from './containers/List.svelte';
|
|
23
|
+
import Menu from './containers/Menu.svelte';
|
|
24
|
+
import MenuBar from './containers/MenuBar.svelte';
|
|
25
|
+
import MenuButton from './buttons/MenuButton.svelte';
|
|
26
|
+
import MenuItem from './containers/MenuItem.svelte';
|
|
27
|
+
import MenuSeparator from './containers/MenuSeparator.svelte';
|
|
20
28
|
import Progress from './display/Progress.svelte';
|
|
21
29
|
import Radio from './inputs/Radio.svelte';
|
|
22
30
|
import Select from './inputs/Select.svelte';
|
|
23
31
|
import Slider from './inputs/Slider.svelte';
|
|
24
32
|
import Switch from './inputs/Switch.svelte';
|
|
33
|
+
import Tab from './containers/Tab.svelte';
|
|
34
|
+
import TabList from './containers/TabList.svelte';
|
|
25
35
|
import TextArea from './inputs/TextArea.svelte';
|
|
26
36
|
import Tree from './containers/Tree.svelte';
|
|
27
37
|
import TreeChevron from './containers/TreeChevron.svelte';
|
|
28
38
|
import TreeItem from './containers/TreeItem.svelte';
|
|
29
|
-
export { Button, Checkbox, Dialog, Input, Label, List, Progress, Radio, Select, Slider, Switch, TextArea, Tree, TreeChevron, TreeItem };
|
|
39
|
+
export { Button, Checkbox, Dialog, Input, Label, List, Menu, MenuBar, MenuButton, MenuItem, MenuSeparator, Progress, Radio, Select, Slider, Switch, Tab, TabList, TextArea, Tree, TreeChevron, TreeItem };
|