@functionalcms/svelte-components 3.0.6 → 3.0.7

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 (53) hide show
  1. package/dist/components/Banner.svelte +5 -3
  2. package/dist/components/Link.svelte +54 -44
  3. package/dist/components/Logo.svelte +15 -3
  4. package/dist/components/Spacer.svelte +10 -7
  5. package/dist/components/Well.svelte +15 -12
  6. package/dist/components/agnostic/Alert/Alert.svelte +64 -57
  7. package/dist/components/agnostic/Avatar/Avatar.svelte +19 -15
  8. package/dist/components/agnostic/Breadcrumb/Breadcrumb.svelte +19 -10
  9. package/dist/components/agnostic/Button/Button.svelte +60 -35
  10. package/dist/components/agnostic/Button/ButtonGroup.svelte +4 -3
  11. package/dist/components/agnostic/Card/Card.svelte +22 -18
  12. package/dist/components/agnostic/ChoiceInput/ChoiceInput.svelte +87 -59
  13. package/dist/components/agnostic/Close/Close.svelte +11 -7
  14. package/dist/components/agnostic/Dialog/Dialog.svelte +64 -42
  15. package/dist/components/agnostic/Dialog/SvelteA11yDialog.svelte +76 -51
  16. package/dist/components/agnostic/Disclose/Disclose.svelte +15 -9
  17. package/dist/components/agnostic/Divider/Divider.svelte +21 -11
  18. package/dist/components/agnostic/Drawer/Drawer.svelte +20 -16
  19. package/dist/components/agnostic/EmptyState/EmptyState.svelte +10 -7
  20. package/dist/components/agnostic/Header/Header.svelte +22 -15
  21. package/dist/components/agnostic/Header/HeaderNav.svelte +4 -3
  22. package/dist/components/agnostic/Header/HeaderNavItem.svelte +3 -2
  23. package/dist/components/agnostic/Icon/Icon.svelte +28 -20
  24. package/dist/components/agnostic/Loader/Loader.svelte +6 -3
  25. package/dist/components/agnostic/Progress/Progress.svelte +5 -4
  26. package/dist/components/agnostic/Spinner/Spinner.svelte +6 -3
  27. package/dist/components/agnostic/Table/Table.svelte +191 -134
  28. package/dist/components/agnostic/Tabs/TabButtonCustom.svelte +24 -12
  29. package/dist/components/agnostic/Tabs/Tabs.svelte +173 -104
  30. package/dist/components/agnostic/Tag/Tag.svelte +14 -10
  31. package/dist/components/agnostic/Tag/TagSlots.svelte +2 -1
  32. package/dist/components/agnostic/Toasts/Toasts.svelte +29 -19
  33. package/dist/components/agnostic/Tooltip/Tooltip.svelte +85 -68
  34. package/dist/components/agnostic/Tooltip/TooltipSlots.svelte +2 -1
  35. package/dist/components/blog/BlogDescription.svelte +6 -4
  36. package/dist/components/blog/BlogTitle.svelte +8 -6
  37. package/dist/components/form/Input.svelte +81 -52
  38. package/dist/components/form/Input.svelte.d.ts +2 -2
  39. package/dist/components/form/Select.svelte +40 -24
  40. package/dist/components/layouts/DefaultLayout.svelte +8 -5
  41. package/dist/components/layouts/Meta.svelte +7 -6
  42. package/dist/components/layouts/SimpleFooter.svelte +13 -3
  43. package/dist/components/layouts/Tracker.svelte +2 -1
  44. package/dist/components/layouts/TwoColumnsLayout.svelte +3 -2
  45. package/dist/components/menu/CollapsibleMenu.svelte +18 -13
  46. package/dist/components/menu/DynamicMenu.svelte +16 -10
  47. package/dist/components/menu/HamburgerMenu.svelte +24 -18
  48. package/dist/components/menu/Menu.svelte +279 -219
  49. package/dist/components/menu/MenuItem.svelte +14 -10
  50. package/dist/components/menu/NavigationItems.svelte +18 -12
  51. package/dist/components/presentation/Carusel.svelte +77 -72
  52. package/dist/components/presentation/Gallery.svelte +14 -8
  53. package/package.json +9 -10
