slim-select 3.4.2 → 3.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 (73) hide show
  1. package/dist/classes.d.ts +46 -0
  2. package/dist/helpers.d.ts +5 -0
  3. package/dist/index.d.ts +53 -318
  4. package/dist/index.umd.d.ts +2 -0
  5. package/dist/react/index.d.ts +4 -318
  6. package/dist/react/index.js +1459 -1696
  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 +88 -0
  12. package/dist/select.d.ts +38 -0
  13. package/dist/settings.d.ts +39 -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 +1233 -1384
  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 -318
  29. package/dist/vue/index.js +1335 -1503
  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 +34 -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 -1877
  57. package/src/slim-select/render.ts +0 -1765
  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,224 +0,0 @@
1
- <script lang="ts">
2
- import { defineComponent, PropType } from 'vue'
3
- import SlimSelect, { Config, Events, Option, Optgroup, Settings } from '../index'
4
-
5
- export default defineComponent({
6
- name: 'SlimSelect',
7
- props: {
8
- modelValue: {
9
- type: [String, Array, undefined] as PropType<string | string[] | undefined>
10
- },
11
- multiple: {
12
- type: Boolean,
13
- default: false
14
- },
15
- data: {
16
- type: Array as PropType<(Partial<Option> | Partial<Optgroup>)[]>
17
- },
18
- settings: {
19
- type: Object as PropType<Partial<Settings>>
20
- },
21
- events: {
22
- type: Object as PropType<Events>,
23
- default: () => {
24
- return {}
25
- }
26
- }
27
- },
28
- emits: ['update:modelValue'],
29
- data() {
30
- return {
31
- slim: null as SlimSelect | null
32
- }
33
- },
34
- mounted() {
35
- // Warning: If both slot and data are provided, data takes precedence
36
- const hasSlotContent = this.$slots.default && this.$slots.default().length > 0
37
- if (hasSlotContent && this.data) {
38
- console.warn(
39
- '[SlimSelect Vue] Both slot content and data prop are provided. Data prop will take precedence and slot content will be ignored.'
40
- )
41
- }
42
-
43
- let config = {
44
- select: this.$refs.slim
45
- } as Config
46
-
47
- // If data is passed in, use it
48
- if (this.data) {
49
- config.data = this.data
50
- }
51
-
52
- // If settings are passed in, use it
53
- if (this.settings) {
54
- config.settings = this.settings
55
- }
56
-
57
- // Create a copy of events to avoid mutating the prop
58
- const ogAfterChange = this.events?.afterChange
59
- config.events = {
60
- ...this.events,
61
- afterChange: (newVal: Option[]) => {
62
- this.handleAfterChange(newVal, ogAfterChange)
63
- }
64
- }
65
-
66
- // Initialize SlimSelect
67
- this.slim = new SlimSelect(config)
68
-
69
- // Sync initial modelValue to SlimSelect
70
- this.syncModelValueToSlimSelect(false)
71
- },
72
- updated() {
73
- // After DOM updates (like slot content changes), sync selection from modelValue
74
- // This ensures :selected attribute isn't needed on slot options
75
- if (this.slim && !this.data) {
76
- const currentSelected = this.slim.getSelected()
77
- const modelValues = Array.isArray(this.value) ? this.value : [this.value]
78
- const needsSync = JSON.stringify(currentSelected.sort()) !== JSON.stringify(modelValues.sort())
79
-
80
- if (needsSync) {
81
- // Use the same sync method to handle invalid values properly
82
- this.syncModelValueToSlimSelect(false)
83
- }
84
- }
85
- },
86
- beforeUnmount() {
87
- if (this.slim) {
88
- this.slim.destroy()
89
- }
90
- },
91
- watch: {
92
- modelValue: {
93
- handler: function (newVal: string | string[] | undefined) {
94
- if (!this.slim) return
95
- // Sync modelValue to SlimSelect (don't trigger afterChange when programmatically updating from parent)
96
- this.syncModelValueToSlimSelect(false)
97
- }
98
- },
99
- data: {
100
- handler: function (newData) {
101
- if (this.slim) {
102
- this.slim.setData(newData)
103
- }
104
- },
105
- deep: true
106
- }
107
- },
108
- computed: {
109
- value: {
110
- get(): string | string[] {
111
- return this.getCleanValue(this.$props.modelValue)
112
- },
113
- set(value: string | string[]) {
114
- this.$emit('update:modelValue', value)
115
- }
116
- }
117
- },
118
- methods: {
119
- // This allows via a ref to call the SlimSelect methods
120
- getSlimSelect() {
121
- return this.slim
122
- },
123
- handleAfterChange(newVal: Option[], ogAfterChange?: (newVal: Option[]) => void): void {
124
- if (!this.slim) return
125
-
126
- const value = this.multiple ? newVal.map((option) => option.value) : newVal.length > 0 ? newVal[0].value : ''
127
-
128
- // Check if the current v-model value exists in options
129
- // If it doesn't exist, don't update v-model (preserve invalid value like regular HTML select)
130
- const currentValue = this.getCleanValue(this.$props.modelValue)
131
- const options = this.slim.store.getDataOptions()
132
- const currentValueExists = Array.isArray(currentValue)
133
- ? currentValue.length > 0 && currentValue.every((val) => options.some((opt) => opt.value === val))
134
- : currentValue !== '' && options.some((opt) => opt.value === currentValue)
135
-
136
- // Check if the new value is valid (exists in options)
137
- const newValueIsValid = Array.isArray(value)
138
- ? value.length > 0 && value.every((val) => options.some((opt) => opt.value === val))
139
- : value !== '' && options.some((opt) => opt.value === value)
140
-
141
- // Check if value actually changed (properly compare arrays)
142
- const valueChanged =
143
- Array.isArray(value) && Array.isArray(this.value)
144
- ? JSON.stringify(value.sort()) !== JSON.stringify(this.value.sort())
145
- : this.value !== value
146
-
147
- // Only update v-model if:
148
- // 1. The value actually changed, AND
149
- // 2. Either the current v-model value exists in options, OR we're setting to a valid non-empty value
150
- // This prevents clearing invalid v-model values when we show placeholder
151
- if (valueChanged && (currentValueExists || newValueIsValid)) {
152
- this.value = value
153
- }
154
-
155
- // Call the original afterChange callback if it exists
156
- if (ogAfterChange) {
157
- ogAfterChange(newVal)
158
- }
159
- },
160
- getCleanValue(val: string | string[] | undefined): string | string[] {
161
- const multi = this.$props.multiple
162
-
163
- // If its multiple and the modelValue is a string, return an array with the string
164
- if (typeof val === 'string') {
165
- return multi ? [val] : val
166
- }
167
-
168
- // If its not multiple and the modelValue is an array, return the first item
169
- if (Array.isArray(val)) {
170
- return multi ? val : val[0]
171
- }
172
-
173
- return multi ? [] : ''
174
- },
175
- syncModelValueToSlimSelect(runAfterChange: boolean = false): void {
176
- if (!this.slim) return
177
-
178
- // Only sync if modelValue is explicitly set (not undefined)
179
- // This prevents adding placeholders when modelValue is not provided
180
- if (this.$props.modelValue === undefined) {
181
- return
182
- }
183
-
184
- const cleanValue = this.getCleanValue(this.$props.modelValue)
185
- const data = this.slim.getData()
186
- // Extract options from data (flatten optgroups if any)
187
- const options = data.flatMap((item: Option | Optgroup) => ('label' in item ? item.options : [item])) as Option[]
188
-
189
- // Check if the value exists in options
190
- const valueExists = Array.isArray(cleanValue)
191
- ? cleanValue.length > 0 && cleanValue.every((val) => options.some((opt) => opt.value === val))
192
- : cleanValue !== '' && options.some((opt) => opt.value === cleanValue)
193
-
194
- // If value doesn't exist in options and it's not empty, add a placeholder option
195
- if (!valueExists) {
196
- // If its not multiple, add a placeholder option
197
- if (!Array.isArray(cleanValue)) {
198
- // For single select, check if placeholder already exists
199
- const hasPlaceholder = options.some((opt) => opt.placeholder)
200
- if (!hasPlaceholder) {
201
- // Get current data and prepend placeholder option
202
- const currentData = this.slim.getData()
203
- const placeholderOption: Partial<Option> = {
204
- value: '',
205
- text: '',
206
- placeholder: true
207
- }
208
- this.slim.setData([placeholderOption].concat(currentData))
209
- }
210
- }
211
- }
212
-
213
- // Set the selected value (will select placeholder if it was just added)
214
- this.slim.setSelected(cleanValue, runAfterChange)
215
- }
216
- }
217
- })
218
- </script>
219
-
220
- <template>
221
- <select :multiple="multiple" ref="slim">
222
- <slot />
223
- </select>
224
- </template>
package/tsconfig.json DELETED
@@ -1,26 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "baseUrl": ".",
4
- "rootDir": "src",
5
- "outDir": "dist",
6
- "declaration": true,
7
- "target": "esnext",
8
- "useDefineForClassFields": true,
9
- "module": "esnext",
10
- "moduleResolution": "bundler",
11
- "jsx": "react-jsx",
12
- "strict": true,
13
- "allowJs": false,
14
- "skipLibCheck": true,
15
- "sourceMap": true,
16
- "resolveJsonModule": true,
17
- "esModuleInterop": true,
18
- "importHelpers": true,
19
- "lib": ["esnext", "dom"],
20
- "paths": {
21
- "@/*": ["src/*"]
22
- }
23
- },
24
- "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.d.ts"],
25
- "exclude": ["dist", "node_modules"]
26
- }
@@ -1,29 +0,0 @@
1
- import vue from '@vitejs/plugin-vue'
2
- import { defineConfig } from 'vite'
3
- import path from 'path'
4
-
5
- // https://vitejs.dev/config/
6
- export default defineConfig({
7
- base: '/',
8
- resolve: {
9
- alias: {
10
- '@': path.resolve(__dirname, 'src')
11
- }
12
- },
13
- server: {
14
- port: 1111
15
- },
16
- build: {
17
- outDir: 'docs',
18
- emptyOutDir: true,
19
- rollupOptions: {
20
- output: {
21
- entryFileNames: `assets/[name].js`,
22
- chunkFileNames: `assets/[name].js`,
23
- assetFileNames: `assets/[name].[ext]`,
24
- manualChunks: () => 'index'
25
- }
26
- }
27
- },
28
- plugins: [vue()]
29
- })
@@ -1,40 +0,0 @@
1
- import { defineConfig } from 'vite'
2
- import path from 'path'
3
- import dts from 'vite-plugin-dts'
4
-
5
- export default defineConfig({
6
- publicDir: false,
7
- resolve: {
8
- alias: {
9
- '@': path.resolve(__dirname, 'src')
10
- }
11
- },
12
- build: {
13
- minify: true,
14
- sourcemap: true,
15
- emptyOutDir: false, // package.json rimraf ./dist/*
16
- lib: {
17
- entry: path.resolve(__dirname, 'src/slim-select/index.ts'),
18
- formats: ['es', 'cjs'],
19
- fileName: (format) => (format === 'es' ? 'slimselect.es.js' : 'slimselect.cjs.js')
20
- },
21
- outDir: path.resolve(__dirname, 'dist'),
22
- rollupOptions: {
23
- output: {
24
- exports: 'named',
25
- assetFileNames: (assetInfo) => {
26
- if (assetInfo.name === 'style.css') return 'slimselect.css'
27
- return assetInfo.name || 'asset'
28
- }
29
- }
30
- }
31
- },
32
- plugins: [
33
- dts({
34
- rollupTypes: true,
35
- outDir: path.resolve(__dirname, 'dist'),
36
- entryRoot: path.resolve(__dirname, 'src/slim-select'),
37
- exclude: [path.resolve(__dirname, 'src/slim-select/**/*.test.ts')]
38
- })
39
- ]
40
- })
@@ -1,34 +0,0 @@
1
- import { defineConfig } from 'vite'
2
- import path from 'path'
3
-
4
- export default defineConfig({
5
- publicDir: false,
6
- resolve: {
7
- alias: {
8
- '@': path.resolve(__dirname, 'src')
9
- }
10
- },
11
- build: {
12
- minify: true,
13
- sourcemap: true,
14
- emptyOutDir: false, // package.json rimraf ./dist/*
15
- lib: {
16
- entry: path.resolve(__dirname, 'src/slim-select/index.umd.ts'),
17
- name: 'SlimSelect',
18
- formats: ['umd', 'iife'],
19
- fileName: (format) => (format === 'iife' ? 'slimselect.iife.js' : 'slimselect.js')
20
- },
21
- outDir: path.resolve(__dirname, 'dist'),
22
- rollupOptions: {
23
- output: {
24
- exports: 'default',
25
- assetFileNames: (assetInfo) => {
26
- if (assetInfo.name === 'style.css') return 'slimselect.css'
27
- return assetInfo.name || 'asset'
28
- },
29
- banner: '/*! SlimSelect - Advanced select dropdown */',
30
- footer: '/*! End SlimSelect */'
31
- }
32
- }
33
- }
34
- })
@@ -1,41 +0,0 @@
1
- import { defineConfig } from 'vite'
2
- import react from '@vitejs/plugin-react'
3
- import path from 'path'
4
- import dts from 'vite-plugin-dts'
5
-
6
- export default defineConfig({
7
- publicDir: false,
8
- resolve: {
9
- alias: {
10
- '@': path.resolve(__dirname, 'src')
11
- }
12
- },
13
- build: {
14
- emptyOutDir: false, // package.json rimraf ./dist/*
15
- lib: {
16
- entry: path.resolve(__dirname, 'src/slim-select/react/index.tsx'),
17
- name: 'SlimSelectReact',
18
- formats: ['es', 'umd'],
19
- fileName: (format) => `index.${format === 'es' ? 'js' : 'umd.js'}`
20
- },
21
- outDir: 'dist/react',
22
- rollupOptions: {
23
- external: ['react', 'react-dom'],
24
- output: {
25
- exports: 'named',
26
- globals: {
27
- react: 'React',
28
- 'react-dom': 'ReactDOM'
29
- }
30
- }
31
- }
32
- },
33
- plugins: [
34
- react(),
35
- dts({
36
- rollupTypes: true,
37
- include: ['src/slim-select/react/index.tsx'],
38
- exclude: ['src/slim-select/**/*.test.ts', 'src/docs/**/*']
39
- })
40
- ]
41
- })
@@ -1,40 +0,0 @@
1
- import vue from '@vitejs/plugin-vue'
2
- import { defineConfig } from 'vite'
3
- import dts from 'vite-plugin-dts'
4
- import path from 'path'
5
-
6
- export default defineConfig({
7
- publicDir: false,
8
- resolve: {
9
- alias: {
10
- '@': path.resolve(__dirname, 'src')
11
- }
12
- },
13
- build: {
14
- emptyOutDir: false, // package.json rimraf ./dist/*
15
- lib: {
16
- entry: path.resolve(__dirname, 'src/slim-select/vue/index.ts'),
17
- name: 'SlimSelectVue',
18
- formats: ['es', 'umd'],
19
- fileName: (format) => `index.${format === 'es' ? 'js' : 'umd.js'}`
20
- },
21
- outDir: path.resolve(__dirname, 'dist/vue'),
22
- rollupOptions: {
23
- external: ['vue'],
24
- output: {
25
- exports: 'named',
26
- globals: {
27
- vue: 'Vue'
28
- }
29
- }
30
- }
31
- },
32
- plugins: [
33
- vue(),
34
- dts({
35
- rollupTypes: true,
36
- include: ['src/slim-select/vue/index.ts'],
37
- exclude: ['src/slim-select/**/*.test.ts', 'src/docs/**/*']
38
- })
39
- ]
40
- })
package/vitest.config.ts DELETED
@@ -1,30 +0,0 @@
1
- import { defineConfig } from 'vitest/config'
2
- import vue from '@vitejs/plugin-vue'
3
- import react from '@vitejs/plugin-react'
4
- import path from 'path'
5
-
6
- export default defineConfig({
7
- plugins: [vue(), react()],
8
- resolve: {
9
- alias: {
10
- '@': path.resolve(__dirname, 'src')
11
- }
12
- },
13
- test: {
14
- globals: true,
15
- environment: 'jsdom',
16
- include: ['src/**/*.test.{ts,tsx}'],
17
- coverage: {
18
- provider: 'v8',
19
- reporter: ['text', 'json', 'html', 'lcov'],
20
- include: ['src/slim-select/**/*.ts'],
21
- exclude: ['src/slim-select/**/*.test.ts', 'src/slim-select/vue/index.ts'],
22
- thresholds: {
23
- lines: 75,
24
- functions: 75,
25
- branches: 75,
26
- statements: 75
27
- }
28
- }
29
- }
30
- })