cisse-vue-ui 0.5.22 → 0.5.23

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 (105) hide show
  1. package/dist/{Button.vue_vue_type_script_setup_true_lang-DKE8elsf.js → Button.vue_vue_type_script_setup_true_lang-CD9QPOeU.js} +13 -4
  2. package/dist/Button.vue_vue_type_script_setup_true_lang-CD9QPOeU.js.map +1 -0
  3. package/dist/{Button.vue_vue_type_script_setup_true_lang-DrGM65ny.cjs → Button.vue_vue_type_script_setup_true_lang-Cev21KGJ.cjs} +13 -4
  4. package/dist/Button.vue_vue_type_script_setup_true_lang-Cev21KGJ.cjs.map +1 -0
  5. package/dist/{Combobox.vue_vue_type_script_setup_true_lang-FdUrjmSG.cjs → Combobox.vue_vue_type_script_setup_true_lang-D9TIId4E.cjs} +233 -101
  6. package/dist/Combobox.vue_vue_type_script_setup_true_lang-D9TIId4E.cjs.map +1 -0
  7. package/dist/{Combobox.vue_vue_type_script_setup_true_lang-DhcLb6DX.js → Combobox.vue_vue_type_script_setup_true_lang-DCLKWzhc.js} +234 -102
  8. package/dist/Combobox.vue_vue_type_script_setup_true_lang-DCLKWzhc.js.map +1 -0
  9. package/dist/{ConfirmDialog.vue_vue_type_script_setup_true_lang-DXb9wQQv.cjs → ConfirmDialog.vue_vue_type_script_setup_true_lang-CwHYxBhR.cjs} +76 -29
  10. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-CwHYxBhR.cjs.map +1 -0
  11. package/dist/{ConfirmDialog.vue_vue_type_script_setup_true_lang-CNucAMQg.js → ConfirmDialog.vue_vue_type_script_setup_true_lang-Dm4kLAnr.js} +77 -30
  12. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-Dm4kLAnr.js.map +1 -0
  13. package/dist/{DarkModeToggle.vue_vue_type_script_setup_true_lang-BoB48313.cjs → DarkModeToggle.vue_vue_type_script_setup_true_lang-CSxGvdSP.cjs} +76 -44
  14. package/dist/DarkModeToggle.vue_vue_type_script_setup_true_lang-CSxGvdSP.cjs.map +1 -0
  15. package/dist/{DarkModeToggle.vue_vue_type_script_setup_true_lang-43fxlbro.js → DarkModeToggle.vue_vue_type_script_setup_true_lang-D1Q43mhJ.js} +76 -44
  16. package/dist/DarkModeToggle.vue_vue_type_script_setup_true_lang-D1Q43mhJ.js.map +1 -0
  17. package/dist/{Dropdown.vue_vue_type_script_setup_true_lang-DKxcVBKu.cjs → Dropdown.vue_vue_type_script_setup_true_lang-DNeh9Gi-.cjs} +32 -15
  18. package/dist/Dropdown.vue_vue_type_script_setup_true_lang-DNeh9Gi-.cjs.map +1 -0
  19. package/dist/{Dropdown.vue_vue_type_script_setup_true_lang-C3pr8BwC.js → Dropdown.vue_vue_type_script_setup_true_lang-DXV811zB.js} +32 -15
  20. package/dist/Dropdown.vue_vue_type_script_setup_true_lang-DXV811zB.js.map +1 -0
  21. package/dist/{PageLayout.vue_vue_type_script_setup_true_lang-D22uNeS1.cjs → PageLayout.vue_vue_type_script_setup_true_lang-C0YzyJnK.cjs} +2 -2
  22. package/dist/{PageLayout.vue_vue_type_script_setup_true_lang-D22uNeS1.cjs.map → PageLayout.vue_vue_type_script_setup_true_lang-C0YzyJnK.cjs.map} +1 -1
  23. package/dist/{PageLayout.vue_vue_type_script_setup_true_lang-kT7np2ir.js → PageLayout.vue_vue_type_script_setup_true_lang-ClzYGS8h.js} +2 -2
  24. package/dist/{PageLayout.vue_vue_type_script_setup_true_lang-kT7np2ir.js.map → PageLayout.vue_vue_type_script_setup_true_lang-ClzYGS8h.js.map} +1 -1
  25. package/dist/components/core/AccordionItem.vue.d.ts +2 -0
  26. package/dist/components/core/Dropdown.vue.d.ts +2 -0
  27. package/dist/components/core/Popover.vue.d.ts +2 -0
  28. package/dist/components/core/Tooltip.vue.d.ts +2 -0
  29. package/dist/components/core/index.cjs +3 -3
  30. package/dist/components/core/index.js +3 -3
  31. package/dist/components/core/index.test.d.ts +1 -0
  32. package/dist/components/feedback/LoadingSpinner.vue.d.ts +6 -1
  33. package/dist/components/feedback/Modal.vue.d.ts +8 -2
  34. package/dist/components/feedback/index.cjs +2 -2
  35. package/dist/components/feedback/index.js +2 -2
  36. package/dist/components/feedback/index.test.d.ts +1 -0
  37. package/dist/components/form/Checkbox.vue.d.ts +2 -0
  38. package/dist/components/form/DatePicker.vue.d.ts +2 -0
  39. package/dist/components/form/FormHelp.vue.d.ts +2 -0
  40. package/dist/components/form/Switch.vue.d.ts +2 -0
  41. package/dist/components/form/index.cjs +2 -2
  42. package/dist/components/form/index.js +2 -2
  43. package/dist/components/form/index.test.d.ts +1 -0
  44. package/dist/components/index.cjs +7 -7
  45. package/dist/components/index.js +7 -7
  46. package/dist/components/index.test.d.ts +1 -0
  47. package/dist/components/layout/index.cjs +1 -1
  48. package/dist/components/layout/index.js +1 -1
  49. package/dist/components/layout/index.test.d.ts +1 -0
  50. package/dist/components/type/index.test.d.ts +1 -0
  51. package/dist/composables/index.cjs +6 -0
  52. package/dist/composables/index.cjs.map +1 -1
  53. package/dist/composables/index.d.ts +2 -0
  54. package/dist/composables/index.js +6 -0
  55. package/dist/composables/index.js.map +1 -1
  56. package/dist/composables/index.test.d.ts +1 -0
  57. package/dist/composables/useDarkMode.test.d.ts +1 -0
  58. package/dist/composables/useDropdown.test.d.ts +1 -0
  59. package/dist/composables/useExportCSV.test.d.ts +1 -0
  60. package/dist/composables/useFocusTrap.d.ts +41 -0
  61. package/dist/composables/useFocusTrap.test.d.ts +1 -0
  62. package/dist/composables/useId.d.ts +42 -0
  63. package/dist/composables/useId.test.d.ts +1 -0
  64. package/dist/composables/useModal.d.ts +1 -1
  65. package/dist/composables/useModal.test.d.ts +1 -0
  66. package/dist/{index-DZYqrXV0.js → index-BMoLBt6A.js} +8 -8
  67. package/dist/index-BMoLBt6A.js.map +1 -0
  68. package/dist/{index-Dghdw1yo.js → index-CJwlO351.js} +18 -9
  69. package/dist/index-CJwlO351.js.map +1 -0
  70. package/dist/{index-D7HVSFi2.cjs → index-CUNU12xk.cjs} +17 -8
  71. package/dist/index-CUNU12xk.cjs.map +1 -0
  72. package/dist/{index-DjEv91o4.cjs → index-DwFvFW-3.cjs} +8 -8
  73. package/dist/index-DwFvFW-3.cjs.map +1 -0
  74. package/dist/index.cjs +14 -8
  75. package/dist/index.cjs.map +1 -1
  76. package/dist/index.js +14 -8
  77. package/dist/index.js.map +1 -1
  78. package/dist/index.test.d.ts +1 -0
  79. package/dist/types/form.d.ts +4 -0
  80. package/dist/types/index.test.d.ts +1 -0
  81. package/dist/useFocusTrap-AnlJsihM.js +120 -0
  82. package/dist/useFocusTrap-AnlJsihM.js.map +1 -0
  83. package/dist/useFocusTrap-kcxO8AeU.cjs +119 -0
  84. package/dist/useFocusTrap-kcxO8AeU.cjs.map +1 -0
  85. package/dist/useId-nxrBaIC9.cjs +25 -0
  86. package/dist/useId-nxrBaIC9.cjs.map +1 -0
  87. package/dist/useId-xeHj7rkg.js +26 -0
  88. package/dist/useId-xeHj7rkg.js.map +1 -0
  89. package/dist/useToast-Bk60GArg.cjs.map +1 -1
  90. package/dist/useToast-ina5g3mj.js.map +1 -1
  91. package/package.json +9 -8
  92. package/dist/Button.vue_vue_type_script_setup_true_lang-DKE8elsf.js.map +0 -1
  93. package/dist/Button.vue_vue_type_script_setup_true_lang-DrGM65ny.cjs.map +0 -1
  94. package/dist/Combobox.vue_vue_type_script_setup_true_lang-DhcLb6DX.js.map +0 -1
  95. package/dist/Combobox.vue_vue_type_script_setup_true_lang-FdUrjmSG.cjs.map +0 -1
  96. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-CNucAMQg.js.map +0 -1
  97. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-DXb9wQQv.cjs.map +0 -1
  98. package/dist/DarkModeToggle.vue_vue_type_script_setup_true_lang-43fxlbro.js.map +0 -1
  99. package/dist/DarkModeToggle.vue_vue_type_script_setup_true_lang-BoB48313.cjs.map +0 -1
  100. package/dist/Dropdown.vue_vue_type_script_setup_true_lang-C3pr8BwC.js.map +0 -1
  101. package/dist/Dropdown.vue_vue_type_script_setup_true_lang-DKxcVBKu.cjs.map +0 -1
  102. package/dist/index-D7HVSFi2.cjs.map +0 -1
  103. package/dist/index-DZYqrXV0.js.map +0 -1
  104. package/dist/index-Dghdw1yo.js.map +0 -1
  105. package/dist/index-DjEv91o4.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Combobox.vue_vue_type_script_setup_true_lang-DCLKWzhc.js","sources":["../src/components/form/FormLabel.vue","../src/components/form/FormHelp.vue","../src/components/form/FormInput.vue","../src/components/form/FormSelect.vue","../src/components/form/FormGroup.vue","../src/components/form/SearchInput.vue","../src/components/form/Switch.vue","../src/components/form/Slider.vue","../src/components/form/DatePicker.vue","../src/components/form/FileUpload.vue","../src/components/form/Rating.vue","../src/components/form/ColorPicker.vue","../src/components/form/RangeSlider.vue","../src/components/form/Combobox.vue"],"sourcesContent":["<script lang=\"ts\" setup>\ndefineProps<{\n error?: string | boolean\n htmlFor?: string\n}>()\n</script>\n\n<template>\n <label\n :data-error=\"!!error\"\n :for=\"htmlFor ?? ''\"\n class=\"block text-sm font-medium text-gray-700 data-[error=true]:text-red-500 dark:text-gray-300\"\n >\n <slot />\n </label>\n</template>\n","<script lang=\"ts\" setup>\r\ndefineProps<{\r\n /** ID for aria-describedby linking */\r\n id?: string\r\n error?: boolean\r\n text?: string\r\n}>()\r\n</script>\r\n\r\n<template>\r\n <p\r\n :id=\"id\"\r\n :data-error=\"error\"\r\n :role=\"error ? 'alert' : undefined\"\r\n :aria-live=\"error ? 'polite' : undefined\"\r\n class=\"mt-2 text-sm text-gray-400 peer-user-invalid:visible data-[error=true]:text-red-500 dark:text-gray-500\"\r\n >\r\n <slot>{{ text ?? '' }}</slot>\r\n </p>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport type { InputProps } from '@/types'\r\n\r\nconst props = withDefaults(defineProps<InputProps>(), {\r\n type: 'text',\r\n})\r\n\r\nconst modelValue = defineModel<string>()\r\n</script>\r\n\r\n<template>\r\n <input\r\n :id=\"props.id ?? props.name ?? ''\"\r\n v-model=\"modelValue\"\r\n :disabled=\"props.disabled\"\r\n :name=\"props.name ?? ''\"\r\n :placeholder=\"props.placeholder\"\r\n :type=\"props.type\"\r\n :required=\"props.required\"\r\n :aria-invalid=\"props.invalid || undefined\"\r\n :aria-required=\"props.required || undefined\"\r\n :aria-describedby=\"props.describedBy || undefined\"\r\n class=\"mt-1 block w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm text-gray-800 placeholder-gray-400 shadow-sm user-invalid:border-red-500 user-invalid:text-red-600 focus:border-primary focus:ring-1 focus:ring-primary focus:outline-none focus:user-invalid:border-red-500 focus:user-invalid:ring-red-500 disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none dark:border-gray-700 dark:bg-gray-900 dark:text-gray-200 dark:placeholder-gray-500 dark:focus:border-primary dark:focus:ring-primary dark:disabled:border-gray-800 dark:disabled:bg-gray-950 dark:disabled:text-gray-500\"\r\n v-bind=\"$attrs\"\r\n >\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { computed, ref, watch, nextTick } from 'vue'\r\nimport { Icon } from '@iconify/vue'\r\nimport type { SelectProps, SelectOption } from '@/types'\r\nimport { useDropdown } from '@/composables/useDropdown'\r\nimport { useId } from '@/composables/useId'\r\n\r\nconst props = withDefaults(\r\n defineProps<\r\n SelectProps & {\r\n /** Use teleport to body to avoid overflow clipping */\r\n teleport?: boolean\r\n /** Show search input in dropdown */\r\n searchable?: boolean\r\n /** Text shown when no results match search */\r\n noResultsText?: string\r\n /** Custom class for the trigger button */\r\n triggerClass?: string\r\n }\r\n >(),\r\n {\r\n teleport: true,\r\n searchable: false,\r\n noResultsText: 'No results found',\r\n },\r\n)\r\n\r\n// Generate unique IDs for accessibility\r\nconst { id: generatedId, related } = useId({ prefix: 'select', id: props.id })\r\nconst triggerId = computed(() => props.id ?? props.name ?? generatedId.value)\r\nconst listboxId = computed(() => related('listbox'))\r\n\r\nconst modelValue = defineModel<string | number | boolean | null>()\r\n\r\nconst searchQuery = ref('')\r\nconst triggerRef = ref<HTMLElement>()\r\nconst dropdownRef = ref<HTMLElement>()\r\nconst searchInputRef = ref<HTMLInputElement>()\r\n\r\nconst {\r\n isOpen,\r\n highlightedIndex,\r\n dropdownStyle,\r\n open: openDropdown,\r\n close,\r\n handleKeydown: baseHandleKeydown,\r\n scrollToHighlighted,\r\n} = useDropdown(triggerRef, dropdownRef, {\r\n teleport: props.teleport,\r\n gap: 4,\r\n onClose: () => {\r\n searchQuery.value = ''\r\n },\r\n})\r\n\r\nconst visibleOptions = computed(() => {\r\n return (props.options ?? []).filter((opt) => !opt.hidden)\r\n})\r\n\r\nconst filteredOptions = computed(() => {\r\n if (!props.searchable || !searchQuery.value) {\r\n return visibleOptions.value\r\n }\r\n const query = searchQuery.value.toLowerCase()\r\n return visibleOptions.value.filter((opt) =>\r\n opt.label.toLowerCase().includes(query) ||\r\n String(opt.value).toLowerCase().includes(query)\r\n )\r\n})\r\n\r\nconst selectedOption = computed(() => {\r\n return visibleOptions.value.find((opt) => opt.value === modelValue.value)\r\n})\r\n\r\nconst displayValue = computed(() => {\r\n if (selectedOption.value) {\r\n return selectedOption.value.label\r\n }\r\n return props.placeholder || 'Select...'\r\n})\r\n\r\nconst open = () => {\r\n if (props.disabled) return\r\n searchQuery.value = ''\r\n highlightedIndex.value = filteredOptions.value.findIndex(\r\n (opt) => opt.value === modelValue.value\r\n )\r\n openDropdown()\r\n nextTick(() => {\r\n if (props.searchable) {\r\n searchInputRef.value?.focus()\r\n }\r\n })\r\n}\r\n\r\nconst toggle = () => {\r\n if (isOpen.value) {\r\n close()\r\n } else {\r\n open()\r\n }\r\n}\r\n\r\nconst selectOption = (option: SelectOption) => {\r\n modelValue.value = option.value\r\n close()\r\n}\r\n\r\nconst handleKeydown = (event: KeyboardEvent) => {\r\n baseHandleKeydown(event, {\r\n itemCount: filteredOptions.value.length,\r\n onSelect: (index) => {\r\n if (filteredOptions.value[index]) {\r\n selectOption(filteredOptions.value[index])\r\n }\r\n },\r\n onOpen: open,\r\n handleOpenKeys: true,\r\n })\r\n if (isOpen.value) {\r\n scrollToHighlighted(dropdownRef.value ?? null)\r\n }\r\n}\r\n\r\nwatch(searchQuery, () => {\r\n highlightedIndex.value = 0\r\n})\r\n\r\nconst triggerClasses = computed(() => {\r\n const base = 'flex w-full items-center justify-between gap-2 rounded-md border px-3 py-2 text-sm text-left transition'\r\n const state = props.disabled\r\n ? 'cursor-not-allowed border-gray-200 bg-gray-50 text-gray-500 dark:border-gray-800 dark:bg-gray-950 dark:text-gray-500'\r\n : isOpen.value\r\n ? 'border-primary ring-2 ring-primary/20 bg-white dark:bg-gray-900'\r\n : 'border-gray-300 bg-white hover:border-gray-400 dark:border-gray-700 dark:bg-gray-900 dark:hover:border-gray-600'\r\n const text = selectedOption.value\r\n ? 'text-gray-800 dark:text-gray-200'\r\n : 'text-gray-400 dark:text-gray-500'\r\n return [base, state, text, props.triggerClass]\r\n})\r\n</script>\r\n\r\n<template>\r\n <div class=\"relative\">\r\n <!-- Trigger -->\r\n <button\r\n :id=\"triggerId\"\r\n ref=\"triggerRef\"\r\n type=\"button\"\r\n :disabled=\"disabled\"\r\n :class=\"triggerClasses\"\r\n :aria-haspopup=\"'listbox'\"\r\n :aria-expanded=\"isOpen\"\r\n :aria-controls=\"listboxId\"\r\n :aria-invalid=\"invalid || undefined\"\r\n :aria-describedby=\"describedBy || undefined\"\r\n @click=\"toggle\"\r\n @keydown=\"handleKeydown\"\r\n >\r\n <slot\r\n name=\"selected\"\r\n :option=\"selectedOption\"\r\n :placeholder=\"placeholder\"\r\n >\r\n <span class=\"flex-1 truncate\">{{ displayValue }}</span>\r\n </slot>\r\n <Icon\r\n icon=\"lucide:chevron-down\"\r\n :class=\"['size-4 shrink-0 text-gray-400 transition-transform', isOpen && 'rotate-180']\"\r\n aria-hidden=\"true\"\r\n />\r\n </button>\r\n\r\n <!-- Dropdown -->\r\n <Teleport\r\n to=\"body\"\r\n :disabled=\"!teleport\"\r\n >\r\n <Transition\r\n enter-active-class=\"transition duration-100 ease-out\"\r\n enter-from-class=\"opacity-0 scale-95\"\r\n enter-to-class=\"opacity-100 scale-100\"\r\n leave-active-class=\"transition duration-75 ease-in\"\r\n leave-from-class=\"opacity-100 scale-100\"\r\n leave-to-class=\"opacity-0 scale-95\"\r\n >\r\n <div\r\n v-if=\"isOpen\"\r\n :id=\"listboxId\"\r\n ref=\"dropdownRef\"\r\n role=\"listbox\"\r\n :aria-label=\"placeholder || 'Select an option'\"\r\n :style=\"dropdownStyle\"\r\n :class=\"[\r\n 'z-[9999] max-h-60 overflow-auto rounded-lg border border-gray-200 bg-white shadow-lg dark:border-gray-700 dark:bg-gray-800',\r\n !teleport && 'absolute mt-1 w-full',\r\n ]\"\r\n >\r\n <!-- Search input -->\r\n <div\r\n v-if=\"searchable\"\r\n class=\"sticky top-0 border-b border-gray-200 bg-white p-2 dark:border-gray-700 dark:bg-gray-800\"\r\n >\r\n <div class=\"flex items-center gap-2 rounded-md border border-gray-300 bg-gray-50 px-2 py-1.5 dark:border-gray-600 dark:bg-gray-900\">\r\n <Icon\r\n icon=\"lucide:search\"\r\n class=\"size-4 text-gray-400\"\r\n aria-hidden=\"true\"\r\n />\r\n <input\r\n ref=\"searchInputRef\"\r\n v-model=\"searchQuery\"\r\n type=\"text\"\r\n class=\"flex-1 bg-transparent text-sm outline-none dark:text-white\"\r\n placeholder=\"Search...\"\r\n aria-label=\"Search options\"\r\n @keydown=\"handleKeydown\"\r\n >\r\n </div>\r\n </div>\r\n\r\n <!-- Empty state -->\r\n <div\r\n v-if=\"filteredOptions.length === 0\"\r\n class=\"px-4 py-3 text-sm text-gray-500 dark:text-gray-400\"\r\n role=\"status\"\r\n >\r\n {{ noResultsText }}\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"py-1\">\r\n <button\r\n v-for=\"(option, index) in filteredOptions\"\r\n :key=\"String(option.value)\"\r\n type=\"button\"\r\n role=\"option\"\r\n :aria-selected=\"modelValue === option.value\"\r\n :data-index=\"index\"\r\n :class=\"[\r\n 'flex w-full items-center gap-2 px-3 py-2 text-left text-sm transition-colors',\r\n highlightedIndex === index && 'bg-gray-100 dark:bg-gray-700',\r\n modelValue === option.value && 'bg-primary/10 text-primary',\r\n modelValue !== option.value && 'text-gray-700 dark:text-gray-200',\r\n ]\"\r\n @click=\"selectOption(option)\"\r\n @mouseenter=\"highlightedIndex = index\"\r\n >\r\n <slot\r\n name=\"option\"\r\n :option=\"option\"\r\n :selected=\"modelValue === option.value\"\r\n :index=\"index\"\r\n >\r\n <Icon\r\n v-if=\"modelValue === option.value\"\r\n icon=\"lucide:check\"\r\n class=\"size-4 shrink-0 text-primary\"\r\n aria-hidden=\"true\"\r\n />\r\n <span\r\n v-else\r\n class=\"size-4 shrink-0\"\r\n aria-hidden=\"true\"\r\n />\r\n <span class=\"flex-1\">{{ option.label }}</span>\r\n </slot>\r\n </button>\r\n </div>\r\n </div>\r\n </Transition>\r\n </Teleport>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { computed } from 'vue'\r\nimport type { FormGroupProps } from '@/types'\r\nimport { useId } from '@/composables/useId'\r\nimport FormLabel from './FormLabel.vue'\r\nimport FormInput from './FormInput.vue'\r\nimport FormSelect from './FormSelect.vue'\r\nimport FormHelp from './FormHelp.vue'\r\n\r\nconst props = withDefaults(defineProps<FormGroupProps>(), {\r\n cols: 6,\r\n})\r\n\r\nconst modelValue = defineModel()\r\n\r\n// Generate unique IDs for accessibility\r\nconst { id: generatedId, related } = useId({ prefix: 'field', id: props.id })\r\nconst inputId = computed(() => props.id ?? props.name ?? generatedId.value)\r\nconst helpId = computed(() => related('help'))\r\n\r\nconst computedCols = computed(() => `span ${props.cols} / span ${props.cols}`)\r\n\r\nconst isSelect = computed(() => props.select === true)\r\n\r\n// Determine if we should link to error message\r\nconst hasError = computed(() => props.error && typeof props.error === 'string')\r\n</script>\r\n\r\n<template>\r\n <div\r\n :style=\"{ gridColumn: computedCols }\"\r\n :hidden=\"hidden\"\r\n >\r\n <slot>\r\n <slot name=\"label\">\r\n <FormLabel\r\n v-if=\"label\"\r\n :html-for=\"inputId\"\r\n :error=\"error\"\r\n >\r\n {{ label }}\r\n </FormLabel>\r\n </slot>\r\n\r\n <slot name=\"input\">\r\n <FormSelect\r\n v-if=\"isSelect\"\r\n v-model=\"modelValue\"\r\n v-bind=\"{ ...$attrs, ...$props }\"\r\n :id=\"inputId\"\r\n :invalid=\"Boolean(error)\"\r\n :described-by=\"hasError ? helpId : undefined\"\r\n />\r\n <FormInput\r\n v-else\r\n v-model=\"modelValue\"\r\n v-bind=\"{ ...$attrs, ...$props }\"\r\n :id=\"inputId\"\r\n :invalid=\"Boolean(error)\"\r\n :described-by=\"hasError ? helpId : undefined\"\r\n />\r\n </slot>\r\n\r\n <FormHelp\r\n v-if=\"hasError\"\r\n :id=\"helpId\"\r\n :error=\"true\"\r\n >\r\n {{ error }}\r\n </FormHelp>\r\n </slot>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\nimport { Icon } from '@iconify/vue'\n\nconst {\n placeholder = 'Search...',\n icon = 'lucide:search',\n disabled = false,\n} = defineProps<{\n modelValue?: string\n placeholder?: string\n icon?: string\n disabled?: boolean\n}>()\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string]\n}>()\n\nconst handleInput = (event: Event) => {\n const target = event.target as HTMLInputElement\n emit('update:modelValue', target.value)\n}\n</script>\n\n<template>\n <div class=\"relative\">\n <Icon\n :icon=\"icon\"\n class=\"absolute top-1/2 left-3 h-5 w-5 -translate-y-1/2 text-gray-400\"\n />\n <input\n :disabled=\"disabled\"\n :placeholder=\"placeholder\"\n :value=\"modelValue\"\n class=\"focus:border-primary focus:ring-primary w-full rounded-lg border border-gray-300 bg-white py-2 pr-4 pl-10 text-gray-900 placeholder-gray-400 transition-colors disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-500\"\n type=\"text\"\n @input=\"handleInput\"\n >\n </div>\n</template>\n","<script lang=\"ts\" setup>\nimport { computed } from 'vue'\nimport { useId } from '@/composables/useId'\n\nconst props = withDefaults(\n defineProps<{\n /** v-model value */\n modelValue?: boolean\n /** Label text */\n label?: string\n /** Description text */\n description?: string\n /** Disabled state */\n disabled?: boolean\n /** Size variant */\n size?: 'sm' | 'md' | 'lg'\n /** Custom ID for the switch */\n id?: string\n }>(),\n {\n modelValue: false,\n size: 'md',\n },\n)\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: boolean]\n}>()\n\n// Generate unique IDs for accessibility\nconst { id: generatedId, related } = useId({ prefix: 'switch', id: props.id })\nconst switchId = computed(() => props.id ?? generatedId.value)\nconst labelId = computed(() => related('label'))\nconst descriptionId = computed(() => related('description'))\n\nconst toggle = () => {\n if (props.disabled) return\n emit('update:modelValue', !props.modelValue)\n}\n\nconst switchSizes = {\n sm: 'h-5 w-9',\n md: 'h-6 w-11',\n lg: 'h-7 w-14',\n}\n\nconst dotSizes = {\n sm: 'size-3',\n md: 'size-4',\n lg: 'size-5',\n}\n\nconst translateSizes = {\n sm: 'translate-x-5',\n md: 'translate-x-6',\n lg: 'translate-x-8',\n}\n</script>\n\n<template>\n <label\n class=\"inline-flex items-start gap-3\"\n :class=\"disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'\"\n >\n <button\n :id=\"switchId\"\n type=\"button\"\n role=\"switch\"\n :aria-checked=\"modelValue\"\n :aria-labelledby=\"label ? labelId : undefined\"\n :aria-describedby=\"description ? descriptionId : undefined\"\n :disabled=\"disabled\"\n :class=\"[\n 'relative inline-flex shrink-0 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2',\n switchSizes[size],\n modelValue ? 'bg-primary' : 'bg-gray-300 dark:bg-gray-600',\n ]\"\n @click=\"toggle\"\n >\n <span\n :class=\"[\n 'inline-block transform rounded-full bg-white shadow-sm transition-transform',\n dotSizes[size],\n modelValue ? translateSizes[size] : 'translate-x-1',\n ]\"\n aria-hidden=\"true\"\n />\n </button>\n <div\n v-if=\"label || description\"\n class=\"flex flex-col\"\n >\n <span\n v-if=\"label\"\n :id=\"labelId\"\n class=\"text-sm font-medium text-gray-900 dark:text-white\"\n >\n {{ label }}\n </span>\n <span\n v-if=\"description\"\n :id=\"descriptionId\"\n class=\"text-sm text-gray-500 dark:text-gray-400\"\n >\n {{ description }}\n </span>\n </div>\n </label>\n</template>\n","<script lang=\"ts\" setup>\r\nimport { computed } from 'vue'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Minimum value */\r\n min?: number\r\n /** Maximum value */\r\n max?: number\r\n /** Step increment */\r\n step?: number\r\n /** Disabled state */\r\n disabled?: boolean\r\n /** Show value label */\r\n showValue?: boolean\r\n /** Format value for display */\r\n formatValue?: (value: number) => string\r\n }>(),\r\n {\r\n min: 0,\r\n max: 100,\r\n step: 1,\r\n disabled: false,\r\n showValue: false,\r\n },\r\n)\r\n\r\nconst modelValue = defineModel<number>({ default: 0 })\r\n\r\nconst percentage = computed(() => {\r\n return ((modelValue.value - props.min) / (props.max - props.min)) * 100\r\n})\r\n\r\nconst displayValue = computed(() => {\r\n if (props.formatValue) {\r\n return props.formatValue(modelValue.value)\r\n }\r\n return modelValue.value.toString()\r\n})\r\n\r\nconst handleInput = (event: Event) => {\r\n const target = event.target as HTMLInputElement\r\n modelValue.value = Number(target.value)\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"w-full\">\r\n <div\n v-if=\"showValue\"\n class=\"mb-2 flex justify-between text-sm\"\n >\r\n <span class=\"text-gray-600 dark:text-gray-400\">{{ min }}</span>\r\n <span class=\"font-medium text-gray-900 dark:text-white\">{{ displayValue }}</span>\r\n <span class=\"text-gray-600 dark:text-gray-400\">{{ max }}</span>\r\n </div>\r\n <div class=\"relative\">\r\n <input\r\n type=\"range\"\r\n :value=\"modelValue\"\r\n :min=\"min\"\r\n :max=\"max\"\r\n :step=\"step\"\r\n :disabled=\"disabled\"\r\n class=\"slider-input w-full cursor-pointer appearance-none bg-transparent disabled:cursor-not-allowed disabled:opacity-50\"\r\n @input=\"handleInput\"\r\n >\r\n <div class=\"pointer-events-none absolute inset-y-0 left-0 flex items-center\">\r\n <div\r\n class=\"h-2 rounded-full bg-primary\"\r\n :style=\"{ width: `${percentage}%` }\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.slider-input {\r\n height: 0.5rem;\r\n}\r\n\r\n.slider-input::-webkit-slider-runnable-track {\r\n height: 0.5rem;\r\n border-radius: 9999px;\r\n background-color: #e5e7eb;\r\n}\r\n\r\n.dark .slider-input::-webkit-slider-runnable-track {\r\n background-color: #374151;\r\n}\r\n\r\n.slider-input::-webkit-slider-thumb {\r\n -webkit-appearance: none;\r\n appearance: none;\r\n width: 1.25rem;\r\n height: 1.25rem;\r\n border-radius: 9999px;\r\n background-color: var(--color-primary, #3b82f6);\r\n border: 2px solid white;\r\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\r\n margin-top: -0.375rem;\r\n cursor: pointer;\r\n}\r\n\r\n.slider-input::-moz-range-track {\r\n height: 0.5rem;\r\n border-radius: 9999px;\r\n background-color: #e5e7eb;\r\n}\r\n\r\n.dark .slider-input::-moz-range-track {\r\n background-color: #374151;\r\n}\r\n\r\n.slider-input::-moz-range-thumb {\r\n width: 1.25rem;\r\n height: 1.25rem;\r\n border-radius: 9999px;\r\n background-color: var(--color-primary, #3b82f6);\r\n border: 2px solid white;\r\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\r\n cursor: pointer;\r\n}\r\n\r\n.slider-input:focus::-webkit-slider-thumb {\r\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.3);\r\n}\r\n\r\n.slider-input:focus::-moz-range-thumb {\r\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.3);\r\n}\r\n</style>\r\n","<script lang=\"ts\" setup>\r\nimport { ref, computed } from 'vue'\r\nimport { Icon } from '@iconify/vue'\r\nimport { useDropdown } from '@/composables/useDropdown'\r\nimport { useId } from '@/composables/useId'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Placeholder text */\r\n placeholder?: string\r\n /** Date format for display */\r\n format?: string\r\n /** Locale for formatting */\r\n locale?: string\r\n /** Disabled state */\r\n disabled?: boolean\r\n /** Minimum selectable date */\r\n minDate?: Date\r\n /** Maximum selectable date */\r\n maxDate?: Date\r\n /** Use teleport */\r\n teleport?: boolean\r\n /** Custom ID for accessibility */\r\n id?: string\r\n }>(),\r\n {\r\n placeholder: 'Select date',\r\n format: 'short',\r\n locale: 'en-US',\r\n disabled: false,\r\n teleport: true,\r\n },\r\n)\r\n\r\n// Generate unique IDs for accessibility\r\nconst { related } = useId({ prefix: 'datepicker', id: props.id })\r\nconst triggerId = computed(() => related('trigger'))\r\nconst calendarId = computed(() => related('calendar'))\r\nconst gridId = computed(() => related('grid'))\r\n\r\nconst modelValue = defineModel<Date | null>({ default: null })\r\n\r\nconst triggerRef = ref<HTMLElement>()\r\nconst calendarRef = ref<HTMLElement>()\r\n\r\nconst { isOpen, dropdownStyle, toggle, close } = useDropdown(triggerRef, calendarRef, {\r\n teleport: props.teleport,\r\n gap: 4,\r\n})\r\n\r\nconst currentMonth = ref(modelValue.value ? new Date(modelValue.value) : new Date())\r\n\r\nconst weekDays = computed(() => {\r\n const days = []\r\n const formatter = new Intl.DateTimeFormat(props.locale, { weekday: 'short' })\r\n for (let i = 0; i < 7; i++) {\r\n const date = new Date(2024, 0, i) // Jan 2024 starts on Monday\r\n days.push(formatter.format(date))\r\n }\r\n return days\r\n})\r\n\r\nconst monthYear = computed(() => {\r\n const formatter = new Intl.DateTimeFormat(props.locale, { month: 'long', year: 'numeric' })\r\n return formatter.format(currentMonth.value)\r\n})\r\n\r\nconst calendarDays = computed(() => {\r\n const year = currentMonth.value.getFullYear()\r\n const month = currentMonth.value.getMonth()\r\n\r\n const firstDay = new Date(year, month, 1)\r\n const lastDay = new Date(year, month + 1, 0)\r\n\r\n const days: Array<{ date: Date; isCurrentMonth: boolean; isToday: boolean; isSelected: boolean; isDisabled: boolean }> = []\r\n\r\n // Get the day of week for the first day (0 = Sunday)\r\n let startDay = firstDay.getDay()\r\n // Adjust for Monday start\r\n startDay = startDay === 0 ? 6 : startDay - 1\r\n\r\n // Previous month days\r\n for (let i = startDay - 1; i >= 0; i--) {\r\n const date = new Date(year, month, -i)\r\n days.push({\r\n date,\r\n isCurrentMonth: false,\r\n isToday: false,\r\n isSelected: false,\r\n isDisabled: isDateDisabled(date),\r\n })\r\n }\r\n\r\n // Current month days\r\n const today = new Date()\r\n for (let i = 1; i <= lastDay.getDate(); i++) {\r\n const date = new Date(year, month, i)\r\n days.push({\r\n date,\r\n isCurrentMonth: true,\r\n isToday: isSameDay(date, today),\r\n isSelected: modelValue.value ? isSameDay(date, modelValue.value) : false,\r\n isDisabled: isDateDisabled(date),\r\n })\r\n }\r\n\r\n // Next month days\r\n const remainingDays = 42 - days.length\r\n for (let i = 1; i <= remainingDays; i++) {\r\n const date = new Date(year, month + 1, i)\r\n days.push({\r\n date,\r\n isCurrentMonth: false,\r\n isToday: false,\r\n isSelected: false,\r\n isDisabled: isDateDisabled(date),\r\n })\r\n }\r\n\r\n return days\r\n})\r\n\r\nconst displayValue = computed(() => {\r\n if (!modelValue.value) return ''\r\n const formatter = new Intl.DateTimeFormat(props.locale, {\r\n dateStyle: props.format as 'short' | 'medium' | 'long' | 'full',\r\n })\r\n return formatter.format(modelValue.value)\r\n})\r\n\r\nconst isSameDay = (a: Date, b: Date) => {\r\n return (\r\n a.getFullYear() === b.getFullYear() &&\r\n a.getMonth() === b.getMonth() &&\r\n a.getDate() === b.getDate()\r\n )\r\n}\r\n\r\nconst isDateDisabled = (date: Date) => {\r\n if (props.minDate && date < props.minDate) return true\r\n if (props.maxDate && date > props.maxDate) return true\r\n return false\r\n}\r\n\r\nconst prevMonth = () => {\r\n currentMonth.value = new Date(currentMonth.value.getFullYear(), currentMonth.value.getMonth() - 1, 1)\r\n}\r\n\r\nconst nextMonth = () => {\r\n currentMonth.value = new Date(currentMonth.value.getFullYear(), currentMonth.value.getMonth() + 1, 1)\r\n}\r\n\r\nconst selectDate = (day: typeof calendarDays.value[0]) => {\r\n if (day.isDisabled) return\r\n modelValue.value = day.date\r\n close()\r\n}\r\n\r\nconst clear = () => {\r\n modelValue.value = null\r\n}\r\n\r\n// Generate accessible label for a date\r\nconst getDateLabel = (date: Date): string => {\r\n const formatter = new Intl.DateTimeFormat(props.locale, {\r\n weekday: 'long',\r\n year: 'numeric',\r\n month: 'long',\r\n day: 'numeric',\r\n })\r\n return formatter.format(date)\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"relative\">\r\n <button\r\n :id=\"triggerId\"\r\n ref=\"triggerRef\"\r\n type=\"button\"\r\n :disabled=\"disabled\"\r\n :aria-expanded=\"isOpen\"\r\n :aria-haspopup=\"'dialog'\"\r\n :aria-controls=\"calendarId\"\r\n :class=\"[\r\n 'flex w-full items-center justify-between gap-2 rounded-md border px-3 py-2 text-sm text-left transition',\r\n disabled\r\n ? 'cursor-not-allowed border-gray-200 bg-gray-50 text-gray-500 dark:border-gray-800 dark:bg-gray-950'\r\n : isOpen\r\n ? 'border-primary ring-2 ring-primary/20 bg-white dark:bg-gray-900'\r\n : 'border-gray-300 bg-white hover:border-gray-400 dark:border-gray-700 dark:bg-gray-900',\r\n modelValue ? 'text-gray-900 dark:text-white' : 'text-gray-400 dark:text-gray-500',\r\n ]\"\r\n @click=\"toggle\"\r\n >\r\n <span class=\"flex-1 truncate\">{{ displayValue || placeholder }}</span>\r\n <div class=\"flex items-center gap-1\">\r\n <button\r\n v-if=\"modelValue\"\r\n type=\"button\"\r\n class=\"rounded p-0.5 hover:bg-gray-100 dark:hover:bg-gray-800\"\r\n aria-label=\"Clear date\"\r\n @click.stop=\"clear\"\r\n >\r\n <Icon\r\n icon=\"lucide:x\"\r\n class=\"size-4 text-gray-400\"\r\n aria-hidden=\"true\"\r\n />\r\n </button>\r\n <Icon\r\n icon=\"lucide:calendar\"\r\n class=\"size-4 text-gray-400\"\r\n aria-hidden=\"true\"\r\n />\r\n </div>\r\n </button>\r\n\r\n <Teleport\r\n to=\"body\"\r\n :disabled=\"!teleport\"\r\n >\r\n <Transition\r\n enter-active-class=\"transition duration-100 ease-out\"\r\n enter-from-class=\"opacity-0 scale-95\"\r\n enter-to-class=\"opacity-100 scale-100\"\r\n leave-active-class=\"transition duration-75 ease-in\"\r\n leave-from-class=\"opacity-100 scale-100\"\r\n leave-to-class=\"opacity-0 scale-95\"\r\n >\r\n <div\r\n v-if=\"isOpen\"\r\n :id=\"calendarId\"\r\n ref=\"calendarRef\"\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n :aria-label=\"`Choose date, ${monthYear}`\"\r\n :style=\"dropdownStyle\"\r\n class=\"z-[9999] w-72 rounded-lg border border-gray-200 bg-white p-4 shadow-lg dark:border-gray-700 dark:bg-gray-800\"\r\n >\r\n <!-- Header -->\r\n <div class=\"mb-4 flex items-center justify-between\">\r\n <button\r\n type=\"button\"\r\n class=\"rounded p-1 hover:bg-gray-100 dark:hover:bg-gray-700\"\r\n aria-label=\"Previous month\"\r\n @click=\"prevMonth\"\r\n >\r\n <Icon\r\n icon=\"lucide:chevron-left\"\r\n class=\"size-5 text-gray-600 dark:text-gray-400\"\r\n aria-hidden=\"true\"\r\n />\r\n </button>\r\n <span\r\n class=\"font-medium text-gray-900 dark:text-white\"\r\n aria-live=\"polite\"\r\n aria-atomic=\"true\"\r\n >\r\n {{ monthYear }}\r\n </span>\r\n <button\r\n type=\"button\"\r\n class=\"rounded p-1 hover:bg-gray-100 dark:hover:bg-gray-700\"\r\n aria-label=\"Next month\"\r\n @click=\"nextMonth\"\r\n >\r\n <Icon\r\n icon=\"lucide:chevron-right\"\r\n class=\"size-5 text-gray-600 dark:text-gray-400\"\r\n aria-hidden=\"true\"\r\n />\r\n </button>\r\n </div>\r\n\r\n <!-- Week days -->\r\n <div\r\n class=\"mb-2 grid grid-cols-7 gap-1\"\r\n role=\"row\"\r\n >\r\n <div\r\n v-for=\"day in weekDays\"\r\n :key=\"day\"\r\n class=\"text-center text-xs font-medium text-gray-500 dark:text-gray-400\"\r\n role=\"columnheader\"\r\n :abbr=\"day\"\r\n >\r\n {{ day }}\r\n </div>\r\n </div>\r\n\r\n <!-- Days grid -->\r\n <div\r\n :id=\"gridId\"\r\n class=\"grid grid-cols-7 gap-1\"\r\n role=\"grid\"\r\n :aria-label=\"monthYear\"\r\n >\r\n <button\r\n v-for=\"(day, index) in calendarDays\"\r\n :key=\"index\"\r\n type=\"button\"\r\n role=\"gridcell\"\r\n :aria-label=\"getDateLabel(day.date)\"\r\n :aria-selected=\"day.isSelected\"\r\n :aria-disabled=\"day.isDisabled || undefined\"\r\n :disabled=\"day.isDisabled\"\r\n :class=\"[\r\n 'h-8 w-8 rounded text-sm transition',\r\n day.isDisabled && 'cursor-not-allowed opacity-30',\r\n !day.isCurrentMonth && 'text-gray-400 dark:text-gray-600',\r\n day.isCurrentMonth && !day.isSelected && !day.isToday && 'text-gray-900 hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700',\r\n day.isToday && !day.isSelected && 'bg-gray-100 font-semibold text-gray-900 dark:bg-gray-700 dark:text-white',\r\n day.isSelected && 'bg-primary text-white font-semibold',\r\n ]\"\r\n @click=\"selectDate(day)\"\r\n >\r\n {{ day.date.getDate() }}\r\n </button>\r\n </div>\r\n\r\n <!-- Today button -->\r\n <div class=\"mt-4 border-t border-gray-200 pt-3 dark:border-gray-700\">\r\n <button\r\n type=\"button\"\r\n class=\"w-full rounded py-1.5 text-sm font-medium text-primary hover:bg-primary/10\"\r\n @click=\"selectDate({ date: new Date(), isCurrentMonth: true, isToday: true, isSelected: false, isDisabled: false })\"\r\n >\r\n Today\r\n </button>\r\n </div>\r\n </div>\r\n </Transition>\r\n </Teleport>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { ref, computed } from 'vue'\r\nimport { Icon } from '@iconify/vue'\r\n\r\nexport interface UploadedFile {\r\n file: File\r\n id: string\r\n progress: number\r\n status: 'pending' | 'uploading' | 'success' | 'error'\r\n error?: string\r\n}\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Accepted file types (e.g., 'image/*,.pdf') */\r\n accept?: string\r\n /** Allow multiple files */\r\n multiple?: boolean\r\n /** Maximum file size in bytes */\r\n maxSize?: number\r\n /** Maximum number of files */\r\n maxFiles?: number\r\n /** Disable the upload */\r\n disabled?: boolean\r\n /** Custom label text */\r\n label?: string\r\n /** Custom description text */\r\n description?: string\r\n }>(),\r\n {\r\n multiple: false,\r\n disabled: false,\r\n label: 'Drop files here or click to upload',\r\n description: '',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n 'files-selected': [files: File[]]\r\n 'file-removed': [file: File]\r\n 'error': [message: string]\r\n}>()\r\n\r\nconst isDragging = ref(false)\r\nconst files = ref<UploadedFile[]>([])\r\nconst inputRef = ref<HTMLInputElement>()\r\n\r\nconst formatSize = (bytes: number): string => {\r\n if (bytes === 0) return '0 B'\r\n const k = 1024\r\n const sizes = ['B', 'KB', 'MB', 'GB']\r\n const i = Math.floor(Math.log(bytes) / Math.log(k))\r\n return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]\r\n}\r\n\r\nconst validateFile = (file: File): string | null => {\r\n if (props.maxSize && file.size > props.maxSize) {\r\n return `File too large. Max size: ${formatSize(props.maxSize)}`\r\n }\r\n if (props.accept) {\r\n const acceptedTypes = props.accept.split(',').map((t) => t.trim())\r\n const fileType = file.type\r\n const fileExt = '.' + file.name.split('.').pop()?.toLowerCase()\r\n\r\n const isAccepted = acceptedTypes.some((type) => {\r\n if (type.startsWith('.')) {\r\n return fileExt === type.toLowerCase()\r\n }\r\n if (type.endsWith('/*')) {\r\n return fileType.startsWith(type.replace('/*', '/'))\r\n }\r\n return fileType === type\r\n })\r\n\r\n if (!isAccepted) {\r\n return `File type not accepted`\r\n }\r\n }\r\n return null\r\n}\r\n\r\nconst addFiles = (newFiles: FileList | File[]) => {\r\n const fileArray = Array.from(newFiles)\r\n const validFiles: File[] = []\r\n\r\n for (const file of fileArray) {\r\n if (props.maxFiles && files.value.length + validFiles.length >= props.maxFiles) {\r\n emit('error', `Maximum ${props.maxFiles} files allowed`)\r\n break\r\n }\r\n\r\n const error = validateFile(file)\r\n if (error) {\r\n emit('error', `${file.name}: ${error}`)\r\n continue\r\n }\r\n\r\n validFiles.push(file)\r\n files.value.push({\r\n file,\r\n id: Math.random().toString(36).substring(2),\r\n progress: 0,\r\n status: 'pending',\r\n })\r\n }\r\n\r\n if (validFiles.length > 0) {\r\n emit('files-selected', validFiles)\r\n }\r\n}\r\n\r\nconst removeFile = (id: string) => {\r\n const index = files.value.findIndex((f) => f.id === id)\r\n if (index > -1) {\r\n const removed = files.value.splice(index, 1)[0]\r\n emit('file-removed', removed.file)\r\n }\r\n}\r\n\r\nconst handleDrop = (e: DragEvent) => {\r\n isDragging.value = false\r\n if (props.disabled || !e.dataTransfer?.files) return\r\n addFiles(e.dataTransfer.files)\r\n}\r\n\r\nconst handleDragOver = (e: DragEvent) => {\r\n e.preventDefault()\r\n if (!props.disabled) {\r\n isDragging.value = true\r\n }\r\n}\r\n\r\nconst handleDragLeave = () => {\r\n isDragging.value = false\r\n}\r\n\r\nconst handleClick = () => {\r\n if (!props.disabled) {\r\n inputRef.value?.click()\r\n }\r\n}\r\n\r\nconst handleInputChange = (e: Event) => {\r\n const target = e.target as HTMLInputElement\r\n if (target.files) {\r\n addFiles(target.files)\r\n target.value = ''\r\n }\r\n}\r\n\r\nconst dropzoneClasses = computed(() => {\r\n const base =\r\n 'relative border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors'\r\n if (props.disabled) {\r\n return `${base} border-gray-200 bg-gray-50 cursor-not-allowed dark:border-gray-700 dark:bg-gray-800`\r\n }\r\n if (isDragging.value) {\r\n return `${base} border-primary-500 bg-primary-50 dark:bg-primary-900/20`\r\n }\r\n return `${base} border-gray-300 hover:border-primary-400 hover:bg-gray-50 dark:border-gray-600 dark:hover:border-primary-500 dark:hover:bg-gray-800`\r\n})\r\n\r\nconst getFileIcon = (file: File): string => {\r\n if (file.type.startsWith('image/')) return 'heroicons:photo'\r\n if (file.type.startsWith('video/')) return 'heroicons:video-camera'\r\n if (file.type.startsWith('audio/')) return 'heroicons:musical-note'\r\n if (file.type.includes('pdf')) return 'heroicons:document-text'\r\n if (file.type.includes('zip') || file.type.includes('rar')) return 'heroicons:archive-box'\r\n return 'heroicons:document'\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"space-y-4\">\r\n <!-- Dropzone -->\r\n <div\r\n :class=\"dropzoneClasses\"\r\n @drop.prevent=\"handleDrop\"\r\n @dragover=\"handleDragOver\"\r\n @dragleave=\"handleDragLeave\"\r\n @click=\"handleClick\"\r\n >\r\n <input\r\n ref=\"inputRef\"\r\n type=\"file\"\r\n class=\"hidden\"\r\n :accept=\"accept\"\r\n :multiple=\"multiple\"\r\n :disabled=\"disabled\"\r\n @change=\"handleInputChange\"\r\n />\r\n\r\n <div class=\"space-y-2\">\r\n <Icon\r\n icon=\"heroicons:cloud-arrow-up\"\r\n class=\"w-12 h-12 mx-auto text-gray-400\"\r\n :class=\"{ 'text-primary-500': isDragging }\"\r\n />\r\n <p class=\"text-sm font-medium text-gray-700 dark:text-gray-300\">\r\n {{ label }}\r\n </p>\r\n <p v-if=\"description\" class=\"text-xs text-gray-500 dark:text-gray-400\">\r\n {{ description }}\r\n </p>\r\n <p v-if=\"maxSize\" class=\"text-xs text-gray-500 dark:text-gray-400\">\r\n Max size: {{ formatSize(maxSize) }}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n <!-- File list -->\r\n <ul v-if=\"files.length > 0\" class=\"space-y-2\">\r\n <li\r\n v-for=\"uploadedFile in files\"\r\n :key=\"uploadedFile.id\"\r\n class=\"flex items-center gap-3 p-3 bg-gray-50 dark:bg-gray-800 rounded-lg\"\r\n >\r\n <Icon :icon=\"getFileIcon(uploadedFile.file)\" class=\"w-8 h-8 text-gray-400\" />\r\n\r\n <div class=\"flex-1 min-w-0\">\r\n <p class=\"text-sm font-medium text-gray-700 dark:text-gray-300 truncate\">\r\n {{ uploadedFile.file.name }}\r\n </p>\r\n <p class=\"text-xs text-gray-500 dark:text-gray-400\">\r\n {{ formatSize(uploadedFile.file.size) }}\r\n </p>\r\n </div>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"p-1 text-gray-400 hover:text-red-500 rounded\"\r\n @click.stop=\"removeFile(uploadedFile.id)\"\r\n >\r\n <Icon icon=\"heroicons:x-mark\" class=\"w-5 h-5\" />\r\n </button>\r\n </li>\r\n </ul>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { ref, computed } from 'vue'\r\nimport { Icon } from '@iconify/vue'\r\n\r\nexport type RatingSize = 'sm' | 'md' | 'lg'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Current rating value */\r\n modelValue?: number\r\n /** Maximum rating */\r\n max?: number\r\n /** Allow half stars */\r\n allowHalf?: boolean\r\n /** Read only mode */\r\n readonly?: boolean\r\n /** Disabled state */\r\n disabled?: boolean\r\n /** Size of stars */\r\n size?: RatingSize\r\n /** Icon for filled star */\r\n filledIcon?: string\r\n /** Icon for empty star */\r\n emptyIcon?: string\r\n /** Icon for half star */\r\n halfIcon?: string\r\n /** Color of filled stars */\r\n color?: string\r\n /** Show rating value */\r\n showValue?: boolean\r\n }>(),\r\n {\r\n modelValue: 0,\r\n max: 5,\r\n allowHalf: false,\r\n readonly: false,\r\n disabled: false,\r\n size: 'md',\r\n filledIcon: 'heroicons:star-solid',\r\n emptyIcon: 'heroicons:star',\r\n halfIcon: 'heroicons:star-solid',\r\n color: 'text-yellow-400',\r\n showValue: false,\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n 'update:modelValue': [value: number]\r\n}>()\r\n\r\nconst hoverValue = ref<number | null>(null)\r\n\r\nconst displayValue = computed(() => {\r\n return hoverValue.value !== null ? hoverValue.value : props.modelValue\r\n})\r\n\r\nconst sizeClasses = computed(() => {\r\n switch (props.size) {\r\n case 'sm':\r\n return 'w-4 h-4'\r\n case 'lg':\r\n return 'w-8 h-8'\r\n default:\r\n return 'w-6 h-6'\r\n }\r\n})\r\n\r\nconst getStarState = (index: number): 'full' | 'half' | 'empty' => {\r\n const value = displayValue.value\r\n if (value >= index) return 'full'\r\n if (props.allowHalf && value >= index - 0.5) return 'half'\r\n return 'empty'\r\n}\r\n\r\nconst handleClick = (index: number, event: MouseEvent) => {\r\n if (props.readonly || props.disabled) return\r\n\r\n let value = index\r\n if (props.allowHalf) {\r\n const rect = (event.target as HTMLElement).getBoundingClientRect()\r\n const isLeftHalf = event.clientX - rect.left < rect.width / 2\r\n value = isLeftHalf ? index - 0.5 : index\r\n }\r\n\r\n emit('update:modelValue', value)\r\n}\r\n\r\nconst handleMouseMove = (index: number, event: MouseEvent) => {\r\n if (props.readonly || props.disabled) return\r\n\r\n let value = index\r\n if (props.allowHalf) {\r\n const rect = (event.target as HTMLElement).getBoundingClientRect()\r\n const isLeftHalf = event.clientX - rect.left < rect.width / 2\r\n value = isLeftHalf ? index - 0.5 : index\r\n }\r\n\r\n hoverValue.value = value\r\n}\r\n\r\nconst handleMouseLeave = () => {\r\n hoverValue.value = null\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"flex items-center gap-1\">\r\n <div\r\n class=\"flex items-center\"\r\n @mouseleave=\"handleMouseLeave\"\r\n >\r\n <button\r\n v-for=\"index in max\"\r\n :key=\"index\"\r\n type=\"button\"\r\n class=\"relative focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-1 rounded\"\r\n :class=\"[\r\n readonly || disabled ? 'cursor-default' : 'cursor-pointer',\r\n disabled && 'opacity-50',\r\n ]\"\r\n :disabled=\"readonly || disabled\"\r\n @click=\"handleClick(index, $event)\"\r\n @mousemove=\"handleMouseMove(index, $event)\"\r\n >\r\n <!-- Empty star (background) -->\r\n <Icon\r\n :icon=\"emptyIcon\"\r\n :class=\"[sizeClasses, 'text-gray-300 dark:text-gray-600']\"\r\n />\r\n\r\n <!-- Filled star (overlay) -->\r\n <div\r\n class=\"absolute inset-0 overflow-hidden\"\r\n :style=\"{\r\n width:\r\n getStarState(index) === 'full'\r\n ? '100%'\r\n : getStarState(index) === 'half'\r\n ? '50%'\r\n : '0%',\r\n }\"\r\n >\r\n <Icon\r\n :icon=\"filledIcon\"\r\n :class=\"[sizeClasses, color]\"\r\n />\r\n </div>\r\n </button>\r\n </div>\r\n\r\n <span\r\n v-if=\"showValue\"\r\n class=\"ml-2 text-sm font-medium text-gray-700 dark:text-gray-300\"\r\n >\r\n {{ modelValue.toFixed(allowHalf ? 1 : 0) }}\r\n </span>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { ref, watch, computed } from 'vue'\r\nimport { Icon } from '@iconify/vue'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Current color value (hex) */\r\n modelValue?: string\r\n /** Predefined color swatches */\r\n swatches?: string[]\r\n /** Show custom color input */\r\n showInput?: boolean\r\n /** Disabled state */\r\n disabled?: boolean\r\n /** Label */\r\n label?: string\r\n /** Teleport target (e.g., 'body', '#app'). Set to false to disable teleport. */\r\n teleport?: string | false\r\n }>(),\r\n {\r\n modelValue: '#3b82f6',\r\n swatches: () => [\r\n '#ef4444', '#f97316', '#f59e0b', '#eab308', '#84cc16',\r\n '#22c55e', '#10b981', '#14b8a6', '#06b6d4', '#0ea5e9',\r\n '#3b82f6', '#6366f1', '#8b5cf6', '#a855f7', '#d946ef',\r\n '#ec4899', '#f43f5e', '#78716c', '#737373', '#000000',\r\n ],\r\n showInput: true,\r\n disabled: false,\r\n teleport: false,\r\n },\r\n)\r\n\r\nconst teleportDisabled = computed(() => props.teleport === false)\r\nconst teleportTarget = computed(() => props.teleport === false ? 'body' : props.teleport)\r\n\r\nconst emit = defineEmits<{\r\n 'update:modelValue': [value: string]\r\n}>()\r\n\r\nconst isOpen = ref(false)\r\nconst inputValue = ref(props.modelValue)\r\n\r\nwatch(\r\n () => props.modelValue,\r\n (newValue) => {\r\n inputValue.value = newValue\r\n },\r\n)\r\n\r\nconst selectColor = (color: string) => {\r\n emit('update:modelValue', color)\r\n inputValue.value = color\r\n}\r\n\r\nconst handleInputChange = () => {\r\n const color = inputValue.value\r\n // Validate hex color\r\n if (/^#([0-9A-Fa-f]{3}){1,2}$/.test(color)) {\r\n emit('update:modelValue', color)\r\n }\r\n}\r\n\r\nconst handleNativeInput = (event: Event) => {\r\n const color = (event.target as HTMLInputElement).value\r\n emit('update:modelValue', color)\r\n inputValue.value = color\r\n}\r\n\r\nconst togglePicker = () => {\r\n if (!props.disabled) {\r\n isOpen.value = !isOpen.value\r\n }\r\n}\r\n\r\nconst closePicker = () => {\r\n isOpen.value = false\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"relative inline-block\">\r\n <label v-if=\"label\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\r\n {{ label }}\r\n </label>\r\n\r\n <!-- Trigger -->\r\n <button\r\n type=\"button\"\r\n class=\"flex items-center gap-2 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors\"\r\n :class=\"{ 'opacity-50 cursor-not-allowed': disabled }\"\r\n :disabled=\"disabled\"\r\n @click=\"togglePicker\"\r\n >\r\n <span\r\n class=\"w-6 h-6 rounded border border-gray-200 dark:border-gray-600\"\r\n :style=\"{ backgroundColor: modelValue }\"\r\n />\r\n <span class=\"text-sm font-mono text-gray-700 dark:text-gray-300\">\r\n {{ modelValue }}\r\n </span>\r\n <Icon\r\n icon=\"heroicons:chevron-down\"\r\n class=\"w-4 h-4 text-gray-400\"\r\n :class=\"{ 'rotate-180': isOpen }\"\r\n />\r\n </button>\r\n\r\n <!-- Dropdown -->\r\n <Teleport :to=\"teleportTarget\" :disabled=\"teleportDisabled\">\r\n <Transition\r\n enter-active-class=\"transition duration-100 ease-out\"\r\n enter-from-class=\"opacity-0 scale-95\"\r\n enter-to-class=\"opacity-100 scale-100\"\r\n leave-active-class=\"transition duration-75 ease-in\"\r\n leave-from-class=\"opacity-100 scale-100\"\r\n leave-to-class=\"opacity-0 scale-95\"\r\n >\r\n <div\r\n v-if=\"isOpen\"\r\n class=\"absolute z-50 mt-2 p-3 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg\"\r\n @click.stop\r\n >\r\n <!-- Swatches -->\r\n <div class=\"grid grid-cols-5 gap-2 mb-3\">\r\n <button\r\n v-for=\"color in swatches\"\r\n :key=\"color\"\r\n type=\"button\"\r\n class=\"w-8 h-8 rounded-lg border-2 transition-transform hover:scale-110 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-1\"\r\n :class=\"[\r\n modelValue === color\r\n ? 'border-primary-500 ring-2 ring-primary-500 ring-offset-1'\r\n : 'border-transparent',\r\n ]\"\r\n :style=\"{ backgroundColor: color }\"\r\n :title=\"color\"\r\n @click=\"selectColor(color)\"\r\n >\r\n <Icon\r\n v-if=\"modelValue === color\"\r\n icon=\"heroicons:check\"\r\n class=\"w-4 h-4 mx-auto\"\r\n :class=\"[\r\n ['#ffffff', '#f9fafb', '#f3f4f6', '#e5e7eb', '#eab308', '#f59e0b'].includes(color)\r\n ? 'text-gray-800'\r\n : 'text-white',\r\n ]\"\r\n />\r\n </button>\r\n </div>\r\n\r\n <!-- Custom input -->\r\n <div v-if=\"showInput\" class=\"flex items-center gap-2 pt-3 border-t border-gray-200 dark:border-gray-700\">\r\n <input\r\n type=\"color\"\r\n :value=\"modelValue\"\r\n class=\"w-8 h-8 rounded cursor-pointer border-0 p-0\"\r\n @input=\"handleNativeInput\"\r\n />\r\n <input\r\n v-model=\"inputValue\"\r\n type=\"text\"\r\n class=\"flex-1 px-2 py-1 text-sm font-mono border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white\"\r\n placeholder=\"#000000\"\r\n @change=\"handleInputChange\"\r\n @keyup.enter=\"handleInputChange\"\r\n />\r\n </div>\r\n </div>\r\n </Transition>\r\n\r\n <!-- Click outside to close -->\r\n <div\r\n v-if=\"isOpen\"\r\n class=\"fixed inset-0 z-40\"\r\n @click=\"closePicker\"\r\n />\r\n </Teleport>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { ref, computed } from 'vue'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Current range value [min, max] */\r\n modelValue?: [number, number]\r\n /** Minimum value */\r\n min?: number\r\n /** Maximum value */\r\n max?: number\r\n /** Step increment */\r\n step?: number\r\n /** Disabled state */\r\n disabled?: boolean\r\n /** Show value labels */\r\n showLabels?: boolean\r\n /** Show min/max labels */\r\n showMinMax?: boolean\r\n /** Format function for labels */\r\n formatLabel?: (value: number) => string\r\n }>(),\r\n {\r\n modelValue: () => [25, 75],\r\n min: 0,\r\n max: 100,\r\n step: 1,\r\n disabled: false,\r\n showLabels: true,\r\n showMinMax: true,\r\n formatLabel: (v: number) => v.toString(),\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n 'update:modelValue': [value: [number, number]]\r\n}>()\r\n\r\nconst sliderRef = ref<HTMLDivElement>()\r\nconst dragging = ref<'min' | 'max' | null>(null)\r\n\r\nconst minValue = computed(() => props.modelValue[0])\r\nconst maxValue = computed(() => props.modelValue[1])\r\n\r\nconst minPercent = computed(() => {\r\n return ((minValue.value - props.min) / (props.max - props.min)) * 100\r\n})\r\n\r\nconst maxPercent = computed(() => {\r\n return ((maxValue.value - props.min) / (props.max - props.min)) * 100\r\n})\r\n\r\nconst rangeStyle = computed(() => ({\r\n left: `${minPercent.value}%`,\r\n width: `${maxPercent.value - minPercent.value}%`,\r\n}))\r\n\r\nconst getValueFromPosition = (clientX: number): number => {\r\n if (!sliderRef.value) return props.min\r\n\r\n const rect = sliderRef.value.getBoundingClientRect()\r\n const percent = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width))\r\n const rawValue = props.min + percent * (props.max - props.min)\r\n\r\n // Snap to step\r\n const steppedValue = Math.round(rawValue / props.step) * props.step\r\n return Math.max(props.min, Math.min(props.max, steppedValue))\r\n}\r\n\r\nconst updateValue = (handle: 'min' | 'max', newValue: number) => {\r\n const [currentMin, currentMax] = props.modelValue\r\n\r\n if (handle === 'min') {\r\n // Don't let min exceed max\r\n const clampedValue = Math.min(newValue, currentMax)\r\n emit('update:modelValue', [clampedValue, currentMax])\r\n } else {\r\n // Don't let max go below min\r\n const clampedValue = Math.max(newValue, currentMin)\r\n emit('update:modelValue', [currentMin, clampedValue])\r\n }\r\n}\r\n\r\nconst handleMouseDown = (handle: 'min' | 'max') => (event: MouseEvent) => {\r\n if (props.disabled) return\r\n event.preventDefault()\r\n dragging.value = handle\r\n\r\n const handleMouseMove = (e: MouseEvent) => {\r\n if (dragging.value) {\r\n const value = getValueFromPosition(e.clientX)\r\n updateValue(dragging.value, value)\r\n }\r\n }\r\n\r\n const handleMouseUp = () => {\r\n dragging.value = null\r\n document.removeEventListener('mousemove', handleMouseMove)\r\n document.removeEventListener('mouseup', handleMouseUp)\r\n }\r\n\r\n document.addEventListener('mousemove', handleMouseMove)\r\n document.addEventListener('mouseup', handleMouseUp)\r\n}\r\n\r\nconst handleTrackClick = (event: MouseEvent) => {\r\n if (props.disabled) return\r\n\r\n const value = getValueFromPosition(event.clientX)\r\n\r\n // Determine which handle to move based on proximity\r\n const distToMin = Math.abs(value - minValue.value)\r\n const distToMax = Math.abs(value - maxValue.value)\r\n\r\n if (distToMin <= distToMax) {\r\n updateValue('min', value)\r\n } else {\r\n updateValue('max', value)\r\n }\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"space-y-2\">\r\n <!-- Labels row -->\r\n <div v-if=\"showLabels\" class=\"flex justify-between text-sm font-medium text-gray-700 dark:text-gray-300\">\r\n <span>{{ formatLabel(minValue) }}</span>\r\n <span>{{ formatLabel(maxValue) }}</span>\r\n </div>\r\n\r\n <!-- Slider track -->\r\n <div\r\n ref=\"sliderRef\"\r\n class=\"relative h-2 rounded-full cursor-pointer\"\r\n :class=\"[\r\n disabled\r\n ? 'bg-gray-200 dark:bg-gray-700 cursor-not-allowed'\r\n : 'bg-gray-200 dark:bg-gray-700',\r\n ]\"\r\n @click=\"handleTrackClick\"\r\n >\r\n <!-- Active range -->\r\n <div\r\n class=\"absolute h-full rounded-full\"\r\n :class=\"[disabled ? 'bg-gray-400' : 'bg-primary-500']\"\r\n :style=\"rangeStyle\"\r\n />\r\n\r\n <!-- Min handle -->\r\n <div\r\n class=\"absolute top-1/2 -translate-y-1/2 -translate-x-1/2 w-5 h-5 rounded-full border-2 shadow transition-shadow\"\r\n :class=\"[\r\n disabled\r\n ? 'bg-gray-300 border-gray-400 cursor-not-allowed'\r\n : 'bg-white border-primary-500 cursor-grab hover:shadow-md active:cursor-grabbing',\r\n dragging === 'min' && 'ring-4 ring-primary-200 dark:ring-primary-800',\r\n ]\"\r\n :style=\"{ left: `${minPercent}%` }\"\r\n @mousedown=\"handleMouseDown('min')\"\r\n />\r\n\r\n <!-- Max handle -->\r\n <div\r\n class=\"absolute top-1/2 -translate-y-1/2 -translate-x-1/2 w-5 h-5 rounded-full border-2 shadow transition-shadow\"\r\n :class=\"[\r\n disabled\r\n ? 'bg-gray-300 border-gray-400 cursor-not-allowed'\r\n : 'bg-white border-primary-500 cursor-grab hover:shadow-md active:cursor-grabbing',\r\n dragging === 'max' && 'ring-4 ring-primary-200 dark:ring-primary-800',\r\n ]\"\r\n :style=\"{ left: `${maxPercent}%` }\"\r\n @mousedown=\"handleMouseDown('max')\"\r\n />\r\n </div>\r\n\r\n <!-- Min/Max labels -->\r\n <div v-if=\"showMinMax\" class=\"flex justify-between text-xs text-gray-500 dark:text-gray-400\">\r\n <span>{{ formatLabel(min) }}</span>\r\n <span>{{ formatLabel(max) }}</span>\r\n </div>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { ref, computed, watch, nextTick } from 'vue'\r\nimport { Icon } from '@iconify/vue'\r\nimport { onClickOutside } from '@vueuse/core'\r\nimport { useId } from '@/composables/useId'\r\n\r\nexport interface ComboboxOption {\r\n value: string | number\r\n label: string\r\n disabled?: boolean\r\n}\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Selected value(s) */\r\n modelValue?: string | number | (string | number)[] | null\r\n /** Available options */\r\n options: ComboboxOption[]\r\n /** Placeholder text */\r\n placeholder?: string\r\n /** Search placeholder */\r\n searchPlaceholder?: string\r\n /** Allow multiple selection */\r\n multiple?: boolean\r\n /** Disabled state */\r\n disabled?: boolean\r\n /** Allow clearing selection */\r\n clearable?: boolean\r\n /** No results message */\r\n noResultsText?: string\r\n /** Input name attribute */\r\n name?: string\r\n /** Input id attribute */\r\n id?: string\r\n /** Teleport target (e.g., 'body', '#app'). Set to false to disable teleport. */\r\n teleport?: string | false\r\n }>(),\r\n {\r\n placeholder: 'Select...',\r\n searchPlaceholder: 'Search...',\r\n multiple: false,\r\n disabled: false,\r\n clearable: false,\r\n noResultsText: 'No results found',\r\n teleport: false,\r\n },\r\n)\r\n\r\n// Generate unique IDs for accessibility\r\nconst { id: generatedId, related } = useId({ prefix: 'combobox', id: props.id })\r\nconst inputId = computed(() => props.id ?? generatedId.value)\r\nconst listboxId = computed(() => related('listbox'))\r\n\r\nconst teleportDisabled = computed(() => props.teleport === false)\r\nconst teleportTarget = computed(() => props.teleport === false ? 'body' : props.teleport)\r\n\r\nconst emit = defineEmits<{\r\n 'update:modelValue': [value: string | number | (string | number)[] | null]\r\n}>()\r\n\r\nconst containerRef = ref<HTMLElement>()\r\nconst inputRef = ref<HTMLInputElement>()\r\nconst isOpen = ref(false)\r\nconst search = ref('')\r\n\r\nonClickOutside(containerRef, () => {\r\n isOpen.value = false\r\n})\r\n\r\nconst filteredOptions = computed(() => {\r\n if (!search.value) return props.options\r\n const query = search.value.toLowerCase()\r\n return props.options.filter((opt) =>\r\n opt.label.toLowerCase().includes(query)\r\n )\r\n})\r\n\r\nconst selectedOptions = computed(() => {\r\n if (props.modelValue === null || props.modelValue === undefined) return []\r\n const values = Array.isArray(props.modelValue) ? props.modelValue : [props.modelValue]\r\n return props.options.filter((opt) => values.includes(opt.value))\r\n})\r\n\r\nconst displayValue = computed(() => {\r\n if (selectedOptions.value.length === 0) return ''\r\n if (props.multiple) {\r\n return selectedOptions.value.map((o) => o.label).join(', ')\r\n }\r\n return selectedOptions.value[0]?.label || ''\r\n})\r\n\r\nconst isSelected = (option: ComboboxOption): boolean => {\r\n if (props.modelValue === null || props.modelValue === undefined) return false\r\n if (Array.isArray(props.modelValue)) {\r\n return props.modelValue.includes(option.value)\r\n }\r\n return props.modelValue === option.value\r\n}\r\n\r\nconst toggleOption = (option: ComboboxOption) => {\r\n if (option.disabled) return\r\n\r\n if (props.multiple) {\r\n const currentValues = Array.isArray(props.modelValue) ? [...props.modelValue] : []\r\n const index = currentValues.indexOf(option.value)\r\n if (index === -1) {\r\n currentValues.push(option.value)\r\n } else {\r\n currentValues.splice(index, 1)\r\n }\r\n emit('update:modelValue', currentValues)\r\n } else {\r\n emit('update:modelValue', option.value)\r\n isOpen.value = false\r\n search.value = ''\r\n }\r\n}\r\n\r\nconst clear = () => {\r\n emit('update:modelValue', props.multiple ? [] : null)\r\n search.value = ''\r\n}\r\n\r\nconst openDropdown = () => {\r\n if (props.disabled) return\r\n isOpen.value = true\r\n nextTick(() => {\r\n inputRef.value?.focus()\r\n })\r\n}\r\n\r\nwatch(isOpen, (open) => {\r\n if (!open) {\r\n search.value = ''\r\n }\r\n})\r\n</script>\r\n\r\n<template>\r\n <div\r\n ref=\"containerRef\"\r\n class=\"relative\"\r\n >\r\n <!-- Trigger -->\r\n <div\r\n role=\"combobox\"\r\n :aria-expanded=\"isOpen\"\r\n :aria-haspopup=\"'listbox'\"\r\n :aria-controls=\"listboxId\"\r\n :class=\"[\r\n 'flex min-h-[42px] w-full cursor-pointer items-center rounded-lg border bg-white px-3 py-2 transition-colors',\r\n 'dark:bg-gray-900',\r\n disabled\r\n ? 'cursor-not-allowed border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-800'\r\n : isOpen\r\n ? 'border-primary ring-2 ring-primary/20'\r\n : 'border-gray-300 hover:border-gray-400 dark:border-gray-600 dark:hover:border-gray-500',\r\n ]\"\r\n @click=\"openDropdown\"\r\n >\r\n <!-- Selected value or placeholder -->\r\n <span\r\n v-if=\"!isOpen\"\r\n :class=\"[\r\n 'flex-1 truncate text-sm',\r\n selectedOptions.length ? 'text-gray-900 dark:text-gray-100' : 'text-gray-400 dark:text-gray-500',\r\n ]\"\r\n >\r\n {{ displayValue || placeholder }}\r\n </span>\r\n\r\n <!-- Search input (when open) -->\r\n <input\r\n v-else\r\n :id=\"inputId\"\r\n ref=\"inputRef\"\r\n v-model=\"search\"\r\n type=\"text\"\r\n :name=\"name\"\r\n :placeholder=\"searchPlaceholder\"\r\n :disabled=\"disabled\"\r\n aria-autocomplete=\"list\"\r\n :aria-controls=\"listboxId\"\r\n class=\"flex-1 border-none bg-transparent text-sm text-gray-900 outline-none placeholder:text-gray-400 dark:text-gray-100 dark:placeholder:text-gray-500\"\r\n @click.stop\r\n />\r\n\r\n <!-- Actions -->\r\n <div class=\"flex items-center gap-1\">\r\n <!-- Clear button -->\r\n <button\r\n v-if=\"clearable && selectedOptions.length > 0 && !disabled\"\r\n type=\"button\"\r\n class=\"rounded p-0.5 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300\"\r\n aria-label=\"Clear selection\"\r\n @click.stop=\"clear\"\r\n >\r\n <Icon icon=\"lucide:x\" class=\"h-4 w-4\" aria-hidden=\"true\" />\r\n </button>\r\n\r\n <!-- Chevron -->\r\n <Icon\r\n icon=\"lucide:chevron-down\"\r\n :class=\"[\r\n 'h-4 w-4 text-gray-400 transition-transform',\r\n isOpen && 'rotate-180',\r\n ]\"\r\n aria-hidden=\"true\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown -->\r\n <Teleport :to=\"teleportTarget\" :disabled=\"teleportDisabled\">\r\n <Transition\r\n enter-active-class=\"transition duration-100 ease-out\"\r\n enter-from-class=\"transform scale-95 opacity-0\"\r\n enter-to-class=\"transform scale-100 opacity-100\"\r\n leave-active-class=\"transition duration-75 ease-in\"\r\n leave-from-class=\"transform scale-100 opacity-100\"\r\n leave-to-class=\"transform scale-95 opacity-0\"\r\n >\r\n <div\r\n v-if=\"isOpen\"\r\n :id=\"listboxId\"\r\n role=\"listbox\"\r\n :aria-label=\"placeholder\"\r\n :aria-multiselectable=\"multiple || undefined\"\r\n class=\"absolute z-50 mt-1 max-h-60 w-full overflow-auto rounded-lg border border-gray-200 bg-white py-1 shadow-lg dark:border-gray-700 dark:bg-gray-900\"\r\n >\r\n <!-- Options -->\r\n <template v-if=\"filteredOptions.length\">\r\n <button\r\n v-for=\"option in filteredOptions\"\r\n :key=\"option.value\"\r\n type=\"button\"\r\n role=\"option\"\r\n :aria-selected=\"isSelected(option)\"\r\n :aria-disabled=\"option.disabled || undefined\"\r\n :disabled=\"option.disabled\"\r\n :class=\"[\r\n 'flex w-full items-center gap-2 px-3 py-2 text-left text-sm transition-colors',\r\n option.disabled\r\n ? 'cursor-not-allowed text-gray-400 dark:text-gray-500'\r\n : isSelected(option)\r\n ? 'bg-primary/10 text-primary dark:bg-primary/20'\r\n : 'text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-800',\r\n ]\"\r\n @click=\"toggleOption(option)\"\r\n >\r\n <!-- Checkbox for multiple -->\r\n <span\r\n v-if=\"multiple\"\r\n :class=\"[\r\n 'flex h-4 w-4 items-center justify-center rounded border',\r\n isSelected(option)\r\n ? 'border-primary bg-primary text-white'\r\n : 'border-gray-300 dark:border-gray-600',\r\n ]\"\r\n aria-hidden=\"true\"\r\n >\r\n <Icon v-if=\"isSelected(option)\" icon=\"lucide:check\" class=\"h-3 w-3\" />\r\n </span>\r\n\r\n <!-- Label -->\r\n <span class=\"flex-1\">{{ option.label }}</span>\r\n\r\n <!-- Check for single -->\r\n <Icon\r\n v-if=\"!multiple && isSelected(option)\"\r\n icon=\"lucide:check\"\r\n class=\"h-4 w-4 text-primary\"\r\n aria-hidden=\"true\"\r\n />\r\n </button>\r\n </template>\r\n\r\n <!-- No results -->\r\n <div\r\n v-else\r\n class=\"px-3 py-2 text-center text-sm text-gray-500 dark:text-gray-400\"\r\n role=\"status\"\r\n >\r\n {{ noResultsText }}\r\n </div>\r\n </div>\r\n </Transition>\r\n </Teleport>\r\n </div>\r\n</template>\r\n"],"names":["_createElementBlock","_renderSlot","_useModel","_withDirectives","_openBlock","_mergeProps","$attrs","_hoisted_1","_createElementVNode","_unref","_hoisted_3","_toDisplayString","_createVNode","_createBlock","_Teleport","_Transition","_normalizeClass","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_Fragment","_renderList","_hoisted_10","_hoisted_11","FormLabel","FormSelect","$props","FormInput","FormHelp","_hoisted_2","_hoisted_4","_hoisted_9","_withModifiers","_normalizeStyle"],"mappings":"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"}
