slim-select 2.0.2 → 2.1.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 (45) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/render.d.ts +1 -1
  3. package/dist/slimselect.cjs.js +54 -16
  4. package/dist/slimselect.es.js +54 -16
  5. package/dist/slimselect.global.js +54 -16
  6. package/dist/slimselect.js +54 -16
  7. package/dist/slimselect.min.js +1 -1
  8. package/dist/slimselect.umd.js +54 -16
  9. package/dist/slimselect.umd.min.js +1 -1
  10. package/docs/assets/index.css +1 -1
  11. package/docs/assets/index.js +7 -7
  12. package/docs/assets/index3.js +25 -16
  13. package/docs/assets/index5.js +145 -9
  14. package/docs/assets/install.js +4 -4
  15. package/package.json +11 -3
  16. package/src/docs/app.vue +4 -4
  17. package/src/docs/{images → assets/images}/check-mark.svg +0 -0
  18. package/src/docs/{images → assets/images}/chrome.svg +0 -0
  19. package/src/docs/{images → assets/images}/firefox.svg +0 -0
  20. package/src/docs/{images → assets/images}/github.png +0 -0
  21. package/src/docs/{images → assets/images}/ie.svg +0 -0
  22. package/src/docs/{images → assets/images}/npm.png +0 -0
  23. package/src/docs/{images → assets/images}/opera.svg +0 -0
  24. package/src/docs/{images → assets/images}/safari.svg +0 -0
  25. package/src/docs/assets/scss/misc.scss +7 -0
  26. package/src/docs/env.d.ts +1 -0
  27. package/src/docs/pages/events/addable.vue +22 -6
  28. package/src/docs/pages/events/before_after_change.vue +15 -1
  29. package/src/docs/pages/events/search.vue +2 -1
  30. package/src/docs/pages/frameworks/vue.vue +373 -7
  31. package/src/docs/pages/home.vue +18 -18
  32. package/src/docs/pages/methods/get_data.vue +2 -1
  33. package/src/docs/pages/methods/open_close.vue +1 -1
  34. package/src/slim-select/index.ts +1 -1
  35. package/src/slim-select/render.ts +83 -25
  36. package/src/slim-select/rollup.config.mjs +5 -0
  37. package/src/slim-select/select.ts +14 -5
  38. package/src/vue/dist/slimselectvue.es.js +1655 -0
  39. package/src/vue/dist/slimselectvue.global.js +1658 -0
  40. package/src/vue/dist/slimselectvue.ssr.js +1657 -0
  41. package/src/vue/hello.ts +5 -0
  42. package/src/vue/package.json +27 -0
  43. package/src/vue/rollup.config.mjs +44 -0
  44. package/src/vue/slimselect.vue +39 -5
  45. package/src/vue/tsconfig.json +14 -0
@@ -1,7 +1,8 @@
1
1
  <script lang="ts" setup>
2
2
  import { onMounted, Ref, ref } from 'vue'
3
3
 
4
- import SlimSelect, { DataArray, Option } from '../../../slim-select'
4
+ import SlimSelect from '../../../slim-select'
5
+ import { DataArray, Option } from '../../../slim-select/store'
5
6
 
