@dosgato/dialog 0.0.3 → 0.0.6

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 (47) hide show
  1. package/ButtonGroup.svelte +1 -1
  2. package/Checkbox.svelte +1 -1
  3. package/Container.svelte +1 -1
  4. package/FieldCheckbox.svelte +1 -1
  5. package/FieldChoices.svelte +1 -1
  6. package/FieldChooserLink.svelte +2 -2
  7. package/FieldDate.svelte +1 -1
  8. package/FieldDateTime.svelte +1 -1
  9. package/FieldDualListbox.svelte +118 -0
  10. package/FieldDualListbox.svelte.d.ts +26 -0
  11. package/FieldMultiple.svelte +1 -1
  12. package/FieldMultiple.svelte.d.ts +2 -2
  13. package/FieldMultiselect.svelte +1 -1
  14. package/FieldNumber.svelte +1 -1
  15. package/FieldRadio.svelte +1 -1
  16. package/FieldSelect.svelte +1 -1
  17. package/FieldStandard.svelte +1 -1
  18. package/FieldStandard.svelte.d.ts +1 -1
  19. package/FieldText.svelte +1 -1
  20. package/FileIcon.svelte +2 -2
  21. package/Form.svelte +3 -31
  22. package/Form.svelte.d.ts +11 -5
  23. package/Icon.svelte +1 -1
  24. package/InlineMessage.svelte +1 -1
  25. package/InlineMessages.svelte +1 -1
  26. package/Input.svelte +1 -1
  27. package/Listbox.svelte +166 -0
  28. package/Listbox.svelte.d.ts +28 -0
  29. package/Radio.svelte +1 -1
  30. package/Tab.svelte +1 -1
  31. package/TabStore.js +1 -0
  32. package/Tabs.svelte +1 -1
  33. package/chooser/Asset.svelte +13 -8
  34. package/chooser/AssetFolder.svelte +9 -7
  35. package/chooser/Chooser.svelte +5 -3
  36. package/chooser/Chooser.svelte.d.ts +18 -16
  37. package/chooser/ChooserAPI.d.ts +4 -3
  38. package/chooser/ChooserStore.d.ts +7 -6
  39. package/chooser/ChooserStore.js +7 -5
  40. package/chooser/Details.svelte +1 -1
  41. package/chooser/Page.svelte +9 -7
  42. package/chooser/Thumbnail.svelte +1 -1
  43. package/chooser/index.d.ts +0 -3
  44. package/chooser/index.js +0 -3
  45. package/index.d.ts +2 -0
  46. package/index.js +2 -0
  47. package/package.json +8 -6
@@ -1,4 +1,4 @@
1
- <script >import { modifierKey } from '@txstate-mws/svelte-components';
1
+ <script>import { modifierKey } from '@txstate-mws/svelte-components';
2
2
  import { createEventDispatcher } from 'svelte';
3
3
  export let name = undefined;
4
4
  export let choices;
package/Checkbox.svelte CHANGED
@@ -1,4 +1,4 @@
1
- <script >import { isNotBlank } from 'txstate-utils';
1
+ <script>import { isNotBlank } from 'txstate-utils';
2
2
  export let id = undefined;
3
3
  export let name;
4
4
  export let value;
package/Container.svelte CHANGED
@@ -1,4 +1,4 @@
1
- <script >import { eq } from '@txstate-mws/svelte-components';
1
+ <script>import { eq } from '@txstate-mws/svelte-components';
2
2
  import InlineMessages from './InlineMessages.svelte';
3
3
  export let id = undefined;
4
4
  export let descid = undefined;
@@ -1,4 +1,4 @@
1
- <script >import { randomid } from 'txstate-utils';
1
+ <script>import { randomid } from 'txstate-utils';
2
2
  import FieldStandard from './FieldStandard.svelte';
3
3
  import Checkbox from './Checkbox.svelte';
4
4
  let className = '';
@@ -1,4 +1,4 @@
1
- <script >import { getContext } from 'svelte';
1
+ <script>import { getContext } from 'svelte';
2
2
  import { Field, FORM_CONTEXT } from '@txstate-mws/svelte-forms';
3
3
  import { derivedStore } from '@txstate-mws/svelte-store';
4
4
  import { randomid } from 'txstate-utils';
@@ -1,6 +1,6 @@
1
- <script context="module">export {};
1
+ <script context="module">export {};
2
2
  </script>
3
- <script >import { FORM_CONTEXT } from '@txstate-mws/svelte-forms';
3
+ <script>import { FORM_CONTEXT } from '@txstate-mws/svelte-forms';
4
4
  import { getContext } from 'svelte';
5
5
  import { randomid } from 'txstate-utils';
6
6
  import { Chooser, ChooserStore, CHOOSER_API_CONTEXT } from './chooser';
package/FieldDate.svelte CHANGED
@@ -1,4 +1,4 @@
1
- <script >import { dateSerialize, dateDeserialize } from '@txstate-mws/svelte-forms';
1
+ <script>import { dateSerialize, dateDeserialize } from '@txstate-mws/svelte-forms';
2
2
  import FieldStandard from './FieldStandard.svelte';
3
3
  import Input from './Input.svelte';
4
4
  let className = '';
@@ -1,4 +1,4 @@
1
- <script >import { datetimeSerialize, datetimeDeserialize } from '@txstate-mws/svelte-forms';
1
+ <script>import { datetimeSerialize, datetimeDeserialize } from '@txstate-mws/svelte-forms';
2
2
  import FieldStandard from './FieldStandard.svelte';
3
3
  import Input from './Input.svelte';
4
4
  let className = '';