@@ -2,45 +2,61 @@
2
2
  const vue = require("vue");
3
3
  const vue$1 = require("@iconify/vue");
4
4
  const _pluginVue_exportHelper = require("./_plugin-vue_export-helper-DM9IkUGy.cjs");
5
- const Button_vue_vue_type_script_setup_true_lang = require("./Button.vue_vue_type_script_setup_true_lang-DrGM65ny.cjs");
6
- const _hoisted_1$a = { class: "flex items-center justify-center py-12" };
5
+ const useId = require("./useId-nxrBaIC9.cjs");
6
+ const useFocusTrap = require("./useFocusTrap-kcxO8AeU.cjs");
7
+ const Button_vue_vue_type_script_setup_true_lang = require("./Button.vue_vue_type_script_setup_true_lang-Cev21KGJ.cjs");
8
+ const _hoisted_1$a = ["aria-label"];
7
9
  const _hoisted_2$8 = { class: "text-center" };
8
10
  const _hoisted_3$8 = {
9
11
  key: 0,
10
12
  class: "mt-4 text-gray-600 dark:text-gray-400"
11
13
  };
14
+ const _hoisted_4$6 = {
15
+ key: 1,
16
+ class: "sr-only"
17
+ };
12
18
  const _sfc_main$b = /* @__PURE__ */ vue.defineComponent({
13
19
  __name: "LoadingSpinner",
14
20
  props: {
15
21
  text: {},
16
- size: { default: "md" }
22
+ size: { default: "md" },
23
+ ariaLabel: { default: "Loading" }
17
24
  },
18
25
  setup(__props) {
26
+ const props = __props;
19
27
  const sizeClasses = {
20
28
  sm: "h-8 w-8",
21
29
  md: "h-12 w-12",
22
30
  lg: "h-16 w-16"
23
31
  };
32
+ const accessibleLabel = vue.computed(() => props.text || props.ariaLabel);
24
33
  return (_ctx, _cache) => {
25
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$a, [
34
+ return vue.openBlock(), vue.createElementBlock("div", {
35
+ class: "flex items-center justify-center py-12",
36
+ role: "status",
37
+ "aria-live": "polite",
38
+ "aria-label": accessibleLabel.value
39
+ }, [
26
40
  vue.createElementVNode("div", _hoisted_2$8, [
27
41
  vue.createElementVNode("div", {
28
- class: vue.normalizeClass([sizeClasses[__props.size], "border-primary inline-block animate-spin rounded-full border-4 border-solid border-r-transparent"])
42
+ class: vue.normalizeClass([sizeClasses[__props.size], "border-primary inline-block animate-spin rounded-full border-4 border-solid border-r-transparent"]),
43
+ "aria-hidden": "true"
29
44
  }, null, 2),
30
- __props.text ? (vue.openBlock(), vue.createElementBlock("p", _hoisted_3$8, vue.toDisplayString(__props.text), 1)) : vue.createCommentVNode("", true)
45
+ __props.text ? (vue.openBlock(), vue.createElementBlock("p", _hoisted_3$8, vue.toDisplayString(__props.text), 1)) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_4$6, vue.toDisplayString(accessibleLabel.value), 1))
31
46
  ])
32
- ]);
47
+ ], 8, _hoisted_1$a);
33
48
  };
