@txstate-mws/svelte-components 0.0.67 → 1.0.3

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 (120) hide show
  1. package/README.md +39 -4
  2. package/{dist/ts/actions/a11y.d.ts → actions/buttonify.d.ts} +0 -0
  3. package/{dist/actions/a11y.js → actions/buttonify.js} +1 -6
  4. package/{dist/ts/actions → actions}/glue.d.ts +2 -2
  5. package/{dist/actions → actions}/glue.js +9 -16
  6. package/actions/index.d.ts +7 -0
  7. package/actions/index.js +7 -0
  8. package/actions/offset.d.ts +15 -0
  9. package/actions/offset.js +35 -0
  10. package/{dist/ts/actions → actions}/portal.d.ts +0 -0
  11. package/actions/portal.js +13 -0
  12. package/{dist/ts/actions → actions}/resize.d.ts +6 -2
  13. package/actions/resize.js +45 -0
  14. package/{dist/ts/actions → actions}/sticky.d.ts +2 -2
  15. package/{dist/actions → actions}/sticky.js +10 -18
  16. package/{dist/ts/actions → actions}/stickyfixed.d.ts +7 -7
  17. package/{dist/actions → actions}/stickyfixed.js +19 -28
  18. package/{dist/components → components}/CollapsingTable.svelte +13 -14
  19. package/components/CollapsingTable.svelte.d.ts +59 -0
  20. package/{dist/ts/components → components}/ConditionalWrapper.svelte +6 -7
  21. package/components/ConditionalWrapper.svelte.d.ts +23 -0
  22. package/{dist/components → components}/FocusLock.svelte +21 -19
  23. package/components/FocusLock.svelte.d.ts +26 -0
  24. package/components/Modal.svelte +53 -0
  25. package/components/Modal.svelte.d.ts +27 -0
  26. package/{dist/components → components}/PopupMenu.svelte +28 -30
  27. package/components/PopupMenu.svelte.d.ts +44 -0
  28. package/{dist/ts/components → components}/ScreenReaderOnly.svelte +4 -5
  29. package/components/ScreenReaderOnly.svelte.d.ts +20 -0
  30. package/{dist/ts/components → components}/index.d.ts +0 -0
  31. package/components/index.js +6 -0
  32. package/index.d.ts +4 -0
  33. package/index.js +4 -0
  34. package/package.json +47 -68
  35. package/{dist/ts/types → types}/CollapsingTable.d.ts +0 -0
  36. package/{dist/ts/tests/Actions/Actions.stories.d.ts → types/CollapsingTable.js} +0 -0
  37. package/{dist/ts/types → types}/PopupMenu.d.ts +0 -0
  38. package/{dist/ts/tests/CollapsingTable/CollapsingTable.stories.d.ts → types/PopupMenu.js} +0 -0
  39. package/types/index.d.ts +2 -0
  40. package/types/index.js +2 -0
  41. package/{dist/ts/lib → util}/bodyoffset.d.ts +2 -1
  42. package/{dist/lib → util}/bodyoffset.js +10 -14
  43. package/util/index.d.ts +3 -0
  44. package/util/index.js +3 -0
  45. package/{dist/ts/lib → util}/repositioned.d.ts +1 -2
  46. package/{dist/lib → util}/repositioned.js +14 -24
  47. package/{dist/ts/lib → util}/util.d.ts +0 -0
  48. package/util/util.js +10 -0
  49. package/LICENSE +0 -21
  50. package/dist/actions/a11y.js.map +0 -1
  51. package/dist/actions/glue.js.map +0 -1
  52. package/dist/actions/index.js +0 -20
  53. package/dist/actions/index.js.map +0 -1
  54. package/dist/actions/offset.js +0 -35
  55. package/dist/actions/offset.js.map +0 -1
  56. package/dist/actions/portal.js +0 -23
  57. package/dist/actions/portal.js.map +0 -1
  58. package/dist/actions/resize.js +0 -48
  59. package/dist/actions/resize.js.map +0 -1
  60. package/dist/actions/sticky.js.map +0 -1
  61. package/dist/actions/stickyfixed.js.map +0 -1
  62. package/dist/components/ConditionalWrapper.svelte +0 -38
  63. package/dist/components/Modal.svelte +0 -44
  64. package/dist/components/ScreenReaderOnly.svelte +0 -26
  65. package/dist/components/index.js +0 -19
  66. package/dist/components/index.js.map +0 -1
  67. package/dist/index.js +0 -17
  68. package/dist/index.js.map +0 -1
  69. package/dist/lib/bodyoffset.js.map +0 -1
  70. package/dist/lib/deepstore.js +0 -80
  71. package/dist/lib/deepstore.js.map +0 -1
  72. package/dist/lib/derivedstore.js +0 -53
  73. package/dist/lib/derivedstore.js.map +0 -1
  74. package/dist/lib/index.js +0 -20
  75. package/dist/lib/index.js.map +0 -1
  76. package/dist/lib/repositioned.js.map +0 -1
  77. package/dist/lib/safestore.js +0 -16
  78. package/dist/lib/safestore.js.map +0 -1
  79. package/dist/lib/substore.js +0 -46
  80. package/dist/lib/substore.js.map +0 -1
  81. package/dist/lib/util.js +0 -16
  82. package/dist/lib/util.js.map +0 -1
  83. package/dist/ts/actions/index.d.ts +0 -7
  84. package/dist/ts/actions/offset.d.ts +0 -15
  85. package/dist/ts/components/CollapsingTable.svelte +0 -147
  86. package/dist/ts/components/FocusLock.svelte +0 -100
  87. package/dist/ts/components/Modal.svelte +0 -45
  88. package/dist/ts/components/PopupMenu.svelte +0 -278
  89. package/dist/ts/index.d.ts +0 -4
  90. package/dist/ts/lib/deepstore.d.ts +0 -42
  91. package/dist/ts/lib/derivedstore.d.ts +0 -16
  92. package/dist/ts/lib/index.d.ts +0 -7
  93. package/dist/ts/lib/safestore.d.ts +0 -4
  94. package/dist/ts/lib/substore.d.ts +0 -23
  95. package/dist/ts/tests/Actions/Offset.svelte +0 -34
  96. package/dist/ts/tests/Actions/Resize.svelte +0 -31
  97. package/dist/ts/tests/Actions/Sticky.svelte +0 -65
  98. package/dist/ts/tests/CollapsingTable/CollapsingTable.test.d.ts +0 -1
  99. package/dist/ts/tests/CollapsingTable/CollapsingTableTest.svelte +0 -36
  100. package/dist/ts/tests/Modal/Modal.stories.d.ts +0 -1
  101. package/dist/ts/tests/Modal/Modal.test.d.ts +0 -1
  102. package/dist/ts/tests/Modal/ModalTest.svelte +0 -58
  103. package/dist/ts/tests/PopupMenu/PopupMenu.stories.d.ts +0 -1
  104. package/dist/ts/tests/PopupMenu/PopupMenu.test.d.ts +0 -1
  105. package/dist/ts/tests/PopupMenu/PopupMenuBody.svelte +0 -34
  106. package/dist/ts/tests/PopupMenu/PopupMenuButtonIsParent.svelte +0 -36
  107. package/dist/ts/tests/PopupMenu/PopupMenuComplex.svelte +0 -34
  108. package/dist/ts/tests/PopupMenu/PopupMenuSimple.svelte +0 -30
  109. package/dist/ts/tests/stores/deepstore.test.d.ts +0 -1
  110. package/dist/ts/types/index.d.ts +0 -2
  111. package/dist/types/CollapsingTable.js +0 -3
  112. package/dist/types/CollapsingTable.js.map +0 -1
  113. package/dist/types/PopupMenu.js +0 -3
  114. package/dist/types/PopupMenu.js.map +0 -1
  115. package/dist/types/index.js +0 -15
  116. package/dist/types/index.js.map +0 -1
  117. package/docs/CollapsingTable.md +0 -80
  118. package/docs/actions.md +0 -10
  119. package/esm/index.js +0 -1
  120. package/esm/package.json +0 -3
