@txstate-mws/svelte-components 0.0.61 → 0.0.65
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/dist/actions/a11y.js +3 -12
- package/dist/actions/glue.js +4 -4
- package/dist/actions/offset.js +3 -3
- package/dist/actions/resize.js +3 -3
- package/dist/actions/sticky.js +2 -2
- package/dist/actions/stickyfixed.js +2 -2
- package/dist/components/CollapsingTable.svelte +2 -1
- package/dist/components/FocusLock.svelte +22 -21
- package/dist/components/Modal.svelte +2 -1
- package/dist/components/PopupMenu.svelte +27 -44
- package/dist/lib/deepstore.js +1 -1
- package/dist/lib/derivedstore.js +1 -1
- package/dist/lib/repositioned.js +6 -6
- package/dist/lib/safestore.js +1 -1
- package/dist/lib/substore.js +2 -2
- package/dist/ts/actions/a11y.d.ts +1 -1
- package/dist/ts/components/CollapsingTable.svelte +2 -0
- package/dist/ts/components/FocusLock.svelte +16 -8
- package/dist/ts/components/Modal.svelte +2 -1
- package/dist/ts/tests/Modal/ModalTest.svelte +1 -1
- package/package.json +1 -1
package/dist/actions/a11y.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.buttonify = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Turns any HTML element into an accessible button that responds to keyboard events and has
|
|
6
6
|
* role="button" and the tabindex attribute set. You are still responsible for making sure it has
|
|
7
7
|
* readable content or a good label.
|
|
8
8
|
*/
|
|
9
|
-
function
|
|
9
|
+
function buttonify(node) {
|
|
10
10
|
function keydown(e) {
|
|
11
11
|
if (e.key === 'Enter') {
|
|
12
12
|
if (!e.shiftKey && !e.metaKey && !e.ctrlKey && !e.altKey) {
|
|
@@ -16,14 +16,6 @@ function button(node) {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
function click(e) {
|
|
20
|
-
if (!(e instanceof CustomEvent)) {
|
|
21
|
-
e.preventDefault();
|
|
22
|
-
e.stopPropagation();
|
|
23
|
-
node.dispatchEvent(new CustomEvent('click'));
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
node.addEventListener('click', click);
|
|
27
19
|
node.addEventListener('keydown', keydown);
|
|
28
20
|
if (node.tabIndex < 0)
|
|
29
21
|
node.tabIndex = 0;
|
|
@@ -31,9 +23,8 @@ function button(node) {
|
|
|
31
23
|
node.style.cursor = 'pointer';
|
|
32
24
|
return {
|
|
33
25
|
destroy() {
|
|
34
|
-
node.removeEventListener('click', click);
|
|
35
26
|
node.removeEventListener('keydown', keydown);
|
|
36
27
|
}
|
|
37
28
|
};
|
|
38
29
|
}
|
|
39
|
-
exports.
|
|
30
|
+
exports.buttonify = buttonify;
|
package/dist/actions/glue.js
CHANGED
|
@@ -10,12 +10,12 @@ function glue(el, { target, align = 'auto', cover = false, store }) {
|
|
|
10
10
|
}
|
|
11
11
|
let halign;
|
|
12
12
|
let valign;
|
|
13
|
-
let sharedOffset = lib_1.sharedOffsetParent(el, target);
|
|
13
|
+
let sharedOffset = (0, lib_1.sharedOffsetParent)(el, target);
|
|
14
14
|
function reposition(offset) {
|
|
15
15
|
if (!target || !sharedOffset || !(el.offsetParent instanceof HTMLElement))
|
|
16
16
|
return;
|
|
17
17
|
let autoalign = align;
|
|
18
|
-
const parentoffset = el.offsetParent === sharedOffset && target !== sharedOffset ? { top: 0, left: 0, bottom: 0, right: 0 } : lib_1.targetOffset(el.offsetParent, sharedOffset);
|
|
18
|
+
const parentoffset = el.offsetParent === sharedOffset && target !== sharedOffset ? { top: 0, left: 0, bottom: 0, right: 0 } : (0, lib_1.targetOffset)(el.offsetParent, sharedOffset);
|
|
19
19
|
if (align === 'auto') {
|
|
20
20
|
const rect = target.getBoundingClientRect();
|
|
21
21
|
const leftright = window.innerWidth - rect.right > rect.left ? 'left' : 'right';
|
|
@@ -65,7 +65,7 @@ function glue(el, { target, align = 'auto', cover = false, store }) {
|
|
|
65
65
|
}
|
|
66
66
|
store === null || store === void 0 ? void 0 : store.update(v => (Object.assign(Object.assign({}, v), { valign, halign })));
|
|
67
67
|
}
|
|
68
|
-
const { destroy, update } = lib_1.watchForPositionChangeInContainer(target, sharedOffset, reposition);
|
|
68
|
+
const { destroy, update } = (0, lib_1.watchForPositionChangeInContainer)(target, sharedOffset, reposition);
|
|
69
69
|
return {
|
|
70
70
|
update({ target: utarget, align: ualign = 'auto', cover: ucover = false, store: ustore }) {
|
|
71
71
|
align = ualign;
|
|
@@ -75,7 +75,7 @@ function glue(el, { target, align = 'auto', cover = false, store }) {
|
|
|
75
75
|
store = ustore;
|
|
76
76
|
}
|
|
77
77
|
if (target !== utarget) {
|
|
78
|
-
sharedOffset = lib_1.sharedOffsetParent(el, utarget);
|
|
78
|
+
sharedOffset = (0, lib_1.sharedOffsetParent)(el, utarget);
|
|
79
79
|
target = utarget;
|
|
80
80
|
update(target, sharedOffset, reposition);
|
|
81
81
|
}
|
package/dist/actions/offset.js
CHANGED
|
@@ -12,8 +12,8 @@ function offset(el, config) {
|
|
|
12
12
|
config.store.update(v => (Object.assign(Object.assign({}, v), current)));
|
|
13
13
|
el.dispatchEvent(new CustomEvent('offset', { detail: current }));
|
|
14
14
|
}
|
|
15
|
-
let resolvedchange = (config === null || config === void 0 ? void 0 : config.debounce) ? lib_1.debounced(lookforoffsetchange, config.debounce) : lookforoffsetchange;
|
|
16
|
-
const { destroy, update } = lib_1.watchForPositionChange(el, resolvedchange);
|
|
15
|
+
let resolvedchange = (config === null || config === void 0 ? void 0 : config.debounce) ? (0, lib_1.debounced)(lookforoffsetchange, config.debounce) : lookforoffsetchange;
|
|
16
|
+
const { destroy, update } = (0, lib_1.watchForPositionChange)(el, resolvedchange);
|
|
17
17
|
return {
|
|
18
18
|
update(newConfig) {
|
|
19
19
|
var _a;
|
|
@@ -23,7 +23,7 @@ function offset(el, config) {
|
|
|
23
23
|
(_a = newConfig === null || newConfig === void 0 ? void 0 : newConfig.store) === null || _a === void 0 ? void 0 : _a.update(v => (Object.assign(Object.assign({}, v), lastOffset)));
|
|
24
24
|
}
|
|
25
25
|
if ((newConfig === null || newConfig === void 0 ? void 0 : newConfig.debounce) !== (config === null || config === void 0 ? void 0 : config.debounce)) {
|
|
26
|
-
resolvedchange = (newConfig === null || newConfig === void 0 ? void 0 : newConfig.debounce) ? lib_1.debounced(lookforoffsetchange, newConfig.debounce) : lookforoffsetchange;
|
|
26
|
+
resolvedchange = (newConfig === null || newConfig === void 0 ? void 0 : newConfig.debounce) ? (0, lib_1.debounced)(lookforoffsetchange, newConfig.debounce) : lookforoffsetchange;
|
|
27
27
|
update(el, resolvedchange);
|
|
28
28
|
}
|
|
29
29
|
config = newConfig;
|
package/dist/actions/resize.js
CHANGED
|
@@ -12,7 +12,7 @@ function resize(el, config) {
|
|
|
12
12
|
let lastSize = {};
|
|
13
13
|
function watch() {
|
|
14
14
|
const current = { clientWidth: el.clientWidth, clientHeight: el.clientHeight, offsetWidth: el.offsetWidth, offsetHeight: el.offsetHeight };
|
|
15
|
-
if (!fast_deep_equal_1.default(lastSize, current)) {
|
|
15
|
+
if (!(0, fast_deep_equal_1.default)(lastSize, current)) {
|
|
16
16
|
lastSize = current;
|
|
17
17
|
if (config === null || config === void 0 ? void 0 : config.store)
|
|
18
18
|
config.store.set(current);
|
|
@@ -21,7 +21,7 @@ function resize(el, config) {
|
|
|
21
21
|
}
|
|
22
22
|
if (!ResizeObserver)
|
|
23
23
|
return watch(); // support SSR
|
|
24
|
-
let observer = new ResizeObserver((config === null || config === void 0 ? void 0 : config.debounce) ? lib_1.debounced(watch, config.debounce) : watch);
|
|
24
|
+
let observer = new ResizeObserver((config === null || config === void 0 ? void 0 : config.debounce) ? (0, lib_1.debounced)(watch, config.debounce) : watch);
|
|
25
25
|
observer.observe(el);
|
|
26
26
|
watch();
|
|
27
27
|
return {
|
|
@@ -34,7 +34,7 @@ function resize(el, config) {
|
|
|
34
34
|
}
|
|
35
35
|
if (!!(newConfig === null || newConfig === void 0 ? void 0 : newConfig.debounce) !== !!(config === null || config === void 0 ? void 0 : config.debounce)) {
|
|
36
36
|
observer.disconnect();
|
|
37
|
-
observer = new ResizeObserver((newConfig === null || newConfig === void 0 ? void 0 : newConfig.debounce) ? lib_1.debounced(watch, newConfig.debounce) : watch);
|
|
37
|
+
observer = new ResizeObserver((newConfig === null || newConfig === void 0 ? void 0 : newConfig.debounce) ? (0, lib_1.debounced)(watch, newConfig.debounce) : watch);
|
|
38
38
|
observer.observe(el);
|
|
39
39
|
}
|
|
40
40
|
config = newConfig;
|
package/dist/actions/sticky.js
CHANGED
|
@@ -60,7 +60,7 @@ function sticky(el, config) {
|
|
|
60
60
|
if (!(offsetParent instanceof HTMLElement))
|
|
61
61
|
return;
|
|
62
62
|
if (lastOffsetParent !== offsetParent) {
|
|
63
|
-
offset[0] = lib_1.bodyOffset(offsetParent);
|
|
63
|
+
offset[0] = (0, lib_1.bodyOffset)(offsetParent);
|
|
64
64
|
update(offsetParent, onpositionchange);
|
|
65
65
|
lastOffsetParent = offsetParent;
|
|
66
66
|
}
|
|
@@ -69,7 +69,7 @@ function sticky(el, config) {
|
|
|
69
69
|
scrollend = Math.max(scrollstart, containeroffset.top + ((_a = config === null || config === void 0 ? void 0 : config.target) !== null && _a !== void 0 ? _a : offsetParent).clientHeight - el.offsetHeight);
|
|
70
70
|
recalc(window.scrollY);
|
|
71
71
|
}
|
|
72
|
-
const { destroy, update } = lib_1.watchForPositionChange([el.offsetParent, config === null || config === void 0 ? void 0 : config.target], onpositionchange);
|
|
72
|
+
const { destroy, update } = (0, lib_1.watchForPositionChange)([el.offsetParent, config === null || config === void 0 ? void 0 : config.target], onpositionchange);
|
|
73
73
|
window.addEventListener('scroll', onscroll, { passive: true });
|
|
74
74
|
window.addEventListener('wheel', onwheel, { passive: false });
|
|
75
75
|
function stickyUpdate(newConfig) {
|
|
@@ -127,7 +127,7 @@ function stickyfixed(el, config) {
|
|
|
127
127
|
if (!(offsetParent instanceof HTMLElement))
|
|
128
128
|
return;
|
|
129
129
|
if (lastOffsetParent !== offsetParent) {
|
|
130
|
-
offset[0] = lib_1.bodyOffset(offsetParent);
|
|
130
|
+
offset[0] = (0, lib_1.bodyOffset)(offsetParent);
|
|
131
131
|
update(offsetParent, onpositionchange);
|
|
132
132
|
lastOffsetParent = offsetParent;
|
|
133
133
|
}
|
|
@@ -142,7 +142,7 @@ function stickyfixed(el, config) {
|
|
|
142
142
|
scrollend = Math.max(scrollstart, containeroffset.top + ((_b = config === null || config === void 0 ? void 0 : config.target) !== null && _b !== void 0 ? _b : offsetParent).clientHeight - el.offsetHeight);
|
|
143
143
|
recalc(window.scrollY);
|
|
144
144
|
}
|
|
145
|
-
const { destroy, update } = lib_1.watchForPositionChange([el.offsetParent, config === null || config === void 0 ? void 0 : config.target], onpositionchange);
|
|
145
|
+
const { destroy, update } = (0, lib_1.watchForPositionChange)([el.offsetParent, config === null || config === void 0 ? void 0 : config.target], onpositionchange);
|
|
146
146
|
window.addEventListener('scroll', onscroll, { passive: true });
|
|
147
147
|
function stickyUpdate(newConfig) {
|
|
148
148
|
var _a;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<script>var _a;
|
|
2
2
|
import { DeepStore, classes } from '../lib';
|
|
3
|
-
;
|
|
4
3
|
import { derived } from 'svelte/store';
|
|
5
4
|
import DefaultPopupMenu from './PopupMenu.svelte';
|
|
6
5
|
import ScreenReaderOnly from './ScreenReaderOnly.svelte';
|
|
@@ -113,7 +112,9 @@ $: menubuttonelement = headers[$state.keepcolumns.length - 1];
|
|
|
113
112
|
{#if slots.footer}<tfoot><slot name="footer" item={undefined} key={undefined} value={undefined}></slot></tfoot>{/if}
|
|
114
113
|
</table>
|
|
115
114
|
</div>
|
|
115
|
+
{#if $menuitems.length > 0}
|
|
116
116
|
<svelte:component this={PopupMenu} {menuContainerClass} {menuClass} {menuItemClass} {menuItemHilitedClass} items={$menuitems} buttonelement={menubuttonelement} bind:selected></svelte:component>
|
|
117
|
+
{/if}
|
|
117
118
|
|
|
118
119
|
<style>
|
|
119
120
|
table { width: 100%; }
|
|
@@ -1,30 +1,23 @@
|
|
|
1
|
-
<script context="module">
|
|
2
|
-
const FocusLockStack = [];
|
|
1
|
+
<script context="module">const FocusLockStack = [];
|
|
3
2
|
</script>
|
|
4
3
|
|
|
5
|
-
<script>
|
|
6
|
-
|
|
7
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
8
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
9
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
10
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
11
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
12
|
-
});
|
|
13
|
-
};
|
|
14
|
-
export let returnfocusto = null;
|
|
4
|
+
<script>export let returnfocusto = undefined;
|
|
5
|
+
export let initialfocus = undefined;
|
|
15
6
|
export let hidefocus = true;
|
|
16
|
-
export let hidefocuslabel = "focus is above dialog";
|
|
7
|
+
export let hidefocuslabel = "focus is above modal dialog, start tabbing";
|
|
17
8
|
export let escapable = true;
|
|
18
9
|
let className = '';
|
|
19
10
|
export { className as class };
|
|
20
11
|
import { onMount, onDestroy, createEventDispatcher, tick } from 'svelte';
|
|
21
12
|
import { tabbable } from 'tabbable';
|
|
22
|
-
import {
|
|
13
|
+
import { buttonify } from '../actions';
|
|
23
14
|
import ScreenReaderOnly from './ScreenReaderOnly.svelte';
|
|
24
15
|
const dispatch = createEventDispatcher();
|
|
25
16
|
let lockelement;
|
|
26
17
|
let abovelockelement;
|
|
27
18
|
let active = true;
|
|
19
|
+
if (initialfocus)
|
|
20
|
+
hidefocus = false;
|
|
28
21
|
onMount(() => {
|
|
29
22
|
const prevFocusLock = FocusLockStack.slice(-1)[0];
|
|
30
23
|
if (prevFocusLock)
|
|
@@ -33,23 +26,31 @@ onMount(() => {
|
|
|
33
26
|
pause: () => { active = false; },
|
|
34
27
|
unpause: () => { active = true; }
|
|
35
28
|
});
|
|
36
|
-
if (
|
|
29
|
+
if (typeof returnfocusto === 'undefined') {
|
|
37
30
|
returnfocusto = document.querySelector(':focus');
|
|
38
31
|
}
|
|
39
|
-
|
|
32
|
+
if (initialfocus) {
|
|
33
|
+
const focusEl = lockelement.querySelector(initialfocus);
|
|
34
|
+
if (focusEl instanceof HTMLElement)
|
|
35
|
+
focusEl.focus();
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
setInitialFocus();
|
|
39
|
+
}
|
|
40
40
|
});
|
|
41
|
-
onDestroy(() =>
|
|
41
|
+
onDestroy(async () => {
|
|
42
42
|
const wasactive = active;
|
|
43
|
+
const focuswasinside = lockelement.matches(':focus-within');
|
|
43
44
|
active = false;
|
|
44
|
-
|
|
45
|
-
if (returnfocusto && wasactive) {
|
|
45
|
+
await tick();
|
|
46
|
+
if (returnfocusto && wasactive && focuswasinside) {
|
|
46
47
|
returnfocusto.focus();
|
|
47
48
|
}
|
|
48
49
|
FocusLockStack.pop();
|
|
49
50
|
const prevFocusLock = FocusLockStack.slice(-1)[0];
|
|
50
51
|
if (prevFocusLock)
|
|
51
52
|
prevFocusLock.unpause();
|
|
52
|
-
})
|
|
53
|
+
});
|
|
53
54
|
const setInitialFocus = () => {
|
|
54
55
|
const firstfocus = tabbable(lockelement)[0];
|
|
55
56
|
if (firstfocus && firstfocus.focus) {
|
|
@@ -81,7 +82,7 @@ const focusin = (e) => {
|
|
|
81
82
|
<div class={className} role="alertdialog" aria-modal="true" on:click|stopPropagation on:keydown|stopPropagation={keydown} on:focusin={focusin}>
|
|
82
83
|
<div bind:this={abovelockelement} tabindex="0"></div>
|
|
83
84
|
<div bind:this={lockelement} on:keydown={keydown}>
|
|
84
|
-
{#if hidefocus}<div class="hiddenfocus" use:
|
|
85
|
+
{#if hidefocus}<div class="hiddenfocus" use:buttonify on:blur={() =>{ hidefocus = false }} on:click={() => escapable && dispatch('escape')}><ScreenReaderOnly>{hidefocuslabel}{#if escapable}, click to escape or use escape key at any time{/if}</ScreenReaderOnly></div>{/if}
|
|
85
86
|
<slot></slot>
|
|
86
87
|
</div>
|
|
87
88
|
<div tabindex="0"></div>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
export let hidefocus = true;
|
|
3
3
|
export let hidefocuslabel = undefined;
|
|
4
4
|
export let returnfocusto = undefined;
|
|
5
|
+
export let initialfocus = undefined;
|
|
5
6
|
import FocusLock from './FocusLock.svelte';
|
|
6
7
|
import { createEventDispatcher, onMount } from 'svelte';
|
|
7
8
|
import { portal } from '../actions';
|
|
@@ -18,7 +19,7 @@ onMount(() => {
|
|
|
18
19
|
</script>
|
|
19
20
|
|
|
20
21
|
<div use:portal class="modal-backdrop" on:click={() => lockbackdrop || endmodal()}>
|
|
21
|
-
<FocusLock class="modal-container" escapable={!lockbackdrop} on:escape={endmodal} {hidefocus} {hidefocuslabel} {returnfocusto} on:escape={() => lockbackdrop || endmodal()}>
|
|
22
|
+
<FocusLock class="modal-container" escapable={!lockbackdrop} on:escape={endmodal} {hidefocus} {hidefocuslabel} {returnfocusto} {initialfocus} on:escape={() => lockbackdrop || endmodal()}>
|
|
22
23
|
<slot></slot>
|
|
23
24
|
</FocusLock>
|
|
24
25
|
</div>
|
|
@@ -1,18 +1,7 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
;
|
|
11
|
-
import { glue, portal } from '../actions';
|
|
1
|
+
<script>import { glue, portal } from '../actions';
|
|
12
2
|
import { createEventDispatcher, onDestroy, tick } from 'svelte';
|
|
13
3
|
import { randomid } from 'txstate-utils';
|
|
14
|
-
;
|
|
15
|
-
import { DeepStore, SettableSubject } from '../lib';
|
|
4
|
+
import { DeepStore } from '../lib';
|
|
16
5
|
import ScreenReaderOnly from './ScreenReaderOnly.svelte';
|
|
17
6
|
const dispatch = createEventDispatcher();
|
|
18
7
|
export let menushown = false;
|
|
@@ -40,34 +29,30 @@ let lastactive = items.length - 1;
|
|
|
40
29
|
function hiddenItem(item) {
|
|
41
30
|
return !!item && !showSelected && item.value === (selected === null || selected === void 0 ? void 0 : selected.value);
|
|
42
31
|
}
|
|
43
|
-
function reactToItems(..._) {
|
|
32
|
+
async function reactToItems(..._) {
|
|
44
33
|
var _a;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
hilited = firstactive;
|
|
50
|
-
});
|
|
34
|
+
firstactive = items.findIndex(itm => !itm.disabled && !hiddenItem(itm));
|
|
35
|
+
lastactive = items.length - [...items].reverse().findIndex(itm => !itm.disabled && !hiddenItem(itm)) - 1;
|
|
36
|
+
if (hilited && ((_a = items[hilited]) === null || _a === void 0 ? void 0 : _a.disabled))
|
|
37
|
+
hilited = firstactive;
|
|
51
38
|
}
|
|
52
39
|
$: reactToItems(items, selected);
|
|
53
|
-
function reactToMenuShown(_) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
buttonelement.focus();
|
|
70
|
-
});
|
|
40
|
+
async function reactToMenuShown(_) {
|
|
41
|
+
if (!buttonelement) {
|
|
42
|
+
hilited = undefined;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
await tick();
|
|
46
|
+
if (!menushown) {
|
|
47
|
+
hilited = undefined;
|
|
48
|
+
buttonelement.removeAttribute('aria-controls');
|
|
49
|
+
buttonelement.setAttribute('aria-expanded', 'false');
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
buttonelement.setAttribute('aria-controls', menuid);
|
|
53
|
+
buttonelement.setAttribute('aria-expanded', 'true');
|
|
54
|
+
}
|
|
55
|
+
buttonelement.focus();
|
|
71
56
|
}
|
|
72
57
|
$: reactToMenuShown(menushown);
|
|
73
58
|
function move(idx) {
|
|
@@ -157,12 +142,10 @@ function onbuttonclick(e) {
|
|
|
157
142
|
e.preventDefault();
|
|
158
143
|
menushown = !menushown;
|
|
159
144
|
}
|
|
160
|
-
function onblur(e) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
menushown = false;
|
|
165
|
-
});
|
|
145
|
+
async function onblur(e) {
|
|
146
|
+
// tabindex=-1 on our menu elements means e.relatedTarget will be set
|
|
147
|
+
if (!(e.relatedTarget instanceof HTMLElement && (menuelement === null || menuelement === void 0 ? void 0 : menuelement.contains(e.relatedTarget))))
|
|
148
|
+
menushown = false;
|
|
166
149
|
}
|
|
167
150
|
function cleanup(element) {
|
|
168
151
|
if (element) {
|
package/dist/lib/deepstore.js
CHANGED
|
@@ -45,7 +45,7 @@ class DeepStore {
|
|
|
45
45
|
set(value) {
|
|
46
46
|
if (this.pause)
|
|
47
47
|
return;
|
|
48
|
-
if (!fast_deep_equal_1.default(value, this.value)) {
|
|
48
|
+
if (!(0, fast_deep_equal_1.default)(value, this.value)) {
|
|
49
49
|
this.value = this.clone(value);
|
|
50
50
|
for (const [id, run] of this.subscribers) {
|
|
51
51
|
run(value);
|
package/dist/lib/derivedstore.js
CHANGED
|
@@ -18,7 +18,7 @@ class DerivedStore extends deepstore_1.DeepStore {
|
|
|
18
18
|
constructor(store, getter) {
|
|
19
19
|
if (typeof getter === 'string') {
|
|
20
20
|
const accessor = getter;
|
|
21
|
-
getter = (parentValue) => txstate_utils_1.get(parentValue, accessor);
|
|
21
|
+
getter = (parentValue) => (0, txstate_utils_1.get)(parentValue, accessor);
|
|
22
22
|
}
|
|
23
23
|
super({});
|
|
24
24
|
if (Array.isArray(store)) {
|
package/dist/lib/repositioned.js
CHANGED
|
@@ -24,7 +24,7 @@ function watchForMutations(cb) {
|
|
|
24
24
|
characterData: true
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
|
-
const id = txstate_utils_1.randomid();
|
|
27
|
+
const id = (0, txstate_utils_1.randomid)();
|
|
28
28
|
observers.set(id, cb);
|
|
29
29
|
cb();
|
|
30
30
|
return {
|
|
@@ -40,10 +40,10 @@ function watchForMutations(cb) {
|
|
|
40
40
|
exports.watchForMutations = watchForMutations;
|
|
41
41
|
function watchForPositionChange(el, cb) {
|
|
42
42
|
let lastoffsets = [];
|
|
43
|
-
let els = txstate_utils_1.toArray(el).filter(txstate_utils_1.isNotNull);
|
|
43
|
+
let els = (0, txstate_utils_1.toArray)(el).filter(txstate_utils_1.isNotNull);
|
|
44
44
|
function watch() {
|
|
45
45
|
const offsets = els.map(bodyoffset_1.bodyOffset);
|
|
46
|
-
if (offsets.some((offset, i) => !fast_deep_equal_1.default(offset, lastoffsets[i]))) {
|
|
46
|
+
if (offsets.some((offset, i) => !(0, fast_deep_equal_1.default)(offset, lastoffsets[i]))) {
|
|
47
47
|
lastoffsets = offsets;
|
|
48
48
|
Array.isArray(el) ? cb(offsets) : cb(offsets[0]);
|
|
49
49
|
}
|
|
@@ -54,7 +54,7 @@ function watchForPositionChange(el, cb) {
|
|
|
54
54
|
const changed = newEl !== el || newCb !== cb;
|
|
55
55
|
if (changed) {
|
|
56
56
|
el = newEl;
|
|
57
|
-
els = txstate_utils_1.toArray(el).filter(txstate_utils_1.isNotNull);
|
|
57
|
+
els = (0, txstate_utils_1.toArray)(el).filter(txstate_utils_1.isNotNull);
|
|
58
58
|
cb = newCb;
|
|
59
59
|
watch();
|
|
60
60
|
}
|
|
@@ -68,8 +68,8 @@ function watchForPositionChangeInContainer(el, container, cb) {
|
|
|
68
68
|
function watch() {
|
|
69
69
|
if (!el || !container)
|
|
70
70
|
return;
|
|
71
|
-
const offset = bodyoffset_1.targetOffset(el, container);
|
|
72
|
-
if (!fast_deep_equal_1.default(offset, lastoffset)) {
|
|
71
|
+
const offset = (0, bodyoffset_1.targetOffset)(el, container);
|
|
72
|
+
if (!(0, fast_deep_equal_1.default)(offset, lastoffset)) {
|
|
73
73
|
lastoffset = offset;
|
|
74
74
|
cb(offset);
|
|
75
75
|
}
|
package/dist/lib/safestore.js
CHANGED
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.SafeStore = void 0;
|
|
7
7
|
const deepstore_1 = require("./deepstore");
|
|
8
8
|
const rfdc_1 = __importDefault(require("rfdc"));
|
|
9
|
-
const cloneDeep = rfdc_1.default();
|
|
9
|
+
const cloneDeep = (0, rfdc_1.default)();
|
|
10
10
|
class SafeStore extends deepstore_1.DeepStore {
|
|
11
11
|
clone(value) {
|
|
12
12
|
return cloneDeep(value);
|
package/dist/lib/substore.js
CHANGED
|
@@ -21,8 +21,8 @@ class SubStore extends deepstore_1.DeepStore {
|
|
|
21
21
|
constructor(store, getter, setter) {
|
|
22
22
|
if (typeof getter === 'string') {
|
|
23
23
|
const accessor = getter;
|
|
24
|
-
getter = parentValue => txstate_utils_1.get(parentValue, accessor);
|
|
25
|
-
setter = (newValue, parentValue) => txstate_utils_1.set(parentValue, accessor, newValue);
|
|
24
|
+
getter = parentValue => (0, txstate_utils_1.get)(parentValue, accessor);
|
|
25
|
+
setter = (newValue, parentValue) => (0, txstate_utils_1.set)(parentValue, accessor, newValue);
|
|
26
26
|
}
|
|
27
27
|
super({});
|
|
28
28
|
this.parentStore = store;
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
* role="button" and the tabindex attribute set. You are still responsible for making sure it has
|
|
4
4
|
* readable content or a good label.
|
|
5
5
|
*/
|
|
6
|
-
export declare function
|
|
6
|
+
export declare function buttonify(node: HTMLElement): {
|
|
7
7
|
destroy(): void;
|
|
8
8
|
};
|
|
@@ -112,7 +112,9 @@
|
|
|
112
112
|
{#if slots.footer}<tfoot><slot name="footer" item={undefined} key={undefined} value={undefined}></slot></tfoot>{/if}
|
|
113
113
|
</table>
|
|
114
114
|
</div>
|
|
115
|
+
{#if $menuitems.length > 0}
|
|
115
116
|
<svelte:component this={PopupMenu} {menuContainerClass} {menuClass} {menuItemClass} {menuItemHilitedClass} items={$menuitems} buttonelement={menubuttonelement} bind:selected></svelte:component>
|
|
117
|
+
{/if}
|
|
116
118
|
|
|
117
119
|
<style>
|
|
118
120
|
table { width: 100%; }
|
|
@@ -3,21 +3,23 @@
|
|
|
3
3
|
</script>
|
|
4
4
|
|
|
5
5
|
<script lang="ts">
|
|
6
|
-
export let returnfocusto: HTMLElement|null =
|
|
6
|
+
export let returnfocusto: HTMLElement|null|undefined = undefined
|
|
7
|
+
export let initialfocus: string|undefined = undefined
|
|
7
8
|
export let hidefocus = true
|
|
8
|
-
export let hidefocuslabel = "focus is above dialog"
|
|
9
|
+
export let hidefocuslabel = "focus is above modal dialog, start tabbing"
|
|
9
10
|
export let escapable = true
|
|
10
11
|
let className = ''
|
|
11
12
|
export { className as class }
|
|
12
13
|
|
|
13
14
|
import { onMount, onDestroy, createEventDispatcher, tick } from 'svelte'
|
|
14
15
|
import { tabbable } from 'tabbable'
|
|
15
|
-
import {
|
|
16
|
+
import { buttonify } from '../actions'
|
|
16
17
|
import ScreenReaderOnly from './ScreenReaderOnly.svelte'
|
|
17
18
|
const dispatch = createEventDispatcher()
|
|
18
19
|
let lockelement: HTMLElement
|
|
19
20
|
let abovelockelement: HTMLElement
|
|
20
21
|
let active = true
|
|
22
|
+
if (initialfocus) hidefocus = false
|
|
21
23
|
onMount(() => {
|
|
22
24
|
const prevFocusLock = FocusLockStack.slice(-1)[0]
|
|
23
25
|
if (prevFocusLock) prevFocusLock.pause()
|
|
@@ -25,16 +27,22 @@
|
|
|
25
27
|
pause: () => { active = false },
|
|
26
28
|
unpause: () => { active = true }
|
|
27
29
|
})
|
|
28
|
-
if (
|
|
29
|
-
returnfocusto = document.querySelector(':focus')
|
|
30
|
+
if (typeof returnfocusto === 'undefined') {
|
|
31
|
+
returnfocusto = document.querySelector(':focus') as HTMLElement
|
|
32
|
+
}
|
|
33
|
+
if (initialfocus) {
|
|
34
|
+
const focusEl = lockelement.querySelector(initialfocus)
|
|
35
|
+
if (focusEl instanceof HTMLElement) focusEl.focus()
|
|
36
|
+
} else {
|
|
37
|
+
setInitialFocus()
|
|
30
38
|
}
|
|
31
|
-
setInitialFocus()
|
|
32
39
|
})
|
|
33
40
|
onDestroy(async () => {
|
|
34
41
|
const wasactive = active
|
|
42
|
+
const focuswasinside = lockelement.matches(':focus-within')
|
|
35
43
|
active = false
|
|
36
44
|
await tick()
|
|
37
|
-
if (returnfocusto && wasactive) {
|
|
45
|
+
if (returnfocusto && wasactive && focuswasinside) {
|
|
38
46
|
returnfocusto.focus()
|
|
39
47
|
}
|
|
40
48
|
FocusLockStack.pop()
|
|
@@ -70,7 +78,7 @@
|
|
|
70
78
|
<div class={className} role="alertdialog" aria-modal="true" on:click|stopPropagation on:keydown|stopPropagation={keydown} on:focusin={focusin}>
|
|
71
79
|
<div bind:this={abovelockelement} tabindex="0"></div>
|
|
72
80
|
<div bind:this={lockelement} on:keydown={keydown}>
|
|
73
|
-
{#if hidefocus}<div class="hiddenfocus" use:
|
|
81
|
+
{#if hidefocus}<div class="hiddenfocus" use:buttonify on:blur={() =>{ hidefocus = false }} on:click={() => escapable && dispatch('escape')}><ScreenReaderOnly>{hidefocuslabel}{#if escapable}, click to escape or use escape key at any time{/if}</ScreenReaderOnly></div>{/if}
|
|
74
82
|
<slot></slot>
|
|
75
83
|
</div>
|
|
76
84
|
<div tabindex="0"></div>
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
export let hidefocus = true
|
|
4
4
|
export let hidefocuslabel: string|undefined = undefined
|
|
5
5
|
export let returnfocusto: HTMLElement|undefined = undefined
|
|
6
|
+
export let initialfocus: string|undefined = undefined
|
|
6
7
|
import FocusLock from './FocusLock.svelte'
|
|
7
8
|
import { createEventDispatcher, onMount } from 'svelte'
|
|
8
9
|
import { portal } from '../actions';
|
|
@@ -20,7 +21,7 @@
|
|
|
20
21
|
</script>
|
|
21
22
|
|
|
22
23
|
<div use:portal class="modal-backdrop" on:click={() => lockbackdrop || endmodal()}>
|
|
23
|
-
<FocusLock class="modal-container" escapable={!lockbackdrop} on:escape={endmodal} {hidefocus} {hidefocuslabel} {returnfocusto} on:escape={() => lockbackdrop || endmodal()}>
|
|
24
|
+
<FocusLock class="modal-container" escapable={!lockbackdrop} on:escape={endmodal} {hidefocus} {hidefocuslabel} {returnfocusto} {initialfocus} on:escape={() => lockbackdrop || endmodal()}>
|
|
24
25
|
<slot></slot>
|
|
25
26
|
</FocusLock>
|
|
26
27
|
</div>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
</script>
|
|
5
5
|
|
|
6
6
|
{#if shown}
|
|
7
|
-
<Modal on:dismiss={() => shown = false}>
|
|
7
|
+
<Modal initialfocus='input[type="submit"]' on:dismiss={() => shown = false}>
|
|
8
8
|
<form>
|
|
9
9
|
<div class="formfield">
|
|
10
10
|
<label for="firstname">First Name:</label><input id="firstname" type="text" name="firstname">
|