@budibase/bbui 1.1.1 → 1.1.4

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 (145) hide show
  1. package/LICENSE +375 -0
  2. package/README.md +19 -17
  3. package/dist/bbui.es.js +210 -0
  4. package/dist/bbui.es.js.map +1 -0
  5. package/package.json +71 -26
  6. package/src/ActionButton/ActionButton.svelte +95 -0
  7. package/src/ActionGroup/ActionGroup.svelte +26 -0
  8. package/src/ActionMenu/ActionMenu.svelte +44 -0
  9. package/src/Actions/ClickOutside.svench.svx +30 -0
  10. package/src/Actions/PositionDropdown.svench.svx +81 -0
  11. package/src/Actions/autoresize_textarea.js +14 -0
  12. package/src/Actions/click_outside.js +18 -0
  13. package/src/Actions/position_dropdown.js +66 -0
  14. package/src/Avatar/Avatar.svelte +49 -0
  15. package/src/Badge/Badge.svelte +29 -0
  16. package/src/Banner/Banner.svelte +72 -0
  17. package/src/Banner/BannerDisplay.svelte +31 -0
  18. package/src/Button/Button.svelte +114 -0
  19. package/src/Button/Button.svench +138 -0
  20. package/src/ButtonGroup/ButtonGroup.svelte +30 -0
  21. package/src/ClearButton/ClearButton.svelte +19 -0
  22. package/src/ColorPicker/ColorPicker.svelte +297 -0
  23. package/src/DetailSummary/DetailSummary.svelte +83 -0
  24. package/src/Divider/Divider.svelte +28 -0
  25. package/src/Drawer/Drawer.svelte +112 -0
  26. package/src/Drawer/Drawer.svench +42 -0
  27. package/src/Drawer/DrawerContent.svelte +46 -0
  28. package/src/Form/Checkbox.svelte +23 -0
  29. package/src/Form/Combobox.svelte +45 -0
  30. package/src/Form/Core/Checkbox.svelte +69 -0
  31. package/src/Form/Core/CheckboxGroup.svelte +68 -0
  32. package/src/Form/Core/Combobox.svelte +142 -0
  33. package/src/Form/Core/DatePicker.svelte +242 -0
  34. package/src/Form/Core/Dropzone.svelte +438 -0
  35. package/src/Form/Core/Multiselect.svelte +88 -0
  36. package/src/Form/Core/Picker.svelte +256 -0
  37. package/src/Form/Core/RadioGroup.svelte +47 -0
  38. package/src/Form/Core/RichTextField.svelte +42 -0
  39. package/src/Form/Core/Search.svelte +105 -0
  40. package/src/Form/Core/Select.svelte +76 -0
  41. package/src/Form/Core/Slider.svelte +86 -0
  42. package/src/Form/Core/Stepper.svelte +172 -0
  43. package/src/Form/Core/Switch.svelte +37 -0
  44. package/src/Form/Core/TextArea.svelte +78 -0
  45. package/src/Form/Core/TextField.svelte +119 -0
  46. package/src/Form/Core/index.js +15 -0
  47. package/src/Form/DatePicker.svelte +37 -0
  48. package/src/Form/Dropzone.svelte +40 -0
  49. package/src/Form/Field.svelte +42 -0
  50. package/src/Form/FieldLabel.svelte +32 -0
  51. package/src/Form/Input.svelte +40 -45
  52. package/src/Form/Multiselect.svelte +39 -0
  53. package/src/Form/RadioGroup.svelte +40 -0
  54. package/src/Form/RichTextField.svelte +36 -0
  55. package/src/Form/Search.svelte +36 -0
  56. package/src/Form/Select.svelte +48 -43
  57. package/src/Form/Slider.svelte +24 -0
  58. package/src/Form/Stepper.svelte +45 -0
  59. package/src/Form/TextArea.svelte +29 -44
  60. package/src/Form/Toggle.svelte +23 -0
  61. package/src/Icon/Icon.svelte +86 -0
  62. package/src/IconSideNav/IconSideNav.svelte +14 -0
  63. package/src/IconSideNav/IconSideNavItem.svelte +56 -0
  64. package/src/InlineAlert/InlineAlert.svelte +56 -0
  65. package/src/Label/Label.svelte +20 -0
  66. package/src/Layout/Layout.svelte +94 -0
  67. package/src/Layout/Page.svelte +32 -0
  68. package/src/Link/Link.svelte +22 -0
  69. package/src/List/Items/DetailSummary.svench +46 -8
  70. package/src/Markdown/MarkdownEditor.svelte +60 -0
  71. package/src/Markdown/MarkdownViewer.svelte +70 -0
  72. package/src/Markdown/SpectrumMDE.svelte +184 -0
  73. package/src/Menu/Item.svelte +45 -0
  74. package/src/Menu/Menu.svelte +7 -0
  75. package/src/Menu/Menu.svench +19 -0
  76. package/src/Menu/Section.svelte +10 -0
  77. package/src/Menu/Separator.svelte +1 -0
  78. package/src/Modal/Content.svelte +6 -0
  79. package/src/Modal/CustomContent.svelte +38 -0
  80. package/src/Modal/Modal.svelte +142 -0
  81. package/src/Modal/Modal.svench +117 -0
  82. package/src/Modal/ModalContent.svelte +190 -0
  83. package/src/Modal/QuizModal.svelte +54 -0
  84. package/src/Notification/Notification.svelte +70 -0
  85. package/src/Notification/NotificationDisplay.svelte +43 -0
  86. package/src/Pagination/Pagination.svelte +57 -0
  87. package/src/Popover/Popover.svelte +77 -0
  88. package/src/Popover/Popover.svench +121 -0
  89. package/src/ProgressBar/ProgressBar.svelte +54 -0
  90. package/src/ProgressCircle/ProgressCircle.svelte +62 -0
  91. package/src/SideNavigation/Item.svelte +47 -0
  92. package/src/SideNavigation/Navigation.svelte +12 -0
  93. package/src/StatusLight/StatusLight.svelte +64 -0
  94. package/src/Stores/Notifications.svench.svx +78 -0
  95. package/src/Stores/banner.js +37 -0
  96. package/src/Stores/notifications.js +84 -0
  97. package/src/Table/ArrayRenderer.svelte +17 -0
  98. package/src/Table/AttachmentRenderer.svelte +60 -0
  99. package/src/Table/BoldRenderer.svelte +15 -0
  100. package/src/Table/BooleanRenderer.svelte +42 -0
  101. package/src/Table/CellRenderer.svelte +69 -0
  102. package/src/Table/CodeRenderer.svelte +14 -0
  103. package/src/Table/DateTimeRenderer.svelte +29 -0
  104. package/src/Table/InternalRenderer.svelte +24 -0
  105. package/src/Table/RelationshipRenderer.svelte +40 -0
  106. package/src/Table/SelectEditRenderer.svelte +28 -0
  107. package/src/Table/StringRenderer.svelte +14 -0
  108. package/src/Table/Table.svelte +631 -0
  109. package/src/Table/index.js +1 -0
  110. package/src/Tabs/Tab.svelte +88 -0
  111. package/src/Tabs/Tabs.svelte +125 -0
  112. package/src/Tags/Tag.svelte +43 -0
  113. package/src/Tags/Tags.svelte +7 -0
  114. package/src/Tooltip/Tooltip.svelte +30 -0
  115. package/src/Tooltip/TooltipWrapper.svelte +60 -0
  116. package/src/TreeView/Item.svelte +41 -0
  117. package/src/TreeView/Tree.svelte +16 -0
  118. package/src/Typography/Body.svelte +21 -0
  119. package/src/Typography/Code.svelte +10 -0
  120. package/src/Typography/Detail.svelte +19 -0
  121. package/src/Typography/Heading.svelte +17 -0
  122. package/src/bbui.css +96 -0
  123. package/src/context.js +3 -0
  124. package/src/helpers.js +134 -0
  125. package/src/index.js +91 -11
  126. package/src/spectrum-icons-rollup.js +31 -0
  127. package/src/spectrum-icons-vite.js +31 -0
  128. package/dist/bundle.css +0 -7
  129. package/dist/bundle.css.map +0 -20
  130. package/dist/index.js +0 -1045
  131. package/dist/index.mjs +0 -1031
  132. package/src/Branding/Budibase-logo.svelte +0 -68
  133. package/src/Branding/Logo.svelte +0 -16
  134. package/src/Branding/Logo.svench +0 -8
  135. package/src/Form/Button.svelte +0 -52
  136. package/src/Form/Button.svench +0 -26
  137. package/src/Form/Input.svench +0 -8
  138. package/src/Form/Select.svench +0 -8
  139. package/src/Form/TextArea.svench +0 -8
  140. package/src/Links/Home.svelte +0 -49
  141. package/src/Links/Home.svench +0 -19
  142. package/src/List/Items/DetailSummary.svelte +0 -66
  143. package/src/actions/autoresize_textarea.js +0 -14
  144. package/src/icons/Contribution.svelte +0 -14
  145. package/src/index.svench.svx +0 -35
