@makolabs/ripple 1.2.3 → 1.2.8

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.
Files changed (114) hide show
  1. package/README.md +77 -0
  2. package/dist/adapters/ai/OpenAIAdapter.js +16 -11
  3. package/dist/adapters/ai/types.d.ts +3 -3
  4. package/dist/adapters/storage/BaseAdapter.d.ts +1 -1
  5. package/dist/adapters/storage/BaseAdapter.js +1 -1
  6. package/dist/adapters/storage/S3Adapter.js +2 -2
  7. package/dist/ai/AIChatInterface.svelte +32 -34
  8. package/dist/ai/AIChatInterface.svelte.d.ts +0 -1
  9. package/dist/ai/AIChatInterfaceTestWrapper.svelte +26 -0
  10. package/dist/ai/AIChatInterfaceTestWrapper.svelte.d.ts +17 -0
  11. package/dist/ai/ChatInput.svelte +7 -15
  12. package/dist/ai/ChatInput.svelte.d.ts +0 -2
  13. package/dist/ai/CodeRenderer.svelte +25 -12
  14. package/dist/ai/ComposeDropdown.svelte +17 -14
  15. package/dist/ai/MermaidRenderer.svelte +21 -17
  16. package/dist/ai/MermaidRenderer.svelte.d.ts +0 -1
  17. package/dist/ai/MessageBox.svelte +10 -7
  18. package/dist/ai/ThinkingDisplay.svelte +67 -43
  19. package/dist/ai/ai-chat-interface.d.ts +22 -21
  20. package/dist/ai/ai-chat-interface.js +8 -7
  21. package/dist/ai/content-detector.js +2 -2
  22. package/dist/button/ButtonTestWrapper.svelte +10 -0
  23. package/dist/button/ButtonTestWrapper.svelte.d.ts +7 -0
  24. package/dist/charts/Chart.svelte +6 -1
  25. package/dist/config/ai.js +1 -0
  26. package/dist/drawer/DrawerTestWrapper.svelte +19 -0
  27. package/dist/drawer/DrawerTestWrapper.svelte.d.ts +9 -0
  28. package/dist/drawer/drawer.d.ts +19 -18
  29. package/dist/drawer/drawer.js +7 -6
  30. package/dist/elements/accordion/Accordion.svelte +1 -1
  31. package/dist/elements/accordion/Accordion.svelte.d.ts +1 -1
  32. package/dist/elements/accordion/AccordionTestWrapper.svelte +21 -0
  33. package/dist/elements/accordion/AccordionTestWrapper.svelte.d.ts +10 -0
  34. package/dist/elements/badge/Badge.svelte +5 -4
  35. package/dist/elements/badge/BadgeTestWrapper.svelte +14 -0
  36. package/dist/elements/badge/BadgeTestWrapper.svelte.d.ts +9 -0
  37. package/dist/elements/badge/badge.d.ts +40 -39
  38. package/dist/elements/badge/badge.js +14 -13
  39. package/dist/elements/dropdown/Dropdown.svelte +0 -1
  40. package/dist/elements/pagination/Pagination.svelte +20 -26
  41. package/dist/elements/progress/Progress.svelte +3 -3
  42. package/dist/elements/timeline/Timeline.svelte +1 -1
  43. package/dist/file-browser/FileBrowser.svelte +7 -10
  44. package/dist/filters/CompactFilters.svelte +3 -3
  45. package/dist/forms/Checkbox.svelte +0 -1
  46. package/dist/forms/CheckboxTestWrapper.svelte +8 -0
  47. package/dist/forms/CheckboxTestWrapper.svelte.d.ts +4 -0
  48. package/dist/forms/DateRange.svelte +186 -198
  49. package/dist/forms/Form.svelte +1 -0
  50. package/dist/forms/Input.svelte +14 -5
  51. package/dist/forms/InputTestWrapper.svelte +8 -0
  52. package/dist/forms/InputTestWrapper.svelte.d.ts +4 -0
  53. package/dist/forms/NumberInput.svelte +2 -2
  54. package/dist/forms/RadioInputs.svelte +1 -1
  55. package/dist/forms/RadioPill.svelte +1 -1
  56. package/dist/forms/Slider.svelte +2 -2
  57. package/dist/forms/Tags.svelte +3 -3
  58. package/dist/forms/ToggleTestWrapper.svelte +8 -0
  59. package/dist/forms/ToggleTestWrapper.svelte.d.ts +7 -0
  60. package/dist/forms/slider.js +1 -1
  61. package/dist/header/PageHeader.svelte +2 -1
  62. package/dist/header/breadcrumbs.d.ts +47 -33
  63. package/dist/header/breadcrumbs.js +12 -11
  64. package/dist/index.d.ts +3 -2
  65. package/dist/index.js +2 -0
  66. package/dist/layout/activity-list/ActivityList.svelte +9 -11
  67. package/dist/layout/card/CardTestWrapper.svelte +15 -0
  68. package/dist/layout/card/CardTestWrapper.svelte.d.ts +7 -0
  69. package/dist/layout/card/RankedCard.svelte +2 -3
  70. package/dist/layout/navbar/navbar.d.ts +19 -18
  71. package/dist/layout/navbar/navbar.js +7 -6
  72. package/dist/layout/sidebar/NavGroup.svelte +1 -0
  73. package/dist/layout/table/Cells.svelte +5 -5
  74. package/dist/layout/table/Table.svelte +8 -8
  75. package/dist/layout/table/table.d.ts +28 -24
  76. package/dist/layout/table/table.js +14 -13
  77. package/dist/modal/Modal.svelte +1 -1
  78. package/dist/modal/ModalTestWrapper.svelte +20 -0
  79. package/dist/modal/ModalTestWrapper.svelte.d.ts +8 -0
  80. package/dist/modal/modal.d.ts +1 -20
  81. package/dist/pipeline/Pipeline.svelte +29 -17
  82. package/dist/user-management/README.md +417 -0
  83. package/dist/user-management/UserManagement.svelte +245 -0
  84. package/dist/user-management/UserManagement.svelte.d.ts +4 -0
  85. package/dist/user-management/UserManagementTestWrapper.svelte +33 -0
  86. package/dist/user-management/UserManagementTestWrapper.svelte.d.ts +13 -0
  87. package/dist/user-management/UserModal.svelte +285 -0
  88. package/dist/user-management/UserModal.svelte.d.ts +4 -0
  89. package/dist/user-management/UserModalTestWrapper.svelte +22 -0
  90. package/dist/user-management/UserModalTestWrapper.svelte.d.ts +7 -0
  91. package/dist/user-management/UserTable.svelte +219 -0
  92. package/dist/user-management/UserTable.svelte.d.ts +4 -0
  93. package/dist/user-management/UserTableTestWrapper.svelte +41 -0
  94. package/dist/user-management/UserTableTestWrapper.svelte.d.ts +7 -0
  95. package/dist/user-management/UserViewModal.svelte +276 -0
  96. package/dist/user-management/UserViewModal.svelte.d.ts +4 -0
  97. package/dist/user-management/UserViewModalTestWrapper.svelte +22 -0
  98. package/dist/user-management/UserViewModalTestWrapper.svelte.d.ts +7 -0
  99. package/dist/user-management/adapters/UserManagement.remote.d.ts +68 -0
  100. package/dist/user-management/adapters/UserManagement.remote.js +487 -0
  101. package/dist/user-management/adapters/index.d.ts +10 -0
  102. package/dist/user-management/adapters/index.js +12 -0
  103. package/dist/user-management/adapters/mockUserManagement.d.ts +70 -0
  104. package/dist/user-management/adapters/mockUserManagement.js +187 -0
  105. package/dist/user-management/adapters/types.d.ts +24 -0
  106. package/dist/user-management/adapters/types.js +7 -0
  107. package/dist/user-management/index.d.ts +12 -0
  108. package/dist/user-management/index.js +11 -0
  109. package/dist/user-management/user-management.d.ts +126 -0
  110. package/dist/user-management/user-management.js +42 -0
  111. package/package.json +4 -1
  112. package/dist/types/markdown.d.ts +0 -14
  113. package/dist/types/variants.d.ts +0 -1
  114. package/dist/types/variants.js +0 -1
