@dosgato/dialog 0.0.51 → 0.0.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Container.svelte +12 -2
- package/dist/Container.svelte.d.ts +10 -5
- package/dist/FieldChoices.svelte +6 -0
- package/dist/FieldChoices.svelte.d.ts +6 -0
- package/dist/FieldMultiselect.svelte +31 -15
- package/dist/FieldMultiselect.svelte.d.ts +17 -4
- package/dist/FieldStandard.svelte +13 -0
- package/dist/FieldStandard.svelte.d.ts +13 -4
- package/dist/Icon.svelte +6 -0
- package/dist/Icon.svelte.d.ts +6 -1
- package/dist/InlineMessage.svelte +13 -0
- package/dist/InlineMessage.svelte.d.ts +1 -0
- package/dist/InlineMessages.svelte +4 -1
- package/dist/InlineMessages.svelte.d.ts +2 -1
- package/dist/Tabs.svelte +3 -2
- package/dist/Tabs.svelte.d.ts +1 -0
- package/dist/chooser/Thumbnail.svelte +1 -1
- package/dist/cropper/FieldCropper.svelte +1 -1
- package/dist/cropper/FieldCropper.svelte.d.ts +1 -1
- package/dist/tree/Tree.svelte +27 -3
- package/dist/tree/Tree.svelte.d.ts +1 -0
- package/dist/tree/TreeNode.svelte +4 -1
- package/dist/tree/treestore.js +1 -0
- package/package.json +1 -1
package/dist/Container.svelte
CHANGED
|
@@ -1,17 +1,27 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
The purpose of `<Container>` is to provide common rendering for helptext, screen reader support,
|
|
3
|
+
and `Feedback` messages for its slotted components under a common `<div>` useful for form fields.
|
|
4
|
+
-->
|
|
1
5
|
<script>import { eq, resize, ScreenReaderOnly } from '@txstate-mws/svelte-components';
|
|
2
6
|
import { randomid } from 'txstate-utils';
|
|
3
7
|
import { getContext } from 'svelte';
|
|
4
8
|
import { DG_DIALOG_FIELD_MULTIPLE } from './FieldMultiple.svelte';
|
|
5
9
|
import InlineMessages from './InlineMessages.svelte';
|
|
6
10
|
import { getDescribedBy } from './';
|
|
11
|
+
/** A label for the Container `<div>`. */
|
|
12
|
+
export let label;
|
|
13
|
+
export let messages;
|
|
14
|
+
/** If the input that's being built has an id pass it here so the label can point at it. */
|
|
7
15
|
export let id = undefined;
|
|
16
|
+
/** If `descid` is defined then this assumes you've made an outside label referenced to by descid `<div id={descid}`.
|
|
17
|
+
Useful for things like checkboxes and radio buttons that have their own individual labels. */
|
|
8
18
|
export let descid = undefined;
|
|
9
|
-
export let label;
|
|
10
19
|
export let helptext = undefined;
|
|
11
|
-
|
|
20
|
+
/** Syntactic sugar that toggles a '*' to be appended to label. */
|
|
12
21
|
export let required = false;
|
|
13
22
|
export let related = 0;
|
|
14
23
|
export let conditional = undefined;
|
|
24
|
+
/** The `id` of `<div>` messages are rendered in. */
|
|
15
25
|
let messagesid;
|
|
16
26
|
const dgMultipleContext = getContext(DG_DIALOG_FIELD_MULTIPLE);
|
|
17
27
|
const helptextid = randomid();
|
|
@@ -2,12 +2,13 @@ import { SvelteComponentTyped } from "svelte";
|
|
|
2
2
|
import type { Feedback } from '@txstate-mws/svelte-forms';
|
|
3
3
|
declare const __propDef: {
|
|
4
4
|
props: {
|
|
5
|
-
|
|
6
|
-
descid?: string | undefined;
|
|
7
|
-
label: string;
|
|
8
|
-
helptext?: string | undefined;
|
|
5
|
+
/** A label for the Container `<div>`. */ label: string;
|
|
9
6
|
messages: Feedback[];
|
|
10
|
-
|
|
7
|
+
/** If the input that's being built has an id pass it here so the label can point at it. */ id?: string | undefined;
|
|
8
|
+
/** If `descid` is defined then this assumes you've made an outside label referenced to by descid `<div id={descid}`.
|
|
9
|
+
Useful for things like checkboxes and radio buttons that have their own individual labels. */ descid?: string | undefined;
|
|
10
|
+
helptext?: string | undefined;
|
|
11
|
+
/** Syntactic sugar that toggles a '*' to be appended to label. */ required?: boolean | undefined;
|
|
11
12
|
related?: number | true | undefined;
|
|
12
13
|
conditional?: boolean | undefined;
|
|
13
14
|
};
|
|
@@ -24,6 +25,10 @@ declare const __propDef: {
|
|
|
24
25
|
export type ContainerProps = typeof __propDef.props;
|
|
25
26
|
export type ContainerEvents = typeof __propDef.events;
|
|
26
27
|
export type ContainerSlots = typeof __propDef.slots;
|
|
28
|
+
/**
|
|
29
|
+
* The purpose of `<Container>` is to provide common rendering for helptext, screen reader support,
|
|
30
|
+
* and `Feedback` messages for its slotted components under a common `<div>` useful for form fields.
|
|
31
|
+
*/
|
|
27
32
|
export default class Container extends SvelteComponentTyped<ContainerProps, ContainerEvents, ContainerSlots> {
|
|
28
33
|
}
|
|
29
34
|
export {};
|
package/dist/FieldChoices.svelte
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
A Field component for dynamically rendering checkbox choices accross the available width of a `<div>`. If there are more
|
|
3
|
+
choices than the available width of the `<div>` will support then it will create multiple rows to render within using
|
|
4
|
+
flex. Ordering is top down by default but can be order horizontally by toggling `leftToRight`.
|
|
5
|
+
The value of the field will be an array corresponding to the values of the checkboxes that are checked.
|
|
6
|
+
-->
|
|
1
7
|
<script>import { getContext } from 'svelte';
|
|
2
8
|
import { Field, FORM_CONTEXT } from '@txstate-mws/svelte-forms';
|
|
3
9
|
import { derivedStore } from '@txstate-mws/svelte-store';
|
|
@@ -26,6 +26,12 @@ declare const __propDef: {
|
|
|
26
26
|
export type FieldChoicesProps = typeof __propDef.props;
|
|
27
27
|
export type FieldChoicesEvents = typeof __propDef.events;
|
|
28
28
|
export type FieldChoicesSlots = typeof __propDef.slots;
|
|
29
|
+
/**
|
|
30
|
+
* A Field component for dynamically rendering checkbox choices accross the available width of a `<div>`. If there are more
|
|
31
|
+
* choices than the available width of the `<div>` will support then it will create multiple rows to render within using
|
|
32
|
+
* flex. Ordering is top down by default but can be order horizontally by toggling `leftToRight`.
|
|
33
|
+
* The value of the field will be an array corresponding to the values of the checkboxes that are checked.
|
|
34
|
+
*/
|
|
29
35
|
export default class FieldChoices extends SvelteComponentTyped<FieldChoicesProps, FieldChoicesEvents, FieldChoicesSlots> {
|
|
30
36
|
}
|
|
31
37
|
export {};
|
|
@@ -1,32 +1,45 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
The purpose of FieldMultiselect is to provide a Field with text input having a popup menu
|
|
3
|
+
that displays, or completes, choice selections based on what's been typed in the text input.
|
|
4
|
+
Selected choices will be added to a list of selected items, in a pill format, that provides
|
|
5
|
+
a means for tracking and removing existing selections. The choices listed in the popup are
|
|
6
|
+
controlled by the parent component via the `getOptions` function that will be used as a
|
|
7
|
+
debounced callback on the contents of the text input.
|
|
8
|
+
-->
|
|
1
9
|
<script>import { MultiSelect } from '@txstate-mws/svelte-components';
|
|
2
10
|
import { Store } from '@txstate-mws/svelte-store';
|
|
3
11
|
import { onMount } from 'svelte';
|
|
4
12
|
import { isNotBlank } from 'txstate-utils';
|
|
5
13
|
import FieldStandard from './FieldStandard.svelte';
|
|
6
14
|
import { getDescribedBy } from './helpers';
|
|
7
|
-
export let id = undefined;
|
|
8
15
|
export let path;
|
|
16
|
+
/** Function to pass to the component that tells it how to use the text
|
|
17
|
+
in the text input to determine what `PopupMenuItem[]` should be displayed
|
|
18
|
+
in the `<PopupMenu>`. Items already 'selected' from the popup menu will be
|
|
19
|
+
tracked and automatically filtered from the popup if returned as one of the
|
|
20
|
+
`PopupMenuItem[]` by `getOptions`. */
|
|
21
|
+
export let getOptions;
|
|
22
|
+
export let id = undefined;
|
|
9
23
|
export let label = '';
|
|
24
|
+
/** Text to display in the text input when it's empty. */
|
|
10
25
|
export let placeholder = '';
|
|
11
26
|
export let disabled = false;
|
|
12
27
|
export let defaultValue = [];
|
|
13
28
|
export let conditional = undefined;
|
|
14
29
|
export let required = false;
|
|
30
|
+
/** Max number of selections to be allowed before disabling the input - 0 for unlimited. */
|
|
15
31
|
export let maxSelections = 0;
|
|
16
|
-
export let getOptions;
|
|
32
|
+
export let lookupByValue = async (val) => { const options = await getOptions(val); return options.find((opt) => opt.value === val); };
|
|
17
33
|
export let related = 0;
|
|
18
34
|
export let extradescid = undefined;
|
|
19
35
|
export let helptext = undefined;
|
|
20
|
-
//
|
|
21
|
-
// that it finds, so that we can display labels on pills
|
|
36
|
+
// Each time we run getOptions we will save the value -> label mappings
|
|
37
|
+
// that it finds, so that we can display labels on pills.
|
|
22
38
|
const valueToLabel = {};
|
|
23
39
|
async function wrapGetOptions(search) {
|
|
24
40
|
const opts = await getOptions(search);
|
|
25
|
-
|
|
26
|
-
//
|
|
27
|
-
// if (opts.length === 0) {
|
|
28
|
-
// opts = await getOptions('')
|
|
29
|
-
// }
|
|
41
|
+
/** If no options are returned with the search term, we can end up with an infinite loop the first time reactToValue calls wrapGetOptions */
|
|
42
|
+
// if (opts.length === 0) opts = await getOptions('')
|
|
30
43
|
for (const opt of opts) {
|
|
31
44
|
valueToLabel[opt.value] = opt.label || opt.value;
|
|
32
45
|
}
|
|
@@ -41,14 +54,17 @@ onMount(async () => {
|
|
|
41
54
|
await reactToValue(defaultValue);
|
|
42
55
|
hasInit = true;
|
|
43
56
|
});
|
|
44
|
-
//
|
|
45
|
-
// yet, we won't have a label for it
|
|
46
|
-
//
|
|
47
|
-
// is currently unknown
|
|
57
|
+
// If we get a value from the form that we haven't seen in the popup menu
|
|
58
|
+
// yet, we won't have a label for it.
|
|
59
|
+
// This function runs getOptions on any selected values for which the label
|
|
60
|
+
// is currently unknown.
|
|
48
61
|
async function reactToValue(value) {
|
|
49
62
|
await Promise.all(value.map(async (v) => {
|
|
50
|
-
if (!valueToLabel[v])
|
|
51
|
-
await
|
|
63
|
+
if (!valueToLabel[v]) {
|
|
64
|
+
const item = await lookupByValue(v);
|
|
65
|
+
if (item)
|
|
66
|
+
valueToLabel[item.value] = item.label ?? item.value;
|
|
67
|
+
}
|
|
52
68
|
}));
|
|
53
69
|
selectedStore.set(value.map(v => ({ value: v, label: valueToLabel[v] })).filter(v => isNotBlank(v.label)));
|
|
54
70
|
}
|
|
@@ -2,16 +2,21 @@ import { SvelteComponentTyped } from "svelte";
|
|
|
2
2
|
import type { PopupMenuItem } from '@txstate-mws/svelte-components';
|
|
3
3
|
declare const __propDef: {
|
|
4
4
|
props: {
|
|
5
|
-
id?: string | undefined;
|
|
6
5
|
path: string;
|
|
6
|
+
/** Function to pass to the component that tells it how to use the text
|
|
7
|
+
in the text input to determine what `PopupMenuItem[]` should be displayed
|
|
8
|
+
in the `<PopupMenu>`. Items already 'selected' from the popup menu will be
|
|
9
|
+
tracked and automatically filtered from the popup if returned as one of the
|
|
10
|
+
`PopupMenuItem[]` by `getOptions`. */ getOptions: (search: string) => Promise<PopupMenuItem[]>;
|
|
11
|
+
id?: string | undefined;
|
|
7
12
|
label?: string | undefined;
|
|
8
|
-
placeholder?: string | undefined;
|
|
13
|
+
/** Text to display in the text input when it's empty. */ placeholder?: string | undefined;
|
|
9
14
|
disabled?: boolean | undefined;
|
|
10
15
|
defaultValue?: string[] | undefined;
|
|
11
16
|
conditional?: boolean | undefined;
|
|
12
17
|
required?: boolean | undefined;
|
|
13
|
-
maxSelections?: number | undefined;
|
|
14
|
-
|
|
18
|
+
/** Max number of selections to be allowed before disabling the input - 0 for unlimited. */ maxSelections?: number | undefined;
|
|
19
|
+
lookupByValue?: ((val: string) => Promise<PopupMenuItem | undefined>) | undefined;
|
|
15
20
|
related?: number | true | undefined;
|
|
16
21
|
extradescid?: string | undefined;
|
|
17
22
|
helptext?: string | undefined;
|
|
@@ -24,6 +29,14 @@ declare const __propDef: {
|
|
|
24
29
|
export type FieldMultiselectProps = typeof __propDef.props;
|
|
25
30
|
export type FieldMultiselectEvents = typeof __propDef.events;
|
|
26
31
|
export type FieldMultiselectSlots = typeof __propDef.slots;
|
|
32
|
+
/**
|
|
33
|
+
* The purpose of FieldMultiselect is to provide a Field with text input having a popup menu
|
|
34
|
+
* that displays, or completes, choice selections based on what's been typed in the text input.
|
|
35
|
+
* Selected choices will be added to a list of selected items, in a pill format, that provides
|
|
36
|
+
* a means for tracking and removing existing selections. The choices listed in the popup are
|
|
37
|
+
* controlled by the parent component via the `getOptions` function that will be used as a
|
|
38
|
+
* debounced callback on the contents of the text input.
|
|
39
|
+
*/
|
|
27
40
|
export default class FieldMultiselect extends SvelteComponentTyped<FieldMultiselectProps, FieldMultiselectEvents, FieldMultiselectSlots> {
|
|
28
41
|
}
|
|
29
42
|
export {};
|
|
@@ -1,10 +1,22 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
The purpose of `<FieldStandard>` is to provide a standard [`<Field>`](https://github.com/txstate-etc/svelte-forms#field)
|
|
3
|
+
component that not only handles the association of a state/value with the JSON payload associated with a
|
|
4
|
+
[`FormStore`](https://github.com/txstate-etc/svelte-forms/blob/main/src/lib/FormStore.ts) but also handles
|
|
5
|
+
common rendering for helptext, aria descriptions, and `Feedback` messages for its slotted components
|
|
6
|
+
by encapsulating them in a [`<Container>`](https://github.com/txstate-etc/dosgato-dialog/blob/main/src/lib/Container.svelte)
|
|
7
|
+
setup to work in conjuction with the parent `<Field>` tag.
|
|
8
|
+
-->
|
|
1
9
|
<script>import { Field } from '@txstate-mws/svelte-forms';
|
|
2
10
|
import { randomid } from 'txstate-utils';
|
|
3
11
|
import Container from './Container.svelte';
|
|
12
|
+
/** If the input that's being built has an id pass it here so the label can point at it. */
|
|
4
13
|
export let id = randomid();
|
|
14
|
+
/** If `descid` is defined then this assumes you've made an outside label referenced to by descid `<div id={descid}`.
|
|
15
|
+
Useful for things like checkboxes and radio buttons that have their own individual labels. */
|
|
5
16
|
export let descid = undefined;
|
|
6
17
|
export let path;
|
|
7
18
|
export let defaultValue = undefined;
|
|
19
|
+
/** A label for the Container `<div>`. */
|
|
8
20
|
export let label;
|
|
9
21
|
export let notNull = false;
|
|
10
22
|
export let number = false;
|
|
@@ -13,6 +25,7 @@ export let datetime = false;
|
|
|
13
25
|
export let boolean = false;
|
|
14
26
|
export let serialize = undefined;
|
|
15
27
|
export let deserialize = undefined;
|
|
28
|
+
/** If you need to do some processing just before submit or validate define that processing here. */
|
|
16
29
|
export let finalize = undefined;
|
|
17
30
|
export let conditional = undefined;
|
|
18
31
|
export let required = false;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { SvelteComponentTyped } from "svelte";
|
|
2
2
|
declare const __propDef: {
|
|
3
3
|
props: {
|
|
4
|
-
id?: string | undefined;
|
|
5
|
-
descid
|
|
4
|
+
/** If the input that's being built has an id pass it here so the label can point at it. */ id?: string | undefined;
|
|
5
|
+
/** If `descid` is defined then this assumes you've made an outside label referenced to by descid `<div id={descid}`.
|
|
6
|
+
Useful for things like checkboxes and radio buttons that have their own individual labels. */ descid?: string | undefined;
|
|
6
7
|
path: string;
|
|
7
8
|
defaultValue?: any;
|
|
8
|
-
label: string;
|
|
9
|
+
/** A label for the Container `<div>`. */ label: string;
|
|
9
10
|
notNull?: boolean | undefined;
|
|
10
11
|
number?: boolean | undefined;
|
|
11
12
|
date?: boolean | undefined;
|
|
@@ -13,7 +14,7 @@ declare const __propDef: {
|
|
|
13
14
|
boolean?: boolean | undefined;
|
|
14
15
|
serialize?: ((value: any) => string) | undefined;
|
|
15
16
|
deserialize?: ((value: string) => any) | undefined;
|
|
16
|
-
finalize?: ((value: any) => any) | undefined;
|
|
17
|
+
/** If you need to do some processing just before submit or validate define that processing here. */ finalize?: ((value: any) => any) | undefined;
|
|
17
18
|
conditional?: boolean | undefined;
|
|
18
19
|
required?: boolean | undefined;
|
|
19
20
|
related?: number | true | undefined;
|
|
@@ -42,6 +43,14 @@ declare const __propDef: {
|
|
|
42
43
|
export type FieldStandardProps = typeof __propDef.props;
|
|
43
44
|
export type FieldStandardEvents = typeof __propDef.events;
|
|
44
45
|
export type FieldStandardSlots = typeof __propDef.slots;
|
|
46
|
+
/**
|
|
47
|
+
* The purpose of `<FieldStandard>` is to provide a standard [`<Field>`](https://github.com/txstate-etc/svelte-forms#field)
|
|
48
|
+
* component that not only handles the association of a state/value with the JSON payload associated with a
|
|
49
|
+
* [`FormStore`](https://github.com/txstate-etc/svelte-forms/blob/main/src/lib/FormStore.ts) but also handles
|
|
50
|
+
* common rendering for helptext, aria descriptions, and `Feedback` messages for its slotted components
|
|
51
|
+
* by encapsulating them in a [`<Container>`](https://github.com/txstate-etc/dosgato-dialog/blob/main/src/lib/Container.svelte)
|
|
52
|
+
* setup to work in conjuction with the parent `<Field>` tag.
|
|
53
|
+
*/
|
|
45
54
|
export default class FieldStandard extends SvelteComponentTyped<FieldStandardProps, FieldStandardEvents, FieldStandardSlots> {
|
|
46
55
|
}
|
|
47
56
|
export {};
|
package/dist/Icon.svelte
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
This is a wrapper component around iconify's [OfflineIcon](https://docs.iconify.design/icon-components/svelte/offline.html)
|
|
3
|
+
implementation of icons that adds a hidden label that can be read by screen readers. Useful for situations where aria-label
|
|
4
|
+
isn't supported, to provide in kind icon support, while still making use of aria attributes regardless of support.
|
|
5
|
+
-->
|
|
1
6
|
<script>import Icon from '@iconify/svelte/dist/OfflineIcon.svelte';
|
|
2
7
|
import { ScreenReaderOnly } from '@txstate-mws/svelte-components';
|
|
3
8
|
export let icon;
|
|
9
|
+
/** Label used in a `<ScreenReaderOnly>`. */
|
|
4
10
|
export let hiddenLabel = undefined;
|
|
5
11
|
export let inline = false;
|
|
6
12
|
export let width = '1em';
|
package/dist/Icon.svelte.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { IconifyIcon } from '@iconify/svelte';
|
|
|
3
3
|
declare const __propDef: {
|
|
4
4
|
props: {
|
|
5
5
|
icon: IconifyIcon | undefined;
|
|
6
|
-
hiddenLabel?: string | undefined;
|
|
6
|
+
/** Label used in a `<ScreenReaderOnly>`. */ hiddenLabel?: string | undefined;
|
|
7
7
|
inline?: boolean | undefined;
|
|
8
8
|
width?: string | number | undefined;
|
|
9
9
|
height?: string | number | undefined;
|
|
@@ -17,6 +17,11 @@ declare const __propDef: {
|
|
|
17
17
|
export type IconProps = typeof __propDef.props;
|
|
18
18
|
export type IconEvents = typeof __propDef.events;
|
|
19
19
|
export type IconSlots = typeof __propDef.slots;
|
|
20
|
+
/**
|
|
21
|
+
* This is a wrapper component around iconify's [OfflineIcon](https://docs.iconify.design/icon-components/svelte/offline.html)
|
|
22
|
+
* implementation of icons that adds a hidden label that can be read by screen readers. Useful for situations where aria-label
|
|
23
|
+
* isn't supported, to provide in kind icon support, while still making use of aria attributes regardless of support.
|
|
24
|
+
*/
|
|
20
25
|
export default class Icon extends SvelteComponentTyped<IconProps, IconEvents, IconSlots> {
|
|
21
26
|
}
|
|
22
27
|
export {};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
The purpose of this component is to provide common `Feedback` message styling with icons that support screen readers.
|
|
3
|
+
-->
|
|
1
4
|
<script>import alertCircleOutline from '@iconify-icons/mdi/alert-circle-outline.js';
|
|
2
5
|
import checkCircleOutline from '@iconify-icons/mdi/check-circle-outline.js';
|
|
3
6
|
import informationOutline from '@iconify-icons/mdi/information-outline.js';
|
|
@@ -11,6 +14,16 @@ const icons = {
|
|
|
11
14
|
system: closeOctagonOutline
|
|
12
15
|
};
|
|
13
16
|
$: icon = icons[message.type] ?? alertCircleOutline;
|
|
17
|
+
// Would we like to add something like the following for non-Error message types being used in aria descriptions?
|
|
18
|
+
/*
|
|
19
|
+
const ariaLables = {
|
|
20
|
+
error: 'Error',
|
|
21
|
+
warning: 'Warning',
|
|
22
|
+
success: 'Success',
|
|
23
|
+
system: 'System'
|
|
24
|
+
}
|
|
25
|
+
$: hiddenLabel = ariaLables[message.type] ?? 'Error'
|
|
26
|
+
*/
|
|
14
27
|
</script>
|
|
15
28
|
|
|
16
29
|
<div class={message.type}><Icon width='1.5em' {icon} hiddenLabel='Error' /><span>{message.message}</span></div>
|
|
@@ -12,6 +12,7 @@ declare const __propDef: {
|
|
|
12
12
|
export type InlineMessageProps = typeof __propDef.props;
|
|
13
13
|
export type InlineMessageEvents = typeof __propDef.events;
|
|
14
14
|
export type InlineMessageSlots = typeof __propDef.slots;
|
|
15
|
+
/** The purpose of this component is to provide common `Feedback` message styling with icons that support screen readers. */
|
|
15
16
|
export default class InlineMessage extends SvelteComponentTyped<InlineMessageProps, InlineMessageEvents, InlineMessageSlots> {
|
|
16
17
|
}
|
|
17
18
|
export {};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
This renders the `Feedback` messages bound to it if there are any to display.
|
|
3
|
+
-->
|
|
1
4
|
<script>import { randomid } from 'txstate-utils';
|
|
2
5
|
import InlineMessage from './InlineMessage.svelte';
|
|
3
|
-
export let id = randomid();
|
|
4
6
|
export let messages;
|
|
7
|
+
export let id = randomid();
|
|
5
8
|
const savedid = id;
|
|
6
9
|
$: id = messages.length ? savedid : undefined;
|
|
7
10
|
</script>
|
|
@@ -2,8 +2,8 @@ import { SvelteComponentTyped } from "svelte";
|
|
|
2
2
|
import type { Feedback } from '@txstate-mws/svelte-forms';
|
|
3
3
|
declare const __propDef: {
|
|
4
4
|
props: {
|
|
5
|
-
id?: string | undefined;
|
|
6
5
|
messages: Feedback[];
|
|
6
|
+
id?: string | undefined;
|
|
7
7
|
};
|
|
8
8
|
events: {
|
|
9
9
|
[evt: string]: CustomEvent<any>;
|
|
@@ -13,6 +13,7 @@ declare const __propDef: {
|
|
|
13
13
|
export type InlineMessagesProps = typeof __propDef.props;
|
|
14
14
|
export type InlineMessagesEvents = typeof __propDef.events;
|
|
15
15
|
export type InlineMessagesSlots = typeof __propDef.slots;
|
|
16
|
+
/** This renders the `Feedback` messages bound to it if there are any to display. */
|
|
16
17
|
export default class InlineMessages extends SvelteComponentTyped<InlineMessagesProps, InlineMessagesEvents, InlineMessagesSlots> {
|
|
17
18
|
}
|
|
18
19
|
export {};
|
package/dist/Tabs.svelte
CHANGED
|
@@ -9,6 +9,7 @@ export let tabs;
|
|
|
9
9
|
export let active = undefined;
|
|
10
10
|
export let store = new TabStore(tabs, active);
|
|
11
11
|
export let disableDialogControl = false;
|
|
12
|
+
export let accordionOnMobile = true;
|
|
12
13
|
$: store.update(v => ({ ...v, tabs }));
|
|
13
14
|
const activeStore = new Store({});
|
|
14
15
|
const tabelements = [];
|
|
@@ -29,7 +30,7 @@ const accordion = store.accordion();
|
|
|
29
30
|
$: cols = Math.min(Math.floor(($store.clientWidth ?? 1024) / 90), $store.tabs.length);
|
|
30
31
|
$: scalefactor = Math.min(roundTo(($store.clientWidth ?? 1024) / (cols * 130), 4), 1);
|
|
31
32
|
$: wrapping = cols !== $store.tabs.length;
|
|
32
|
-
$: dialogContext.hasTabs = !$accordion;
|
|
33
|
+
$: dialogContext.hasTabs = !$accordion || !accordionOnMobile;
|
|
33
34
|
function onClick(idx) {
|
|
34
35
|
return () => store.activate(idx);
|
|
35
36
|
}
|
|
@@ -86,7 +87,7 @@ onMount(reactToCurrent);
|
|
|
86
87
|
</script>
|
|
87
88
|
|
|
88
89
|
{#if $store.tabs.length > 1}
|
|
89
|
-
{#if !$accordion}
|
|
90
|
+
{#if !$accordion || !accordionOnMobile}
|
|
90
91
|
<!-- svelte-ignore a11y-no-noninteractive-element-to-interactive-role -->
|
|
91
92
|
<ul use:resize={{ store }} class="tabs-buttons" role="tablist">
|
|
92
93
|
{#each $store.tabs as tab, idx (tab.name)}
|
package/dist/Tabs.svelte.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export let larger = false;
|
|
|
9
9
|
<div class="dialog-chooser-thumbnail">
|
|
10
10
|
{#if item.type === 'asset'}
|
|
11
11
|
{#if item.image}
|
|
12
|
-
<img src={(larger ? item.image.thumbnailUrl : item.image.
|
|
12
|
+
<img src={(larger ? (item.image.previewUrl ?? item.image.thumbnailUrl) : (item.image.thumbnailUrl ?? item.image.previewUrl)) ?? item.url} alt="" />
|
|
13
13
|
{:else}
|
|
14
14
|
<FileIcon mime={item.mime} width='5em' />
|
|
15
15
|
{/if}
|
|
@@ -108,7 +108,7 @@ let focusWithin = false;
|
|
|
108
108
|
</script>
|
|
109
109
|
|
|
110
110
|
<svelte:window on:mousemove={onMouseMove} on:mouseup={onMouseUp} on:touchend={onMouseUp} on:touchcancel={onMouseUp} />
|
|
111
|
-
<FieldStandard bind:id {label} {path} {required} {conditional} {helptext} {descid} let:value let:setVal let:helptextid>
|
|
111
|
+
<FieldStandard bind:id {label} {path} {required} conditional={conditional && isNotBlank(imageSrc)} {helptext} {descid} let:value let:setVal let:helptextid>
|
|
112
112
|
{@const _ = init(value, setVal)}
|
|
113
113
|
{#if isNotBlank(imageSrc)}
|
|
114
114
|
<div on:focusin={() => { focusWithin = true }} on:focusout={() => { focusWithin = false }}>
|
package/dist/tree/Tree.svelte
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
<script>import { resize } from '@txstate-mws/svelte-components';
|
|
2
2
|
import { derivedStore, Store } from '@txstate-mws/svelte-store';
|
|
3
|
-
import { afterUpdate, beforeUpdate, onDestroy, onMount, setContext
|
|
3
|
+
import { afterUpdate, beforeUpdate, onDestroy, onMount, setContext } from 'svelte';
|
|
4
|
+
import { toArray } from 'txstate-utils';
|
|
4
5
|
import LoadIcon from './LoadIcon.svelte';
|
|
5
6
|
import TreeNode from './TreeNode.svelte';
|
|
6
7
|
import { getHashId, TreeStore, TREE_STORE_CONTEXT } from './treestore';
|
|
7
8
|
export let headers;
|
|
9
|
+
export let searchable = undefined;
|
|
8
10
|
export let nodeClass = undefined;
|
|
9
11
|
export let singleSelect = undefined;
|
|
10
12
|
export let enableResize = false;
|
|
@@ -53,6 +55,28 @@ $: store.singleSelect = singleSelect;
|
|
|
53
55
|
function onDragEnd() {
|
|
54
56
|
store.update(v => ({ ...v, dragging: false }));
|
|
55
57
|
}
|
|
58
|
+
let search = '';
|
|
59
|
+
let searchTimer = 0;
|
|
60
|
+
$: searchableFn = searchable == null ? undefined : (typeof searchable === 'function' ? (itm) => toArray(searchable(itm)) : (itm) => [itm[searchable]]);
|
|
61
|
+
function onKeyUp(e) {
|
|
62
|
+
if (!searchableFn)
|
|
63
|
+
return;
|
|
64
|
+
if (e.key.length === 1) {
|
|
65
|
+
search += e.key;
|
|
66
|
+
const searchItems = $store.focused?.parent ? $store.focused.parent.children : $store.rootItems;
|
|
67
|
+
const newFocus = searchItems?.find(itm => searchableFn(itm).some(str => str.toLocaleLowerCase().startsWith(search.toLocaleLowerCase())));
|
|
68
|
+
if (newFocus)
|
|
69
|
+
store.focus(newFocus);
|
|
70
|
+
clearTimeout(searchTimer);
|
|
71
|
+
searchTimer = setTimeout(() => { search = ''; }, 4000);
|
|
72
|
+
}
|
|
73
|
+
else if (e.key === 'Backspace') {
|
|
74
|
+
search = search.substring(0, search.length - 1);
|
|
75
|
+
}
|
|
76
|
+
else if (e.key === 'Escape') {
|
|
77
|
+
search = '';
|
|
78
|
+
}
|
|
79
|
+
}
|
|
56
80
|
let dragheaderid;
|
|
57
81
|
let dragheaderidx;
|
|
58
82
|
let dragtarget;
|
|
@@ -126,13 +150,13 @@ afterUpdate(() => {
|
|
|
126
150
|
<div class="tree-header" class:resizing={!!dragheaderid} use:resize={{ store: treeWidth }} aria-hidden="true" on:mouseup={headerDragEnd} on:touchend={headerDragEnd} on:mousemove={dragheaderid ? headerDrag : undefined} on:touchmove={dragheaderid ? headerDrag : undefined}>
|
|
127
151
|
<div class="checkbox" bind:this={checkboxelement}> </div>
|
|
128
152
|
{#each headers as header, i (header.label)}
|
|
129
|
-
<div bind:this={headerelements[i]} id={header.id} class="tree-header-cell {header.id}" style:width={$headerOverride[header.id] ?? $headerSizes?.[i]}>{header.label}{#if i === 0 && $store.loading}<LoadIcon />{/if}</div>
|
|
153
|
+
<div bind:this={headerelements[i]} id={header.id} class="tree-header-cell {header.id}" style:width={$headerOverride[header.id] ?? $headerSizes?.[i]}>{header.label}{#if i === 0 && $store.loading}<LoadIcon />{/if}{#if i === 0 && search} (searching: {search}){/if}</div>
|
|
130
154
|
{#if enableResize && i !== headers.length - 1}<div class="tree-separator" on:mousedown={headerDragStart(header, i)} on:touchstart={headerDragStart(header, i)} on:dblclick={headerDragReset}> </div>{/if}
|
|
131
155
|
{/each}
|
|
132
156
|
</div>
|
|
133
157
|
{#if mounted && $rootItems?.length}
|
|
134
158
|
<!-- svelte-ignore a11y-no-noninteractive-element-to-interactive-role -->
|
|
135
|
-
<ul bind:this={store.treeElement} role="tree" class:resizing={!!dragheaderid} on:mousemove={dragheaderid ? headerDrag : undefined} on:touchmove={dragheaderid ? headerDrag : undefined} on:mouseup={headerDragEnd} on:touchend={headerDragEnd}>
|
|
159
|
+
<ul bind:this={store.treeElement} role="tree" class:resizing={!!dragheaderid} on:mousemove={dragheaderid ? headerDrag : undefined} on:touchmove={dragheaderid ? headerDrag : undefined} on:mouseup={headerDragEnd} on:touchend={headerDragEnd} on:keyup={onKeyUp}>
|
|
136
160
|
{#each $rootItems as item, i (item.id)}
|
|
137
161
|
<TreeNode
|
|
138
162
|
{item}
|
|
@@ -4,6 +4,7 @@ import type { DragEligibleFn, CopyHandlerFn, DropEffectFn, FetchChildrenFn, Move
|
|
|
4
4
|
declare class __sveltets_Render<T extends TreeItemFromDB> {
|
|
5
5
|
props(): {
|
|
6
6
|
headers: TreeHeader<T>[];
|
|
7
|
+
searchable?: keyof T | ((item: T) => string | string[]) | undefined;
|
|
7
8
|
nodeClass?: ((itm: T) => string) | undefined;
|
|
8
9
|
singleSelect?: boolean | undefined;
|
|
9
10
|
enableResize?: boolean | undefined;
|
|
@@ -356,7 +356,7 @@ $: if ($dragging) {
|
|
|
356
356
|
border-bottom: var(--tree-border, 1px dashed #aaaaaa);
|
|
357
357
|
width: 100%;
|
|
358
358
|
overflow: hidden;
|
|
359
|
-
min-height: 2.
|
|
359
|
+
min-height: calc(2.7em + 2px);
|
|
360
360
|
}
|
|
361
361
|
:global(.resizing) .tree-node {
|
|
362
362
|
cursor: col-resize;
|
|
@@ -390,6 +390,9 @@ $: if ($dragging) {
|
|
|
390
390
|
.tree-node.dropDisabled {
|
|
391
391
|
opacity: 0.6;
|
|
392
392
|
}
|
|
393
|
+
.tree-node :global(svg) {
|
|
394
|
+
display: block;
|
|
395
|
+
}
|
|
393
396
|
.drop-above {
|
|
394
397
|
position: absolute;
|
|
395
398
|
top: -3px;
|
package/dist/tree/treestore.js
CHANGED
|
@@ -209,6 +209,7 @@ export class TreeStore extends ActiveStore {
|
|
|
209
209
|
this.trigger();
|
|
210
210
|
const selectedItems = Array.from(droppedItems.values());
|
|
211
211
|
const commonparent = this.findCommonParent([...selectedItems, item]);
|
|
212
|
+
this.focus(item, false);
|
|
212
213
|
try {
|
|
213
214
|
const result = dropEffect === 'move'
|
|
214
215
|
? await this.moveHandler?.(selectedItems, item, above)
|
package/package.json
CHANGED