@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.
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.button = void 0;
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 button(node) {
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.button = button;
30
+ exports.buttonify = buttonify;
@@ -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
  }
@@ -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;
@@ -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;
@@ -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">"use strict";
2
- const FocusLockStack = [];
1
+ <script context="module">const FocusLockStack = [];
3
2
  </script>
4
3
 
5
- <script>var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
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 { button } from '../actions';
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 (!returnfocusto) {
29
+ if (typeof returnfocusto === 'undefined') {
37
30
  returnfocusto = document.querySelector(':focus');
38
31
  }
39
- setInitialFocus();
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(() => __awaiter(void 0, void 0, void 0, function* () {
41
+ onDestroy(async () => {
42
42
  const wasactive = active;
43
+ const focuswasinside = lockelement.matches(':focus-within');
43
44
  active = false;
44
- yield tick();
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:button 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
+ {#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>var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
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
- return __awaiter(this, void 0, void 0, function* () {
46
- firstactive = items.findIndex(itm => !itm.disabled && !hiddenItem(itm));
47
- lastactive = items.length - [...items].reverse().findIndex(itm => !itm.disabled && !hiddenItem(itm)) - 1;
48
- if (hilited && ((_a = items[hilited]) === null || _a === void 0 ? void 0 : _a.disabled))
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
- return __awaiter(this, void 0, void 0, function* () {
55
- if (!buttonelement) {
56
- hilited = undefined;
57
- return;
58
- }
59
- yield tick();
60
- if (!menushown) {
61
- hilited = undefined;
62
- buttonelement.removeAttribute('aria-controls');
63
- buttonelement.setAttribute('aria-expanded', 'false');
64
- }
65
- else {
66
- buttonelement.setAttribute('aria-controls', menuid);
67
- buttonelement.setAttribute('aria-expanded', 'true');
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
- return __awaiter(this, void 0, void 0, function* () {
162
- // tabindex=-1 on our menu elements means e.relatedTarget will be set
163
- if (!(e.relatedTarget instanceof HTMLElement && (menuelement === null || menuelement === void 0 ? void 0 : menuelement.contains(e.relatedTarget))))
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) {
@@ -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);
@@ -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)) {
@@ -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
  }
@@ -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);
@@ -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 button(node: HTMLElement): {
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 = 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 { button } from '../actions'
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 (!returnfocusto) {
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:button 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}
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">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@txstate-mws/svelte-components",
3
- "version": "0.0.61",
3
+ "version": "0.0.65",
4
4
  "description": "Svelte components that are generically useful.",
5
5
  "main": "dist/index.js",
6
6
  "module": "esm/index.js",