34
49
  }
35
50
  });
36
- const _hoisted_1$9 = {
51
+ const _hoisted_1$9 = ["id", "aria-labelledby"];
52
+ const _hoisted_2$7 = {
37
53
  key: 0,
38
54
  class: "flex items-center justify-between border-b border-gray-200 px-6 py-4 dark:border-gray-700"
39
55
  };
40
- const _hoisted_2$7 = { class: "text-xl font-semibold text-gray-900 dark:text-gray-100" };
41
- const _hoisted_3$7 = { class: "sr-only" };
42
- const _hoisted_4$5 = { class: "flex-1 overflow-y-auto px-6 py-4" };
43
- const _hoisted_5$2 = {
56
+ const _hoisted_3$7 = ["id"];
57
+ const _hoisted_4$5 = { class: "sr-only" };
58
+ const _hoisted_5$2 = { class: "flex-1 overflow-y-auto px-6 py-4" };
59
+ const _hoisted_6$1 = {
44
60
  key: 1,
45
61
  class: "flex items-center justify-end gap-3 border-t border-gray-200 px-6 py-4 dark:border-gray-700"
46
62
  };
@@ -52,7 +68,8 @@ const _sfc_main$a = /* @__PURE__ */ vue.defineComponent({
52
68
  closeOnBackdrop: { type: Boolean, default: true },
53
69
  closeOnEscape: { type: Boolean, default: true },
54
70
  closeButtonLabel: { default: "Close" },
55
- teleport: { type: [String, Boolean], default: "body" }
71
+ teleport: { type: [String, Boolean], default: "body" },
72
+ id: {}
56
73
  },
57
74
  emits: ["close"],
58
75
  setup(__props, { emit: __emit }) {
@@ -67,6 +84,15 @@ const _sfc_main$a = /* @__PURE__ */ vue.defineComponent({
67
84
  const teleportDisabled = vue.computed(() => props.teleport === false);
68
85
  const teleportTarget = vue.computed(() => props.teleport === false ? "body" : props.teleport);
69
86
  const emit = __emit;
87
+ const { id: modalId, related } = useId.useId({ prefix: "modal", id: props.id });
88
+ const titleId = vue.computed(() => related("title"));
89
+ const isActive = vue.ref(true);
90
+ const { containerRef: dialogRef } = useFocusTrap.useFocusTrap({
91
+ active: isActive,
92
+ focusFirst: true,
93
+ restoreFocus: true
94
+ });
95
+ const hasTitle = vue.computed(() => Boolean(props.title));
70
96
  const sizeClasses = {
71
97
  sm: "max-w-md",
72
98
  default: "max-w-3xl",
@@ -102,35 +128,46 @@ const _sfc_main$a = /* @__PURE__ */ vue.defineComponent({
102
128
  onClick: vue.withModifiers(handleBackdropClick, ["self"])
103
129
  }, [
104
130
  vue.createElementVNode("div", {
131
+ ref_key: "dialogRef",
132
+ ref: dialogRef,
133
+ id: vue.unref(modalId),
134
+ role: "dialog",
135
+ "aria-modal": "true",
136
+ "aria-labelledby": hasTitle.value ? titleId.value : void 0,
105
137
  class: vue.normalizeClass([sizeClasses[vue.unref(size)], "flex max-h-[90vh] w-full flex-col rounded-lg bg-white shadow-xl dark:bg-gray-900"])
106
138
  }, [
107
- vue.unref(title) || _ctx.$slots.header || _ctx.$slots.title ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$9, [
108
- vue.createElementVNode("h3", _hoisted_2$7, [
139
+ vue.unref(title) || _ctx.$slots.header || _ctx.$slots.title ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$7, [
140
+ vue.createElementVNode("h3", {
141
+ id: titleId.value,
142
+ class: "text-xl font-semibold text-gray-900 dark:text-gray-100"
143
+ }, [
109
144
  vue.renderSlot(_ctx.$slots, "header", {}, () => [
110
145
  vue.renderSlot(_ctx.$slots, "title", {}, () => [
111
146
  vue.createTextVNode(vue.toDisplayString(vue.unref(title)), 1)
112
147
  ])
113
148
  ])
114
- ]),
149
+ ], 8, _hoisted_3$7),
115
150
  vue.createElementVNode("button", {
116
151
  class: "rounded-lg p-1.5 text-gray-400 hover:bg-gray-100 hover:text-gray-900 dark:hover:bg-gray-800 dark:hover:text-gray-100",
117
152
  type: "button",
153
+ "aria-label": "Close dialog",
118
154
  onClick: _cache[0] || (_cache[0] = ($event) => emit("close"))
119
155
  }, [
120
156
  vue.createVNode(vue.unref(vue$1.Icon), {
121
157
  class: "h-5 w-5",
122
- icon: "lucide:x"
158
+ icon: "lucide:x",
159
+ "aria-hidden": "true"
123
160
  }),
124
- vue.createElementVNode("span", _hoisted_3$7, vue.toDisplayString(vue.unref(closeButtonLabel)), 1)
161
+ vue.createElementVNode("span", _hoisted_4$5, vue.toDisplayString(vue.unref(closeButtonLabel)), 1)
125
162
  ])
126
163
  ])) : vue.createCommentVNode("", true),
127
- vue.createElementVNode("div", _hoisted_4$5, [
164
+ vue.createElementVNode("div", _hoisted_5$2, [
128
165
  vue.renderSlot(_ctx.$slots, "default")
129
166
  ]),
130
- _ctx.$slots.footer ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_5$2, [
167
+ _ctx.$slots.footer ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6$1, [
131
168
  vue.renderSlot(_ctx.$slots, "footer")
132
169
  ])) : vue.createCommentVNode("", true)
133
- ], 2)
170
+ ], 10, _hoisted_1$9)
134
171
  ])
135
172
  ], 8, ["to", "disabled"]);
136
173
  };
@@ -418,7 +455,8 @@ const _sfc_main$6 = /* @__PURE__ */ vue.defineComponent({
418
455
  }, [
419
456
  vue.createVNode(vue.unref(vue$1.Icon), {
420
457
  icon: __props.icon || vue.unref(styles).icon,
421
- class: vue.normalizeClass(["size-5 shrink-0", vue.unref(styles).iconColor])
458
+ class: vue.normalizeClass(["size-5 shrink-0", vue.unref(styles).iconColor]),
459
+ "aria-hidden": "true"
422
460
  }, null, 8, ["icon", "class"]),
423
461
  vue.createElementVNode("div", _hoisted_1$5, [
424
462
  __props.title ? (vue.openBlock(), vue.createElementBlock("h4", _hoisted_2$4, vue.toDisplayString(__props.title), 1)) : vue.createCommentVNode("", true),
@@ -430,11 +468,13 @@ const _sfc_main$6 = /* @__PURE__ */ vue.defineComponent({
430
468
  key: 0,
431
469
  type: "button",
432
470
  class: "shrink-0 rounded p-1 text-gray-400 hover:bg-gray-200 hover:text-gray-600 dark:hover:bg-gray-700 dark:hover:text-gray-300",
471
+ "aria-label": "Dismiss alert",
433
472
  onClick: _cache[0] || (_cache[0] = ($event) => emit("dismiss"))
434
473
  }, [
435
474
  vue.createVNode(vue.unref(vue$1.Icon), {
436
475
  icon: "lucide:x",
437
- class: "size-4"
476
+ class: "size-4",
477
+ "aria-hidden": "true"
438
478
  })
439
479
  ])) : vue.createCommentVNode("", true)
440
480
  ], 2);
@@ -536,7 +576,8 @@ const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
536
576
  }, [
537
577
  vue.createVNode(vue.unref(vue$1.Icon), {
538
578
  icon: vue.unref(config).icon,
539
- class: vue.normalizeClass(["size-5 shrink-0", vue.unref(config).iconColor])
579
+ class: vue.normalizeClass(["size-5 shrink-0", vue.unref(config).iconColor]),
580
+ "aria-hidden": "true"
540
581
  }, null, 8, ["icon", "class"]),
541
582
  vue.createElementVNode("div", _hoisted_1$3, [
542
583
  __props.title ? (vue.openBlock(), vue.createElementBlock("p", _hoisted_2$2, vue.toDisplayString(__props.title), 1)) : vue.createCommentVNode("", true),
@@ -546,11 +587,13 @@ const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
546
587
  key: 0,
547
588
  type: "button",
548
589
  class: "shrink-0 rounded p-1 text-gray-400 hover:bg-gray-200 hover:text-gray-600 dark:hover:bg-gray-700 dark:hover:text-gray-300",
590
+ "aria-label": "Dismiss notification",
549
591
  onClick: _cache[0] || (_cache[0] = ($event) => emit("close"))
550
592
  }, [
551
593
  vue.createVNode(vue.unref(vue$1.Icon), {
552
594
  icon: "lucide:x",
553
- class: "size-4"
595
+ class: "size-4",
596
+ "aria-hidden": "true"
554
597
  })
555
598
  ])) : vue.createCommentVNode("", true)
556
599
  ], 2);