@@ -44,21 +44,6 @@
44
44
  return format.replace('yyyy', String(year)).replace('MM', month).replace('dd', day);
45
45
  }
46
46
 
47
- function parseDate(dateStr: string): Date | null {
48
- if (!dateStr) return null;
49
-
50
- const parts = dateStr.split('/');
51
- if (parts.length !== 3) return null;
52
-
53
- const month = parseInt(parts[0], 10) - 1;
54
- const day = parseInt(parts[1], 10);
55
- const year = parseInt(parts[2], 10);
56
-
57
- if (isNaN(month) || isNaN(day) || isNaN(year)) return null;
58
-
59
- return new Date(year, month, day);
60
- }
61
-
62
47
  function getDaysInMonth(month: Date): {
63
48
  date: Date;
64
49
  isCurrentMonth: boolean;
@@ -83,6 +68,7 @@
83
68
  const daysInCalendar = 42; // 6 rows of 7 days
84
69
  const daysFromNextMonth = daysInCalendar - daysInMonth - daysFromPrevMonth;
85
70
 
71
+ // eslint-disable-next-line svelte/prefer-svelte-reactivity
86
72
  const today = new Date();
87
73
  today.setHours(0, 0, 0, 0);
88
74
 
@@ -298,205 +284,207 @@
298
284
  <Portal target={datePickerRef}>
299
285
  <div
300
286
  bind:this={calendarRef}
301
- class="ring-opacity-5 absolute z-10 mt-1 w-full origin-top-left rounded-md bg-white p-4 shadow-lg ring-1 ring-default-300 focus:outline-none"
287
+ class="ring-opacity-5 ring-default-300 absolute z-10 mt-1 w-full origin-top-left rounded-md bg-white p-4 shadow-lg ring-1 focus:outline-none"
302
288
  >
303
- <div class="mb-2 flex items-center justify-between">
304
- {#if viewMode === 'days'}
305
- <button
306
- type="button"
307
- aria-label="Previous month"
308
- class="text-default-500 hover:bg-default-100 inline-flex items-center rounded-md p-1 text-sm"
309
- onclick={prevMonth}
310
- >
311
- <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
312
- <path
313
- fill-rule="evenodd"
314
- d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
315
- clip-rule="evenodd"
316
- />
317
- </svg>
318
- </button>
319
- <button
320
- type="button"
321
- class="text-default-700 hover:bg-default-100 inline-flex items-center rounded-md px-2 py-1 text-sm font-medium"
322
- onclick={showMonths}
323
- >
324
- {getMonthName(viewDate.getMonth())}
325
- {viewDate.getFullYear()}
326
- </button>
327
- <button
328
- type="button"
329
- aria-label="Next month"
330
- class="text-default-500 hover:bg-default-100 inline-flex items-center rounded-md p-1 text-sm"
331
- onclick={nextMonth}
332
- >
333
- <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
334
- <path
335
- fill-rule="evenodd"
336
- d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
337
- clip-rule="evenodd"
338
- />
339
- </svg>
340
- </button>
341
- {:else if viewMode === 'months'}
342
- <button
343
- type="button"
344
- aria-label="Previous year"
345
- class="text-default-500 hover:bg-default-100 inline-flex items-center rounded-md p-1 text-sm"
346
- onclick={() =>
347
- (viewDate = new Date(viewDate.getFullYear() - 1, viewDate.getMonth(), 1))}
348
- >
349
- <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
350
- <path
351
- fill-rule="evenodd"
352
- d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
353
- clip-rule="evenodd"
354
- />
355
- </svg>
356
- </button>
357
- <button
358
- type="button"
359
- aria-label="Current year"
360
- class="text-default-700 inline-flex items-center rounded-md px-2 py-1 text-sm font-medium"
361
- onclick={showYears}
362
- >
363
- {viewDate.getFullYear()}
364
- </button>
365
- <button
366
- type="button"
367
- aria-label="Next year"
368
- class="text-default-500 hover:bg-default-100 inline-flex items-center rounded-md p-1 text-sm"
369
- onclick={() =>
370
- (viewDate = new Date(viewDate.getFullYear() + 1, viewDate.getMonth(), 1))}
371
- >
372
- <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
373
- <path
374
- fill-rule="evenodd"
375
- d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
376
- clip-rule="evenodd"
377
- />
378
- </svg>
379
- </button>
380
- {:else if viewMode === 'years'}
381
- <button
382
- type="button"
383
- aria-label="Previous year"
384
- class="text-default-500 hover:bg-default-100 inline-flex items-center rounded-md p-1 text-sm"
385
- onclick={() =>
386
- (viewDate = new Date(viewDate.getFullYear() - 12, viewDate.getMonth(), 1))}
387
- >
388
- <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
389
- <path
390
- fill-rule="evenodd"
391
- d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
392
- clip-rule="evenodd"
393
- />
394
- </svg>
395
- </button>
396
- <button
397
- type="button"
398
- aria-label="Current year range"
399
- class="text-default-700 inline-flex items-center rounded-md px-2 py-1 text-sm font-medium"
400
- >
401
- {viewDate.getFullYear() - 6} - {viewDate.getFullYear() + 5}
402
- </button>
403
- <button
404
- type="button"
405
- aria-label="Next year"
406
- class="text-default-500 hover:bg-default-100 inline-flex items-center rounded-md p-1 text-sm"
407
- onclick={() =>
408
- (viewDate = new Date(viewDate.getFullYear() + 12, viewDate.getMonth(), 1))}
409
- >
410
- <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
411
- <path
412
- fill-rule="evenodd"
413
- d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
414
- clip-rule="evenodd"
415
- />
416
- </svg>
417
- </button>
418
- {/if}
419
- </div>
420
-
421
- {#if viewMode === 'days'}
422
- <div class="text-default-500 mb-1 grid grid-cols-7 gap-1 text-center text-xs font-medium">
423
- <div>Su</div>
424
- <div>Mo</div>
425
- <div>Tu</div>
426
- <div>We</div>
427
- <div>Th</div>
428
- <div>Fr</div>
429
- <div>Sa</div>
430
- </div>
431
- <div class="grid grid-cols-7 gap-1">
432
- {#each getDaysInMonth(viewDate) as { date, isCurrentMonth, isToday, isSelected, isInRange, isDisabled }}
289
+ <div class="mb-2 flex items-center justify-between">
290
+ {#if viewMode === 'days'}
433
291
  <button
434
292
  type="button"
435
- class={cn(
436
- 'flex h-8 w-8 items-center justify-center rounded-full text-sm font-medium',
437
- isDisabled ? 'text-default-300 cursor-not-allowed' : 'hover:bg-default-100',
438
- isSelected ? 'bg-primary-500 hover:bg-primary-600 text-white' : '',
439
- isInRange && !isSelected ? 'bg-primary-100 text-primary-800' : '',
440
- !isCurrentMonth && !isSelected && !isInRange ? 'text-default-400' : '',
441
- isToday && !isSelected ? 'border-primary-500 border' : ''
442
- )}
443
- onclick={() => handleDateClick(date)}
444
- onmouseenter={() => handleDateHover(date)}
445
- disabled={isDisabled}
293
+ aria-label="Previous month"
294
+ class="text-default-500 hover:bg-default-100 inline-flex items-center rounded-md p-1 text-sm"
295
+ onclick={prevMonth}
446
296
  >
447
- {date.getDate()}
297
+ <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
298
+ <path
299
+ fill-rule="evenodd"
300
+ d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
301
+ clip-rule="evenodd"
302
+ />
303
+ </svg>
448
304
  </button>
449
- {/each}
450
- </div>
451
- {:else if viewMode === 'months'}
452
- <div class="grid grid-cols-3 gap-2">
453
- {#each Array(12).fill(0) as _, month}
454
305
  <button
455
306
  type="button"
456
- class={cn(
457
- 'flex items-center justify-center rounded-md px-2 py-1 text-sm font-medium',
458
- viewDate.getMonth() === month
459
- ? 'bg-primary-500 text-white'
460
- : 'text-default-700 hover:bg-default-100'
461
- )}
462
- onclick={() => selectMonth(month)}
307
+ class="text-default-700 hover:bg-default-100 inline-flex items-center rounded-md px-2 py-1 text-sm font-medium"
308
+ onclick={showMonths}
463
309
  >
464
- {getMonthName(month).substring(0, 3)}
310
+ {getMonthName(viewDate.getMonth())}
311
+ {viewDate.getFullYear()}
312
+ </button>
313
+ <button
314
+ type="button"
315
+ aria-label="Next month"
316
+ class="text-default-500 hover:bg-default-100 inline-flex items-center rounded-md p-1 text-sm"
317
+ onclick={nextMonth}
318
+ >
319
+ <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
320
+ <path
321
+ fill-rule="evenodd"
322
+ d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
323
+ clip-rule="evenodd"
324
+ />
325
+ </svg>
326
+ </button>
327
+ {:else if viewMode === 'months'}
328
+ <button
329
+ type="button"
330
+ aria-label="Previous year"
331
+ class="text-default-500 hover:bg-default-100 inline-flex items-center rounded-md p-1 text-sm"
332
+ onclick={() =>
333
+ (viewDate = new Date(viewDate.getFullYear() - 1, viewDate.getMonth(), 1))}
334
+ >
335
+ <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
336
+ <path
337
+ fill-rule="evenodd"
338
+ d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
339
+ clip-rule="evenodd"
340
+ />
341
+ </svg>
342
+ </button>
343
+ <button
344
+ type="button"
345
+ aria-label="Current year"
346
+ class="text-default-700 inline-flex items-center rounded-md px-2 py-1 text-sm font-medium"
347
+ onclick={showYears}
348
+ >
349
+ {viewDate.getFullYear()}
350
+ </button>
351
+ <button
352
+ type="button"
353
+ aria-label="Next year"
354
+ class="text-default-500 hover:bg-default-100 inline-flex items-center rounded-md p-1 text-sm"
355
+ onclick={() =>
356
+ (viewDate = new Date(viewDate.getFullYear() + 1, viewDate.getMonth(), 1))}
357
+ >
358
+ <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
359
+ <path
360
+ fill-rule="evenodd"
361
+ d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
362
+ clip-rule="evenodd"
363
+ />
364
+ </svg>
365
+ </button>
366
+ {:else if viewMode === 'years'}
367
+ <button
368
+ type="button"
369
+ aria-label="Previous year"
370
+ class="text-default-500 hover:bg-default-100 inline-flex items-center rounded-md p-1 text-sm"
371
+ onclick={() =>
372
+ (viewDate = new Date(viewDate.getFullYear() - 12, viewDate.getMonth(), 1))}
373
+ >
374
+ <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
375
+ <path
376
+ fill-rule="evenodd"
377
+ d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
378
+ clip-rule="evenodd"
379
+ />
380
+ </svg>
381
+ </button>
382
+ <button
383
+ type="button"
384
+ aria-label="Current year range"
385
+ class="text-default-700 inline-flex items-center rounded-md px-2 py-1 text-sm font-medium"
386
+ >
387
+ {viewDate.getFullYear() - 6} - {viewDate.getFullYear() + 5}
465
388
  </button>
466
- {/each}
467
- </div>
468
- {:else if viewMode === 'years'}
469
- <div class="grid grid-cols-3 gap-2">
470
- {#each Array(12).fill(0) as _, i}
471
- {@const year = viewDate.getFullYear() - 6 + i}
472
389
  <button
473
390
  type="button"
474
- class={cn(
475
- 'flex items-center justify-center rounded-md px-2 py-1 text-sm font-medium',
476
- viewDate.getFullYear() === year
477
- ? 'bg-primary-500 text-white'
478
- : 'text-default-700 hover:bg-default-100'
479
- )}
480
- onclick={() => selectYear(year)}
391
+ aria-label="Next year"
392
+ class="text-default-500 hover:bg-default-100 inline-flex items-center rounded-md p-1 text-sm"
393
+ onclick={() =>
394
+ (viewDate = new Date(viewDate.getFullYear() + 12, viewDate.getMonth(), 1))}
481
395
  >
482
- {year}
396
+ <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
397
+ <path
398
+ fill-rule="evenodd"
399
+ d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
400
+ clip-rule="evenodd"
401
+ />
402
+ </svg>
483
403
  </button>
484
- {/each}
404
+ {/if}
485
405
  </div>
486
- {/if}
487
-
488
- {#if startDate || endDate}
489
- <div
490
- class="border-default-200 text-default-500 mt-4 flex justify-between border-t pt-3 text-xs"
491
- >
492
- <div>
493
- {startDate ? `${startLabel}: ${formatDate(startDate)}` : ''}
406
+
407
+ {#if viewMode === 'days'}
408
+ <div class="text-default-500 mb-1 grid grid-cols-7 gap-1 text-center text-xs font-medium">
409
+ <div>Su</div>
410
+ <div>Mo</div>
411
+ <div>Tu</div>
412
+ <div>We</div>
413
+ <div>Th</div>
414
+ <div>Fr</div>
415
+ <div>Sa</div>
494
416
  </div>
495
- <div>
496
- {endDate ? `${endLabel}: ${formatDate(endDate)}` : ''}
417
+ <div class="grid grid-cols-7 gap-1">
418
+ {#each getDaysInMonth(viewDate) as { date, isCurrentMonth, isToday, isSelected, isInRange, isDisabled } (date.getTime())}
419
+ <button
420
+ type="button"
421
+ class={cn(
422
+ 'flex h-8 w-8 items-center justify-center rounded-full text-sm font-medium',
423
+ isDisabled ? 'text-default-300 cursor-not-allowed' : 'hover:bg-default-100',
424
+ isSelected ? 'bg-primary-500 hover:bg-primary-600 text-white' : '',
425
+ isInRange && !isSelected ? 'bg-primary-100 text-primary-800' : '',
426
+ !isCurrentMonth && !isSelected && !isInRange ? 'text-default-400' : '',
427
+ isToday && !isSelected ? 'border-primary-500 border' : ''
428
+ )}
429
+ onclick={() => handleDateClick(date)}
430
+ onmouseenter={() => handleDateHover(date)}
431
+ disabled={isDisabled}
432
+ >
433
+ {date.getDate()}
434
+ </button>
435
+ {/each}
497
436
  </div>
498
- </div>
499
- {/if}
437
+ {:else if viewMode === 'months'}
438
+ <div class="grid grid-cols-3 gap-2">
439
+ <!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
440
+ {#each Array(12).fill(0) as _, month (month)}
441
+ <button
442
+ type="button"
443
+ class={cn(
444
+ 'flex items-center justify-center rounded-md px-2 py-1 text-sm font-medium',
445
+ viewDate.getMonth() === month
446
+ ? 'bg-primary-500 text-white'
447
+ : 'text-default-700 hover:bg-default-100'
448
+ )}
449
+ onclick={() => selectMonth(month)}
450
+ >
451
+ {getMonthName(month).substring(0, 3)}
452
+ </button>
453
+ {/each}
454
+ </div>
455
+ {:else if viewMode === 'years'}
456
+ <div class="grid grid-cols-3 gap-2">
457
+ <!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
458
+ {#each Array(12).fill(0) as _, i (i)}
459
+ {@const year = viewDate.getFullYear() - 6 + i}
460
+ <button
461
+ type="button"
462
+ class={cn(
463
+ 'flex items-center justify-center rounded-md px-2 py-1 text-sm font-medium',
464
+ viewDate.getFullYear() === year
465
+ ? 'bg-primary-500 text-white'
466
+ : 'text-default-700 hover:bg-default-100'
467
+ )}
468
+ onclick={() => selectYear(year)}
469
+ >
470
+ {year}
471
+ </button>
472
+ {/each}
473
+ </div>
474
+ {/if}
475
+
476
+ {#if startDate || endDate}
477
+ <div
478
+ class="border-default-200 text-default-500 mt-4 flex justify-between border-t pt-3 text-xs"
479
+ >
480
+ <div>
481
+ {startDate ? `${startLabel}: ${formatDate(startDate)}` : ''}
482
+ </div>
483
+ <div>
484
+ {endDate ? `${endLabel}: ${formatDate(endDate)}` : ''}
485
+ </div>
486
+ </div>
487
+ {/if}
500
488
  </div>
501
489
  </Portal>
502
490
  {/if}
@@ -13,6 +13,7 @@
13
13
  novalidate = false,
14
14
  children,
15
15
  ...restProps
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
17
  }: FormProps<any> = $props();
17
18
 
18
19
  const { enhance, delayed } = form;
@@ -40,15 +40,24 @@
40
40
  )
41
41
  );
42
42
 
43
- const inputCommonProps = $derived({
43
+ const commonProps = $derived({
44
44
  id,
45
45
  name,
46
- type,
47
46
  placeholder,
48
47
  disabled,
49
48
  class: inputClasses,
50
49
  'aria-invalid': !!errors.length,
51
- 'aria-describedby': errors.length ? `${name}-errors` : undefined,
50
+ 'aria-describedby': errors.length ? `${name}-errors` : undefined
51
+ });
52
+
53
+ const inputProps = $derived({
54
+ ...commonProps,
55
+ type,
56
+ ...restProps
57
+ });
58
+
59
+ const textareaProps = $derived({
60
+ ...commonProps,
52
61
  ...restProps
53
62
  });
54
63
  </script>
@@ -56,9 +65,9 @@
56
65
  <div class="w-full">
57
66
  {@render Label('mb-2')}
58
67
  {#if type === 'textarea'}
59
- <textarea {...inputCommonProps} bind:value></textarea>
68
+ <textarea {...textareaProps as unknown as Record<string, unknown>} bind:value></textarea>
60
69
  {:else}
61
- <input {...inputCommonProps} bind:value />
70
+ <input {...inputProps} bind:value />
62
71
  {/if}
63
72
  {#if errors.length}
64
73
  {#each errors as error (error)}
@@ -0,0 +1,8 @@
1
+ <script lang="ts">
2
+ import Input from './Input.svelte';
3
+ import type { InputProps } from '../index.js';
4
+
5
+ let { ...inputProps }: InputProps = $props();
6
+ </script>
7
+
8
+ <Input {...inputProps} />
@@ -0,0 +1,4 @@
1
+ import type { InputProps } from '../index.js';
2
+ declare const InputTestWrapper: import("svelte").Component<InputProps, {}, "">;
3
+ type InputTestWrapper = ReturnType<typeof InputTestWrapper>;
4
+ export default InputTestWrapper;
@@ -131,7 +131,7 @@
131
131
 
132
132
  {#if showUnitDropdown}
133
133
  <div class={dropdownClass}>
134
- {#each units as unitOption}
134
+ {#each units as unitOption (unitOption.value)}
135
135
  <button
136
136
  type="button"
137
137
  class="hover:bg-default-100 w-full px-3 py-1.5 text-left text-sm"
@@ -152,7 +152,7 @@
152
152
  </div>
153
153
 
154
154
  {#if errors?.length}
155
- {#each errors as error}
155
+ {#each errors as error (error)}
156
156
  <p class="text-danger-600 text-sm">{error}</p>
157
157
  {/each}
158
158
  {/if}
@@ -35,7 +35,7 @@
35
35
  <label class={labelClass} for={`${name}-${value || options[0].value}`}>{label}</label>
36
36
  {/if}
37
37
  <div class="space-y-2">
38
- {#each options as option}
38
+ {#each options as option (option.value)}
39
39
  <div class="flex items-center gap-2">
40
40
  <input
41
41
  type="radio"
@@ -38,7 +38,7 @@
38
38
  >
39
39
  {/if}
40
40
  <div class="inline-flex flex-wrap gap-2">
41
- {#each options as option}
41
+ {#each options as option (option.value)}
42
42
  <button
43
43
  id={option.value}
44
44
  type="button"
@@ -311,7 +311,7 @@
311
311
  onkeydown={handleKeydown}
312
312
  onmousedown={(e) => handleThumbMouseDown(e, 'single')}
313
313
  ></div>
314
- {#each options as option, i}
314
+ {#each options as option, i (option.value)}
315
315
  <div class={markClass} style="left: {(i / (options.length - 1)) * 100}%">
316
316
  {option.label}
317
317
  </div>
@@ -333,7 +333,7 @@
333
333
  </div>
334
334
 
335
335
  {#if errors.length}
336
- {#each errors as error}
336
+ {#each errors as error (error)}
337
337
  <p class="mt-2.5 text-sm text-red-600" role="alert">
338
338
  {error}
339
339
  </p>
@@ -133,7 +133,7 @@
133
133
  <label for={name} class="text-default-700 block text-sm font-medium">{label}</label>
134
134
  {/if}
135
135
  <div class={containerClass} onfocusout={handleFocusOut}>
136
- {#each value as tag}
136
+ {#each value as tag (tag)}
137
137
  <Badge {size} color="info" onclose={() => handleTagRemoval(tag)} class="shadow-xs">
138
138
  {tag}
139
139
  </Badge>
@@ -157,7 +157,7 @@
157
157
 
158
158
  {#if showSuggestions && filteredSuggestions.length > 0}
159
159
  <div class={suggestionClass}>
160
- {#each filteredSuggestions as suggestion, i}
160
+ {#each filteredSuggestions as suggestion, i (suggestion)}
161
161
  <button
162
162
  type="button"
163
163
  class={suggestionItemClass(i === highlightedIndex)}
@@ -174,7 +174,7 @@
174
174
  </div>
175
175
 
176
176
  {#if errors?.length}
177
- {#each errors as error}
177
+ {#each errors as error (error)}
178
178
  <p class="text-sm text-red-600">{error}</p>
179
179
  {/each}
180
180
  {/if}
@@ -0,0 +1,8 @@
1
+ <script lang="ts">
2
+ import Toggle from './Toggle.svelte';
3
+ import type { ToggleProps } from '../index.js';
4
+
5
+ let { label = '', ...toggleProps }: ToggleProps & { label?: string } = $props();
6
+ </script>
7
+
8
+ <Toggle {label} {...toggleProps} />
@@ -0,0 +1,7 @@
1
+ import type { ToggleProps } from '../index.js';
2
+ type $$ComponentProps = ToggleProps & {
3
+ label?: string;
4
+ };
5
+ declare const ToggleTestWrapper: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type ToggleTestWrapper = ReturnType<typeof ToggleTestWrapper>;
7
+ export default ToggleTestWrapper;
@@ -1,5 +1,5 @@
1
1
  import { tv } from 'tailwind-variants';
2
- import { Color, Size } from '../variants.js';
2
+ import { Size } from '../variants.js';
3
3
  export const slider = tv({
4
4
  slots: {
5
5
  base: 'relative w-full',
@@ -18,6 +18,7 @@
18
18
 
19
19
  const hasBreadcrumbs = $derived(breadcrumbs && breadcrumbs.length > 0);
20
20
  const titleClasses = $derived(cn(defaultTitleClasses, titleClassName));
21
+ const containerClass = $derived(cn('space-y-4', className as string));
21
22
  </script>
22
23
 
23
24
  <div class="pb-4">
@@ -45,7 +46,7 @@
45
46
  </div>
46
47
  {:else}
47
48
  <!-- Vertical layout - title/subtitle unit first, children unit below -->
48
- <div class={className}>
49
+ <div class={containerClass}>
49
50
  <!-- Title and subtitle grouped together -->
50
51
  <div class="min-w-0 gap-4">
51
52
  {#if hasBreadcrumbs}