@@ -1,222 +1,282 @@
1
- <script>import { onDestroy, onMount } from "svelte";
2
- export let id;
3
- export let type = "simple";
4
- export let size = "";
5
- export let menuTitle;
6
- export let menuItems = [];
7
- export let isDisabled = false;
8
- export let isRounded = false;
9
- export let isBordered = false;
10
- export let isItemsRight = false;
11
- export let icon = "\u25BE";
12
- export let onOpen;
13
- export let onClose;
14
- export let closeOnClickOutside = true;
15
- export let closeOnSelect = true;
16
- let rootRef;
17
- let triggerRef;
18
- let menuItemRefs = [];
19
- $: menuItemRefs = [];
20
- let expanded = false;
21
- const setExpanded = (b) => expanded = b;
22
- let selectedItem = -1;
23
- const setSelectedItem = (n) => selectedItem = n;
24
- const setOpened = (open) => {
25
- if (open && onOpen) {
26
- onOpen(selectedItem);
27
- } else if (onClose) {
28
- onClose();
29
- }
30
- setExpanded(open);
31
- };
32
- const focusItem = (index, direction) => {
33
- let i = index;
34
- if (direction === "asc") {
35
- i += 1;
36
- } else if (direction === "desc") {
37
- i -= 1;
38
- }
39
- if (i < 0) {
40
- i = menuItems.length - 1;
41
- } else if (i >= menuItems.length) {
42
- i = 0;
43
- }
44
- const nextMenuItem = menuItemRefs[i];
45
- if (nextMenuItem) {
46
- if (nextMenuItem.isDisabled() && direction) {
47
- focusItem(i, direction);
48
- } else {
49
- nextMenuItem.focus();
50
- }
51
- }
52
- };
53
- const focusTriggerButton = () => triggerRef && triggerRef.focus();
54
- const isInside = (el) => {
55
- if (rootRef) {
56
- const children = rootRef.querySelectorAll("*");
57
- for (let i = 0; i < children.length; i += 1) {
58
- const child = children[i];
59
- if (el === child) {
60
- return true;
61
- }
62
- }
63
- }
64
- return false;
65
- };
66
- const clickedOutside = (ev) => {
67
- if (expanded && closeOnClickOutside) {
68
- if (!isInside(ev.target)) {
69
- setExpanded(false);
70
- focusTriggerButton();
71
- }
72
- }
73
- };
74
- onMount(() => {
75
- if (typeof window !== "undefined") {
76
- document.addEventListener("click", clickedOutside);
77
- }
78
- });
79
- onDestroy(() => {
80
- if (typeof window !== "undefined") {
81
- document.removeEventListener("click", clickedOutside);
82
- }
83
- });
84
- let triggerSizeClasses;
85
- let itemSizeClasses;
86
- switch (size) {
87
- case "small":
88
- triggerSizeClasses = "menu-trigger-small";
89
- itemSizeClasses = "menu-item-small";
90
- break;
91
- case "large":
92
- triggerSizeClasses = "menu-trigger-large";
93
- itemSizeClasses = "menu-item-large";
94
- break;
95
- default:
96
- triggerSizeClasses = "";
97
- itemSizeClasses = "";
98
- }
99
- const dotBarClasses = [
100
- type === "hamburger" ? "bar" : "dot"
101
- ].filter((cls) => cls).join(" ");
102
- const triggerClasses = [
103
- type === "simple" ? "menu-trigger" : "",
104
- triggerSizeClasses,
105
- isBordered ? "menu-trigger-bordered" : "",
106
- isRounded ? "menu-trigger-rounded" : "",
107
- type !== "simple" ? "btn-base" : "",
108
- type !== "simple" ? "btn-blank" : "",
109
- type === "kebab" ? "btn-kebab" : "",
110
- type === "meatball" ? "btn-meatball" : "",
111
- type === "hamburger" ? "btn-hamburger" : ""
112
- ].filter((cls) => cls).join(" ");
113
- const itemClasses = [itemSizeClasses, isRounded ? "menu-item-rounded" : ""].filter((cls) => cls).join(" ");
114
- const afterOpened = () => {
115
- requestAnimationFrame(() => {
116
- if (selectedItem < 1) {
117
- setSelectedItem(0);
118
- onMenuItemKeyDown("Home", 0);
119
- } else {
120
- focusItem(selectedItem);
121
- setSelectedItem(selectedItem);
122
- }
123
- });
124
- };
125
- const onMenuItemKeyDown = (evOrString, index) => {
126
- const key = typeof evOrString === "string" ? evOrString : evOrString.key;
127
- switch (key) {
128
- case "Up":
129
- case "ArrowUp":
130
- focusItem(index, "desc");
131
- break;
132
- case "Down":
133
- case "ArrowDown":
134
- focusItem(index, "asc");
135
- break;
136
- case "Home":
137
- case "ArrowHome":
138
- focusItem(0);
139
- break;
140
- case "End":
141
- case "ArrowEnd":
142
- focusItem(menuItems.length - 1);
143
- break;
144
- case "Enter":
145
- case "Space":
146
- focusItem(index);
147
- setSelectedItem(index);
148
- if (closeOnSelect) {
149
- setOpened(false);
150
- focusTriggerButton();
151
- }
152
- break;
153
- case "Escape":
154
- setOpened(false);
155
- focusTriggerButton();
156
- break;
157
- case "Tab":
158
- if (typeof evOrString !== "string") {
159
- evOrString.preventDefault();
160
- }
161
- break;
162
- default:
163
- return;
164
- }
165
- if (typeof evOrString !== "string") {
166
- evOrString.preventDefault();
167
- }
168
- };
169
- const onTriggerButtonKeyDown = (e) => {
170
- switch (e.key) {
171
- case "Down":
172
- case "ArrowDown":
173
- if (!expanded) {
174
- setOpened(true);
175
- afterOpened();
176
- e.preventDefault();
177
- }
178
- break;
179
- case "Escape":
180
- if (expanded) {
181
- setOpened(false);
182
- focusTriggerButton();
183
- }
184
- break;
185
- default:
186
- }
187
- };
188
- const onTriggerButtonClicked = () => {
189
- const toggled = !expanded;
190
- setOpened(toggled);
191
- setTimeout(() => {
192
- if (toggled) {
193
- afterOpened();
194
- } else if (closeOnSelect) {
195
- setOpened(false);
196
- focusTriggerButton();
197
- }
198
- }, 10);
199
- };
200
- $: menuItemClasses = (isSelected) => {
201
- return [
202
- `menu-item`,
203
- itemClasses,
204
- isSelected ? "menu-item-selected" : ""
205
- ].filter((klass) => klass.length).join(" ");
206
- };
207
- $: menuItemsClasses = () => {
208
- return [
209
- isItemsRight ? "menu-items-right" : "",
210
- !isItemsRight ? "menu-items" : ""
211
- ].filter((c) => c && c.length).join(" ");
212
- };
213
- $: onMenuItemClicked = (index) => {
214
- setSelectedItem(index);
215
- if (closeOnSelect) {
216
- setOpened(false);
217
- focusTriggerButton();
218
- }
219
- };
1
+ <script lang="ts">
2
+ import { onDestroy, onMount } from 'svelte';
3
+
4
+ export let id;
5
+ export let type: 'simple' | 'kebab' | 'hamburger' | 'meatball' = 'simple';
6
+ export let size: 'small' | 'large' | '' = '';
7
+ export let menuTitle;
8
+ export let menuItems = [];
9
+ export let isDisabled = false;
10
+ export let isRounded = false;
11
+ export let isBordered = false;
12
+ export let isItemsRight = false;
13
+ export let icon = '▾';
14
+ export let onOpen;
15
+ export let onClose;
16
+ export let closeOnClickOutside = true;
17
+ export let closeOnSelect = true;
18
+
19
+ // References aka bindings
20
+ let rootRef;
21
+ let triggerRef;
22
+
23
+ let menuItemRefs = []; //https://svelte.dev/tutorial/component-this
24
+ $: menuItemRefs = [];
25
+
26
+ // State management
27
+ let expanded = false;
28
+ const setExpanded = (b) => expanded = b;
29
+ let selectedItem = -1;
30
+ const setSelectedItem = (n) => selectedItem = n;
31
+
32
+ const setOpened = (open) => {
33
+ if (open && onOpen) {
34
+ onOpen(selectedItem);
35
+ } else if (onClose) {
36
+ onClose();
37
+ }
38
+ setExpanded(open);
39
+ };
40
+
41
+ // Focus management
42
+ const focusItem = (index: number, direction?: 'asc' | 'desc') => {
43
+ let i = index;
44
+ if (direction === 'asc') {
45
+ i += 1;
46
+ } else if (direction === 'desc') {
47
+ i -= 1;
48
+ }
49
+
50
+ // Circular navigation
51
+ //
52
+ // If we've went beyond "start" circle around to last
53
+ if (i < 0) {
54
+ i = menuItems.length - 1;
55
+ } else if (i >= menuItems.length) {
56
+ // We've went beyond "last" so circle around to first
57
+ i = 0;
58
+ }
59
+
60
+ const nextMenuItem = menuItemRefs[i];
61
+
62
+ if (nextMenuItem) {
63
+ // Edge case: We hit a tab button that's been disabled. If so, we recurse, but
64
+ // only if we've been supplied a `direction`. Otherwise, nothing left to do.
65
+ if (nextMenuItem.isDisabled() && direction) {
66
+ // Retry with new `i` index going in same direction
67
+ focusItem(i, direction);
68
+ } else {
69
+ // Note that .focus is available here as a result of agnostic-svelte/src/lib/components/Menu/MenuItem.svelte
70
+ // maintaining its own reference to the native <button> element and then exposing itw own export function focus
71
+ nextMenuItem.focus();
72
+ }
73
+ }
74
+ };
75
+
76
+ const focusTriggerButton = () => triggerRef && triggerRef.focus();
77
+
78
+ const isInside = (el) => {
79
+ if (rootRef) {
80
+ const children = rootRef.querySelectorAll('*');
81
+ for (let i = 0; i < children.length; i += 1) {
82
+ const child = children[i];
83
+ if (el === child) {
84
+ return true;
85
+ }
86
+ }
87
+ }
88
+ return false;
89
+ };
90
+
91
+ const clickedOutside = (ev) => {
92
+ if (expanded && closeOnClickOutside) {
93
+ if (!isInside(ev.target)) {
94
+ setExpanded(false);
95
+ focusTriggerButton();
96
+ }
97
+ }
98
+ };
99
+
100
+ onMount(() => {
101
+ if (typeof window !== 'undefined') {
102
+ document.addEventListener('click', clickedOutside);
103
+ }
104
+ });
105
+
106
+ onDestroy(() => {
107
+ if (typeof window !== 'undefined') {
108
+ document.removeEventListener('click', clickedOutside);
109
+ }
110
+ });
111
+
112
+ // CSS Classes
113
+ let triggerSizeClasses;
114
+ let itemSizeClasses;
115
+ switch (size) {
116
+ case 'small':
117
+ triggerSizeClasses = "menu-trigger-small";
118
+ itemSizeClasses = "menu-item-small";
119
+ break;
120
+ case 'large':
121
+ triggerSizeClasses = "menu-trigger-large";
122
+ itemSizeClasses = "menu-item-large";
123
+ break;
124
+ default:
125
+ triggerSizeClasses = '';
126
+ itemSizeClasses = '';
127
+ }
128
+
129
+ const dotBarClasses = [
130
+ type === 'hamburger' ? 'bar' : 'dot'
131
+ ]
132
+ .filter((cls) => cls)
133
+ .join(' ');
134
+
135
+ const triggerClasses = [
136
+ type === 'simple' ? "menu-trigger" : '',
137
+ triggerSizeClasses,
138
+ isBordered ? "menu-trigger-bordered" : '',
139
+ isRounded ? "menu-trigger-rounded" : '',
140
+ type !== 'simple' ? "btn-base" : '',
141
+ type !== 'simple' ? "btn-blank" : '',
142
+ type === 'kebab' ? "btn-kebab" : '',
143
+ type === 'meatball' ? "btn-meatball" : '',
144
+ type === 'hamburger' ? "btn-hamburger" : '',
145
+ ]
146
+ .filter((cls) => cls)
147
+ .join(' ');
148
+
149
+ const itemClasses = [itemSizeClasses, isRounded ? "menu-item-rounded" : '']
150
+ .filter((cls) => cls)
151
+ .join(' ');
152
+
153
+ const afterOpened = () => {
154
+ requestAnimationFrame(() => {
155
+ // If selectedItem < 1 probably hasn't been opened before (or happens to be on
156
+ // first item). Otherwise, might be "reopening" and has previously selected item
157
+ if (selectedItem < 1) {
158
+ setSelectedItem(0);
159
+ onMenuItemKeyDown('Home', 0);
160
+ } else {
161
+ focusItem(selectedItem);
162
+ setSelectedItem(selectedItem);
163
+ }
164
+ });
165
+ };
166
+
167
+ /**
168
+ * @param evOrString arg of either keyboard event or a string w/direction key like Up Down etc.
169
+ * @param index
170
+ * @returns
171
+ */
172
+ const onMenuItemKeyDown = (evOrString, index) => {
173
+ const key = typeof evOrString === 'string' ? evOrString : evOrString.key;
174
+ switch (key) {
175
+ case 'Up': // These first cases are IEEdge :(
176
+ case 'ArrowUp':
177
+ focusItem(index, 'desc');
178
+ break;
179
+ case 'Down':
180
+ case 'ArrowDown':
181
+ focusItem(index, 'asc');
182
+ break;
183
+ case 'Home':
184
+ case 'ArrowHome':
185
+ focusItem(0);
186
+ break;
187
+ case 'End':
188
+ case 'ArrowEnd':
189
+ focusItem(menuItems.length - 1);
190
+ break;
191
+ case 'Enter':
192
+ case 'Space':
193
+ // Focus and select the item
194
+ focusItem(index);
195
+ setSelectedItem(index);
196
+ // If we're to close the menu on selection (default) then do so
197
+ if (closeOnSelect) {
198
+ setOpened(false);
199
+ focusTriggerButton();
200
+ }
201
+ break;
202
+ case 'Escape':
203
+ setOpened(false);
204
+ focusTriggerButton();
205
+ break;
206
+ case 'Tab':
207
+ // Trap tabs while capturing these menu events
208
+ if (typeof evOrString !== 'string') {
209
+ evOrString.preventDefault();
210
+ }
211
+ break;
212
+ default:
213
+ return;
214
+ }
215
+ if (typeof evOrString !== 'string') {
216
+ evOrString.preventDefault();
217
+ }
218
+ };
219
+
220
+ const onTriggerButtonKeyDown = (e) => {
221
+ switch (e.key) {
222
+ case 'Down':
223
+ case 'ArrowDown':
224
+ // If not expanded and we haven't previously selected an item other then first item
225
+ // puts focus on first item in menu list. Otherwise,
226
+ if (!expanded) {
227
+ setOpened(true);
228
+ afterOpened();
229
+ e.preventDefault();
230
+ }
231
+ break;
232
+ case 'Escape':
233
+ if (expanded) {
234
+ setOpened(false);
235
+ focusTriggerButton();
236
+ }
237
+ break;
238
+ default:
239
+ // Noop
240
+ }
241
+ };
242
+
243
+ const onTriggerButtonClicked = () => {
244
+ // toggled is local reference to !expanded since setExpanded is async (avoids race condition)
245
+ const toggled = !expanded;
246
+ setOpened(toggled);
247
+ setTimeout(() => {
248
+ if (toggled) {
249
+ afterOpened();
250
+ } else if (closeOnSelect) {
251
+ // If we're to close the menu on selection (default) then do so
252
+ setOpened(false);
253
+ focusTriggerButton();
254
+ }
255
+ }, 10);
256
+ };
257
+
258
+ $: menuItemClasses = (isSelected) => {
259
+ return [
260
+ `menu-item`,
261
+ itemClasses,
262
+ isSelected ? "menu-item-selected" : "",
263
+ ].filter((klass) => klass.length).join(" ");
264
+ };
265
+
266
+ $: menuItemsClasses = () => {
267
+ return [
268
+ isItemsRight ? "menu-items-right" : "",
269
+ !isItemsRight ? "menu-items" : ""
270
+ ].filter(c => c && c.length).join(' ');
271
+ };
272
+
273
+ $: onMenuItemClicked = (index) => {
274
+ setSelectedItem(index);
275
+ if (closeOnSelect) {
276
+ setOpened(false);
277
+ focusTriggerButton();
278
+ }
279
+ };
220
280
  </script>