@@ -0,0 +1,118 @@
1
+ <script>import menuRight from '@iconify-icons/mdi/menu-right.js';
2
+ import menuLeft from '@iconify-icons/mdi/menu-left.js';
3
+ import FieldStandard from './FieldStandard.svelte';
4
+ import { ScreenReaderOnly, modifierKey } from '@txstate-mws/svelte-components';
5
+ import Icon from './Icon.svelte';
6
+ import Listbox from './Listbox.svelte';
7
+ import { randomid } from 'txstate-utils';
8
+ export let id = undefined;
9
+ export let path;
10
+ export let label = '';
11
+ export let sourceLabel = 'Available';
12
+ export let selectedLabel = 'Selected';
13
+ export let multiselect = false;
14
+ export let choices;
15
+ export let defaultValue = [];
16
+ export let conditional = undefined;
17
+ export let required = false;
18
+ let itemsToAdd = []; //the items selected in the left listbox
19
+ let itemsToRemove = []; //the items selected in the right listbox
20
+ let instructions = 'test';
21
+ $: {
22
+ if (itemsToAdd.length === 1)
23
+ instructions = `Press right arrow key to move selected ${sourceLabel} items to ${selectedLabel} items list.`;
24
+ else
25
+ instructions = '';
26
+ }
27
+ $: {
28
+ if (itemsToRemove.length === 1)
29
+ instructions = `Press left arrow key to move selected ${selectedLabel} items to ${sourceLabel} list.`;
30
+ else
31
+ instructions = '';
32
+ }
33
+ const descid = randomid();
34
+ function addToSelected(value, setVal) {
35
+ return () => {
36
+ const selected = value.concat(itemsToAdd.map(item => item.value));
37
+ itemsToAdd = [];
38
+ setVal(selected);
39
+ };
40
+ }
41
+ function addToAvailable(value, setVal) {
42
+ return () => {
43
+ const itemsToRemoveSet = new Set(itemsToRemove.map(i => i.value));
44
+ const selected = value.filter(v => !itemsToRemoveSet.has(v));
45
+ itemsToRemove = [];
46
+ setVal(selected);
47
+ };
48
+ }
49
+ let valueToLabel = {};
50
+ for (const choice of choices) {
51
+ valueToLabel[choice.value] = choice.label || choice.value;
52
+ }
53
+ function valueToSelectedChoices(value) {
54
+ // keep the selected options ordered as they were in the available options
55
+ const valueSet = new Set(value);
56
+ const ret = [];
57
+ for (const choice of choices) {
58
+ if (valueSet.has(choice.value))
59
+ ret.push({ value: choice.value, label: choice.label || choice.value });
60
+ }
61
+ return ret;
62
+ }
63
+ function getAvailable(value) {
64
+ return choices.filter(choice => value.indexOf(choice.value) === -1);
65
+ }
66
+ function onkeydown(value, setVal) {
67
+ return (e) => {
68
+ if (modifierKey(e))
69
+ return;
70
+ if (e.key === 'ArrowRight') {
71
+ e.preventDefault();
72
+ if (itemsToAdd.length === 0)
73
+ return;
74
+ addToSelected(value, setVal)();
75
+ }
76
+ else if (e.key === 'ArrowLeft') {
77
+ e.preventDefault();
78
+ if (itemsToRemove.length === 0)
79
+ return;
80
+ addToAvailable(value, setVal)();
81
+ }
82
+ };
83
+ }
84
+ </script>
85
+
86
+ <FieldStandard bind:id {label} {path} {required} {defaultValue} {conditional} {descid} let:value let:valid let:invalid let:id let:onBlur let:setVal>
87
+ <div {id} role="group" class="dual-list-container" on:keydown={onkeydown(value, setVal)}>
88
+ <ScreenReaderOnly>
89
+ <span aria-live="polite">{instructions}</span>
90
+ </ScreenReaderOnly>
91
+ <Listbox label={sourceLabel} multiselect={multiselect} items={getAvailable(value)} {descid} {valid} {invalid} on:change={e => itemsToAdd = e.detail} selected={itemsToAdd} on:blur={onBlur}/>
92
+ <div class="toolbar">
93
+ <button type="button" class="toolbar-button" title="Move selection to {selectedLabel}" disabled={itemsToAdd.length === 0} on:click={addToSelected(value, setVal)}>
94
+ <Icon icon={menuRight} width='3em'/>
95
+ </button>
96
+ <button type="button" class="toolbar-button" title="Remove selection from {selectedLabel}" disabled={itemsToRemove.length === 0} on:click={addToAvailable(value, setVal)}>
97
+ <Icon icon={menuLeft} width='3em'/>
98
+ </button>
99
+ </div>
100
+ <Listbox label={selectedLabel} multiselect={multiselect} items={valueToSelectedChoices(value)} {descid} {valid} {invalid} on:change={e => itemsToRemove = e.detail} selected={itemsToRemove} on:blur={onBlur}/>
101
+ </div>
102
+ </FieldStandard>
103
+
104
+ <style>
105
+ .dual-list-container {
106
+ display: flex;
107
+ }
108
+ .toolbar {
109
+ display: flex;
110
+ flex-direction: column;
111
+ justify-content: center;
112
+ }
113
+ .toolbar .toolbar-button {
114
+ background-color: transparent;
115
+ border: 0;
116
+ padding: 0;
117
+ }
118
+ </style>
@@ -0,0 +1,26 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import { type PopupMenuItem } from '@txstate-mws/svelte-components';
3
+ declare const __propDef: {
4
+ props: {
5
+ id?: string | undefined;
6
+ path: string;
7
+ label?: string;
8
+ sourceLabel?: string;
9
+ selectedLabel?: string;
10
+ multiselect?: boolean;
11
+ choices: PopupMenuItem[];
12
+ defaultValue?: string[];
13
+ conditional?: boolean | undefined;
14
+ required?: boolean;
15
+ };
16
+ events: {
17
+ [evt: string]: CustomEvent<any>;
18
+ };
19
+ slots: {};
20
+ };
21
+ export declare type FieldDualListboxProps = typeof __propDef.props;
22
+ export declare type FieldDualListboxEvents = typeof __propDef.events;
23
+ export declare type FieldDualListboxSlots = typeof __propDef.slots;
24
+ export default class FieldDualListbox extends SvelteComponentTyped<FieldDualListboxProps, FieldDualListboxEvents, FieldDualListboxSlots> {
25
+ }
26
+ export {};
@@ -1,4 +1,4 @@
1
- <script >import { AddMore, FORM_CONTEXT, FORM_INHERITED_PATH } from '@txstate-mws/svelte-forms';
1
+ <script>import { AddMore, FORM_CONTEXT, FORM_INHERITED_PATH } from '@txstate-mws/svelte-forms';
2
2
  import { derivedStore } from '@txstate-mws/svelte-store';
3
3
  import { getContext } from 'svelte';
4
4
  import { isNotNull } from 'txstate-utils';