@@ -0,0 +1,59 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import type { CollapsingTableColumn } from '../types';
3
+ import DefaultPopupMenu from './PopupMenu.svelte';
4
+ declare const __propDef: {
5
+ props: {
6
+ tableClass?: string;
7
+ bodyRowClass?: string;
8
+ bodyCellClass?: string;
9
+ headerRowClass?: string;
10
+ headerCellClass?: string;
11
+ menuContainerClass?: string;
12
+ menuClass?: string;
13
+ menuItemClass?: string;
14
+ menuItemHilitedClass?: string;
15
+ items: any[];
16
+ config?: CollapsingTableColumn[] | undefined;
17
+ defaultCellWidth?: number;
18
+ PopupMenu?: typeof DefaultPopupMenu;
19
+ slots?: Record<string, boolean>;
20
+ stickyheader?: boolean;
21
+ };
22
+ events: {
23
+ [evt: string]: CustomEvent<any>;
24
+ };
25
+ slots: {
26
+ headercell: {
27
+ column: CollapsingTableColumn & {
28
+ widthPercent?: number;
29
+ };
30
+ key: string;
31
+ title: string;
32
+ item: any;
33
+ value: any;
34
+ };
35
+ dropicon: {
36
+ column: CollapsingTableColumn & {
37
+ widthPercent?: number;
38
+ };
39
+ item: any;
40
+ value: any;
41
+ };
42
+ default: {
43
+ key: string;
44
+ value: any;
45
+ item: any;
46
+ };
47
+ footer: {
48
+ item: any;
49
+ key: any;
50
+ value: any;
51
+ };
52
+ };
53
+ };
54
+ export declare type CollapsingTableProps = typeof __propDef.props;
55
+ export declare type CollapsingTableEvents = typeof __propDef.events;
56
+ export declare type CollapsingTableSlots = typeof __propDef.slots;
57
+ export default class CollapsingTable extends SvelteComponentTyped<CollapsingTableProps, CollapsingTableEvents, CollapsingTableSlots> {
58
+ }
59
+ export {};
@@ -1,10 +1,9 @@
1
- <script lang="ts">
2
- export let condition: boolean|undefined = undefined
3
- export let component: Function|undefined = undefined
4
- export let a = false
5
- export let span = false
6
- export let element: HTMLElement|undefined = undefined
7
- $: passthrough = (({ condition, component, a, span, element, ...passthrough }) => passthrough)($$props)
1
+ <script >export let condition;
2
+ export let component = undefined;
3
+ export let a = false;
4
+ export let span = false;
5
+ export let element = undefined;
6
+ $: passthrough = (({ condition, component, a, span, element, ...passthrough }) => passthrough)($$props);
8
7
  </script>