@@ -588,7 +631,9 @@ const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
588
631
  return vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
589
632
  vue.createElementVNode("div", {
590
633
  class: vue.normalizeClass(["fixed z-[9999] flex flex-col gap-2 w-full max-w-sm", positionClasses[__props.position]]),
591
- style: vue.normalizeStyle(topStyle.value)
634
+ style: vue.normalizeStyle(topStyle.value),
635
+ "aria-live": "polite",
636
+ "aria-atomic": "false"
592
637
  }, [
593
638
  vue.createVNode(vue.TransitionGroup, {
594
639
  "enter-active-class": "transition duration-300 ease-out",
@@ -687,7 +732,8 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
687
732
  const Progress = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main$2, [["__scopeId", "data-v-546a3ae5"]]);
688
733
  const _hoisted_1$1 = {
689
734
  key: 0,
690
- class: "space-y-2"
735
+ class: "space-y-2",
736
+ "aria-hidden": "true"
691
737
  };
692
738
  const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
693
739
  __name: "Skeleton",
@@ -731,7 +777,8 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
731
777
  style: vue.normalizeStyle({
732
778
  width: __props.width || (__props.variant === "circular" ? "3rem" : "100%"),
733
779
  height: __props.height || (__props.variant === "circular" ? "3rem" : __props.variant === "text" ? "1rem" : "6rem")
734
- })
780
+ }),
781
+ "aria-hidden": "true"
735
782
  }, null, 6));