@@ -0,0 +1,88 @@
1
+ <script>
2
+ import Picker from "./Picker.svelte"
3
+ import { createEventDispatcher } from "svelte"
4
+
5
+ export let value = []
6
+ export let id = null
7
+ export let placeholder = null
8
+ export let disabled = false
9
+ export let error = null
10
+ export let options = []
11
+ export let getOptionLabel = option => option
12
+ export let getOptionValue = option => option
13
+ export let readonly = false
14
+ export let autocomplete = false
15
+ export let sort = false
16
+
17
+ const dispatch = createEventDispatcher()
18
+ $: selectedLookupMap = getSelectedLookupMap(value)
19
+ $: optionLookupMap = getOptionLookupMap(options)
20
+ $: fieldText = getFieldText(value, optionLookupMap, placeholder)
21
+ $: isOptionSelected = optionValue => selectedLookupMap[optionValue] === true
22
+ $: toggleOption = makeToggleOption(selectedLookupMap, value)
23
+
24
+ const getFieldText = (value, map, placeholder) => {
25
+ if (value?.length) {
26
+ if (!map) {
27
+ return ""
28
+ }
29
+ const vals = value.map(option => map[option] || option).join(", ")
30
+ return `(${value.length}) ${vals}`
31
+ } else {
32
+ return placeholder || "Choose some options"
33
+ }
34
+ }
35
+
36
+ const getSelectedLookupMap = value => {
37
+ let map = {}
38
+ if (value?.length) {
39
+ value.forEach(option => {
40
+ if (option) {
41
+ map[option] = true
42
+ }
43
+ })
44
+ }
45
+ return map
46
+ }
47
+
48
+ const getOptionLookupMap = options => {
49
+ let map = null
50
+ if (options?.length) {
51
+ map = {}
52
+ options.forEach((option, idx) => {
53
+ const optionValue = getOptionValue(option, idx)
54
+ if (optionValue != null) {
55
+ map[optionValue] = getOptionLabel(option, idx) || ""
56
+ }
57
+ })
58
+ }
59
+ return map
60
+ }
61
+
62
+ const makeToggleOption = (map, value) => {
63
+ return optionValue => {
64
+ if (map[optionValue]) {
65
+ const filtered = value.filter(option => option !== optionValue)
66
+ dispatch("change", filtered)
67
+ } else {
68
+ dispatch("change", [...value, optionValue])
69
+ }
70
+ }
71
+ }
72
+ </script>
73
+
74
+ <Picker
75
+ {id}
76
+ {error}
77
+ {disabled}
78
+ {readonly}
79
+ {fieldText}
80
+ {options}
81
+ isPlaceholder={!value?.length}
82
+ {autocomplete}
83
+ {isOptionSelected}
84
+ {getOptionLabel}
85
+ {getOptionValue}
86
+ onSelectOption={toggleOption}
87
+ {sort}
88
+ />
@@ -0,0 +1,256 @@
1
+ <script>
2
+ import "@spectrum-css/picker/dist/index-vars.css"
3
+ import "@spectrum-css/popover/dist/index-vars.css"
4
+ import "@spectrum-css/menu/dist/index-vars.css"
5
+ import { fly } from "svelte/transition"
6
+ import { createEventDispatcher } from "svelte"
7
+ import clickOutside from "../../Actions/click_outside"
8
+ import Search from "./Search.svelte"
9
+ import Icon from "../../Icon/Icon.svelte"
10
+ import StatusLight from "../../StatusLight/StatusLight.svelte"
11
+
12
+ export let id = null
13
+ export let disabled = false
14
+ export let error = null
15
+ export let fieldText = ""
16
+ export let fieldIcon = ""
17
+ export let fieldColour = ""
18
+ export let isPlaceholder = false
19
+ export let placeholderOption = null
20
+ export let options = []
21
+ export let isOptionSelected = () => false
22
+ export let onSelectOption = () => {}
23
+ export let getOptionLabel = option => option
24
+ export let getOptionValue = option => option
25
+ export let getOptionIcon = () => null
26
+ export let getOptionColour = () => null
27
+ export let open = false
28
+ export let readonly = false
29
+ export let quiet = false
30
+ export let autoWidth = false
31
+ export let autocomplete = false
32
+ export let sort = false
33
+
34
+ const dispatch = createEventDispatcher()
35
+ let searchTerm = null
36
+
37
+ $: sortedOptions = getSortedOptions(options, getOptionLabel, sort)
38
+ $: filteredOptions = getFilteredOptions(
39
+ sortedOptions,
40
+ searchTerm,
41
+ getOptionLabel
42
+ )
43
+
44
+ const onClick = () => {
45
+ dispatch("click")
46
+ if (readonly) {
47
+ return
48
+ }
49
+ searchTerm = null
50
+ open = !open
51
+ }
52
+
53
+ const getSortedOptions = (options, getLabel, sort) => {
54
+ if (!options?.length || !Array.isArray(options)) {
55
+ return []
56
+ }
57
+ if (!sort) {
58
+ return options
59
+ }
60
+ return options.sort((a, b) => {
61
+ const labelA = getLabel(a)
62
+ const labelB = getLabel(b)
63
+ return labelA > labelB ? 1 : -1
64
+ })
65
+ }
66
+
67
+ const getFilteredOptions = (options, term, getLabel) => {
68
+ if (autocomplete && term) {
69
+ const lowerCaseTerm = term.toLowerCase()
70
+ return options.filter(option => {
71
+ return `${getLabel(option)}`.toLowerCase().includes(lowerCaseTerm)
72
+ })
73
+ }
74
+ return options
75
+ }
76
+ </script>
77
+
78
+ <div use:clickOutside={() => (open = false)}>
79
+ <button
80
+ {id}
81
+ class="spectrum-Picker spectrum-Picker--sizeM"
82
+ class:spectrum-Picker--quiet={quiet}
83
+ {disabled}
84
+ class:is-invalid={!!error}
85
+ class:is-open={open}
86
+ aria-haspopup="listbox"
87
+ on:mousedown={onClick}
88
+ >
89
+ {#if fieldIcon}
90
+ <span class="option-icon">
91
+ <Icon name={fieldIcon} />
92
+ </span>
93
+ {/if}
94
+ <span
95
+ class="spectrum-Picker-label"
96
+ class:is-placeholder={isPlaceholder}
97
+ class:auto-width={autoWidth}
98
+ >
99
+ {fieldText}
100
+ </span>
101
+ {#if error}
102
+ <svg
103
+ class="spectrum-Icon spectrum-Icon--sizeM spectrum-Picker-validationIcon"
104
+ focusable="false"
105
+ aria-hidden="true"
106
+ aria-label="Folder"
107
+ >
108
+ <use xlink:href="#spectrum-icon-18-Alert" />
109
+ </svg>
110
+ {/if}
111
+ {#if fieldColour}
112
+ <span class="option-colour">
113
+ <StatusLight size="L" color={fieldColour} />
114
+ </span>
115
+ {/if}
116
+ <svg
117
+ class="spectrum-Icon spectrum-UIIcon-ChevronDown100 spectrum-Picker-menuIcon"
118
+ focusable="false"
119
+ aria-hidden="true"
120
+ >
121
+ <use xlink:href="#spectrum-css-icon-Chevron100" />
122
+ </svg>
123
+ </button>
124
+ {#if open}
125
+ <div
126
+ transition:fly|local={{ y: -20, duration: 200 }}
127
+ class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover is-open"
128
+ class:auto-width={autoWidth}
129
+ >
130
+ {#if autocomplete}
131
+ <Search
132
+ value={searchTerm}
133
+ on:change={event => (searchTerm = event.detail)}
134
+ {disabled}
135
+ placeholder="Search"
136
+ />
137
+ {/if}
138
+ <ul class="spectrum-Menu" role="listbox">
139
+ {#if placeholderOption}
140
+ <li
141
+ class="spectrum-Menu-item placeholder"
142
+ class:is-selected={isPlaceholder}
143
+ role="option"
144
+ aria-selected="true"
145
+ tabindex="0"
146
+ on:click={() => onSelectOption(null)}
147
+ >
148
+ <span class="spectrum-Menu-itemLabel">{placeholderOption}</span>
149
+ <svg
150
+ class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
151
+ focusable="false"
152
+ aria-hidden="true"
153
+ >
154
+ <use xlink:href="#spectrum-css-icon-Checkmark100" />
155
+ </svg>
156
+ </li>
157
+ {/if}
158
+ {#if filteredOptions.length}
159
+ {#each filteredOptions as option, idx}
160
+ <li
161
+ class="spectrum-Menu-item"
162
+ class:is-selected={isOptionSelected(getOptionValue(option, idx))}
163
+ role="option"
164
+ aria-selected="true"
165
+ tabindex="0"
166
+ on:click={() => onSelectOption(getOptionValue(option, idx))}
167
+ >
168
+ {#if getOptionIcon(option, idx)}
169
+ <span class="option-icon">
170
+ <Icon name={getOptionIcon(option, idx)} />
171
+ </span>
172
+ {/if}
173
+ <span class="spectrum-Menu-itemLabel">
174
+ {getOptionLabel(option, idx)}
175
+ </span>
176
+ <svg
177
+ class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
178
+ focusable="false"
179
+ aria-hidden="true"
180
+ >
181
+ <use xlink:href="#spectrum-css-icon-Checkmark100" />
182
+ </svg>
183
+ {#if getOptionColour(option, idx)}
184
+ <span class="option-colour">
185
+ <StatusLight size="L" color={getOptionColour(option, idx)} />
186
+ </span>
187
+ {/if}
188
+ </li>
189
+ {/each}
190
+ {/if}
191
+ </ul>
192
+ </div>
193
+ {/if}
194
+ </div>
195
+
196
+ <style>
197
+ .spectrum-Popover {
198
+ max-height: 240px;
199
+ z-index: 999;
200
+ top: 100%;
201
+ }
202
+ .spectrum-Popover:not(.auto-width) {
203
+ width: 100%;
204
+ }
205
+ .spectrum-Popover.auto-width :global(.spectrum-Menu-itemLabel) {
206
+ white-space: nowrap;
207
+ }
208
+ .spectrum-Picker {
209
+ width: 100%;
210
+ box-shadow: none;
211
+ }
212
+ .spectrum-Picker-label:not(.auto-width) {
213
+ overflow: hidden;
214
+ text-overflow: ellipsis;
215
+ white-space: nowrap;
216
+ width: 0;
217
+ }
218
+ .placeholder {
219
+ font-style: italic;
220
+ }
221
+ .spectrum-Picker-label.auto-width.is-placeholder {
222
+ padding-right: 2px;
223
+ }
224
+
225
+ /* Icon and colour alignment */
226
+ .spectrum-Menu-checkmark {
227
+ align-self: center;
228
+ margin-top: 0;
229
+ }
230
+ .option-colour {
231
+ padding-left: 8px;
232
+ }
233
+ .option-icon {
234
+ padding-right: 8px;
235
+ }
236
+
237
+ .spectrum-Popover :global(.spectrum-Search) {
238
+ margin-top: -1px;
239
+ margin-left: -1px;
240
+ width: calc(100% + 2px);
241
+ }
242
+ .spectrum-Popover :global(.spectrum-Search input) {
243
+ height: auto;
244
+ border-bottom-left-radius: 0;
245
+ border-bottom-right-radius: 0;
246
+ padding-top: var(--spectrum-global-dimension-size-100);
247
+ padding-bottom: var(--spectrum-global-dimension-size-100);
248
+ }
249
+ .spectrum-Popover :global(.spectrum-Search .spectrum-ClearButton) {
250
+ right: 1px;
251
+ top: 2px;
252
+ }
253
+ .spectrum-Popover :global(.spectrum-Search .spectrum-Textfield-icon) {
254
+ top: 9px;
255
+ }
256
+ </style>
@@ -0,0 +1,47 @@
1
+ <script>
2
+ import "@spectrum-css/fieldgroup/dist/index-vars.css"
3
+ import "@spectrum-css/radio/dist/index-vars.css"
4
+ import { createEventDispatcher } from "svelte"
5
+
6
+ export let direction = "vertical"
7
+ export let value = null
8
+ export let options = []
9
+ export let error = null
10
+ export let disabled = false
11
+ export let getOptionLabel = option => option
12
+ export let getOptionValue = option => option
13
+
14
+ const dispatch = createEventDispatcher()
15
+ const onChange = e => dispatch("change", e.target.value)
16
+ </script>
17
+
18
+ <div class={`spectrum-FieldGroup spectrum-FieldGroup--${direction}`}>
19
+ {#if options && Array.isArray(options)}
20
+ {#each options as option}
21
+ <div
22
+ title={getOptionLabel(option)}
23
+ class="spectrum-Radio spectrum-FieldGroup-item spectrum-Radio--emphasized"
24
+ class:is-invalid={!!error}
25
+ >
26
+ <input
27
+ on:change={onChange}
28
+ bind:group={value}
29
+ value={getOptionValue(option)}
30
+ type="radio"
31
+ class="spectrum-Radio-input"
32
+ {disabled}
33
+ />
34
+ <span class="spectrum-Radio-button" />
35
+ <label for="" class="spectrum-Radio-label">
36
+ {getOptionLabel(option)}
37
+ </label>
38
+ </div>
39
+ {/each}
40
+ {/if}
41
+ </div>
42
+
43
+ <style>
44
+ .spectrum-Radio-input {
45
+ opacity: 0;
46
+ }
47
+ </style>
@@ -0,0 +1,42 @@
1
+ <script>
2
+ import MarkdownEditor from "../../Markdown/MarkdownEditor.svelte"
3
+
4
+ export let value = ""
5
+ export let placeholder = null
6
+ export let disabled = false
7
+ export let error = null
8
+ export let height = null
9
+ export let id = null
10
+ export let fullScreenOffset = null
11
+ export let easyMDEOptions = null
12
+ </script>
13
+
14
+ <div class:error>
15
+ <MarkdownEditor
16
+ {value}
17
+ {placeholder}
18
+ {height}
19
+ {id}
20
+ {fullScreenOffset}
21
+ {disabled}
22
+ {easyMDEOptions}
23
+ on:change
24
+ />
25
+ </div>
26
+
27
+ <style>
28
+ .error :global(.EasyMDEContainer .editor-toolbar) {
29
+ border-top-color: var(--spectrum-semantic-negative-color-default);
30
+ border-left-color: var(--spectrum-semantic-negative-color-default);
31
+ border-right-color: var(--spectrum-semantic-negative-color-default);
32
+ }
33
+ .error :global(.EasyMDEContainer .CodeMirror) {
34
+ border-bottom-color: var(--spectrum-semantic-negative-color-default);
35
+ border-left-color: var(--spectrum-semantic-negative-color-default);
36
+ border-right-color: var(--spectrum-semantic-negative-color-default);
37
+ }
38
+ .error :global(.EasyMDEContainer .editor-preview-side) {
39
+ border-bottom-color: var(--spectrum-semantic-negative-color-default);
40
+ border-right-color: var(--spectrum-semantic-negative-color-default);
41
+ }
42
+ </style>
@@ -0,0 +1,105 @@
1
+ <script>
2
+ import "@spectrum-css/search/dist/index-vars.css"
3
+ import { createEventDispatcher } from "svelte"
4
+
5
+ export let value = null
6
+ export let placeholder = null
7
+ export let disabled = false
8
+ export let id = null
9
+ export let updateOnChange = true
10
+ export let quiet = false
11
+ export let inputRef
12
+
13
+ const dispatch = createEventDispatcher()
14
+ let focus = false
15
+
16
+ const updateValue = value => {
17
+ dispatch("change", value)
18
+ }
19
+
20
+ const onFocus = () => {
21
+ focus = true
22
+ }
23
+
24
+ const onBlur = event => {
25
+ focus = false
26
+ updateValue(event.target.value)
27
+ }
28
+
29
+ const onInput = event => {
30
+ if (!updateOnChange) {
31
+ return
32
+ }
33
+ updateValue(event.target.value)
34
+ }
35
+
36
+ const updateValueOnEnter = event => {
37
+ if (event.key === "Enter") {
38
+ updateValue(event.target.value)
39
+ }
40
+ }
41
+ </script>
42
+
43
+ <div class="spectrum-Search" class:is-disabled={disabled}>
44
+ <div
45
+ class="spectrum-Textfield"
46
+ class:spectrum-Textfield--quiet={quiet}
47
+ class:is-focused={focus}
48
+ class:is-disabled={disabled}
49
+ >
50
+ <svg
51
+ class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-icon"
52
+ focusable="false"
53
+ aria-hidden="true"
54
+ >
55
+ <use xlink:href="#spectrum-icon-18-Magnify" />
56
+ </svg>
57
+ <input
58
+ {disabled}
59
+ {id}
60
+ value={value || ""}
61
+ placeholder={placeholder || ""}
62
+ on:click
63
+ on:blur
64
+ on:focus
65
+ on:input
66
+ on:blur={onBlur}
67
+ on:focus={onFocus}
68
+ on:input={onInput}
69
+ on:keyup={updateValueOnEnter}
70
+ type="search"
71
+ class="spectrum-Textfield-input spectrum-Search-input"
72
+ autocomplete="off"
73
+ bind:this={inputRef}
74
+ />
75
+ </div>
76
+ <button
77
+ on:click={() => updateValue("")}
78
+ type="reset"
79
+ class="spectrum-ClearButton spectrum-Search-clearButton"
80
+ >
81
+ <svg
82
+ class="spectrum-Icon spectrum-UIIcon-Cross75"
83
+ focusable="false"
84
+ aria-hidden="true"
85
+ >
86
+ <use xlink:href="#spectrum-css-icon-Cross75" />
87
+ </svg>
88
+ </button>
89
+ </div>
90
+
91
+ <style>
92
+ .spectrum-Search,
93
+ .spectrum-Textfield {
94
+ width: 100%;
95
+ }
96
+ .spectrum-Search-input {
97
+ padding-right: 24px;
98
+ }
99
+ .is-disabled {
100
+ pointer-events: none;
101
+ }
102
+ .spectrum-Search-clearButton {
103
+ position: absolute;
104
+ }
105
+ </style>
@@ -0,0 +1,76 @@
1
+ <script>
2
+ import { createEventDispatcher } from "svelte"
3
+ import Picker from "./Picker.svelte"
4
+
5
+ export let value = null
6
+ export let id = null
7
+ export let placeholder = "Choose an option"
8
+ export let disabled = false
9
+ export let error = null
10
+ export let options = []
11
+ export let getOptionLabel = option => option
12
+ export let getOptionValue = option => option
13
+ export let getOptionIcon = () => null
14
+ export let getOptionColour = () => null
15
+ export let readonly = false
16
+ export let quiet = false
17
+ export let autoWidth = false
18
+ export let autocomplete = false
19
+ export let sort = false
20
+
21
+ const dispatch = createEventDispatcher()
22
+ let open = false
23
+ $: fieldText = getFieldText(value, options, placeholder)
24
+ $: fieldIcon = getFieldAttribute(getOptionIcon, value, options)
25
+ $: fieldColour = getFieldAttribute(getOptionColour, value, options)
26
+
27
+ const getFieldAttribute = (getAttribute, value, options) => {
28
+ // Wait for options to load if there is a value but no options
29
+ if (!options?.length) {
30
+ return ""
31
+ }
32
+ const index = options.findIndex(
33
+ (option, idx) => getOptionValue(option, idx) === value
34
+ )
35
+ return index !== -1 ? getAttribute(options[index], index) : null
36
+ }
37
+
38
+ const getFieldText = (value, options, placeholder) => {
39
+ // Always use placeholder if no value
40
+ if (value == null || value === "") {
41
+ return placeholder || "Choose an option"
42
+ }
43
+
44
+ return getFieldAttribute(getOptionLabel, value, options)
45
+ }
46
+
47
+ const selectOption = value => {
48
+ dispatch("change", value)
49
+ open = false
50
+ }
51
+ </script>
52
+
53
+ <Picker
54
+ on:click
55
+ bind:open
56
+ {quiet}
57
+ {id}
58
+ {error}
59
+ {disabled}
60
+ {readonly}
61
+ {fieldText}
62
+ {fieldIcon}
63
+ {fieldColour}
64
+ {options}
65
+ {autoWidth}
66
+ {getOptionLabel}
67
+ {getOptionValue}
68
+ {getOptionIcon}
69
+ {getOptionColour}
70
+ {autocomplete}
71
+ {sort}
72
+ isPlaceholder={value == null || value === ""}
73
+ placeholderOption={placeholder}
74
+ isOptionSelected={option => option === value}
75
+ onSelectOption={selectOption}
76
+ />
@@ -0,0 +1,86 @@
1
+ <script>
2
+ import "@spectrum-css/slider/dist/index-vars.css"
3
+ import { createEventDispatcher } from "svelte"
4
+
5
+ export let value = false
6
+ export let id = null
7
+ export let disabled = false
8
+ export let min = 0
9
+ export let max = 100
10
+ export let step = 1
11
+
12
+ const dispatch = createEventDispatcher()
13
+ const onChange = event => {
14
+ dispatch("change", event.target.value)
15
+ }
16
+ </script>
17
+
18
+ <div>
19
+ <input
20
+ type="range"
21
+ {min}
22
+ {max}
23
+ {step}
24
+ {value}
25
+ {disabled}
26
+ {id}
27
+ on:change={onChange}
28
+ />
29
+ </div>
30
+
31
+ <style>
32
+ div {
33
+ display: grid;
34
+ place-items: center;
35
+ }
36
+
37
+ input {
38
+ width: 100%;
39
+ padding: 0;
40
+ margin: 0;
41
+ -webkit-appearance: none;
42
+ background: transparent;
43
+ }
44
+ input::-webkit-slider-thumb {
45
+ -webkit-appearance: none;
46
+ }
47
+ input:focus {
48
+ outline: none;
49
+ }
50
+
51
+ input[type="range"]::-webkit-slider-thumb {
52
+ -webkit-appearance: none;
53
+ border: 2px solid var(--spectrum-global-color-gray-700);
54
+ height: 16px;
55
+ width: 16px;
56
+ border-radius: 50%;
57
+ background: var(--background);
58
+ cursor: pointer;
59
+ transition: background 130ms ease-out;
60
+ margin-top: -7px;
61
+ }
62
+ input[type="range"]::-moz-range-thumb {
63
+ border: 2px solid var(--spectrum-global-color-gray-700);
64
+ height: 12px;
65
+ width: 12px;
66
+ border-radius: 50%;
67
+ background: var(--background);
68
+ cursor: pointer;
69
+ transition: background 130ms ease-out;
70
+ }
71
+
72
+ input[type="range"]::-webkit-slider-runnable-track {
73
+ width: 100%;
74
+ height: 2px;
75
+ cursor: pointer;
76
+ background: var(--spectrum-global-color-gray-300);
77
+ border-radius: 2px;
78
+ }
79
+ input[type="range"]::-moz-range-track {
80
+ width: 100%;
81
+ height: 2px;
82
+ cursor: pointer;
83
+ background: var(--spectrum-global-color-gray-300);
84
+ border-radius: 2px;
85
+ }
86
+ </style>