6
7
  interface Person {
7
8
  first_name: string
@@ -1,39 +1,405 @@
1
1
  <script lang="ts">
2
2
  import { defineComponent } from 'vue'
3
3
 
4
+ // We need to import from the root of the package
5
+ // Because if we use @slim-select/vue then we loose
6
+ // hot reloading of the file changes
7
+ import SlimSelectJS from '../../../slim-select'
4
8
  import SlimSelect from '../../../vue/slimselect.vue'
9
+ import Settings from '../../../slim-select/settings'
10
+ import { Option, OptionOptional } from '../../../slim-select/store'
11
+ import { Events } from '../../../slim-select'
12
+
13
+ interface Person {
14
+ id: string
15
+ first_name: string
16
+ last_name: string
17
+ selected: number
18
+ }
5
19
 
6
20
  export default defineComponent({
7
21
  name: 'Vue',
8
22
  components: {
9
23
  SlimSelect,
10
24
  },
25
+ data() {
26
+ return {
27
+ settings: {
28
+ showSearch: false,
29
+ } as Settings,
30
+ data: [
31
+ { value: 'value1', text: 'Value 1' },
32
+ { value: 'value2', text: 'Value 2' },
33
+ { value: 'value3', text: 'Value 3' },
34
+ ],
35
+ dynamicData: [] as OptionOptional[],
36
+ afterChangeData: [] as OptionOptional[],
37
+ events: {
38
+ afterChange: this.afterChange,
39
+ } as Events,
40
+ }
41
+ },
42
+ mounted() {
43
+ // Show the original select for debugging
44
+ // const randomComponent = this.$refs.randomDynamic as any
45
+ // const randomSlim = randomComponent.getSlimSelect()
46
+ // randomSlim.select.showUI()
47
+ },
48
+ methods: {
49
+ changeData() {
50
+ const dataSingle = this.$refs.dataSingle as any
51
+ const dataSingleSlim = dataSingle.getSlimSelect() as SlimSelectJS
52
+ dataSingleSlim.open()
53
+ const dataMultiple = this.$refs.dataMultiple as any
54
+ const dataMultipleSlim = dataMultiple.getSlimSelect() as SlimSelectJS
55
+ dataMultipleSlim.open()
56
+
57
+ setTimeout(() => {
58
+ this.data = [
59
+ { value: 'value4', text: 'Value 4' },
60
+ { value: 'value5', text: 'Value 5' },
61
+ { value: 'value6', text: 'Value 6' },
62
+ ]
63
+ }, 500)
64
+ },
65
+ afterChange(newVal: Option[]) {
66
+ this.afterChangeData = newVal
67
+ },
68
+ randomDynamicData() {
69
+ // Go fetch some gofakeit data via post to json
70
+ fetch('https://api.gofakeit.com/json', {
71
+ method: 'POST',
72
+ headers: {
73
+ 'Content-Type': 'application/json',
74
+ },
75
+ body: JSON.stringify({
76
+ type: 'array',
77
+ rowcount: 20,
78
+ indent: false,
79
+ fields: [
80
+ {
81
+ name: 'key',
82
+ function: 'password',
83
+ params: {
84
+ lower: true,
85
+ upper: true,
86
+ numeric: true,
87
+ special: false,
88
+ space: false,
89
+ length: 10,
90
+ },
91
+ },
92
+ { name: 'first_name', function: 'firstname', params: {} },
93
+ { name: 'last_name', function: 'lastname', params: {} },
94
+ { name: 'selected', function: 'number', params: { min: 1, max: 10 } },
95
+ ],
96
+ }),
97
+ })
98
+ .then((response) => response.json())
99
+ .then((data: Person[]) => {
100
+ // Map the data to the format slim select expects
101
+ this.dynamicData = data.map((person: Person) => {
102
+ return {
103
+ id: person.id,
104
+ text: `${person.first_name} ${person.last_name}`,
105
+ value: `${person.first_name} ${person.last_name}`,
106
+ selected: person.selected >= 8,
107
+ } as OptionOptional
108
+ })
109
+ })
110
+ },
111
+ },
11
112
  })
12
113
  </script>
13
114
 
14
115
  <template>
15
- <div id="error" class="content">
116
+ <div id="vue" class="content">
16
117
  <h2 class="header">Vue</h2>
17
118
 
119
+ <h3>Install</h3>
120
+ <p>The vue component is in a sub package under SlimSelect</p>
121
+ <pre>
122
+ <code class="language-bash">
123
+ npm install @slim-select/vue
124
+ </code>
125
+ </pre>
126
+ <br />
127
+
128
+ <h3>Simple example</h3>
18
129
  <div class="row">
19
130
  <SlimSelect>
20
131
  <option value="1">Option 1</option>
21
132
  <option value="2">Option 2</option>
22
133
  <option value="3">Option 3</option>
23
134
  </SlimSelect>
135
+
136
+ <SlimSelect multiple>
137
+ <option value="1">Option 1</option>
138
+ <option value="2">Option 2</option>
139
+ <option value="3">Option 3</option>
140
+ </SlimSelect>
141
+ </div>
142
+
143
+ <pre>
144
+ <code class="language-javascript">
145
+ import { defineComponent } from 'vue'
146
+ import SlimSelect from '@slim-select/vue'
147
+
148
+ export default defineComponent({
149
+ components: {
150
+ SlimSelect,
151
+ },
152
+ })
153
+ </code>
154
+ </pre>
155
+
156
+ <pre>
157
+ <code class="language-html">
158
+ &lt;SlimSelect&gt;
159
+ &lt;option value="1"&gt;Option 1&lt;/option&gt;
160
+ &lt;option value="2"&gt;Option 2&lt;/option&gt;
161
+ &lt;option value="3"&gt;Option 3&lt;/option&gt;
162
+ &lt;/SlimSelect&gt;
163
+
164
+ &lt;SlimSelect multiple&gt;
165
+ &lt;option value="1"&gt;Option 1&lt;/option&gt;
166
+ &lt;option value="2"&gt;Option 2&lt;/option&gt;
167
+ &lt;option value="3"&gt;Option 3&lt;/option&gt;
168
+ &lt;/SlimSelect&gt;
169
+ </code>
170
+ </pre>
171
+
172
+ <br />
173
+ <div class="separator"></div>
174
+ <br />
175
+
176
+ <h3>Settings</h3>
177
+ <p>
178
+ Settings just like its passed as an object in normal SlimSelct will also be passed as an object to the component
179
+ prop
180
+ </p>
181
+
182
+ <div class="row">
183
+ <SlimSelect :settings="settings">
184
+ <option value="1">Option 1</option>
185
+ <option value="2">Option 2</option>
186
+ <option value="3">Option 3</option>
187
+ </SlimSelect>
188
+
189
+ <SlimSelect :settings="settings" multiple>
190
+ <option value="1">Option 1</option>
191
+ <option value="2">Option 2</option>
192
+ <option value="3">Option 3</option>
193
+ </SlimSelect>
194
+ </div>
195
+
196
+ <pre>
197
+ <code class="language-javascript">
198
+ import { defineComponent } from 'vue'
199
+ import SlimSelect from '@slim-select/vue'
200
+
201
+ export default defineComponent({
202
+ components: {
203
+ SlimSelect,
204
+ },
205
+ data() {
206
+ return {
207
+ settings: {
208
+ showSearch: false,
209
+ }
210
+ }
211
+ },
212
+ })
213
+ </code>
214
+ </pre>
215
+
216
+ <pre>
217
+ <code class="language-html">
218
+ &lt;SlimSelect :settings="settings"&gt;
219
+ &lt;option value="1"&gt;Option 1&lt;/option&gt;
220
+ &lt;option value="2"&gt;Option 2&lt;/option&gt;
221
+ &lt;option value="3"&gt;Option 3&lt;/option&gt;
222
+ &lt;/SlimSelect&gt;
223
+
224
+ &lt;SlimSelect :settings="settings" multiple&gt;
225
+ &lt;option value="1"&gt;Option 1&lt;/option&gt;
226
+ &lt;option value="2"&gt;Option 2&lt;/option&gt;
227
+ &lt;option value="3"&gt;Option 3&lt;/option&gt;
228
+ &lt;/SlimSelect&gt;
229
+ </code>
230
+ </pre>
231
+
232
+ <br />
233
+ <div class="separator"></div>
234
+ <br />
235
+
236
+ <h3>Data</h3>
237
+ <p>
238
+ Data just like its passed as an array in normal SlimSelct will also be passed as an array to the component prop.
239
+ </p>
240
+ <div class="alert info">
241
+ You may pass data as a prop if you would like. But you can also have reactive options that when options change the
242
+ select will update as well. See Reactivity below for more info.
243
+ </div>
244
+
245
+ <div class="row">
246
+ <div class="btn info" @click="changeData">Change data</div>
247
+ <SlimSelect ref="dataSingle" :data="data" />
248
+ <SlimSelect ref="dataMultiple" :data="data" multiple />
249
+ </div>
250
+
251
+ <pre>
252
+ <code class="language-javascript">
253
+ import { defineComponent } from 'vue'
254
+ import SlimSelect from '@slim-select/vue'
255
+
256
+ export default defineComponent({
257
+ components: {
258
+ SlimSelect,
259
+ },
260
+ data() {
261
+ return {
262
+ data: [
263
+ { value: 'value1', text: 'Value 1' },
264
+ { value: 'value2', text: 'Value 2' },
265
+ { value: 'value3', text: 'Value 3' },
266
+ ],
267
+ }
268
+ },
269
+ })
270
+ </code>
271
+ </pre>
272
+
273
+ <pre>
274
+ <code class="language-html">
275
+ &lt;SlimSelect :data="data" /&gt;
276
+
277
+ &lt;SlimSelect :data="data" multiple /&gt;
278
+ </code>
279
+ </pre>
280
+
281
+ <br />
282
+ <div class="separator"></div>
283
+ <br />
284
+
285
+ <h3>Events</h3>
286
+ <p>
287
+ Events just like its passed as an object in normal SlimSelct will also be passed as an object to the component
288
+ prop.
289
+ </p>
290
+
291
+ <div v-if="afterChangeData.length"><strong>afterChange:</strong> {{ afterChangeData }}</div>
292
+ <div class="row">
293
+ <SlimSelect :events="events">
294
+ <option value="1">Option 1</option>
295
+ <option value="2">Option 2</option>
296
+ <option value="3">Option 3</option>
297
+ </SlimSelect>
298
+
299
+ <SlimSelect :events="events" multiple>
300
+ <option value="1">Option 1</option>
301
+ <option value="2">Option 2</option>
302
+ <option value="3">Option 3</option>
303
+ </SlimSelect>
304
+ </div>
305
+
306
+ <pre>
307
+ <code class="language-javascript">
308
+ import { defineComponent } from 'vue'
309
+ import SlimSelect from '@slim-select/vue'
310
+
311
+ export default defineComponent({
312
+ components: {
313
+ SlimSelect,
314
+ },
315
+ data() {
316
+ return {
317
+ data: [],
318
+ }
319
+ },
320
+ methods: {
321
+ afterChange(newVal) {
322
+ console.log(newVal)
323
+ },
324
+ },
325
+ })
326
+ </code>
327
+ </pre>
328
+
329
+ <pre>
330
+ <code class="language-html">
331
+ &lt;SlimSelect :events="events"&gt;
332
+ &lt;option value="1"&gt;Option 1&lt;/option&gt;
333
+ &lt;option value="2"&gt;Option 2&lt;/option&gt;
334
+ &lt;option value="3"&gt;Option 3&lt;/option&gt;
335
+ &lt;/SlimSelect&gt;
336
+
337
+ &lt;SlimSelect :events="events" multiple&gt;
338
+ &lt;option value="1"&gt;Option 1&lt;/option&gt;
339
+ &lt;option value="2"&gt;Option 2&lt;/option&gt;
340
+ &lt;option value="3"&gt;Option 3&lt;/option&gt;
341
+ &lt;/SlimSelect&gt;
342
+ </code>
343
+ </pre>
344
+
345
+ <br />
346
+ <div class="separator"></div>
347
+ <br />
348
+
349
+ <h3>Reactivity</h3>
350
+ <p>
351
+ Slim select will look out for any options changes that happen to the select options and SlimSelect will update
352
+ accordingly. This is done via mutation observers.
353
+ </p>
354
+
355
+ <div class="row">
356
+ <div class="btn info" @click="randomDynamicData">Change data</div>
357
+ <SlimSelect ref="randomDynamic">
358
+ <option v-for="d in dynamicData" :key="d.id" :value="d.value" :selected="d.selected">{{ d.text }}</option>
359
+ </SlimSelect>
360
+
361
+ <SlimSelect multiple>
362
+ <option v-for="d in dynamicData" :value="d.value" :selected="d.selected">{{ d.text }}</option>
363
+ </SlimSelect>
24
364
  </div>
25
365
 
26
366
  <pre>
27
367
  <code class="language-javascript">
28
- var select = new SlimSelect({
29
- select: '#selectElement',
30
- events: {
31
- error: function(err) {
32
- console.error(err)
368
+ import { defineComponent } from 'vue'
369
+ import SlimSelect from '@slim-select/vue'
370
+
371
+ export default defineComponent({
372
+ components: {
373
+ SlimSelect,
374
+ },
375
+ data() {
376
+ return {
377
+ dynamicData: []
33
378
  }
34
- }
379
+ },
380
+ methods: {
381
+ changeData() {
382
+ this.dynamicData = [
383
+ { id: 1, value: 1, text: 'Option 1', selected: true },
384
+ { id: 2, value: 2, text: 'Option 2', selected: false },
385
+ { id: 3, value: 3, text: 'Option 3', selected: false },
386
+ ]
387
+ },
388
+ },
35
389
  })
36
390
  </code>
37
391
  </pre>
392
+
393
+ <pre>
394
+ <code class="language-html">
395
+ &lt;SlimSelect :events="events"&gt;
396
+ &lt;option v-for="d in dynamicData" :key="d.id" :value="d.value" :selected="d.selected"&gt;&#123;&#123; d.text &#125;&#125;&lt;/option&gt;
397
+ &lt;/SlimSelect&gt;
398
+
399
+ &lt;SlimSelect :events="events" multiple&gt;
400
+ &lt;option v-for="d in dynamicData" :value="d.value" :selected="d.selected"&gt;&#123;&#123; d.text &#125;&#125;&lt;/option&gt;
401
+ &lt;/SlimSelect&gt;
402
+ </code>
403
+ </pre>
38
404
  </div>
39
405
  </template>
@@ -166,26 +166,26 @@ export default defineComponent({
166
166
 
167
167
  <div class="row">
168
168
  <ul class="list">
169
- <li><img src="../images/check-mark.svg" /> No Dependencies</li>
170
- <li><img src="../images/check-mark.svg" /> ~30kb - ~5kb gzip</li>
171
- <li><img src="../images/check-mark.svg" /> Single Select</li>
172
- <li><img src="../images/check-mark.svg" /> Multiple Select</li>
173
- <li><img src="../images/check-mark.svg" /> Addable Options</li>
174
- <li><img src="../images/check-mark.svg" /> Html Options</li>
175
- <li><img src="../images/check-mark.svg" /> Settable Data</li>
176
- <li><img src="../images/check-mark.svg" /> Callback Events</li>
177
- <li><img src="../images/check-mark.svg" /> Placeholders</li>
169
+ <li><img src="../assets/images/check-mark.svg" /> No Dependencies</li>
170
+ <li><img src="../assets/images/check-mark.svg" /> ~30kb - ~5kb gzip</li>
171
+ <li><img src="../assets/images/check-mark.svg" /> Single Select</li>
172
+ <li><img src="../assets/images/check-mark.svg" /> Multiple Select</li>
173
+ <li><img src="../assets/images/check-mark.svg" /> Addable Options</li>
174
+ <li><img src="../assets/images/check-mark.svg" /> Html Options</li>
175
+ <li><img src="../assets/images/check-mark.svg" /> Settable Data</li>
176
+ <li><img src="../assets/images/check-mark.svg" /> Callback Events</li>
177
+ <li><img src="../assets/images/check-mark.svg" /> Placeholders</li>
178
178
  </ul>
179
179
  <ul class="list">
180
- <li><img src="../images/check-mark.svg" /> Advanced Search</li>
181
- <li><img src="../images/check-mark.svg" /> Tabbable</li>
182
- <li><img src="../images/check-mark.svg" /> Disable Options</li>
183
- <li><img src="../images/check-mark.svg" /> Light Css</li>
184
- <li><img src="../images/check-mark.svg" /> Light Color Scheme</li>
185
- <li><img src="../images/check-mark.svg" /> Style Inheritance</li>
186
- <li><img src="../images/check-mark.svg" /> Clean Animations</li>
187
- <li><img src="../images/check-mark.svg" /> Performant</li>
188
- <li><img src="../images/check-mark.svg" /> Typescript</li>
180
+ <li><img src="../assets/images/check-mark.svg" /> Advanced Search</li>
181
+ <li><img src="../assets/images/check-mark.svg" /> Tabbable</li>
182
+ <li><img src="../assets/images/check-mark.svg" /> Disable Options</li>
183
+ <li><img src="../assets/images/check-mark.svg" /> Light Css</li>
184
+ <li><img src="../assets/images/check-mark.svg" /> Light Color Scheme</li>
185
+ <li><img src="../assets/images/check-mark.svg" /> Style Inheritance</li>
186
+ <li><img src="../assets/images/check-mark.svg" /> Clean Animations</li>
187
+ <li><img src="../assets/images/check-mark.svg" /> Performant</li>
188
+ <li><img src="../assets/images/check-mark.svg" /> Typescript</li>
189
189
  </ul>
190
190
  </div>
191
191
  </div>
@@ -1,7 +1,8 @@
1
1
  <script lang="ts">
2
2
  import { defineComponent } from 'vue'
3
3
 
4
- import SlimSelect, { DataArray } from '../../../slim-select'
4
+ import SlimSelect from '../../../slim-select'
5
+ import { DataArray } from '../../../slim-select/store'
5
6
 
6
7
  export default defineComponent({
7
8
  name: 'GetData',
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { defineComponent } from 'vue'
3
3
 
4
- import SlimSelect, { DataArray } from '../../../slim-select'
4
+ import SlimSelect from '../../../slim-select'
5
5
 
6
6
  export default defineComponent({
7
7
  name: 'OpenClose',
@@ -14,7 +14,7 @@ export interface Config {
14
14
  export interface Events {
15
15
  search?: (searchValue: string, currentData: DataArray) => Promise<DataArrayPartial> | DataArrayPartial
16
16
  searchFilter?: (option: Option, search: string) => boolean
17
- addable?: (value: string) => OptionOptional | string
17
+ addable?: (value: string) => Promise<OptionOptional | string> | OptionOptional | string
18
18
  beforeChange?: (newVal: Option[], oldVal: Option[]) => boolean | void
19
19
  afterChange?: (newVal: Option[]) => void
20
20
  beforeOpen?: () => void
@@ -5,7 +5,7 @@ import Store, { DataArray, Optgroup, Option, OptionOptional } from './store'
5
5
  export interface Callbacks {
6
6
  open: () => void
7
7
  close: () => void
8
- addable?: (value: string) => OptionOptional | string
8
+ addable?: (value: string) => Promise<OptionOptional | string> | OptionOptional | string
9
9
  setSelected: (value: string[]) => void
10
10
  addOption: (option: Option) => void
11
11
  search: (search: string) => void
@@ -266,6 +266,8 @@ export default class Render {
266
266
  if (!this.settings.allowDeselect || this.settings.isMultiple) {
267
267
  deselect.classList.add(this.classes.hide)
268
268
  }
269
+
270
+ // Add deselect onclick event
269
271
  deselect.onclick = (e: Event) => {
270
272
  e.stopPropagation()
271
273
 
@@ -274,7 +276,29 @@ export default class Render {
274
276
  return
275
277
  }
276
278
 
277
- this.callbacks.setSelected([''])
279
+ // By Default we will delete
280
+ let shouldDelete = true
281
+ const before = this.store.getSelectedOptions()
282
+ const after = [] as Option[]
283
+
284
+ // Add beforeChange callback
285
+ if (this.callbacks.beforeChange) {
286
+ shouldDelete = this.callbacks.beforeChange(after, before) === true
287
+ }
288
+
289
+ if (shouldDelete) {
290
+ this.callbacks.setSelected([''])
291
+
292
+ // Check if we need to close the dropdown
293
+ if (this.settings.closeOnSelect) {
294
+ this.callbacks.close()
295
+ }
296
+
297
+ // Run afterChange callback
298
+ if (this.callbacks.afterChange) {
299
+ this.callbacks.afterChange(after)
300
+ }
301
+ }
278
302
  }
279
303
 
280
304
  // Add deselect svg
@@ -466,8 +490,11 @@ export default class Render {
466
490
 
467
491
  // Only add deletion if the option is not mandatory
468
492
  if (!option.mandatory) {
493
+ // Create delete div element
469
494
  const deleteDiv = document.createElement('div')
470
495
  deleteDiv.classList.add(this.classes.valueDelete)
496
+
497
+ // Add delete onclick event
471
498
  deleteDiv.onclick = (e: Event) => {
472
499
  e.preventDefault()
473
500
  e.stopPropagation()
@@ -656,13 +683,18 @@ export default class Render {
656
683
 
657
684
  // If addable is enabled, add the addable div
658
685
  if (this.callbacks.addable) {
686
+ // Add main class
659
687
  addable.classList.add(this.classes.addable)
688
+
689
+ // Add svg icon
660
690
  const plus = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
661
691
  plus.setAttribute('viewBox', '0 0 100 100')
662
692
  const plusPath = document.createElementNS('http://www.w3.org/2000/svg', 'path')
663
693
  plusPath.setAttribute('d', this.classes.addablePath)
664
694
  plus.appendChild(plusPath)
665
695
  addable.appendChild(plus)
696
+
697
+ // Add click event to addable div
666
698
  addable.onclick = (e: Event) => {
667
699
  e.preventDefault()
668
700
  e.stopPropagation()
@@ -679,35 +711,61 @@ export default class Render {
679
711
  return
680
712
  }
681
713
 
714
+ // Run finish will be ran at the end of the addable function.
715
+ // Reason its in a function is so we can run it after the
716
+ // addable function is done for promise based addables
717
+ const runFinish = (oo: OptionOptional) => {
718
+ let newOption = new Option(oo)
719
+
720
+ // Call addOption to add the new option
721
+ this.callbacks.addOption(newOption)
722
+
723
+ // set selected value for single and multiple
724
+ if (this.settings.isMultiple) {
725
+ let values = this.store.getSelected()
726
+ values.push(newOption.value)
727
+ this.callbacks.setSelected(values)
728
+ } else {
729
+ this.callbacks.setSelected([newOption.value])
730
+ }
731
+
732
+ // Clear search
733
+ this.callbacks.search('')
734
+
735
+ // Close it only if closeOnSelect = true
736
+ if (this.settings.closeOnSelect) {
737
+ setTimeout(() => {
738
+ // Give it a little padding for a better looking animation
739
+ this.callbacks.close()
740
+ }, 100)
741
+ }
742
+ }
743
+
682
744
  // Call addable callback
683
745
  const addableValue = this.callbacks.addable(inputValue)
684
746
 
685
- // If the addableValue is a string, we will add it as a new option
686
- // Otherwise we will assume it is an option object
687
- if (typeof addableValue === 'string') {
688
- this.callbacks.addOption(
689
- new Option({
690
- text: addableValue,
691
- value: addableValue,
692
- }),
693
- )
747
+ // If addableValue is a promise, wait for it to resolve
748
+ if (addableValue instanceof Promise) {
749
+ addableValue.then((value) => {
750
+ if (typeof value === 'string') {
751
+ runFinish({
752
+ text: value,
753
+ value: value,
754
+ })
755
+ } else {
756
+ runFinish(value)
757
+ }
758
+ })
759
+ } else if (typeof addableValue === 'string') {
760
+ runFinish({
761
+ text: addableValue,
762
+ value: addableValue,
763
+ })
694
764
  } else {
695
- this.callbacks.addOption(new Option(addableValue))
765
+ runFinish(addableValue)
696
766
  }
697
767
 
698
- // Add option to selected
699
- this.callbacks.setSelected([inputValue])
700
-
701
- // Clear search
702
- this.callbacks.search('')
703
-
704
- // Close it only if closeOnSelect = true
705
- if (this.settings.closeOnSelect) {
706
- setTimeout(() => {
707
- // Give it a little padding for a better looking animation
708
- this.callbacks.close()
709
- }, 100)
710
- }
768
+ return
711
769
  }
712
770
  main.appendChild(addable)
713
771