@dosgato/dialog 1.4.5 → 1.5.0
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/Dialog.svelte +3 -3
- package/dist/FieldAutocomplete.svelte +19 -15
- package/dist/FieldCheckbox.svelte +4 -4
- package/dist/FieldChoices.svelte +11 -7
- package/dist/FieldChooserLink.svelte +30 -32
- package/dist/FieldDate.svelte +3 -3
- package/dist/FieldDateTime.svelte +3 -4
- package/dist/FieldDualListbox.svelte +9 -11
- package/dist/FieldIdentifier.svelte +2 -2
- package/dist/FieldMultiple.svelte +6 -5
- package/dist/FieldMultiselect.svelte +5 -5
- package/dist/FieldNumber.svelte +3 -3
- package/dist/FieldRadio.svelte +3 -7
- package/dist/FieldSelect.svelte +4 -8
- package/dist/FieldStandard.svelte +5 -3
- package/dist/FieldStandard.svelte.d.ts +4 -2
- package/dist/FieldText.svelte +6 -5
- package/dist/FieldText.svelte.d.ts +2 -1
- package/dist/FieldTextArea.svelte +3 -4
- package/dist/FileIcon.svelte +1 -1
- package/dist/Form.svelte +4 -4
- package/dist/FormDialog.svelte +2 -2
- package/dist/Icon.svelte +10 -6
- package/dist/InlineMessage.svelte +3 -3
- package/dist/InlineMessages.svelte +1 -1
- package/dist/Input.svelte +3 -3
- package/dist/Input.svelte.d.ts +2 -1
- package/dist/Listbox.svelte +3 -4
- package/dist/Radio.svelte +0 -1
- package/dist/Switcher.svelte +1 -1
- package/dist/Tabs.svelte +3 -4
- package/dist/Tooltip.svelte +6 -5
- package/dist/chooser/AssetTabs.svelte +19 -17
- package/dist/chooser/AssetTabs.svelte.d.ts +1 -1
- package/dist/chooser/Chooser.svelte +3 -3
- package/dist/chooser/Chooser.svelte.d.ts +5 -5
- package/dist/chooser/ChooserStore.js +2 -2
- package/dist/chooser/UploadUI.svelte +4 -4
- package/dist/code/FieldCodeEditor.svelte +3 -3
- package/dist/code/FieldGraphQLEditor.svelte +28 -0
- package/dist/code/FieldGraphQLEditor.svelte.d.ts +36 -0
- package/dist/code/FieldTypeScriptEditor.svelte +27 -0
- package/dist/code/FieldTypeScriptEditor.svelte.d.ts +34 -0
- package/dist/code/GraphQLEditor.svelte +145 -0
- package/dist/code/GraphQLEditor.svelte.d.ts +35 -0
- package/dist/code/TypeScriptEditor.svelte +186 -0
- package/dist/code/TypeScriptEditor.svelte.d.ts +33 -0
- package/dist/code/index.d.ts +2 -0
- package/dist/code/index.js +2 -0
- package/dist/colorpicker/FieldColorPicker.svelte +2 -2
- package/dist/cropper/FieldCropper.svelte +8 -10
- package/dist/cropper/cropper.js +9 -11
- package/dist/iconpicker/FieldIconPicker.svelte +7 -11
- package/dist/imageposition/FieldImagePosition.svelte +4 -5
- package/dist/imageposition/index.d.ts +1 -1
- package/dist/imageposition/index.js +0 -1
- package/dist/tagpicker/FieldTagPicker.svelte +1 -2
- package/dist/tree/Tree.svelte +2 -3
- package/dist/tree/TreeCell.svelte +2 -2
- package/dist/tree/TreeNode.svelte +16 -17
- package/package.json +14 -7
package/dist/Dialog.svelte
CHANGED
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
export let icon: IconifyIcon | undefined = undefined
|
|
29
29
|
export let size: 'tiny' | 'small' | 'normal' | 'large' | 'xl' = 'normal'
|
|
30
30
|
export let cancelText: string | undefined = undefined
|
|
31
|
-
export let continueText
|
|
31
|
+
export let continueText = 'Ok'
|
|
32
32
|
export let continueIcon: IconifyIcon | undefined = undefined
|
|
33
33
|
export let escapable = isNotBlank(cancelText)
|
|
34
|
-
export let expandable
|
|
34
|
+
export let expandable = false
|
|
35
35
|
export let disabled = false
|
|
36
36
|
export let ignoreTabs = false
|
|
37
37
|
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
let hasRequired: boolean | undefined = false
|
|
46
46
|
let onPrev: (() => void) | undefined
|
|
47
47
|
let onNext: (() => void) | undefined
|
|
48
|
-
let expanded
|
|
48
|
+
let expanded = false
|
|
49
49
|
function onTabChange () {
|
|
50
50
|
({ hasTabs, prevTitle, nextTitle, hasRequired, onPrev, onNext } = ctx)
|
|
51
51
|
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { modifierKey, PopupMenu, ScreenReaderOnly, type PopupMenuItem } from '@txstate-mws/svelte-components'
|
|
3
|
-
import {
|
|
3
|
+
import { FORM_CONTEXT, FORM_INHERITED_PATH, type FormStore } from '@txstate-mws/svelte-forms'
|
|
4
4
|
import { isBlank, isNotBlank, randomid } from 'txstate-utils'
|
|
5
5
|
import { getDescribedBy } from './'
|
|
6
6
|
import FieldStandard from './FieldStandard.svelte'
|
|
7
|
+
import { getContext } from 'svelte'
|
|
7
8
|
|
|
8
9
|
export let id: string | undefined = undefined
|
|
9
10
|
export let path: string
|
|
10
|
-
export let label
|
|
11
|
+
export let label = ''
|
|
11
12
|
export let placeholder: string = 'Select' + (label ? ' ' + label : '')
|
|
12
13
|
let className = ''
|
|
13
14
|
export { className as class }
|
|
@@ -27,19 +28,21 @@
|
|
|
27
28
|
let menuid: string
|
|
28
29
|
|
|
29
30
|
const liveTextId = randomid()
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
let finalDeserialize: (value: string) => any
|
|
32
|
+
|
|
33
|
+
const store = getContext<FormStore>(FORM_CONTEXT)
|
|
34
|
+
const inheritedPath = getContext<string>(FORM_INHERITED_PATH)
|
|
35
|
+
const finalPath = [inheritedPath, path].filter(isNotBlank).join('.')
|
|
36
|
+
const val = store.getField<string>(finalPath)
|
|
32
37
|
|
|
33
38
|
$: valueToLabel = Object.fromEntries(choices.map(c => [c.value, c.label || c.value]))
|
|
34
39
|
$: labelToValue = Object.fromEntries(choices.map(c => [c.label || c.value, c.value]))
|
|
35
|
-
$: filteredChoices = choices.filter((item: PopupMenuItem) =>
|
|
36
|
-
return item.label?.toLowerCase().includes(inputvalue.toLowerCase()) || item.value.toLowerCase().includes(inputvalue.toLowerCase())
|
|
37
|
-
})
|
|
40
|
+
$: filteredChoices = choices.filter((item: PopupMenuItem) => item.label?.toLowerCase().includes(inputvalue.toLowerCase()) || item.value.toLowerCase().includes(inputvalue.toLowerCase()))
|
|
38
41
|
|
|
39
42
|
let menushown = false
|
|
40
43
|
let savedVal = defaultValue
|
|
41
44
|
function onKeyUp (setVal: any) {
|
|
42
|
-
return
|
|
45
|
+
return e => {
|
|
43
46
|
if (!modifierKey(e)) {
|
|
44
47
|
const val = labelToValue[inputvalue.trim()]
|
|
45
48
|
menushown = !val
|
|
@@ -55,7 +58,7 @@
|
|
|
55
58
|
}
|
|
56
59
|
|
|
57
60
|
function onchangepopup (setVal: any) {
|
|
58
|
-
return
|
|
61
|
+
return e => {
|
|
59
62
|
inputvalue = e.detail.label || e.detail.value
|
|
60
63
|
popupvalue = undefined
|
|
61
64
|
savedVal = e.detail.value
|
|
@@ -63,8 +66,9 @@
|
|
|
63
66
|
}
|
|
64
67
|
}
|
|
65
68
|
|
|
66
|
-
function reactToValue (value: string
|
|
67
|
-
|
|
69
|
+
async function reactToValue (value: string) {
|
|
70
|
+
if (!finalDeserialize) return
|
|
71
|
+
const dsvalue = finalDeserialize(value)
|
|
68
72
|
if (dsvalue !== savedVal) {
|
|
69
73
|
const label = valueToLabel[dsvalue]
|
|
70
74
|
|
|
@@ -77,14 +81,14 @@
|
|
|
77
81
|
|
|
78
82
|
savedVal = dsvalue
|
|
79
83
|
// if the form state value changes from the outside to an invalid value, we have to clear it out
|
|
80
|
-
if (isNotBlank(dsvalue) && isBlank(label))
|
|
84
|
+
if (isNotBlank(dsvalue) && isBlank(label)) await store.setField(finalPath, finalDeserialize(''), { notDirty: true })
|
|
81
85
|
}
|
|
82
86
|
}
|
|
87
|
+
$: reactToValue($val).catch(console.error)
|
|
83
88
|
</script>
|
|
84
89
|
|
|
85
|
-
<FieldStandard bind:id {label} {path} {required} {defaultValue} {conditional} {related} {helptext}
|
|
86
|
-
{
|
|
87
|
-
<input bind:this={inputelement} bind:value={inputvalue} {id} {placeholder} class="dialog-input {className}" class:valid class:invalid aria-invalid={invalid} aria-expanded={false} aria-controls={menuid} on:blur={onBlur} on:keyup={onKeyUp(setVal)} autocapitalize="none" type="text" autocomplete="off" aria-autocomplete="list" role="combobox" {disabled} aria-describedby={getDescribedBy([messagesid, helptextid, extradescid])}>
|
|
90
|
+
<FieldStandard bind:id {label} {path} {required} {defaultValue} {conditional} {related} {helptext} {notNull} bind:finalDeserialize let:setVal let:valid let:invalid let:id={fieldid} let:onBlur let:messagesid let:helptextid>
|
|
91
|
+
<input bind:this={inputelement} bind:value={inputvalue} id={fieldid} {placeholder} class="dialog-input {className}" class:valid class:invalid aria-invalid={invalid} aria-expanded={false} aria-controls={menuid} on:blur={onBlur} on:keyup={onKeyUp(setVal)} autocapitalize="none" type="text" autocomplete="off" aria-autocomplete="list" role="combobox" {disabled} aria-describedby={getDescribedBy([messagesid, helptextid, extradescid])}>
|
|
88
92
|
<PopupMenu bind:menushown bind:menuid align="bottomleft" items={filteredChoices} buttonelement={inputelement} bind:value={popupvalue} on:change={onchangepopup(setVal)} emptyText="No options available"/>
|
|
89
93
|
<ScreenReaderOnly arialive="polite" ariaatomic={true} id={liveTextId}>
|
|
90
94
|
{filteredChoices.length} {filteredChoices.length === 1 ? 'option' : 'options'} available.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
export { className as class }
|
|
8
8
|
export let id: string | undefined = undefined
|
|
9
9
|
export let path: string
|
|
10
|
-
export let label
|
|
10
|
+
export let label = ''
|
|
11
11
|
export let boxLabel: string
|
|
12
12
|
export let defaultValue: boolean | undefined = undefined
|
|
13
13
|
export let conditional: boolean | undefined = undefined
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
const descid = randomid()
|
|
27
27
|
</script>
|
|
28
28
|
|
|
29
|
-
<FieldStandard bind:id {path} {descid} {label} {defaultValue} {conditional} {related} {helptext} {required} let:value let:messagesid let:helptextid let:valid let:invalid let:id let:onBlur let:setVal>
|
|
29
|
+
<FieldStandard bind:id {path} {descid} {label} {defaultValue} {conditional} {related} {helptext} {required} let:value let:messagesid let:helptextid let:valid let:invalid let:id={fieldid} let:onBlur let:setVal>
|
|
30
30
|
<div class={className}>
|
|
31
|
-
<label for={
|
|
32
|
-
<Checkbox bind:inputelement {
|
|
31
|
+
<label for={fieldid}>
|
|
32
|
+
<Checkbox bind:inputelement id={fieldid} name={path} {value} descid={getDescribedBy([descid, messagesid, helptextid, extradescid])} {valid} {invalid} {onBlur} onChange={onChange(setVal)}></Checkbox>
|
|
33
33
|
<span>{boxLabel}</span>
|
|
34
34
|
</label>
|
|
35
35
|
</div>
|
package/dist/FieldChoices.svelte
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
export { className as class }
|
|
19
19
|
export let id: string | undefined = undefined
|
|
20
20
|
export let path: string
|
|
21
|
-
export let label
|
|
21
|
+
export let label = ''
|
|
22
22
|
export let choices: { label?: string, value: any, disabled?: boolean }[]
|
|
23
23
|
export let defaultValue: any = []
|
|
24
24
|
export let conditional: boolean | undefined = undefined
|
|
@@ -27,12 +27,12 @@
|
|
|
27
27
|
export let related: true | number = 0
|
|
28
28
|
export let extradescid: string | undefined = undefined
|
|
29
29
|
export let helptext: string | undefined = undefined
|
|
30
|
-
export let selectAll
|
|
30
|
+
export let selectAll = false
|
|
31
31
|
|
|
32
32
|
const store = getContext<FormStore>(FORM_CONTEXT)
|
|
33
33
|
const inheritedPath = getContext<string>(FORM_INHERITED_PATH)
|
|
34
34
|
const finalPath = [inheritedPath, path].filter(isNotBlank).join('.')
|
|
35
|
-
const
|
|
35
|
+
const val = store.getField<any[]>(finalPath)
|
|
36
36
|
const currentWidth = derivedStore(store, 'width')
|
|
37
37
|
$: cols = Math.min(Math.ceil($currentWidth / maxwidth), choices.length)
|
|
38
38
|
|
|
@@ -53,7 +53,11 @@
|
|
|
53
53
|
})
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
let selected = new Set<any>()
|
|
57
|
+
function reactToValue (value: any[]) {
|
|
58
|
+
selected = new Set(value ?? [])
|
|
59
|
+
}
|
|
60
|
+
$: reactToValue($val)
|
|
57
61
|
|
|
58
62
|
let selectAllElement: HTMLInputElement | undefined
|
|
59
63
|
const selectAllId = randomid()
|
|
@@ -83,8 +87,8 @@
|
|
|
83
87
|
onMount(reactToChoices)
|
|
84
88
|
</script>
|
|
85
89
|
|
|
86
|
-
<Field {path} {defaultValue} {conditional} let:path let:value let:onBlur let:setVal let:messages let:valid let:invalid serialize={arraySerialize}>
|
|
87
|
-
<Container {
|
|
90
|
+
<Field {path} {defaultValue} {conditional} let:path={fullpath} let:value let:onBlur let:setVal let:messages let:valid let:invalid serialize={arraySerialize}>
|
|
91
|
+
<Container path={fullpath} {id} {label} {messages} {descid} {related} {helptext} let:messagesid let:helptextid>
|
|
88
92
|
<div class="dialog-choices {className}" class:valid class:invalid>
|
|
89
93
|
{#if selectAll}
|
|
90
94
|
<label for={selectAllId} style:width>
|
|
@@ -93,7 +97,7 @@
|
|
|
93
97
|
</label>
|
|
94
98
|
{/if}
|
|
95
99
|
{#each choices as choice, idx (choice.value)}
|
|
96
|
-
{@const checkid = `${
|
|
100
|
+
{@const checkid = `${fullpath}.${idx}`}
|
|
97
101
|
{@const included = value?.includes(choice.value)}
|
|
98
102
|
{@const label = choice.label || (typeof choice.value === 'string' ? choice.value : '')}
|
|
99
103
|
<label for={checkid} style:width style:order={orders[idx]}>
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
export let id: string | undefined = undefined
|
|
16
16
|
export let path: string
|
|
17
|
-
export let label
|
|
17
|
+
export let label = ''
|
|
18
18
|
export let defaultValue: boolean | undefined = undefined
|
|
19
19
|
export let conditional: boolean | undefined = undefined
|
|
20
20
|
export let required = false
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
export let extradescid: string | undefined = undefined
|
|
30
30
|
export let helptext: string | undefined = undefined
|
|
31
31
|
export let selectedAsset: AnyItem | RawURL | BrokenURL | undefined = undefined
|
|
32
|
-
export let altTextPath
|
|
33
|
-
export let altTextRequired
|
|
34
|
-
export let altTextHelp
|
|
32
|
+
export let altTextPath: string | undefined = undefined
|
|
33
|
+
export let altTextRequired = false
|
|
34
|
+
export let altTextHelp = 'Describes the asset for visually-impaired users and search engines.'
|
|
35
35
|
|
|
36
36
|
// TODO: add a mime type acceptance prop, maybe a regex or function, to prevent users from
|
|
37
37
|
// choosing unacceptable mime types
|
|
@@ -56,13 +56,13 @@
|
|
|
56
56
|
modalshown = false
|
|
57
57
|
}
|
|
58
58
|
function onChange (setVal: any) {
|
|
59
|
-
return
|
|
59
|
+
return e => {
|
|
60
60
|
selectedAsset = e.detail.preview
|
|
61
61
|
if (
|
|
62
|
-
finalAltTextPath
|
|
63
|
-
e.detail.copyAltText
|
|
64
|
-
selectedAsset?.type === 'asset'
|
|
65
|
-
selectedAsset?.image?.altText
|
|
62
|
+
finalAltTextPath
|
|
63
|
+
&& e.detail.copyAltText
|
|
64
|
+
&& selectedAsset?.type === 'asset'
|
|
65
|
+
&& selectedAsset?.image?.altText
|
|
66
66
|
) {
|
|
67
67
|
formStore.setField(finalAltTextPath, selectedAsset.image.altText).catch(console.error)
|
|
68
68
|
}
|
|
@@ -98,10 +98,10 @@
|
|
|
98
98
|
if (item) {
|
|
99
99
|
found = true
|
|
100
100
|
if (
|
|
101
|
-
(item.type === 'page' && !pages)
|
|
102
|
-
(item.type === 'folder' && !folders)
|
|
103
|
-
(item.type === 'asset' && !assets)
|
|
104
|
-
(item.type === 'asset' && !item.image && images) // they typed the URL for a non-image asset but we only want images
|
|
101
|
+
(item.type === 'page' && !pages) // they typed the URL for a page but we don't allow pages right now
|
|
102
|
+
|| (item.type === 'folder' && !folders) // they typed the URL for an asset folder but not allowed
|
|
103
|
+
|| (item.type === 'asset' && !assets) // they typed the URL for an asset but not allowed
|
|
104
|
+
|| (item.type === 'asset' && !item.image && images) // they typed the URL for a non-image asset but we only want images
|
|
105
105
|
) {
|
|
106
106
|
// they entered something that is recognized but not allowed
|
|
107
107
|
// they can keep the typing they've done, but the id must be 'undefined' so that nothing
|
|
@@ -119,18 +119,16 @@
|
|
|
119
119
|
if (!found) {
|
|
120
120
|
if (urlToValueCache[url]) {
|
|
121
121
|
selectedAsset = { type: 'raw', id: urlToValueCache[url], url }
|
|
122
|
-
} else {
|
|
123
|
-
if (isBlank(cleanedUrl) || cleanedUrl.startsWith('/')) {
|
|
122
|
+
} else if (isBlank(cleanedUrl) || cleanedUrl.startsWith('/')) {
|
|
124
123
|
// here we "select" a raw url so that we do not interrupt the users' typing, but
|
|
125
124
|
// we set its id to 'undefined' so that nothing makes it into the form until it's
|
|
126
125
|
// a valid URL
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
126
|
+
selectedAsset = { type: 'raw', id: undefined, url }
|
|
127
|
+
} else {
|
|
128
|
+
selectedAsset = {
|
|
129
|
+
type: 'raw',
|
|
130
|
+
id: chooserClient.urlToValue?.(cleanedUrl) ?? cleanedUrl,
|
|
131
|
+
url
|
|
134
132
|
}
|
|
135
133
|
}
|
|
136
134
|
}
|
|
@@ -174,17 +172,17 @@
|
|
|
174
172
|
}
|
|
175
173
|
$: void updateSelected($value)
|
|
176
174
|
function onClickRemove (setVal: any) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
175
|
+
return e => {
|
|
176
|
+
selectedAsset = undefined
|
|
177
|
+
setVal(undefined)
|
|
178
|
+
if (finalAltTextPath) {
|
|
179
|
+
formStore.setField(finalAltTextPath, undefined).catch(console.error)
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
185
183
|
</script>
|
|
186
184
|
|
|
187
|
-
<FieldStandard bind:id {path} {descid} {label} {defaultValue} {conditional} {required} {related} {helptext} let:value let:messagesid let:helptextid let:valid let:invalid let:id let:onBlur let:setVal>
|
|
185
|
+
<FieldStandard bind:id {path} {descid} {label} {defaultValue} {conditional} {required} {related} {helptext} let:value let:messagesid let:helptextid let:valid let:invalid let:id={fieldid} let:onBlur let:setVal>
|
|
188
186
|
{#if selectedAsset?.id}
|
|
189
187
|
{#if selectedAsset?.type === 'asset'}
|
|
190
188
|
<div class="asset-chooser-container">
|
|
@@ -237,7 +235,7 @@
|
|
|
237
235
|
<div class="dialog-chooser-entry">
|
|
238
236
|
{#if urlEntry}
|
|
239
237
|
<div class="dialog-chooser-entry-input">
|
|
240
|
-
<input bind:this={urlEntryInput} {
|
|
238
|
+
<input bind:this={urlEntryInput} id={fieldid} type="text" data-lpignore="true" value={selectedAsset?.url ?? ''} on:change={userUrlEntry} on:input={userUrlEntry} on:blur={onBlur}>
|
|
241
239
|
<button type="button" on:click={clearUrlEntry}><Icon icon={xCircle} hiddenLabel="clear input" inline/></button>
|
|
242
240
|
</div>
|
|
243
241
|
{/if}
|
package/dist/FieldDate.svelte
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
export { className as class }
|
|
7
7
|
export let id: string | undefined = undefined
|
|
8
8
|
export let path: string
|
|
9
|
-
export let label
|
|
9
|
+
export let label = ''
|
|
10
10
|
export let defaultValue: any = undefined
|
|
11
11
|
export let min: Date | { toJSDate: () => Date } | undefined = undefined
|
|
12
12
|
export let max: Date | { toJSDate: () => Date } | undefined = undefined
|
|
@@ -19,6 +19,6 @@
|
|
|
19
19
|
export let helptext: string | undefined = undefined
|
|
20
20
|
</script>
|
|
21
21
|
|
|
22
|
-
<FieldStandard bind:id {label} {path} {required} {defaultValue} {conditional} {related} {helptext} serialize={dateSerialize} deserialize={dateDeserialize} let:value let:valid let:invalid let:id let:onBlur let:onChange let:messagesid let:helptextid>
|
|
23
|
-
<Input bind:inputelement type="date" name={path} {value} {
|
|
22
|
+
<FieldStandard bind:id {label} {path} {required} {defaultValue} {conditional} {related} {helptext} serialize={dateSerialize} deserialize={dateDeserialize} let:value let:valid let:invalid let:id={fieldid} let:onBlur let:onChange let:messagesid let:helptextid>
|
|
23
|
+
<Input bind:inputelement type="date" name={path} {value} id={fieldid} class="dialog-input {className}" {onChange} {onBlur} {valid} {invalid} {min} {max} {step} {extradescid} {messagesid} {helptextid}/>
|
|
24
24
|
</FieldStandard>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
export { className as class }
|
|
8
8
|
export let id: string | undefined = undefined
|
|
9
9
|
export let path: string
|
|
10
|
-
export let label
|
|
10
|
+
export let label = ''
|
|
11
11
|
export let defaultValue: any = undefined
|
|
12
12
|
export let min: Date | { toJSDate: () => Date } | undefined = undefined
|
|
13
13
|
export let max: Date | { toJSDate: () => Date } | undefined = undefined
|
|
@@ -38,7 +38,6 @@
|
|
|
38
38
|
}
|
|
39
39
|
</script>
|
|
40
40
|
|
|
41
|
-
<FieldStandard bind:id {label} {path} {required} {defaultValue} {conditional} {related} {helptext} serialize={datetimeSerialize} deserialize={datetimeDeserialize} let:value let:valid let:invalid let:id let:onBlur let:helptextid let:messagesid let:setVal>
|
|
42
|
-
<Input bind:inputelement={inputelement} type="datetime-local" name={path} {value} {
|
|
41
|
+
<FieldStandard bind:id {label} {path} {required} {defaultValue} {conditional} {related} {helptext} serialize={datetimeSerialize} deserialize={datetimeDeserialize} let:value let:valid let:invalid let:id={fieldid} let:onBlur let:helptextid let:messagesid let:setVal>
|
|
42
|
+
<Input bind:inputelement={inputelement} type="datetime-local" name={path} {value} id={fieldid} class="dialog-input {className}" {onBlur} onChange={onChange(setVal)} {valid} {invalid} {min} {max} {step} {extradescid} {messagesid} {helptextid}/>
|
|
43
43
|
</FieldStandard>
|
|
44
|
-
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
|
|
12
12
|
export let id: string | undefined = undefined
|
|
13
13
|
export let path: string
|
|
14
|
-
export let label
|
|
15
|
-
export let sourceLabel
|
|
16
|
-
export let selectedLabel
|
|
17
|
-
export let multiselect
|
|
14
|
+
export let label = ''
|
|
15
|
+
export let sourceLabel = 'Available'
|
|
16
|
+
export let selectedLabel = 'Selected'
|
|
17
|
+
export let multiselect = false
|
|
18
18
|
export let choices: PopupMenuItem[]
|
|
19
19
|
export let defaultValue: string[] = []
|
|
20
20
|
export let conditional: boolean | undefined = undefined
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
let itemsToAdd: PopupMenuItem[] = [] // the items selected in the left listbox
|
|
27
27
|
let itemsToRemove: PopupMenuItem[] = [] // the items selected in the right listbox
|
|
28
|
-
let instructions
|
|
28
|
+
let instructions = ''
|
|
29
29
|
|
|
30
30
|
$: {
|
|
31
31
|
if (itemsToAdd.length === 1) instructions = `Press right arrow key to move selected ${sourceLabel} items to ${selectedLabel} items list.`
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
function onkeydown (value: string[], setVal: (val: any) => void) {
|
|
74
|
-
return
|
|
74
|
+
return e => {
|
|
75
75
|
if (modifierKey(e)) return
|
|
76
76
|
if (e.key === 'ArrowRight') {
|
|
77
77
|
e.preventDefault()
|
|
@@ -86,12 +86,10 @@
|
|
|
86
86
|
}
|
|
87
87
|
</script>
|
|
88
88
|
|
|
89
|
-
<FieldStandard bind:id {label} {path} {required} {defaultValue} {conditional} {descid} {related} {helptext} let:value let:valid let:invalid let:id let:onBlur let:setVal let:helptextid let:messagesid serialize={arraySerialize}>
|
|
89
|
+
<FieldStandard bind:id {label} {path} {required} {defaultValue} {conditional} {descid} {related} {helptext} let:value let:valid let:invalid let:id={fieldid} let:onBlur let:setVal let:helptextid let:messagesid serialize={arraySerialize}>
|
|
90
90
|
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
|
|
91
|
-
<div {
|
|
92
|
-
<ScreenReaderOnly>
|
|
93
|
-
<span aria-live="polite">{instructions}</span>
|
|
94
|
-
</ScreenReaderOnly>
|
|
91
|
+
<div id={fieldid} role="group" class="dual-list-container" on:keydown={onkeydown(value, setVal)}>
|
|
92
|
+
<ScreenReaderOnly arialive="polite">{instructions}</ScreenReaderOnly>
|
|
95
93
|
<Listbox label={sourceLabel} multiselect={multiselect} items={getAvailable(value)} descid={getDescribedBy([descid, messagesid, helptextid, extradescid])} {valid} {invalid} on:change={e => { itemsToAdd = e.detail }} selected={itemsToAdd} on:blur={onBlur}/>
|
|
96
94
|
<div class="toolbar">
|
|
97
95
|
<button type="button" class="toolbar-button" title="Move selection to {selectedLabel}" disabled={itemsToAdd.length === 0} on:click={addToSelected(value, setVal)}>
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
export let path: string
|
|
7
7
|
export let conditional: boolean | undefined = undefined
|
|
8
|
-
export let length
|
|
8
|
+
export let length = 10
|
|
9
9
|
|
|
10
10
|
const store = getContext<FormStore>(FORM_CONTEXT)
|
|
11
11
|
const inheritedPath = getContext<string>(FORM_INHERITED_PATH)
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
const valueStore = store.getField<string | null>(finalPath)
|
|
14
14
|
|
|
15
15
|
onMount(() => {
|
|
16
|
-
if (!$valueStore) store.setField(finalPath, randomid(length), { notDirty: true })
|
|
16
|
+
if (!$valueStore) void store.setField(finalPath, randomid(length), { notDirty: true })
|
|
17
17
|
})
|
|
18
18
|
</script>
|
|
19
19
|
|
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
import xCircle from '@iconify-icons/ph/x-circle-fill'
|
|
10
10
|
import { AddMore, type Feedback } from '@txstate-mws/svelte-forms'
|
|
11
11
|
import { setContext } from 'svelte'
|
|
12
|
-
import { writable } from 'svelte/store'
|
|
13
12
|
import Button from './Button.svelte'
|
|
14
13
|
import Container from './Container.svelte'
|
|
15
14
|
import Icon from './Icon.svelte'
|
|
16
15
|
|
|
17
16
|
export let path: string
|
|
18
17
|
export let label: string
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents -- it's weird but helps with understanding
|
|
19
19
|
export let initialState: any | ((index: number) => any) = undefined
|
|
20
20
|
export let minLength = 1
|
|
21
21
|
export let maxLength: number | undefined = undefined
|
|
@@ -65,8 +65,9 @@
|
|
|
65
65
|
|
|
66
66
|
function confirmedDelete (onDelete: () => void, item: any) {
|
|
67
67
|
return () => {
|
|
68
|
-
if (confirmDelete == null)
|
|
68
|
+
if (confirmDelete == null) { onDelete(); return }
|
|
69
69
|
const msg = typeof confirmDelete === 'string' ? confirmDelete : confirmDelete(item)
|
|
70
|
+
// eslint-disable-next-line no-alert -- I don't have a better way to do this at the moment
|
|
70
71
|
if (confirm(msg)) onDelete()
|
|
71
72
|
}
|
|
72
73
|
}
|
|
@@ -76,12 +77,12 @@
|
|
|
76
77
|
|
|
77
78
|
<Container {path} {label} {messages} {conditional} {related} {helptext} let:helptextid>
|
|
78
79
|
{noOp(fieldMultipleContext.helptextid = helptextid)}
|
|
79
|
-
<AddMore bind:messages {path} {initialState} {minLength} {maxLength} {conditional} let:path let:currentLength let:maxLength let:index let:minned let:maxed let:value let:onDelete let:onMoveUp let:onMoveDown>
|
|
80
|
+
<AddMore bind:messages {path} {initialState} {minLength} {maxLength} {conditional} let:path={fullpath} let:currentLength let:maxLength={resolvedMaxLength} let:index let:minned let:maxed let:value let:onDelete let:onMoveUp let:onMoveDown>
|
|
80
81
|
{@const showDelete = removable && !minned}
|
|
81
82
|
{@const showMove = reorder && currentLength > 1}
|
|
82
83
|
<div class="dialog-multiple" class:has-delete-icon={showDelete} class:has-move-icon={showMove} class:first={index === 0}>
|
|
83
84
|
<div class="dialog-multiple-content">
|
|
84
|
-
<slot {
|
|
85
|
+
<slot path={fullpath} {index} {value} {maxed} maxLength={resolvedMaxLength} {currentLength}/>
|
|
85
86
|
</div>
|
|
86
87
|
{#if showDelete || showMove}<div class="dialog-multiple-buttons">
|
|
87
88
|
{#if showMove}
|
|
@@ -92,7 +93,7 @@
|
|
|
92
93
|
</div>{/if}
|
|
93
94
|
</div>
|
|
94
95
|
<svelte:fragment slot="addbutton" let:maxed let:onClick>
|
|
95
|
-
{#if !maxed || (maxed &&
|
|
96
|
+
{#if !maxed || (maxed && resolvedMaxLength > 1)}
|
|
96
97
|
<Button type="button" icon={plusCircleLight} class="{addMoreClass} dialog-multiple-button" disabled={maxed} on:click={onClick}>{maxed ? maxedText : addMoreText}</Button>
|
|
97
98
|
{/if}
|
|
98
99
|
</svelte:fragment>
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
`PopupMenuItem[]` by `getOptions`. */
|
|
25
25
|
export let getOptions: (search: string) => Promise<PopupMenuItem[]>
|
|
26
26
|
export let id: string | undefined = undefined
|
|
27
|
-
export let label
|
|
27
|
+
export let label = ''
|
|
28
28
|
/** Text to display in the text input when it's empty. */
|
|
29
29
|
export let placeholder = ''
|
|
30
30
|
/** When there are no items (e.g. it's a filtered search and there were no results), we still display one
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
export let required = false
|
|
37
37
|
/** Max number of selections to be allowed before disabling the input - 0 for unlimited. */
|
|
38
38
|
export let maxSelections = 0
|
|
39
|
-
export let lookupByValue: (val: string) => Promise<PopupMenuItem | undefined> = async
|
|
39
|
+
export let lookupByValue: (val: string) => Promise<PopupMenuItem | undefined> = async val => { const options = await getOptions(val); return options.find(opt => opt.value === val) }
|
|
40
40
|
export let related: true | number = 0
|
|
41
41
|
export let extradescid: string | undefined = undefined
|
|
42
42
|
export let helptext: string | undefined = undefined
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
/** Show a confirmation message before clearing all selections */
|
|
51
51
|
export let confirmDelete: string | undefined = undefined
|
|
52
52
|
|
|
53
|
-
export let selectedItemLabel: ((item: PopupMenuItem) => string) | undefined =
|
|
53
|
+
export let selectedItemLabel: ((item: PopupMenuItem) => string) | undefined = item => item.label || item.value
|
|
54
54
|
|
|
55
55
|
/** Each time we run getOptions we will save the value -> label mappings that it finds, so that we can display labels on pills. */
|
|
56
56
|
const valueToLabel: Record<string, string> = {}
|
|
@@ -96,10 +96,10 @@
|
|
|
96
96
|
|
|
97
97
|
<div bind:this={inputelement}></div>
|
|
98
98
|
{#if hasInit}
|
|
99
|
-
<FieldStandard bind:id {label} {path} {required} {defaultValue} {conditional} {related} {helptext} let:value let:valid let:invalid let:id let:onBlur let:setVal let:messagesid let:helptextid serialize={arraySerialize}>
|
|
99
|
+
<FieldStandard bind:id {label} {path} {required} {defaultValue} {conditional} {related} {helptext} let:value let:valid let:invalid let:id={fieldid} let:onBlur let:setVal let:messagesid let:helptextid serialize={arraySerialize}>
|
|
100
100
|
{@const _ = reactToValue(value)}
|
|
101
101
|
<div class:valid class:invalid>
|
|
102
|
-
<MultiSelect {
|
|
102
|
+
<MultiSelect id={fieldid} name={path} descid={getDescribedBy([messagesid, helptextid, extradescid])}
|
|
103
103
|
{disabled} {maxSelections} selected={$selectedStore} {placeholder} {emptyText} getOptions={wrapGetOptions}
|
|
104
104
|
inputClass='multiselect-input'
|
|
105
105
|
on:change={e => setVal(e.detail.map(itm => itm.value))} on:blur={onBlur}
|
package/dist/FieldNumber.svelte
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
export { className as class }
|
|
7
7
|
export let id: string | undefined = undefined
|
|
8
8
|
export let path: string
|
|
9
|
-
export let label
|
|
9
|
+
export let label = ''
|
|
10
10
|
export let defaultValue: number | undefined = undefined
|
|
11
11
|
export let nullable = false
|
|
12
12
|
export let min: number | undefined = undefined
|
|
@@ -20,6 +20,6 @@
|
|
|
20
20
|
export let helptext: string | undefined = undefined
|
|
21
21
|
</script>
|
|
22
22
|
|
|
23
|
-
<FieldStandard bind:id {label} {path} {required} {defaultValue} {conditional} {related} {helptext} serialize={numberSerialize} deserialize={nullable ? numberNullableDeserialize : numberDeserialize} let:value let:valid let:invalid let:id let:onBlur let:onChange let:helptextid>
|
|
24
|
-
<Input bind:inputelement type="number" name={path} {value} {
|
|
23
|
+
<FieldStandard bind:id {label} {path} {required} {defaultValue} {conditional} {related} {helptext} serialize={numberSerialize} deserialize={nullable ? numberNullableDeserialize : numberDeserialize} let:value let:valid let:invalid let:id={fieldid} let:onBlur let:onChange let:helptextid>
|
|
24
|
+
<Input bind:inputelement type="number" name={path} {value} id={fieldid} class="dialog-input {className}" {onChange} {onBlur} {valid} {invalid} {min} {max} {step} {helptextid} {extradescid}></Input>
|
|
25
25
|
</FieldStandard>
|
package/dist/FieldRadio.svelte
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
export { className as class }
|
|
8
8
|
export let id: string | undefined = undefined
|
|
9
9
|
export let path: string
|
|
10
|
-
export let label
|
|
10
|
+
export let label = ''
|
|
11
11
|
export let notNull = false
|
|
12
12
|
export let choices: { label?: string, value: any, disabled?: boolean }[]
|
|
13
13
|
export let defaultValue: any = notNull ? choices[0].value : undefined
|
|
@@ -29,9 +29,6 @@
|
|
|
29
29
|
const finalPath = [inheritedPath, path].filter(isNotBlank).join('.')
|
|
30
30
|
|
|
31
31
|
let finalDeserialize: (value: string) => any
|
|
32
|
-
function updateDeserialize (fDes: any) {
|
|
33
|
-
finalDeserialize = fDes
|
|
34
|
-
}
|
|
35
32
|
async function reactToChoices (..._: any[]) {
|
|
36
33
|
if (!finalDeserialize) return
|
|
37
34
|
if (!choices.length) {
|
|
@@ -44,7 +41,6 @@
|
|
|
44
41
|
onMount(reactToChoices)
|
|
45
42
|
</script>
|
|
46
43
|
|
|
47
|
-
<Field {path} {defaultValue} {conditional} {notNull} {number} {date} {datetime} {boolean} {serialize} {deserialize} let:value let:valid let:invalid let:onBlur let:onChange let:messages
|
|
48
|
-
{
|
|
49
|
-
<Switcher bind:id {path} class={className} name={finalPath} {horizontal} {label} iptValue={value} {valid} {invalid} {required} {related} {extradescid} {helptext} {messages} on:change={onChange} {onBlur} choices={choices.map(c => ({ ...c, value: serialize(c.value) }))} />
|
|
44
|
+
<Field {path} {defaultValue} {conditional} {notNull} {number} {date} {datetime} {boolean} {serialize} {deserialize} bind:finalDeserialize let:serialize={finalSerialize} let:value let:valid let:invalid let:onBlur let:onChange let:messages>
|
|
45
|
+
<Switcher bind:id {path} class={className} name={finalPath} {horizontal} {label} iptValue={value} {valid} {invalid} {required} {related} {extradescid} {helptext} {messages} on:change={onChange} {onBlur} choices={choices.map(c => ({ ...c, value: finalSerialize(c.value) }))} />
|
|
50
46
|
</Field>
|
package/dist/FieldSelect.svelte
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
export { className as class }
|
|
9
9
|
export let id: string | undefined = undefined
|
|
10
10
|
export let path: string
|
|
11
|
-
export let label
|
|
11
|
+
export let label = ''
|
|
12
12
|
export let placeholder: string = 'Select' + (label ? ' ' + label : '')
|
|
13
13
|
export let notNull = false
|
|
14
14
|
export let disabled = false
|
|
@@ -32,9 +32,6 @@
|
|
|
32
32
|
const finalPath = [inheritedPath, path].filter(isNotBlank).join('.')
|
|
33
33
|
|
|
34
34
|
let finalDeserialize: (value: string) => any
|
|
35
|
-
function updateDeserialize (fDes: any) {
|
|
36
|
-
finalDeserialize = fDes
|
|
37
|
-
}
|
|
38
35
|
async function reactToChoices (..._: any[]) {
|
|
39
36
|
if (!finalDeserialize) return
|
|
40
37
|
if (!choices.length) {
|
|
@@ -47,12 +44,11 @@
|
|
|
47
44
|
onMount(reactToChoices)
|
|
48
45
|
</script>
|
|
49
46
|
|
|
50
|
-
<FieldStandard bind:id {label} {path} {required} {defaultValue} {conditional} {related} {helptext} {notNull} {number} {date} {datetime} {boolean} {serialize} {deserialize} let:value let:valid let:invalid let:id let:onBlur let:onChange let:messagesid let:helptextid
|
|
51
|
-
{
|
|
52
|
-
<select bind:this={inputelement} {id} name={path} {disabled} class="dialog-input dialog-select {className}" on:change={onChange} on:blur={onBlur} class:valid class:invalid aria-describedby={getDescribedBy([messagesid, helptextid, extradescid])}>
|
|
47
|
+
<FieldStandard bind:id {label} {path} {required} {defaultValue} {conditional} {related} {helptext} {notNull} {number} {date} {datetime} {boolean} {serialize} {deserialize} bind:finalDeserialize let:serialize={finalSerialize} let:value let:valid let:invalid let:id={fieldid} let:onBlur let:onChange let:messagesid let:helptextid>
|
|
48
|
+
<select bind:this={inputelement} id={fieldid} name={path} {disabled} class="dialog-input dialog-select {className}" on:change={onChange} on:blur={onBlur} class:valid class:invalid aria-describedby={getDescribedBy([messagesid, helptextid, extradescid])}>
|
|
53
49
|
{#if !notNull}<option value="" selected={!value}>{placeholder}</option>{/if}
|
|
54
50
|
{#each choices as choice (choice.value)}
|
|
55
|
-
{@const serializedValue =
|
|
51
|
+
{@const serializedValue = finalSerialize?.(choice.value)}
|
|
56
52
|
<option value={serializedValue} disabled={choice.disabled} selected={value === serializedValue}>{choice.label || serializedValue}</option>
|
|
57
53
|
{/each}
|
|
58
54
|
</select>
|
|
@@ -34,10 +34,12 @@
|
|
|
34
34
|
export let required = false
|
|
35
35
|
export let related: true | number = 0
|
|
36
36
|
export let helptext: string | undefined = undefined
|
|
37
|
+
export let finalSerialize: ((value: any) => string) | undefined = undefined
|
|
38
|
+
export let finalDeserialize: ((value: string) => any) | undefined = undefined
|
|
37
39
|
</script>
|
|
38
40
|
|
|
39
|
-
<Field {path} {defaultValue} {conditional} {notNull} {number} {date} {datetime} {boolean} {serialize} {deserialize} {initialize} {finalize} let:path let:value let:onBlur let:onChange let:setVal let:messages let:valid let:invalid
|
|
40
|
-
<Container {
|
|
41
|
-
<slot {id} {
|
|
41
|
+
<Field {path} {defaultValue} {conditional} {notNull} {number} {date} {datetime} {boolean} {serialize} {deserialize} bind:finalSerialize bind:finalDeserialize {initialize} {finalize} let:path={fullpath} let:value let:onBlur let:onChange let:setVal let:messages let:valid let:invalid>
|
|
42
|
+
<Container path={fullpath} {id} {label} {messages} {descid} {required} {related} {helptext} let:messagesid let:helptextid>
|
|
43
|
+
<slot {id} path={fullpath} {value} {onBlur} {onChange} {setVal} {valid} {invalid} {messagesid} {helptextid} serialize={finalSerialize} deserialize={finalDeserialize} />
|
|
42
44
|
</Container>
|
|
43
45
|
</Field>
|
|
@@ -20,6 +20,8 @@ declare const __propDef: {
|
|
|
20
20
|
required?: boolean;
|
|
21
21
|
related?: true | number;
|
|
22
22
|
helptext?: string | undefined;
|
|
23
|
+
finalSerialize?: ((value: any) => string) | undefined;
|
|
24
|
+
finalDeserialize?: ((value: string) => any) | undefined;
|
|
23
25
|
};
|
|
24
26
|
events: {
|
|
25
27
|
[evt: string]: CustomEvent<any>;
|
|
@@ -36,8 +38,8 @@ declare const __propDef: {
|
|
|
36
38
|
invalid: boolean;
|
|
37
39
|
messagesid: string | undefined;
|
|
38
40
|
helptextid: string | undefined;
|
|
39
|
-
serialize: (value: any) => string;
|
|
40
|
-
deserialize: (value: string) => any;
|
|
41
|
+
serialize: ((value: any) => string) | undefined;
|
|
42
|
+
deserialize: ((value: string) => any) | undefined;
|
|
41
43
|
};
|
|
42
44
|
};
|
|
43
45
|
};
|