@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.
Files changed (61) hide show
  1. package/dist/Dialog.svelte +3 -3
  2. package/dist/FieldAutocomplete.svelte +19 -15
  3. package/dist/FieldCheckbox.svelte +4 -4
  4. package/dist/FieldChoices.svelte +11 -7
  5. package/dist/FieldChooserLink.svelte +30 -32
  6. package/dist/FieldDate.svelte +3 -3
  7. package/dist/FieldDateTime.svelte +3 -4
  8. package/dist/FieldDualListbox.svelte +9 -11
  9. package/dist/FieldIdentifier.svelte +2 -2
  10. package/dist/FieldMultiple.svelte +6 -5
  11. package/dist/FieldMultiselect.svelte +5 -5
  12. package/dist/FieldNumber.svelte +3 -3
  13. package/dist/FieldRadio.svelte +3 -7
  14. package/dist/FieldSelect.svelte +4 -8
  15. package/dist/FieldStandard.svelte +5 -3
  16. package/dist/FieldStandard.svelte.d.ts +4 -2
  17. package/dist/FieldText.svelte +6 -5
  18. package/dist/FieldText.svelte.d.ts +2 -1
  19. package/dist/FieldTextArea.svelte +3 -4
  20. package/dist/FileIcon.svelte +1 -1
  21. package/dist/Form.svelte +4 -4
  22. package/dist/FormDialog.svelte +2 -2
  23. package/dist/Icon.svelte +10 -6
  24. package/dist/InlineMessage.svelte +3 -3
  25. package/dist/InlineMessages.svelte +1 -1
  26. package/dist/Input.svelte +3 -3
  27. package/dist/Input.svelte.d.ts +2 -1
  28. package/dist/Listbox.svelte +3 -4
  29. package/dist/Radio.svelte +0 -1
  30. package/dist/Switcher.svelte +1 -1
  31. package/dist/Tabs.svelte +3 -4
  32. package/dist/Tooltip.svelte +6 -5
  33. package/dist/chooser/AssetTabs.svelte +19 -17
  34. package/dist/chooser/AssetTabs.svelte.d.ts +1 -1
  35. package/dist/chooser/Chooser.svelte +3 -3
  36. package/dist/chooser/Chooser.svelte.d.ts +5 -5
  37. package/dist/chooser/ChooserStore.js +2 -2
  38. package/dist/chooser/UploadUI.svelte +4 -4
  39. package/dist/code/FieldCodeEditor.svelte +3 -3
  40. package/dist/code/FieldGraphQLEditor.svelte +28 -0
  41. package/dist/code/FieldGraphQLEditor.svelte.d.ts +36 -0
  42. package/dist/code/FieldTypeScriptEditor.svelte +27 -0
  43. package/dist/code/FieldTypeScriptEditor.svelte.d.ts +34 -0
  44. package/dist/code/GraphQLEditor.svelte +145 -0
  45. package/dist/code/GraphQLEditor.svelte.d.ts +35 -0
  46. package/dist/code/TypeScriptEditor.svelte +186 -0
  47. package/dist/code/TypeScriptEditor.svelte.d.ts +33 -0
  48. package/dist/code/index.d.ts +2 -0
  49. package/dist/code/index.js +2 -0
  50. package/dist/colorpicker/FieldColorPicker.svelte +2 -2
  51. package/dist/cropper/FieldCropper.svelte +8 -10
  52. package/dist/cropper/cropper.js +9 -11
  53. package/dist/iconpicker/FieldIconPicker.svelte +7 -11
  54. package/dist/imageposition/FieldImagePosition.svelte +4 -5
  55. package/dist/imageposition/index.d.ts +1 -1
  56. package/dist/imageposition/index.js +0 -1
  57. package/dist/tagpicker/FieldTagPicker.svelte +1 -2
  58. package/dist/tree/Tree.svelte +2 -3
  59. package/dist/tree/TreeCell.svelte +2 -2
  60. package/dist/tree/TreeNode.svelte +16 -17
  61. package/package.json +14 -7
@@ -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: string = 'Ok'
31
+ export let continueText = 'Ok'
32
32
  export let continueIcon: IconifyIcon | undefined = undefined