736
783
  };
737
784
  }
@@ -845,4 +892,4 @@ exports._sfc_main$6 = _sfc_main$5;
845
892
  exports._sfc_main$7 = _sfc_main$4;
846
893
  exports._sfc_main$8 = _sfc_main$3;
847
894
  exports._sfc_main$9 = _sfc_main$1;
848
- //# sourceMappingURL=ConfirmDialog.vue_vue_type_script_setup_true_lang-DXb9wQQv.cjs.map
895
+ //# sourceMappingURL=ConfirmDialog.vue_vue_type_script_setup_true_lang-CwHYxBhR.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfirmDialog.vue_vue_type_script_setup_true_lang-CwHYxBhR.cjs","sources":["../src/components/feedback/LoadingSpinner.vue","../src/components/feedback/Modal.vue","../src/components/feedback/PaginationControls.vue","../src/components/feedback/NotificationComponent.vue","../src/components/feedback/NotificationList.vue","../src/components/feedback/Alert.vue","../src/components/feedback/EmptyState.vue","../src/components/feedback/Toast.vue","../src/components/feedback/ToastContainer.vue","../src/components/feedback/Progress.vue","../src/components/feedback/Skeleton.vue","../src/components/feedback/ConfirmDialog.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { computed } from 'vue'\nimport type { SpinnerSize } from '@/types'\n\nconst props = withDefaults(\n defineProps<{\n text?: string\n size?: SpinnerSize\n /** Accessible label for screen readers (defaults to 'Loading' or text prop) */\n ariaLabel?: string\n }>(),\n {\n size: 'md',\n ariaLabel: 'Loading',\n },\n)\n\nconst sizeClasses: Record<SpinnerSize, string> = {\n sm: 'h-8 w-8',\n md: 'h-12 w-12',\n lg: 'h-16 w-16',\n}\n\nconst accessibleLabel = computed(() => props.text || props.ariaLabel)\n</script>\n\n<template>\n <div\n class=\"flex items-center justify-center py-12\"\n role=\"status\"\n aria-live=\"polite\"\n :aria-label=\"accessibleLabel\"\n >\n <div class=\"text-center\">\n <div\n :class=\"sizeClasses[size]\"\n class=\"border-primary inline-block animate-spin rounded-full border-4 border-solid border-r-transparent\"\n aria-hidden=\"true\"\n />\n <p\n v-if=\"text\"\n class=\"mt-4 text-gray-600 dark:text-gray-400\"\n >\n {{ text }}\n </p>\n <span v-else class=\"sr-only\">{{ accessibleLabel }}</span>\n </div>\n </div>\n</template>\n","<script lang=\"ts\" setup>\r\nimport { Icon } from '@iconify/vue'\r\nimport { onMounted, onUnmounted, computed, ref } from 'vue'\r\nimport type { ModalSize } from '@/types'\r\nimport { useId } from '@/composables/useId'\r\nimport { useFocusTrap } from '@/composables/useFocusTrap'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n title?: string\r\n size?: ModalSize\r\n closeOnBackdrop?: boolean\r\n closeOnEscape?: boolean\r\n closeButtonLabel?: string\r\n /** Teleport target (e.g., 'body', '#app'). Set to false to disable teleport. */\r\n teleport?: string | false\r\n /** Custom ID for the modal (auto-generated if not provided) */\r\n id?: string\r\n }>(),\r\n {\r\n title: '',\r\n size: 'default',\r\n closeOnBackdrop: true,\r\n closeOnEscape: true,\r\n closeButtonLabel: 'Close',\r\n teleport: 'body',\r\n },\r\n)\r\n\r\nconst {\r\n title,\r\n size,\r\n closeOnBackdrop,\r\n closeOnEscape,\r\n closeButtonLabel,\r\n} = props\r\n\r\nconst teleportDisabled = computed(() => props.teleport === false)\r\nconst teleportTarget = computed(() => props.teleport === false ? 'body' : props.teleport)\r\n\r\nconst emit = defineEmits<{\r\n close: []\r\n}>()\r\n\r\n// Generate unique IDs for ARIA relationships\r\nconst { id: modalId, related } = useId({ prefix: 'modal', id: props.id })\r\nconst titleId = computed(() => related('title'))\r\n\r\n// Focus trap\r\nconst isActive = ref(true)\r\nconst { containerRef: dialogRef } = useFocusTrap({\r\n active: isActive,\r\n focusFirst: true,\r\n restoreFocus: true,\r\n})\r\n\r\n// Check if modal has a title (for aria-labelledby)\r\nconst hasTitle = computed(() => Boolean(props.title))\r\n\r\nconst sizeClasses: Record<ModalSize, string> = {\r\n sm: 'max-w-md',\r\n default: 'max-w-3xl',\r\n lg: 'max-w-5xl',\r\n xl: 'max-w-7xl',\r\n full: 'max-w-full mx-4',\r\n}\r\n\r\nconst handleBackdropClick = () => {\r\n if (closeOnBackdrop) {\r\n emit('close')\r\n }\r\n}\r\n\r\nconst handleEscape = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape' && closeOnEscape) {\r\n emit('close')\r\n }\r\n}\r\n\r\nonMounted(() => {\r\n document.addEventListener('keydown', handleEscape)\r\n document.body.style.overflow = 'hidden'\r\n})\r\n\r\nonUnmounted(() => {\r\n document.removeEventListener('keydown', handleEscape)\r\n document.body.style.overflow = ''\r\n})\r\n</script>\r\n\r\n<template>\r\n <Teleport :to=\"teleportTarget\" :disabled=\"teleportDisabled\">\r\n <div\r\n class=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\"\r\n @click.self=\"handleBackdropClick\"\r\n >\r\n <div\r\n ref=\"dialogRef\"\r\n :id=\"modalId\"\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n :aria-labelledby=\"hasTitle ? titleId : undefined\"\r\n :class=\"sizeClasses[size]\"\r\n class=\"flex max-h-[90vh] w-full flex-col rounded-lg bg-white shadow-xl dark:bg-gray-900\"\r\n >\r\n <!-- Header -->\r\n <div\r\n v-if=\"title || $slots.header || $slots.title\"\r\n class=\"flex items-center justify-between border-b border-gray-200 px-6 py-4 dark:border-gray-700\"\r\n >\r\n <h3\r\n :id=\"titleId\"\r\n class=\"text-xl font-semibold text-gray-900 dark:text-gray-100\"\r\n >\r\n <slot name=\"header\">\r\n <slot name=\"title\">\r\n {{ title }}\r\n </slot>\r\n </slot>\r\n </h3>\r\n <button\r\n class=\"rounded-lg p-1.5 text-gray-400 hover:bg-gray-100 hover:text-gray-900 dark:hover:bg-gray-800 dark:hover:text-gray-100\"\r\n type=\"button\"\r\n aria-label=\"Close dialog\"\r\n @click=\"emit('close')\"\r\n >\r\n <Icon\r\n class=\"h-5 w-5\"\r\n icon=\"lucide:x\"\r\n aria-hidden=\"true\"\r\n />\r\n <span class=\"sr-only\">{{ closeButtonLabel }}</span>\r\n </button>\r\n </div>\r\n\r\n <!-- Body -->\r\n <div class=\"flex-1 overflow-y-auto px-6 py-4\">\r\n <slot />\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div\r\n v-if=\"$slots.footer\"\r\n class=\"flex items-center justify-end gap-3 border-t border-gray-200 px-6 py-4 dark:border-gray-700\"\r\n >\r\n <slot name=\"footer\" />\r\n </div>\r\n </div>\r\n </div>\r\n </Teleport>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { Icon } from '@iconify/vue'\r\n\r\nconst {\r\n currentPage,\r\n totalPages,\r\n loading = false,\r\n pageSize = 10,\r\n pageSizeOptions = [10, 20, 50, 100],\r\n showPageSize = true,\r\n pageLabel = 'Page',\r\n ofLabel = 'of',\r\n itemsPerPageLabel = 'Items per page:',\r\n previousLabel = 'Previous',\r\n nextLabel = 'Next',\r\n} = defineProps<{\r\n currentPage: number\r\n totalPages: number\r\n loading?: boolean\r\n pageSize?: number\r\n pageSizeOptions?: number[]\r\n showPageSize?: boolean\r\n pageLabel?: string\r\n ofLabel?: string\r\n itemsPerPageLabel?: string\r\n previousLabel?: string\r\n nextLabel?: string\r\n}>()\r\n\r\nconst emit = defineEmits<{\r\n 'update:page': [page: number]\r\n 'update:pageSize': [size: number]\r\n}>()\r\n\r\nconst changePage = (page: number) => {\r\n if (page >= 1 && page <= totalPages && !loading) {\r\n emit('update:page', page)\r\n }\r\n}\r\n\r\nconst changePageSize = (event: Event) => {\r\n const target = event.target as HTMLSelectElement\r\n emit('update:pageSize', Number(target.value))\r\n}\r\n</script>\r\n\r\n<template>\r\n <div\r\n v-if=\"totalPages > 1\"\r\n class=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 border-t border-gray-200 px-4 sm:px-6 py-4 dark:border-gray-700\"\r\n >\r\n <!-- Info and page size -->\r\n <div class=\"flex flex-col sm:flex-row sm:items-center gap-3 sm:gap-4\">\r\n <div class=\"text-sm text-gray-700 dark:text-gray-300 text-center sm:text-left\">\r\n {{ pageLabel }} {{ currentPage }} {{ ofLabel }} {{ totalPages }}\r\n </div>\r\n <div\n v-if=\"showPageSize\"\n class=\"flex items-center justify-center sm:justify-start gap-2\"\n >\r\n <label\n class=\"text-sm text-gray-600 dark:text-gray-400 hidden sm:inline\"\n for=\"page-size\"\n >\r\n {{ itemsPerPageLabel }}\r\n </label>\r\n <select\r\n id=\"page-size\"\r\n :value=\"pageSize\"\r\n class=\"focus:border-primary focus:ring-primary rounded border border-gray-300 bg-white px-2 py-1 text-sm text-gray-900 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100\"\r\n @change=\"changePageSize\"\r\n >\r\n <option\n v-for=\"size in pageSizeOptions\"\n :key=\"size\"\n :value=\"size\"\n >\r\n {{ size }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <!-- Navigation buttons -->\r\n <div class=\"flex justify-center sm:justify-end gap-2\">\r\n <button\r\n :disabled=\"currentPage === 1 || loading\"\r\n class=\"focus:ring-primary inline-flex items-center gap-1 rounded-lg border border-gray-300 bg-white px-3 sm:px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700\"\r\n @click=\"changePage(currentPage - 1)\"\r\n >\r\n <Icon\n class=\"h-4 w-4\"\n icon=\"lucide:chevron-left\"\n />\r\n <span class=\"hidden sm:inline\">{{ previousLabel }}</span>\r\n </button>\r\n <button\r\n :disabled=\"currentPage === totalPages || loading\"\r\n class=\"focus:ring-primary inline-flex items-center gap-1 rounded-lg border border-gray-300 bg-white px-3 sm:px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700\"\r\n @click=\"changePage(currentPage + 1)\"\r\n >\r\n <span class=\"hidden sm:inline\">{{ nextLabel }}</span>\r\n <Icon\n class=\"h-4 w-4\"\n icon=\"lucide:chevron-right\"\n />\r\n </button>\r\n </div>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\nimport type { Notification } from '@/types'\nimport { computed, onMounted } from 'vue'\nimport { Icon } from '@iconify/vue'\n\nconst props = defineProps<{\n notification: Notification\n autoDismiss?: boolean\n duration?: number\n}>()\n\nconst emit = defineEmits<{\n dismiss: [id: string]\n}>()\n\nconst iconName = computed(() => {\n switch (props.notification.type) {\n case 'success':\n return 'lucide:check-circle'\n case 'info':\n return 'lucide:info'\n case 'warning':\n return 'lucide:alert-triangle'\n case 'error':\n return 'lucide:x-circle'\n default:\n return 'lucide:bell'\n }\n})\n\nconst iconColor = computed(() => {\n switch (props.notification.type) {\n case 'success':\n return 'text-green-600 dark:text-green-400'\n case 'info':\n return 'text-blue-600 dark:text-blue-400'\n case 'warning':\n return 'text-yellow-600 dark:text-yellow-400'\n case 'error':\n return 'text-red-600 dark:text-red-400'\n default:\n return 'text-gray-600 dark:text-gray-400'\n }\n})\n\nconst bgColor = computed(() => {\n switch (props.notification.type) {\n case 'success':\n return 'bg-green-50 dark:bg-green-950'\n case 'info':\n return 'bg-blue-50 dark:bg-blue-950'\n case 'warning':\n return 'bg-yellow-50 dark:bg-yellow-950'\n case 'error':\n return 'bg-red-50 dark:bg-red-950'\n default:\n return 'bg-gray-50 dark:bg-gray-950'\n }\n})\n\nconst handleDismiss = () => {\n if (props.notification.id) {\n emit('dismiss', props.notification.id)\n }\n}\n\nonMounted(() => {\n const duration = props.notification.duration ?? props.duration ?? 5000\n if (props.autoDismiss !== false && duration > 0) {\n setTimeout(() => {\n handleDismiss()\n }, duration)\n }\n})\n</script>\n\n<template>\n <div\n class=\"flex max-w-md items-start space-x-3 rounded-lg border border-gray-200 bg-white p-4 shadow-lg dark:border-gray-800 dark:bg-black\"\n >\n <div :class=\"[bgColor, 'flex items-center justify-center rounded-full p-2']\">\n <Icon\n :class=\"iconColor\"\n :icon=\"iconName\"\n class=\"h-5 w-5\"\n />\n </div>\n\n <div class=\"flex min-w-0 flex-1 flex-col\">\n <h4\n v-if=\"notification.title\"\n class=\"text-sm font-semibold text-gray-900 dark:text-gray-100\"\n >\n {{ notification.title }}\n </h4>\n <p\n v-if=\"notification.message\"\n class=\"mt-1 text-sm text-gray-600 dark:text-gray-400\"\n >\n {{ notification.message }}\n </p>\n </div>\n\n <button\n class=\"shrink-0 text-gray-400 transition-colors hover:text-gray-600 dark:text-gray-600 dark:hover:text-gray-400\"\n @click=\"handleDismiss\"\n >\n <Icon\n class=\"h-4 w-4\"\n icon=\"lucide:x\"\n />\n </button>\n </div>\n</template>\n","<script lang=\"ts\" setup>\nimport type { Notification } from '@/types'\nimport NotificationComponent from './NotificationComponent.vue'\n\ndefineProps<{\n notifications: Notification[]\n autoDismiss?: boolean\n duration?: number\n}>()\n\nconst emit = defineEmits<{\n dismiss: [id: string]\n}>()\n</script>\n\n<template>\n <div class=\"fixed top-5 right-5 z-50 flex flex-col gap-3\">\n <NotificationComponent\n v-for=\"notification in notifications\"\n :key=\"notification.id\"\n :notification=\"notification\"\n :auto-dismiss=\"autoDismiss\"\n :duration=\"duration\"\n @dismiss=\"emit('dismiss', $event)\"\n />\n </div>\n</template>\n","<script lang=\"ts\" setup>\nimport { Icon } from '@iconify/vue'\n\nexport type AlertVariant = 'info' | 'success' | 'warning' | 'error'\n\nconst props = withDefaults(\n defineProps<{\n /** Alert variant */\n variant?: AlertVariant\n /** Title text */\n title?: string\n /** Show close button */\n dismissible?: boolean\n /** Custom icon */\n icon?: string\n }>(),\n {\n variant: 'info',\n },\n)\n\nconst emit = defineEmits<{\n dismiss: []\n}>()\n\nconst variantStyles: Record<AlertVariant, { bg: string; border: string; icon: string; iconColor: string }> = {\n info: {\n bg: 'bg-blue-50 dark:bg-blue-900/20',\n border: 'border-blue-200 dark:border-blue-800',\n icon: 'lucide:info',\n iconColor: 'text-blue-500',\n },\n success: {\n bg: 'bg-green-50 dark:bg-green-900/20',\n border: 'border-green-200 dark:border-green-800',\n icon: 'lucide:check-circle',\n iconColor: 'text-green-500',\n },\n warning: {\n bg: 'bg-yellow-50 dark:bg-yellow-900/20',\n border: 'border-yellow-200 dark:border-yellow-800',\n icon: 'lucide:alert-triangle',\n iconColor: 'text-yellow-500',\n },\n error: {\n bg: 'bg-red-50 dark:bg-red-900/20',\n border: 'border-red-200 dark:border-red-800',\n icon: 'lucide:alert-circle',\n iconColor: 'text-red-500',\n },\n}\n\nconst styles = variantStyles[props.variant]\n</script>\n\n<template>\n <div\n :class=\"[\n 'flex gap-3 rounded-lg border p-4',\n styles.bg,\n styles.border,\n ]\"\n role=\"alert\"\n >\n <Icon\n :icon=\"icon || styles.icon\"\n :class=\"['size-5 shrink-0', styles.iconColor]\"\n aria-hidden=\"true\"\n />\n <div class=\"flex-1\">\n <h4\n v-if=\"title\"\n class=\"mb-1 font-medium text-gray-900 dark:text-white\"\n >\n {{ title }}\n </h4>\n <div class=\"text-sm text-gray-700 dark:text-gray-300\">\n <slot />\n </div>\n </div>\n <button\n v-if=\"dismissible\"\n type=\"button\"\n class=\"shrink-0 rounded p-1 text-gray-400 hover:bg-gray-200 hover:text-gray-600 dark:hover:bg-gray-700 dark:hover:text-gray-300\"\n aria-label=\"Dismiss alert\"\n @click=\"emit('dismiss')\"\n >\n <Icon\n icon=\"lucide:x\"\n class=\"size-4\"\n aria-hidden=\"true\"\n />\n </button>\n </div>\n</template>\n","<script lang=\"ts\" setup>\nimport { Icon } from '@iconify/vue'\n\nwithDefaults(\n defineProps<{\n /** Message to display */\n message?: string\n /** Icon name (iconify format) */\n icon?: string\n /** Title text */\n title?: string\n }>(),\n {\n message: 'No results found',\n icon: 'lucide:inbox',\n },\n)\n</script>\n\n<template>\n <div class=\"py-12 text-center\">\n <Icon\n v-if=\"icon\"\n :icon=\"icon\"\n class=\"mx-auto mb-4 size-12 text-gray-400 dark:text-gray-500\"\n />\n <h3\n v-if=\"title\"\n class=\"mb-2 text-lg font-medium text-gray-900 dark:text-white\"\n >\n {{ title }}\n </h3>\n <p class=\"text-gray-500 dark:text-gray-400\">\n <slot>{{ message }}</slot>\n </p>\n <div\n v-if=\"$slots.action\"\n class=\"mt-4\"\n >\n <slot name=\"action\" />\n </div>\n </div>\n</template>\n","<script lang=\"ts\" setup>\r\nimport { Icon } from '@iconify/vue'\r\n\r\nexport type ToastType = 'success' | 'error' | 'warning' | 'info'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Toast message */\r\n message: string\r\n /** Toast type */\r\n type?: ToastType\r\n /** Title (optional) */\r\n title?: string\r\n /** Show close button */\r\n closable?: boolean\r\n /** Duration in ms (0 = no auto-close) */\r\n duration?: number\r\n }>(),\r\n {\r\n type: 'info',\r\n closable: true,\r\n duration: 5000,\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n close: []\r\n}>()\r\n\r\nconst typeConfig: Record<ToastType, { icon: string; bg: string; iconColor: string }> = {\r\n success: {\r\n icon: 'lucide:check-circle',\r\n bg: 'bg-green-50 border-green-200 dark:bg-green-900/20 dark:border-green-800',\r\n iconColor: 'text-green-500',\r\n },\r\n error: {\r\n icon: 'lucide:x-circle',\r\n bg: 'bg-red-50 border-red-200 dark:bg-red-900/20 dark:border-red-800',\r\n iconColor: 'text-red-500',\r\n },\r\n warning: {\r\n icon: 'lucide:alert-triangle',\r\n bg: 'bg-yellow-50 border-yellow-200 dark:bg-yellow-900/20 dark:border-yellow-800',\r\n iconColor: 'text-yellow-500',\r\n },\r\n info: {\r\n icon: 'lucide:info',\r\n bg: 'bg-blue-50 border-blue-200 dark:bg-blue-900/20 dark:border-blue-800',\r\n iconColor: 'text-blue-500',\r\n },\r\n}\r\n\r\nconst config = typeConfig[props.type]\r\n\r\n// Auto-close\r\nif (props.duration > 0) {\r\n setTimeout(() => {\r\n emit('close')\r\n }, props.duration)\r\n}\r\n</script>\r\n\r\n<template>\r\n <div\r\n :class=\"[\r\n 'flex items-start gap-3 rounded-lg border p-4 shadow-lg',\r\n config.bg,\r\n ]\"\r\n role=\"alert\"\r\n >\r\n <Icon\r\n :icon=\"config.icon\"\r\n :class=\"['size-5 shrink-0', config.iconColor]\"\r\n aria-hidden=\"true\"\r\n />\r\n <div class=\"flex-1 min-w-0\">\r\n <p\r\n v-if=\"title\"\r\n class=\"font-medium text-gray-900 dark:text-white\"\r\n >\r\n {{ title }}\r\n </p>\r\n <p class=\"text-sm text-gray-700 dark:text-gray-300\">\r\n {{ message }}\r\n </p>\r\n </div>\r\n <button\r\n v-if=\"closable\"\r\n type=\"button\"\r\n class=\"shrink-0 rounded p-1 text-gray-400 hover:bg-gray-200 hover:text-gray-600 dark:hover:bg-gray-700 dark:hover:text-gray-300\"\r\n aria-label=\"Dismiss notification\"\r\n @click=\"emit('close')\"\r\n >\r\n <Icon\r\n icon=\"lucide:x\"\r\n class=\"size-4\"\r\n aria-hidden=\"true\"\r\n />\r\n </button>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { computed } from 'vue'\r\nimport Toast from './Toast.vue'\r\nimport type { ToastType } from './Toast.vue'\r\n\r\nexport interface ToastItem {\r\n id: string\r\n message: string\r\n type?: ToastType\r\n title?: string\r\n duration?: number\r\n}\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Array of toast items */\r\n toasts: ToastItem[]\r\n /** Position of the container */\r\n position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center'\r\n /** Custom top offset (e.g., '80px', '5rem') to account for fixed headers */\r\n topOffset?: string\r\n }>(),\r\n {\r\n position: 'top-right',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n close: [id: string]\r\n}>()\r\n\r\nconst positionClasses: Record<string, string> = {\r\n 'top-right': 'right-4',\r\n 'top-left': 'left-4',\r\n 'bottom-right': 'bottom-4 right-4',\r\n 'bottom-left': 'bottom-4 left-4',\r\n 'top-center': 'left-1/2 -translate-x-1/2',\r\n 'bottom-center': 'bottom-4 left-1/2 -translate-x-1/2',\r\n}\r\n\r\nconst isTopPosition = computed(() => props.position?.startsWith('top'))\r\n\r\nconst topStyle = computed(() => {\r\n if (!isTopPosition.value) return {}\r\n return { top: props.topOffset || '1rem' }\r\n})\r\n</script>\r\n\r\n<template>\r\n <Teleport to=\"body\">\r\n <div\r\n :class=\"['fixed z-[9999] flex flex-col gap-2 w-full max-w-sm', positionClasses[position]]\"\r\n :style=\"topStyle\"\r\n aria-live=\"polite\"\r\n aria-atomic=\"false\"\r\n >\r\n <TransitionGroup\r\n enter-active-class=\"transition duration-300 ease-out\"\r\n enter-from-class=\"opacity-0 translate-x-4\"\r\n enter-to-class=\"opacity-100 translate-x-0\"\r\n leave-active-class=\"transition duration-200 ease-in\"\r\n leave-from-class=\"opacity-100 translate-x-0\"\r\n leave-to-class=\"opacity-0 translate-x-4\"\r\n >\r\n <Toast\r\n v-for=\"toast in toasts\"\r\n :key=\"toast.id\"\r\n :message=\"toast.message\"\r\n :type=\"toast.type\"\r\n :title=\"toast.title\"\r\n :duration=\"toast.duration\"\r\n @close=\"emit('close', toast.id)\"\r\n />\r\n </TransitionGroup>\r\n </div>\r\n </Teleport>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { computed } from 'vue'\r\n\r\nexport type ProgressSize = 'sm' | 'md' | 'lg'\r\nexport type ProgressVariant = 'default' | 'success' | 'warning' | 'error'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Current value (0-100) */\r\n value: number\r\n /** Maximum value */\r\n max?: number\r\n /** Size variant */\r\n size?: ProgressSize\r\n /** Color variant */\r\n variant?: ProgressVariant\r\n /** Show percentage label */\r\n showLabel?: boolean\r\n /** Striped animation */\r\n striped?: boolean\r\n /** Animated stripes */\r\n animated?: boolean\r\n /** Indeterminate state (loading) */\r\n indeterminate?: boolean\r\n }>(),\r\n {\r\n max: 100,\r\n size: 'md',\r\n variant: 'default',\r\n showLabel: false,\r\n striped: false,\r\n animated: false,\r\n indeterminate: false,\r\n },\r\n)\r\n\r\nconst percentage = computed(() => {\r\n if (props.indeterminate) return 100\r\n return Math.min(Math.max((props.value / props.max) * 100, 0), 100)\r\n})\r\n\r\nconst sizeClasses: Record<ProgressSize, string> = {\r\n sm: 'h-1',\r\n md: 'h-2',\r\n lg: 'h-4',\r\n}\r\n\r\nconst variantClasses: Record<ProgressVariant, string> = {\r\n default: 'bg-primary',\r\n success: 'bg-green-500',\r\n warning: 'bg-yellow-500',\r\n error: 'bg-red-500',\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"w-full\">\r\n <div\n v-if=\"showLabel && !indeterminate\"\n class=\"mb-1 flex justify-between text-sm\"\n >\r\n <span class=\"text-gray-600 dark:text-gray-400\">Progress</span>\r\n <span class=\"font-medium text-gray-900 dark:text-white\">{{ Math.round(percentage) }}%</span>\r\n </div>\r\n <div\r\n :class=\"[\r\n 'w-full overflow-hidden rounded-full bg-gray-200 dark:bg-gray-700',\r\n sizeClasses[size],\r\n ]\"\r\n role=\"progressbar\"\r\n :aria-valuenow=\"indeterminate ? undefined : value\"\r\n :aria-valuemin=\"0\"\r\n :aria-valuemax=\"max\"\r\n >\r\n <div\r\n :class=\"[\r\n 'h-full rounded-full transition-all duration-300',\r\n variantClasses[variant],\r\n striped && 'bg-stripes',\r\n animated && 'animate-stripes',\r\n indeterminate && 'animate-indeterminate',\r\n ]\"\r\n :style=\"{ width: indeterminate ? '30%' : `${percentage}%` }\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.bg-stripes {\r\n background-image: linear-gradient(\r\n 45deg,\r\n rgba(255, 255, 255, 0.15) 25%,\r\n transparent 25%,\r\n transparent 50%,\r\n rgba(255, 255, 255, 0.15) 50%,\r\n rgba(255, 255, 255, 0.15) 75%,\r\n transparent 75%,\r\n transparent\r\n );\r\n background-size: 1rem 1rem;\r\n}\r\n\r\n.animate-stripes {\r\n animation: stripes 1s linear infinite;\r\n}\r\n\r\n@keyframes stripes {\r\n from {\r\n background-position: 1rem 0;\r\n }\r\n to {\r\n background-position: 0 0;\r\n }\r\n}\r\n\r\n.animate-indeterminate {\r\n animation: indeterminate 1.5s ease-in-out infinite;\r\n}\r\n\r\n@keyframes indeterminate {\r\n 0% {\r\n transform: translateX(-100%);\r\n }\r\n 100% {\r\n transform: translateX(400%);\r\n }\r\n}\r\n</style>\r\n","<script lang=\"ts\" setup>\r\nexport type SkeletonVariant = 'text' | 'circular' | 'rectangular' | 'rounded'\r\n\r\nwithDefaults(\r\n defineProps<{\r\n /** Variant style */\r\n variant?: SkeletonVariant\r\n /** Width (CSS value) */\r\n width?: string\r\n /** Height (CSS value) */\r\n height?: string\r\n /** Number of lines (for text variant) */\r\n lines?: number\r\n /** Animate the skeleton */\r\n animate?: boolean\r\n }>(),\r\n {\r\n variant: 'text',\r\n animate: true,\r\n lines: 1,\r\n },\r\n)\r\n\r\nconst variantClasses: Record<SkeletonVariant, string> = {\r\n text: 'h-4 rounded',\r\n circular: 'rounded-full',\r\n rectangular: '',\r\n rounded: 'rounded-lg',\r\n}\r\n</script>\r\n\r\n<template>\r\n <div\r\n v-if=\"variant === 'text' && lines > 1\"\r\n class=\"space-y-2\"\r\n aria-hidden=\"true\"\r\n >\r\n <div\r\n v-for=\"i in lines\"\r\n :key=\"i\"\r\n :class=\"[\r\n 'bg-gray-200 dark:bg-gray-700',\r\n variantClasses[variant],\r\n animate && 'animate-pulse',\r\n ]\"\r\n :style=\"{\r\n width: i === lines ? '75%' : width || '100%',\r\n height: height,\r\n }\"\r\n />\r\n </div>\r\n <div\r\n v-else\r\n :class=\"[\r\n 'bg-gray-200 dark:bg-gray-700',\r\n variantClasses[variant],\r\n animate && 'animate-pulse',\r\n ]\"\r\n :style=\"{\r\n width: width || (variant === 'circular' ? '3rem' : '100%'),\r\n height: height || (variant === 'circular' ? '3rem' : variant === 'text' ? '1rem' : '6rem'),\r\n }\"\r\n aria-hidden=\"true\"\r\n />\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nimport { Icon } from '@iconify/vue'\r\nimport Modal from './Modal.vue'\r\nimport Button from '@/components/core/Button.vue'\r\n\r\nexport type ConfirmDialogVariant = 'info' | 'warning' | 'danger' | 'success'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Whether the dialog is open */\r\n open?: boolean\r\n /** Dialog title */\r\n title?: string\r\n /** Dialog message */\r\n message?: string\r\n /** Confirm button text */\r\n confirmText?: string\r\n /** Cancel button text */\r\n cancelText?: string\r\n /** Dialog variant (affects icon and confirm button color) */\r\n variant?: ConfirmDialogVariant\r\n /** Show loading state on confirm button */\r\n loading?: boolean\r\n /** Icon to display */\r\n icon?: string\r\n /** Teleport target (e.g., 'body', '#app'). Set to false to disable teleport. */\r\n teleport?: string | false\r\n }>(),\r\n {\r\n open: false,\r\n title: 'Confirm',\r\n message: 'Are you sure you want to proceed?',\r\n confirmText: 'Confirm',\r\n cancelText: 'Cancel',\r\n variant: 'info',\r\n loading: false,\r\n teleport: 'body',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n confirm: []\r\n cancel: []\r\n}>()\r\n\r\nconst variantConfig: Record<ConfirmDialogVariant, { icon: string; iconClass: string; buttonVariant: 'primary' | 'danger' | 'success' }> = {\r\n info: {\r\n icon: 'lucide:info',\r\n iconClass: 'text-blue-500',\r\n buttonVariant: 'primary',\r\n },\r\n warning: {\r\n icon: 'lucide:alert-triangle',\r\n iconClass: 'text-yellow-500',\r\n buttonVariant: 'primary',\r\n },\r\n danger: {\r\n icon: 'lucide:alert-circle',\r\n iconClass: 'text-red-500',\r\n buttonVariant: 'danger',\r\n },\r\n success: {\r\n icon: 'lucide:check-circle',\r\n iconClass: 'text-green-500',\r\n buttonVariant: 'success',\r\n },\r\n}\r\n\r\nconst config = variantConfig[props.variant]\r\n</script>\r\n\r\n<template>\r\n <Modal\r\n v-if=\"open\"\r\n size=\"sm\"\r\n :close-on-backdrop=\"!loading\"\r\n :close-on-escape=\"!loading\"\r\n :teleport=\"teleport\"\r\n @close=\"emit('cancel')\"\r\n >\r\n <div class=\"text-center\">\r\n <!-- Icon -->\r\n <div class=\"mx-auto mb-4 flex h-14 w-14 items-center justify-center rounded-full bg-gray-100 dark:bg-gray-800\">\r\n <Icon\r\n :icon=\"icon || config.icon\"\r\n :class=\"[config.iconClass, 'h-8 w-8']\"\r\n />\r\n </div>\r\n\r\n <!-- Title -->\r\n <h3 class=\"mb-2 text-lg font-semibold text-gray-900 dark:text-gray-100\">\r\n {{ title }}\r\n </h3>\r\n\r\n <!-- Message -->\r\n <p class=\"mb-6 text-gray-600 dark:text-gray-400\">\r\n <slot>{{ message }}</slot>\r\n </p>\r\n\r\n <!-- Actions -->\r\n <div class=\"flex justify-center gap-3\">\r\n <Button\r\n variant=\"outline\"\r\n :disabled=\"loading\"\r\n @click=\"emit('cancel')\"\r\n >\r\n {{ cancelText }}\r\n </Button>\r\n <Button\r\n :variant=\"config.buttonVariant\"\r\n :loading=\"loading\"\r\n @click=\"emit('confirm')\"\r\n >\r\n {{ confirmText }}\r\n </Button>\r\n </div>\r\n </div>\r\n </Modal>\r\n</template>\r\n"],"names":["computed","_createElementBlock","_createElementVNode","_hoisted_2","_normalizeClass","_hoisted_3","_toDisplayString","_hoisted_4","useId","ref","useFocusTrap","onMounted","onUnmounted","_createBlock","_Teleport","_unref","$slots","_openBlock","_renderSlot","_createVNode","Icon","_hoisted_5","_hoisted_6","_hoisted_1","_Fragment","_renderList","NotificationComponent","_TransitionGroup","Toast","_normalizeStyle","Modal","Button"],"mappings":"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"}