@dosgato/dialog 1.2.2 → 1.2.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.
- package/dist/FieldChoices.svelte +24 -1
- package/dist/FieldChoices.svelte.d.ts +1 -0
- package/dist/FieldMultiselect.svelte +4 -1
- package/dist/FieldMultiselect.svelte.d.ts +2 -0
- package/dist/cropper/FieldCropper.svelte +26 -7
- package/dist/tagpicker/FieldTagPicker.svelte +4 -1
- package/dist/tagpicker/FieldTagPicker.svelte.d.ts +3 -0
- package/package.json +1 -1
package/dist/FieldChoices.svelte
CHANGED
|
@@ -24,9 +24,11 @@ export let leftToRight = false;
|
|
|
24
24
|
export let related = 0;
|
|
25
25
|
export let extradescid = undefined;
|
|
26
26
|
export let helptext = undefined;
|
|
27
|
+
export let selectAll = false;
|
|
27
28
|
const store = getContext(FORM_CONTEXT);
|
|
28
29
|
const inheritedPath = getContext(FORM_INHERITED_PATH);
|
|
29
30
|
const finalPath = [inheritedPath, path].filter(isNotBlank).join('.');
|
|
31
|
+
const valStore = store.getField(finalPath);
|
|
30
32
|
const currentWidth = derivedStore(store, 'width');
|
|
31
33
|
$: cols = Math.min(Math.ceil($currentWidth / maxwidth), choices.length);
|
|
32
34
|
let orders;
|
|
@@ -47,10 +49,25 @@ function onChangeCheckbox(setVal, choice, included) {
|
|
|
47
49
|
return [...v, choice.value];
|
|
48
50
|
});
|
|
49
51
|
}
|
|
52
|
+
$: selected = new Set($valStore ?? []);
|
|
53
|
+
let selectAllElement;
|
|
54
|
+
const selectAllId = randomid();
|
|
55
|
+
$: selectAllChecked = choices.every(choice => choice.disabled || selected.has(choice.value));
|
|
56
|
+
function selectAllChanged() {
|
|
57
|
+
if (selectAllChecked) {
|
|
58
|
+
// it was checked and is now unchecked, clear it out
|
|
59
|
+
void store.setField(finalPath, []);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
// it was not checked and now it is checked
|
|
63
|
+
void store.setField(finalPath, choices.filter(choice => !choice.disabled).map(choice => choice.value));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
50
66
|
const descid = randomid();
|
|
51
67
|
function reactToChoices(..._) {
|
|
52
68
|
const choiceSet = new Set(choices?.filter(c => !c.disabled).map(c => c.value));
|
|
53
|
-
|
|
69
|
+
selected = new Set(Array.from(selected).filter(v => choiceSet.has(v)));
|
|
70
|
+
const val = get($store.data, finalPath);
|
|
54
71
|
const filtered = val?.filter(v => choiceSet.has(v));
|
|
55
72
|
if (filtered?.length !== val?.length)
|
|
56
73
|
store.setField(finalPath, filtered).catch(console.error);
|
|
@@ -62,6 +79,12 @@ onMount(reactToChoices);
|
|
|
62
79
|
<Field {path} {defaultValue} {conditional} let:path let:value let:onBlur let:setVal let:messages let:valid let:invalid serialize={arraySerialize}>
|
|
63
80
|
<Container {path} {id} {label} {messages} {descid} {related} {helptext} let:messagesid let:helptextid>
|
|
64
81
|
<div class="dialog-choices {className}" class:valid class:invalid>
|
|
82
|
+
{#if selectAll}
|
|
83
|
+
<label for={selectAllId} style:width>
|
|
84
|
+
<Checkbox id={selectAllId} name={selectAllId} bind:inputelement={selectAllElement} value={selectAllChecked} onChange={selectAllChanged} />
|
|
85
|
+
<span>Select All</span>
|
|
86
|
+
</label>
|
|
87
|
+
{/if}
|
|
65
88
|
{#each choices as choice, idx (choice.value)}
|
|
66
89
|
{@const checkid = `${path}.${idx}`}
|
|
67
90
|
{@const included = value?.includes(choice.value)}
|
|
@@ -24,6 +24,9 @@ export let id = undefined;
|
|
|
24
24
|
export let label = '';
|
|
25
25
|
/** Text to display in the text input when it's empty. */
|
|
26
26
|
export let placeholder = '';
|
|
27
|
+
/** When there are no items (e.g. it's a filtered search and there were no results), we still display one
|
|
28
|
+
disabled item in the menu to let the user know what is going on. Use this prop to specify the message. */
|
|
29
|
+
export let emptyText = undefined;
|
|
27
30
|
export let disabled = false;
|
|
28
31
|
export let defaultValue = [];
|
|
29
32
|
export let conditional = undefined;
|
|
@@ -73,7 +76,7 @@ async function reactToValue(value) {
|
|
|
73
76
|
{@const _ = reactToValue(value)}
|
|
74
77
|
<div class:valid class:invalid>
|
|
75
78
|
<MultiSelect {id} name={path} descid={getDescribedBy([messagesid, helptextid, extradescid])}
|
|
76
|
-
{disabled} {maxSelections} selected={$selectedStore} {placeholder} getOptions={wrapGetOptions}
|
|
79
|
+
{disabled} {maxSelections} selected={$selectedStore} {placeholder} {emptyText} getOptions={wrapGetOptions}
|
|
77
80
|
inputClass='multiselect-input'
|
|
78
81
|
on:change={e => setVal(e.detail.map(itm => itm.value))} on:blur={onBlur}
|
|
79
82
|
/>
|
|
@@ -11,6 +11,8 @@ declare const __propDef: {
|
|
|
11
11
|
id?: string | undefined;
|
|
12
12
|
label?: string;
|
|
13
13
|
/** Text to display in the text input when it's empty. */ placeholder?: string;
|
|
14
|
+
/** When there are no items (e.g. it's a filtered search and there were no results), we still display one
|
|
15
|
+
disabled item in the menu to let the user know what is going on. Use this prop to specify the message. */ emptyText?: string | undefined;
|
|
14
16
|
disabled?: boolean;
|
|
15
17
|
defaultValue?: string[];
|
|
16
18
|
conditional?: boolean | undefined;
|
|
@@ -3,6 +3,9 @@ import { onMount, tick } from 'svelte';
|
|
|
3
3
|
import { isNotBlank, randomid } from 'txstate-utils';
|
|
4
4
|
import FieldStandard from '../FieldStandard.svelte';
|
|
5
5
|
import { CropperStore } from './cropper';
|
|
6
|
+
import { Button } from '..';
|
|
7
|
+
import arrowsOutIcon from '@iconify-icons/ph/arrows-out-fill';
|
|
8
|
+
import arrowsCircleIcon from '@iconify-icons/ph/arrows-clockwise-fill';
|
|
6
9
|
export let id = undefined;
|
|
7
10
|
export let path;
|
|
8
11
|
export let imageSrc;
|
|
@@ -134,6 +137,13 @@ $: void reactToAspectRatio(selectionAspectRatio);
|
|
|
134
137
|
{@const _ = init(value, setVal)}
|
|
135
138
|
{#if isNotBlank(imageSrc)}
|
|
136
139
|
<div on:focusin={() => { focusWithin = true }} on:focusout={() => { focusWithin = false }}>
|
|
140
|
+
<div class="action-buttons">
|
|
141
|
+
<Button type="button" on:click={onMaximize} icon={arrowsOutIcon}>Center and Maximize</Button>
|
|
142
|
+
<Button type="button" on:click={() => store.reset()} icon={arrowsCircleIcon} class="btn-clear">Clear</Button>
|
|
143
|
+
</div>
|
|
144
|
+
<div class="cropper-instructions">
|
|
145
|
+
Click and drag to select a section of your image to use.
|
|
146
|
+
</div>
|
|
137
147
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
138
148
|
<div bind:this={container} use:resize on:resize={() => updateRect()} class="crop-image-container" on:mousedown={onMouseDown} on:touchstart={onMouseDown} on:touchmove={onMouseMove} style:cursor={$store.cursor}>
|
|
139
149
|
<img class="crop-image" src={imageSrc} alt="" />
|
|
@@ -187,13 +197,6 @@ $: void reactToAspectRatio(selectionAspectRatio);
|
|
|
187
197
|
</div>
|
|
188
198
|
{/if}
|
|
189
199
|
</div>
|
|
190
|
-
<div class="action-buttons">
|
|
191
|
-
<button type="button" class='btn-center-max' on:click={onMaximize}>Center and Maximize</button>
|
|
192
|
-
<button type="button" class='btn-clear' on:click={() => store.reset()}>Clear</button>
|
|
193
|
-
</div>
|
|
194
|
-
<div class="cropper-instructions">
|
|
195
|
-
Click and drag to select a section of your image to use.
|
|
196
|
-
</div>
|
|
197
200
|
</div>
|
|
198
201
|
{:else}
|
|
199
202
|
Image not selected
|
|
@@ -201,6 +204,22 @@ $: void reactToAspectRatio(selectionAspectRatio);
|
|
|
201
204
|
</FieldStandard>
|
|
202
205
|
|
|
203
206
|
<style>
|
|
207
|
+
.action-buttons {
|
|
208
|
+
display: flex;
|
|
209
|
+
gap: 1em;
|
|
210
|
+
}
|
|
211
|
+
:global(button.reset.btn-clear) {
|
|
212
|
+
background-color: var(--dg-button-cancel-bg, #808080);
|
|
213
|
+
|
|
214
|
+
}
|
|
215
|
+
:global(button.reset.btn-clear:not([disabled]):hover) {
|
|
216
|
+
background-color: var(--dg-button-cancel-hover-bg, #595959);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.cropper-instructions {
|
|
220
|
+
padding: 0.5em 0;
|
|
221
|
+
}
|
|
222
|
+
|
|
204
223
|
.crop-image-container {
|
|
205
224
|
position: relative;
|
|
206
225
|
user-select: none;
|
|
@@ -5,6 +5,9 @@ import { TAG_API_CONTEXT } from './TagAPI';
|
|
|
5
5
|
export let path;
|
|
6
6
|
export let label;
|
|
7
7
|
export let target;
|
|
8
|
+
export let conditional = undefined;
|
|
9
|
+
export let required = false;
|
|
10
|
+
export let helptext = undefined;
|
|
8
11
|
const tagClient = getContext(TAG_API_CONTEXT);
|
|
9
12
|
let lasttarget = -1;
|
|
10
13
|
let groups = [];
|
|
@@ -33,4 +36,4 @@ async function lookupByValue(id) {
|
|
|
33
36
|
}
|
|
34
37
|
</script>
|
|
35
38
|
|
|
36
|
-
<FieldMultiselect {path} {label} {getOptions} {lookupByValue} />
|
|
39
|
+
<FieldMultiselect {path} {label} {getOptions} {lookupByValue} {conditional} {required} {helptext}/>
|
package/package.json
CHANGED