@functionalcms/svelte-components 3.5.16 → 3.5.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 (129) hide show
  1. package/css/functional.css +1 -1
  2. package/css/functional.css.map +1 -1
  3. package/dist/components/Banner.svelte +1 -1
  4. package/dist/components/Banner.svelte.d.ts +8 -13
  5. package/dist/components/Link.svelte.d.ts +45 -34
  6. package/dist/components/Logo.svelte.d.ts +26 -22
  7. package/dist/components/Markdown.svelte.d.ts +5 -14
  8. package/dist/components/Spacer.svelte.d.ts +6 -14
  9. package/dist/components/Well.svelte.d.ts +11 -13
  10. package/dist/components/agnostic/Button/Button.svelte +333 -332
  11. package/dist/components/agnostic/Button/Button.svelte.d.ts +50 -39
  12. package/dist/components/agnostic/Button/ButtonGroup.svelte.d.ts +30 -19
  13. package/dist/components/agnostic/Close/Close.svelte.d.ts +22 -18
  14. package/dist/components/agnostic/Disclose/Disclose.svelte.d.ts +10 -13
  15. package/dist/components/agnostic/Divider/Divider.svelte.d.ts +21 -17
  16. package/dist/components/agnostic/Loader/Loader.svelte.d.ts +20 -16
  17. package/dist/components/blog/BlogDescription.svelte.d.ts +21 -17
  18. package/dist/components/blog/BlogTitle.svelte.d.ts +21 -17
  19. package/dist/components/form/DateTimePicker.svelte.d.ts +16 -12
  20. package/dist/components/form/Input.svelte +1 -1
  21. package/dist/components/form/Input.svelte.d.ts +46 -20
  22. package/dist/components/form/InputAddonItem.svelte +34 -34
  23. package/dist/components/form/InputAddonItem.svelte.d.ts +27 -27
  24. package/dist/components/form/Select.svelte.d.ts +32 -28
  25. package/dist/components/{agnostic/Switch → form}/Switch.svelte +1 -1
  26. package/dist/components/form/Switch.svelte.d.ts +30 -0
  27. package/dist/components/layouts/DefaultLayout.svelte.d.ts +11 -13
  28. package/dist/components/layouts/Meta.svelte.d.ts +10 -13
  29. package/dist/components/layouts/SimpleFooter.svelte.d.ts +7 -13
  30. package/dist/components/layouts/Tracker.svelte.d.ts +5 -13
  31. package/dist/components/layouts/TwoColumnsLayout.svelte.d.ts +9 -13
  32. package/dist/components/menu/CollapsibleMenu.svelte.d.ts +27 -23
  33. package/dist/components/menu/DynamicMenu.svelte.d.ts +27 -23
  34. package/dist/components/menu/HamburgerMenu.svelte +3 -3
  35. package/dist/components/menu/HamburgerMenu.svelte.d.ts +25 -21
  36. package/dist/components/menu/Menu.svelte.d.ts +31 -27
  37. package/dist/components/menu/MenuItem.svelte.d.ts +37 -25
  38. package/dist/components/menu/NavigationItems.svelte +9 -4
  39. package/dist/components/menu/NavigationItems.svelte.d.ts +27 -23
  40. package/dist/components/presentation/Card.svelte.d.ts +17 -13
  41. package/dist/components/presentation/Carousel/carousel-content.svelte +35 -0
  42. package/dist/components/presentation/Carousel/carousel-content.svelte.d.ts +28 -0
  43. package/dist/components/presentation/Carousel/carousel-item.svelte +25 -0
  44. package/dist/components/presentation/Carousel/carousel-item.svelte.d.ts +28 -0
  45. package/dist/components/presentation/Carousel/carousel-next.svelte +39 -0
  46. package/dist/components/presentation/Carousel/carousel-next.svelte.d.ts +18 -0
  47. package/dist/components/presentation/Carousel/carousel-previous.svelte +40 -0
  48. package/dist/components/presentation/Carousel/carousel-previous.svelte.d.ts +18 -0
  49. package/dist/components/presentation/Carousel/carousel.svelte +99 -0
  50. package/dist/components/presentation/Carousel/carousel.svelte.d.ts +31 -0
  51. package/dist/components/presentation/Carousel/context.d.ts +32 -0
  52. package/dist/components/presentation/Carousel/context.js +12 -0
  53. package/dist/components/presentation/Carousel.svelte +4 -0
  54. package/dist/components/presentation/Carousel.svelte.d.ts +18 -0
  55. package/dist/components/presentation/Carusele.d.ts +1 -1
  56. package/dist/components/presentation/Carusele.js +1 -1
  57. package/dist/components/presentation/Gallery.svelte.d.ts +14 -13
  58. package/dist/components/presentation/ImageCompare.svelte +15 -12
  59. package/dist/components/presentation/ImageCompare.svelte.d.ts +24 -38
  60. package/dist/index.d.ts +4 -4
  61. package/dist/index.js +11 -6
  62. package/package.json +24 -24
  63. package/dist/components/agnostic/Alert/Alert.svelte +0 -317
  64. package/dist/components/agnostic/Alert/Alert.svelte.d.ts +0 -29
  65. package/dist/components/agnostic/Avatar/Avatar.svelte +0 -127
  66. package/dist/components/agnostic/Avatar/Avatar.svelte.d.ts +0 -24
  67. package/dist/components/agnostic/Avatar/AvatarGroup.svelte +0 -106
  68. package/dist/components/agnostic/Avatar/AvatarGroup.svelte.d.ts +0 -27
  69. package/dist/components/agnostic/Breadcrumb/Breadcrumb.svelte +0 -65
  70. package/dist/components/agnostic/Breadcrumb/Breadcrumb.svelte.d.ts +0 -18
  71. package/dist/components/agnostic/Breadcrumb/api.d.ts +0 -4
  72. package/dist/components/agnostic/Breadcrumb/api.js +0 -1
  73. package/dist/components/agnostic/ChoiceInput/ChoiceInput.svelte +0 -365
  74. package/dist/components/agnostic/ChoiceInput/ChoiceInput.svelte.d.ts +0 -35
  75. package/dist/components/agnostic/ChoiceInput/api.d.ts +0 -7
  76. package/dist/components/agnostic/ChoiceInput/api.js +0 -1
  77. package/dist/components/agnostic/Dialog/Dialog.svelte +0 -278
  78. package/dist/components/agnostic/Dialog/Dialog.svelte.d.ts +0 -37
  79. package/dist/components/agnostic/Dialog/SvelteA11yDialog.svelte +0 -128
  80. package/dist/components/agnostic/Dialog/SvelteA11yDialog.svelte.d.ts +0 -28
  81. package/dist/components/agnostic/Dialog/a11y-dialog.d.ts +0 -56
  82. package/dist/components/agnostic/Dialog/a11y-dialog.js +0 -216
  83. package/dist/components/agnostic/Dialog/dom-utils.d.ts +0 -26
  84. package/dist/components/agnostic/Dialog/dom-utils.js +0 -206
  85. package/dist/components/agnostic/Drawer/Drawer.svelte +0 -34
  86. package/dist/components/agnostic/Drawer/Drawer.svelte.d.ts +0 -26
  87. package/dist/components/agnostic/Drawer/api.d.ts +0 -1
  88. package/dist/components/agnostic/Drawer/api.js +0 -1
  89. package/dist/components/agnostic/EmptyState/EmptyState.svelte +0 -49
  90. package/dist/components/agnostic/EmptyState/EmptyState.svelte.d.ts +0 -21
  91. package/dist/components/agnostic/Header/Header.svelte +0 -111
  92. package/dist/components/agnostic/Header/Header.svelte.d.ts +0 -24
  93. package/dist/components/agnostic/Header/HeaderNav.svelte +0 -29
  94. package/dist/components/agnostic/Header/HeaderNav.svelte.d.ts +0 -18
  95. package/dist/components/agnostic/Header/HeaderNavItem.svelte +0 -31
  96. package/dist/components/agnostic/Header/HeaderNavItem.svelte.d.ts +0 -18
  97. package/dist/components/agnostic/Icon/Icon.svelte +0 -188
  98. package/dist/components/agnostic/Icon/Icon.svelte.d.ts +0 -21
  99. package/dist/components/agnostic/Icon/api.d.ts +0 -2
  100. package/dist/components/agnostic/Icon/api.js +0 -1
  101. package/dist/components/agnostic/Progress/Progress.svelte +0 -51
  102. package/dist/components/agnostic/Progress/Progress.svelte.d.ts +0 -18
  103. package/dist/components/agnostic/Spinner/Spinner.svelte +0 -108
  104. package/dist/components/agnostic/Spinner/Spinner.svelte.d.ts +0 -17
  105. package/dist/components/agnostic/Switch/Switch.svelte.d.ts +0 -43
  106. package/dist/components/agnostic/Table/Table.svelte +0 -521
  107. package/dist/components/agnostic/Table/Table.svelte.d.ts +0 -34
  108. package/dist/components/agnostic/Table/TableCustomRenderComponent.svelte +0 -13
  109. package/dist/components/agnostic/Table/TableCustomRenderComponent.svelte.d.ts +0 -23
  110. package/dist/components/agnostic/Tabs/TabButtonCustom.svelte +0 -77
  111. package/dist/components/agnostic/Tabs/TabButtonCustom.svelte.d.ts +0 -33
  112. package/dist/components/agnostic/Tabs/Tabs.svelte +0 -399
  113. package/dist/components/agnostic/Tabs/Tabs.svelte.d.ts +0 -32
  114. package/dist/components/agnostic/Tabs/api.d.ts +0 -10
  115. package/dist/components/agnostic/Tabs/api.js +0 -1
  116. package/dist/components/agnostic/Tag/Tag.svelte +0 -78
  117. package/dist/components/agnostic/Tag/Tag.svelte.d.ts +0 -21
  118. package/dist/components/agnostic/Tag/TagSlots.svelte +0 -52
  119. package/dist/components/agnostic/Tag/TagSlots.svelte.d.ts +0 -14
  120. package/dist/components/agnostic/Toasts/Toasts.svelte +0 -56
  121. package/dist/components/agnostic/Toasts/Toasts.svelte.d.ts +0 -20
  122. package/dist/components/agnostic/Tooltip/Tooltip.svelte +0 -120
  123. package/dist/components/agnostic/Tooltip/Tooltip.svelte.d.ts +0 -21
  124. package/dist/components/agnostic/Tooltip/TooltipSlots.svelte +0 -82
  125. package/dist/components/agnostic/Tooltip/TooltipSlots.svelte.d.ts +0 -14
  126. package/dist/components/agnostic/Tooltip/api.d.ts +0 -1
  127. package/dist/components/agnostic/Tooltip/api.js +0 -1
  128. package/dist/components/presentation/Carusel.svelte +0 -109
  129. package/dist/components/presentation/Carusel.svelte.d.ts +0 -56