@@ -17,8 +17,8 @@ declare const __propDef: {
17
17
  slots: {
18
18
  default: {
19
19
  path: string;
20
- index: any;
21
- value: any;
20
+ index: number;
21
+ value: unknown;
22
22
  maxed: boolean;
23
23
  maxLength: number;
24
24
  currentLength: number;
@@ -1,4 +1,4 @@
1
- <script >import { MultiSelect } from '@txstate-mws/svelte-components';
1
+ <script>import { MultiSelect } from '@txstate-mws/svelte-components';
2
2
  import FieldStandard from './FieldStandard.svelte';
3
3
  export let id = undefined;
4
4
  export let path;
@@ -1,4 +1,4 @@
1
- <script >import FieldStandard from './FieldStandard.svelte';
1
+ <script>import FieldStandard from './FieldStandard.svelte';
2
2
  import Input from './Input.svelte';
3
3
  import { numberDeserialize, numberNullableDeserialize, numberSerialize } from '@txstate-mws/svelte-forms';
4
4
  let className = '';
package/FieldRadio.svelte CHANGED
@@ -1,4 +1,4 @@
1
- <script >import { nullableSerialize, nullableDeserialize } from '@txstate-mws/svelte-forms';
1
+ <script>import { nullableSerialize, nullableDeserialize } from '@txstate-mws/svelte-forms';
2
2
  import { randomid } from 'txstate-utils';
3
3
  import FieldStandard from './FieldStandard.svelte';
4
4
  import Radio from './Radio.svelte';
@@ -1,4 +1,4 @@
1
- <script >import { nullableSerialize, nullableDeserialize } from '@txstate-mws/svelte-forms';
1
+ <script>import { nullableSerialize, nullableDeserialize } from '@txstate-mws/svelte-forms';
2
2
  import FieldStandard from './FieldStandard.svelte';
3
3
  let className = '';
4
4
  export { className as class };
@@ -1,4 +1,4 @@
1
- <script >import { Field } from '@txstate-mws/svelte-forms';
1
+ <script>import { Field } from '@txstate-mws/svelte-forms';
2
2
  import { randomid } from 'txstate-utils';
3
3
  import Container from './Container.svelte';
4
4
  export let id = randomid();
@@ -21,7 +21,7 @@ declare const __propDef: {
21
21
  value: any;
22
22
  onBlur: () => void;
23
23
  onChange: (e?: any) => void;
24
- setVal: (val: any) => void;
24
+ setVal: (val: string | number | boolean | object | Date) => void;
25
25
  valid: boolean;
26
26
  invalid: boolean;
27
27
  messagesid: any;
package/FieldText.svelte CHANGED
@@ -1,4 +1,4 @@
1
- <script >import { nullableSerialize, nullableDeserialize } from '@txstate-mws/svelte-forms';
1
+ <script>import { nullableSerialize, nullableDeserialize } from '@txstate-mws/svelte-forms';
2
2
  import FieldStandard from './FieldStandard.svelte';
3
3
  import Input from './Input.svelte';
4
4
  let className = '';
package/FileIcon.svelte CHANGED
@@ -1,4 +1,4 @@
1
- <script context="module">import archiveOutline from '@iconify-icons/mdi/archive-outline.js';
1
+ <script context="module">import archiveOutline from '@iconify-icons/mdi/archive-outline.js';
2
2
  import fileCodeOutline from '@iconify-icons/mdi/file-code-outline.js';
3
3
  import fileDocumentOutline from '@iconify-icons/mdi/file-document-outline.js';
4
4
  import fileMusicOutline from '@iconify-icons/mdi/file-music-outline.js';
@@ -43,7 +43,7 @@ const prefixes = {
43
43
  audio: fileMusicOutline
44
44
  };
45
45
  </script>
46
- <script >import Icon from './Icon.svelte';
46
+ <script>import Icon from './Icon.svelte';
47
47
  export let mime;
48
48
  export let hiddenLabel = undefined;
49
49
  export let inline = false;
package/Form.svelte CHANGED
@@ -1,31 +1,20 @@
1
- <script >import { Form, FormStore } from '@txstate-mws/svelte-forms';
2
- import { createEventDispatcher, setContext } from 'svelte';
1
+ <script>import { Form, FormStore } from '@txstate-mws/svelte-forms';
2
+ import { setContext } from 'svelte';
3
3
  import { CHOOSER_API_CONTEXT } from './chooser';
4
4
  let className = '';
5
5
  export { className as class };
6
6
  export let submit = undefined;
7
7
  export let validate = undefined;
8
- export let success = undefined;
9
8
  export let store = undefined;
10
9
  export let chooserClient = undefined;
11
10
  export let autocomplete = undefined;
12
11
  export let name = undefined;
13
12
  export let preload = undefined;
14
13
  setContext(CHOOSER_API_CONTEXT, chooserClient);
15
- const dispatch = createEventDispatcher();
16
- function onCancel() {
17
- dispatch('close');
18
- }
19
14
  </script>
20
15
 
21
- <Form bind:store class="{className} dialog-form" {submit} {validate} {success} {autocomplete} {name} {preload} let:messages let:saved let:valid let:invalid let:validating let:submitting>
16
+ <Form bind:store class="{className} dialog-form" {submit} {validate} on:saved {autocomplete} {name} {preload} let:messages let:saved let:valid let:invalid let:validating let:submitting>
22
17
  <slot {messages} {saved} {validating} {submitting} {valid} {invalid} />
23
- <div class="dialog-buttons">
24
- <slot name="buttons" {onCancel}>
25
- <button type="button" on:click={onCancel}>Cancel</button>
26
- <button>Save</button>
27
- </slot>
28
- </div>
29
18
  </Form>
30
19
 
31
20
  <style>
@@ -35,21 +24,4 @@ function onCancel() {
35
24
  :global(.dialog-form) {
36
25
  padding: 0;
37
26
  }
38
- :global(.dialog-form fieldset) {
39
- border: 1px solid #666666;
40
- border-width: 1px 0;
41
- padding: 1em 0;
42
- margin: 2em 0;
43
- }
44
- .dialog-buttons {
45
- display: flex;
46
- justify-content: flex-end;
47
- }
48
- .dialog-buttons > * {
49
- margin-left: 1em;
50
- }
51
- .dialog-buttons :global(button) {
52
- padding: 0.4em 0.8em;
53
- min-width: 8em;
54
- }
55
27
  </style>
package/Form.svelte.d.ts CHANGED
@@ -1,8 +1,14 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
- declare const __propDef: any;
3
- export declare type FormProps = typeof __propDef.props;
4
- export declare type FormEvents = typeof __propDef.events;
5
- export declare type FormSlots = typeof __propDef.slots;
6
- export default class Form extends SvelteComponentTyped<FormProps, FormEvents, FormSlots> {
2
+ declare class __sveltets_Render<T, F> {
3
+ props(): any;
4
+ events(): {
5
+ [evt: string]: CustomEvent<any>;
6
+ };
7
+ slots(): any;
8
+ }
9
+ export declare type FormProps<T, F> = ReturnType<__sveltets_Render<T, F>['props']>;
10
+ export declare type FormEvents<T, F> = ReturnType<__sveltets_Render<T, F>['events']>;
11
+ export declare type FormSlots<T, F> = ReturnType<__sveltets_Render<T, F>['slots']>;
12
+ export default class Form<T, F> extends SvelteComponentTyped<FormProps<T, F>, FormEvents<T, F>, FormSlots<T, F>> {
7
13
  }
8
14
  export {};
package/Icon.svelte CHANGED
@@ -1,4 +1,4 @@
1
- <script >import Icon from '@iconify/svelte/dist/OfflineIcon.svelte';
1
+ <script>import Icon from '@iconify/svelte/dist/OfflineIcon.svelte';
2
2
  import { ScreenReaderOnly } from '@txstate-mws/svelte-components';
3
3
  export let icon;
4
4
  export let hiddenLabel = undefined;
@@ -1,4 +1,4 @@
1
- <script >import alertCircleOutline from '@iconify-icons/mdi/alert-circle-outline.js';
1
+ <script>import alertCircleOutline from '@iconify-icons/mdi/alert-circle-outline.js';
2
2
  import checkCircleOutline from '@iconify-icons/mdi/check-circle-outline.js';
3
3
  import informationOutline from '@iconify-icons/mdi/information-outline.js';
4
4
  import closeOctagonOutline from '@iconify-icons/mdi/close-octagon-outline.js';
@@ -1,4 +1,4 @@
1
- <script >import { randomid } from 'txstate-utils';
1
+ <script>import { randomid } from 'txstate-utils';
2
2
  import InlineMessage from './InlineMessage.svelte';
3
3
  export let id = randomid();
4
4
  export let messages;
package/Input.svelte CHANGED
@@ -1,4 +1,4 @@
1
- <script >import { dateSerialize, datetimeSerialize } from '@txstate-mws/svelte-forms';
1
+ <script>import { dateSerialize, datetimeSerialize } from '@txstate-mws/svelte-forms';
2
2
  let className = '';
3
3
  export { className as class };
4
4
  export let name;
package/Listbox.svelte ADDED
@@ -0,0 +1,166 @@
1
+ <script>import { createEventDispatcher } from 'svelte';
2
+ import { modifierKey } from '@txstate-mws/svelte-components';
3
+ import check from '@iconify-icons/mdi/check.js';
4
+ import Icon from './Icon.svelte';
5
+ const dispatch = createEventDispatcher();
6
+ export let items = [];
7
+ export let label;
8
+ export let multiselect = false;
9
+ export let selected = [];
10
+ export let descid = undefined;
11
+ export let valid = false;
12
+ export let invalid = false;
13
+ import { randomid } from 'txstate-utils';
14
+ const listId = randomid();
15
+ const labelId = randomid();
16
+ let listboxElement;
17
+ let hilited = undefined;
18
+ let firstactive = 0;
19
+ let lastactive = items.length - 1;
20
+ const itemelements = [];
21
+ $: selectedSet = new Set(selected.map(s => s.value));
22
+ async function reactToItems(..._) {
23
+ firstactive = items.findIndex(itm => !itm.disabled);
24
+ lastactive = items.length - [...items].reverse().findIndex(itm => !itm.disabled) - 1;
25
+ hilited = undefined;
26
+ if (listboxElement)
27
+ listboxElement.setAttribute('aria-activedescendant', null);
28
+ }
29
+ $: reactToItems(items);
30
+ const selectItem = (item, index) => (e) => {
31
+ e.stopPropagation();
32
+ e.preventDefault();
33
+ if (item.disabled)
34
+ return;
35
+ listboxElement.setAttribute('aria-activedescendant', `${listId}-${index}`);
36
+ hilited = index;
37
+ if (multiselect) {
38
+ if (selectedSet.has(item.value)) {
39
+ // remove it from selected
40
+ selected = selected.filter(s => s.value !== item.value);
41
+ }
42
+ else {
43
+ selected = [...selected, item];
44
+ }
45
+ }
46
+ else {
47
+ selected = [item];
48
+ }
49
+ dispatch('change', selected);
50
+ };
51
+ function move(idx) {
52
+ if (items[idx]?.disabled)
53
+ return;
54
+ hilited = Math.max(firstactive, Math.min(lastactive, idx));
55
+ itemelements[hilited].scrollIntoView({ block: 'center' });
56
+ listboxElement.setAttribute('aria-activedescendant', `${listId}-${hilited}`);
57
+ if (!multiselect) {
58
+ selected = [items[hilited]];
59
+ dispatch('change', selected);
60
+ }
61
+ }
62
+ function onkeydown(e) {
63
+ if (modifierKey(e))
64
+ return;
65
+ if (e.key === 'ArrowDown') {
66
+ e.preventDefault();
67
+ if (items.length < 1)
68
+ return;
69
+ let i = (hilited ?? firstactive - 1) + 1;
70
+ while (items[i]?.disabled)
71
+ i++;
72
+ move(i);
73
+ }
74
+ else if (e.key === 'ArrowUp') {
75
+ e.preventDefault();
76
+ if (items.length < 1)
77
+ return;
78
+ let i = (hilited ?? lastactive + 1) - 1;
79
+ while (items[i]?.disabled)
80
+ i--;
81
+ move(i);
82
+ }
83
+ else if (e.key === ' ') {
84
+ e.preventDefault();
85
+ if (items.length < 1)
86
+ return;
87
+ if (multiselect) {
88
+ if (typeof hilited !== 'undefined') {
89
+ if (selectedSet.has(items[hilited].value)) {
90
+ // remove it from selected
91
+ selected = selected.filter(s => s.value !== items[hilited].value);
92
+ }
93
+ else {
94
+ selected = [...selected, items[hilited]];
95
+ }
96
+ dispatch('change', selected);
97
+ }
98
+ }
99
+ }
100
+ }
101
+ function focusListbox() {
102
+ if (selected.length) {
103
+ for (let i = 0; i < items.length; i++) {
104
+ if (items[i].value === selected[0].value) {
105
+ hilited = i;
106
+ listboxElement.setAttribute('aria-activedescendant', `${listId}-${hilited}`);
107
+ }
108
+ }
109
+ }
110
+ else {
111
+ hilited = firstactive;
112
+ listboxElement.setAttribute('aria-activedescendant', `${listId}-${hilited}`);
113
+ if (!multiselect) {
114
+ selected = [items[hilited]];
115
+ dispatch('change', selected);
116
+ }
117
+ }
118
+ }
119
+ </script>
120
+
121
+ <div class="listbox-container" class:valid class:invalid>
122
+ <span id={labelId}>{label}</span>
123
+ <ul bind:this={listboxElement} role="listbox" id={listId} class="listbox-items" tabindex="0" aria-describedby={descid} aria-labelledby={labelId} aria-multiselectable={multiselect} on:keydown={onkeydown} on:focus={focusListbox}>
124
+ {#each items as item, i (item.value)}
125
+ <li
126
+ bind:this={itemelements[i]}
127
+ id={`${listId}-${i}`}
128
+ role="option"
129
+ class="listbox-item"
130
+ class:hilited={hilited === i}
131
+ class:disabled={!!item.disabled}
132
+ aria-selected={selectedSet.has(item.value)}
133
+ aria-disabled={item.disabled}
134
+ on:click={selectItem(item, i)}
135
+ >
136
+ <span class:invisible={!multiselect || !selectedSet.has(item.value)}><Icon icon={check} width='0.8em'/></span>
137
+ {item.label || item.value}
138
+ </li>
139
+ {/each}
140
+ </ul>
141
+ </div>
142
+
143
+ <style>
144
+ .listbox-container {
145
+ width: 25%;
146
+ }
147
+ .listbox-items {
148
+ list-style: none;
149
+ padding-left: 0;
150
+ border: 1px solid #666;
151
+ height: 40vh;
152
+ overflow-y: scroll;
153
+ }
154
+ .listbox-item {
155
+ padding: 0.2em;
156
+ }
157
+ .listbox-item span.invisible {
158
+ visibility: hidden;
159
+ }
160
+ .listbox-item.hilited {
161
+ background-color: lightcyan;
162
+ }
163
+ .listbox-item.disabled {
164
+ color: rgba(0,0,0,0.6);
165
+ }
166
+ </style>
@@ -0,0 +1,28 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import { type PopupMenuItem } from '@txstate-mws/svelte-components';
3
+ declare const __propDef: {
4
+ props: {
5
+ items?: PopupMenuItem[];
6
+ label: string;
7
+ multiselect?: boolean;
8
+ selected?: {
9
+ value: string;
10
+ label?: string;
11
+ }[];
12
+ descid?: string | undefined;
13
+ valid?: boolean;
14
+ invalid?: boolean;
15
+ };
16
+ events: {
17
+ change: CustomEvent<any>;
18
+ } & {
19
+ [evt: string]: CustomEvent<any>;
20
+ };
21
+ slots: {};
22
+ };
23
+ export declare type ListboxProps = typeof __propDef.props;
24
+ export declare type ListboxEvents = typeof __propDef.events;
25
+ export declare type ListboxSlots = typeof __propDef.slots;
26
+ export default class Listbox extends SvelteComponentTyped<ListboxProps, ListboxEvents, ListboxSlots> {
27
+ }
28
+ export {};
package/Radio.svelte CHANGED
@@ -1,4 +1,4 @@
1
- <script >export let id = undefined;
1
+ <script>export let id = undefined;
2
2
  export let name;
3
3
  export let value;
4
4
  export let selected = false;
package/Tab.svelte CHANGED
@@ -1,4 +1,4 @@
1
- <script >import { getContext } from 'svelte';
1
+ <script>import { getContext } from 'svelte';
2
2
  import Icon from './Icon.svelte';
3
3
  import { TabStore, TAB_CONTEXT } from './TabStore';
4
4
  export let title;
package/TabStore.js CHANGED
@@ -2,6 +2,7 @@ import { Store, derivedStore } from '@txstate-mws/svelte-store';
2
2
  import { findIndex, randomid } from 'txstate-utils';
3
3
  export const TAB_CONTEXT = {};
4
4
  export class TabStore extends Store {
5
+ initialTab;
5
6
  constructor(tabs, initialTab) {
6
7
  super({
7
8
  tabs,
package/Tabs.svelte CHANGED
@@ -1,4 +1,4 @@
1
- <script >import { modifierKey, resize } from '@txstate-mws/svelte-components';
1
+ <script>import { modifierKey, resize } from '@txstate-mws/svelte-components';
2
2
  import { setContext } from 'svelte';
3
3
  import { roundTo } from 'txstate-utils';
4
4
  import Icon from './Icon.svelte';
@@ -1,4 +1,4 @@
1
- <script >import { modifierKey } from '@txstate-mws/svelte-components';
1
+ <script>import { modifierKey } from '@txstate-mws/svelte-components';
2
2
  import { createEventDispatcher, getContext } from 'svelte';
3
3
  import { hashid } from 'txstate-utils';
4
4
  import { CHOOSER_STORE_CONTEXT } from './ChooserStore';
@@ -19,12 +19,7 @@ function onKeyDown(e) {
19
19
  if (modifierKey(e))
20
20
  return;
21
21
  if (['Enter', ' '].includes(e.key)) {
22
- e.preventDefault();
23
- e.stopPropagation();
24
- if ($store.preview?.id === asset.id)
25
- dispatch('choose', asset);
26
- else
27
- store.preview(asset);
22
+ onClick(e);
28
23
  }
29
24
  else if (e.key === 'ArrowDown') {
30
25
  e.preventDefault();
@@ -53,6 +48,16 @@ function onKeyDown(e) {
53
48
  }
54
49
  }
55
50
  }
51
+ function onClick(e) {
52
+ e.preventDefault();
53
+ e.stopPropagation();
54
+ // if the id was already the same as the one that was clicked, the user
55
+ // has clicked it twice, so we should choose the item and end the modal
56
+ if ($store.preview?.id === asset.id)
57
+ dispatch('choose', asset);
58
+ else
59
+ store.preview(asset);
60
+ }
56
61
  </script>
57
62
 
58
63
  <li
@@ -65,7 +70,7 @@ function onKeyDown(e) {
65
70
  class="dialog-asset-file"
66
71
  class:isPreview
67
72
  on:keydown={onKeyDown}
68
- on:click={() => store.preview(asset)}
73
+ on:click={onClick}
69
74
  >
70
75
  <FileIcon mime={asset.mime} inline /> {asset.name}
71
76
  </li>
@@ -1,4 +1,4 @@
1
- <script >import folderOutline from '@iconify-icons/mdi/folder-outline.js';
1
+ <script>import folderOutline from '@iconify-icons/mdi/folder-outline.js';
2
2
  import folderOpenOutline from '@iconify-icons/mdi/folder-open-outline.js';
3
3
  import folderSyncOutline from '@iconify-icons/mdi/folder-sync-outline.js';
4
4
  import { modifierKey } from '@txstate-mws/svelte-components';
@@ -26,10 +26,6 @@ function onKeyDown(e) {
26
26
  return;
27
27
  if (['Enter', ' '].includes(e.key)) {
28
28
  onClick(e);
29
- if ($store.preview?.id === folder.id)
30
- dispatch('choose', folder);
31
- else
32
- store.preview(folder);
33
29
  }
34
30
  else if (e.key === 'ArrowRight') {
35
31
  e.preventDefault();
@@ -77,8 +73,14 @@ function onKeyDown(e) {
77
73
  function onClick(e) {
78
74
  e.preventDefault();
79
75
  e.stopPropagation();
80
- store.preview(folder);
81
- store.toggle(folder);
76
+ // if the id was already the same as the one that was clicked, the user
77
+ // has clicked it twice, so we should choose the item and end the modal
78
+ if ($store.preview?.id === folder.id)
79
+ dispatch('choose', folder);
80
+ else {
81
+ store.preview(folder);
82
+ store.toggle(folder);
83
+ }
82
84
  }
83
85
  </script>
84
86
 
@@ -1,4 +1,4 @@
1
- <script >import fileTree from '@iconify-icons/mdi/file-tree.js';
1
+ <script>import fileTree from '@iconify-icons/mdi/file-tree.js';
2
2
  import viewGrid from '@iconify-icons/mdi/view-grid.js';
3
3
  import { Loading, Modal } from '@txstate-mws/svelte-components';
4
4
  import { derivedStore } from '@txstate-mws/svelte-store';
@@ -23,6 +23,8 @@ export let initialType = undefined;
23
23
  export let initialSource = undefined;
24
24
  export let initialPath = undefined;
25
25
  export let activeSources = undefined;
26
+ export let passthruFilters = undefined;
27
+ export let filter = undefined;
26
28
  export let store = new ChooserStore(chooserClient);
27
29
  setContext(CHOOSER_STORE_CONTEXT, store);
28
30
  $: if (!pages && !assets)
@@ -38,7 +40,7 @@ function onChoose() {
38
40
  dispatch('change', $store.preview);
39
41
  }
40
42
  onMount(async () => {
41
- await store.init({ activeTypes, activeSources, initialType, initialSource, initialPath, onlyImages: images, chooseFolder: folders });
43
+ await store.init({ activeTypes, activeSources, initialType, initialSource, initialPath, passthruFilters, filter, onlyImages: images, chooseFolder: folders });
42
44
  if ($store.focus)
43
45
  document.getElementById(hashid($store.focus))?.scrollIntoView();
44
46
  });
@@ -55,7 +57,7 @@ onMount(async () => {
55
57
  <div class="dialog-chooser-source">
56
58
  <select on:change={function () { store.changeSource(Number(this.value)) }}>
57
59
  {#each $sources as source, i}
58
- <option value={i}>{source.name}</option>
60
+ <option value={i}>{source.label || source.name}</option>
59
61
  {/each}
60
62
  </select>
61
63
  </div>
@@ -1,30 +1,32 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
- import { type ChooserType } from './ChooserAPI';
2
+ import { type AnyItem, type ChooserType } from './ChooserAPI';
3
3
  import { ChooserStore } from './ChooserStore';
4
- declare const __propDef: {
5
- props: {
6
- label?: string | undefined;
4
+ declare class __sveltets_Render<F> {
5
+ props(): {
6
+ label?: string;
7
7
  images?: boolean;
8
8
  pages?: boolean;
9
9
  assets?: boolean;
10
10
  folders?: boolean;
11
- initialType?: ChooserType | undefined;
12
- initialSource?: string | undefined;
13
- initialPath?: string | undefined;
14
- activeSources?: string[] | undefined;
15
- store?: ChooserStore;
11
+ initialType?: ChooserType;
12
+ initialSource?: string;
13
+ initialPath?: string;
14
+ activeSources?: string[];
15
+ passthruFilters?: F;
16
+ filter?: (item: AnyItem) => boolean | Promise<boolean>;
17
+ store?: ChooserStore<F>;
16
18
  };
17
- events: {
19
+ events(): {
18
20
  escape: CustomEvent<any>;
19
21
  change: CustomEvent<any>;
20
22
  } & {
21
23
  [evt: string]: CustomEvent<any>;
22
24
  };
23
- slots: {};
24
- };
25
- export declare type ChooserProps = typeof __propDef.props;
26
- export declare type ChooserEvents = typeof __propDef.events;
27
- export declare type ChooserSlots = typeof __propDef.slots;
28
- export default class Chooser extends SvelteComponentTyped<ChooserProps, ChooserEvents, ChooserSlots> {
25
+ slots(): {};
26
+ }
27
+ export declare type ChooserProps<F> = ReturnType<__sveltets_Render<F>['props']>;
28
+ export declare type ChooserEvents<F> = ReturnType<__sveltets_Render<F>['events']>;
29
+ export declare type ChooserSlots<F> = ReturnType<__sveltets_Render<F>['slots']>;
30
+ export default class Chooser<F> extends SvelteComponentTyped<ChooserProps<F>, ChooserEvents<F>, ChooserSlots<F>> {
29
31
  }
30
32
  export {};
@@ -1,10 +1,10 @@
1
1
  export declare const CHOOSER_API_CONTEXT: {};
2
2
  export declare type ChooserType = 'asset' | 'page';
3
3
  export declare type AnyItem = Asset | Folder | Page;
4
- export interface Client {
4
+ export interface Client<F = any> {
5
5
  getSources: (type: ChooserType) => Promise<Source[]>;
6
- getChildren: (source: string, path: string, filter: (assetOrFolder: AnyItem) => boolean | Promise<boolean>) => Promise<(AnyItem)[]>;
7
- find: (source: string, path: string, searchstring: string, filter: (asset: AnyItem) => boolean | Promise<boolean>) => Promise<(AnyItem)[]>;
6
+ getChildren: (source: string, path: string, filters: F) => Promise<(AnyItem)[]>;
7
+ find: (source: string, path: string, searchstring: string, filters: F) => Promise<(AnyItem)[]>;
8
8
  findById: (id: string) => Promise<AnyItem>;
9
9
  findByUrl?: (url: string) => Promise<AnyItem>;
10
10
  urlToValue?: (url: string) => string;
@@ -13,6 +13,7 @@ export interface Client {
13
13
  export interface Source {
14
14
  type: ChooserType;
15
15
  name: string;
16
+ label?: string;
16
17
  rootAcceptsUpload?: boolean;
17
18
  }
18
19
  interface Item {
@@ -32,8 +32,9 @@ export interface IAssetStore {
32
32
  focus?: string;
33
33
  focusPath?: string;
34
34
  }
35
- export interface ChooserStoreOptions {
35
+ export interface ChooserStoreOptions<F> {
36
36
  filter?: (itm: AnyItem) => boolean | Promise<boolean>;
37
+ passthruFilters?: F;
37
38
  activeTypes?: ChooserType[];
38
39
  activeSources?: string[];
39
40
  initialType?: ChooserType;
@@ -42,20 +43,20 @@ export interface ChooserStoreOptions {
42
43
  chooseFolder?: boolean;
43
44
  onlyImages?: boolean;
44
45
  }
45
- interface InternalStoreOptions extends Omit<ChooserStoreOptions, 'activeSources'> {
46
+ interface InternalStoreOptions<F> extends Omit<ChooserStoreOptions<F>, 'activeSources'> {
46
47
  activeSources?: Set<string>;
47
48
  }
48
49
  export declare const CHOOSER_STORE_CONTEXT: {};
49
50
  export declare function combinePath(path: string, name: string): string;
50
51
  export declare function bytesToHuman(bytes: number): string;
51
- export declare class ChooserStore extends SafeStore<IAssetStore> {
52
+ export declare class ChooserStore<F = any> extends SafeStore<IAssetStore> {
52
53
  client: Client;
53
- options: InternalStoreOptions;
54
+ options: InternalStoreOptions<F>;
54
55
  constructor(client: Client);
55
- setOptions(options: ChooserStoreOptions): void;
56
+ setOptions(options: ChooserStoreOptions<F>): void;
56
57
  getSource(state?: IAssetStore): UISource;
57
58
  getSourceIndex(name: string, state?: IAssetStore, type?: ChooserType): number;
58
- init(options: ChooserStoreOptions): Promise<void>;
59
+ init(options: ChooserStoreOptions<F>): Promise<void>;
59
60
  itemByPath(state: IAssetStore, path: string): AnyUIItem;
60
61
  open(folder: UIFolder | UIPage): Promise<void>;
61
62
  openPath(path: string): Promise<void>;
@@ -1,5 +1,5 @@
1
1
  import { SafeStore } from '@txstate-mws/svelte-store';
2
- import { findIndex, isNotBlank } from 'txstate-utils';
2
+ import { filterAsync, findIndex, isNotBlank } from 'txstate-utils';
3
3
  export const CHOOSER_STORE_CONTEXT = {};
4
4
  const nofilter = (x) => true;
5
5
  export function combinePath(path, name) {
@@ -13,6 +13,8 @@ export function bytesToHuman(bytes) {
13
13
  return String(parseFloat((bytes / Math.pow(1024, scale)).toPrecision(3))) + scales[scale];
14
14
  }
15
15
  export class ChooserStore extends SafeStore {
16
+ client;
17
+ options;
16
18
  constructor(client) {
17
19
  super({ activetype: 'page', activesource: 0 });
18
20
  this.client = client;
@@ -88,7 +90,7 @@ export class ChooserStore extends SafeStore {
88
90
  return v;
89
91
  });
90
92
  try {
91
- const children = await this.client.getChildren(this.getSource().name, path, this.options.filter);
93
+ const children = await filterAsync(await this.client.getChildren(this.getSource().name, path, this.options.passthruFilters), this.options.filter);
92
94
  this.update(v => {
93
95
  const folder = this.itemByPath(v, path);
94
96
  folder.open = true;
@@ -110,13 +112,13 @@ export class ChooserStore extends SafeStore {
110
112
  const parts = path.substring(1).split('/');
111
113
  const source = this.getSource(this.clone(this.value));
112
114
  if (!source.children)
113
- source.children = await this.client.getChildren(source.name, '/', this.options.filter);
115
+ source.children = await filterAsync(await this.client.getChildren(source.name, '/', this.options.passthruFilters), this.options.filter);
114
116
  let current = source.children.find(c => c.name === parts[0]) ?? source.children[0];
115
117
  for (const part of parts.slice(1).filter(isNotBlank)) {
116
118
  if (!current || current.type === 'asset')
117
119
  break;
118
120
  if (!current.open) {
119
- current.children = await this.client.getChildren(source.name, combinePath(current.path, current.name), this.options.filter);
121
+ current.children = await filterAsync(await this.client.getChildren(source.name, combinePath(current.path, current.name), this.options.passthruFilters), this.options.filter);
120
122
  current.loading = false;
121
123
  current.open = true;
122
124
  }
@@ -175,7 +177,7 @@ export class ChooserStore extends SafeStore {
175
177
  return v;
176
178
  });
177
179
  const source = this.getSource();
178
- const children = await this.client.getChildren(source.name, '/', this.options.filter);
180
+ const children = await filterAsync(await this.client.getChildren(source.name, '/', this.options.passthruFilters), this.options.filter);
179
181
  this.update(v => {
180
182
  const source = this.getSource(v);
181
183
  source.children = children;
@@ -1,4 +1,4 @@
1
- <script >import { bytesToHuman, combinePath } from './ChooserStore';
1
+ <script>import { bytesToHuman, combinePath } from './ChooserStore';
2
2
  export let item;
3
3
  </script>
4
4
 
@@ -1,4 +1,4 @@
1
- <script >import fileOutline from '@iconify-icons/mdi/file-outline.js';
1
+ <script>import fileOutline from '@iconify-icons/mdi/file-outline.js';
2
2
  import fileSyncOutline from '@iconify-icons/mdi/file-sync-outline.js';
3
3
  import { modifierKey } from '@txstate-mws/svelte-components';
4
4
  import { createEventDispatcher, getContext } from 'svelte';
@@ -24,10 +24,6 @@ function onKeyDown(e) {
24
24
  return;
25
25
  if (['Enter', ' '].includes(e.key)) {
26
26
  onClick(e);
27
- if ($store.preview?.id === page.id)
28
- dispatch('choose', page);
29
- else
30
- store.preview(page);
31
27
  }
32
28
  else if (e.key === 'ArrowRight') {
33
29
  e.preventDefault();
@@ -75,8 +71,14 @@ function onKeyDown(e) {
75
71
  function onClick(e) {
76
72
  e.preventDefault();
77
73
  e.stopPropagation();
78
- store.preview(page);
79
- store.toggle(page);
74
+ // if the id was already the same as the one that was clicked, the user
75
+ // has clicked it twice, so we should choose the item and end the modal
76
+ if ($store.preview?.id === page.id)
77
+ dispatch('choose', page);
78
+ else {
79
+ store.preview(page);
80
+ store.toggle(page);
81
+ }
80
82
  }
81
83
  </script>
82
84
 
@@ -1,4 +1,4 @@
1
- <script >import folderOutline from '@iconify-icons/mdi/folder-outline.js';
1
+ <script>import folderOutline from '@iconify-icons/mdi/folder-outline.js';
2
2
  import fileLinkOutline from '@iconify-icons/mdi/file-link-outline.js';
3
3
  import FileIcon from '../FileIcon.svelte';
4
4
  import Icon from '../Icon.svelte';
@@ -1,6 +1,3 @@
1
1
  export * from './ChooserAPI.js';
2
2
  export * from './ChooserStore.js';
3
- export { default as Asset } from './Asset.svelte';
4
- export { default as AssetFolder } from './AssetFolder.svelte';
5
3
  export { default as Chooser } from './Chooser.svelte';
6
- export { default as Page } from './Page.svelte';
package/chooser/index.js CHANGED
@@ -1,6 +1,3 @@
1
1
  export * from './ChooserAPI.js';
2
2
  export * from './ChooserStore.js';
3
- export { default as Asset } from './Asset.svelte';
4
- export { default as AssetFolder } from './AssetFolder.svelte';
5
3
  export { default as Chooser } from './Chooser.svelte';
6
- export { default as Page } from './Page.svelte';
package/index.d.ts CHANGED
@@ -5,6 +5,7 @@ export { default as FieldChoices } from './FieldChoices.svelte';
5
5
  export { default as FieldChooserLink } from './FieldChooserLink.svelte';
6
6
  export { default as FieldDate } from './FieldDate.svelte';
7
7
  export { default as FieldDateTime } from './FieldDateTime.svelte';
8
+ export { default as FieldDualListbox } from './FieldDualListbox.svelte';
8
9
  export { default as FieldMultiple } from './FieldMultiple.svelte';
9
10
  export { default as FieldMultiselect } from './FieldMultiselect.svelte';
10
11
  export { default as FieldNumber } from './FieldNumber.svelte';
@@ -20,5 +21,6 @@ export { default as Input } from './Input.svelte';
20
21
  export { default as Radio } from './Radio.svelte';
21
22
  export { default as Tab } from './Tab.svelte';
22
23
  export { default as Tabs } from './Tabs.svelte';
24
+ export { default as Listbox } from './Listbox.svelte';
23
25
  export * from './chooser/index.js';
24
26
  export * from './TabStore.js';
package/index.js CHANGED
@@ -5,6 +5,7 @@ export { default as FieldChoices } from './FieldChoices.svelte';
5
5
  export { default as FieldChooserLink } from './FieldChooserLink.svelte';
6
6
  export { default as FieldDate } from './FieldDate.svelte';
7
7
  export { default as FieldDateTime } from './FieldDateTime.svelte';
8
+ export { default as FieldDualListbox } from './FieldDualListbox.svelte';
8
9
  export { default as FieldMultiple } from './FieldMultiple.svelte';
9
10
  export { default as FieldMultiselect } from './FieldMultiselect.svelte';
10
11
  export { default as FieldNumber } from './FieldNumber.svelte';
@@ -20,5 +21,6 @@ export { default as Input } from './Input.svelte';
20
21
  export { default as Radio } from './Radio.svelte';
21
22
  export { default as Tab } from './Tab.svelte';
22
23
  export { default as Tabs } from './Tabs.svelte';
24
+ export { default as Listbox } from './Listbox.svelte';
23
25
  export * from './chooser/index.js';
24
26
  export * from './TabStore.js';
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@dosgato/dialog",
3
3
  "description": "A component library for building forms that edit a JSON document.",
4
- "version": "0.0.3",
4
+ "version": "0.0.6",
5
5
  "dependencies": {
6
- "@txstate-mws/svelte-components": "^1.2.5",
7
- "@txstate-mws/svelte-forms": "^0.0.14",
8
- "@iconify/svelte": "^2.1.1",
9
- "@iconify-icons/mdi": "^1.2.6",
10
- "txstate-utils": "^1.6.6"
6
+ "@txstate-mws/svelte-components": "^1.2.9",
7
+ "@txstate-mws/svelte-forms": "^0.0.18",
8
+ "@iconify/svelte": "^2.2.1",
9
+ "@iconify-icons/mdi": "^1.2.22",
10
+ "txstate-utils": "^1.7.3"
11
11
  },
12
12
  "devDependencies": {
13
13
  "@sveltejs/adapter-auto": "next",
@@ -32,6 +32,7 @@
32
32
  "./FieldChooserLink.svelte": "./FieldChooserLink.svelte",
33
33
  "./FieldDate.svelte": "./FieldDate.svelte",
34
34
  "./FieldDateTime.svelte": "./FieldDateTime.svelte",
35
+ "./FieldDualListbox.svelte": "./FieldDualListbox.svelte",
35
36
  "./FieldMultiple.svelte": "./FieldMultiple.svelte",
36
37
  "./FieldMultiselect.svelte": "./FieldMultiselect.svelte",
37
38
  "./FieldNumber.svelte": "./FieldNumber.svelte",
@@ -45,6 +46,7 @@
45
46
  "./InlineMessage.svelte": "./InlineMessage.svelte",
46
47
  "./InlineMessages.svelte": "./InlineMessages.svelte",
47
48
  "./Input.svelte": "./Input.svelte",
49
+ "./Listbox.svelte": "./Listbox.svelte",
48
50
  "./Radio.svelte": "./Radio.svelte",
49
51
  "./Tab.svelte": "./Tab.svelte",
50
52
  "./TabStore": "./TabStore.js",