33
33
  export let escapable = isNotBlank(cancelText)
34
- export let expandable: boolean = false
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: boolean = false
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 { nullableSerialize, nullableDeserialize } from '@txstate-mws/svelte-forms'
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: string = ''
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
- $: finalserialize = !notNull ? nullableSerialize : v => v
31
- $: finaldeserialize = !notNull ? nullableDeserialize : v => v
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 (e) => {
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 (e) => {
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, setVal: any) {
67
- const dsvalue = finaldeserialize(value)
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)) setVal(finaldeserialize(''))
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} serialize={finalserialize} deserialize={finaldeserialize} let:value let:setVal let:valid let:invalid let:id let:onBlur let:messagesid let:helptextid>
86
- {@const _ = reactToValue(value, setVal)}
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: string = ''
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={id}>
32
- <Checkbox bind:inputelement {id} name={path} {value} descid={getDescribedBy([descid, messagesid, helptextid, extradescid])} {valid} {invalid} {onBlur} onChange={onChange(setVal)}></Checkbox>
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>
@@ -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: string = ''
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: boolean = false
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 valStore = store.getField<any[]>(finalPath)
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
- $: selected = new Set($valStore ?? [])
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 {path} {id} {label} {messages} {descid} {related} {helptext} let:messagesid let:helptextid>
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 = `${path}.${idx}`}
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: string = ''
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 : string | undefined = undefined
33
- export let altTextRequired: boolean = false
34
- export let altTextHelp: string = 'Describes the asset for visually-impaired users and search engines.'
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 (e) => {
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) || // 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
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
- selectedAsset = { type: 'raw', id: undefined, url }
128
- } else {
129
- selectedAsset = {
130
- type: 'raw',
131
- id: chooserClient.urlToValue?.(cleanedUrl) ?? cleanedUrl,
132
- url
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
- return (e) => {
178
- selectedAsset = undefined
179
- setVal(undefined)
180
- if (finalAltTextPath) {
181
- formStore.setField(finalAltTextPath, undefined).catch(console.error)
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} {id} type="text" data-lpignore="true" value={selectedAsset?.url ?? ''} on:change={userUrlEntry} on:input={userUrlEntry} on:blur={onBlur}>
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}
@@ -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: string = ''
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} {id} class="dialog-input {className}" {onChange} {onBlur} {valid} {invalid} {min} {max} {step} {extradescid} {messagesid} {helptextid}/>
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: string = ''
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} {id} class="dialog-input {className}" {onBlur} onChange={onChange(setVal)} {valid} {invalid} {min} {max} {step} {extradescid} {messagesid} {helptextid}/>
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: string = ''
15
- export let sourceLabel: string = 'Available'
16
- export let selectedLabel: string = 'Selected'
17
- export let multiselect: boolean = false
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: string = 'test'
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 (e) => {
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 {id} role="group" class="dual-list-container" on:keydown={onkeydown(value, setVal)}>
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: number = 10
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) return onDelete()
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 {path} {index} {value} {maxed} {maxLength} {currentLength}/>
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 && maxLength > 1)}
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: string = ''
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 (val) => { const options = await getOptions(val); return options.find((opt) => opt.value === val) }
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 = (item) => item.label || item.value
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 {id} name={path} descid={getDescribedBy([messagesid, helptextid, extradescid])}
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}
@@ -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: string = ''
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} {id} class="dialog-input {className}" {onChange} {onBlur} {valid} {invalid} {min} {max} {step} {helptextid} {extradescid}></Input>
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>
@@ -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: string = ''
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 let:serialize let:deserialize>
48
- {@const _ = updateDeserialize(deserialize)}
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>
@@ -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: string = ''
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 let:serialize let:deserialize>
51
- {@const _ = updateDeserialize(deserialize)}
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 = serialize(choice.value)}
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 let:serialize let:deserialize>
40
- <Container {path} {id} {label} {messages} {descid} {required} {related} {helptext} let:messagesid let:helptextid>
41
- <slot {id} {path} {value} {onBlur} {onChange} {setVal} {valid} {invalid} {messagesid} {helptextid} {serialize} {deserialize} />
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
  };