221
281
  <div bind:this={rootRef} class="menu">
222
282
  <button
@@ -1,13 +1,17 @@
1
- <script>export let disabled = false;
2
- export let isSelected = false;
3
- export let classes;
4
- let btn;
5
- export function focus() {
6
- return btn.focus();
7
- }
8
- export function isDisabled() {
9
- return btn.disabled;
10
- }
1
+ <script lang="ts">
2
+ export let disabled = false;
3
+ export let isSelected = false;
4
+ export let classes;
5
+
6
+ // This is a component reference which we need to control the keyboard navigation
7
+ // in our tabs implementation. See: https://svelte.dev/tutorial/component-this
8
+ let btn;
9
+ export function focus() {
10
+ return btn.focus();
11
+ }
12
+ export function isDisabled() {
13
+ return btn.disabled;
14
+ }
11
15
  </script>
12
16
  <button
13
17
  on:click
@@ -1,15 +1,21 @@
1
- <script>import { isSelected, defaultCss } from "./Menu.js";
2
- import { Orientation } from "../Styling.js";
3
- import Link from "../Link.svelte";
4
- import { page } from "$app/stores";
5
- import { mergedClasses } from "../CssHelper.js";
6
- export let css = defaultCss;
7
- export let localPages = [];
8
- export let orientation = Orientation.Column;
9
- export let includeSubpagesForSelect = true;
10
- const cssClasses = { ...defaultCss, ...css };
11
- const containerCss = mergedClasses("flex", cssClasses.container, orientation);
12
- const linkCss = mergedClasses(cssClasses.link);
1
+ <script lang="ts">
2
+ import { type HeaderNavigationItem, isSelected, defaultCss } from './Menu.js';
3
+ import { Orientation } from '../Styling.js';
4
+ import Link from '../Link.svelte';
5
+ import { page } from '$app/stores';
6
+ import { mergedClasses } from '../CssHelper.js';
7
+
8
+ export let css: { container: string[]; link: string[] } = defaultCss;
9
+
10
+ export let localPages: Array<HeaderNavigationItem> = [];
11
+
12
+ export let orientation: Orientation = Orientation.Column;
13
+
14
+ export let includeSubpagesForSelect: boolean = true;
15
+
16
+ const cssClasses = { ...defaultCss, ...css };
17
+ const containerCss = mergedClasses('flex', cssClasses.container, orientation);
18
+ const linkCss = mergedClasses(cssClasses.link);
13
19
  </script>
14
20
 
15
21
  <ul class={containerCss} role="menu" aria-label="menu">