@loop8/vue-select 0.1.3

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.
@@ -0,0 +1,42 @@
1
+ export interface Loop8SelectOption {
2
+ [key: string]: any;
3
+ }
4
+ export interface PaginationInfo {
5
+ page: number;
6
+ limit: number;
7
+ }
8
+ export interface Loop8SelectAjaxConfig {
9
+ url: string;
10
+ method?: 'GET' | 'POST';
11
+ delay?: number;
12
+ minimumInputLength?: number;
13
+ params?: Record<string, any> | ((term: string, pagination?: PaginationInfo) => Record<string, any>);
14
+ headers?: Record<string, string>;
15
+ processResults?: (data: any) => {
16
+ results: Loop8SelectOption[];
17
+ more: boolean;
18
+ };
19
+ cache?: boolean;
20
+ pagination?: boolean;
21
+ limit?: number;
22
+ pageParam?: string;
23
+ limitParam?: string;
24
+ urlBuilder?: (term: string, baseUrl: string) => string;
25
+ initialValueUrl?: string;
26
+ initialValueResolver?: (value: any) => Promise<Loop8SelectOption | null>;
27
+ initialValueParams?: Record<string, any> | ((ids: any[]) => Record<string, any>);
28
+ idParam?: string;
29
+ }
30
+ export interface Loop8SelectProps {
31
+ modelValue: any | any[];
32
+ options: Loop8SelectOption[];
33
+ placeholder?: string;
34
+ multiple?: boolean;
35
+ disabled?: boolean;
36
+ required?: boolean;
37
+ name?: string;
38
+ loading?: boolean;
39
+ valueKey?: string;
40
+ labelKey?: string;
41
+ ajax?: Loop8SelectAjaxConfig;
42
+ }
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@loop8/vue-select",
3
+ "version": "0.1.3",
4
+ "description": "A Vue 3 select component inspired by Select2",
5
+ "main": "dist/loop8-select.umd.js",
6
+ "module": "dist/loop8-select.es.js",
7
+ "types": "dist/types/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "src/styles"
11
+ ],
12
+ "scripts": {
13
+ "build": "vue-tsc --noEmit && vite build",
14
+ "dev": "vite --config vite.config.demo.js",
15
+ "lint": "eslint --ext .js,.vue,.ts src/",
16
+ "test": "vitest run",
17
+ "prepublishOnly": "npm run build"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://bitbucket.org/loop8gate/loop-8-select.git"
22
+ },
23
+ "peerDependencies": {
24
+ "vue": "^3.2.0"
25
+ },
26
+ "devDependencies": {
27
+ "@vitejs/plugin-vue": "^4.1.0",
28
+ "@vue/eslint-config-typescript": "^11.0.3",
29
+ "@vue/test-utils": "^2.3.0",
30
+ "eslint": "^8.35.0",
31
+ "eslint-plugin-vue": "^9.9.0",
32
+ "typescript": "^4.9.5",
33
+ "vite": "^4.1.0",
34
+ "vite-plugin-dts": "^2.0.0",
35
+ "vitest": "^0.29.2",
36
+ "vue-tsc": "^1.2.0"
37
+ },
38
+ "keywords": [
39
+ "vue",
40
+ "vue3",
41
+ "select",
42
+ "select2",
43
+ "dropdown",
44
+ "component",
45
+ "customizable"
46
+ ],
47
+ "author": "claude-3.7-sonnet",
48
+ "license": "MIT"
49
+ }
@@ -0,0 +1,231 @@
1
+ .loop-select-container {
2
+ position: relative;
3
+ width: 100%;
4
+ border: 1px solid #ccc;
5
+ border-radius: 4px;
6
+ box-sizing: border-box;
7
+ cursor: pointer;
8
+ }
9
+
10
+ .loop-select-disabled {
11
+ opacity: 0.6;
12
+ cursor: not-allowed;
13
+ }
14
+
15
+ .loop-select-selection {
16
+ min-height: 36px;
17
+ padding: 4px 8px;
18
+ display: flex;
19
+ align-items: center;
20
+ flex-wrap: nowrap;
21
+ }
22
+
23
+ .loop-select-single-selection {
24
+ flex: 1;
25
+ display: flex;
26
+ align-items: center;
27
+ overflow: hidden;
28
+ min-width: 0;
29
+ }
30
+
31
+ .loop-select-tags-container {
32
+ display: flex;
33
+ flex-wrap: wrap;
34
+ gap: 4px;
35
+ max-width: 100%;
36
+ overflow: hidden;
37
+ align-items: center;
38
+ }
39
+
40
+ .loop-select-selected-item {
41
+ display: inline-flex;
42
+ align-items: center;
43
+ background-color: #e4e4e4;
44
+ border-radius: 3px;
45
+ padding: 2px 6px;
46
+ margin-right: 4px;
47
+ margin-bottom: 2px;
48
+ max-width: 100%;
49
+ overflow: hidden;
50
+ text-overflow: ellipsis;
51
+ white-space: nowrap;
52
+ }
53
+
54
+ .loop-select-remove-item {
55
+ background: none;
56
+ border: none;
57
+ color: #666;
58
+ cursor: pointer;
59
+ margin-left: 4px;
60
+ padding: 0;
61
+ line-height: 1;
62
+ font-size: 16px;
63
+ flex-shrink: 0;
64
+ }
65
+
66
+ .loop-select-remove-item:hover {
67
+ color: #333;
68
+ }
69
+
70
+ .loop-select-search-container {
71
+ padding: 6px 8px;
72
+ border-bottom: 1px solid #eee;
73
+ position: relative;
74
+ display: flex;
75
+ align-items: center;
76
+ }
77
+
78
+ .loop-select-search {
79
+ border: 1px solid #ccc;
80
+ border-radius: 3px;
81
+ outline: none;
82
+ background: transparent;
83
+ width: 100%;
84
+ padding: 6px 8px;
85
+ margin: 0;
86
+ font-size: 14px;
87
+ box-sizing: border-box;
88
+ }
89
+
90
+ .loop-select-search-spinner {
91
+ position: absolute;
92
+ right: 14px;
93
+ top: 50%;
94
+ transform: translateY(-50%);
95
+ pointer-events: none;
96
+ display: flex;
97
+ align-items: center;
98
+ justify-content: center;
99
+ height: 20px;
100
+ line-height: 0;
101
+ }
102
+
103
+ /* Override the spinner size to fit in the search box */
104
+ .loop-select-search-spinner .lds-dual-ring {
105
+ width: 18px;
106
+ height: 18px;
107
+ line-height: 0;
108
+ vertical-align: middle;
109
+ }
110
+
111
+ .loop-select-search-spinner .lds-dual-ring:after {
112
+ width: 14px;
113
+ height: 14px;
114
+ margin: 2px;
115
+ border-width: 1.5px;
116
+ vertical-align: middle;
117
+ }
118
+
119
+ .loop-select-placeholder {
120
+ color: #999;
121
+ overflow: hidden;
122
+ text-overflow: ellipsis;
123
+ white-space: nowrap;
124
+ }
125
+
126
+ .loop-select-selected-text {
127
+ overflow: hidden;
128
+ text-overflow: ellipsis;
129
+ white-space: nowrap;
130
+ }
131
+
132
+ .loop-select-arrow {
133
+ display: flex;
134
+ align-items: center;
135
+ margin-left: 8px;
136
+ flex-shrink: 0;
137
+ }
138
+
139
+ .loop-select-dropdown {
140
+ position: absolute;
141
+ width: 100%;
142
+ max-height: 250px;
143
+ background: white;
144
+ border: 1px solid #ccc;
145
+ border-top: none;
146
+ border-radius: 0 0 4px 4px;
147
+ z-index: 1000;
148
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
149
+ box-sizing: border-box;
150
+ display: flex;
151
+ flex-direction: column;
152
+ }
153
+
154
+ .loop-select-options {
155
+ list-style: none;
156
+ margin: 0;
157
+ padding: 0;
158
+ overflow-y: auto;
159
+ max-height: 200px;
160
+ flex: 1;
161
+ /* Style for keyboard focus */
162
+ outline: none;
163
+ }
164
+
165
+ /* Add subtle focus style */
166
+ .loop-select-options:focus {
167
+ box-shadow: inset 0 0 2px rgba(0, 0, 0, 0.2);
168
+ }
169
+
170
+ .loop-select-option {
171
+ padding: 8px 12px;
172
+ cursor: pointer;
173
+ }
174
+
175
+ .loop-select-option:hover {
176
+ background-color: #f5f5f5;
177
+ }
178
+
179
+ .loop-select-option-selected {
180
+ background-color: #e6f7ff;
181
+ }
182
+
183
+ .loop-select-option-highlighted {
184
+ background-color: #f0f0f0;
185
+ }
186
+
187
+ .loop-select-loading,
188
+ .loop-select-no-results {
189
+ padding: 8px 12px;
190
+ text-align: center;
191
+ color: #999;
192
+ }
193
+
194
+ .loop-select-loading-more {
195
+ padding: 8px 12px;
196
+ text-align: center;
197
+ color: #999;
198
+ font-style: italic;
199
+ font-size: 0.9em;
200
+ background-color: #f9f9f9;
201
+ display: flex;
202
+ justify-content: center;
203
+ align-items: center;
204
+ line-height: 0;
205
+ }
206
+
207
+ .loop-select-loading-more .lds-dual-ring {
208
+ width: 24px;
209
+ height: 24px;
210
+ vertical-align: middle;
211
+ line-height: 0;
212
+ }
213
+
214
+ .loop-select-loading-more .lds-dual-ring:after {
215
+ width: 18px;
216
+ height: 18px;
217
+ margin: 3px;
218
+ border-width: 2px;
219
+ vertical-align: middle;
220
+ }
221
+
222
+ .loop-select-hidden {
223
+ position: absolute;
224
+ width: 0;
225
+ height: 0;
226
+ overflow: hidden;
227
+ clip: rect(0 0 0 0);
228
+ margin: -1px;
229
+ padding: 0;
230
+ border: 0;
231
+ }
@@ -0,0 +1,26 @@
1
+ .lds-dual-ring {
2
+ display: inline-block;
3
+ width: 24px;
4
+ height: 24px;
5
+ }
6
+
7
+ .lds-dual-ring:after {
8
+ content: " ";
9
+ display: block;
10
+ width: 18px;
11
+ height: 18px;
12
+ margin: 3px;
13
+ border-radius: 50%;
14
+ border: 2px solid #666;
15
+ border-color: #666 transparent #666 transparent;
16
+ animation: lds-dual-ring 1.2s linear infinite;
17
+ }
18
+
19
+ @keyframes lds-dual-ring {
20
+ 0% {
21
+ transform: rotate(0deg);
22
+ }
23
+ 100% {
24
+ transform: rotate(360deg);
25
+ }
26
+ }