slim-select 3.4.3 → 3.6.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 (73) hide show
  1. package/dist/classes.d.ts +47 -0
  2. package/dist/helpers.d.ts +5 -0
  3. package/dist/index.d.ts +53 -319
  4. package/dist/index.umd.d.ts +2 -0
  5. package/dist/react/index.d.ts +4 -319
  6. package/dist/react/index.js +1471 -1697
  7. package/dist/react/index.umd.js +2 -2
  8. package/dist/react/react.d.ts +17 -0
  9. package/dist/react/react.test.d.ts +1 -0
  10. package/dist/react/slim-select/react/index.d.ts +4 -0
  11. package/dist/render.d.ts +90 -0
  12. package/dist/select.d.ts +38 -0
  13. package/dist/settings.d.ts +40 -0
  14. package/dist/slimselect.cjs.js +2 -2
  15. package/dist/slimselect.cjs.js.map +1 -1
  16. package/dist/slimselect.css +1 -1
  17. package/dist/slimselect.css.map +1 -1
  18. package/dist/slimselect.es.js +1245 -1385
  19. package/dist/slimselect.es.js.map +1 -1
  20. package/dist/slimselect.iife.js +2 -2
  21. package/dist/slimselect.iife.js.map +1 -1
  22. package/dist/slimselect.js +2 -2
  23. package/dist/slimselect.js.map +1 -1
  24. package/dist/src/docs/main.d.ts +0 -0
  25. package/dist/src/docs/router.d.ts +2 -0
  26. package/dist/src/docs/store.d.ts +12 -0
  27. package/dist/store.d.ts +53 -0
  28. package/dist/vue/index.d.ts +4 -319
  29. package/dist/vue/index.js +1347 -1504
  30. package/dist/vue/index.umd.js +1 -1
  31. package/dist/vue/slim-select/vue/index.d.ts +4 -0
  32. package/package.json +30 -36
  33. package/src/slim-select/slimselect.scss +47 -5
  34. package/.nvmrc +0 -1
  35. package/.prettierignore +0 -1
  36. package/.prettierrc +0 -7
  37. package/CODE_OF_CONDUCT.md +0 -46
  38. package/CONTRIBUTING.md +0 -1
  39. package/cdn.html +0 -21
  40. package/docs.go +0 -12
  41. package/example.html +0 -25
  42. package/index.html +0 -76
  43. package/release.js +0 -191
  44. package/sitemap.js +0 -108
  45. package/src/slim-select/accessibility.test.ts +0 -782
  46. package/src/slim-select/classes.test.ts +0 -73
  47. package/src/slim-select/classes.ts +0 -117
  48. package/src/slim-select/helpers.test.ts +0 -162
  49. package/src/slim-select/helpers.ts +0 -61
  50. package/src/slim-select/index.test.ts +0 -1356
  51. package/src/slim-select/index.ts +0 -594
  52. package/src/slim-select/index.umd.ts +0 -8
  53. package/src/slim-select/react/index.tsx +0 -9
  54. package/src/slim-select/react/react.test.tsx +0 -498
  55. package/src/slim-select/react/react.tsx +0 -209
  56. package/src/slim-select/render.test.ts +0 -1927
  57. package/src/slim-select/render.ts +0 -1771
  58. package/src/slim-select/select.test.ts +0 -683
  59. package/src/slim-select/select.ts +0 -659
  60. package/src/slim-select/settings.test.ts +0 -285
  61. package/src/slim-select/settings.ts +0 -78
  62. package/src/slim-select/store.test.ts +0 -1007
  63. package/src/slim-select/store.ts +0 -433
  64. package/src/slim-select/vue/index.ts +0 -9
  65. package/src/slim-select/vue/vue.test.ts +0 -1091
  66. package/src/slim-select/vue/vue.vue +0 -224
  67. package/tsconfig.json +0 -26
  68. package/vite.config.docs.mts +0 -29
  69. package/vite.config.lib.es-cjs.ts +0 -40
  70. package/vite.config.lib.umd-iife.ts +0 -34
  71. package/vite.config.react.mts +0 -41
  72. package/vite.config.vue.mts +0 -40
  73. package/vitest.config.ts +0 -30
