@smilodon/svelte 1.0.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.
- package/README.md +364 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.mjs +353 -0
- package/dist/index.mjs.map +1 -0
- package/dist/types/Select.svelte.d.ts +59 -0
- package/dist/types/index.d.ts +23 -0
- package/package.json +71 -0
package/README.md
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
# @smilodon/svelte
|
|
2
|
+
|
|
3
|
+
Production-ready, accessible select component for Svelte applications. Part of the [Smilodon](https://github.com/navidrezadoost/smilodon) UI toolkit.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✨ **Single & Multi-Select** - Choose one or multiple options
|
|
8
|
+
- 🔍 **Searchable** - Filter options with built-in or custom search
|
|
9
|
+
- ♿ **Fully Accessible** - WCAG 2.1 AAA compliant
|
|
10
|
+
- ⚡ **Virtual Scrolling** - Handle 100k+ options smoothly
|
|
11
|
+
- 📜 **Infinite Scroll** - Load data progressively
|
|
12
|
+
- 👥 **Grouped Options** - Organize options into categories
|
|
13
|
+
- 🎨 **Customizable** - Style with CSS variables or custom themes
|
|
14
|
+
- 📦 **Tiny Bundle** - ~2KB gzipped
|
|
15
|
+
- 🔧 **TypeScript** - Full type safety included
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @smilodon/svelte @smilodon/core
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
```svelte
|
|
26
|
+
<script lang="ts">
|
|
27
|
+
import { Select } from '@smilodon/svelte';
|
|
28
|
+
|
|
29
|
+
const items = [
|
|
30
|
+
{ value: '1', label: 'Apple' },
|
|
31
|
+
{ value: '2', label: 'Banana' },
|
|
32
|
+
{ value: '3', label: 'Cherry' },
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
let selectedValue;
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<Select {items} bind:value={selectedValue} placeholder="Select a fruit..." />
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Examples
|
|
42
|
+
|
|
43
|
+
### Searchable Select
|
|
44
|
+
|
|
45
|
+
```svelte
|
|
46
|
+
<script lang="ts">
|
|
47
|
+
import { Select } from '@smilodon/svelte';
|
|
48
|
+
|
|
49
|
+
const items = [
|
|
50
|
+
{ value: 'us', label: 'United States' },
|
|
51
|
+
{ value: 'ca', label: 'Canada' },
|
|
52
|
+
{ value: 'mx', label: 'Mexico' },
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
let country;
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
<Select
|
|
59
|
+
{items}
|
|
60
|
+
bind:value={country}
|
|
61
|
+
searchable
|
|
62
|
+
placeholder="Search countries..."
|
|
63
|
+
/>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Multi-Select
|
|
67
|
+
|
|
68
|
+
```svelte
|
|
69
|
+
<script lang="ts">
|
|
70
|
+
import { Select } from '@smilodon/svelte';
|
|
71
|
+
|
|
72
|
+
const items = [
|
|
73
|
+
{ value: 'js', label: 'JavaScript' },
|
|
74
|
+
{ value: 'ts', label: 'TypeScript' },
|
|
75
|
+
{ value: 'py', label: 'Python' },
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
let languages = [];
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<Select
|
|
82
|
+
{items}
|
|
83
|
+
bind:value={languages}
|
|
84
|
+
multiple
|
|
85
|
+
placeholder="Select languages..."
|
|
86
|
+
/>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Grouped Options
|
|
90
|
+
|
|
91
|
+
```svelte
|
|
92
|
+
<script lang="ts">
|
|
93
|
+
import { Select } from '@smilodon/svelte';
|
|
94
|
+
|
|
95
|
+
const groupedItems = [
|
|
96
|
+
{
|
|
97
|
+
group: 'Fruits',
|
|
98
|
+
items: [
|
|
99
|
+
{ value: 'apple', label: 'Apple' },
|
|
100
|
+
{ value: 'banana', label: 'Banana' },
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
group: 'Vegetables',
|
|
105
|
+
items: [
|
|
106
|
+
{ value: 'carrot', label: 'Carrot' },
|
|
107
|
+
{ value: 'potato', label: 'Potato' },
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
|
|
112
|
+
let food;
|
|
113
|
+
</script>
|
|
114
|
+
|
|
115
|
+
<Select {groupedItems} bind:value={food} />
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Infinite Scroll
|
|
119
|
+
|
|
120
|
+
```svelte
|
|
121
|
+
<script lang="ts">
|
|
122
|
+
import { Select } from '@smilodon/svelte';
|
|
123
|
+
|
|
124
|
+
let items = generateItems(1, 50);
|
|
125
|
+
let page = 1;
|
|
126
|
+
|
|
127
|
+
function handleLoadMore() {
|
|
128
|
+
page++;
|
|
129
|
+
const newItems = generateItems(page * 50 + 1, (page + 1) * 50);
|
|
130
|
+
items = [...items, ...newItems];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function generateItems(start, end) {
|
|
134
|
+
return Array.from({ length: end - start + 1 }, (_, i) => ({
|
|
135
|
+
value: start + i,
|
|
136
|
+
label: `Item ${start + i}`,
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
139
|
+
</script>
|
|
140
|
+
|
|
141
|
+
<Select
|
|
142
|
+
{items}
|
|
143
|
+
infiniteScroll
|
|
144
|
+
pageSize={50}
|
|
145
|
+
on:loadMore={handleLoadMore}
|
|
146
|
+
placeholder="Scroll to load more..."
|
|
147
|
+
/>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Virtual Scrolling (Large Datasets)
|
|
151
|
+
|
|
152
|
+
```svelte
|
|
153
|
+
<script lang="ts">
|
|
154
|
+
import { Select } from '@smilodon/svelte';
|
|
155
|
+
|
|
156
|
+
// Generate 100,000 items
|
|
157
|
+
const items = Array.from({ length: 100000 }, (_, i) => ({
|
|
158
|
+
value: i + 1,
|
|
159
|
+
label: `Item ${i + 1}`,
|
|
160
|
+
}));
|
|
161
|
+
</script>
|
|
162
|
+
|
|
163
|
+
<Select
|
|
164
|
+
{items}
|
|
165
|
+
virtualized
|
|
166
|
+
searchable
|
|
167
|
+
placeholder="100k items with virtual scrolling..."
|
|
168
|
+
/>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Server-Side Search
|
|
172
|
+
|
|
173
|
+
```svelte
|
|
174
|
+
<script lang="ts">
|
|
175
|
+
import { Select } from '@smilodon/svelte';
|
|
176
|
+
|
|
177
|
+
let items = [];
|
|
178
|
+
let isLoading = false;
|
|
179
|
+
|
|
180
|
+
async function handleSearch(event) {
|
|
181
|
+
const query = event.detail.query;
|
|
182
|
+
|
|
183
|
+
if (!query) {
|
|
184
|
+
items = [];
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
isLoading = true;
|
|
189
|
+
const response = await fetch(`/api/search?q=${query}`);
|
|
190
|
+
const data = await response.json();
|
|
191
|
+
items = data.results;
|
|
192
|
+
isLoading = false;
|
|
193
|
+
}
|
|
194
|
+
</script>
|
|
195
|
+
|
|
196
|
+
<Select
|
|
197
|
+
{items}
|
|
198
|
+
searchable
|
|
199
|
+
on:search={handleSearch}
|
|
200
|
+
placeholder="Type to search..."
|
|
201
|
+
/>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Controlled Component
|
|
205
|
+
|
|
206
|
+
```svelte
|
|
207
|
+
<script lang="ts">
|
|
208
|
+
import { Select } from '@smilodon/svelte';
|
|
209
|
+
|
|
210
|
+
const items = [
|
|
211
|
+
{ value: 'draft', label: 'Draft' },
|
|
212
|
+
{ value: 'published', label: 'Published' },
|
|
213
|
+
{ value: 'archived', label: 'Archived' },
|
|
214
|
+
];
|
|
215
|
+
|
|
216
|
+
let status = 'draft';
|
|
217
|
+
|
|
218
|
+
function handleChange(event) {
|
|
219
|
+
console.log('Status changed:', event.detail.value);
|
|
220
|
+
status = event.detail.value;
|
|
221
|
+
}
|
|
222
|
+
</script>
|
|
223
|
+
|
|
224
|
+
<Select
|
|
225
|
+
{items}
|
|
226
|
+
value={status}
|
|
227
|
+
on:change={handleChange}
|
|
228
|
+
/>
|
|
229
|
+
|
|
230
|
+
<button on:click={() => status = 'published'}>
|
|
231
|
+
Publish
|
|
232
|
+
</button>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Imperative API
|
|
236
|
+
|
|
237
|
+
```svelte
|
|
238
|
+
<script lang="ts">
|
|
239
|
+
import { Select } from '@smilodon/svelte';
|
|
240
|
+
|
|
241
|
+
let selectRef;
|
|
242
|
+
const items = [...];
|
|
243
|
+
|
|
244
|
+
function programmaticOpen() {
|
|
245
|
+
selectRef.open();
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function programmaticClear() {
|
|
249
|
+
selectRef.clear();
|
|
250
|
+
}
|
|
251
|
+
</script>
|
|
252
|
+
|
|
253
|
+
<Select bind:this={selectRef} {items} />
|
|
254
|
+
|
|
255
|
+
<button on:click={programmaticOpen}>Open Select</button>
|
|
256
|
+
<button on:click={programmaticClear}>Clear Selection</button>
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Props
|
|
260
|
+
|
|
261
|
+
| Prop | Type | Default | Description |
|
|
262
|
+
|------|------|---------|-------------|
|
|
263
|
+
| `items` | `SelectItem[]` | `[]` | Array of selectable items |
|
|
264
|
+
| `groupedItems` | `GroupedItem[]` | `undefined` | Grouped items array |
|
|
265
|
+
| `value` | `string \| number \| Array` | `undefined` | Controlled value |
|
|
266
|
+
| `defaultValue` | `string \| number \| Array` | `undefined` | Initial value (uncontrolled) |
|
|
267
|
+
| `multiple` | `boolean` | `false` | Enable multi-select |
|
|
268
|
+
| `searchable` | `boolean` | `false` | Enable search/filter |
|
|
269
|
+
| `placeholder` | `string` | `''` | Placeholder text |
|
|
270
|
+
| `disabled` | `boolean` | `false` | Disable the select |
|
|
271
|
+
| `required` | `boolean` | `false` | Mark as required |
|
|
272
|
+
| `error` | `boolean` | `false` | Show error state |
|
|
273
|
+
| `infiniteScroll` | `boolean` | `false` | Enable infinite scroll |
|
|
274
|
+
| `pageSize` | `number` | `50` | Items per page (infinite scroll) |
|
|
275
|
+
| `virtualized` | `boolean` | `true` | Enable virtual scrolling |
|
|
276
|
+
| `maxSelections` | `number` | `undefined` | Max selections (multi-select) |
|
|
277
|
+
| `placement` | `'bottom' \| 'top' \| 'auto'` | `'auto'` | Dropdown placement |
|
|
278
|
+
| `className` | `string` | `''` | Custom CSS class |
|
|
279
|
+
| `style` | `string` | `''` | Custom inline styles |
|
|
280
|
+
|
|
281
|
+
## Events
|
|
282
|
+
|
|
283
|
+
| Event | Detail | Description |
|
|
284
|
+
|-------|--------|-------------|
|
|
285
|
+
| `change` | `{ value, selectedItems }` | Value changed |
|
|
286
|
+
| `select` | `{ item, index }` | Item selected |
|
|
287
|
+
| `open` | `void` | Dropdown opened |
|
|
288
|
+
| `close` | `void` | Dropdown closed |
|
|
289
|
+
| `search` | `{ query }` | Search query changed |
|
|
290
|
+
| `loadMore` | `{ page }` | Load more requested |
|
|
291
|
+
| `create` | `{ value }` | New item creation |
|
|
292
|
+
|
|
293
|
+
## Methods
|
|
294
|
+
|
|
295
|
+
Access these methods using `bind:this`:
|
|
296
|
+
|
|
297
|
+
| Method | Signature | Description |
|
|
298
|
+
|--------|-----------|-------------|
|
|
299
|
+
| `open()` | `() => void` | Open the dropdown |
|
|
300
|
+
| `close()` | `() => void` | Close the dropdown |
|
|
301
|
+
| `focus()` | `() => void` | Focus the select |
|
|
302
|
+
| `clear()` | `() => void` | Clear selection |
|
|
303
|
+
| `setItems()` | `(items: SelectItem[]) => void` | Update items |
|
|
304
|
+
| `setGroupedItems()` | `(groups: GroupedItem[]) => void` | Update grouped items |
|
|
305
|
+
|
|
306
|
+
## Types
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
interface SelectItem {
|
|
310
|
+
value: string | number;
|
|
311
|
+
label: string;
|
|
312
|
+
disabled?: boolean;
|
|
313
|
+
group?: string;
|
|
314
|
+
[key: string]: any;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
interface GroupedItem {
|
|
318
|
+
group: string;
|
|
319
|
+
items: SelectItem[];
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## Styling
|
|
324
|
+
|
|
325
|
+
The component uses CSS variables for easy customization:
|
|
326
|
+
|
|
327
|
+
```css
|
|
328
|
+
enhanced-select {
|
|
329
|
+
--select-border-color: #d1d5db;
|
|
330
|
+
--select-focus-border-color: #3b82f6;
|
|
331
|
+
--select-background: white;
|
|
332
|
+
--select-text-color: #1f2937;
|
|
333
|
+
--select-placeholder-color: #9ca3af;
|
|
334
|
+
--select-option-hover-background: #f3f4f6;
|
|
335
|
+
--select-option-selected-background: #eff6ff;
|
|
336
|
+
--select-border-radius: 0.375rem;
|
|
337
|
+
--select-padding: 0.5rem 0.75rem;
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## Accessibility
|
|
342
|
+
|
|
343
|
+
This component is fully accessible and compliant with WCAG 2.1 AAA standards:
|
|
344
|
+
|
|
345
|
+
- ✅ Keyboard navigation (Arrow keys, Enter, Escape, Tab)
|
|
346
|
+
- ✅ Screen reader support (ARIA labels and live regions)
|
|
347
|
+
- ✅ Focus management
|
|
348
|
+
- ✅ High contrast mode support
|
|
349
|
+
- ✅ Reduced motion support
|
|
350
|
+
|
|
351
|
+
## Browser Support
|
|
352
|
+
|
|
353
|
+
- Chrome/Edge 90+
|
|
354
|
+
- Firefox 88+
|
|
355
|
+
- Safari 14+
|
|
356
|
+
- Opera 76+
|
|
357
|
+
|
|
358
|
+
## License
|
|
359
|
+
|
|
360
|
+
MIT © [Navid Rezadoost](https://github.com/navidrezadoost)
|
|
361
|
+
|
|
362
|
+
## Contributing
|
|
363
|
+
|
|
364
|
+
Contributions are welcome! Please see the [main repository](https://github.com/navidrezadoost/smilodon) for guidelines.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("svelte/internal"),t=require("svelte");function i(t){let i;return{c(){i=e.element("enhanced-select"),e.set_custom_element_data(i,"class",t[0]),e.set_custom_element_data(i,"style",t[1])},m(n,s){e.insert(n,i,s),t[27](i)},p(t,n){1&n[0]&&e.set_custom_element_data(i,"class",t[0]),2&n[0]&&e.set_custom_element_data(i,"style",t[1])},i:e.noop,o:e.noop,d(n){n&&e.detach(i),t[27](null)}}}function n(i,n,s){let r,l,{items:a=[]}=n,{groupedItems:u}=n,{value:o}=n,{defaultValue:c}=n,{multiple:d=!1}=n,{searchable:m=!1}=n,{placeholder:v=""}=n,{disabled:p=!1}=n,{required:b=!1}=n,{error:f=!1}=n,{infiniteScroll:h=!1}=n,{pageSize:g=50}=n,{virtualized:$=!0}=n,{maxSelections:A}=n,{placement:y="auto"}=n,{className:S=""}=n,{style:_=""}=n;const I=t.createEventDispatcher();let x,E=c;function L(e){const t=e,{item:i,index:n}=t.detail;I("select",{item:i,index:n})}function z(e){const t=e,{selectedItems:i,selectedValues:n}=t.detail,l=n;r||s(24,E=d?l:l[0]);const a=d?l:l[0];s(3,o=a),I("change",{value:a,selectedItems:i})}function q(){I("open")}function V(){I("close")}function w(e){I("search",{query:e.detail.query})}function G(e){I("loadMore",{page:e.detail.page})}function M(e){I("create",{value:e.detail.value})}return t.onMount(()=>{if(!x)return;const e=x;if(v&&e.setAttribute("placeholder",v),p&&e.setAttribute("disabled",""),b&&e.setAttribute("required",""),f&&e.setAttribute("error",""),m&&e.setAttribute("searchable",""),d&&e.setAttribute("multiple",""),$&&e.setAttribute("virtualized",""),h&&e.setAttribute("infinite-scroll",""),g&&e.setAttribute("page-size",String(g)),A&&e.setAttribute("max-selections",String(A)),y&&e.setAttribute("placement",y),(null==a?void 0:a.length)&&e.setItems(a),(null==u?void 0:u.length)&&e.setGroupedItems(u),void 0!==l){const t=Array.isArray(l)?l:[l];e.setSelectedValues(t)}e.addEventListener("select",L),e.addEventListener("change",z),e.addEventListener("open",q),e.addEventListener("close",V),e.addEventListener("search",w),e.addEventListener("loadMore",G),e.addEventListener("create",M)}),t.onDestroy(()=>{if(!x)return;const e=x;e.removeEventListener("select",L),e.removeEventListener("change",z),e.removeEventListener("open",q),e.removeEventListener("close",V),e.removeEventListener("search",w),e.removeEventListener("loadMore",G),e.removeEventListener("create",M)}),i.$$set=e=>{"items"in e&&s(4,a=e.items),"groupedItems"in e&&s(5,u=e.groupedItems),"value"in e&&s(3,o=e.value),"defaultValue"in e&&s(6,c=e.defaultValue),"multiple"in e&&s(7,d=e.multiple),"searchable"in e&&s(8,m=e.searchable),"placeholder"in e&&s(9,v=e.placeholder),"disabled"in e&&s(10,p=e.disabled),"required"in e&&s(11,b=e.required),"error"in e&&s(12,f=e.error),"infiniteScroll"in e&&s(13,h=e.infiniteScroll),"pageSize"in e&&s(14,g=e.pageSize),"virtualized"in e&&s(15,$=e.virtualized),"maxSelections"in e&&s(16,A=e.maxSelections),"placement"in e&&s(17,y=e.placement),"className"in e&&s(0,S=e.className),"style"in e&&s(1,_=e.style)},i.$$.update=()=>{if(8&i.$$.dirty[0]&&s(25,r=void 0!==o),50331656&i.$$.dirty[0]&&s(26,l=r?o:E),20&i.$$.dirty[0]&&x&&a&&x.setItems(a),36&i.$$.dirty[0]&&x&&u&&x.setGroupedItems(u),67108868&i.$$.dirty[0]&&x&&void 0!==l){const e=Array.isArray(l)?l:[l];x.setSelectedValues(e)}34692&i.$$.dirty[0]&&x&&(v&&x.setAttribute("placeholder",v),p?x.setAttribute("disabled",""):x.removeAttribute("disabled"),m?x.setAttribute("searchable",""):x.removeAttribute("searchable"),d?x.setAttribute("multiple",""):x.removeAttribute("multiple"),$?x.setAttribute("virtualized",""):x.removeAttribute("virtualized"))},[S,_,x,o,a,u,c,d,m,v,p,b,f,h,g,$,A,y,function(){null==x||x.open()},function(){null==x||x.close()},function(){null==x||x.focus()},function(e){null==x||x.setItems(e)},function(e){null==x||x.setGroupedItems(e)},function(){null==x||x.setSelectedValues([]),r||s(24,E=d?[]:void 0);const e=d?[]:"";s(3,o=e),I("change",{value:e,selectedItems:[]})},E,r,l,function(t){e.binding_callbacks[t?"unshift":"push"](()=>{x=t,s(2,x)})}]}"undefined"!=typeof window&&(window.__svelte||(window.__svelte={v:new Set})).v.add("4");class s extends e.SvelteComponent{constructor(t){super(),e.init(this,t,n,i,e.safe_not_equal,{items:4,groupedItems:5,value:3,defaultValue:6,multiple:7,searchable:8,placeholder:9,disabled:10,required:11,error:12,infiniteScroll:13,pageSize:14,virtualized:15,maxSelections:16,placement:17,className:0,style:1,open:18,close:19,focus:20,setItems:21,setGroupedItems:22,clear:23},null,[-1,-1])}get open(){return this.$$.ctx[18]}get close(){return this.$$.ctx[19]}get focus(){return this.$$.ctx[20]}get setItems(){return this.$$.ctx[21]}get setGroupedItems(){return this.$$.ctx[22]}get clear(){return this.$$.ctx[23]}}exports.Select=s;
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/Select.svelte","../../../node_modules/svelte/src/runtime/internal/disclose-version/index.js","../../../node_modules/svelte/src/shared/version.js"],"sourcesContent":["<!--\n Smilodon Select Component for Svelte\n \n A production-ready, accessible select component with advanced features:\n - Single and multi-select modes\n - Searchable with client or server-side filtering\n - Infinite scroll and virtual scrolling for large datasets\n - Grouped options\n - Custom rendering\n - Full keyboard navigation\n - WCAG 2.1 AAA compliant\n \n @example\n <Select\n {items}\n bind:value={selectedValue}\n searchable\n placeholder=\"Select an option...\"\n />\n-->\n\n<script lang=\"ts\">\n import { onMount, onDestroy, createEventDispatcher } from 'svelte';\n import type {\n SelectEventDetail,\n OpenEventDetail,\n CloseEventDetail,\n SearchEventDetail,\n ChangeEventDetail,\n LoadMoreEventDetail,\n GroupedItem,\n } from '@smilodon/core';\n\n export interface SelectItem {\n value: string | number;\n label: string;\n disabled?: boolean;\n group?: string;\n [key: string]: any;\n }\n\n // Props\n export let items: SelectItem[] = [];\n export let groupedItems: GroupedItem[] | undefined = undefined;\n export let value: string | number | (string | number)[] | undefined = undefined;\n export let defaultValue: string | number | (string | number)[] | undefined = undefined;\n export let multiple: boolean = false;\n export let searchable: boolean = false;\n export let placeholder: string = '';\n export let disabled: boolean = false;\n export let required: boolean = false;\n export let error: boolean = false;\n export let infiniteScroll: boolean = false;\n export let pageSize: number = 50;\n export let virtualized: boolean = true;\n export let maxSelections: number | undefined = undefined;\n export let placement: 'bottom' | 'top' | 'auto' = 'auto';\n export let className: string = '';\n export let style: string = '';\n\n const dispatch = createEventDispatcher<{\n change: { value: string | number | (string | number)[]; selectedItems: SelectItem[] };\n select: { item: SelectItem; index: number };\n open: void;\n close: void;\n search: { query: string };\n loadMore: { page: number };\n create: { value: string };\n }>();\n\n let selectRef: HTMLElement;\n let internalValue: string | number | (string | number)[] | undefined = defaultValue;\n\n // Check if component is controlled\n $: isControlled = value !== undefined;\n $: currentValue = isControlled ? value : internalValue;\n\n // Event handlers\n function handleSelect(e: Event) {\n const customEvent = e as CustomEvent<SelectEventDetail>;\n const { item, index } = customEvent.detail;\n dispatch('select', { item: item as SelectItem, index });\n }\n\n function handleChange(e: Event) {\n const customEvent = e as CustomEvent<ChangeEventDetail>;\n const { selectedItems, selectedValues } = customEvent.detail;\n\n const values = selectedValues as (string | number)[];\n\n // Update internal value in uncontrolled mode\n if (!isControlled) {\n internalValue = multiple ? values : values[0];\n }\n\n // Emit change event\n const newValue = multiple ? values : values[0];\n value = newValue; // Update binding\n dispatch('change', { value: newValue, selectedItems: selectedItems as SelectItem[] });\n }\n\n function handleOpen() {\n dispatch('open');\n }\n\n function handleClose() {\n dispatch('close');\n }\n\n function handleSearch(e: Event) {\n const customEvent = e as CustomEvent<SearchEventDetail>;\n dispatch('search', { query: customEvent.detail.query });\n }\n\n function handleLoadMore(e: Event) {\n const customEvent = e as CustomEvent<LoadMoreEventDetail>;\n dispatch('loadMore', { page: customEvent.detail.page });\n }\n\n function handleCreate(e: Event) {\n const customEvent = e as CustomEvent<{ value: string }>;\n dispatch('create', { value: customEvent.detail.value });\n }\n\n onMount(() => {\n if (!selectRef) return;\n\n const element = selectRef;\n\n // Set initial attributes\n if (placeholder) element.setAttribute('placeholder', placeholder);\n if (disabled) element.setAttribute('disabled', '');\n if (required) element.setAttribute('required', '');\n if (error) element.setAttribute('error', '');\n if (searchable) element.setAttribute('searchable', '');\n if (multiple) element.setAttribute('multiple', '');\n if (virtualized) element.setAttribute('virtualized', '');\n if (infiniteScroll) element.setAttribute('infinite-scroll', '');\n if (pageSize) element.setAttribute('page-size', String(pageSize));\n if (maxSelections) element.setAttribute('max-selections', String(maxSelections));\n if (placement) element.setAttribute('placement', placement);\n\n // Set initial items\n if (items?.length) {\n (element as any).setItems(items);\n }\n if (groupedItems?.length) {\n (element as any).setGroupedItems(groupedItems);\n }\n\n // Set initial value\n if (currentValue !== undefined) {\n const values = Array.isArray(currentValue) ? currentValue : [currentValue];\n (element as any).setSelectedValues(values);\n }\n\n // Add event listeners\n element.addEventListener('select', handleSelect as EventListener);\n element.addEventListener('change', handleChange as EventListener);\n element.addEventListener('open', handleOpen as EventListener);\n element.addEventListener('close', handleClose as EventListener);\n element.addEventListener('search', handleSearch as EventListener);\n element.addEventListener('loadMore', handleLoadMore as EventListener);\n element.addEventListener('create', handleCreate as EventListener);\n });\n\n onDestroy(() => {\n if (!selectRef) return;\n\n const element = selectRef;\n\n // Remove event listeners\n element.removeEventListener('select', handleSelect as EventListener);\n element.removeEventListener('change', handleChange as EventListener);\n element.removeEventListener('open', handleOpen as EventListener);\n element.removeEventListener('close', handleClose as EventListener);\n element.removeEventListener('search', handleSearch as EventListener);\n element.removeEventListener('loadMore', handleLoadMore as EventListener);\n element.removeEventListener('create', handleCreate as EventListener);\n });\n\n // Reactive updates\n $: if (selectRef && items) {\n (selectRef as any).setItems(items);\n }\n\n $: if (selectRef && groupedItems) {\n (selectRef as any).setGroupedItems(groupedItems);\n }\n\n $: if (selectRef && currentValue !== undefined) {\n const values = Array.isArray(currentValue) ? currentValue : [currentValue];\n (selectRef as any).setSelectedValues(values);\n }\n\n $: if (selectRef) {\n if (placeholder) selectRef.setAttribute('placeholder', placeholder);\n if (disabled) {\n selectRef.setAttribute('disabled', '');\n } else {\n selectRef.removeAttribute('disabled');\n }\n if (searchable) {\n selectRef.setAttribute('searchable', '');\n } else {\n selectRef.removeAttribute('searchable');\n }\n if (multiple) {\n selectRef.setAttribute('multiple', '');\n } else {\n selectRef.removeAttribute('multiple');\n }\n if (virtualized) {\n selectRef.setAttribute('virtualized', '');\n } else {\n selectRef.removeAttribute('virtualized');\n }\n }\n\n // Public methods\n export function open() {\n (selectRef as any)?.open();\n }\n\n export function close() {\n (selectRef as any)?.close();\n }\n\n export function focus() {\n selectRef?.focus();\n }\n\n export function setItems(newItems: SelectItem[]) {\n (selectRef as any)?.setItems(newItems);\n }\n\n export function setGroupedItems(groups: GroupedItem[]) {\n (selectRef as any)?.setGroupedItems(groups);\n }\n\n export function clear() {\n (selectRef as any)?.setSelectedValues([]);\n if (!isControlled) {\n internalValue = multiple ? [] : undefined;\n }\n const newValue = multiple ? [] : '';\n value = newValue as any;\n dispatch('change', { value: newValue as any, selectedItems: [] });\n }\n</script>\n\n<enhanced-select\n bind:this={selectRef}\n class={className}\n {style}\n/>\n\n<style>\n /* Component uses web component styling from @smilodon/core */\n</style>\n","import { PUBLIC_VERSION } from '../../../shared/version.js';\n\nif (typeof window !== 'undefined')\n\t// @ts-ignore\n\t(window.__svelte || (window.__svelte = { v: new Set() })).v.add(PUBLIC_VERSION);\n","// generated during release, do not modify\n\n/**\n * The current version, as set in package.json.\n *\n * https://svelte.dev/docs/svelte-compiler#svelte-version\n * @type {string}\n */\nexport const VERSION = '4.2.20';\nexport const PUBLIC_VERSION = '4';\n"],"names":["ctx","insert","target","enhanced_select","anchor","items","$$props","groupedItems","value","defaultValue","multiple","searchable","placeholder","disabled","required","error","infiniteScroll","pageSize","virtualized","maxSelections","placement","className","style","dispatch","createEventDispatcher","selectRef","internalValue","handleSelect","e","customEvent","item","index","detail","handleChange","selectedItems","selectedValues","values","isControlled","newValue","handleOpen","handleClose","handleSearch","query","handleLoadMore","page","handleCreate","onMount","element","setAttribute","String","length","setItems","setGroupedItems","currentValue","Array","isArray","setSelectedValues","addEventListener","onDestroy","removeEventListener","$$invalidate","removeAttribute","open","close","focus","newItems","groups","$$value","window","__svelte","v","Set","add"],"mappings":"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","x_google_ignoreList":[1,2]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import { SvelteComponent, init, safe_not_equal, noop, detach, set_custom_element_data, insert, element, binding_callbacks } from "svelte/internal";
|
|
2
|
+
import { createEventDispatcher, onMount, onDestroy } from "svelte";
|
|
3
|
+
const PUBLIC_VERSION = "4";
|
|
4
|
+
if (typeof window !== "undefined")
|
|
5
|
+
(window.__svelte || (window.__svelte = { v: /* @__PURE__ */ new Set() })).v.add(PUBLIC_VERSION);
|
|
6
|
+
function create_fragment(ctx) {
|
|
7
|
+
let enhanced_select;
|
|
8
|
+
return {
|
|
9
|
+
c() {
|
|
10
|
+
enhanced_select = element("enhanced-select");
|
|
11
|
+
set_custom_element_data(
|
|
12
|
+
enhanced_select,
|
|
13
|
+
"class",
|
|
14
|
+
/*className*/
|
|
15
|
+
ctx[0]
|
|
16
|
+
);
|
|
17
|
+
set_custom_element_data(
|
|
18
|
+
enhanced_select,
|
|
19
|
+
"style",
|
|
20
|
+
/*style*/
|
|
21
|
+
ctx[1]
|
|
22
|
+
);
|
|
23
|
+
},
|
|
24
|
+
m(target, anchor) {
|
|
25
|
+
insert(target, enhanced_select, anchor);
|
|
26
|
+
ctx[27](enhanced_select);
|
|
27
|
+
},
|
|
28
|
+
p(ctx2, dirty) {
|
|
29
|
+
if (dirty[0] & /*className*/
|
|
30
|
+
1) {
|
|
31
|
+
set_custom_element_data(
|
|
32
|
+
enhanced_select,
|
|
33
|
+
"class",
|
|
34
|
+
/*className*/
|
|
35
|
+
ctx2[0]
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
if (dirty[0] & /*style*/
|
|
39
|
+
2) {
|
|
40
|
+
set_custom_element_data(
|
|
41
|
+
enhanced_select,
|
|
42
|
+
"style",
|
|
43
|
+
/*style*/
|
|
44
|
+
ctx2[1]
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
i: noop,
|
|
49
|
+
o: noop,
|
|
50
|
+
d(detaching) {
|
|
51
|
+
if (detaching) {
|
|
52
|
+
detach(enhanced_select);
|
|
53
|
+
}
|
|
54
|
+
ctx[27](null);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function instance($$self, $$props, $$invalidate) {
|
|
59
|
+
let isControlled;
|
|
60
|
+
let currentValue;
|
|
61
|
+
let { items = [] } = $$props;
|
|
62
|
+
let { groupedItems = void 0 } = $$props;
|
|
63
|
+
let { value = void 0 } = $$props;
|
|
64
|
+
let { defaultValue = void 0 } = $$props;
|
|
65
|
+
let { multiple = false } = $$props;
|
|
66
|
+
let { searchable = false } = $$props;
|
|
67
|
+
let { placeholder = "" } = $$props;
|
|
68
|
+
let { disabled = false } = $$props;
|
|
69
|
+
let { required = false } = $$props;
|
|
70
|
+
let { error = false } = $$props;
|
|
71
|
+
let { infiniteScroll = false } = $$props;
|
|
72
|
+
let { pageSize = 50 } = $$props;
|
|
73
|
+
let { virtualized = true } = $$props;
|
|
74
|
+
let { maxSelections = void 0 } = $$props;
|
|
75
|
+
let { placement = "auto" } = $$props;
|
|
76
|
+
let { className = "" } = $$props;
|
|
77
|
+
let { style = "" } = $$props;
|
|
78
|
+
const dispatch = createEventDispatcher();
|
|
79
|
+
let selectRef;
|
|
80
|
+
let internalValue = defaultValue;
|
|
81
|
+
function handleSelect(e) {
|
|
82
|
+
const customEvent = e;
|
|
83
|
+
const { item, index } = customEvent.detail;
|
|
84
|
+
dispatch("select", { item, index });
|
|
85
|
+
}
|
|
86
|
+
function handleChange(e) {
|
|
87
|
+
const customEvent = e;
|
|
88
|
+
const { selectedItems, selectedValues } = customEvent.detail;
|
|
89
|
+
const values = selectedValues;
|
|
90
|
+
if (!isControlled) {
|
|
91
|
+
$$invalidate(24, internalValue = multiple ? values : values[0]);
|
|
92
|
+
}
|
|
93
|
+
const newValue = multiple ? values : values[0];
|
|
94
|
+
$$invalidate(3, value = newValue);
|
|
95
|
+
dispatch("change", { value: newValue, selectedItems });
|
|
96
|
+
}
|
|
97
|
+
function handleOpen() {
|
|
98
|
+
dispatch("open");
|
|
99
|
+
}
|
|
100
|
+
function handleClose() {
|
|
101
|
+
dispatch("close");
|
|
102
|
+
}
|
|
103
|
+
function handleSearch(e) {
|
|
104
|
+
const customEvent = e;
|
|
105
|
+
dispatch("search", { query: customEvent.detail.query });
|
|
106
|
+
}
|
|
107
|
+
function handleLoadMore(e) {
|
|
108
|
+
const customEvent = e;
|
|
109
|
+
dispatch("loadMore", { page: customEvent.detail.page });
|
|
110
|
+
}
|
|
111
|
+
function handleCreate(e) {
|
|
112
|
+
const customEvent = e;
|
|
113
|
+
dispatch("create", { value: customEvent.detail.value });
|
|
114
|
+
}
|
|
115
|
+
onMount(() => {
|
|
116
|
+
if (!selectRef) return;
|
|
117
|
+
const element2 = selectRef;
|
|
118
|
+
if (placeholder) element2.setAttribute("placeholder", placeholder);
|
|
119
|
+
if (disabled) element2.setAttribute("disabled", "");
|
|
120
|
+
if (required) element2.setAttribute("required", "");
|
|
121
|
+
if (error) element2.setAttribute("error", "");
|
|
122
|
+
if (searchable) element2.setAttribute("searchable", "");
|
|
123
|
+
if (multiple) element2.setAttribute("multiple", "");
|
|
124
|
+
if (virtualized) element2.setAttribute("virtualized", "");
|
|
125
|
+
if (infiniteScroll) element2.setAttribute("infinite-scroll", "");
|
|
126
|
+
if (pageSize) element2.setAttribute("page-size", String(pageSize));
|
|
127
|
+
if (maxSelections) element2.setAttribute("max-selections", String(maxSelections));
|
|
128
|
+
if (placement) element2.setAttribute("placement", placement);
|
|
129
|
+
if (items == null ? void 0 : items.length) {
|
|
130
|
+
element2.setItems(items);
|
|
131
|
+
}
|
|
132
|
+
if (groupedItems == null ? void 0 : groupedItems.length) {
|
|
133
|
+
element2.setGroupedItems(groupedItems);
|
|
134
|
+
}
|
|
135
|
+
if (currentValue !== void 0) {
|
|
136
|
+
const values = Array.isArray(currentValue) ? currentValue : [currentValue];
|
|
137
|
+
element2.setSelectedValues(values);
|
|
138
|
+
}
|
|
139
|
+
element2.addEventListener("select", handleSelect);
|
|
140
|
+
element2.addEventListener("change", handleChange);
|
|
141
|
+
element2.addEventListener("open", handleOpen);
|
|
142
|
+
element2.addEventListener("close", handleClose);
|
|
143
|
+
element2.addEventListener("search", handleSearch);
|
|
144
|
+
element2.addEventListener("loadMore", handleLoadMore);
|
|
145
|
+
element2.addEventListener("create", handleCreate);
|
|
146
|
+
});
|
|
147
|
+
onDestroy(() => {
|
|
148
|
+
if (!selectRef) return;
|
|
149
|
+
const element2 = selectRef;
|
|
150
|
+
element2.removeEventListener("select", handleSelect);
|
|
151
|
+
element2.removeEventListener("change", handleChange);
|
|
152
|
+
element2.removeEventListener("open", handleOpen);
|
|
153
|
+
element2.removeEventListener("close", handleClose);
|
|
154
|
+
element2.removeEventListener("search", handleSearch);
|
|
155
|
+
element2.removeEventListener("loadMore", handleLoadMore);
|
|
156
|
+
element2.removeEventListener("create", handleCreate);
|
|
157
|
+
});
|
|
158
|
+
function open() {
|
|
159
|
+
selectRef == null ? void 0 : selectRef.open();
|
|
160
|
+
}
|
|
161
|
+
function close() {
|
|
162
|
+
selectRef == null ? void 0 : selectRef.close();
|
|
163
|
+
}
|
|
164
|
+
function focus() {
|
|
165
|
+
selectRef == null ? void 0 : selectRef.focus();
|
|
166
|
+
}
|
|
167
|
+
function setItems(newItems) {
|
|
168
|
+
selectRef == null ? void 0 : selectRef.setItems(newItems);
|
|
169
|
+
}
|
|
170
|
+
function setGroupedItems(groups) {
|
|
171
|
+
selectRef == null ? void 0 : selectRef.setGroupedItems(groups);
|
|
172
|
+
}
|
|
173
|
+
function clear() {
|
|
174
|
+
selectRef == null ? void 0 : selectRef.setSelectedValues([]);
|
|
175
|
+
if (!isControlled) {
|
|
176
|
+
$$invalidate(24, internalValue = multiple ? [] : void 0);
|
|
177
|
+
}
|
|
178
|
+
const newValue = multiple ? [] : "";
|
|
179
|
+
$$invalidate(3, value = newValue);
|
|
180
|
+
dispatch("change", { value: newValue, selectedItems: [] });
|
|
181
|
+
}
|
|
182
|
+
function enhanced_select_binding($$value) {
|
|
183
|
+
binding_callbacks[$$value ? "unshift" : "push"](() => {
|
|
184
|
+
selectRef = $$value;
|
|
185
|
+
$$invalidate(2, selectRef);
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
$$self.$$set = ($$props2) => {
|
|
189
|
+
if ("items" in $$props2) $$invalidate(4, items = $$props2.items);
|
|
190
|
+
if ("groupedItems" in $$props2) $$invalidate(5, groupedItems = $$props2.groupedItems);
|
|
191
|
+
if ("value" in $$props2) $$invalidate(3, value = $$props2.value);
|
|
192
|
+
if ("defaultValue" in $$props2) $$invalidate(6, defaultValue = $$props2.defaultValue);
|
|
193
|
+
if ("multiple" in $$props2) $$invalidate(7, multiple = $$props2.multiple);
|
|
194
|
+
if ("searchable" in $$props2) $$invalidate(8, searchable = $$props2.searchable);
|
|
195
|
+
if ("placeholder" in $$props2) $$invalidate(9, placeholder = $$props2.placeholder);
|
|
196
|
+
if ("disabled" in $$props2) $$invalidate(10, disabled = $$props2.disabled);
|
|
197
|
+
if ("required" in $$props2) $$invalidate(11, required = $$props2.required);
|
|
198
|
+
if ("error" in $$props2) $$invalidate(12, error = $$props2.error);
|
|
199
|
+
if ("infiniteScroll" in $$props2) $$invalidate(13, infiniteScroll = $$props2.infiniteScroll);
|
|
200
|
+
if ("pageSize" in $$props2) $$invalidate(14, pageSize = $$props2.pageSize);
|
|
201
|
+
if ("virtualized" in $$props2) $$invalidate(15, virtualized = $$props2.virtualized);
|
|
202
|
+
if ("maxSelections" in $$props2) $$invalidate(16, maxSelections = $$props2.maxSelections);
|
|
203
|
+
if ("placement" in $$props2) $$invalidate(17, placement = $$props2.placement);
|
|
204
|
+
if ("className" in $$props2) $$invalidate(0, className = $$props2.className);
|
|
205
|
+
if ("style" in $$props2) $$invalidate(1, style = $$props2.style);
|
|
206
|
+
};
|
|
207
|
+
$$self.$$.update = () => {
|
|
208
|
+
if ($$self.$$.dirty[0] & /*value*/
|
|
209
|
+
8) {
|
|
210
|
+
$$invalidate(25, isControlled = value !== void 0);
|
|
211
|
+
}
|
|
212
|
+
if ($$self.$$.dirty[0] & /*isControlled, value, internalValue*/
|
|
213
|
+
50331656) {
|
|
214
|
+
$$invalidate(26, currentValue = isControlled ? value : internalValue);
|
|
215
|
+
}
|
|
216
|
+
if ($$self.$$.dirty[0] & /*selectRef, items*/
|
|
217
|
+
20) {
|
|
218
|
+
if (selectRef && items) {
|
|
219
|
+
selectRef.setItems(items);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if ($$self.$$.dirty[0] & /*selectRef, groupedItems*/
|
|
223
|
+
36) {
|
|
224
|
+
if (selectRef && groupedItems) {
|
|
225
|
+
selectRef.setGroupedItems(groupedItems);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if ($$self.$$.dirty[0] & /*selectRef, currentValue*/
|
|
229
|
+
67108868) {
|
|
230
|
+
if (selectRef && currentValue !== void 0) {
|
|
231
|
+
const values = Array.isArray(currentValue) ? currentValue : [currentValue];
|
|
232
|
+
selectRef.setSelectedValues(values);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if ($$self.$$.dirty[0] & /*selectRef, placeholder, disabled, searchable, multiple, virtualized*/
|
|
236
|
+
34692) {
|
|
237
|
+
if (selectRef) {
|
|
238
|
+
if (placeholder) selectRef.setAttribute("placeholder", placeholder);
|
|
239
|
+
if (disabled) {
|
|
240
|
+
selectRef.setAttribute("disabled", "");
|
|
241
|
+
} else {
|
|
242
|
+
selectRef.removeAttribute("disabled");
|
|
243
|
+
}
|
|
244
|
+
if (searchable) {
|
|
245
|
+
selectRef.setAttribute("searchable", "");
|
|
246
|
+
} else {
|
|
247
|
+
selectRef.removeAttribute("searchable");
|
|
248
|
+
}
|
|
249
|
+
if (multiple) {
|
|
250
|
+
selectRef.setAttribute("multiple", "");
|
|
251
|
+
} else {
|
|
252
|
+
selectRef.removeAttribute("multiple");
|
|
253
|
+
}
|
|
254
|
+
if (virtualized) {
|
|
255
|
+
selectRef.setAttribute("virtualized", "");
|
|
256
|
+
} else {
|
|
257
|
+
selectRef.removeAttribute("virtualized");
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
return [
|
|
263
|
+
className,
|
|
264
|
+
style,
|
|
265
|
+
selectRef,
|
|
266
|
+
value,
|
|
267
|
+
items,
|
|
268
|
+
groupedItems,
|
|
269
|
+
defaultValue,
|
|
270
|
+
multiple,
|
|
271
|
+
searchable,
|
|
272
|
+
placeholder,
|
|
273
|
+
disabled,
|
|
274
|
+
required,
|
|
275
|
+
error,
|
|
276
|
+
infiniteScroll,
|
|
277
|
+
pageSize,
|
|
278
|
+
virtualized,
|
|
279
|
+
maxSelections,
|
|
280
|
+
placement,
|
|
281
|
+
open,
|
|
282
|
+
close,
|
|
283
|
+
focus,
|
|
284
|
+
setItems,
|
|
285
|
+
setGroupedItems,
|
|
286
|
+
clear,
|
|
287
|
+
internalValue,
|
|
288
|
+
isControlled,
|
|
289
|
+
currentValue,
|
|
290
|
+
enhanced_select_binding
|
|
291
|
+
];
|
|
292
|
+
}
|
|
293
|
+
class Select extends SvelteComponent {
|
|
294
|
+
constructor(options) {
|
|
295
|
+
super();
|
|
296
|
+
init(
|
|
297
|
+
this,
|
|
298
|
+
options,
|
|
299
|
+
instance,
|
|
300
|
+
create_fragment,
|
|
301
|
+
safe_not_equal,
|
|
302
|
+
{
|
|
303
|
+
items: 4,
|
|
304
|
+
groupedItems: 5,
|
|
305
|
+
value: 3,
|
|
306
|
+
defaultValue: 6,
|
|
307
|
+
multiple: 7,
|
|
308
|
+
searchable: 8,
|
|
309
|
+
placeholder: 9,
|
|
310
|
+
disabled: 10,
|
|
311
|
+
required: 11,
|
|
312
|
+
error: 12,
|
|
313
|
+
infiniteScroll: 13,
|
|
314
|
+
pageSize: 14,
|
|
315
|
+
virtualized: 15,
|
|
316
|
+
maxSelections: 16,
|
|
317
|
+
placement: 17,
|
|
318
|
+
className: 0,
|
|
319
|
+
style: 1,
|
|
320
|
+
open: 18,
|
|
321
|
+
close: 19,
|
|
322
|
+
focus: 20,
|
|
323
|
+
setItems: 21,
|
|
324
|
+
setGroupedItems: 22,
|
|
325
|
+
clear: 23
|
|
326
|
+
},
|
|
327
|
+
null,
|
|
328
|
+
[-1, -1]
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
get open() {
|
|
332
|
+
return this.$$.ctx[18];
|
|
333
|
+
}
|
|
334
|
+
get close() {
|
|
335
|
+
return this.$$.ctx[19];
|
|
336
|
+
}
|
|
337
|
+
get focus() {
|
|
338
|
+
return this.$$.ctx[20];
|
|
339
|
+
}
|
|
340
|
+
get setItems() {
|
|
341
|
+
return this.$$.ctx[21];
|
|
342
|
+
}
|
|
343
|
+
get setGroupedItems() {
|
|
344
|
+
return this.$$.ctx[22];
|
|
345
|
+
}
|
|
346
|
+
get clear() {
|
|
347
|
+
return this.$$.ctx[23];
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
export {
|
|
351
|
+
Select
|
|
352
|
+
};
|
|
353
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../node_modules/svelte/src/shared/version.js","../../../node_modules/svelte/src/runtime/internal/disclose-version/index.js","../src/Select.svelte"],"sourcesContent":["// generated during release, do not modify\n\n/**\n * The current version, as set in package.json.\n *\n * https://svelte.dev/docs/svelte-compiler#svelte-version\n * @type {string}\n */\nexport const VERSION = '4.2.20';\nexport const PUBLIC_VERSION = '4';\n","import { PUBLIC_VERSION } from '../../../shared/version.js';\n\nif (typeof window !== 'undefined')\n\t// @ts-ignore\n\t(window.__svelte || (window.__svelte = { v: new Set() })).v.add(PUBLIC_VERSION);\n","<!--\n Smilodon Select Component for Svelte\n \n A production-ready, accessible select component with advanced features:\n - Single and multi-select modes\n - Searchable with client or server-side filtering\n - Infinite scroll and virtual scrolling for large datasets\n - Grouped options\n - Custom rendering\n - Full keyboard navigation\n - WCAG 2.1 AAA compliant\n \n @example\n <Select\n {items}\n bind:value={selectedValue}\n searchable\n placeholder=\"Select an option...\"\n />\n-->\n\n<script lang=\"ts\">\n import { onMount, onDestroy, createEventDispatcher } from 'svelte';\n import type {\n SelectEventDetail,\n OpenEventDetail,\n CloseEventDetail,\n SearchEventDetail,\n ChangeEventDetail,\n LoadMoreEventDetail,\n GroupedItem,\n } from '@smilodon/core';\n\n export interface SelectItem {\n value: string | number;\n label: string;\n disabled?: boolean;\n group?: string;\n [key: string]: any;\n }\n\n // Props\n export let items: SelectItem[] = [];\n export let groupedItems: GroupedItem[] | undefined = undefined;\n export let value: string | number | (string | number)[] | undefined = undefined;\n export let defaultValue: string | number | (string | number)[] | undefined = undefined;\n export let multiple: boolean = false;\n export let searchable: boolean = false;\n export let placeholder: string = '';\n export let disabled: boolean = false;\n export let required: boolean = false;\n export let error: boolean = false;\n export let infiniteScroll: boolean = false;\n export let pageSize: number = 50;\n export let virtualized: boolean = true;\n export let maxSelections: number | undefined = undefined;\n export let placement: 'bottom' | 'top' | 'auto' = 'auto';\n export let className: string = '';\n export let style: string = '';\n\n const dispatch = createEventDispatcher<{\n change: { value: string | number | (string | number)[]; selectedItems: SelectItem[] };\n select: { item: SelectItem; index: number };\n open: void;\n close: void;\n search: { query: string };\n loadMore: { page: number };\n create: { value: string };\n }>();\n\n let selectRef: HTMLElement;\n let internalValue: string | number | (string | number)[] | undefined = defaultValue;\n\n // Check if component is controlled\n $: isControlled = value !== undefined;\n $: currentValue = isControlled ? value : internalValue;\n\n // Event handlers\n function handleSelect(e: Event) {\n const customEvent = e as CustomEvent<SelectEventDetail>;\n const { item, index } = customEvent.detail;\n dispatch('select', { item: item as SelectItem, index });\n }\n\n function handleChange(e: Event) {\n const customEvent = e as CustomEvent<ChangeEventDetail>;\n const { selectedItems, selectedValues } = customEvent.detail;\n\n const values = selectedValues as (string | number)[];\n\n // Update internal value in uncontrolled mode\n if (!isControlled) {\n internalValue = multiple ? values : values[0];\n }\n\n // Emit change event\n const newValue = multiple ? values : values[0];\n value = newValue; // Update binding\n dispatch('change', { value: newValue, selectedItems: selectedItems as SelectItem[] });\n }\n\n function handleOpen() {\n dispatch('open');\n }\n\n function handleClose() {\n dispatch('close');\n }\n\n function handleSearch(e: Event) {\n const customEvent = e as CustomEvent<SearchEventDetail>;\n dispatch('search', { query: customEvent.detail.query });\n }\n\n function handleLoadMore(e: Event) {\n const customEvent = e as CustomEvent<LoadMoreEventDetail>;\n dispatch('loadMore', { page: customEvent.detail.page });\n }\n\n function handleCreate(e: Event) {\n const customEvent = e as CustomEvent<{ value: string }>;\n dispatch('create', { value: customEvent.detail.value });\n }\n\n onMount(() => {\n if (!selectRef) return;\n\n const element = selectRef;\n\n // Set initial attributes\n if (placeholder) element.setAttribute('placeholder', placeholder);\n if (disabled) element.setAttribute('disabled', '');\n if (required) element.setAttribute('required', '');\n if (error) element.setAttribute('error', '');\n if (searchable) element.setAttribute('searchable', '');\n if (multiple) element.setAttribute('multiple', '');\n if (virtualized) element.setAttribute('virtualized', '');\n if (infiniteScroll) element.setAttribute('infinite-scroll', '');\n if (pageSize) element.setAttribute('page-size', String(pageSize));\n if (maxSelections) element.setAttribute('max-selections', String(maxSelections));\n if (placement) element.setAttribute('placement', placement);\n\n // Set initial items\n if (items?.length) {\n (element as any).setItems(items);\n }\n if (groupedItems?.length) {\n (element as any).setGroupedItems(groupedItems);\n }\n\n // Set initial value\n if (currentValue !== undefined) {\n const values = Array.isArray(currentValue) ? currentValue : [currentValue];\n (element as any).setSelectedValues(values);\n }\n\n // Add event listeners\n element.addEventListener('select', handleSelect as EventListener);\n element.addEventListener('change', handleChange as EventListener);\n element.addEventListener('open', handleOpen as EventListener);\n element.addEventListener('close', handleClose as EventListener);\n element.addEventListener('search', handleSearch as EventListener);\n element.addEventListener('loadMore', handleLoadMore as EventListener);\n element.addEventListener('create', handleCreate as EventListener);\n });\n\n onDestroy(() => {\n if (!selectRef) return;\n\n const element = selectRef;\n\n // Remove event listeners\n element.removeEventListener('select', handleSelect as EventListener);\n element.removeEventListener('change', handleChange as EventListener);\n element.removeEventListener('open', handleOpen as EventListener);\n element.removeEventListener('close', handleClose as EventListener);\n element.removeEventListener('search', handleSearch as EventListener);\n element.removeEventListener('loadMore', handleLoadMore as EventListener);\n element.removeEventListener('create', handleCreate as EventListener);\n });\n\n // Reactive updates\n $: if (selectRef && items) {\n (selectRef as any).setItems(items);\n }\n\n $: if (selectRef && groupedItems) {\n (selectRef as any).setGroupedItems(groupedItems);\n }\n\n $: if (selectRef && currentValue !== undefined) {\n const values = Array.isArray(currentValue) ? currentValue : [currentValue];\n (selectRef as any).setSelectedValues(values);\n }\n\n $: if (selectRef) {\n if (placeholder) selectRef.setAttribute('placeholder', placeholder);\n if (disabled) {\n selectRef.setAttribute('disabled', '');\n } else {\n selectRef.removeAttribute('disabled');\n }\n if (searchable) {\n selectRef.setAttribute('searchable', '');\n } else {\n selectRef.removeAttribute('searchable');\n }\n if (multiple) {\n selectRef.setAttribute('multiple', '');\n } else {\n selectRef.removeAttribute('multiple');\n }\n if (virtualized) {\n selectRef.setAttribute('virtualized', '');\n } else {\n selectRef.removeAttribute('virtualized');\n }\n }\n\n // Public methods\n export function open() {\n (selectRef as any)?.open();\n }\n\n export function close() {\n (selectRef as any)?.close();\n }\n\n export function focus() {\n selectRef?.focus();\n }\n\n export function setItems(newItems: SelectItem[]) {\n (selectRef as any)?.setItems(newItems);\n }\n\n export function setGroupedItems(groups: GroupedItem[]) {\n (selectRef as any)?.setGroupedItems(groups);\n }\n\n export function clear() {\n (selectRef as any)?.setSelectedValues([]);\n if (!isControlled) {\n internalValue = multiple ? [] : undefined;\n }\n const newValue = multiple ? [] : '';\n value = newValue as any;\n dispatch('change', { value: newValue as any, selectedItems: [] });\n }\n</script>\n\n<enhanced-select\n bind:this={selectRef}\n class={className}\n {style}\n/>\n\n<style>\n /* Component uses web component styling from @smilodon/core */\n</style>\n"],"names":["ctx","element"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from 'svelte';
|
|
2
|
+
import type {
|
|
3
|
+
SelectEventDetail,
|
|
4
|
+
OpenEventDetail,
|
|
5
|
+
CloseEventDetail,
|
|
6
|
+
SearchEventDetail,
|
|
7
|
+
ChangeEventDetail,
|
|
8
|
+
LoadMoreEventDetail,
|
|
9
|
+
GroupedItem,
|
|
10
|
+
} from '@smilodon/core';
|
|
11
|
+
|
|
12
|
+
export interface SelectItem {
|
|
13
|
+
value: string | number;
|
|
14
|
+
label: string;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
group?: string;
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface SelectProps {
|
|
21
|
+
items?: SelectItem[];
|
|
22
|
+
groupedItems?: GroupedItem[];
|
|
23
|
+
value?: string | number | (string | number)[];
|
|
24
|
+
defaultValue?: string | number | (string | number)[];
|
|
25
|
+
multiple?: boolean;
|
|
26
|
+
searchable?: boolean;
|
|
27
|
+
placeholder?: string;
|
|
28
|
+
disabled?: boolean;
|
|
29
|
+
required?: boolean;
|
|
30
|
+
error?: boolean;
|
|
31
|
+
infiniteScroll?: boolean;
|
|
32
|
+
pageSize?: number;
|
|
33
|
+
virtualized?: boolean;
|
|
34
|
+
maxSelections?: number;
|
|
35
|
+
placement?: 'bottom' | 'top' | 'auto';
|
|
36
|
+
className?: string;
|
|
37
|
+
style?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface SelectEvents {
|
|
41
|
+
change: CustomEvent<{ value: string | number | (string | number)[]; selectedItems: SelectItem[] }>;
|
|
42
|
+
select: CustomEvent<{ item: SelectItem; index: number }>;
|
|
43
|
+
open: CustomEvent<void>;
|
|
44
|
+
close: CustomEvent<void>;
|
|
45
|
+
search: CustomEvent<{ query: string }>;
|
|
46
|
+
loadMore: CustomEvent<{ page: number }>;
|
|
47
|
+
create: CustomEvent<{ value: string }>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface SelectSlots {}
|
|
51
|
+
|
|
52
|
+
export default class Select extends SvelteComponentTyped<SelectProps, SelectEvents, SelectSlots> {
|
|
53
|
+
open(): void;
|
|
54
|
+
close(): void;
|
|
55
|
+
focus(): void;
|
|
56
|
+
setItems(items: SelectItem[]): void;
|
|
57
|
+
setGroupedItems(groups: GroupedItem[]): void;
|
|
58
|
+
clear(): void;
|
|
59
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @smilodon/svelte - Svelte wrapper for Smilodon Select
|
|
3
|
+
*
|
|
4
|
+
* A production-ready, accessible select component for Svelte applications.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export { default as Select } from './Select.svelte';
|
|
10
|
+
|
|
11
|
+
// Re-export types from core
|
|
12
|
+
export type {
|
|
13
|
+
SelectEventDetail,
|
|
14
|
+
OpenEventDetail,
|
|
15
|
+
CloseEventDetail,
|
|
16
|
+
SearchEventDetail,
|
|
17
|
+
ChangeEventDetail,
|
|
18
|
+
LoadMoreEventDetail,
|
|
19
|
+
GroupedItem,
|
|
20
|
+
} from '@smilodon/core';
|
|
21
|
+
|
|
22
|
+
// Export component-specific types
|
|
23
|
+
export type { SelectItem, SelectProps, SelectEvents } from './Select.svelte.d.ts';
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@smilodon/svelte",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Production-ready, accessible select component for Svelte - part of the Smilodon UI toolkit",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"svelte": "./dist/index.mjs",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.mjs",
|
|
9
|
+
"types": "./dist/types/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"svelte": "./dist/index.mjs",
|
|
13
|
+
"types": "./dist/types/index.d.ts",
|
|
14
|
+
"import": "./dist/index.mjs",
|
|
15
|
+
"require": "./dist/index.cjs"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "vite build && npm run build:types",
|
|
24
|
+
"build:types": "mkdir -p dist/types && cp src/index.d.ts dist/types/ && cp src/Select.svelte.d.ts dist/types/",
|
|
25
|
+
"size": "gzip -c dist/index.mjs | wc -c",
|
|
26
|
+
"prepublishOnly": "npm run build"
|
|
27
|
+
},
|
|
28
|
+
"peerDependencies": {
|
|
29
|
+
"@smilodon/core": "^1.0.0",
|
|
30
|
+
"svelte": ">=3.0.0 || >=4.0.0 || >=5.0.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
|
34
|
+
"svelte": "^4.2.19",
|
|
35
|
+
"typescript": "^5.6.2",
|
|
36
|
+
"vite": "^5.4.11"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"svelte",
|
|
40
|
+
"select",
|
|
41
|
+
"dropdown",
|
|
42
|
+
"combobox",
|
|
43
|
+
"autocomplete",
|
|
44
|
+
"virtualization",
|
|
45
|
+
"infinite-scroll",
|
|
46
|
+
"accessibility",
|
|
47
|
+
"wcag",
|
|
48
|
+
"a11y",
|
|
49
|
+
"smilodon"
|
|
50
|
+
],
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "git+https://github.com/navidrezadoost/smilodon.git",
|
|
54
|
+
"directory": "packages/svelte"
|
|
55
|
+
},
|
|
56
|
+
"bugs": {
|
|
57
|
+
"url": "https://github.com/navidrezadoost/smilodon/issues"
|
|
58
|
+
},
|
|
59
|
+
"homepage": "https://github.com/navidrezadoost/smilodon#readme",
|
|
60
|
+
"author": "Navid Rezadoost <navidrezadoost07@gmail.com>",
|
|
61
|
+
"license": "MIT",
|
|
62
|
+
"sideEffects": false,
|
|
63
|
+
"engines": {
|
|
64
|
+
"node": ">=18",
|
|
65
|
+
"npm": ">=9"
|
|
66
|
+
},
|
|
67
|
+
"publishConfig": {
|
|
68
|
+
"access": "public",
|
|
69
|
+
"registry": "https://registry.npmjs.org/"
|
|
70
|
+
}
|
|
71
|
+
}
|