9
8
 
10
9
  {#if condition || (typeof condition === 'undefined' && component)}
@@ -0,0 +1,23 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ [x: string]: any;
5
+ condition: boolean | undefined;
6
+ component?: Function | undefined;
7
+ a?: boolean;
8
+ span?: boolean;
9
+ element?: HTMLElement | undefined;
10
+ };
11
+ events: {
12
+ [evt: string]: CustomEvent<any>;
13
+ };
14
+ slots: {
15
+ default: {};
16
+ };
17
+ };
18
+ export declare type ConditionalWrapperProps = typeof __propDef.props;
19
+ export declare type ConditionalWrapperEvents = typeof __propDef.events;
20
+ export declare type ConditionalWrapperSlots = typeof __propDef.slots;
21
+ export default class ConditionalWrapper extends SvelteComponentTyped<ConditionalWrapperProps, ConditionalWrapperEvents, ConditionalWrapperSlots> {
22
+ }
23
+ export {};
@@ -1,10 +1,10 @@
1
- <script context="module">const FocusLockStack = [];
1
+ <script context="module" >const FocusLockStack = [];
2
2
  </script>
3
3
 
4
- <script>export let returnfocusto = undefined;
4
+ <script >export let returnfocusto = undefined;
5
5
  export let initialfocus = undefined;
6
6
  export let hidefocus = true;
7
- export let hidefocuslabel = "focus is above modal dialog, start tabbing";
7
+ export let hidefocuslabel = 'focus is above modal dialog, start tabbing';
8
8
  export let escapable = true;