@@ -1,285 +0,0 @@
1
- 'use strict'
2
-
3
- import { describe, expect, test, beforeEach } from 'vitest'
4
- import Settings from './settings'
5
- import Select from './select'
6
- import { Option, Optgroup } from './store'
7
-
8
- const defaultSettings: { [key: string]: any } = {
9
- id: 'ss-qucyuytu',
10
- style: '',
11
- class: [],
12
- isMultiple: false,
13
- isOpen: false,
14
- isFullOpen: false,
15
- intervalMove: null,
16
- disabled: false,
17
- alwaysOpen: false,
18
- showSearch: true,
19
- focusSearch: true,
20
- keepSearch: false,
21
- ariaLabel: 'Combobox',
22
- searchPlaceholder: 'Search...',
23
- searchText: 'No Results',
24
- searchingText: 'Searching...',
25
- searchHighlight: false,
26
- closeOnSelect: true,
27
- contentLocation: HTMLBodyElement,
28
- contentPosition: 'absolute',
29
- openPosition: 'auto',
30
- placeholderText: 'Select Value',
31
- allowDeselect: false,
32
- hideSelected: false,
33
- keepOrder: false,
34
- showOptionTooltips: false,
35
- minSelected: 0,
36
- maxSelected: 1000,
37
- timeoutDelay: 200,
38
- maxValuesShown: 20,
39
- maxValuesMessage: '{number} selected',
40
- contentWidth: ''
41
- }
42
-
43
- describe('Settings module', () => {
44
- let select: Select
45
-
46
- beforeEach(() => {
47
- const selectElement = document.createElement('select')
48
- select = new Select(selectElement)
49
- })
50
-
51
- test('empty constructor returns default settings', () => {
52
- // Convert to unknown and then to custom object to prevent TS from throwing errors
53
- const settings = new Settings() as unknown as { [key: string]: string }
54
- Object.keys(defaultSettings).forEach((key) => {
55
- if (key === 'id') {
56
- expect(settings[key].substring(0, 3)).toBe('ss-')
57
- } else if (key === 'contentLocation') {
58
- expect(settings[key]).toBeInstanceOf(defaultSettings[key])
59
- } else {
60
- expect(settings[key]).toStrictEqual(defaultSettings[key])
61
- }
62
- })
63
- })
64
-
65
- test('settings can be overwritten via the constructor', () => {
66
- const customSettings = {
67
- disabled: true,
68
- alwaysOpen: true,
69
- showSearch: false,
70
- focusSearch: true,
71
- searchHighlight: true,
72
- closeOnSelect: false,
73
- placeholderText: 'new placeholder',
74
- hideSelected: true,
75
- keepOrder: true,
76
- showOptionTooltips: true
77
- }
78
-
79
- const settingsWithOverride = {
80
- ...defaultSettings,
81
- ...customSettings
82
- } as unknown as { [key: string]: any }
83
-
84
- // Convert to unknown and then to custom object to prevent TS from throwing errors
85
- const settings = new Settings(customSettings) as unknown as { [key: string]: any }
86
- Object.keys(settingsWithOverride).forEach((key) => {
87
- if (key === 'id') {
88
- expect(settings[key].substring(0, 3)).toBe('ss-')
89
- } else if (key === 'contentLocation') {
90
- expect(settings[key]).toBeInstanceOf(defaultSettings[key])
91
- } else {
92
- expect(settings[key]).toStrictEqual(settingsWithOverride[key])
93
- }
94
- })
95
- })
96
-
97
- test('enable', () => {
98
- select.select.disabled = true
99
-
100
- select.enable()
101
- expect(select.select.disabled).toBe(false)
102
- })
103
-
104
- test('disable', () => {
105
- select.select.disabled = false
106
-
107
- select.disable()
108
- expect(select.select.disabled).toBe(true)
109
- })
110
-
111
- test('showUI', () => {
112
- select.select.setAttribute('tabindex', '1')
113
- select.select.setAttribute('aria-hidden', 'true')
114
- select.select.style.position = 'absolute'
115
- select.select.style.width = '0'
116
- select.select.style.opacity = '0'
117
- select.select.style.margin = '0'
118
- select.select.style.padding = '0'
119
- select.select.style.borderWidth = '0'
120
-
121
- select.showUI()
122
- expect(select.select.getAttribute('tabindex')).toBeFalsy()
123
- expect(select.select.getAttribute('aria-hidden')).toBeFalsy()
124
- expect(select.select.style.position).toBeFalsy()
125
- expect(select.select.style.width).toBeFalsy()
126
- expect(select.select.style.opacity).toBeFalsy()
127
- expect(select.select.style.margin).toBeFalsy()
128
- expect(select.select.style.padding).toBeFalsy()
129
- // borderWidth gets reset
130
- })
131
-
132
- describe('createOptgroup', () => {
133
- test('group gets created correctly', () => {
134
- const optGroup = new Optgroup({
135
- label: 'test',
136
- options: [
137
- {
138
- text: 'opt 1'
139
- },
140
- {
141
- text: 'opt 2'
142
- }
143
- ]
144
- })
145
-
146
- const optGroupElement = select.createOptgroup(optGroup)
147
-
148
- expect(optGroupElement).toBeInstanceOf(HTMLOptGroupElement)
149
- expect(optGroupElement.children).toHaveLength(2)
150
- })
151
-
152
- test('selectAll get set correctly', () => {
153
- const optGroup = new Optgroup({
154
- label: 'test',
155
- selectAll: true,
156
- options: [
157
- {
158
- text: 'opt 1'
159
- },
160
- {
161
- text: 'opt 2'
162
- }
163
- ]
164
- })
165
-
166
- const optGroupElement = select.createOptgroup(optGroup)
167
-
168
- expect(optGroupElement).toBeInstanceOf(HTMLOptGroupElement)
169
- expect(optGroupElement.dataset.selectAll).toBe('true')
170
- })
171
-
172
- test('closable get set correctly', () => {
173
- const optGroup = new Optgroup({
174
- label: 'test',
175
- closable: 'open',
176
- options: [
177
- {
178
- text: 'opt 1'
179
- },
180
- {
181
- text: 'opt 2'
182
- }
183
- ]
184
- })
185
-
186
- const optGroupElement = select.createOptgroup(optGroup)
187
-
188
- expect(optGroupElement).toBeInstanceOf(HTMLOptGroupElement)
189
- expect(optGroupElement.dataset.closable).toBe(optGroup.closable)
190
- })
191
- })
192
-
193
- describe('createOption', () => {
194
- test('correct content is set', () => {
195
- const option = new Option({ text: 'opt' })
196
- const optionElement = select.createOption(option)
197
-
198
- expect(optionElement).toBeInstanceOf(HTMLOptionElement)
199
- expect(optionElement.id).toBe(option.id)
200
- expect(optionElement.textContent).toBe(option.text)
201
- })
202
-
203
- test('HTML is set as data attribute', () => {
204
- const option = new Option({ text: 'opt', html: '<h1>opt</h1>' })
205
- const optionElement = select.createOption(option)
206
-
207
- expect(optionElement.dataset.html).toBe(option.html)
208
- })
209
-
210
- test('malicious text is inserted with innerText', () => {
211
- // decoded text: <img src=x onerror=alert(1)></img>
212
- const str =
213
- '&#x3c;&#x69;&#x6d;&#x67;&#x20;&#x73;&#x72;&#x63;&#x3d;&#x78;&#x20;&#x6f;&#x6e;&#x65;&#x72;&#x72;&#x6f;&#x72;&#x3d;&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;&#x3e;&#x3c;&#x2f;&#x69;&#x6d;&#x67;&#x3e;'
214
- // const str = 'opt'
215
- const decode = (string: string | null) => {
216
- if (string === null) return ''
217
- const doc = new DOMParser().parseFromString(string, 'text/html')
218
- return doc.documentElement.textContent
219
- }
220
- const option = new Option({ text: str })
221
- const optionElement = select.createOption(option)
222
- // expect(decode(optionElement.textContent)).toBe('opt')
223
- expect(optionElement.textContent).toBe(str)
224
- })
225
-
226
- test('disabled sets disabled property correctly', () => {
227
- const option = new Option({ text: 'opt', disabled: true })
228
- const optionElement = select.createOption(option)
229
-
230
- expect(optionElement.disabled).toBe(true)
231
- })
232
-
233
- test('display false sets inline style correctly', () => {
234
- const option = new Option({ text: 'opt', display: false })
235
- const optionElement = select.createOption(option)
236
-
237
- expect(optionElement.style.display).toBe('none')
238
- })
239
-
240
- test('placeholder and mandatory set data attributes correctly', () => {
241
- const option = new Option({
242
- text: 'opt',
243
- placeholder: true,
244
- mandatory: true
245
- })
246
- const optionElement = select.createOption(option)
247
-
248
- expect(optionElement.dataset.placeholder).toBeTruthy()
249
- expect(optionElement.dataset.mandatory).toBeTruthy()
250
- })
251
-
252
- test('class sets CSS classes correctly', () => {
253
- const option = new Option({
254
- text: 'opt',
255
- class: 'class0 class1 class2'
256
- })
257
- const optionElement = select.createOption(option)
258
-
259
- expect(optionElement.classList.contains('class0')).toBe(true)
260
- expect(optionElement.classList.contains('class1')).toBe(true)
261
- expect(optionElement.classList.contains('class2')).toBe(true)
262
- })
263
-
264
- test('custom data attributes are set correctly', () => {
265
- const option = new Option({
266
- text: 'opt',
267
- data: {
268
- test0: 'a',
269
- test1: 'b'
270
- }
271
- })
272
- const optionElement = select.createOption(option)
273
-
274
- expect(optionElement.dataset.test0).toBe('a')
275
- expect(optionElement.dataset.test1).toBe('b')
276
- })
277
- })
278
-
279
- test('destroy', () => {
280
- select.destroy()
281
-
282
- expect((<any>select).observer).toBeFalsy()
283
- expect('id' in select.select.dataset).toBeFalsy()
284
- })
285
- })
@@ -1,78 +0,0 @@
1
- import { generateID } from './helpers'
2
-
3
- export default class Settings {
4
- public id: string = '' // Primary ID for the select
5
- public style: string = '' // Style attribute from the select element
6
- public class: string[] = [] // Class attribute from the select element
7
-
8
- // Dynamic settings
9
- public isMultiple: boolean = false
10
- public isOpen: boolean = false
11
- public isFullOpen: boolean = false
12
- public intervalMove: ReturnType<typeof setInterval> | null = null
13
-
14
- // Fields set from constructor
15
- public disabled: boolean
16
- public alwaysOpen: boolean
17
- public showSearch: boolean
18
- public focusSearch: boolean
19
- public keepSearch: boolean
20
- public ariaLabel: string
21
- public searchPlaceholder: string
22
- public searchText: string
23
- public searchingText: string
24
- public searchHighlight: boolean
25
- public closeOnSelect: boolean
26
- public contentLocation: HTMLElement | null
27
- public contentPosition: 'relative' | 'absolute' | 'fixed'
28
- public contentWidth: string
29
- public openPosition: 'auto' | 'up' | 'down'
30
- public placeholderText: string
31
- public allowDeselect: boolean
32
- public hideSelected: boolean
33
- public keepOrder: boolean
34
- public showOptionTooltips: boolean
35
- public minSelected: number
36
- public maxSelected: number
37
- public timeoutDelay: number
38
- public maxValuesShown: number
39
- public maxValuesMessage: string
40
- public addableText: string
41
-
42
- constructor(settings?: Partial<Settings>) {
43
- if (!settings) {
44
- settings = {}
45
- }
46
-
47
- this.id = 'ss-' + generateID()
48
- this.style = settings.style || ''
49
- this.class = settings.class || []
50
-
51
- this.disabled = settings.disabled !== undefined ? settings.disabled : false
52
- this.alwaysOpen = settings.alwaysOpen !== undefined ? settings.alwaysOpen : false
53
- this.showSearch = settings.showSearch !== undefined ? settings.showSearch : true
54
- this.focusSearch = settings.focusSearch !== undefined ? settings.focusSearch : true
55
- this.keepSearch = settings.keepSearch !== undefined ? settings.keepSearch : false
56
- this.ariaLabel = settings.ariaLabel || 'Combobox'
57
- this.searchPlaceholder = settings.searchPlaceholder || 'Search...'
58
- this.searchText = settings.searchText || 'No Results'
59
- this.searchingText = settings.searchingText || 'Searching...'
60
- this.searchHighlight = settings.searchHighlight !== undefined ? settings.searchHighlight : false
61
- this.closeOnSelect = settings.closeOnSelect !== undefined ? settings.closeOnSelect : true
62
- this.contentLocation = settings.contentLocation || document.body
63
- this.contentPosition = settings.contentPosition || 'absolute'
64
- this.contentWidth = settings.contentWidth || ''
65
- this.openPosition = settings.openPosition || 'auto' // options: auto, up, down
66
- this.placeholderText = settings.placeholderText !== undefined ? settings.placeholderText : 'Select Value'
67
- this.allowDeselect = settings.allowDeselect !== undefined ? settings.allowDeselect : false
68
- this.hideSelected = settings.hideSelected !== undefined ? settings.hideSelected : false
69
- this.keepOrder = settings.keepOrder !== undefined ? settings.keepOrder : false
70
- this.showOptionTooltips = settings.showOptionTooltips !== undefined ? settings.showOptionTooltips : false
71
- this.minSelected = settings.minSelected || 0
72
- this.maxSelected = settings.maxSelected || 1000
73
- this.timeoutDelay = settings.timeoutDelay || 200
74
- this.maxValuesShown = settings.maxValuesShown || 20
75
- this.maxValuesMessage = settings.maxValuesMessage || '{number} selected'
76
- this.addableText = settings.addableText || 'Press "Enter" to add {value}'
77
- }
78
- }