@djcali570/component-lib 0.0.1

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 ADDED
@@ -0,0 +1,58 @@
1
+ # Svelte library
2
+
3
+ Everything you need to build a Svelte library, powered by [`sv`](https://npmjs.com/package/sv).
4
+
5
+ Read more about creating a library [in the docs](https://svelte.dev/docs/kit/packaging).
6
+
7
+ ## Creating a project
8
+
9
+ If you're seeing this, you've probably already done this step. Congrats!
10
+
11
+ ```bash
12
+ # create a new project in the current directory
13
+ npx sv create
14
+
15
+ # create a new project in my-app
16
+ npx sv create my-app
17
+ ```
18
+
19
+ ## Developing
20
+
21
+ Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
22
+
23
+ ```bash
24
+ npm run dev
25
+
26
+ # or start the server and open the app in a new browser tab
27
+ npm run dev -- --open
28
+ ```
29
+
30
+ Everything inside `src/lib` is part of your library, everything inside `src/routes` can be used as a showcase or preview app.
31
+
32
+ ## Building
33
+
34
+ To build your library:
35
+
36
+ ```bash
37
+ npm run package
38
+ ```
39
+
40
+ To create a production version of your showcase app:
41
+
42
+ ```bash
43
+ npm run build
44
+ ```
45
+
46
+ You can preview the production build with `npm run preview`.
47
+
48
+ > To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
49
+
50
+ ## Publishing
51
+
52
+ Go into the `package.json` and give your package the desired name through the `"name"` option. Also consider adding a `"license"` field and point it to a `LICENSE` file which you can create from a template (one popular option is the [MIT license](https://opensource.org/license/mit/)).
53
+
54
+ To publish your library to [npm](https://www.npmjs.com):
55
+
56
+ ```bash
57
+ npm publish
58
+ ```
@@ -0,0 +1,625 @@
1
+ <script lang="ts">
2
+ import { browser } from '$app/environment';
3
+ import { fly } from 'svelte/transition';
4
+
5
+ // Props with runes
6
+ let {
7
+ colorScheme = {
8
+ labelTextColor: '#989A9A',
9
+ inputTextColor: '#D6D6D6',
10
+ inputBgColor: '#121212',
11
+ inputBorderColor: '#262626',
12
+ inputFocusedBorderColor: '#4787ac',
13
+ inputClearColor: '#989A9A',
14
+ inputClearHoverColor: '#1F2023',
15
+ placeholderColor: '#46464A',
16
+ pickerBgColor: '#121212',
17
+ pickerMonthBgColor: '#121212',
18
+ pickerTextColor: '#D6D6D6',
19
+ pickerInactiveDayColor: '#46464A',
20
+ pickerTodayColor: '#BF3131',
21
+ pickerSelectedDayBgColor: '#4787ac',
22
+ pickerSelectedDayTextColor: '#121212',
23
+ pickerChevronHoverColor: '#1F2023',
24
+ pickerMaxHeight: '340px'
25
+ },
26
+ title = '',
27
+ name = '',
28
+ dateText = $bindable(),
29
+ placeholder = '',
30
+ minDate = new Date(),
31
+ maxDate = null,
32
+ blockedDates = [],
33
+ radius = 'full',
34
+ position = 'left-0',
35
+ disabled = false,
36
+ onDateUpdate = (date: string) => {}
37
+ }: {
38
+ title: string;
39
+ name: string;
40
+ dateText?: string;
41
+ placeholder?: string;
42
+ minDate?: Date;
43
+ maxDate?: Date | null;
44
+ blockedDates?: Date[];
45
+ radius?: 'right' | 'left' | 'full';
46
+ position?: 'left-0' | 'right-0';
47
+ disabled?: boolean;
48
+ colorScheme?: Record<string, string>;
49
+ onDateUpdate?: (date: string) => void;
50
+ } = $props();
51
+
52
+ // Normalize minDate to start of day
53
+ minDate = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate());
54
+
55
+ // State with runes
56
+ let showDropdown = $state(false);
57
+ let viewDate = $state(dateText ? new Date(dateText) : new Date());
58
+ let today = $state(new Date());
59
+ let selectedDate = $state(dateText ? new Date(dateText) : null);
60
+ let calendarDays = $state<(Date | null)[]>([]);
61
+ let dropdownRef = $state<HTMLElement | null>(null); // Reference to the dropdown
62
+ let inputRef = $state<HTMLElement | null>(null); // Reference to the input container
63
+ let showPrevMonthButton = $state(true);
64
+ let showNextMonthButton = $state(true);
65
+
66
+ // Static data
67
+ const weekAbv = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
68
+ const monthNames = [
69
+ 'January',
70
+ 'February',
71
+ 'March',
72
+ 'April',
73
+ 'May',
74
+ 'June',
75
+ 'July',
76
+ 'August',
77
+ 'September',
78
+ 'October',
79
+ 'November',
80
+ 'December'
81
+ ];
82
+ const calendarGridCount = 42;
83
+ const id = generateRandomString();
84
+
85
+ // Default maxDate
86
+ if (!maxDate && minDate) {
87
+ maxDate = new Date(minDate);
88
+ maxDate.setFullYear(minDate.getFullYear() + 1);
89
+ }
90
+
91
+ // Initial call to populate calendarDays
92
+ getDays();
93
+
94
+ // Reactive updates for dateText
95
+ $effect(() => {
96
+ if (dateText) {
97
+ const newDate = new Date(dateText);
98
+ if (
99
+ !isNaN(newDate.getTime()) &&
100
+ dateText !==
101
+ selectedDate?.toLocaleDateString('en-US', {
102
+ year: 'numeric',
103
+ month: '2-digit',
104
+ day: '2-digit'
105
+ })
106
+ ) {
107
+ selectedDate = newDate;
108
+ viewDate = new Date(newDate.getFullYear(), newDate.getMonth(), 1);
109
+ }
110
+ } else if (selectedDate !== null) {
111
+ selectedDate = null;
112
+ }
113
+ });
114
+
115
+ // Close dropdown when clicking outside
116
+ $effect(() => {
117
+ if (!browser || !showDropdown) return;
118
+
119
+ const handleClickOutside = (event: MouseEvent) => {
120
+ const target = event.target as Node;
121
+ if (dropdownRef && inputRef && !dropdownRef.contains(target) && !inputRef.contains(target)) {
122
+ showDropdown = false;
123
+ }
124
+ };
125
+
126
+ document.addEventListener('click', handleClickOutside);
127
+
128
+ return () => {
129
+ document.removeEventListener('click', handleClickOutside);
130
+ };
131
+ });
132
+
133
+ // Refresh calendar when minDate or maxDate changes
134
+ $effect(() => {
135
+ minDate;
136
+ maxDate;
137
+ getDays();
138
+ });
139
+
140
+ // Auto-scroll to make dropdown fully visible
141
+
142
+ $effect(() => {
143
+ if (!browser || !showDropdown || !dropdownRef) return;
144
+ setTimeout(() => {
145
+ if (!dropdownRef) return;
146
+ const dropdownRect = dropdownRef.getBoundingClientRect();
147
+ const viewportHeight = window.innerHeight;
148
+ if (dropdownRect.bottom > viewportHeight) {
149
+ const scrollY = window.scrollY + (dropdownRect.bottom - viewportHeight) + 10;
150
+ window.scrollTo({ top: scrollY, behavior: 'smooth' });
151
+ }
152
+ }, 0);
153
+ });
154
+
155
+ function getDays() {
156
+ const year = viewDate.getFullYear();
157
+ const month = viewDate.getMonth();
158
+
159
+ // Current month days
160
+ const lastDayOfMonth = new Date(year, month + 1, 0).getDate();
161
+ let daysOfMonth: Date[] = [];
162
+ for (let day = 1; day <= lastDayOfMonth; day++) {
163
+ daysOfMonth.push(new Date(year, month, day));
164
+ }
165
+
166
+ // Initialize calendarDays
167
+ let calendarDaysTemp = Array(calendarGridCount).fill(null);
168
+
169
+ // First day's weekday
170
+ const firstDayOfMonth = new Date(year, month, 1);
171
+ const firstDayOfWeekValue = firstDayOfMonth.getDay();
172
+
173
+ // Previous month padding
174
+ const prevMonthLastDay = new Date(year, month, 0).getDate();
175
+ const prevMonthStart = prevMonthLastDay - firstDayOfWeekValue + 1;
176
+ for (let i = 0; i < firstDayOfWeekValue; i++) {
177
+ calendarDaysTemp[i] = new Date(year, month - 1, prevMonthStart + i);
178
+ }
179
+
180
+ // Current month days
181
+ calendarDaysTemp = replaceCellsWithDays(calendarDaysTemp, daysOfMonth, firstDayOfWeekValue);
182
+
183
+ // Next month padding
184
+ const filledCells = firstDayOfWeekValue + daysOfMonth.length;
185
+ for (let i = filledCells, day = 1; i < calendarGridCount; i++, day++) {
186
+ calendarDaysTemp[i] = new Date(year, month + 1, day);
187
+ }
188
+
189
+ // Update month button states
190
+ showPrevMonthButton =
191
+ year < minDate.getFullYear() ||
192
+ (year === minDate.getFullYear() && month <= minDate.getMonth());
193
+ showNextMonthButton = maxDate
194
+ ? year > maxDate.getFullYear() ||
195
+ (year === maxDate.getFullYear() && month >= maxDate.getMonth())
196
+ : false;
197
+
198
+ calendarDays = calendarDaysTemp;
199
+ }
200
+
201
+ /**
202
+ * Fill the calendarDays array
203
+ */
204
+ function replaceCellsWithDays(cells: (Date | null)[], days: Date[], startPoint: number) {
205
+ const newCells = [...cells];
206
+
207
+ // Place days starting at startPoint
208
+ for (let i = 0; i < days.length; i++) {
209
+ if (startPoint + i < newCells.length) {
210
+ newCells[startPoint + i] = days[i];
211
+ } else {
212
+ break;
213
+ }
214
+ }
215
+
216
+ return newCells;
217
+ }
218
+
219
+ function clearDate() {
220
+ dateText = '';
221
+ selectedDate = null;
222
+ showDropdown = false;
223
+ getDays();
224
+ onDateUpdate('');
225
+ }
226
+
227
+ function prevMonth() {
228
+ viewDate = new Date(viewDate.getFullYear(), viewDate.getMonth() - 1, 1);
229
+ getDays();
230
+ }
231
+ function nextMonth() {
232
+ viewDate = new Date(viewDate.getFullYear(), viewDate.getMonth() + 1, 1);
233
+ getDays();
234
+ }
235
+
236
+ function selectDate(date: Date) {
237
+ selectedDate = date;
238
+ viewDate = new Date(date.getFullYear(), date.getMonth(), 1);
239
+ const newDateText = date.toLocaleDateString('en-US', {
240
+ year: 'numeric',
241
+ month: '2-digit',
242
+ day: '2-digit'
243
+ });
244
+ dateText = newDateText;
245
+ getDays();
246
+ showDropdown = false;
247
+ onDateUpdate(newDateText);
248
+ }
249
+
250
+ /**
251
+ * Generate a random string so that each
252
+ * input will have a unique id in the dom
253
+ */
254
+ function generateRandomString() {
255
+ const length = 6;
256
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
257
+
258
+ let result = '';
259
+ for (let i = 0; i < length; i++) {
260
+ const randomIndex = Math.floor(Math.random() * characters.length);
261
+ result += characters.charAt(randomIndex);
262
+ }
263
+
264
+ return result;
265
+ }
266
+
267
+ // blockedDates = [
268
+ // new Date(2025, 3, 15), // April 15, 2025
269
+ // new Date(2025, 3, 20), // April 20, 2025
270
+ // new Date(2025, 4, 5) // May 5, 2025
271
+ // ];
272
+ </script>
273
+
274
+ <div
275
+ class="picker"
276
+ style="
277
+ --dpicker-inputBgColor: {colorScheme.inputBgColor};
278
+ --dpicker-borderColor: {colorScheme.inputBorderColor};
279
+ --dpicker-textColor: {colorScheme.inputTextColor};
280
+ --dpicker-labelTextColor: {colorScheme.labelTextColor};
281
+ --dpicker-clearColor: {colorScheme.inputClearColor};
282
+ --dpicker-clearHoverColor: {colorScheme.inputClearHoverColor};
283
+ --dpicker-maxHeight: {colorScheme.pickerMaxHeight};
284
+ --dpicker-bgColor: {colorScheme.pickerBgColor};
285
+ --dpicker-inputFocusedBorderColor: {colorScheme.inputFocusedBorderColor};
286
+ --dpicker-monthBgColor: {colorScheme.pickerMonthBgColor};
287
+ --dpicker-selectedDayBgColor: {colorScheme.pickerSelectedDayBgColor};
288
+ --dpicker-selectedDayTextColor: {colorScheme.pickerSelectedDayTextColor};
289
+ --dpicker-inactiveDayColor: {colorScheme.pickerInactiveDayColor};
290
+ "
291
+ >
292
+ <div
293
+ class="outer"
294
+ bind:this={inputRef}
295
+ role="button"
296
+ tabindex={disabled ? -1 : 0}
297
+ class:disabled-input={disabled}
298
+ class:radius--l--only={radius === 'left'}
299
+ class:radius--r--only={radius === 'right'}
300
+ class:radius--full={radius === 'full'}
301
+ onclick={() => !disabled && (showDropdown = true)}
302
+ onkeydown={(e) =>
303
+ !disabled && (e.key === 'Enter' || e.key === 'Space') && (showDropdown = true)}
304
+ >
305
+ <label for="dpicker-{id}">
306
+ <div class="dpicker-title">
307
+ <div>{title}</div>
308
+ </div>
309
+ <div>
310
+ <div class="dpicker-input">
311
+ <input
312
+ type="text"
313
+ aria-label={name}
314
+ aria-describedby={name}
315
+ id="dpicker-input-{id}"
316
+ autocomplete="off"
317
+ {placeholder}
318
+ {name}
319
+ readonly
320
+ bind:value={dateText}
321
+ />
322
+ <div class="flex justify-center items-center p-3">
323
+ {#if dateText && !disabled}
324
+ <button
325
+ aria-label="Close Date Picker"
326
+ id="dpicker-CloseBtn-{id}"
327
+ class="dpicker-closeBtn w-6 h-6 flex justify-center items-center rounded-full"
328
+ onclick={(e) => {
329
+ e.stopPropagation();
330
+ clearDate();
331
+ }}
332
+ >
333
+ <div class="h-[14px] w-[14px] close-btn">
334
+ <svg
335
+ version="1.1"
336
+ id="Layer_1"
337
+ xmlns="http://www.w3.org/2000/svg"
338
+ xmlns:xlink="http://www.w3.org/1999/xlink"
339
+ x="0px"
340
+ y="0px"
341
+ viewBox="0 0 100 100"
342
+ style="enable-background:new 0 0 100 100;"
343
+ xml:space="preserve"
344
+ >
345
+ <path
346
+ fill="currentColor"
347
+ d="M87.8,87.4c-0.7,0.7-1.6,1.1-2.6,1.1c-0.9,0-1.8-0.4-2.5-1.1L50,55.1L17.8,87.8c-0.7,0.7-1.6,1.1-2.6,1.1
348
+ c-0.9,0-1.8-0.3-2.5-1.1c-1.4-1.4-1.4-3.7,0-5.1L44.9,50L12.2,17.8c-1.4-1.4-1.4-3.7,0-5.1c1.4-1.4,3.7-1.4,5.1,0L50,44.9l32.3-32.6
349
+ c1.4-1.4,3.7-1.4,5.1,0c1.4,1.4,1.4,3.7,0,5.1L55.1,50l32.6,32.3C89.2,83.7,89.2,86,87.8,87.4z"
350
+ />
351
+ </svg>
352
+ </div>
353
+ </button>
354
+ {/if}
355
+ </div>
356
+ </div>
357
+ </div>
358
+ </label>
359
+ </div>
360
+ {#if showDropdown && !disabled}
361
+ <div
362
+ bind:this={dropdownRef}
363
+ class="dpicker-dropdown {position}"
364
+ style="box-shadow: 0px 1px 16px 0px rgba(0,0,0,0.12);"
365
+ transition:fly={{ y: 10 }}
366
+ >
367
+ <div class="h-full">
368
+ <div class="grid grid-cols-7 month-block">
369
+ <button
370
+ id="chev-prev-{id}"
371
+ type="button"
372
+ aria-label="Previous Month"
373
+ class="w-full flex col-span-1 items-center justify-center cursor-pointer"
374
+ disabled={showPrevMonthButton}
375
+ onclick={prevMonth}
376
+ >
377
+ <div
378
+ class="size-8 flex justify-center items-center rounded-full chev"
379
+ class:disabled={showPrevMonthButton}
380
+ >
381
+ <div class="size-5">
382
+ <svg
383
+ version="1.1"
384
+ id="Layer_1"
385
+ xmlns="http://www.w3.org/2000/svg"
386
+ xmlns:xlink="http://www.w3.org/1999/xlink"
387
+ x="0px"
388
+ y="0px"
389
+ viewBox="0 0 200 200"
390
+ style="enable-background:new 0 0 200 200;"
391
+ xml:space="preserve"
392
+ >
393
+ <path
394
+ fill="currentColor"
395
+ d="M63.6,103.4c-1.9-1.9-1.9-5.1,0-7.1L129,30.9c1-1,2.2-1.5,3.5-1.5c1.3,0,2.6,0.5,3.5,1.5c1.9,1.9,1.9,5.1,0,7.1L74.3,99.8
396
+ l62.1,62.1c1.9,1.9,1.9,5.1,0,7.1l-0.1,0.1c-1.1,0.9-2.3,1.4-3.6,1.4c-1.3,0-2.6-0.5-3.5-1.5L63.6,103.4z"
397
+ />
398
+ </svg>
399
+ </div>
400
+ </div>
401
+ </button>
402
+ <div class="col-span-5 flex justify-center items-center">
403
+ {monthNames[viewDate.getMonth()]}
404
+ {viewDate.getFullYear()}
405
+ </div>
406
+ <button
407
+ id="chev-next-{id}"
408
+ type="button"
409
+ aria-label="Next Month"
410
+ class="w-full flex col-span-1 items-center justify-center cursor-pointer"
411
+ disabled={showNextMonthButton}
412
+ onclick={nextMonth}
413
+ >
414
+ <div
415
+ class="size-8 flex justify-center items-center rounded-full chev"
416
+ class:disabled={showNextMonthButton}
417
+ >
418
+ <div class="size-5">
419
+ <svg
420
+ version="1.1"
421
+ id="Layer_1"
422
+ xmlns="http://www.w3.org/2000/svg"
423
+ xmlns:xlink="http://www.w3.org/1999/xlink"
424
+ x="0px"
425
+ y="0px"
426
+ viewBox="0 0 200 200"
427
+ style="enable-background:new 0 0 200 200;"
428
+ xml:space="preserve"
429
+ >
430
+ <path
431
+ fill="currentColor"
432
+ d="M136.4,96.6c1.9,1.9,1.9,5.1,0,7.1L71,169.1c-1,1-2.2,1.5-3.5,1.5c-1.3,0-2.6-0.5-3.5-1.5c-1.9-1.9-1.9-5.1,0-7.1l61.8-61.8
433
+ L63.6,38c-1.9-1.9-1.9-5.1,0-7.1l0.1-0.1c1.1-0.9,2.3-1.4,3.6-1.4c1.3,0,2.6,0.5,3.5,1.5L136.4,96.6z"
434
+ />
435
+ </svg>
436
+ </div>
437
+ </div>
438
+ </button>
439
+ </div>
440
+ <div class="grid grid-cols-7">
441
+ {#each weekAbv as weekday}
442
+ <div class="flex justify-center items-center text-[var(--text-light)] text-sm">
443
+ {weekday}
444
+ </div>
445
+ {/each}
446
+ </div>
447
+ <div class="grid grid-cols-7 grid-rows-6">
448
+ {#each calendarDays as date, index (index)}
449
+ <div id="day-{index}" class="flex justify-center items-center">
450
+ {#if date}
451
+ <button
452
+ id="day-btn-{index}"
453
+ type="button"
454
+ class="h-10 w-10 flex justify-center items-center calendar-day"
455
+ class:highlighted={(selectedDate &&
456
+ date.toDateString() === selectedDate.toDateString()) ||
457
+ (!selectedDate && date.toDateString() === today.toDateString())}
458
+ class:other-month={date.getMonth() !== viewDate.getMonth()}
459
+ class:blocked={blockedDates.some((d) => d.toDateString() === date.toDateString())}
460
+ data-index={index}
461
+ aria-label={`Select ${date.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' })}`}
462
+ disabled={date < minDate ||
463
+ (maxDate && date > maxDate) ||
464
+ blockedDates.some((d) => d.toDateString() === date.toDateString())}
465
+ onclick={() => selectDate(date)}
466
+ >
467
+ {date.getDate()}
468
+ </button>
469
+ {:else}
470
+ <div class="h-10 w-10 flex justify-center items-center"></div>
471
+ {/if}
472
+ </div>
473
+ {/each}
474
+ </div>
475
+ </div>
476
+ </div>
477
+ {/if}
478
+ </div>
479
+
480
+ <style>
481
+ .picker {
482
+ position: relative;
483
+ display: inline-block;
484
+ width: 100%;
485
+ color: var(--dpicker-textColor);
486
+ }
487
+ .outer {
488
+ background-color: var(--dpicker-inputBgColor);
489
+ border: none;
490
+ line-height: 20px;
491
+ font-size: 16px;
492
+ margin: 0;
493
+ box-shadow: inset 0 0 0 1px var(--dpicker-borderColor);
494
+ width: 100%;
495
+ display: flex;
496
+ position: relative;
497
+ min-height: 62px;
498
+ text-size-adjust: 100%;
499
+ }
500
+ label {
501
+ line-height: 20px;
502
+ color: var(--dpicker-textColor);
503
+ flex-grow: 1;
504
+ flex-basis: 0%;
505
+ flex-shrink: 1;
506
+ position: relative;
507
+ box-sizing: border-box;
508
+ }
509
+ .dpicker-title {
510
+ line-height: 20px;
511
+ color: var(--dpicker-labelTextColor);
512
+ display: block;
513
+ left: 12px;
514
+ right: 12px;
515
+ position: absolute;
516
+ top: 18px;
517
+ transform: matrix(0.75, 0, 0, 0.75, 0, -8);
518
+ transform-origin: 0px 0px;
519
+ transition: transform 0.15s cubic-bezier(0.455, 0.03, 0.515, 0.955);
520
+ }
521
+ input {
522
+ background-color: transparent;
523
+ border: none;
524
+ font-family: inherit;
525
+ padding: 0;
526
+ line-height: inherit;
527
+ margin: 26px 12px 10px;
528
+ height: 20px;
529
+ width: 100%;
530
+ outline: none;
531
+ color: inherit;
532
+ appearance: none;
533
+ -webkit-appearance: none;
534
+ }
535
+ .dpicker-input {
536
+ display: flex;
537
+ opacity: 1;
538
+ }
539
+ .radius--full {
540
+ border-radius: 0.5rem /* 8px */;
541
+ }
542
+ .radius--l--only {
543
+ border-top-left-radius: 0.5rem /* 8px */;
544
+ border-bottom-left-radius: 0.5rem /* 8px */;
545
+ }
546
+ .radius--r--only {
547
+ border-top-right-radius: 0.5rem /* 8px */;
548
+ border-bottom-right-radius: 0.5rem /* 8px */;
549
+ }
550
+ .dpicker-closeBtn {
551
+ display: none;
552
+ color: var(--dpicker-clearColor);
553
+ }
554
+
555
+ .dpicker-closeBtn:hover {
556
+ background-color: var(--dpicker-clearHoverColor);
557
+ }
558
+ .outer:focus-within .dpicker-closeBtn {
559
+ display: flex;
560
+ }
561
+ .outer:not(.disabled-input):focus-within {
562
+ box-shadow: inset 0 0 0 2px var(--dpicker-inputFocusedBorderColor);
563
+ }
564
+
565
+ .dpicker-dropdown {
566
+ position: absolute;
567
+ display: flex;
568
+ flex-direction: column;
569
+ top: 110%;
570
+ z-index: 20;
571
+ overflow-y: auto;
572
+ border-radius: 0.5rem /* 8px */;
573
+ max-height: var(--dpicker-maxHeight);
574
+ width: 100%;
575
+ min-width: 300px;
576
+ background-color: var(--dpicker-bgColor);
577
+ }
578
+ .month-block {
579
+ width: 100%;
580
+ background-color: var(--picker-monthBgColor);
581
+ }
582
+ .chev:hover {
583
+ background-color: var(--dpicker-clearHoverColor);
584
+ }
585
+
586
+ .chev.disabled {
587
+ color: var(--dpicker-inactiveDayColor);
588
+ }
589
+ .calendar-day {
590
+ color: var(--dpicker-textColor);
591
+ border-radius: 50%;
592
+ }
593
+ .calendar-day:hover:not(:disabled) {
594
+ border: 1px solid var(--dpicker-textColor);
595
+ }
596
+ .highlighted {
597
+ background-color: var(--dpicker-selectedDayBgColor);
598
+ color: var(--dpicker-selectedDayTextColor);
599
+ opacity: 1 !important; /* Ensure full opacity for highlighted dates */
600
+ }
601
+
602
+ .other-month:not(.highlighted) {
603
+ color: var(--dpicker-textColor);
604
+ opacity: 0.65;
605
+ }
606
+ .calendar-day.blocked {
607
+ text-decoration: line-through;
608
+ color: var(--dpicker-inactiveDayColor);
609
+ cursor: not-allowed;
610
+ }
611
+
612
+ .calendar-day.blocked:hover:not(:disabled) {
613
+ border: none;
614
+ }
615
+
616
+ .calendar-day:disabled {
617
+ color: var(--dpicker-inactiveDayColor);
618
+ opacity: 0.7;
619
+ cursor: not-allowed;
620
+ }
621
+ .disabled-input {
622
+ opacity: 0.5;
623
+ cursor: not-allowed;
624
+ }
625
+ </style>
@@ -0,0 +1,17 @@
1
+ type $$ComponentProps = {
2
+ title: string;
3
+ name: string;
4
+ dateText?: string;
5
+ placeholder?: string;
6
+ minDate?: Date;
7
+ maxDate?: Date | null;
8
+ blockedDates?: Date[];
9
+ radius?: 'right' | 'left' | 'full';
10
+ position?: 'left-0' | 'right-0';
11
+ disabled?: boolean;
12
+ colorScheme?: Record<string, string>;
13
+ onDateUpdate?: (date: string) => void;
14
+ };
15
+ declare const DatePicker5: import("svelte").Component<$$ComponentProps, {}, "dateText">;
16
+ type DatePicker5 = ReturnType<typeof DatePicker5>;
17
+ export default DatePicker5;
@@ -0,0 +1,2 @@
1
+ import DatePicker5 from "./DatePicker5.svelte";
2
+ export { DatePicker5 };
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ // Reexport your entry components here
2
+ import DatePicker5 from "./DatePicker5.svelte";
3
+ export { DatePicker5 };
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@djcali570/component-lib",
3
+ "version": "0.0.1",
4
+ "scripts": {
5
+ "dev": "vite dev",
6
+ "build": "vite build && npm run prepack",
7
+ "package": "svelte-kit sync && svelte-package && publint",
8
+ "preview": "vite preview",
9
+ "prepare": "svelte-kit sync || echo ''",
10
+ "prepack": "svelte-kit sync && svelte-package && publint",
11
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
12
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
13
+ "format": "prettier --write .",
14
+ "lint": "prettier --check . && eslint ."
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "!dist/**/*.test.*",
19
+ "!dist/**/*.spec.*"
20
+ ],
21
+ "sideEffects": [
22
+ "**/*.css"
23
+ ],
24
+ "svelte": "./dist/index.js",
25
+ "types": "./dist/index.d.ts",
26
+ "type": "module",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "svelte": "./dist/index.js"
31
+ }
32
+ },
33
+ "peerDependencies": {
34
+ "svelte": "^5.0.0",
35
+ "@sveltejs/kit": "^2.16.0"
36
+ },
37
+ "devDependencies": {
38
+ "@eslint/compat": "^1.2.5",
39
+ "@eslint/js": "^9.18.0",
40
+ "@sveltejs/adapter-auto": "^6.0.0",
41
+ "@sveltejs/kit": "^2.16.0",
42
+ "@sveltejs/package": "^2.0.0",
43
+ "@sveltejs/vite-plugin-svelte": "^5.0.0",
44
+ "@tailwindcss/vite": "^4.0.0",
45
+ "eslint": "^9.18.0",
46
+ "eslint-config-prettier": "^10.0.1",
47
+ "eslint-plugin-svelte": "^3.0.0",
48
+ "globals": "^16.0.0",
49
+ "prettier": "^3.4.2",
50
+ "prettier-plugin-svelte": "^3.3.3",
51
+ "prettier-plugin-tailwindcss": "^0.6.11",
52
+ "publint": "^0.3.2",
53
+ "svelte": "^5.0.0",
54
+ "svelte-check": "^4.0.0",
55
+ "tailwindcss": "^4.0.0",
56
+ "typescript": "^5.0.0",
57
+ "typescript-eslint": "^8.20.0",
58
+ "vite": "^6.2.6"
59
+ },
60
+ "keywords": [
61
+ "svelte",
62
+ "SvelteKit",
63
+ "components"
64
+ ],
65
+ "author": {
66
+ "name": "Jay Cali"
67
+ }
68
+ }