9
9
  let className = '';
10
10
  export { className as class };
@@ -17,6 +17,7 @@ const dispatch = createEventDispatcher();
17
17
  let lockelement;
18
18
  let abovelockelement;
19
19
  let active = true;
20
+ let listenforescape = false;
20
21
  if (initialfocus)
21
22
  hidefocus = false;
22
23
  onMount(async () => {
@@ -30,7 +31,9 @@ onMount(async () => {
30
31
  if (typeof returnfocusto === 'undefined') {
31
32
  returnfocusto = document.querySelector(':focus');
32
33
  }
33
- await sleep(1);
34
+ await sleep(1); // sapper resets focus on page load, so we'll wait a millisecond in case our modal is on screen at load
35
+ if (!lockelement)
36
+ return; // in case we already unmounted
34
37
  if (initialfocus) {
35
38
  const focusEl = lockelement.querySelector(initialfocus);
36
39
  if (focusEl instanceof HTMLElement)
@@ -39,20 +42,13 @@ onMount(async () => {
39
42
  else {
40
43
  setInitialFocus();
41
44
  }
45
+ setTimeout(() => { listenforescape = true; }, 0);
42
46
  });
43
47
  onDestroy(async () => {
44
48
  const wasactive = active;
45
- let focuswasinside;
46
- try {
47
- focuswasinside = lockelement.matches(':focus-within');
48
- }
49
- catch (e) {
50
- // browser doesn't support :focus-within
51
- focuswasinside = true;
52
- }
53
49
  active = false;
54
50
  await tick();
55
- if (returnfocusto && wasactive && focuswasinside) {
51
+ if (returnfocusto && wasactive) {
56
52
  returnfocusto.focus();
57
53
  }
58
54
  FocusLockStack.pop();
@@ -61,37 +57,43 @@ onDestroy(async () => {
61
57
  prevFocusLock.unpause();
62
58
  });
63
59
  const setInitialFocus = () => {
64
- const firstfocus = tabbable(lockelement)[0];
60
+ const firstfocus = lockelement ? tabbable(lockelement)[0] : undefined;
65
61
  if (firstfocus && firstfocus.focus) {
66
62
  firstfocus.focus();
67
63
  }
68
64
  };
69
65
  const setLastFocus = () => {
70
- const lastfocus = tabbable(lockelement).slice(-1)[0];
66
+ const lastfocus = lockelement ? tabbable(lockelement).slice(-1)[0] : undefined;
71
67
  if (lastfocus && lastfocus.focus) {
72
68
  lastfocus.focus();
73
69
  }
74
70
  };
75
71
  const keydown = (e) => {
76
- if (active && e.key === "Escape" && escapable) {
72
+ if (active && e.key === 'Escape' && escapable) {
77
73
  e.preventDefault();
78
74
  dispatch('escape');
79
75
  }
80
76
  };
81
77
  const focusin = (e) => {
82
- if (active && e.target instanceof HTMLElement && !(lockelement === null || lockelement === void 0 ? void 0 : lockelement.contains(e.target))) {
78
+ if (active && e.target instanceof HTMLElement && !lockelement?.contains(e.target)) {
83
79
  if (e.target === abovelockelement)
84
80
  setLastFocus();
85
81
  else
86
82
  setInitialFocus();
87
83
  }
88
84
  };
85
+ const windowclick = (_) => {
86
+ if (listenforescape && active) {
87
+ returnfocusto = undefined;
88
+ dispatch('escape');
89
+ }
90
+ };
89
91
  </script>
90
-
92
+ <svelte:window on:click={windowclick} />
91
93
  <div class={className} role="alertdialog" aria-modal="true" on:click|stopPropagation on:keydown|stopPropagation={keydown} on:focusin={focusin}>
92
94
  <div bind:this={abovelockelement} tabindex="0"></div>
93
95
  <div bind:this={lockelement} on:keydown={keydown}>
94
- {#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}
96
+ {#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}
95
97
  <slot></slot>
96
98
  </div>
97
99
  <div tabindex="0"></div>
@@ -0,0 +1,26 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ returnfocusto?: HTMLElement | null | undefined;
5
+ initialfocus?: string | undefined;
6
+ hidefocus?: boolean;
7
+ hidefocuslabel?: string;
8
+ escapable?: boolean;
9
+ class?: string;
10
+ };
11
+ events: {
12
+ click: MouseEvent;
13
+ escape: CustomEvent<any>;
14
+ } & {
15
+ [evt: string]: CustomEvent<any>;
16
+ };
17
+ slots: {
18
+ default: {};
19
+ };
20
+ };
21
+ export declare type FocusLockProps = typeof __propDef.props;
22
+ export declare type FocusLockEvents = typeof __propDef.events;
23
+ export declare type FocusLockSlots = typeof __propDef.slots;
24
+ export default class FocusLock extends SvelteComponentTyped<FocusLockProps, FocusLockEvents, FocusLockSlots> {
25
+ }
26
+ export {};
@@ -0,0 +1,53 @@
1
+ <script >export let escapable = true;
2
+ export let hidefocus = true;
3
+ export let hidefocuslabel = undefined;
4
+ export let returnfocusto = undefined;
5
+ export let initialfocus = undefined;
6
+ export let containerClass = '';
7
+ export let opaque = false;
8
+ export let usePortal = undefined;
9
+ import { createEventDispatcher, onMount } from 'svelte';
10
+ import FocusLock from './FocusLock.svelte';
11
+ import { portal } from '../actions';
12
+ const dispatch = createEventDispatcher();
13
+ const endmodal = () => {
14
+ dispatch('escape');
15
+ };
16
+ onMount(() => {
17
+ document.body.style.marginRight = (window.innerWidth - document.body.clientWidth) + 'px';
18
+ document.body.style.overflow = 'hidden';
19
+ return () => {
20
+ document.body.style.overflow = '';
21
+ document.body.style.marginRight = '';
22
+ };
23
+ });
24
+ </script>
25
+
26
+ <div use:portal={usePortal} class="modal-backdrop" class:opaque on:click|stopPropagation|preventDefault={() => escapable && endmodal()}>
27
+ <FocusLock class="modal-container {containerClass}" {escapable} on:escape {hidefocus} {hidefocuslabel} {returnfocusto} {initialfocus}>
28
+ <slot></slot>
29
+ </FocusLock>
30
+ </div>
31
+
32
+ <style>
33
+ .modal-backdrop {
34
+ position: fixed;
35
+ top: 0;
36
+ left: 0;
37
+ width: 100vw;
38
+ height: 100vh;
39
+ background-color: var(--modal-bg, rgba(0, 0, 0, 0.7));
40
+ z-index: 2147483000;
41
+ display: flex;
42
+ justify-content: center;
43
+ align-items: center
44
+ }
45
+ .modal-backdrop.opaque {
46
+ background-color: var(--modal-bg-opaque, #4c4c4c);
47
+ }
48
+ .modal-backdrop :global(.modal-container) {
49
+ max-width: 100vw;
50
+ max-height: 100vh;
51
+ overflow: auto;
52
+ }
53
+ </style>
@@ -0,0 +1,27 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ escapable?: boolean;
5
+ hidefocus?: boolean;
6
+ hidefocuslabel?: string | undefined;
7
+ returnfocusto?: HTMLElement | undefined;
8
+ initialfocus?: string | undefined;
9
+ containerClass?: string;
10
+ opaque?: boolean;
11
+ usePortal?: HTMLElement | undefined;
12
+ };
13
+ events: {
14
+ escape: CustomEvent<any>;
15
+ } & {
16
+ [evt: string]: CustomEvent<any>;
17
+ };
18
+ slots: {
19
+ default: {};
20
+ };
21
+ };
22
+ export declare type ModalProps = typeof __propDef.props;
23
+ export declare type ModalEvents = typeof __propDef.events;
24
+ export declare type ModalSlots = typeof __propDef.slots;
25
+ export default class Modal extends SvelteComponentTyped<ModalProps, ModalEvents, ModalSlots> {
26
+ }
27
+ export {};
@@ -1,7 +1,7 @@
1
- <script>import { glue, portal } from '../actions';
2
- import { createEventDispatcher, onDestroy, tick } from 'svelte';
1
+ <script >import { createEventDispatcher, onDestroy, tick } from 'svelte';
3
2
  import { randomid } from 'txstate-utils';
4
- import { DeepStore } from '../lib';
3
+ import { Store } from '@txstate-mws/svelte-store';
4
+ import { glue, portal } from '../actions';
5
5
  import ScreenReaderOnly from './ScreenReaderOnly.svelte';
6
6
  const dispatch = createEventDispatcher();
7
7
  export let menushown = false;
@@ -16,27 +16,26 @@ export let align = 'auto';
16
16
  export let cover = false;
17
17
  export let showSelected = true;
18
18
  export let width = undefined;
19
- export let computedalign = new DeepStore({ valign: 'bottom', halign: 'left' });
19
+ export let computedalign = new Store({ valign: 'bottom', halign: 'left' });
20
20
  export let usePortal = undefined;
21
21
  export let emptyText = undefined;
22
- export let hilited = undefined;
23
- export let selected = undefined;
22
+ export let value = undefined;
23
+ let hilited = undefined;
24
24
  let menuelement;
25
- let itemelements = [];
25
+ const itemelements = [];
26
26
  const menuid = randomid();
27
27
  let firstactive = 0;
28
28
  let lastactive = items.length - 1;
29
29
  function hiddenItem(item) {
30
- return !!item && !showSelected && item.value === (selected === null || selected === void 0 ? void 0 : selected.value);
30
+ return !!item && !showSelected && item.value === value;
31
31
  }
32
32
  async function reactToItems(..._) {
33
- var _a;
34
33
  firstactive = items.findIndex(itm => !itm.disabled && !hiddenItem(itm));
35
34
  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))
35
+ if (hilited && items[hilited]?.disabled)
37
36
  hilited = firstactive;
38
37
  }
39
- $: reactToItems(items, selected);
38
+ $: reactToItems(items, value);
40
39
  async function reactToMenuShown(_) {
41
40
  if (!buttonelement) {
42
41
  hilited = undefined;
@@ -56,22 +55,20 @@ async function reactToMenuShown(_) {
56
55
  }
57
56
  $: reactToMenuShown(menushown);
58
57
  function move(idx) {
59
- var _a;
60
58
  if (!menushown)
61
59
  return;
62
- if ((_a = items[idx]) === null || _a === void 0 ? void 0 : _a.disabled)
60
+ if (items[idx]?.disabled)
63
61
  return;
64
62
  hilited = Math.max(firstactive, Math.min(lastactive, idx));
65
63
  itemelements[hilited].scrollIntoView({ block: 'center' });
66
64
  buttonelement.setAttribute('aria-activedescendant', `${menuid}-${hilited}`);
67
65
  }
68
66
  function onkeydown(e) {
69
- var _a, _b;
70
67
  if (e.key === 'ArrowDown') {
71
68
  e.preventDefault();
72
69
  if (menushown) {
73
- let i = (hilited !== null && hilited !== void 0 ? hilited : firstactive - 1) + 1;
74
- while (((_a = items[i]) === null || _a === void 0 ? void 0 : _a.disabled) || hiddenItem(items[i]))
70
+ let i = (hilited ?? firstactive - 1) + 1;
71
+ while (items[i]?.disabled || hiddenItem(items[i]))
75
72
  i++;
76
73
  move(i);
77
74
  }
@@ -83,8 +80,8 @@ function onkeydown(e) {
83
80
  else if (e.key === 'ArrowUp') {
84
81
  e.preventDefault();
85
82
  if (menushown) {
86
- let i = (hilited !== null && hilited !== void 0 ? hilited : lastactive + 1) - 1;
87
- while (((_b = items[i]) === null || _b === void 0 ? void 0 : _b.disabled) || hiddenItem(items[i]))
83
+ let i = (hilited ?? lastactive + 1) - 1;
84
+ while (items[i]?.disabled || hiddenItem(items[i]))
88
85
  i--;
89
86
  move(i);
90
87
  }
@@ -98,8 +95,8 @@ function onkeydown(e) {
98
95
  if (menushown) {
99
96
  menushown = false;
100
97
  if (typeof hilited !== 'undefined') {
101
- selected = items[hilited];
102
- dispatch('change', items[hilited].value);
98
+ value = items[hilited]?.value;
99
+ dispatch('change', items[hilited]);
103
100
  }
104
101
  }
105
102
  else {
@@ -114,8 +111,8 @@ function onkeydown(e) {
114
111
  if (typeof hilited !== 'undefined') {
115
112
  e.preventDefault();
116
113
  menushown = false;
117
- selected = items[hilited];
118
- dispatch('change', items[hilited].value);
114
+ value = items[hilited]?.value;
115
+ dispatch('change', items[hilited]);
119
116
  }
120
117
  else {
121
118
  if (buttonelement.tagName !== 'INPUT') {
@@ -144,7 +141,7 @@ function onbuttonclick(e) {
144
141
  }
145
142
  async function onblur(e) {
146
143
  // 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))))
144
+ if (!(e.relatedTarget instanceof HTMLElement && menuelement?.contains(e.relatedTarget)))
148
145
  menushown = false;
149
146
  }
150
147
  function cleanup(element) {
@@ -152,6 +149,7 @@ function cleanup(element) {
152
149
  element.removeEventListener('click', onbuttonclick);
153
150
  element.removeEventListener('keydown', onkeydown);
154
151
  element.removeEventListener('blur', onblur);
152
+ element.removeAttribute('aria-disabled');
155
153
  element.removeAttribute('aria-haspopup');
156
154
  element.removeAttribute('aria-expanded');
157
155
  element.removeAttribute('aria-controls');
@@ -178,29 +176,29 @@ const onclick = (item) => (e) => {
178
176
  if (item.disabled)
179
177
  return;
180
178
  menushown = false;
181
- selected = item;
182
- dispatch('change', item.value);
179
+ value = item.value;
180
+ dispatch('change', item);
183
181
  };
184
- $: hasSelected = showSelected && !!items.find(itm => itm.value === (selected === null || selected === void 0 ? void 0 : selected.value));
182
+ $: hasSelected = showSelected && items.some(itm => itm.value === value);
185
183
  </script>
186
184
 
187
185
  {#if menushown}
188
186
  <div use:portal={usePortal === true ? document.body : (usePortal || null)} use:glue={{ target: buttonelement, align, cover, store: computedalign }} class={menuContainerClass}>
189
187
  <ul bind:this={menuelement} id={menuid} role='listbox' style={width ? `width: ${width}` : ''} class={menuClass} class:hasSelected class:defaultmenu={!menuClass && !menuContainerClass} on:keydown={onkeydown}>
190
188
  {#each items as item, i (item.value)}
191
- {#if showSelected || !selected || item.value !== selected.value}
189
+ {#if showSelected || item.value !== value}
192
190
  <li
193
191
  id={`${menuid}-${i}`}
194
192
  bind:this={itemelements[i]}
195
- class={`${menuItemClass} ${i === hilited ? menuItemHilitedClass || '' : ''} ${selected && selected.value === item.value ? menuItemSelectedClass || '' : ''}`}
193
+ class={`${menuItemClass} ${i === hilited ? menuItemHilitedClass || '' : ''} ${value === item.value ? menuItemSelectedClass || '' : ''}`}
196
194
  class:disabled={!!item.disabled}
197
195
  class:hilited={!menuItemHilitedClass && i === hilited}
198
- class:selected={showSelected && !menuItemSelectedClass && selected && selected.value === item.value}
196
+ class:selected={showSelected && !menuItemSelectedClass && value === item.value}
199
197
  on:click={onclick(item)}
200
198
  role="option"
201
199
  tabindex=-1
202
200
  aria-disabled={item.disabled}
203
- ><slot {item} label={item.label || item.value} hilited={i === hilited} selected={selected && selected.value === item.value}>{item.label || item.value}</slot></li>
201
+ ><slot {item} label={item.label || item.value} hilited={i === hilited} selected={value === item.value}>{item.label || item.value}</slot></li>
204
202
  {/if}
205
203
  {/each}
206
204
  {#if items.length === 0}
@@ -0,0 +1,44 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import { Store } from '@txstate-mws/svelte-store';
3
+ import type { GlueAlignOpts, GlueAlignStore } from '../actions';
4
+ import type { PopupMenuItem } from '../types';
5
+ declare const __propDef: {
6
+ props: {
7
+ menushown?: boolean;
8
+ menuContainerClass?: string;
9
+ menuClass?: string;
10
+ menuItemClass?: string;
11
+ menuItemHilitedClass?: string;
12
+ menuItemSelectedClass?: string;
13
+ items?: PopupMenuItem[];
14
+ buttonelement: HTMLElement;
15
+ align?: GlueAlignOpts;
16
+ cover?: boolean;
17
+ showSelected?: boolean;
18
+ width?: string | undefined;
19
+ computedalign?: Store<GlueAlignStore>;
20
+ usePortal?: HTMLElement | true | undefined;
21
+ emptyText?: string | undefined;
22
+ value?: string | undefined;
23
+ };
24
+ events: {
25
+ change: CustomEvent<any>;
26
+ } & {
27
+ [evt: string]: CustomEvent<any>;
28
+ };
29
+ slots: {
30
+ default: {
31
+ item: PopupMenuItem;
32
+ label: string;
33
+ hilited: boolean;
34
+ selected: boolean;
35
+ };
36
+ noresults: {};
37
+ };
38
+ };
39
+ export declare type PopupMenuProps = typeof __propDef.props;
40
+ export declare type PopupMenuEvents = typeof __propDef.events;
41
+ export declare type PopupMenuSlots = typeof __propDef.slots;
42
+ export default class PopupMenu extends SvelteComponentTyped<PopupMenuProps, PopupMenuEvents, PopupMenuSlots> {
43
+ }
44
+ export {};
@@ -1,7 +1,6 @@
1
- <script>
2
- export let id = ''
3
- export let arialive = ''
4
- export let ariaatomic = ''
1
+ <script >export let id = undefined;
2
+ export let arialive = undefined;
3
+ export let ariaatomic = undefined;
5
4
  </script>
6
5
 
7
6
  <style>
@@ -23,4 +22,4 @@
23
22
  }
24
23
  </style>
25
24
 
26
- <span id={id} class="sr-only" aria-live={arialive} aria-atomic={ariaatomic}><slot/></span>
25
+ <span {id} class="sr-only" aria-live={arialive} aria-atomic={ariaatomic}><slot/></span>
@@ -0,0 +1,20 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ id?: string | undefined;
5
+ arialive?: 'off' | 'assertive' | 'polite' | undefined;
6
+ ariaatomic?: boolean | 'false' | 'true' | undefined;
7
+ };
8
+ events: {
9
+ [evt: string]: CustomEvent<any>;
10
+ };
11
+ slots: {
12
+ default: {};
13
+ };
14
+ };
15
+ export declare type ScreenReaderOnlyProps = typeof __propDef.props;
16
+ export declare type ScreenReaderOnlyEvents = typeof __propDef.events;
17
+ export declare type ScreenReaderOnlySlots = typeof __propDef.slots;
18
+ export default class ScreenReaderOnly extends SvelteComponentTyped<ScreenReaderOnlyProps, ScreenReaderOnlyEvents, ScreenReaderOnlySlots> {
19
+ }
20
+ export {};
File without changes
@@ -0,0 +1,6 @@
1
+ export { default as CollapsingTable } from './CollapsingTable.svelte';
2
+ export { default as FocusLock } from './FocusLock.svelte';
3
+ export { default as ConditionalWrapper } from './ConditionalWrapper.svelte';
4
+ export { default as Modal } from './Modal.svelte';
5
+ export { default as PopupMenu } from './PopupMenu.svelte';
6
+ export { default as ScreenReaderOnly } from './ScreenReaderOnly.svelte';
package/index.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from './components/index.js';
2
+ export * from './actions/index.js';
3
+ export * from './types/index.js';
4
+ export * from './util/index.js';
package/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from './components/index.js';
2
+ export * from './actions/index.js';
3
+ export * from './types/index.js';
4
+ export * from './util/index.js';