svelte-5-select 1.0.0-beta.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/LICENSE +9 -0
- package/README.md +320 -0
- package/dist/ChevronIcon.svelte +22 -0
- package/dist/ChevronIcon.svelte.d.ts +26 -0
- package/dist/ClearIcon.svelte +22 -0
- package/dist/ClearIcon.svelte.d.ts +26 -0
- package/dist/LoadingIcon.svelte +33 -0
- package/dist/LoadingIcon.svelte.d.ts +26 -0
- package/dist/Select.svelte +1461 -0
- package/dist/Select.svelte.d.ts +4 -0
- package/dist/aria-handlers.svelte.d.ts +19 -0
- package/dist/aria-handlers.svelte.js +36 -0
- package/dist/filter.d.ts +2 -0
- package/dist/filter.js +30 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +10 -0
- package/dist/keyboard-navigation.svelte.d.ts +12 -0
- package/dist/keyboard-navigation.svelte.js +124 -0
- package/dist/styles/default.css +387 -0
- package/dist/tailwind.css +130 -0
- package/dist/types.d.ts +134 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +10 -0
- package/dist/utils.js +28 -0
- package/package.json +86 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
@import 'tailwindcss/base';
|
|
2
|
+
|
|
3
|
+
.svelte-select {
|
|
4
|
+
@apply border rounded box-border h-10 relative flex items-center px-4 py-0 bg-white m-0 w-full
|
|
5
|
+
hover:border-gray-400;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.svelte-select input {
|
|
9
|
+
@apply cursor-default border-none text-gray-600 h-10 leading-10 px-4 py-0 bg-transparent text-sm absolute left-0 m-0 w-full
|
|
10
|
+
focus:outline-none hover:border-gray-400;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.svelte-select.focused {
|
|
14
|
+
@apply border-blue-600;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.svelte-select.disabled {
|
|
18
|
+
@apply bg-gray-200 border-gray-200 text-gray-600;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.svelte-select.disabled input {
|
|
22
|
+
@apply placeholder:text-gray-400 placeholder:opacity-100;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.svelte-select .selected-item {
|
|
26
|
+
@apply leading-10 h-10 overflow-x-hidden pr-5
|
|
27
|
+
focus:outline-none;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.svelte-select .icons {
|
|
31
|
+
@apply absolute flex items-center right-0 translate-y-0 text-gray-200 pointer-events-none top-0 bottom-0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.svelte-select .icons > * {
|
|
35
|
+
@apply transition-colors ease-in-out duration-200;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.svelte-select .clear-select {
|
|
39
|
+
@apply pointer-events-auto;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.svelte-select.focused .icons,
|
|
43
|
+
.svelte-select .chevron:hover,
|
|
44
|
+
.svelte-select .clear-select:hover {
|
|
45
|
+
@apply text-gray-600;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.svelte-select .clear-select {
|
|
49
|
+
@apply px-2 h-5 text-gray-300 flex-none w-9;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.svelte-select .chevron {
|
|
53
|
+
@apply flex pt-0 pr-2 pl-2 border-l-2 w-9 h-5 text-gray-300;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.svelte-select.multi {
|
|
57
|
+
@apply pr-9 pl-4 h-auto flex-wrap items-stretch;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.svelte-select.multi input {
|
|
61
|
+
@apply p-0 relative m-0;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.svelte-select.error {
|
|
65
|
+
@apply border-red-500 bg-white;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.a11y-text {
|
|
69
|
+
@apply sr-only;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.list {
|
|
73
|
+
@apply shadow-md rounded-sm max-h-64 overflow-y-auto bg-white border-none absolute z-10 w-full left-0 right-0;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.list .list-group-title {
|
|
77
|
+
@apply text-slate-800 cursor-default text-sm font-medium h-10 leading-10 px-5 overflow-ellipsis whitespace-nowrap uppercase;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.list .empty {
|
|
81
|
+
@apply text-center py-5 text-gray-500;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.item {
|
|
85
|
+
@apply cursor-default h-10 leading-10 px-5 text-gray-800 overflow-ellipsis overflow-hidden whitespace-nowrap;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.item.group-item {
|
|
89
|
+
@apply px-10;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.item:active {
|
|
93
|
+
@apply bg-blue-200;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.item.active {
|
|
97
|
+
@apply bg-blue-600 text-white;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.item.not-selectable {
|
|
101
|
+
@apply text-gray-300;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.item.first {
|
|
105
|
+
@apply rounded-t-sm;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.item.hover:not(.active) {
|
|
109
|
+
@apply bg-blue-100;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.multi input {
|
|
113
|
+
flex: 1 1 40px;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.multi-item {
|
|
117
|
+
@apply bg-gray-100 mt-1 mr-1 border border-gray-200 rounded-sm h-8 leading-8 flex cursor-default pr-1 pl-1 max-w-full items-center mr-1 overflow-hidden overflow-ellipsis whitespace-nowrap;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.multi-item.disabled {
|
|
121
|
+
@apply hover:bg-gray-300 hover:text-gray-500;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.multi-item-clear {
|
|
125
|
+
@apply flex items-center justify-center w-5;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.list-item {
|
|
129
|
+
@apply list-none;
|
|
130
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { ComputePositionConfig } from 'svelte-floating-ui/dom';
|
|
3
|
+
export interface ErrorEvent {
|
|
4
|
+
type: string;
|
|
5
|
+
details: any;
|
|
6
|
+
}
|
|
7
|
+
export interface FilterConfig {
|
|
8
|
+
loadOptions?: (filterText: string) => Promise<SelectItem[] | string[]>;
|
|
9
|
+
filterText: string;
|
|
10
|
+
items: SelectItem[] | string[] | null;
|
|
11
|
+
multiple: boolean;
|
|
12
|
+
value: SelectItem | SelectItem[] | null | undefined;
|
|
13
|
+
itemId: string;
|
|
14
|
+
groupBy?: (item: SelectItem) => string | undefined;
|
|
15
|
+
label: string;
|
|
16
|
+
filterSelectedItems: boolean;
|
|
17
|
+
itemFilter: (label: string, filterText: string, option: SelectItem) => boolean;
|
|
18
|
+
convertStringItemsToObjects: (items: string[]) => SelectItem[];
|
|
19
|
+
filterGroupedItems: (items: SelectItem[]) => SelectItem[];
|
|
20
|
+
}
|
|
21
|
+
export interface FloatingConfig extends Partial<ComputePositionConfig> {
|
|
22
|
+
autoUpdate?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface KeyboardNavigationContext {
|
|
25
|
+
getState: () => {
|
|
26
|
+
listOpen: boolean;
|
|
27
|
+
filteredItems: SelectItem[];
|
|
28
|
+
hoverItemIndex: number;
|
|
29
|
+
multiple: boolean;
|
|
30
|
+
value: any;
|
|
31
|
+
filterText: string;
|
|
32
|
+
activeValue: number | undefined;
|
|
33
|
+
itemId: string;
|
|
34
|
+
focused: boolean;
|
|
35
|
+
};
|
|
36
|
+
setListOpen: (value: boolean) => void;
|
|
37
|
+
setHoverItemIndex: (value: number) => void;
|
|
38
|
+
setActiveValue: (value: number | undefined) => void;
|
|
39
|
+
closeList: () => void;
|
|
40
|
+
setHoverIndex: (increment: number) => void;
|
|
41
|
+
handleSelect: (item: SelectItem) => void;
|
|
42
|
+
handleMultiItemClear: (index: number) => Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
export interface ScrollActionParams {
|
|
45
|
+
scroll: boolean;
|
|
46
|
+
}
|
|
47
|
+
export interface SelectItem {
|
|
48
|
+
value?: any;
|
|
49
|
+
label?: string;
|
|
50
|
+
index?: number;
|
|
51
|
+
group?: string;
|
|
52
|
+
groupHeader?: boolean;
|
|
53
|
+
groupItem?: boolean;
|
|
54
|
+
selectable?: boolean;
|
|
55
|
+
id?: string | number;
|
|
56
|
+
[key: string]: any;
|
|
57
|
+
}
|
|
58
|
+
export interface SelectProps {
|
|
59
|
+
filterText?: string;
|
|
60
|
+
itemId?: string;
|
|
61
|
+
items?: SelectItem[] | string[] | null;
|
|
62
|
+
justValue?: any;
|
|
63
|
+
label?: string;
|
|
64
|
+
value?: SelectItem | SelectItem[] | string | null;
|
|
65
|
+
disabled?: boolean;
|
|
66
|
+
focused?: boolean;
|
|
67
|
+
hasError?: boolean;
|
|
68
|
+
hideEmptyState?: boolean;
|
|
69
|
+
id?: string | null;
|
|
70
|
+
listOpen?: boolean;
|
|
71
|
+
loading?: boolean;
|
|
72
|
+
name?: string | null;
|
|
73
|
+
placeholder?: string;
|
|
74
|
+
placeholderAlwaysShow?: boolean;
|
|
75
|
+
showChevron?: boolean;
|
|
76
|
+
clearable?: boolean;
|
|
77
|
+
clearFilterTextOnBlur?: boolean;
|
|
78
|
+
closeListOnChange?: boolean;
|
|
79
|
+
filterSelectedItems?: boolean;
|
|
80
|
+
groupHeaderSelectable?: boolean;
|
|
81
|
+
multiFullItemClearable?: boolean;
|
|
82
|
+
multiple?: boolean;
|
|
83
|
+
required?: boolean;
|
|
84
|
+
searchable?: boolean;
|
|
85
|
+
useJustValue?: boolean;
|
|
86
|
+
class?: string;
|
|
87
|
+
containerStyles?: string;
|
|
88
|
+
inputStyles?: string;
|
|
89
|
+
listStyle?: string;
|
|
90
|
+
debounceWait?: number;
|
|
91
|
+
floatingConfig?: FloatingConfig;
|
|
92
|
+
hoverItemIndex?: number;
|
|
93
|
+
inputAttributes?: Record<string, any>;
|
|
94
|
+
listAutoWidth?: boolean;
|
|
95
|
+
listOffset?: number;
|
|
96
|
+
loadOptionsDeps?: any[];
|
|
97
|
+
createGroupHeaderItem?: (groupValue: string, item: SelectItem) => SelectItem;
|
|
98
|
+
debounce?: (fn: () => void, wait: number) => void;
|
|
99
|
+
filter?: (config: FilterConfig) => SelectItem[];
|
|
100
|
+
getFilteredItems?: () => SelectItem[];
|
|
101
|
+
groupBy?: ((item: SelectItem) => string) | undefined;
|
|
102
|
+
groupFilter?: (groups: string[]) => string[];
|
|
103
|
+
itemFilter?: (label: string, filterText: string, option: any) => boolean;
|
|
104
|
+
loadOptions?: (filterText: string) => Promise<SelectItem[] | string[]>;
|
|
105
|
+
ariaFocused?: () => string;
|
|
106
|
+
ariaListOpen?: (label: string, count: number) => string;
|
|
107
|
+
ariaValues?: (values: string) => string;
|
|
108
|
+
handleClear?: () => void;
|
|
109
|
+
onblur?: (e: FocusEvent) => void;
|
|
110
|
+
onchange?: (value: any) => void;
|
|
111
|
+
onclear?: (value: any) => void;
|
|
112
|
+
onerror?: (error: ErrorEvent) => void;
|
|
113
|
+
onfilter?: (items: SelectItem[]) => void;
|
|
114
|
+
onfocus?: (e: FocusEvent) => void;
|
|
115
|
+
onhoveritem?: (index: number) => void;
|
|
116
|
+
oninput?: (value: any) => void;
|
|
117
|
+
onloaded?: (options: SelectItem[]) => void;
|
|
118
|
+
onselect?: (selection: SelectItem) => void;
|
|
119
|
+
chevronIconSnippet?: Snippet<[boolean]>;
|
|
120
|
+
clearIconSnippet?: Snippet;
|
|
121
|
+
emptySnippet?: Snippet;
|
|
122
|
+
inputHiddenSnippet?: Snippet<[any]>;
|
|
123
|
+
itemSnippet?: Snippet<[SelectItem, number]>;
|
|
124
|
+
listAppendSnippet?: Snippet;
|
|
125
|
+
listPrependSnippet?: Snippet;
|
|
126
|
+
listSnippet?: Snippet<[SelectItem[]]>;
|
|
127
|
+
loadingIconSnippet?: Snippet;
|
|
128
|
+
multiClearIconSnippet?: Snippet;
|
|
129
|
+
prependSnippet?: Snippet;
|
|
130
|
+
requiredSnippet?: Snippet<[any]>;
|
|
131
|
+
selectionSnippet?: Snippet<[any, number?]>;
|
|
132
|
+
container?: HTMLDivElement;
|
|
133
|
+
input?: HTMLInputElement;
|
|
134
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SelectItem } from './types';
|
|
2
|
+
export declare function getItemProperty<T>(item: T, key: keyof T | string): T[keyof T] | undefined;
|
|
3
|
+
export declare function areItemsEqual(a: any, b: any, itemId: string): boolean;
|
|
4
|
+
export declare function isCancelled(res: any): res is {
|
|
5
|
+
cancelled: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare function isStringArray(arr: any[]): arr is string[];
|
|
8
|
+
export declare function isItemSelectableCheck(item: SelectItem | undefined): boolean;
|
|
9
|
+
export declare function hasValueChanged(newValue: any, oldValue: any): boolean;
|
|
10
|
+
export declare function createGroupHeaderItem(groupValue: string, item: SelectItem, labelKey?: string): SelectItem;
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export function getItemProperty(item, key) {
|
|
2
|
+
return item && typeof item === 'object' ? item[key] : undefined;
|
|
3
|
+
}
|
|
4
|
+
export function areItemsEqual(a, b, itemId) {
|
|
5
|
+
if (!a || !b)
|
|
6
|
+
return false;
|
|
7
|
+
return getItemProperty(a, itemId) === getItemProperty(b, itemId);
|
|
8
|
+
}
|
|
9
|
+
export function isCancelled(res) {
|
|
10
|
+
return res && typeof res === 'object' && 'cancelled' in res && res.cancelled === true;
|
|
11
|
+
}
|
|
12
|
+
export function isStringArray(arr) {
|
|
13
|
+
return arr.length > 0 && arr.every(item => typeof item === 'string');
|
|
14
|
+
}
|
|
15
|
+
export function isItemSelectableCheck(item) {
|
|
16
|
+
if (!item)
|
|
17
|
+
return false;
|
|
18
|
+
return !item.hasOwnProperty('selectable') || item.selectable !== false;
|
|
19
|
+
}
|
|
20
|
+
export function hasValueChanged(newValue, oldValue) {
|
|
21
|
+
return JSON.stringify(newValue) !== JSON.stringify(oldValue);
|
|
22
|
+
}
|
|
23
|
+
export function createGroupHeaderItem(groupValue, item, labelKey = 'label') {
|
|
24
|
+
return {
|
|
25
|
+
value: groupValue,
|
|
26
|
+
[labelKey]: groupValue,
|
|
27
|
+
};
|
|
28
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "svelte-5-select",
|
|
3
|
+
"version": "1.0.0-beta.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"repository": "https://github.com/IDontKnowMyUsername/svelte-5-select.git",
|
|
8
|
+
"description": "A <Select> component for Svelte 5 apps",
|
|
9
|
+
"devDependencies": {
|
|
10
|
+
"@sveltejs/adapter-auto": "7.0.0",
|
|
11
|
+
"@sveltejs/adapter-static": "3.0.10",
|
|
12
|
+
"@sveltejs/kit": "2.47.3",
|
|
13
|
+
"@sveltejs/package": "^2.5.4",
|
|
14
|
+
"@sveltejs/vite-plugin-svelte": "6.2.1",
|
|
15
|
+
"@testing-library/svelte": "^5.2.8",
|
|
16
|
+
"@testing-library/user-event": "^14.6.1",
|
|
17
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
18
|
+
"@vitest/ui": "^3.2.4",
|
|
19
|
+
"autoprefixer": "^10.4.21",
|
|
20
|
+
"cross-env": "^10.1.0",
|
|
21
|
+
"find-in-files": "^0.5.0",
|
|
22
|
+
"fuse.js": "^7.1.0",
|
|
23
|
+
"happy-dom": "^20.0.8",
|
|
24
|
+
"npm-check-updates": "^19.1.1",
|
|
25
|
+
"prettier": "~3.6.2",
|
|
26
|
+
"prettier-plugin-svelte": "^3.4.0",
|
|
27
|
+
"release-it": "^19.0.5",
|
|
28
|
+
"svelte-check": "^4.3.3",
|
|
29
|
+
"svelte-highlight": "^7.9.0",
|
|
30
|
+
"svelte-preprocess": "^6.0.3",
|
|
31
|
+
"svelte-virtual-list": "^3.0.1",
|
|
32
|
+
"svelte2tsx": "^0.7.45",
|
|
33
|
+
"tsx": "^4.20.6",
|
|
34
|
+
"typescript": "^5.9.3",
|
|
35
|
+
"vite": "^7.1.12",
|
|
36
|
+
"vitest": "^3.2.4"
|
|
37
|
+
},
|
|
38
|
+
"author": "https://github.com/IDontKnowMyUsername/svelte-5-select, https://github.com/kodaicoder, Robert Balfré <rob.balfre@gmail.com> (https://github.com/rob-balfre)",
|
|
39
|
+
"license": "ISC",
|
|
40
|
+
"homepage": "https://github.com/IDontKnowMyUsername/svelte-5-select#readme",
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/IDontKnowMyUsername/svelte-5-select/issues"
|
|
43
|
+
},
|
|
44
|
+
"keywords": [
|
|
45
|
+
"svelte",
|
|
46
|
+
"svelte5",
|
|
47
|
+
"select",
|
|
48
|
+
"dropdown",
|
|
49
|
+
"component",
|
|
50
|
+
"select-component"
|
|
51
|
+
],
|
|
52
|
+
"type": "module",
|
|
53
|
+
"exports": {
|
|
54
|
+
".": {
|
|
55
|
+
"types": "./dist/index.d.ts",
|
|
56
|
+
"svelte": "./dist/index.js"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"svelte": "./dist/index.js",
|
|
60
|
+
"files": [
|
|
61
|
+
"dist"
|
|
62
|
+
],
|
|
63
|
+
"peerDependencies": {
|
|
64
|
+
"svelte": "^5.41.2"
|
|
65
|
+
},
|
|
66
|
+
"dependencies": {
|
|
67
|
+
"@floating-ui/dom": "^1.7.4",
|
|
68
|
+
"svelte-floating-ui": "1.6.2"
|
|
69
|
+
},
|
|
70
|
+
"scripts": {
|
|
71
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
72
|
+
"dev": "vite dev",
|
|
73
|
+
"build": "vite build",
|
|
74
|
+
"build:lib": "vite build --config vite.lib.config.ts",
|
|
75
|
+
"coverage": "vitest run --coverage",
|
|
76
|
+
"preview": "vite preview",
|
|
77
|
+
"test": "vitest",
|
|
78
|
+
"test:ui": "vitest --ui",
|
|
79
|
+
"test:run": "vitest run",
|
|
80
|
+
"gen:docs": "node docs/generate_theming_variables_md.cjs",
|
|
81
|
+
"package": "svelte-kit sync && svelte-package",
|
|
82
|
+
"preprepare": "tsx src/remove-styles.ts",
|
|
83
|
+
"postprepare": "tsx src/post-prepare.ts && npm run gen:docs",
|
|
84
|
+
"release": "release-it"
|
|
85
|
+
}
|
|
86
|
+
}
|