@@ -1,216 +0,0 @@
1
- import { closest, focus, getActiveEl, trapTabKey } from './dom-utils.js';
2
- const SCOPE = 'data-a11y-dialog';
3
- export default class A11yDialog {
4
- $el;
5
- id;
6
- previouslyFocused;
7
- shown;
8
- constructor(element) {
9
- this.$el = element;
10
- this.id = this.$el.getAttribute(SCOPE) || this.$el.id;
11
- this.previouslyFocused = null;
12
- this.shown = false;
13
- this.maintainFocus = this.maintainFocus.bind(this);
14
- this.bindKeypress = this.bindKeypress.bind(this);
15
- this.handleTriggerClicks = this.handleTriggerClicks.bind(this);
16
- this.show = this.show.bind(this);
17
- this.hide = this.hide.bind(this);
18
- this.$el.setAttribute('aria-hidden', 'true');
19
- this.$el.setAttribute('aria-modal', 'true');
20
- this.$el.setAttribute('tabindex', '-1');
21
- if (!this.$el.hasAttribute('role')) {
22
- this.$el.setAttribute('role', 'dialog');
23
- }
24
- document.addEventListener('click', this.handleTriggerClicks, true);
25
- }
26
- /**
27
- * Destroy the current instance (after making sure the dialog has been hidden)
28
- * and remove all associated listeners from dialog openers and closers
29
- */
30
- destroy() {
31
- // Dispatch a `destroy` event
32
- const destroyEvent = this.fire('destroy');
33
- // If the event was prevented, do not continue with the normal behavior
34
- if (destroyEvent.defaultPrevented)
35
- return this;
36
- // Hide the dialog to avoid destroying an open instance
37
- this.hide();
38
- // Remove the click event delegates for our openers and closers
39
- document.removeEventListener('click', this.handleTriggerClicks, true);
40
- // Clone and replace the dialog element to prevent memory leaks caused by
41
- // event listeners that the author might not have cleaned up.
42
- this.$el.replaceWith(this.$el.cloneNode(true));
43
- return this;
44
- }
45
- /**
46
- * Show the dialog element, trap the current focus within it, listen for some
47
- * specific key presses and fire all registered callbacks for `show` event
48
- */
49
- show(event) {
50
- // If the dialog is already open, abort
51
- if (this.shown)
52
- return this;
53
- // Dispatch a `show` event
54
- const showEvent = this.fire('show', event);
55
- // If the event was prevented, do not continue with the normal behavior
56
- if (showEvent.defaultPrevented)
57
- return this;
58
- // Keep a reference to the currently focused element to be able to restore
59
- // it later
60
- this.shown = true;
61
- this.$el.removeAttribute('aria-hidden');
62
- this.previouslyFocused = getActiveEl();
63
- // Due to a long lasting bug in Safari, clicking an interactive element
64
- // (like a <button>) does *not* move the focus to that element, which means
65
- // `document.activeElement` is whatever element is currently focused (like
66
- // an <input>), or the <body> element otherwise. We can work around that
67
- // problem by checking whether the focused element is the <body>, and if it,
68
- // store the click event target.
69
- // See: https://bugs.webkit.org/show_bug.cgi?id=22261
70
- if (this.previouslyFocused?.tagName === 'BODY' && event?.target) {
71
- this.previouslyFocused = event.target;
72
- }
73
- // Set the focus to the dialog element
74
- // See: https://github.com/KittyGiraudel/a11y-dialog/pull/583
75
- if (event?.type === 'focus') {
76
- this.maintainFocus(event);
77
- }
78
- else {
79
- focus(this.$el);
80
- }
81
- // Bind a focus event listener to the body element to make sure the focus
82
- // stays trapped inside the dialog while open, and start listening for some
83
- // specific key presses (TAB and ESC)
84
- document.body.addEventListener('focus', this.maintainFocus, true);
85
- this.$el.addEventListener('keydown', this.bindKeypress, true);
86
- return this;
87
- }
88
- /**
89
- * Hide the dialog element, restore the focus to the previously active
90
- * element, stop listening for some specific key presses and fire all
91
- * registered callbacks for `hide` event
92
- */
93
- hide(event) {
94
- // If the dialog is already closed, abort
95
- if (!this.shown)
96
- return this;
97
- // Dispatch a `hide` event
98
- const hideEvent = this.fire('hide', event);
99
- // If the event was prevented, do not continue with the normal behavior
100
- if (hideEvent.defaultPrevented)
101
- return this;
102
- this.shown = false;
103
- this.$el.setAttribute('aria-hidden', 'true');
104
- // Ensure the previously focused element (if any) has a `focus` method
105
- // before attempting to call it to account for SVG elements
106
- // See: https://github.com/KittyGiraudel/a11y-dialog/issues/108
107
- this.previouslyFocused?.focus?.();
108
- // Remove the focus event listener to the body element and stop listening
109
- // for specific key presses
110
- document.body.removeEventListener('focus', this.maintainFocus, true);
111
- this.$el.removeEventListener('keydown', this.bindKeypress, true);
112
- return this;
113
- }
114
- /**
115
- * Register a new callback for the given event type
116
- */
117
- on(type, handler, options) {
118
- this.$el.addEventListener(type, handler, options);
119
- return this;
120
- }
121
- /**
122
- * Unregister an existing callback for the given event type
123
- */
124
- off(type, handler, options) {
125
- this.$el.removeEventListener(type, handler, options);
126
- return this;
127
- }
128
- /**
129
- * Dispatch and return a custom event from the DOM element associated with
130
- * this dialog; this allows authors to listen for and respond to the events
131
- * in their own code
132
- */
133
- fire(type, event) {
134
- const customEvent = new CustomEvent(type, {
135
- detail: event,
136
- cancelable: true,
137
- });
138
- this.$el.dispatchEvent(customEvent);
139
- return customEvent;
140
- }
141
- /**
142
- * Add a delegated event listener for when elememts that open or close the
143
- * dialog are clicked, and call `show` or `hide`, respectively
144
- */
145
- handleTriggerClicks(event) {
146
- // We need to retrieve the click target while accounting for Shadow DOM.
147
- // When within a web component, `event.target` is the shadow root (e.g.
148
- // `<my-dialog>`), so we need to use `event.composedPath()` to get the click
149
- // target
150
- // See: https://github.com/KittyGiraudel/a11y-dialog/issues/582
151
- const target = event.composedPath()[0];
152
- const opener = closest(`[${SCOPE}-show="${this.id}"]`, target);
153
- const explicitCloser = closest(`[${SCOPE}-hide="${this.id}"]`, target);
154
- const implicitCloser = closest(`[${SCOPE}-hide]`, target) &&
155
- closest('[aria-modal="true"]', target) === this.$el;
156
- // We use `closest(..)` (instead of `matches(..)`) so that clicking an
157
- // element nested within a dialog opener does cause the dialog to open, and
158
- // we use our custom `closest(..)` function so that it can cross shadow
159
- // boundaries
160
- // See: https://github.com/KittyGiraudel/a11y-dialog/issues/712
161
- if (opener)
162
- this.show(event);
163
- if (explicitCloser || implicitCloser)
164
- this.hide(event);
165
- }
166
- /**
167
- * Private event handler used when listening to some specific key presses
168
- * (namely ESC and TAB)
169
- */
170
- bindKeypress(event) {
171
- // This is an escape hatch in case there are nested open dialogs, so that
172
- // only the top most dialog gets interacted with (`closest` is basically
173
- // `Element.prototype.closest()` accounting for Shadow DOM subtrees)
174
- if (closest('[aria-modal="true"]', getActiveEl()) !== this.$el) {
175
- return;
176
- }
177
- let hasOpenPopover = false;
178
- try {
179
- hasOpenPopover = !!this.$el.querySelector('[popover]:not([popover="manual"]):popover-open');
180
- }
181
- catch {
182
- // Run that DOM query in a try/catch because not all browsers support the
183
- // `:popover-open` selector, which would cause the whole expression to
184
- // fail
185
- // See: https://caniuse.com/mdn-css_selectors_popover-open
186
- // See: https://github.com/KittyGiraudel/a11y-dialog/pull/578#discussion_r1343215149
187
- }
188
- // If the dialog is shown and the ESC key is pressed, prevent any further
189
- // effects from the ESC key and hide the dialog, unless:
190
- // - its role is `alertdialog`, which means it should be modal
191
- // - or it contains an open popover, in which case ESC should close it
192
- if (event.key === 'Escape' &&
193
- this.$el.getAttribute('role') !== 'alertdialog' &&
194
- !hasOpenPopover) {
195
- event.preventDefault();
196
- this.hide(event);
197
- }
198
- // If the dialog is shown and the TAB key is pressed, make sure the focus
199
- // stays trapped within the dialog element
200
- if (event.key === 'Tab') {
201
- trapTabKey(this.$el, event);
202
- }
203
- }
204
- /**
205
- * If the dialog is shown and the focus is not within a dialog element (either
206
- * this one or another one in case of nested dialogs) or attribute, move it
207
- * back to the dialog container
208
- * See: https://github.com/KittyGiraudel/a11y-dialog/issues/177
209
- */
210
- maintainFocus(event) {
211
- const target = event.target;
212
- if (!target.closest(`[aria-modal="true"], [${SCOPE}-ignore-focus-trap]`)) {
213
- focus(this.$el);
214
- }
215
- }
216
- }
@@ -1,26 +0,0 @@
1
- /**
2
- * Set the focus to the first element with `autofocus` with the element or the
3
- * element itself.
4
- */
5
- export declare function focus(el: HTMLElement): void;
6
- /**
7
- * Get the first and last focusable elements within a given element.
8
- */
9
- export declare function getFocusableEdges(el: HTMLElement): readonly [HTMLElement | null, HTMLElement | null];
10
- /**
11
- * Get the active element, accounting for Shadow DOM subtrees.
12
- * @author Cory LaViska
13
- * @see: https://www.abeautifulsite.net/posts/finding-the-active-element-in-a-shadow-root/
14
- */
15
- export declare function getActiveEl(root?: Document | ShadowRoot): Element | null;
16
- /**
17
- * Trap the focus inside the given element
18
- */
19
- export declare function trapTabKey(el: HTMLElement, event: KeyboardEvent): void;
20
- /**
21
- * Find the closest element to the given element matching the given selector,
22
- * accounting for Shadow DOM subtrees.
23
- * @author Louis St-Amour
24
- * @see: https://stackoverflow.com/a/56105394
25
- */
26
- export declare function closest(selector: string, base: Element | null): Element | null;
@@ -1,206 +0,0 @@
1
- import focusableSelectors from 'focusable-selectors';
2
- /**
3
- * Set the focus to the first element with `autofocus` with the element or the
4
- * element itself.
5
- */
6
- export function focus(el) {
7
- ;
8
- (el.querySelector('[autofocus]') || el).focus();
9
- }
10
- /**
11
- * Get the first and last focusable elements within a given element.
12
- */
13
- export function getFocusableEdges(el) {
14
- // Check for a focusable element within the subtree of the given element.
15
- const firstEl = findFocusableEl(el, true);
16
- // Only if we find the first element do we need to look for the last one. If
17
- // there’s no last element, we set `lastEl` as a reference to `firstEl` so
18
- // that the returned array is still always of length 2.
19
- const lastEl = firstEl ? findFocusableEl(el, false) || firstEl : null;
20
- return [firstEl, lastEl];
21
- }
22
- /**
23
- * Find the first focusable element inside the given element if `forward` is
24
- * truthy or the last focusable element otherwise.
25
- */
26
- function findFocusableEl(el, forward) {
27
- // If we’re walking forward, check if this element is focusable, and return it
28
- // immediately if it is.
29
- if (forward && isFocusable(el))
30
- return el;
31
- // We should only search the subtree of this element if it can have focusable
32
- // children.
33
- if (canHaveFocusableChildren(el)) {
34
- // Start walking the DOM tree, looking for focusable elements.
35
- // Case 1: If this element has a shadow root, search it recursively.
36
- if (el.shadowRoot) {
37
- // Descend into this subtree.
38
- let next = getNextChildEl(el.shadowRoot, forward);
39
- // Traverse the siblings, searching the subtree of each one for focusable
40
- // elements.
41
- while (next) {
42
- const focusableEl = findFocusableEl(next, forward);
43
- if (focusableEl)
44
- return focusableEl;
45
- next = getNextSiblingEl(next, forward);
46
- }
47
- }
48
- // Case 2: If this element is a slot for a Custom Element, search its
49
- // assigned elements recursively.
50
- else if (el.localName === 'slot') {
51
- const assignedElements = el.assignedElements({
52
- flatten: true,
53
- });
54
- if (!forward)
55
- assignedElements.reverse();
56
- for (const assignedElement of assignedElements) {
57
- const focusableEl = findFocusableEl(assignedElement, forward);
58
- if (focusableEl)
59
- return focusableEl;
60
- }
61
- }
62
- // Case 3: this is a regular Light DOM element. Search its subtree.
63
- else {
64
- // Descend into this subtree.
65
- let next = getNextChildEl(el, forward);
66
- // Traverse siblings, searching the subtree of each one
67
- // for focusable elements.
68
- while (next) {
69
- const focusableEl = findFocusableEl(next, forward);
70
- if (focusableEl)
71
- return focusableEl;
72
- next = getNextSiblingEl(next, forward);
73
- }
74
- }
75
- }
76
- // If we’re walking backward, we want to check the element’s entire subtree
77
- // before checking the element itself. If this element is focusable, return
78
- // it.
79
- if (!forward && isFocusable(el))
80
- return el;
81
- return null;
82
- }
83
- function getNextChildEl(el, forward) {
84
- return forward ? el.firstElementChild : el.lastElementChild;
85
- }
86
- function getNextSiblingEl(el, forward) {
87
- return forward ? el.nextElementSibling : el.previousElementSibling;
88
- }
89
- /**
90
- * Determine if an element is hidden from the user.
91
- */
92
- const isHidden = (el) => {
93
- // Browsers hide all non-<summary> descendants of closed <details> elements
94
- // from user interaction, but those non-<summary> elements may still match our
95
- // focusable-selectors and may still have dimensions, so we need a special
96
- // case to ignore them.
97
- if (el.matches('details:not([open]) *') &&
98
- !el.matches('details>summary:first-of-type'))
99
- return true;
100
- // If this element has no painted dimensions, it's hidden.
101
- return !(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
102
- };
103
- /**
104
- * Determine if an element is focusable and has user-visible painted dimensions.
105
- */
106
- const isFocusable = (el) => {
107
- // A shadow host that delegates focus will never directly receive focus,
108
- // even with `tabindex=0`. Consider our <fancy-button> custom element, which
109
- // delegates focus to its shadow button:
110
- //
111
- // <fancy-button tabindex="0">
112
- // #shadow-root
113
- // <button><slot></slot></button>
114
- // </fancy-button>
115
- //
116
- // The browser acts as as if there is only one focusable element – the shadow
117
- // button. Our library should behave the same way.
118
- if (el.shadowRoot?.delegatesFocus)
119
- return false;
120
- return el.matches(focusableSelectors.join(',')) && !isHidden(el);
121
- };
122
- /**
123
- * Determine if an element can have focusable children. Useful for bailing out
124
- * early when walking the DOM tree.
125
- * @example
126
- * This div is inert, so none of its children can be focused, even though they
127
- * meet our criteria for what is focusable. Once we check the div, we can skip
128
- * the rest of the subtree.
129
- * ```html
130
- * <div inert>
131
- * <button>Button</button>
132
- * <a href="#">Link</a>
133
- * </div>
134
- * ```
135
- */
136
- function canHaveFocusableChildren(el) {
137
- // The browser will never send focus into a Shadow DOM if the host element
138
- // has a negative tabindex. This applies to both slotted Light DOM Shadow DOM
139
- // children
140
- if (el.shadowRoot && el.getAttribute('tabindex') === '-1')
141
- return false;
142
- // Elemments matching this selector are either hidden entirely from the user,
143
- // or are visible but unavailable for interaction. Their descentants can never
144
- // receive focus.
145
- return !el.matches(':disabled,[hidden],[inert]');
146
- }
147
- /**
148
- * Get the active element, accounting for Shadow DOM subtrees.
149
- * @author Cory LaViska
150
- * @see: https://www.abeautifulsite.net/posts/finding-the-active-element-in-a-shadow-root/
151
- */
152
- export function getActiveEl(root = document) {
153
- const activeEl = root.activeElement;
154
- if (!activeEl)
155
- return null;
156
- // If there’s a shadow root, recursively find the active element within it.
157
- // If the recursive call returns null, return the active element
158
- // of the top-level Document.
159
- if (activeEl.shadowRoot)
160
- return getActiveEl(activeEl.shadowRoot) || document.activeElement;
161
- // If not, we can just return the active element
162
- return activeEl;
163
- }
164
- /**
165
- * Trap the focus inside the given element
166
- */
167
- export function trapTabKey(el, event) {
168
- const [firstFocusableEl, lastFocusableEl] = getFocusableEdges(el);
169
- // If there are no focusable children in the dialog, prevent the user from
170
- // tabbing out of it
171
- if (!firstFocusableEl)
172
- return event.preventDefault();
173
- const activeEl = getActiveEl();
174
- // If the SHIFT key is pressed while tabbing (moving backwards) and the
175
- // currently focused item is the first one, move the focus to the last
176
- // focusable item from the dialog element
177
- if (event.shiftKey && activeEl === firstFocusableEl) {
178
- // @ts-ignore: we know that `lastFocusableEl` is not null here
179
- lastFocusableEl.focus();
180
- event.preventDefault();
181
- }
182
- // If the SHIFT key is not pressed (moving forwards) and the currently focused
183
- // item is the last one, move the focus to the first focusable item from the
184
- // dialog element
185
- else if (!event.shiftKey && activeEl === lastFocusableEl) {
186
- firstFocusableEl.focus();
187
- event.preventDefault();
188
- }
189
- }
190
- /**
191
- * Find the closest element to the given element matching the given selector,
192
- * accounting for Shadow DOM subtrees.
193
- * @author Louis St-Amour
194
- * @see: https://stackoverflow.com/a/56105394
195
- */
196
- export function closest(selector, base) {
197
- function from(el) {
198
- if (!el || el === document || el === window)
199
- return null;
200
- if (el.assignedSlot)
201
- el = el.assignedSlot;
202
- return (el.closest(selector) ||
203
- from(el.getRootNode().host));
204
- }
205
- return from(base);
206
- }
@@ -1,34 +0,0 @@
1
- <script lang="ts">
2
- import type { DrawerRoles } from './api';
3
- import Dialog from "../Dialog/Dialog.svelte";
4
- import { createEventDispatcher } from "svelte";
5
- const dispatch = createEventDispatcher();
6
-
7
- let drawerInstance;
8
- const assignDrawerRef = (ev) => {
9
- drawerInstance = ev.detail.instance;
10
- dispatch("instance", {
11
- instance: drawerInstance,
12
- });
13
- };
14
-
15
- export let id;
16
- export let drawerRoot;
17
- export let placement;
18
- export let title;
19
- export let role: DrawerRoles = "dialog";
20
- export let isAnimationFadeIn = true;
21
- </script>
22
- <Dialog
23
- id={id}
24
- dialogRoot={drawerRoot}
25
- drawerPlacement={placement}
26
- titleId="{`${title.replaceAll(' ', '-').toLowerCase()}-id`}"
27
- role={role}
28
- title={title}
29
- on:instance={assignDrawerRef}
30
- isAnimationFadeIn={isAnimationFadeIn}
31
- closeButtonLabel="Close drawer"
32
- >
33
- <slot />
34
- </Dialog>
@@ -1,26 +0,0 @@
1
- import { SvelteComponentTyped } from "svelte";
2
- import type { DrawerRoles } from './api';
3
- declare const __propDef: {
4
- props: {
5
- id: any;
6
- drawerRoot: any;
7
- placement: any;
8
- title: any;
9
- role?: DrawerRoles;
10
- isAnimationFadeIn?: boolean;
11
- };
12
- events: {
13
- instance: CustomEvent<any>;
14
- } & {
15
- [evt: string]: CustomEvent<any>;
16
- };
17
- slots: {
18
- default: {};
19
- };
20
- };
21
- export type DrawerProps = typeof __propDef.props;
22
- export type DrawerEvents = typeof __propDef.events;
23
- export type DrawerSlots = typeof __propDef.slots;
24
- export default class Drawer extends SvelteComponentTyped<DrawerProps, DrawerEvents, DrawerSlots> {
25
- }
26
- export {};
@@ -1 +0,0 @@
1
- export type DrawerRoles = 'alertdialog' | 'dialog';
@@ -1 +0,0 @@
1
- export {};
@@ -1,49 +0,0 @@
1
- <style>
2
- .empty-base,
3
- .empty {
4
- display: flex;
5
- flex-flow: column wrap;
6
- align-items: center;
7
- text-align: center;
8
- width: 100%;
9
- }
10
-
11
- .empty {
12
- padding: calc(2 * var(--functional-side-padding));
13
- background: var(--functional-gray-extra-light);
14
- }
15
-
16
- .empty-bordered {
17
- background: transparent;
18
- border: 1px solid var(--functional-gray-light);
19
- }
20
-
21
- .empty-rounded {
22
- border-radius: var(--functional-radius);
23
- }
24
-
25
- .empty-actions {
26
- margin-block-start: var(--spacing-24);
27
- }
28
-
29
- </style>
30
-
31
- <script lang="ts">
32
- export let isRounded = false;
33
- export let isBordered = false;
34
- const emptyClasses: string = [
35
- "empty",
36
- isRounded ? "empty-rounded" : "",
37
- isBordered ? "empty-bordered" : "",
38
- ]
39
- .filter((cl) => cl.length)
40
- .join(" ");
41
- </script>
42
-
43
- <div class={emptyClasses}>
44
- <slot name="header" />
45
- <slot name="body" />
46
- <div class="empty-actions">
47
- <slot name="footer" />
48
- </div>
49
- </div>
@@ -1,21 +0,0 @@
1
- import { SvelteComponentTyped } from "svelte";
2
- declare const __propDef: {
3
- props: {
4
- isRounded?: boolean;
5
- isBordered?: boolean;
6
- };
7
- events: {
8
- [evt: string]: CustomEvent<any>;
9
- };
10
- slots: {
11
- header: {};
12
- body: {};
13
- footer: {};
14
- };
15
- };
16
- export type EmptyStateProps = typeof __propDef.props;
17
- export type EmptyStateEvents = typeof __propDef.events;
18
- export type EmptyStateSlots = typeof __propDef.slots;
19
- export default class EmptyState extends SvelteComponentTyped<EmptyStateProps, EmptyStateEvents, EmptyStateSlots> {
20
- }
21
- export {};