@djcali570/component-lib 0.0.3 → 0.0.5
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 +7 -56
- package/dist/Accordion5.svelte +147 -0
- package/dist/Accordion5.svelte.d.ts +14 -0
- package/dist/DatePicker5.svelte +117 -30
- package/dist/DropDown5.svelte +329 -0
- package/dist/DropDown5.svelte.d.ts +26 -0
- package/dist/Input5.svelte +412 -0
- package/dist/Input5.svelte.d.ts +20 -0
- package/dist/TimePicker5.svelte +687 -0
- package/dist/TimePicker5.svelte.d.ts +14 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +5 -1
- package/package.json +66 -69
- package/dist/app.css +0 -1
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Dropdown5 v0.0.1
|
|
4
|
+
*/
|
|
5
|
+
export interface DropDownItem<TProps extends Record<string, any> = {}> {
|
|
6
|
+
id?: string;
|
|
7
|
+
value: string;
|
|
8
|
+
extraValue?: string;
|
|
9
|
+
component?: Component<TProps>;
|
|
10
|
+
componentStyles?: string;
|
|
11
|
+
props?: TProps;
|
|
12
|
+
}
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<script lang="ts">
|
|
16
|
+
import { browser } from '$app/environment';
|
|
17
|
+
import { onDestroy, onMount, type Component } from 'svelte';
|
|
18
|
+
import { fly } from 'svelte/transition';
|
|
19
|
+
|
|
20
|
+
let {
|
|
21
|
+
colorScheme = {
|
|
22
|
+
textColor: '#D6D6D6',
|
|
23
|
+
bgColor: '#121212',
|
|
24
|
+
borderColor: '#262626',
|
|
25
|
+
titleColor: '#989A9A',
|
|
26
|
+
dropdownBgColor: '#141414',
|
|
27
|
+
focusedColor: '#4787ac',
|
|
28
|
+
itemTextColor: '#D6D6D6',
|
|
29
|
+
itemHoverBgColor: '#4787ac',
|
|
30
|
+
itemHoverTextColor: '#121212'
|
|
31
|
+
},
|
|
32
|
+
name = 'dropdown',
|
|
33
|
+
title = 'Title',
|
|
34
|
+
value = $bindable(),
|
|
35
|
+
valueKey = $bindable(),
|
|
36
|
+
extraValue = $bindable(),
|
|
37
|
+
onUpdate = (key, v, ev) => {},
|
|
38
|
+
disabled = false,
|
|
39
|
+
dropdownItems = [] as DropDownItem[]
|
|
40
|
+
}: {
|
|
41
|
+
colorScheme?: any;
|
|
42
|
+
name?: string;
|
|
43
|
+
title?: string;
|
|
44
|
+
value: any;
|
|
45
|
+
valueKey?: string | null | undefined;
|
|
46
|
+
extraValue?: string | null | undefined;
|
|
47
|
+
onUpdate?: (valueKey: string, value: string, extraValue: string) => void;
|
|
48
|
+
disabled?: boolean;
|
|
49
|
+
dropdownItems?: DropDownItem[];
|
|
50
|
+
} = $props();
|
|
51
|
+
|
|
52
|
+
const id = generateRandomString();
|
|
53
|
+
let showDropdown = $state(false);
|
|
54
|
+
let dropdownRef: HTMLDivElement | null = $state(null);
|
|
55
|
+
let filteredItems: DropDownItem[] = $state([]);
|
|
56
|
+
|
|
57
|
+
$effect(() => {
|
|
58
|
+
if (!browser || !showDropdown || !dropdownRef) return;
|
|
59
|
+
setTimeout(() => {
|
|
60
|
+
if (!dropdownRef) return;
|
|
61
|
+
const dropdownRect = dropdownRef.getBoundingClientRect();
|
|
62
|
+
const viewportHeight = window.innerHeight;
|
|
63
|
+
if (dropdownRect.bottom > viewportHeight) {
|
|
64
|
+
const scrollY = window.scrollY + (dropdownRect.bottom - viewportHeight) + 10;
|
|
65
|
+
window.scrollTo({ top: scrollY, behavior: 'smooth' });
|
|
66
|
+
}
|
|
67
|
+
}, 0);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
onMount(() => {
|
|
71
|
+
document.addEventListener('click', closeDropdown);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
onDestroy(() => {
|
|
75
|
+
try {
|
|
76
|
+
document.removeEventListener('click', closeDropdown);
|
|
77
|
+
} catch (error) {}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Generate a random string so that each
|
|
82
|
+
* input will have a unique id in the dom
|
|
83
|
+
*/
|
|
84
|
+
function generateRandomString() {
|
|
85
|
+
const length = 6;
|
|
86
|
+
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
87
|
+
|
|
88
|
+
let result = '';
|
|
89
|
+
for (let i = 0; i < length; i++) {
|
|
90
|
+
const randomIndex = Math.floor(Math.random() * characters.length);
|
|
91
|
+
result += characters.charAt(randomIndex);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Show the dropdown list
|
|
99
|
+
*/
|
|
100
|
+
function showDropdownList() {
|
|
101
|
+
showDropdown = true;
|
|
102
|
+
filteredItems = dropdownItems;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function closeDropdown(event: Event) {
|
|
106
|
+
const target = event.target as HTMLElement;
|
|
107
|
+
|
|
108
|
+
if (target.id !== `dropdown-${id}`) {
|
|
109
|
+
showDropdown = false;
|
|
110
|
+
validateInput();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function filterItems() {
|
|
114
|
+
filteredItems = dropdownItems.filter((item) =>
|
|
115
|
+
item.value.toLowerCase().includes(value.toLowerCase())
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
function selectItem(item: DropDownItem) {
|
|
119
|
+
valueKey = item.id ?? '';
|
|
120
|
+
extraValue = item.extraValue ?? '';
|
|
121
|
+
value = item.value;
|
|
122
|
+
onUpdate(valueKey, value, extraValue);
|
|
123
|
+
showDropdown = false;
|
|
124
|
+
}
|
|
125
|
+
function validateInput() {
|
|
126
|
+
const matchedItem = dropdownItems.find((item) => {
|
|
127
|
+
return item.value.toLowerCase() === value.toLowerCase(); // Add return statement
|
|
128
|
+
});
|
|
129
|
+
if (!matchedItem) {
|
|
130
|
+
// Clear input if the entered value is not in the list
|
|
131
|
+
value = '';
|
|
132
|
+
} else if (value !== matchedItem.value) {
|
|
133
|
+
// Set the inputText to the matched item's value if it's different
|
|
134
|
+
value = matchedItem.value;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
</script>
|
|
138
|
+
|
|
139
|
+
<div
|
|
140
|
+
class="dropdown5__container"
|
|
141
|
+
style="
|
|
142
|
+
--dropdown5__textColor: {colorScheme.textColor};
|
|
143
|
+
--dropdown5__mainBgColor: {colorScheme.bgColor};
|
|
144
|
+
--dropdown5__borderColor: {colorScheme.borderColor};
|
|
145
|
+
--dropdown5__titleColor: {colorScheme.titleColor};
|
|
146
|
+
--dropdown5__bgColor: {colorScheme.dropdownBgColor};
|
|
147
|
+
--dropdown5__focusedColor: {colorScheme.focusedColor};
|
|
148
|
+
--dropdown5__itemTextColor: {colorScheme.itemTextColor};
|
|
149
|
+
--dropdown5__itemHoverBgColor: {colorScheme.itemHoverBgColor};
|
|
150
|
+
--dropdown5__itemHoverTextColor: {colorScheme.itemHoverTextColor};
|
|
151
|
+
"
|
|
152
|
+
>
|
|
153
|
+
<div>
|
|
154
|
+
<div class="dropdown5__title">{title}</div>
|
|
155
|
+
<div class="dropdown5__input">
|
|
156
|
+
<input
|
|
157
|
+
id="dropdown-{id}"
|
|
158
|
+
type="text"
|
|
159
|
+
aria-controls="dropdown-{id}-list"
|
|
160
|
+
aria-haspopup="listbox"
|
|
161
|
+
{name}
|
|
162
|
+
bind:value
|
|
163
|
+
oninput={filterItems}
|
|
164
|
+
onfocus={showDropdownList}
|
|
165
|
+
onblur={validateInput}
|
|
166
|
+
autocomplete="off"
|
|
167
|
+
{disabled}
|
|
168
|
+
/>
|
|
169
|
+
<input
|
|
170
|
+
id="dropdown-valueKey-{id}"
|
|
171
|
+
name={`${name}-valueKey-${id}`}
|
|
172
|
+
type="hidden"
|
|
173
|
+
bind:value={valueKey}
|
|
174
|
+
/>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
|
|
178
|
+
{#if showDropdown}
|
|
179
|
+
<div
|
|
180
|
+
class="dropdown5__list__container"
|
|
181
|
+
style="box-shadow: 0px 1px 16px 0px rgba(0,0,0,0.12);"
|
|
182
|
+
role="listbox"
|
|
183
|
+
aria-labelledby="dropdown-{id}-title"
|
|
184
|
+
bind:this={dropdownRef}
|
|
185
|
+
oninput={filterItems}
|
|
186
|
+
transition:fly={{
|
|
187
|
+
y: 10
|
|
188
|
+
}}
|
|
189
|
+
>
|
|
190
|
+
<div style="height:100%;">
|
|
191
|
+
{#each filteredItems as item, index}
|
|
192
|
+
<button
|
|
193
|
+
type="button"
|
|
194
|
+
class="dropdown5__list__item"
|
|
195
|
+
role="option"
|
|
196
|
+
aria-selected={item.value === value ? 'true' : 'false'}
|
|
197
|
+
onclick={() => selectItem(item)}
|
|
198
|
+
>
|
|
199
|
+
{#if item.value === value}
|
|
200
|
+
<div class="fic">
|
|
201
|
+
<div style="padding-right: 0.5rem;">
|
|
202
|
+
<div class="fca" style="width: 1rem; height: 1rem;">
|
|
203
|
+
<svg
|
|
204
|
+
viewBox="0 0 12 12"
|
|
205
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
206
|
+
aria-hidden="true"
|
|
207
|
+
role="presentation"
|
|
208
|
+
focusable="false"
|
|
209
|
+
style="display: block; height: 12px; width: 12px; fill: currentcolor;"
|
|
210
|
+
><path
|
|
211
|
+
d="m10.5 1.939 1.061 1.061-7.061 7.061-.53-.531-3-3-.531-.53 1.061-1.061 3 3 5.47-5.469z"
|
|
212
|
+
></path></svg
|
|
213
|
+
>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
{#if item.component}
|
|
217
|
+
{@const Component = item.component}
|
|
218
|
+
<div class="component" style={item.componentStyles}>
|
|
219
|
+
<Component {...item.props} />
|
|
220
|
+
</div>
|
|
221
|
+
{/if}
|
|
222
|
+
<div>{item.value}</div>
|
|
223
|
+
</div>
|
|
224
|
+
{:else}
|
|
225
|
+
<div class="fic">
|
|
226
|
+
<div style="padding-right: 0.5rem;">
|
|
227
|
+
<div style="width: 1rem; height: 1rem;"></div>
|
|
228
|
+
</div>
|
|
229
|
+
|
|
230
|
+
{#if item.component}
|
|
231
|
+
{@const Component = item.component}
|
|
232
|
+
<div class="component" style={item.componentStyles}>
|
|
233
|
+
<Component {...item.props} />
|
|
234
|
+
</div>
|
|
235
|
+
{/if}
|
|
236
|
+
|
|
237
|
+
<div>{item.value}</div>
|
|
238
|
+
</div>
|
|
239
|
+
{/if}
|
|
240
|
+
</button>
|
|
241
|
+
{/each}
|
|
242
|
+
</div>
|
|
243
|
+
</div>
|
|
244
|
+
{/if}
|
|
245
|
+
</div>
|
|
246
|
+
|
|
247
|
+
<style>
|
|
248
|
+
.dropdown5__container {
|
|
249
|
+
position: relative;
|
|
250
|
+
display: flex;
|
|
251
|
+
flex-direction: column;
|
|
252
|
+
width: 100%;
|
|
253
|
+
min-height: 64px;
|
|
254
|
+
font-family: Arial, sans-serif;
|
|
255
|
+
margin: calc(var(--spacing) * 0);
|
|
256
|
+
background-color: var(--dropdown5__mainBgColor);
|
|
257
|
+
box-shadow: inset 0 0 0 1px var(--dropdown5__borderColor);
|
|
258
|
+
border: none;
|
|
259
|
+
border-radius: 0.5rem;
|
|
260
|
+
line-height: 1.25rem;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.dropdown5__container:focus-within {
|
|
264
|
+
box-shadow: inset 0 0 0 2px var(--dropdown5__focusedColor);
|
|
265
|
+
}
|
|
266
|
+
.dropdown5__title {
|
|
267
|
+
font-size: 0.75rem;
|
|
268
|
+
font-family: inherit;
|
|
269
|
+
color: var(--dropdown5__titleColor);
|
|
270
|
+
padding-inline: 0.75rem;
|
|
271
|
+
padding-top: 0.5rem;
|
|
272
|
+
}
|
|
273
|
+
.dropdown5__input {
|
|
274
|
+
display: flex;
|
|
275
|
+
padding-inline: 0.75rem;
|
|
276
|
+
color: var(--dropdown5__textColor);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
input {
|
|
280
|
+
width: 100%;
|
|
281
|
+
color: inherit;
|
|
282
|
+
outline: none;
|
|
283
|
+
font-family: inherit;
|
|
284
|
+
max-height: 24px;
|
|
285
|
+
background-color: var(--dropdown5__mainBgColor);
|
|
286
|
+
border: none;
|
|
287
|
+
}
|
|
288
|
+
.dropdown5__list__container {
|
|
289
|
+
position: absolute;
|
|
290
|
+
top: 110%;
|
|
291
|
+
left: 0;
|
|
292
|
+
display: flex;
|
|
293
|
+
flex-direction: column;
|
|
294
|
+
width: 100%;
|
|
295
|
+
max-height: 10rem;
|
|
296
|
+
overflow-y: auto;
|
|
297
|
+
background-color: var(--dropdown5__bgColor);
|
|
298
|
+
border-radius: 0.75rem;
|
|
299
|
+
z-index: 10;
|
|
300
|
+
}
|
|
301
|
+
.dropdown5__list__item {
|
|
302
|
+
display: flex;
|
|
303
|
+
width: 100%;
|
|
304
|
+
padding: 0.5rem;
|
|
305
|
+
cursor: pointer;
|
|
306
|
+
color: var(--dropdown5__itemTextColor);
|
|
307
|
+
text-align: start;
|
|
308
|
+
background-color: transparent;
|
|
309
|
+
border: none;
|
|
310
|
+
}
|
|
311
|
+
.dropdown5__list__item:hover {
|
|
312
|
+
background-color: var(--dropdown5__itemHoverBgColor);
|
|
313
|
+
color: var(--dropdown5__itemHoverTextColor);
|
|
314
|
+
}
|
|
315
|
+
.fic {
|
|
316
|
+
display: flex;
|
|
317
|
+
align-items: center;
|
|
318
|
+
}
|
|
319
|
+
.fca {
|
|
320
|
+
display: flex;
|
|
321
|
+
align-items: center;
|
|
322
|
+
justify-content: center;
|
|
323
|
+
}
|
|
324
|
+
.component {
|
|
325
|
+
margin-right: 0.5rem;
|
|
326
|
+
width: 2rem;
|
|
327
|
+
height: 2rem;
|
|
328
|
+
}
|
|
329
|
+
</style>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dropdown5 v0.0.1
|
|
3
|
+
*/
|
|
4
|
+
export interface DropDownItem<TProps extends Record<string, any> = {}> {
|
|
5
|
+
id?: string;
|
|
6
|
+
value: string;
|
|
7
|
+
extraValue?: string;
|
|
8
|
+
component?: Component<TProps>;
|
|
9
|
+
componentStyles?: string;
|
|
10
|
+
props?: TProps;
|
|
11
|
+
}
|
|
12
|
+
import { type Component } from 'svelte';
|
|
13
|
+
type $$ComponentProps = {
|
|
14
|
+
colorScheme?: any;
|
|
15
|
+
name?: string;
|
|
16
|
+
title?: string;
|
|
17
|
+
value: any;
|
|
18
|
+
valueKey?: string | null | undefined;
|
|
19
|
+
extraValue?: string | null | undefined;
|
|
20
|
+
onUpdate?: (valueKey: string, value: string, extraValue: string) => void;
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
dropdownItems?: DropDownItem[];
|
|
23
|
+
};
|
|
24
|
+
declare const DropDown5: Component<$$ComponentProps, {}, "value" | "valueKey" | "extraValue">;
|
|
25
|
+
type DropDown5 = ReturnType<typeof DropDown5>;
|
|
26
|
+
export default DropDown5;
|