cisse-vue-ui 0.8.4 → 0.10.0

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 (147) hide show
  1. package/README.md +666 -4
  2. package/dist/{CheckboxGroup.vue_vue_type_script_setup_true_lang-B190Yija.js → CheckboxGroup.vue_vue_type_script_setup_true_lang-ZP02bMgY.js} +2 -2
  3. package/dist/{CheckboxGroup.vue_vue_type_script_setup_true_lang-B190Yija.js.map → CheckboxGroup.vue_vue_type_script_setup_true_lang-ZP02bMgY.js.map} +1 -1
  4. package/dist/{ConfirmDialog.vue_vue_type_script_setup_true_lang-DWs2V7xX.js → ConfirmDialog.vue_vue_type_script_setup_true_lang-C5KHLMvx.js} +37 -184
  5. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-C5KHLMvx.js.map +1 -0
  6. package/dist/{ConfirmDialog.vue_vue_type_script_setup_true_lang-BGUoa5fT.cjs → ConfirmDialog.vue_vue_type_script_setup_true_lang-CLfy0-Wb.cjs} +33 -180
  7. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-CLfy0-Wb.cjs.map +1 -0
  8. package/dist/{FilterTabs.vue_vue_type_script_setup_true_lang-BmJHgkBs.js → FilterTabs.vue_vue_type_script_setup_true_lang-CJnvcF8Z.js} +1568 -384
  9. package/dist/FilterTabs.vue_vue_type_script_setup_true_lang-CJnvcF8Z.js.map +1 -0
  10. package/dist/{FilterTabs.vue_vue_type_script_setup_true_lang-DYxh-wFx.cjs → FilterTabs.vue_vue_type_script_setup_true_lang-l8lJzwoY.cjs} +1564 -380
  11. package/dist/FilterTabs.vue_vue_type_script_setup_true_lang-l8lJzwoY.cjs.map +1 -0
  12. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-BHopJ9RG.js +298 -0
  13. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-BHopJ9RG.js.map +1 -0
  14. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-Bo3HqgX0.cjs +297 -0
  15. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-Bo3HqgX0.cjs.map +1 -0
  16. package/dist/components/core/Breadcrumb.stories.d.ts +5 -0
  17. package/dist/components/core/CardWrapper.stories.d.ts +32 -0
  18. package/dist/components/core/CardWrapper.vue.d.ts +129 -0
  19. package/dist/components/core/CollapsibleCard.vue.d.ts +1 -1
  20. package/dist/components/core/DataTable.stories.d.ts +38 -0
  21. package/dist/components/core/Dropdown.vue.d.ts +1 -1
  22. package/dist/components/core/Popover.vue.d.ts +2 -2
  23. package/dist/components/core/StatItem.stories.d.ts +25 -0
  24. package/dist/components/core/StatItem.test.d.ts +1 -0
  25. package/dist/components/core/StatItem.vue.d.ts +81 -0
  26. package/dist/components/core/Stats.stories.d.ts +24 -0
  27. package/dist/components/core/Stats.test.d.ts +1 -0
  28. package/dist/components/core/Stats.vue.d.ts +41 -0
  29. package/dist/components/core/Tooltip.stories.d.ts +3 -0
  30. package/dist/components/core/index.cjs +41 -22
  31. package/dist/components/core/index.cjs.map +1 -1
  32. package/dist/components/core/index.d.ts +10 -4
  33. package/dist/components/core/index.js +41 -22
  34. package/dist/components/core/table/DataTable.test.d.ts +1 -0
  35. package/dist/components/core/{TableComponent.vue.d.ts → table/DataTable.vue.d.ts} +60 -7
  36. package/dist/components/core/table/Table.stories.d.ts +27 -0
  37. package/dist/components/core/table/atoms/Caption.test.d.ts +1 -0
  38. package/dist/components/core/table/atoms/Caption.vue.d.ts +26 -0
  39. package/dist/components/core/table/atoms/Col.test.d.ts +1 -0
  40. package/dist/components/core/table/atoms/Col.vue.d.ts +8 -0
  41. package/dist/components/core/table/atoms/Colgroup.test.d.ts +1 -0
  42. package/dist/components/core/table/atoms/Colgroup.vue.d.ts +17 -0
  43. package/dist/components/core/table/atoms/Table.test.d.ts +1 -0
  44. package/dist/components/core/table/atoms/Table.vue.d.ts +46 -0
  45. package/dist/components/core/table/atoms/Tbody.test.d.ts +1 -0
  46. package/dist/components/core/table/atoms/Tbody.vue.d.ts +17 -0
  47. package/dist/components/core/table/atoms/Td.test.d.ts +1 -0
  48. package/dist/components/core/table/atoms/Td.vue.d.ts +43 -0
  49. package/dist/components/core/table/atoms/Tfoot.test.d.ts +1 -0
  50. package/dist/components/core/table/atoms/Tfoot.vue.d.ts +17 -0
  51. package/dist/components/core/table/atoms/Th.test.d.ts +1 -0
  52. package/dist/components/core/table/atoms/Th.vue.d.ts +64 -0
  53. package/dist/components/core/table/atoms/Thead.test.d.ts +1 -0
  54. package/dist/components/core/table/atoms/Thead.vue.d.ts +17 -0
  55. package/dist/components/core/table/atoms/Tr.test.d.ts +1 -0
  56. package/dist/components/core/table/atoms/Tr.vue.d.ts +35 -0
  57. package/dist/components/core/table/atoms/index.d.ts +10 -0
  58. package/dist/components/core/table/index.d.ts +3 -0
  59. package/dist/components/core/table/molecules/ExpandableRow.test.d.ts +1 -0
  60. package/dist/components/core/table/molecules/ExpandableRow.vue.d.ts +47 -0
  61. package/dist/components/core/table/molecules/TableFooter.test.d.ts +1 -0
  62. package/dist/components/core/table/molecules/TableFooter.vue.d.ts +21 -0
  63. package/dist/components/core/table/molecules/TableHeader.test.d.ts +1 -0
  64. package/dist/components/core/table/molecules/TableHeader.vue.d.ts +49 -0
  65. package/dist/components/core/table/molecules/TableRow.test.d.ts +1 -0
  66. package/dist/components/core/table/molecules/TableRow.vue.d.ts +59 -0
  67. package/dist/components/core/table/molecules/index.d.ts +4 -0
  68. package/dist/components/feedback/Progress.vue.d.ts +1 -1
  69. package/dist/components/feedback/TableSkeleton.vue.d.ts +1 -1
  70. package/dist/components/feedback/index.cjs +14 -14
  71. package/dist/components/feedback/index.js +14 -14
  72. package/dist/components/form/Combobox.vue.d.ts +1 -1
  73. package/dist/components/form/DatePicker.vue.d.ts +1 -1
  74. package/dist/components/form/FormSection.vue.d.ts +1 -1
  75. package/dist/components/form/IconPicker.stories.d.ts +19 -0
  76. package/dist/components/form/IconPicker.test.d.ts +1 -0
  77. package/dist/components/form/InputWrapper.stories.d.ts +0 -5
  78. package/dist/components/form/Rating.vue.d.ts +1 -1
  79. package/dist/components/form/SearchInput.vue.d.ts +1 -1
  80. package/dist/components/form/index.js +2 -2
  81. package/dist/components/index.cjs +55 -36
  82. package/dist/components/index.cjs.map +1 -1
  83. package/dist/components/index.js +67 -48
  84. package/dist/composables/index.cjs +15 -8
  85. package/dist/composables/index.cjs.map +1 -1
  86. package/dist/composables/index.d.ts +7 -0
  87. package/dist/composables/index.js +12 -5
  88. package/dist/composables/useColumnResize.d.ts +38 -0
  89. package/dist/composables/useColumnResize.test.d.ts +1 -0
  90. package/dist/composables/useColumnVisibility.d.ts +44 -0
  91. package/dist/composables/useColumnVisibility.test.d.ts +1 -0
  92. package/dist/composables/useEditableCell.d.ts +51 -0
  93. package/dist/composables/useEditableCell.test.d.ts +1 -0
  94. package/dist/composables/usePagination.d.ts +44 -0
  95. package/dist/composables/usePagination.test.d.ts +1 -0
  96. package/dist/composables/usePinnedRows.d.ts +41 -0
  97. package/dist/composables/usePinnedRows.test.d.ts +1 -0
  98. package/dist/composables/useTableKeyboardNavigation.d.ts +52 -0
  99. package/dist/composables/useTableKeyboardNavigation.test.d.ts +1 -0
  100. package/dist/composables/useVirtualScroll.d.ts +32 -0
  101. package/dist/composables/useVirtualScroll.test.d.ts +1 -0
  102. package/dist/{index-SNefWfX0.js → index-BaWpldIJ.js} +3 -3
  103. package/dist/{index-SNefWfX0.js.map → index-BaWpldIJ.js.map} +1 -1
  104. package/dist/{index-LFQFhClN.cjs → index-CYXOfUOG.cjs} +56 -37
  105. package/dist/{index-LFQFhClN.cjs.map → index-CYXOfUOG.cjs.map} +1 -1
  106. package/dist/index-C_N7WRnM.js +116 -0
  107. package/dist/index-C_N7WRnM.js.map +1 -0
  108. package/dist/index.cjs +71 -45
  109. package/dist/index.cjs.map +1 -1
  110. package/dist/index.js +81 -55
  111. package/dist/style.css +1 -1
  112. package/dist/types/components.d.ts +1 -1
  113. package/dist/types/property.d.ts +8 -0
  114. package/dist/usePagination-BGwbICFC.js +135 -0
  115. package/dist/usePagination-BGwbICFC.js.map +1 -0
  116. package/dist/usePagination-gvvh1zqA.cjs +134 -0
  117. package/dist/usePagination-gvvh1zqA.cjs.map +1 -0
  118. package/dist/useVirtualScroll-BivP86fA.cjs +869 -0
  119. package/dist/useVirtualScroll-BivP86fA.cjs.map +1 -0
  120. package/dist/useVirtualScroll-YeZru2Eo.js +870 -0
  121. package/dist/useVirtualScroll-YeZru2Eo.js.map +1 -0
  122. package/package.json +1 -1
  123. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-BGUoa5fT.cjs.map +0 -1
  124. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-DWs2V7xX.js.map +0 -1
  125. package/dist/FilterTabs.vue_vue_type_script_setup_true_lang-BmJHgkBs.js.map +0 -1
  126. package/dist/FilterTabs.vue_vue_type_script_setup_true_lang-DYxh-wFx.cjs.map +0 -1
  127. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-BwtEbaiT.js +0 -150
  128. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-BwtEbaiT.js.map +0 -1
  129. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-DtwwmfWr.cjs +0 -149
  130. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-DtwwmfWr.cjs.map +0 -1
  131. package/dist/components/core/StatsCard.stories.d.ts +0 -15
  132. package/dist/components/core/StatsCard.vue.d.ts +0 -44
  133. package/dist/components/core/StatsGrid.stories.d.ts +0 -12
  134. package/dist/components/core/StatsGrid.vue.d.ts +0 -16
  135. package/dist/components/core/TableComponent.stories.d.ts +0 -16
  136. package/dist/index-CyL_6V7D.js +0 -97
  137. package/dist/index-CyL_6V7D.js.map +0 -1
  138. package/dist/useDarkMode-Cl5QWTlC.js +0 -53
  139. package/dist/useDarkMode-Cl5QWTlC.js.map +0 -1
  140. package/dist/useDarkMode-DLZcJEUQ.cjs +0 -52
  141. package/dist/useDarkMode-DLZcJEUQ.cjs.map +0 -1
  142. package/dist/useToast-Bk60GArg.cjs +0 -176
  143. package/dist/useToast-Bk60GArg.cjs.map +0 -1
  144. package/dist/useToast-ina5g3mj.js +0 -177
  145. package/dist/useToast-ina5g3mj.js.map +0 -1
  146. /package/dist/components/core/{StatsCard.test.d.ts → AccordionItem.test.d.ts} +0 -0
  147. /package/dist/components/core/{StatsGrid.test.d.ts → CardWrapper.test.d.ts} +0 -0
@@ -1,117 +1,1129 @@
1
- import { defineComponent, computed, createBlock, createElementBlock, openBlock, createCommentVNode, renderSlot, normalizeClass, createElementVNode, createTextVNode, toDisplayString, useSlots, createVNode, Fragment, renderList, resolveDynamicComponent, withCtx, createSlots, ref, watch, unref, withDirectives, vModelText, withModifiers, Teleport, Transition, normalizeStyle, nextTick, resolveComponent, mergeProps, provide, inject, vShow, onMounted, onUnmounted, mergeModels, useModel } from "vue";
2
- import { _ as _sfc_main$o, u as useBreakpoints } from "./index-SNefWfX0.js";
3
- import { a as _sfc_main$m, _ as _sfc_main$n, b as _sfc_main$u } from "./ListSkeleton.vue_vue_type_script_setup_true_lang-BwtEbaiT.js";
4
- import { e as _sfc_main$p, d as _sfc_main$q, c as _sfc_main$r, b as _sfc_main$s, a as _sfc_main$t } from "./BadgeType.vue_vue_type_script_setup_true_lang-tHRMWBb-.js";
1
+ import { defineComponent, computed, createBlock, createElementBlock, openBlock, createCommentVNode, renderSlot, normalizeClass, createElementVNode, createTextVNode, toDisplayString, useSlots, withKeys, withModifiers, normalizeStyle, unref, useAttrs, toRefs, provide, reactive, mergeProps, normalizeProps, guardReactiveProps, inject, Fragment, withCtx, createVNode, renderList, resolveDynamicComponent, ref, createSlots, watch, withDirectives, vModelText, Teleport, Transition, nextTick, resolveComponent, vShow, onMounted, onUnmounted, mergeModels, useModel } from "vue";
2
+ import { _ as _sfc_main$C, a as useBreakpoints } from "./index-BaWpldIJ.js";
3
+ import { b as _sfc_main$B, a as _sfc_main$I, _ as _sfc_main$J, c as _sfc_main$K } from "./ListSkeleton.vue_vue_type_script_setup_true_lang-BHopJ9RG.js";
4
+ import { e as _sfc_main$D, d as _sfc_main$E, c as _sfc_main$F, b as _sfc_main$G, a as _sfc_main$H } from "./BadgeType.vue_vue_type_script_setup_true_lang-tHRMWBb-.js";
5
+ import { a as usePagination, u as useDarkMode } from "./usePagination-BGwbICFC.js";
5
6
  import { Icon } from "@iconify/vue";
6
7
  import { u as useDropdown } from "./useDropdown-XITCE_SM.js";
7
8
  import { u as useId } from "./useId-xeHj7rkg.js";
8
- import { u as useDarkMode } from "./useDarkMode-Cl5QWTlC.js";
9
- const _hoisted_1$h = {
9
+ const _hoisted_1$o = {
10
10
  key: 1,
11
11
  class: "flex flex-col overflow-hidden rounded-lg bg-white shadow-md dark:bg-slate-950"
12
12
  };
13
- const _hoisted_2$d = { class: "flex flex-col gap-0.5" };
14
- const _hoisted_3$8 = {
13
+ const _hoisted_2$h = { class: "flex flex-col gap-0.5" };
14
+ const _hoisted_3$a = {
15
15
  key: 1,
16
16
  class: "text-sm font-normal text-gray-600 dark:text-gray-400"
17
17
  };
18
- const _hoisted_4$6 = { class: "flex gap-2" };
18
+ const _hoisted_4$7 = { class: "flex gap-2" };
19
+ const _sfc_main$A = /* @__PURE__ */ defineComponent({
20
+ __name: "CardComponent",
21
+ props: {
22
+ title: {},
23
+ description: {},
24
+ titleClass: {},
25
+ dividerClass: {},
26
+ loading: { type: Boolean, default: false },
27
+ loadingLines: { default: 3 },
28
+ loadingAvatar: { type: Boolean, default: false },
29
+ loadingActions: { type: Boolean, default: false }
30
+ },
31
+ setup(__props) {
32
+ const props = __props;
33
+ const titleClasses = computed(
34
+ () => props.titleClass || "text-gray-800 dark:text-gray-200"
35
+ );
36
+ const dividerClasses = computed(
37
+ () => props.dividerClass || "border-gray-200 dark:border-gray-700"
38
+ );
39
+ return (_ctx, _cache) => {
40
+ return __props.loading ? (openBlock(), createBlock(_sfc_main$B, {
41
+ key: 0,
42
+ lines: __props.loadingLines,
43
+ "show-avatar": __props.loadingAvatar,
44
+ "show-actions": __props.loadingActions
45
+ }, null, 8, ["lines", "show-avatar", "show-actions"])) : (openBlock(), createElementBlock("div", _hoisted_1$o, [
46
+ _ctx.$slots.header ? (openBlock(), createElementBlock("div", {
47
+ key: 0,
48
+ class: normalizeClass(["border-b", dividerClasses.value])
49
+ }, [
50
+ renderSlot(_ctx.$slots, "header")
51
+ ], 2)) : __props.title || __props.description || _ctx.$slots.title || _ctx.$slots.description || _ctx.$slots.actions ? (openBlock(), createElementBlock("div", {
52
+ key: 1,
53
+ class: normalizeClass(["flex items-center justify-between border-b px-5 py-3", dividerClasses.value])
54
+ }, [
55
+ createElementVNode("div", _hoisted_2$h, [
56
+ __props.title || _ctx.$slots.title ? (openBlock(), createElementBlock("span", {
57
+ key: 0,
58
+ class: normalizeClass(["text-md font-semibold", titleClasses.value])
59
+ }, [
60
+ renderSlot(_ctx.$slots, "title", {}, () => [
61
+ createTextVNode(toDisplayString(__props.title), 1)
62
+ ])
63
+ ], 2)) : createCommentVNode("", true),
64
+ __props.description || _ctx.$slots.description ? (openBlock(), createElementBlock("span", _hoisted_3$a, [
65
+ renderSlot(_ctx.$slots, "description", {}, () => [
66
+ createTextVNode(toDisplayString(__props.description), 1)
67
+ ])
68
+ ])) : createCommentVNode("", true)
69
+ ]),
70
+ createElementVNode("div", _hoisted_4$7, [
71
+ renderSlot(_ctx.$slots, "actions")
72
+ ])
73
+ ], 2)) : createCommentVNode("", true),
74
+ renderSlot(_ctx.$slots, "default")
75
+ ]));
76
+ };
77
+ }
78
+ });
79
+ const _hoisted_1$n = ["role", "tabindex", "onKeydown"];
80
+ const _hoisted_2$g = ["src", "alt"];
81
+ const _hoisted_3$9 = ["src", "alt"];
82
+ const _hoisted_4$6 = { class: "flex items-center gap-3" };
83
+ const _hoisted_5$4 = { class: "flex flex-col gap-0.5" };
84
+ const _hoisted_6$3 = ["src", "alt"];
85
+ const _sfc_main$z = /* @__PURE__ */ defineComponent({
86
+ __name: "CardWrapper",
87
+ props: {
88
+ title: {},
89
+ description: {},
90
+ icon: {},
91
+ shadow: { default: "md" },
92
+ rounded: { default: "lg" },
93
+ padding: { default: "none" },
94
+ headerPadding: { default: "md" },
95
+ border: { default: "none" },
96
+ variant: { default: "default" },
97
+ accent: { default: "none" },
98
+ headerDivider: { type: Boolean, default: true },
99
+ footerDivider: { type: Boolean, default: true },
100
+ clickable: { type: Boolean, default: false },
101
+ selected: { type: Boolean, default: false },
102
+ disabled: { type: Boolean, default: false },
103
+ image: {},
104
+ imageAlt: {},
105
+ imagePosition: { default: "top" },
106
+ imageHeight: { default: "200px" },
107
+ imageWidth: { default: "200px" },
108
+ loading: { type: Boolean, default: false },
109
+ loadingLines: { default: 3 },
110
+ loadingAvatar: { type: Boolean, default: false },
111
+ loadingActions: { type: Boolean, default: false },
112
+ cardClass: {},
113
+ headerClass: {},
114
+ titleClass: {},
115
+ descriptionClass: {},
116
+ iconClass: {},
117
+ iconElementClass: {},
118
+ contentClass: {},
119
+ footerClass: {},
120
+ dividerClass: {},
121
+ actionsClass: {},
122
+ imageClass: {}
123
+ },
124
+ emits: ["click"],
125
+ setup(__props, { emit: __emit }) {
126
+ const props = __props;
127
+ const emit = __emit;
128
+ const slots = useSlots();
129
+ const hasHeader = computed(
130
+ () => props.title || props.description || props.icon || slots.header || slots.title || slots.description || slots.icon || slots.actions
131
+ );
132
+ const hasFooter = computed(() => !!slots.footer);
133
+ const hasImage = computed(() => !!props.image || !!slots.image);
134
+ const isHorizontal = computed(() => props.imagePosition === "left" || props.imagePosition === "right");
135
+ const shadowClasses = computed(() => {
136
+ const map = {
137
+ none: "",
138
+ sm: "shadow-sm",
139
+ md: "shadow-md",
140
+ lg: "shadow-lg",
141
+ xl: "shadow-xl"
142
+ };
143
+ return map[props.shadow];
144
+ });
145
+ const roundedClasses = computed(() => {
146
+ const map = {
147
+ none: "rounded-none",
148
+ sm: "rounded-sm",
149
+ md: "rounded-md",
150
+ lg: "rounded-lg",
151
+ xl: "rounded-xl",
152
+ full: "rounded-3xl"
153
+ };
154
+ return map[props.rounded];
155
+ });
156
+ const paddingClasses = computed(() => {
157
+ const map = {
158
+ none: "",
159
+ sm: "p-3",
160
+ md: "p-5",
161
+ lg: "p-6"
162
+ };
163
+ return map[props.padding];
164
+ });
165
+ const headerPaddingClasses = computed(() => {
166
+ const map = {
167
+ none: "",
168
+ sm: "px-3 py-2",
169
+ md: "px-5 py-3",
170
+ lg: "px-6 py-4"
171
+ };
172
+ return map[props.headerPadding];
173
+ });
174
+ const footerPaddingClasses = computed(() => {
175
+ const map = {
176
+ none: "",
177
+ sm: "px-3 py-2",
178
+ md: "px-5 py-3",
179
+ lg: "px-6 py-4"
180
+ };
181
+ return map[props.headerPadding];
182
+ });
183
+ const borderClasses = computed(() => {
184
+ const map = {
185
+ none: "",
186
+ default: "border border-gray-200 dark:border-gray-700",
187
+ primary: "border border-primary-500 dark:border-primary-400",
188
+ secondary: "border border-secondary-500 dark:border-secondary-400"
189
+ };
190
+ return map[props.border];
191
+ });
192
+ const variantClasses = computed(() => {
193
+ const map = {
194
+ default: "bg-white dark:bg-slate-950",
195
+ glass: "bg-white/15 backdrop-blur-sm",
196
+ outline: "bg-transparent",
197
+ flat: "bg-gray-50 dark:bg-slate-900"
198
+ };
199
+ return map[props.variant];
200
+ });
201
+ const accentClasses = computed(() => {
202
+ if (props.accent === "none") return "";
203
+ const colorMap = {
204
+ primary: "border-primary-500",
205
+ secondary: "border-secondary-500",
206
+ success: "border-emerald-500",
207
+ warning: "border-amber-500",
208
+ danger: "border-red-500",
209
+ info: "border-blue-500"
210
+ };
211
+ const position = isHorizontal.value ? "border-l-4" : "border-t-4";
212
+ return `${position} ${colorMap[props.accent]}`;
213
+ });
214
+ const interactiveClasses = computed(() => {
215
+ if (props.disabled) {
216
+ return "opacity-60 cursor-not-allowed";
217
+ }
218
+ if (props.clickable) {
219
+ return "cursor-pointer transition-all duration-200 hover:shadow-lg hover:-translate-y-0.5 active:translate-y-0 active:shadow-md";
220
+ }
221
+ return "";
222
+ });
223
+ const selectedClasses = computed(() => {
224
+ if (!props.selected) return "";
225
+ return "ring-2 ring-primary-500 ring-offset-2 dark:ring-offset-slate-900";
226
+ });
227
+ const computedDividerClass = computed(
228
+ () => props.dividerClass || "border-gray-200 dark:border-gray-700"
229
+ );
230
+ const computedTitleClass = computed(
231
+ () => props.titleClass || "text-gray-800 dark:text-gray-200"
232
+ );
233
+ const computedDescriptionClass = computed(
234
+ () => props.descriptionClass || "text-gray-600 dark:text-gray-400"
235
+ );
236
+ const computedIconClass = computed(
237
+ () => props.iconClass || "flex items-center justify-center size-10 rounded-lg bg-primary-100 dark:bg-primary-900/30"
238
+ );
239
+ const computedIconElementClass = computed(
240
+ () => props.iconElementClass || "size-5 text-primary-600 dark:text-primary-400"
241
+ );
242
+ const imageContainerClasses = computed(() => {
243
+ const base = "overflow-hidden flex-shrink-0";
244
+ switch (props.imagePosition) {
245
+ case "left":
246
+ return `${base} rounded-l-lg`;
247
+ case "right":
248
+ return `${base} rounded-r-lg`;
249
+ case "top":
250
+ return `${base} rounded-t-lg`;
251
+ case "bottom":
252
+ return `${base} rounded-b-lg`;
253
+ case "background":
254
+ return "absolute inset-0";
255
+ default:
256
+ return base;
257
+ }
258
+ });
259
+ const imageStyle = computed(() => {
260
+ if (props.imagePosition === "background") {
261
+ return {};
262
+ }
263
+ if (isHorizontal.value) {
264
+ return { width: props.imageWidth };
265
+ }
266
+ return { height: props.imageHeight };
267
+ });
268
+ const handleClick = (event) => {
269
+ if (props.disabled) return;
270
+ if (props.clickable) {
271
+ emit("click", event);
272
+ }
273
+ };
274
+ return (_ctx, _cache) => {
275
+ return __props.loading ? (openBlock(), createBlock(_sfc_main$B, {
276
+ key: 0,
277
+ lines: __props.loadingLines,
278
+ "show-avatar": __props.loadingAvatar,
279
+ "show-actions": __props.loadingActions
280
+ }, null, 8, ["lines", "show-avatar", "show-actions"])) : (openBlock(), createElementBlock("div", {
281
+ key: 1,
282
+ class: normalizeClass([
283
+ "overflow-hidden relative",
284
+ isHorizontal.value ? "flex" : "flex flex-col",
285
+ __props.imagePosition === "right" && "flex-row-reverse",
286
+ shadowClasses.value,
287
+ roundedClasses.value,
288
+ borderClasses.value,
289
+ variantClasses.value,
290
+ accentClasses.value,
291
+ interactiveClasses.value,
292
+ selectedClasses.value,
293
+ __props.cardClass
294
+ ]),
295
+ role: __props.clickable ? "button" : void 0,
296
+ tabindex: __props.clickable && !__props.disabled ? 0 : void 0,
297
+ onClick: handleClick,
298
+ onKeydown: [
299
+ withKeys(handleClick, ["enter"]),
300
+ withKeys(withModifiers(handleClick, ["prevent"]), ["space"])
301
+ ]
302
+ }, [
303
+ hasImage.value && __props.imagePosition === "background" ? (openBlock(), createElementBlock("div", {
304
+ key: 0,
305
+ class: normalizeClass(imageContainerClasses.value)
306
+ }, [
307
+ renderSlot(_ctx.$slots, "image", {}, () => [
308
+ __props.image ? (openBlock(), createElementBlock("img", {
309
+ key: 0,
310
+ src: __props.image,
311
+ alt: __props.imageAlt || "",
312
+ class: normalizeClass(["w-full h-full object-cover", __props.imageClass])
313
+ }, null, 10, _hoisted_2$g)) : createCommentVNode("", true)
314
+ ]),
315
+ _cache[0] || (_cache[0] = createElementVNode("div", { class: "absolute inset-0 bg-gradient-to-t from-black/60 to-transparent" }, null, -1))
316
+ ], 2)) : createCommentVNode("", true),
317
+ hasImage.value && (__props.imagePosition === "left" || __props.imagePosition === "top") ? (openBlock(), createElementBlock("div", {
318
+ key: 1,
319
+ class: normalizeClass(imageContainerClasses.value),
320
+ style: normalizeStyle(imageStyle.value)
321
+ }, [
322
+ renderSlot(_ctx.$slots, "image", {}, () => [
323
+ __props.image ? (openBlock(), createElementBlock("img", {
324
+ key: 0,
325
+ src: __props.image,
326
+ alt: __props.imageAlt || "",
327
+ class: normalizeClass(["w-full h-full object-cover", __props.imageClass])
328
+ }, null, 10, _hoisted_3$9)) : createCommentVNode("", true)
329
+ ])
330
+ ], 6)) : createCommentVNode("", true),
331
+ createElementVNode("div", {
332
+ class: normalizeClass(["flex flex-col flex-1 min-w-0", __props.imagePosition === "background" && "relative z-10"])
333
+ }, [
334
+ _ctx.$slots.header ? (openBlock(), createElementBlock("div", {
335
+ key: 0,
336
+ class: normalizeClass([
337
+ __props.headerDivider && "border-b",
338
+ computedDividerClass.value,
339
+ __props.headerClass
340
+ ])
341
+ }, [
342
+ renderSlot(_ctx.$slots, "header")
343
+ ], 2)) : hasHeader.value ? (openBlock(), createElementBlock("div", {
344
+ key: 1,
345
+ class: normalizeClass([
346
+ "flex items-center justify-between gap-4",
347
+ headerPaddingClasses.value,
348
+ __props.headerDivider && "border-b",
349
+ computedDividerClass.value,
350
+ __props.headerClass,
351
+ __props.imagePosition === "background" && "text-white border-white/20"
352
+ ])
353
+ }, [
354
+ createElementVNode("div", _hoisted_4$6, [
355
+ __props.icon || _ctx.$slots.icon ? (openBlock(), createElementBlock("div", {
356
+ key: 0,
357
+ class: normalizeClass(computedIconClass.value)
358
+ }, [
359
+ renderSlot(_ctx.$slots, "icon", {}, () => [
360
+ __props.icon ? (openBlock(), createBlock(unref(Icon), {
361
+ key: 0,
362
+ icon: __props.icon,
363
+ class: normalizeClass(computedIconElementClass.value)
364
+ }, null, 8, ["icon", "class"])) : createCommentVNode("", true)
365
+ ])
366
+ ], 2)) : createCommentVNode("", true),
367
+ createElementVNode("div", _hoisted_5$4, [
368
+ __props.title || _ctx.$slots.title ? (openBlock(), createElementBlock("span", {
369
+ key: 0,
370
+ class: normalizeClass([
371
+ "text-md font-semibold",
372
+ __props.imagePosition === "background" ? "text-white" : computedTitleClass.value
373
+ ])
374
+ }, [
375
+ renderSlot(_ctx.$slots, "title", {}, () => [
376
+ createTextVNode(toDisplayString(__props.title), 1)
377
+ ])
378
+ ], 2)) : createCommentVNode("", true),
379
+ __props.description || _ctx.$slots.description ? (openBlock(), createElementBlock("span", {
380
+ key: 1,
381
+ class: normalizeClass([
382
+ "text-sm font-normal",
383
+ __props.imagePosition === "background" ? "text-white/80" : computedDescriptionClass.value
384
+ ])
385
+ }, [
386
+ renderSlot(_ctx.$slots, "description", {}, () => [
387
+ createTextVNode(toDisplayString(__props.description), 1)
388
+ ])
389
+ ], 2)) : createCommentVNode("", true)
390
+ ])
391
+ ]),
392
+ _ctx.$slots.actions ? (openBlock(), createElementBlock("div", {
393
+ key: 0,
394
+ class: normalizeClass(["flex gap-2", __props.actionsClass])
395
+ }, [
396
+ renderSlot(_ctx.$slots, "actions")
397
+ ], 2)) : createCommentVNode("", true)
398
+ ], 2)) : createCommentVNode("", true),
399
+ createElementVNode("div", {
400
+ class: normalizeClass(["flex-1", paddingClasses.value, __props.contentClass])
401
+ }, [
402
+ renderSlot(_ctx.$slots, "default")
403
+ ], 2),
404
+ hasFooter.value ? (openBlock(), createElementBlock("div", {
405
+ key: 2,
406
+ class: normalizeClass([
407
+ __props.footerDivider && "border-t",
408
+ computedDividerClass.value,
409
+ footerPaddingClasses.value,
410
+ __props.footerClass,
411
+ __props.imagePosition === "background" && "text-white border-white/20"
412
+ ])
413
+ }, [
414
+ renderSlot(_ctx.$slots, "footer")
415
+ ], 2)) : createCommentVNode("", true)
416
+ ], 2),
417
+ hasImage.value && (__props.imagePosition === "right" || __props.imagePosition === "bottom") ? (openBlock(), createElementBlock("div", {
418
+ key: 2,
419
+ class: normalizeClass(imageContainerClasses.value),
420
+ style: normalizeStyle(imageStyle.value)
421
+ }, [
422
+ renderSlot(_ctx.$slots, "image", {}, () => [
423
+ __props.image ? (openBlock(), createElementBlock("img", {
424
+ key: 0,
425
+ src: __props.image,
426
+ alt: __props.imageAlt || "",
427
+ class: normalizeClass(["w-full h-full object-cover", __props.imageClass])
428
+ }, null, 10, _hoisted_6$3)) : createCommentVNode("", true)
429
+ ])
430
+ ], 6)) : createCommentVNode("", true)
431
+ ], 42, _hoisted_1$n));
432
+ };
433
+ }
434
+ });
435
+ const _hoisted_1$m = { class: "overflow-x-auto" };
436
+ const TableContextKey = Symbol("TableContext");
437
+ const _sfc_main$y = /* @__PURE__ */ defineComponent({
438
+ ...{
439
+ inheritAttrs: false
440
+ },
441
+ __name: "Table",
442
+ props: {
443
+ striped: { type: Boolean, default: false },
444
+ bordered: { type: Boolean, default: false },
445
+ hover: { type: Boolean, default: true },
446
+ compact: { type: Boolean, default: false },
447
+ stickyHeader: { type: Boolean, default: false }
448
+ },
449
+ setup(__props) {
450
+ const attrs = useAttrs();
451
+ const props = __props;
452
+ const tableClasses = computed(() => [
453
+ "w-full text-left",
454
+ props.bordered ? "border border-gray-200 dark:border-gray-700" : ""
455
+ ]);
456
+ const wrapperClasses = computed(() => [
457
+ "overflow-hidden",
458
+ props.stickyHeader ? "max-h-[600px] overflow-y-auto" : ""
459
+ ]);
460
+ const { striped, bordered, hover, compact, stickyHeader } = toRefs(props);
461
+ provide(TableContextKey, reactive({
462
+ striped,
463
+ bordered,
464
+ hover,
465
+ compact,
466
+ stickyHeader
467
+ }));
468
+ return (_ctx, _cache) => {
469
+ return openBlock(), createElementBlock("div", {
470
+ class: normalizeClass(wrapperClasses.value)
471
+ }, [
472
+ createElementVNode("div", _hoisted_1$m, [
473
+ createElementVNode("table", mergeProps(unref(attrs), { class: tableClasses.value }), [
474
+ renderSlot(_ctx.$slots, "default")
475
+ ], 16)
476
+ ])
477
+ ], 2);
478
+ };
479
+ }
480
+ });
481
+ const _sfc_main$x = /* @__PURE__ */ defineComponent({
482
+ ...{
483
+ inheritAttrs: false
484
+ },
485
+ __name: "Caption",
486
+ props: {
487
+ position: { default: "top" },
488
+ srOnly: { type: Boolean, default: false }
489
+ },
490
+ setup(__props) {
491
+ const attrs = useAttrs();
492
+ return (_ctx, _cache) => {
493
+ return openBlock(), createElementBlock("caption", mergeProps(unref(attrs), {
494
+ class: [
495
+ __props.position === "bottom" ? "caption-bottom" : "caption-top",
496
+ __props.srOnly ? "sr-only" : "py-2 text-sm text-gray-600 dark:text-gray-400"
497
+ ]
498
+ }), [
499
+ renderSlot(_ctx.$slots, "default")
500
+ ], 16);
501
+ };
502
+ }
503
+ });
504
+ const _sfc_main$w = /* @__PURE__ */ defineComponent({
505
+ ...{
506
+ inheritAttrs: false
507
+ },
508
+ __name: "Colgroup",
509
+ setup(__props) {
510
+ const attrs = useAttrs();
511
+ return (_ctx, _cache) => {
512
+ return openBlock(), createElementBlock("colgroup", normalizeProps(guardReactiveProps(unref(attrs))), [
513
+ renderSlot(_ctx.$slots, "default")
514
+ ], 16);
515
+ };
516
+ }
517
+ });
518
+ const _hoisted_1$l = ["span"];
519
+ const _sfc_main$v = /* @__PURE__ */ defineComponent({
520
+ ...{
521
+ inheritAttrs: false
522
+ },
523
+ __name: "Col",
524
+ props: {
525
+ span: {},
526
+ width: {}
527
+ },
528
+ setup(__props) {
529
+ const props = __props;
530
+ const attrs = useAttrs();
531
+ const colStyles = computed(() => ({
532
+ width: props.width
533
+ }));
534
+ return (_ctx, _cache) => {
535
+ return openBlock(), createElementBlock("col", mergeProps(unref(attrs), {
536
+ span: __props.span,
537
+ style: colStyles.value
538
+ }), null, 16, _hoisted_1$l);
539
+ };
540
+ }
541
+ });
542
+ const _sfc_main$u = /* @__PURE__ */ defineComponent({
543
+ ...{
544
+ inheritAttrs: false
545
+ },
546
+ __name: "Thead",
547
+ setup(__props) {
548
+ const context = inject(TableContextKey);
549
+ const attrs = useAttrs();
550
+ const theadClasses = computed(() => [
551
+ "text-sm font-semibold text-gray-600 uppercase dark:text-gray-400",
552
+ (context == null ? void 0 : context.bordered) ? "border-b border-gray-200 dark:border-gray-700" : "border-b border-black/10 dark:border-white/10",
553
+ (context == null ? void 0 : context.stickyHeader) ? "sticky top-0 z-10" : ""
554
+ ]);
555
+ return (_ctx, _cache) => {
556
+ return openBlock(), createElementBlock("thead", mergeProps(unref(attrs), {
557
+ class: [theadClasses.value, "bg-black/5 dark:bg-white/5"]
558
+ }), [
559
+ renderSlot(_ctx.$slots, "default")
560
+ ], 16);
561
+ };
562
+ }
563
+ });
564
+ const _sfc_main$t = /* @__PURE__ */ defineComponent({
565
+ ...{
566
+ inheritAttrs: false
567
+ },
568
+ __name: "Tbody",
569
+ setup(__props) {
570
+ const context = inject(TableContextKey);
571
+ const attrs = useAttrs();
572
+ const tbodyClasses = computed(() => [
573
+ "font-medium",
574
+ (context == null ? void 0 : context.bordered) ? "divide-y divide-gray-200 dark:divide-gray-700" : "divide-y divide-black/10 dark:divide-white/10"
575
+ ]);
576
+ return (_ctx, _cache) => {
577
+ return openBlock(), createElementBlock("tbody", mergeProps(unref(attrs), { class: tbodyClasses.value }), [
578
+ renderSlot(_ctx.$slots, "default")
579
+ ], 16);
580
+ };
581
+ }
582
+ });
583
+ const _sfc_main$s = /* @__PURE__ */ defineComponent({
584
+ ...{
585
+ inheritAttrs: false
586
+ },
587
+ __name: "Tfoot",
588
+ setup(__props) {
589
+ const context = inject(TableContextKey);
590
+ const attrs = useAttrs();
591
+ const tfootClasses = computed(() => [
592
+ "text-sm font-medium text-gray-600 dark:text-gray-400",
593
+ (context == null ? void 0 : context.bordered) ? "border-t border-gray-200 dark:border-gray-700" : "border-t border-black/10 dark:border-white/10"
594
+ ]);
595
+ return (_ctx, _cache) => {
596
+ return openBlock(), createElementBlock("tfoot", mergeProps(unref(attrs), {
597
+ class: [tfootClasses.value, "bg-black/5 dark:bg-white/5"]
598
+ }), [
599
+ renderSlot(_ctx.$slots, "default")
600
+ ], 16);
601
+ };
602
+ }
603
+ });
604
+ const _sfc_main$r = /* @__PURE__ */ defineComponent({
605
+ ...{
606
+ inheritAttrs: false
607
+ },
608
+ __name: "Tr",
609
+ props: {
610
+ selected: { type: Boolean, default: false },
611
+ clickable: { type: Boolean, default: false },
612
+ disabled: { type: Boolean, default: false },
613
+ even: { type: Boolean }
614
+ },
615
+ emits: ["click"],
616
+ setup(__props, { emit: __emit }) {
617
+ const props = __props;
618
+ const attrs = useAttrs();
619
+ const emit = __emit;
620
+ const context = inject(TableContextKey);
621
+ const rowClasses = computed(() => [
622
+ "transition-colors",
623
+ // Hover effect
624
+ (context == null ? void 0 : context.hover) && !props.disabled ? "hover:bg-black/5 dark:hover:bg-white/5" : "",
625
+ // Selected state
626
+ props.selected ? "bg-primary-50 dark:bg-primary-900/20" : "",
627
+ // Striped (only apply if not selected)
628
+ (context == null ? void 0 : context.striped) && props.even && !props.selected ? "bg-black/[0.02] dark:bg-white/[0.02]" : "",
629
+ // Clickable
630
+ props.clickable && !props.disabled ? "cursor-pointer" : "",
631
+ // Disabled
632
+ props.disabled ? "opacity-50 cursor-not-allowed" : ""
633
+ ]);
634
+ const handleClick = (event) => {
635
+ if (props.clickable && !props.disabled) {
636
+ emit("click", event);
637
+ }
638
+ };
639
+ return (_ctx, _cache) => {
640
+ return openBlock(), createElementBlock("tr", mergeProps(unref(attrs), {
641
+ class: rowClasses.value,
642
+ onClick: handleClick
643
+ }), [
644
+ renderSlot(_ctx.$slots, "default")
645
+ ], 16);
646
+ };
647
+ }
648
+ });
649
+ const _hoisted_1$k = ["colspan", "rowspan", "scope", "aria-sort"];
650
+ const _hoisted_2$f = {
651
+ key: 0,
652
+ d: "M7 14l5-5 5 5H7z"
653
+ };
654
+ const _hoisted_3$8 = {
655
+ key: 1,
656
+ d: "M7 10l5 5 5-5H7z"
657
+ };
658
+ const _sfc_main$q = /* @__PURE__ */ defineComponent({
659
+ ...{
660
+ inheritAttrs: false
661
+ },
662
+ __name: "Th",
663
+ props: {
664
+ sortable: { type: Boolean, default: false },
665
+ sorted: { type: Boolean, default: false },
666
+ sortDirection: { default: "asc" },
667
+ align: { default: "left" },
668
+ width: {},
669
+ minWidth: {},
670
+ maxWidth: {},
671
+ sticky: { type: Boolean, default: false },
672
+ stickyLeft: { default: "0" },
673
+ colspan: {},
674
+ rowspan: {},
675
+ scope: { default: "col" },
676
+ resizable: { type: Boolean, default: false },
677
+ resizing: { type: Boolean, default: false }
678
+ },
679
+ emits: ["sort", "resizeStart"],
680
+ setup(__props, { emit: __emit }) {
681
+ const props = __props;
682
+ const attrs = useAttrs();
683
+ const emit = __emit;
684
+ const context = inject(TableContextKey);
685
+ const thClasses = computed(() => [
686
+ // Padding
687
+ (context == null ? void 0 : context.compact) ? "px-2 py-2" : "px-3 py-3",
688
+ // Alignment
689
+ props.align === "center" ? "text-center" : props.align === "right" ? "text-right" : "text-left",
690
+ // Sortable hover
691
+ props.sortable ? "cursor-pointer select-none hover:bg-black/5 dark:hover:bg-white/5" : "",
692
+ // Border for bordered tables
693
+ (context == null ? void 0 : context.bordered) ? "border-r border-gray-200 dark:border-gray-700 last:border-r-0" : "",
694
+ // Sticky column
695
+ props.sticky ? "sticky bg-black/5 dark:bg-white/5 z-20" : "",
696
+ // Resizable
697
+ props.resizable ? "relative" : ""
698
+ ]);
699
+ const thStyles = computed(() => ({
700
+ width: props.width,
701
+ minWidth: props.minWidth,
702
+ maxWidth: props.maxWidth,
703
+ left: props.sticky ? props.stickyLeft : void 0
704
+ }));
705
+ const handleSort = () => {
706
+ if (props.sortable) {
707
+ emit("sort");
708
+ }
709
+ };
710
+ return (_ctx, _cache) => {
711
+ return openBlock(), createElementBlock("th", mergeProps(unref(attrs), {
712
+ class: thClasses.value,
713
+ style: thStyles.value,
714
+ colspan: __props.colspan,
715
+ rowspan: __props.rowspan,
716
+ scope: __props.scope,
717
+ "aria-sort": __props.sortable ? __props.sorted ? __props.sortDirection === "asc" ? "ascending" : "descending" : "none" : void 0,
718
+ onClick: handleSort
719
+ }), [
720
+ createElementVNode("div", {
721
+ class: normalizeClass(["flex items-center gap-1", {
722
+ "justify-center": __props.align === "center",
723
+ "justify-end": __props.align === "right"
724
+ }])
725
+ }, [
726
+ renderSlot(_ctx.$slots, "default"),
727
+ __props.sortable ? (openBlock(), createElementBlock("svg", {
728
+ key: 0,
729
+ class: normalizeClass([
730
+ "size-4 transition-colors flex-shrink-0",
731
+ __props.sorted ? "text-primary-500" : "text-gray-400"
732
+ ]),
733
+ viewBox: "0 0 24 24",
734
+ fill: "currentColor"
735
+ }, [
736
+ __props.sorted && __props.sortDirection === "asc" ? (openBlock(), createElementBlock("path", _hoisted_2$f)) : __props.sorted && __props.sortDirection === "desc" ? (openBlock(), createElementBlock("path", _hoisted_3$8)) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [
737
+ _cache[2] || (_cache[2] = createElementVNode("path", {
738
+ d: "M7 14l5-5 5 5H7z",
739
+ class: "opacity-40"
740
+ }, null, -1)),
741
+ _cache[3] || (_cache[3] = createElementVNode("path", {
742
+ d: "M7 10l5 5 5-5H7z",
743
+ class: "opacity-40"
744
+ }, null, -1))
745
+ ], 64))
746
+ ], 2)) : createCommentVNode("", true)
747
+ ], 2),
748
+ __props.resizable ? (openBlock(), createElementBlock("div", {
749
+ key: 0,
750
+ class: normalizeClass([
751
+ "absolute top-0 right-0 bottom-0 w-1 cursor-col-resize select-none",
752
+ "hover:bg-primary-400 dark:hover:bg-primary-500",
753
+ "transition-colors",
754
+ __props.resizing ? "bg-primary-500" : "bg-transparent"
755
+ ]),
756
+ role: "separator",
757
+ "aria-orientation": "vertical",
758
+ tabindex: "-1",
759
+ onMousedown: _cache[0] || (_cache[0] = withModifiers(($event) => emit("resizeStart", $event), ["stop"])),
760
+ onTouchstart: _cache[1] || (_cache[1] = withModifiers(($event) => emit("resizeStart", $event), ["stop"]))
761
+ }, null, 34)) : createCommentVNode("", true)
762
+ ], 16, _hoisted_1$k);
763
+ };
764
+ }
765
+ });
766
+ const _hoisted_1$j = ["colspan", "rowspan"];
767
+ const _sfc_main$p = /* @__PURE__ */ defineComponent({
768
+ ...{
769
+ inheritAttrs: false
770
+ },
771
+ __name: "Td",
772
+ props: {
773
+ align: { default: "left" },
774
+ main: { type: Boolean, default: false },
775
+ className: {},
776
+ truncate: { type: Boolean, default: false },
777
+ width: {},
778
+ sticky: { type: Boolean, default: false },
779
+ stickyLeft: { default: "0" },
780
+ colspan: {},
781
+ rowspan: {}
782
+ },
783
+ setup(__props) {
784
+ const props = __props;
785
+ const attrs = useAttrs();
786
+ const context = inject(TableContextKey);
787
+ const tdClasses = computed(() => [
788
+ // Padding
789
+ (context == null ? void 0 : context.compact) ? "px-2 py-2" : "px-3 py-4",
790
+ // Alignment
791
+ props.align === "center" ? "text-center" : props.align === "right" ? "text-right" : "text-left",
792
+ // Main column styling
793
+ props.main ? "text-sm font-semibold text-gray-900 dark:text-gray-100" : "text-xs font-medium text-gray-600 dark:text-gray-400",
794
+ // Truncate
795
+ props.truncate ? "truncate" : "",
796
+ // Border for bordered tables
797
+ (context == null ? void 0 : context.bordered) ? "border-r border-gray-200 dark:border-gray-700 last:border-r-0" : "",
798
+ // Sticky column
799
+ props.sticky ? "sticky bg-white dark:bg-gray-900 z-10" : "",
800
+ // Custom className
801
+ props.className || ""
802
+ ]);
803
+ const tdStyles = computed(() => ({
804
+ width: props.width,
805
+ maxWidth: props.truncate ? props.width || "200px" : void 0,
806
+ left: props.sticky ? props.stickyLeft : void 0
807
+ }));
808
+ return (_ctx, _cache) => {
809
+ return openBlock(), createElementBlock("td", mergeProps(unref(attrs), {
810
+ class: tdClasses.value,
811
+ style: tdStyles.value,
812
+ colspan: __props.colspan,
813
+ rowspan: __props.rowspan
814
+ }), [
815
+ renderSlot(_ctx.$slots, "default")
816
+ ], 16, _hoisted_1$j);
817
+ };
818
+ }
819
+ });
820
+ const _sfc_main$o = /* @__PURE__ */ defineComponent({
821
+ __name: "TableHeader",
822
+ props: {
823
+ columns: {},
824
+ selectable: { type: Boolean, default: false },
825
+ allSelected: { type: Boolean, default: false },
826
+ someSelected: { type: Boolean, default: false },
827
+ selectableCount: { default: 0 },
828
+ sortBy: {},
829
+ sortDirection: {},
830
+ showActions: { type: Boolean, default: false }
831
+ },
832
+ emits: ["selectAll", "sort"],
833
+ setup(__props, { emit: __emit }) {
834
+ const props = __props;
835
+ const emit = __emit;
836
+ const handleSort = (property) => {
837
+ if (!property.sortable) return;
838
+ const newDirection = props.sortBy === property.name && props.sortDirection === "asc" ? "desc" : "asc";
839
+ emit("sort", property.name, newDirection);
840
+ };
841
+ return (_ctx, _cache) => {
842
+ return openBlock(), createBlock(_sfc_main$r, null, {
843
+ default: withCtx(() => [
844
+ __props.selectable ? (openBlock(), createBlock(_sfc_main$q, {
845
+ key: 0,
846
+ width: "48px"
847
+ }, {
848
+ default: withCtx(() => [
849
+ createVNode(_sfc_main$C, {
850
+ "model-value": __props.allSelected,
851
+ indeterminate: __props.someSelected,
852
+ disabled: __props.selectableCount === 0,
853
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => emit("selectAll"))
854
+ }, null, 8, ["model-value", "indeterminate", "disabled"])
855
+ ]),
856
+ _: 1
857
+ })) : createCommentVNode("", true),
858
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (column) => {
859
+ return openBlock(), createBlock(_sfc_main$q, {
860
+ key: column.name,
861
+ sortable: column.sortable,
862
+ sorted: __props.sortBy === column.name,
863
+ "sort-direction": __props.sortDirection,
864
+ align: column.align,
865
+ width: column.width,
866
+ "min-width": column.minWidth,
867
+ "max-width": column.maxWidth,
868
+ onSort: ($event) => handleSort(column)
869
+ }, {
870
+ default: withCtx(() => [
871
+ renderSlot(_ctx.$slots, "header-" + column.name, { column }, () => [
872
+ createTextVNode(toDisplayString(column.label ?? column.name), 1)
873
+ ])
874
+ ]),
875
+ _: 2
876
+ }, 1032, ["sortable", "sorted", "sort-direction", "align", "width", "min-width", "max-width", "onSort"]);
877
+ }), 128)),
878
+ __props.showActions ? (openBlock(), createBlock(_sfc_main$q, {
879
+ key: 1,
880
+ align: "right",
881
+ width: "100px"
882
+ })) : createCommentVNode("", true)
883
+ ]),
884
+ _: 3
885
+ });
886
+ };
887
+ }
888
+ });
889
+ const _hoisted_1$i = { class: "flex items-center justify-end gap-2" };
890
+ const _sfc_main$n = /* @__PURE__ */ defineComponent({
891
+ __name: "TableRow",
892
+ props: {
893
+ item: {},
894
+ columns: {},
895
+ selectable: { type: Boolean, default: false },
896
+ selected: { type: Boolean, default: false },
897
+ canSelect: { type: Boolean, default: true },
898
+ clickable: { type: Boolean, default: false },
899
+ even: { type: Boolean, default: false },
900
+ showActions: { type: Boolean, default: false }
901
+ },
902
+ emits: ["select", "click"],
903
+ setup(__props, { emit: __emit }) {
904
+ const emit = __emit;
905
+ const typeComponents = {
906
+ text: _sfc_main$H,
907
+ number: _sfc_main$G,
908
+ date: _sfc_main$F,
909
+ boolean: _sfc_main$E,
910
+ badge: _sfc_main$D
911
+ };
912
+ const getTypeComponent = (type = "text") => {
913
+ return typeComponents[type] || _sfc_main$H;
914
+ };
915
+ const getItemValue = (item, property) => {
916
+ if (property.name.includes(".")) {
917
+ let value = item;
918
+ for (const key of property.name.split(".")) {
919
+ if (value && typeof value === "object" && key in value) {
920
+ value = value[key];
921
+ } else {
922
+ return void 0;
923
+ }
924
+ }
925
+ return value;
926
+ }
927
+ return item[property.name];
928
+ };
929
+ return (_ctx, _cache) => {
930
+ return openBlock(), createBlock(_sfc_main$r, {
931
+ selected: __props.selected,
932
+ clickable: __props.clickable,
933
+ even: __props.even,
934
+ onClick: _cache[1] || (_cache[1] = (e) => emit("click", e))
935
+ }, {
936
+ default: withCtx(() => [
937
+ __props.selectable ? (openBlock(), createBlock(_sfc_main$p, {
938
+ key: 0,
939
+ width: "48px"
940
+ }, {
941
+ default: withCtx(() => [
942
+ __props.canSelect ? (openBlock(), createBlock(_sfc_main$C, {
943
+ key: 0,
944
+ "model-value": __props.selected,
945
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => emit("select"))
946
+ }, null, 8, ["model-value"])) : createCommentVNode("", true)
947
+ ]),
948
+ _: 1
949
+ })) : createCommentVNode("", true),
950
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (column) => {
951
+ return openBlock(), createBlock(_sfc_main$p, {
952
+ key: column.name,
953
+ align: column.align,
954
+ main: column.main,
955
+ "class-name": column.className,
956
+ truncate: column.truncate,
957
+ width: column.width
958
+ }, {
959
+ default: withCtx(() => [
960
+ renderSlot(_ctx.$slots, "cell-" + column.name, {
961
+ item: __props.item,
962
+ value: getItemValue(__props.item, column),
963
+ column
964
+ }, () => [
965
+ (openBlock(), createBlock(resolveDynamicComponent(getTypeComponent(column.type || "text")), {
966
+ value: getItemValue(__props.item, column)
967
+ }, null, 8, ["value"]))
968
+ ])
969
+ ]),
970
+ _: 2
971
+ }, 1032, ["align", "main", "class-name", "truncate", "width"]);
972
+ }), 128)),
973
+ __props.showActions ? (openBlock(), createBlock(_sfc_main$p, {
974
+ key: 1,
975
+ align: "right"
976
+ }, {
977
+ default: withCtx(() => [
978
+ createElementVNode("div", _hoisted_1$i, [
979
+ renderSlot(_ctx.$slots, "actions", { item: __props.item })
980
+ ])
981
+ ]),
982
+ _: 3
983
+ })) : createCommentVNode("", true)
984
+ ]),
985
+ _: 3
986
+ }, 8, ["selected", "clickable", "even"]);
987
+ };
988
+ }
989
+ });
990
+ const _sfc_main$m = /* @__PURE__ */ defineComponent({
991
+ __name: "TableFooter",
992
+ props: {
993
+ colSpan: {}
994
+ },
995
+ setup(__props) {
996
+ return (_ctx, _cache) => {
997
+ return openBlock(), createBlock(_sfc_main$r, null, {
998
+ default: withCtx(() => [
999
+ createVNode(_sfc_main$p, {
1000
+ colspan: __props.colSpan,
1001
+ class: "text-center"
1002
+ }, {
1003
+ default: withCtx(() => [
1004
+ renderSlot(_ctx.$slots, "default")
1005
+ ]),
1006
+ _: 3
1007
+ }, 8, ["colspan"])
1008
+ ]),
1009
+ _: 3
1010
+ });
1011
+ };
1012
+ }
1013
+ });
1014
+ const _hoisted_1$h = ["disabled", "aria-expanded"];
1015
+ const _hoisted_2$e = { class: "p-4" };
19
1016
  const _sfc_main$l = /* @__PURE__ */ defineComponent({
20
- __name: "CardComponent",
1017
+ ...{
1018
+ inheritAttrs: false
1019
+ },
1020
+ __name: "ExpandableRow",
21
1021
  props: {
22
- title: {},
23
- description: {},
24
- titleClass: {},
25
- dividerClass: {},
26
- loading: { type: Boolean, default: false },
27
- loadingLines: { default: 3 },
28
- loadingAvatar: { type: Boolean, default: false },
29
- loadingActions: { type: Boolean, default: false }
1022
+ colspan: {},
1023
+ defaultExpanded: { type: Boolean, default: false },
1024
+ expanded: { type: Boolean, default: void 0 },
1025
+ selected: { type: Boolean, default: false },
1026
+ disabled: { type: Boolean, default: false },
1027
+ expandOnRowClick: { type: Boolean, default: false }
30
1028
  },
31
- setup(__props) {
1029
+ emits: ["update:expanded", "click"],
1030
+ setup(__props, { expose: __expose, emit: __emit }) {
32
1031
  const props = __props;
33
- const titleClasses = computed(
34
- () => props.titleClass || "text-gray-800 dark:text-gray-200"
35
- );
36
- const dividerClasses = computed(
37
- () => props.dividerClass || "border-gray-200 dark:border-gray-700"
38
- );
1032
+ const emit = __emit;
1033
+ const attrs = useAttrs();
1034
+ const internalExpanded = ref(props.defaultExpanded);
1035
+ const isExpanded = computed({
1036
+ get: () => props.expanded !== void 0 ? props.expanded : internalExpanded.value,
1037
+ set: (value) => {
1038
+ internalExpanded.value = value;
1039
+ emit("update:expanded", value);
1040
+ }
1041
+ });
1042
+ const toggle = () => {
1043
+ if (!props.disabled) {
1044
+ isExpanded.value = !isExpanded.value;
1045
+ }
1046
+ };
1047
+ const handleRowClick = (event) => {
1048
+ emit("click", event);
1049
+ if (props.expandOnRowClick) {
1050
+ toggle();
1051
+ }
1052
+ };
1053
+ __expose({ toggle, isExpanded });
39
1054
  return (_ctx, _cache) => {
40
- return __props.loading ? (openBlock(), createBlock(_sfc_main$m, {
41
- key: 0,
42
- lines: __props.loadingLines,
43
- "show-avatar": __props.loadingAvatar,
44
- "show-actions": __props.loadingActions
45
- }, null, 8, ["lines", "show-avatar", "show-actions"])) : (openBlock(), createElementBlock("div", _hoisted_1$h, [
46
- _ctx.$slots.header ? (openBlock(), createElementBlock("div", {
1055
+ return openBlock(), createElementBlock(Fragment, null, [
1056
+ createVNode(_sfc_main$r, mergeProps(unref(attrs), {
1057
+ selected: __props.selected,
1058
+ disabled: __props.disabled,
1059
+ clickable: "",
1060
+ onClick: handleRowClick
1061
+ }), {
1062
+ default: withCtx(() => [
1063
+ createVNode(_sfc_main$p, {
1064
+ width: "40px",
1065
+ class: "!p-2"
1066
+ }, {
1067
+ default: withCtx(() => [
1068
+ createElementVNode("button", {
1069
+ type: "button",
1070
+ disabled: __props.disabled,
1071
+ class: "flex size-6 items-center justify-center rounded transition-colors hover:bg-black/10 dark:hover:bg-white/10 disabled:opacity-50 disabled:cursor-not-allowed",
1072
+ "aria-expanded": isExpanded.value,
1073
+ "aria-label": "Toggle row details",
1074
+ onClick: withModifiers(toggle, ["stop"])
1075
+ }, [
1076
+ (openBlock(), createElementBlock("svg", {
1077
+ class: normalizeClass(["size-4 transition-transform", { "rotate-90": isExpanded.value }]),
1078
+ viewBox: "0 0 24 24",
1079
+ fill: "currentColor"
1080
+ }, [..._cache[0] || (_cache[0] = [
1081
+ createElementVNode("path", { d: "M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z" }, null, -1)
1082
+ ])], 2))
1083
+ ], 8, _hoisted_1$h)
1084
+ ]),
1085
+ _: 1
1086
+ }),
1087
+ renderSlot(_ctx.$slots, "row")
1088
+ ]),
1089
+ _: 3
1090
+ }, 16, ["selected", "disabled"]),
1091
+ isExpanded.value ? (openBlock(), createBlock(_sfc_main$r, {
47
1092
  key: 0,
48
- class: normalizeClass(["border-b", dividerClasses.value])
49
- }, [
50
- renderSlot(_ctx.$slots, "header")
51
- ], 2)) : __props.title || __props.description || _ctx.$slots.title || _ctx.$slots.description || _ctx.$slots.actions ? (openBlock(), createElementBlock("div", {
52
- key: 1,
53
- class: normalizeClass(["flex items-center justify-between border-b px-5 py-3", dividerClasses.value])
54
- }, [
55
- createElementVNode("div", _hoisted_2$d, [
56
- __props.title || _ctx.$slots.title ? (openBlock(), createElementBlock("span", {
57
- key: 0,
58
- class: normalizeClass(["text-md font-semibold", titleClasses.value])
59
- }, [
60
- renderSlot(_ctx.$slots, "title", {}, () => [
61
- createTextVNode(toDisplayString(__props.title), 1)
62
- ])
63
- ], 2)) : createCommentVNode("", true),
64
- __props.description || _ctx.$slots.description ? (openBlock(), createElementBlock("span", _hoisted_3$8, [
65
- renderSlot(_ctx.$slots, "description", {}, () => [
66
- createTextVNode(toDisplayString(__props.description), 1)
67
- ])
68
- ])) : createCommentVNode("", true)
1093
+ class: "bg-gray-50 dark:bg-gray-800/50"
1094
+ }, {
1095
+ default: withCtx(() => [
1096
+ createVNode(_sfc_main$p, {
1097
+ colspan: __props.colspan + 1,
1098
+ class: "!p-0"
1099
+ }, {
1100
+ default: withCtx(() => [
1101
+ createElementVNode("div", _hoisted_2$e, [
1102
+ renderSlot(_ctx.$slots, "expanded")
1103
+ ])
1104
+ ]),
1105
+ _: 3
1106
+ }, 8, ["colspan"])
69
1107
  ]),
70
- createElementVNode("div", _hoisted_4$6, [
71
- renderSlot(_ctx.$slots, "actions")
72
- ])
73
- ], 2)) : createCommentVNode("", true),
74
- renderSlot(_ctx.$slots, "default")
75
- ]));
1108
+ _: 3
1109
+ })) : createCommentVNode("", true)
1110
+ ], 64);
76
1111
  };
77
1112
  }
78
1113
  });
79
1114
  const _hoisted_1$g = { class: "overflow-hidden" };
80
- const _hoisted_2$c = {
1115
+ const _hoisted_2$d = {
81
1116
  key: 1,
82
- class: "overflow-x-auto"
1117
+ class: "flex flex-col items-center justify-center py-12 text-center"
83
1118
  };
84
- const _hoisted_3$7 = { class: "w-full divide-y divide-black/10 text-left dark:divide-white/10" };
85
- const _hoisted_4$5 = { class: "bg-black/5 text-sm font-semibold text-gray-600 uppercase dark:bg-white/5 dark:text-gray-400" };
1119
+ const _hoisted_3$7 = { class: "flex flex-col items-center gap-3" };
1120
+ const _hoisted_4$5 = { class: "text-sm text-gray-600 dark:text-gray-400" };
86
1121
  const _hoisted_5$3 = {
87
- key: 0,
88
- class: "w-12 px-3 py-3"
89
- };
90
- const _hoisted_6$3 = ["onClick"];
91
- const _hoisted_7$3 = {
92
- key: 0,
93
- d: "M7 14l5-5 5 5H7z"
94
- };
95
- const _hoisted_8$3 = {
96
- key: 1,
97
- d: "M7 10l5 5 5-5H7z"
98
- };
99
- const _hoisted_9$3 = {
100
- key: 1,
101
- class: "px-3 py-3 text-right"
102
- };
103
- const _hoisted_10$2 = { class: "divide-y divide-black/10 font-medium dark:divide-white/10" };
104
- const _hoisted_11$1 = {
105
- key: 0,
106
- class: "px-3 py-4"
107
- };
108
- const _hoisted_12$1 = {
109
- key: 1,
110
- class: "flex items-center justify-end gap-2 px-3 py-4"
1122
+ key: 3,
1123
+ class: "flex flex-col items-center justify-center py-12 text-center"
111
1124
  };
112
- const _hoisted_13 = { key: 0 };
113
1125
  const _sfc_main$k = /* @__PURE__ */ defineComponent({
114
- __name: "TableComponent",
1126
+ __name: "DataTable",
115
1127
  props: {
116
1128
  properties: {},
117
1129
  items: {},
@@ -122,58 +1134,65 @@ const _sfc_main$k = /* @__PURE__ */ defineComponent({
122
1134
  sortBy: {},
123
1135
  sortDirection: {},
124
1136
  loading: { type: Boolean, default: false },
125
- loadingRows: { default: 5 }
1137
+ loadingRows: { default: 5 },
1138
+ error: { type: Boolean, default: false },
1139
+ errorMessage: { default: "An error occurred while loading data." },
1140
+ striped: { type: Boolean, default: false },
1141
+ bordered: { type: Boolean, default: false },
1142
+ hover: { type: Boolean, default: true },
1143
+ compact: { type: Boolean, default: false },
1144
+ stickyHeader: { type: Boolean, default: false },
1145
+ clickableRows: { type: Boolean, default: false },
1146
+ paginated: { type: Boolean, default: false },
1147
+ pageSize: { default: 10 },
1148
+ pageSizeOptions: { default: () => [10, 20, 50, 100] },
1149
+ showPageSize: { type: Boolean, default: true },
1150
+ currentPage: {},
1151
+ totalItems: {}
126
1152
  },
127
- emits: ["select", "selectAll", "sort"],
1153
+ emits: ["select", "selectAll", "sort", "rowClick", "update:currentPage", "update:pageSize"],
128
1154
  setup(__props, { emit: __emit }) {
129
1155
  const slots = useSlots();
130
1156
  const props = __props;
131
1157
  const emit = __emit;
132
- const typeComponents = {
133
- text: _sfc_main$t,
134
- number: _sfc_main$s,
135
- date: _sfc_main$r,
136
- boolean: _sfc_main$q,
137
- badge: _sfc_main$p
1158
+ const visibleProperties = computed(() => props.properties.filter((p) => !p.hidden));
1159
+ const {
1160
+ currentPage: internalPage,
1161
+ pageSize: internalPageSize,
1162
+ totalPages,
1163
+ paginatedItems,
1164
+ setPageSize: setInternalPageSize,
1165
+ goToPage
1166
+ } = usePagination({
1167
+ items: computed(() => props.items),
1168
+ pageSize: props.pageSize,
1169
+ initialPage: props.currentPage ?? 1
1170
+ });
1171
+ const effectivePage = computed(() => props.currentPage ?? internalPage.value);
1172
+ const effectivePageSize = computed(() => props.pageSize ?? internalPageSize.value);
1173
+ const effectiveTotalPages = computed(() => {
1174
+ if (props.totalItems !== void 0) {
1175
+ return Math.ceil(props.totalItems / effectivePageSize.value);
1176
+ }
1177
+ return totalPages.value;
1178
+ });
1179
+ const displayItems = computed(() => {
1180
+ if (!props.paginated) return props.items;
1181
+ if (props.totalItems !== void 0) return props.items;
1182
+ return paginatedItems.value;
1183
+ });
1184
+ const handlePageChange = (page) => {
1185
+ goToPage(page);
1186
+ emit("update:currentPage", page);
138
1187
  };
139
- const getTypeComponent = (type = "text") => {
140
- return typeComponents[type] || _sfc_main$t;
1188
+ const handlePageSizeChange = (size) => {
1189
+ setInternalPageSize(size);
1190
+ emit("update:pageSize", size);
141
1191
  };
142
- const visibleProperties = computed(() => props.properties.filter((p) => !p.hidden));
143
1192
  const getKey = (item) => {
144
1193
  const keyValue = item[props.keyField];
145
1194
  return String(keyValue ?? Math.random());
146
1195
  };
147
- const getItemValue = (item, property) => {
148
- if (property.name.includes(".")) {
149
- let value = item;
150
- for (const key of property.name.split(".")) {
151
- if (value && typeof value === "object" && key in value) {
152
- value = value[key];
153
- } else {
154
- return void 0;
155
- }
156
- }
157
- return value;
158
- }
159
- return item[property.name];
160
- };
161
- const getAlignmentClass = (align) => {
162
- switch (align) {
163
- case "center":
164
- return "text-center";
165
- case "right":
166
- return "text-right";
167
- default:
168
- return "text-left";
169
- }
170
- };
171
- const getMainClass = (main) => {
172
- if (main) {
173
- return "text-sm font-semibold text-gray-900 dark:text-gray-100";
174
- }
175
- return "text-xs font-medium text-gray-600 dark:text-gray-400";
176
- };
177
1196
  const selectableItems = computed(() => {
178
1197
  if (!props.selectableFilter) return props.items;
179
1198
  return props.items.filter(props.selectableFilter);
@@ -201,129 +1220,145 @@ const _sfc_main$k = /* @__PURE__ */ defineComponent({
201
1220
  const handleSelect = (item) => {
202
1221
  emit("select", getKey(item));
203
1222
  };
204
- const hasActionSlot = computed(() => !!slots.action);
205
- const handleSort = (property) => {
206
- if (!property.sortable) return;
207
- const newDirection = props.sortBy === property.name && props.sortDirection === "asc" ? "desc" : "asc";
208
- emit("sort", property.name, newDirection);
209
- };
210
- const isSortedColumn = (property) => {
211
- return props.sortBy === property.name;
1223
+ const handleRowClick = (item, event) => {
1224
+ if (props.clickableRows) {
1225
+ emit("rowClick", item, event);
1226
+ }
212
1227
  };
1228
+ const hasActionSlot = computed(() => !!slots.action);
213
1229
  return (_ctx, _cache) => {
214
1230
  return openBlock(), createElementBlock("div", _hoisted_1$g, [
215
- __props.loading ? (openBlock(), createBlock(_sfc_main$n, {
1231
+ __props.loading ? (openBlock(), createBlock(_sfc_main$I, {
216
1232
  key: 0,
217
1233
  rows: __props.loadingRows,
218
1234
  columns: visibleProperties.value.length
219
- }, null, 8, ["rows", "columns"])) : (openBlock(), createElementBlock("div", _hoisted_2$c, [
220
- createElementVNode("table", _hoisted_3$7, [
221
- createElementVNode("thead", _hoisted_4$5, [
222
- createElementVNode("tr", null, [
223
- __props.selectable ? (openBlock(), createElementBlock("th", _hoisted_5$3, [
224
- createVNode(_sfc_main$o, {
225
- "model-value": allSelected.value,
226
- indeterminate: someSelected.value,
227
- disabled: selectableItems.value.length === 0,
228
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => emit("selectAll"))
229
- }, null, 8, ["model-value", "indeterminate", "disabled"])
230
- ])) : createCommentVNode("", true),
231
- (openBlock(true), createElementBlock(Fragment, null, renderList(visibleProperties.value, (property) => {
232
- return openBlock(), createElementBlock("th", {
233
- key: property.name,
234
- class: normalizeClass([
235
- getAlignmentClass(property.align),
236
- "px-3 py-3",
237
- property.sortable ? "cursor-pointer select-none hover:bg-black/5 dark:hover:bg-white/5" : ""
1235
+ }, null, 8, ["rows", "columns"])) : __props.error ? (openBlock(), createElementBlock("div", _hoisted_2$d, [
1236
+ renderSlot(_ctx.$slots, "error", {}, () => [
1237
+ createElementVNode("div", _hoisted_3$7, [
1238
+ _cache[2] || (_cache[2] = createElementVNode("svg", {
1239
+ class: "size-12 text-red-400",
1240
+ fill: "none",
1241
+ viewBox: "0 0 24 24",
1242
+ stroke: "currentColor"
1243
+ }, [
1244
+ createElementVNode("path", {
1245
+ "stroke-linecap": "round",
1246
+ "stroke-linejoin": "round",
1247
+ "stroke-width": "1.5",
1248
+ d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
1249
+ })
1250
+ ], -1)),
1251
+ createElementVNode("p", _hoisted_4$5, toDisplayString(__props.errorMessage), 1)
1252
+ ])
1253
+ ])
1254
+ ])) : __props.items && __props.items.length > 0 ? (openBlock(), createBlock(_sfc_main$y, {
1255
+ key: 2,
1256
+ striped: __props.striped,
1257
+ bordered: __props.bordered,
1258
+ hover: __props.hover,
1259
+ compact: __props.compact,
1260
+ "sticky-header": __props.stickyHeader
1261
+ }, {
1262
+ default: withCtx(() => [
1263
+ createVNode(_sfc_main$u, null, {
1264
+ default: withCtx(() => [
1265
+ createVNode(_sfc_main$o, {
1266
+ columns: visibleProperties.value,
1267
+ selectable: __props.selectable,
1268
+ "all-selected": allSelected.value,
1269
+ "some-selected": someSelected.value,
1270
+ "selectable-count": selectableItems.value.length,
1271
+ "sort-by": __props.sortBy,
1272
+ "sort-direction": __props.sortDirection,
1273
+ "show-actions": hasActionSlot.value,
1274
+ onSelectAll: _cache[0] || (_cache[0] = ($event) => emit("selectAll")),
1275
+ onSort: _cache[1] || (_cache[1] = (col, dir) => emit("sort", col, dir))
1276
+ }, createSlots({ _: 2 }, [
1277
+ renderList(visibleProperties.value, (column) => {
1278
+ return {
1279
+ name: `header-${column.name}`,
1280
+ fn: withCtx((slotProps) => [
1281
+ renderSlot(_ctx.$slots, "header-" + column.name, normalizeProps(guardReactiveProps(slotProps)))
1282
+ ])
1283
+ };
1284
+ })
1285
+ ]), 1032, ["columns", "selectable", "all-selected", "some-selected", "selectable-count", "sort-by", "sort-direction", "show-actions"])
1286
+ ]),
1287
+ _: 3
1288
+ }),
1289
+ createVNode(_sfc_main$t, null, {
1290
+ default: withCtx(() => [
1291
+ (openBlock(true), createElementBlock(Fragment, null, renderList(displayItems.value, (item, index) => {
1292
+ return openBlock(), createBlock(_sfc_main$n, {
1293
+ key: getKey(item),
1294
+ item,
1295
+ columns: visibleProperties.value,
1296
+ selectable: __props.selectable,
1297
+ selected: isSelected(item),
1298
+ "can-select": isSelectable(item),
1299
+ clickable: __props.clickableRows,
1300
+ even: index % 2 === 1,
1301
+ "show-actions": hasActionSlot.value,
1302
+ onSelect: ($event) => handleSelect(item),
1303
+ onClick: (e) => handleRowClick(item, e)
1304
+ }, createSlots({
1305
+ actions: withCtx(({ item: rowItem }) => [
1306
+ renderSlot(_ctx.$slots, "action", { item: rowItem })
238
1307
  ]),
239
- onClick: ($event) => handleSort(property)
1308
+ _: 2
240
1309
  }, [
241
- createElementVNode("div", {
242
- class: normalizeClass(["flex items-center gap-1", {
243
- "justify-center": property.align === "center",
244
- "justify-end": property.align === "right"
245
- }])
246
- }, [
247
- renderSlot(_ctx.$slots, "header-" + property.name, { property }, () => [
248
- createTextVNode(toDisplayString(property.label ?? property.name), 1)
249
- ]),
250
- property.sortable ? (openBlock(), createElementBlock("svg", {
251
- key: 0,
252
- class: normalizeClass([
253
- "size-4 transition-colors",
254
- isSortedColumn(property) ? "text-primary-500" : "text-gray-400"
255
- ]),
256
- viewBox: "0 0 24 24",
257
- fill: "currentColor"
258
- }, [
259
- isSortedColumn(property) && __props.sortDirection === "asc" ? (openBlock(), createElementBlock("path", _hoisted_7$3)) : isSortedColumn(property) && __props.sortDirection === "desc" ? (openBlock(), createElementBlock("path", _hoisted_8$3)) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [
260
- _cache[1] || (_cache[1] = createElementVNode("path", {
261
- d: "M7 14l5-5 5 5H7z",
262
- class: "opacity-40"
263
- }, null, -1)),
264
- _cache[2] || (_cache[2] = createElementVNode("path", {
265
- d: "M7 10l5 5 5-5H7z",
266
- class: "opacity-40"
267
- }, null, -1))
268
- ], 64))
269
- ], 2)) : createCommentVNode("", true)
270
- ], 2)
271
- ], 10, _hoisted_6$3);
272
- }), 128)),
273
- hasActionSlot.value ? (openBlock(), createElementBlock("th", _hoisted_9$3)) : createCommentVNode("", true)
274
- ])
275
- ]),
276
- createElementVNode("tbody", _hoisted_10$2, [
277
- (openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item) => {
278
- return openBlock(), createElementBlock("tr", {
279
- key: getKey(item),
280
- class: normalizeClass(["hover:bg-black/5 dark:hover:bg-white/5 transition-colors", { "bg-primary/5 dark:bg-primary/10": isSelected(item) }])
281
- }, [
282
- __props.selectable ? (openBlock(), createElementBlock("td", _hoisted_11$1, [
283
- isSelectable(item) ? (openBlock(), createBlock(_sfc_main$o, {
284
- key: 0,
285
- "model-value": isSelected(item),
286
- "onUpdate:modelValue": ($event) => handleSelect(item)
287
- }, null, 8, ["model-value", "onUpdate:modelValue"])) : createCommentVNode("", true)
288
- ])) : createCommentVNode("", true),
289
- (openBlock(true), createElementBlock(Fragment, null, renderList(visibleProperties.value, (property) => {
290
- return openBlock(), createElementBlock("td", {
291
- key: property.name,
292
- class: normalizeClass([
293
- getAlignmentClass(property.align),
294
- getMainClass(property.main),
295
- property.className,
296
- "px-3 py-4"
297
- ])
298
- }, [
299
- renderSlot(_ctx.$slots, "item-" + property.name, {
300
- item,
301
- property,
302
- value: getItemValue(item, property)
303
- }, () => [
304
- (openBlock(), createBlock(resolveDynamicComponent(getTypeComponent(property.type || "text")), {
305
- value: getItemValue(item, property)
306
- }, null, 8, ["value"]))
307
- ])
308
- ], 2);
309
- }), 128)),
310
- hasActionSlot.value ? (openBlock(), createElementBlock("td", _hoisted_12$1, [
311
- renderSlot(_ctx.$slots, "action", { item })
312
- ])) : createCommentVNode("", true)
313
- ], 2);
314
- }), 128))
315
- ])
1310
+ renderList(visibleProperties.value, (column) => {
1311
+ return {
1312
+ name: `cell-${column.name}`,
1313
+ fn: withCtx((slotProps) => [
1314
+ renderSlot(_ctx.$slots, "item-" + column.name, mergeProps({ ref_for: true }, slotProps))
1315
+ ])
1316
+ };
1317
+ })
1318
+ ]), 1032, ["item", "columns", "selectable", "selected", "can-select", "clickable", "even", "show-actions", "onSelect", "onClick"]);
1319
+ }), 128))
1320
+ ]),
1321
+ _: 3
1322
+ })
316
1323
  ]),
317
- !__props.items || __props.items.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_13, [
318
- renderSlot(_ctx.$slots, "empty")
319
- ])) : createCommentVNode("", true)
320
- ]))
1324
+ _: 3
1325
+ }, 8, ["striped", "bordered", "hover", "compact", "sticky-header"])) : (openBlock(), createElementBlock("div", _hoisted_5$3, [
1326
+ renderSlot(_ctx.$slots, "empty", {}, () => [
1327
+ _cache[3] || (_cache[3] = createElementVNode("div", { class: "flex flex-col items-center gap-3" }, [
1328
+ createElementVNode("svg", {
1329
+ class: "size-12 text-gray-300 dark:text-gray-600",
1330
+ fill: "none",
1331
+ viewBox: "0 0 24 24",
1332
+ stroke: "currentColor"
1333
+ }, [
1334
+ createElementVNode("path", {
1335
+ "stroke-linecap": "round",
1336
+ "stroke-linejoin": "round",
1337
+ "stroke-width": "1.5",
1338
+ d: "M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"
1339
+ })
1340
+ ]),
1341
+ createElementVNode("p", { class: "text-sm text-gray-500 dark:text-gray-400" }, "No data available")
1342
+ ], -1))
1343
+ ])
1344
+ ])),
1345
+ __props.paginated && __props.items && __props.items.length > 0 && !__props.loading && !__props.error ? (openBlock(), createBlock(_sfc_main$J, {
1346
+ key: 4,
1347
+ "current-page": effectivePage.value,
1348
+ "total-pages": effectiveTotalPages.value,
1349
+ "page-size": effectivePageSize.value,
1350
+ "page-size-options": __props.pageSizeOptions,
1351
+ "show-page-size": __props.showPageSize,
1352
+ class: "mt-4",
1353
+ "onUpdate:currentPage": handlePageChange,
1354
+ "onUpdate:pageSize": handlePageSizeChange
1355
+ }, null, 8, ["current-page", "total-pages", "page-size", "page-size-options", "show-page-size"])) : createCommentVNode("", true)
321
1356
  ]);
322
1357
  };
323
1358
  }
324
1359
  });
325
1360
  const _hoisted_1$f = { class: "space-y-3" };
326
- const _hoisted_2$b = { class: "flex items-center gap-3 p-3" };
1361
+ const _hoisted_2$c = { class: "flex items-center gap-3 p-3" };
327
1362
  const _hoisted_3$6 = { class: "text-sm text-gray-600 dark:text-gray-400" };
328
1363
  const _hoisted_4$4 = {
329
1364
  key: 0,
@@ -391,9 +1426,9 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
391
1426
  const hasEmptySlot = computed(() => !!slots.empty);
392
1427
  return (_ctx, _cache) => {
393
1428
  return openBlock(), createElementBlock("div", _hoisted_1$f, [
394
- __props.loading ? (openBlock(), createBlock(_sfc_main$l, { key: 0 }, {
1429
+ __props.loading ? (openBlock(), createBlock(_sfc_main$A, { key: 0 }, {
395
1430
  default: withCtx(() => [
396
- createVNode(_sfc_main$u, {
1431
+ createVNode(_sfc_main$K, {
397
1432
  items: __props.loadingItems,
398
1433
  "show-avatar": "",
399
1434
  "show-secondary": "",
@@ -402,10 +1437,10 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
402
1437
  ]),
403
1438
  _: 1
404
1439
  })) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
405
- __props.selectable && selectableItems.value.length > 0 ? (openBlock(), createBlock(_sfc_main$l, { key: 0 }, {
1440
+ __props.selectable && selectableItems.value.length > 0 ? (openBlock(), createBlock(_sfc_main$A, { key: 0 }, {
406
1441
  default: withCtx(() => [
407
- createElementVNode("div", _hoisted_2$b, [
408
- createVNode(_sfc_main$o, {
1442
+ createElementVNode("div", _hoisted_2$c, [
1443
+ createVNode(_sfc_main$C, {
409
1444
  "model-value": allSelected.value,
410
1445
  indeterminate: someSelected.value,
411
1446
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => emit("selectAll"))
@@ -417,7 +1452,7 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
417
1452
  _: 1
418
1453
  })) : createCommentVNode("", true),
419
1454
  (openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item) => {
420
- return openBlock(), createBlock(_sfc_main$l, {
1455
+ return openBlock(), createBlock(_sfc_main$A, {
421
1456
  key: getKey(item),
422
1457
  class: normalizeClass(["hover:shadow-lg transition-all duration-200", {
423
1458
  "ring-2 ring-primary": isSelected(item)
@@ -426,7 +1461,7 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
426
1461
  default: withCtx(() => [
427
1462
  createElementVNode("div", _hoisted_5$2, [
428
1463
  __props.selectable ? (openBlock(), createElementBlock("div", _hoisted_6$2, [
429
- isSelectable(item) ? (openBlock(), createBlock(_sfc_main$o, {
1464
+ isSelectable(item) ? (openBlock(), createBlock(_sfc_main$C, {
430
1465
  key: 0,
431
1466
  "model-value": isSelected(item),
432
1467
  "onUpdate:modelValue": ($event) => handleSelect(item)
@@ -538,9 +1573,9 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
538
1573
  renderSlot(_ctx.$slots, "empty")
539
1574
  ]),
540
1575
  _: 3
541
- }, 8, ["items", "key-field", "selectable", "selected-items", "selectable-filter", "loading", "loading-items"])) : (openBlock(), createBlock(_sfc_main$l, { key: 1 }, {
1576
+ }, 8, ["items", "key-field", "selectable", "selected-items", "selectable-filter", "loading", "loading-items"])) : (openBlock(), createBlock(_sfc_main$A, { key: 1 }, {
542
1577
  default: withCtx(() => [
543
- createVNode(_sfc_main$k, {
1578
+ createVNode(unref(_sfc_main$k), {
544
1579
  items: __props.items,
545
1580
  properties: tableProperties.value,
546
1581
  "key-field": __props.keyField,
@@ -593,7 +1628,7 @@ const _hoisted_1$e = {
593
1628
  key: 0,
594
1629
  class: "mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"
595
1630
  };
596
- const _hoisted_2$a = { class: "relative" };
1631
+ const _hoisted_2$b = { class: "relative" };
597
1632
  const _hoisted_3$5 = ["disabled", "placeholder"];
598
1633
  const _hoisted_4$3 = ["disabled"];
599
1634
  const _hoisted_5$1 = {
@@ -710,7 +1745,7 @@ const _sfc_main$h = /* @__PURE__ */ defineComponent({
710
1745
  class: "autocomplete-container"
711
1746
  }, [
712
1747
  __props.label ? (openBlock(), createElementBlock("label", _hoisted_1$e, toDisplayString(__props.label), 1)) : createCommentVNode("", true),
713
- createElementVNode("div", _hoisted_2$a, [
1748
+ createElementVNode("div", _hoisted_2$b, [
714
1749
  createElementVNode("div", {
715
1750
  ref_key: "inputWrapperRef",
716
1751
  ref: inputWrapperRef,
@@ -886,7 +1921,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
886
1921
  }
887
1922
  });
888
1923
  const _hoisted_1$d = { class: "relative inline-block" };
889
- const _hoisted_2$9 = ["src", "alt"];
1924
+ const _hoisted_2$a = ["src", "alt"];
890
1925
  const _hoisted_3$4 = { key: 1 };
891
1926
  const _sfc_main$f = /* @__PURE__ */ defineComponent({
892
1927
  __name: "Avatar",
@@ -1008,7 +2043,7 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
1008
2043
  alt: __props.alt || __props.name,
1009
2044
  class: "size-full object-cover",
1010
2045
  onError: _cache[0] || (_cache[0] = ($event) => imageError.value = true)
1011
- }, null, 40, _hoisted_2$9)) : initials.value ? (openBlock(), createElementBlock("span", _hoisted_3$4, toDisplayString(initials.value), 1)) : (openBlock(), createBlock(unref(Icon), {
2046
+ }, null, 40, _hoisted_2$a)) : initials.value ? (openBlock(), createElementBlock("span", _hoisted_3$4, toDisplayString(initials.value), 1)) : (openBlock(), createBlock(unref(Icon), {
1012
2047
  key: 2,
1013
2048
  icon: "lucide:user",
1014
2049
  class: "size-1/2"
@@ -1027,7 +2062,7 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
1027
2062
  }
1028
2063
  });
1029
2064
  const _hoisted_1$c = ["aria-selected", "disabled", "onClick"];
1030
- const _hoisted_2$8 = { class: "mt-4" };
2065
+ const _hoisted_2$9 = { class: "mt-4" };
1031
2066
  const _sfc_main$e = /* @__PURE__ */ defineComponent({
1032
2067
  __name: "Tabs",
1033
2068
  props: {
@@ -1096,7 +2131,7 @@ const _sfc_main$e = /* @__PURE__ */ defineComponent({
1096
2131
  }, toDisplayString(tab.label), 11, _hoisted_1$c);
1097
2132
  }), 128))
1098
2133
  ], 2),
1099
- createElementVNode("div", _hoisted_2$8, [
2134
+ createElementVNode("div", _hoisted_2$9, [
1100
2135
  renderSlot(_ctx.$slots, "default", { activeTab: activeTab.value })
1101
2136
  ])
1102
2137
  ]);
@@ -1241,7 +2276,7 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
1241
2276
  };
1242
2277
  const hasCustomHeader = () => !!slots.header;
1243
2278
  return (_ctx, _cache) => {
1244
- return openBlock(), createBlock(_sfc_main$l, null, createSlots({
2279
+ return openBlock(), createBlock(_sfc_main$A, null, createSlots({
1245
2280
  default: withCtx(() => [
1246
2281
  createVNode(Transition, {
1247
2282
  "enter-active-class": "transition-all duration-200 ease-out",
@@ -1320,7 +2355,7 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
1320
2355
  }
1321
2356
  });
1322
2357
  const _hoisted_1$9 = ["aria-describedby"];
1323
- const _hoisted_2$7 = ["id"];
2358
+ const _hoisted_2$8 = ["id"];
1324
2359
  const _sfc_main$a = /* @__PURE__ */ defineComponent({
1325
2360
  __name: "Tooltip",
1326
2361
  props: {
@@ -1392,7 +2427,7 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
1392
2427
  id: unref(tooltipId),
1393
2428
  class: normalizeClass(positionClasses.value),
1394
2429
  role: "tooltip"
1395
- }, toDisplayString(__props.content), 11, _hoisted_2$7)) : createCommentVNode("", true)
2430
+ }, toDisplayString(__props.content), 11, _hoisted_2$8)) : createCommentVNode("", true)
1396
2431
  ]),
1397
2432
  _: 1
1398
2433
  })
@@ -1401,7 +2436,7 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
1401
2436
  }
1402
2437
  });
1403
2438
  const _hoisted_1$8 = ["id", "aria-expanded", "aria-controls"];
1404
- const _hoisted_2$6 = ["id", "aria-labelledby"];
2439
+ const _hoisted_2$7 = ["id", "aria-labelledby"];
1405
2440
  const _sfc_main$9 = /* @__PURE__ */ defineComponent({
1406
2441
  __name: "Popover",
1407
2442
  props: {
@@ -1486,7 +2521,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
1486
2521
  ])
1487
2522
  }, [
1488
2523
  renderSlot(_ctx.$slots, "default", { close: unref(close) })
1489
- ], 14, _hoisted_2$6)) : createCommentVNode("", true)
2524
+ ], 14, _hoisted_2$7)) : createCommentVNode("", true)
1490
2525
  ]),
1491
2526
  _: 3
1492
2527
  })
@@ -1499,7 +2534,7 @@ const _hoisted_1$7 = {
1499
2534
  key: 0,
1500
2535
  class: "flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-gray-700"
1501
2536
  };
1502
- const _hoisted_2$5 = { class: "text-lg font-semibold text-gray-900 dark:text-white" };
2537
+ const _hoisted_2$6 = { class: "text-lg font-semibold text-gray-900 dark:text-white" };
1503
2538
  const _hoisted_3$3 = { class: "flex-1 overflow-y-auto p-4" };
1504
2539
  const _hoisted_4$2 = {
1505
2540
  key: 1,
@@ -1626,7 +2661,7 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
1626
2661
  }, [
1627
2662
  __props.title || __props.showClose || _ctx.$slots.header ? (openBlock(), createElementBlock("div", _hoisted_1$7, [
1628
2663
  renderSlot(_ctx.$slots, "header", {}, () => [
1629
- createElementVNode("h2", _hoisted_2$5, toDisplayString(__props.title), 1)
2664
+ createElementVNode("h2", _hoisted_2$6, toDisplayString(__props.title), 1)
1630
2665
  ]),
1631
2666
  __props.showClose ? (openBlock(), createElementBlock("button", {
1632
2667
  key: 0,
@@ -1655,7 +2690,7 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
1655
2690
  }
1656
2691
  });
1657
2692
  const _hoisted_1$6 = { "aria-label": "Breadcrumb" };
1658
- const _hoisted_2$4 = { class: "flex items-center flex-wrap gap-1 text-sm" };
2693
+ const _hoisted_2$5 = { class: "flex items-center flex-wrap gap-1 text-sm" };
1659
2694
  const _sfc_main$7 = /* @__PURE__ */ defineComponent({
1660
2695
  __name: "Breadcrumb",
1661
2696
  props: {
@@ -1668,7 +2703,7 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
1668
2703
  setup(__props) {
1669
2704
  return (_ctx, _cache) => {
1670
2705
  return openBlock(), createElementBlock("nav", _hoisted_1$6, [
1671
- createElementVNode("ol", _hoisted_2$4, [
2706
+ createElementVNode("ol", _hoisted_2$5, [
1672
2707
  (openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item, index) => {
1673
2708
  return openBlock(), createElementBlock("li", {
1674
2709
  key: index,
@@ -1744,7 +2779,7 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
1744
2779
  }
1745
2780
  });
1746
2781
  const _hoisted_1$4 = ["id", "disabled", "aria-expanded", "aria-controls"];
1747
- const _hoisted_2$3 = { class: "flex items-center gap-2 font-medium" };
2782
+ const _hoisted_2$4 = { class: "flex items-center gap-2 font-medium" };
1748
2783
  const _hoisted_3$2 = ["id", "aria-labelledby"];
1749
2784
  const _hoisted_4$1 = { class: "px-4 py-3 bg-gray-50 dark:bg-gray-900 text-gray-700 dark:text-gray-300" };
1750
2785
  const _sfc_main$5 = /* @__PURE__ */ defineComponent({
@@ -1781,7 +2816,7 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
1781
2816
  "aria-controls": panelId.value,
1782
2817
  onClick: toggle
1783
2818
  }, [
1784
- createElementVNode("span", _hoisted_2$3, [
2819
+ createElementVNode("span", _hoisted_2$4, [
1785
2820
  __props.icon ? (openBlock(), createBlock(unref(Icon), {
1786
2821
  key: 0,
1787
2822
  icon: __props.icon,
@@ -1828,7 +2863,7 @@ const _hoisted_1$3 = {
1828
2863
  key: 0,
1829
2864
  class: "relative"
1830
2865
  };
1831
- const _hoisted_2$2 = { class: "flex items-start gap-4" };
2866
+ const _hoisted_2$3 = { class: "flex items-start gap-4" };
1832
2867
  const _hoisted_3$1 = { class: "flex-1 min-w-0 pt-0.5" };
1833
2868
  const _hoisted_4 = { class: "flex items-center justify-between gap-2" };
1834
2869
  const _hoisted_5 = { class: "text-sm font-medium text-gray-900 dark:text-white" };
@@ -1907,7 +2942,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
1907
2942
  key: 0,
1908
2943
  class: normalizeClass(["absolute left-4 top-8 w-0.5 h-full -ml-px", getStatusClasses(item.status).line])
1909
2944
  }, null, 2)) : createCommentVNode("", true),
1910
- createElementVNode("div", _hoisted_2$2, [
2945
+ createElementVNode("div", _hoisted_2$3, [
1911
2946
  createElementVNode("div", {
1912
2947
  class: normalizeClass(["relative z-10 flex items-center justify-center size-8 rounded-full shrink-0", getStatusClasses(item.status).dot])
1913
2948
  }, [
@@ -1960,7 +2995,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
1960
2995
  }
1961
2996
  });
1962
2997
  const _hoisted_1$2 = ["aria-label"];
1963
- const _hoisted_2$1 = {
2998
+ const _hoisted_2$2 = {
1964
2999
  key: 0,
1965
3000
  class: "text-sm font-medium"
1966
3001
  };
@@ -1999,129 +3034,258 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
1999
3034
  icon: unref(isDark) ? __props.darkIcon : __props.lightIcon,
2000
3035
  class: normalizeClass(sizeClasses[__props.size].icon)
2001
3036
  }, null, 8, ["icon", "class"]),
2002
- __props.showLabel ? (openBlock(), createElementBlock("span", _hoisted_2$1, toDisplayString(unref(isDark) ? "Dark" : "Light"), 1)) : createCommentVNode("", true)
3037
+ __props.showLabel ? (openBlock(), createElementBlock("span", _hoisted_2$2, toDisplayString(unref(isDark) ? "Dark" : "Light"), 1)) : createCommentVNode("", true)
2003
3038
  ], 10, _hoisted_1$2);
2004
3039
  };
2005
3040
  }
2006
3041
  });
2007
- const _hoisted_1$1 = {
2008
- key: 0,
3042
+ const _hoisted_1$1 = { key: 0 };
3043
+ const _hoisted_2$1 = {
3044
+ key: 1,
2009
3045
  class: "text-gray-400"
2010
3046
  };
2011
3047
  const _sfc_main$2 = /* @__PURE__ */ defineComponent({
2012
- __name: "StatsCard",
3048
+ __name: "StatItem",
2013
3049
  props: {
2014
3050
  label: {},
2015
3051
  value: {},
2016
3052
  icon: {},
3053
+ iconPosition: { default: "top" },
2017
3054
  change: {},
2018
3055
  changeLabel: {},
3056
+ trend: {},
3057
+ trendOnly: { type: Boolean, default: false },
3058
+ size: { default: "md" },
2019
3059
  variant: { default: "default" },
2020
- color: { default: "primary" }
3060
+ color: { default: "primary" },
3061
+ clickable: { type: Boolean, default: false },
3062
+ centered: { type: Boolean },
3063
+ cardClass: {},
3064
+ iconClass: {},
3065
+ valueClass: {},
3066
+ labelClass: {}
2021
3067
  },
3068
+ emits: ["click"],
2022
3069
  setup(__props) {
3070
+ const props = __props;
3071
+ const isCentered = computed(() => {
3072
+ if (props.centered !== void 0) return props.centered;
3073
+ return props.iconPosition === "top";
3074
+ });
3075
+ const effectiveTrend = computed(() => {
3076
+ if (props.trend) return props.trend;
3077
+ if (props.change === void 0) return void 0;
3078
+ if (props.change > 0) return "up";
3079
+ if (props.change < 0) return "down";
3080
+ return "neutral";
3081
+ });
3082
+ const sizeClasses = computed(() => {
3083
+ const sizes = {
3084
+ sm: {
3085
+ padding: "sm",
3086
+ icon: "size-8",
3087
+ iconInner: "size-4",
3088
+ value: "text-xl font-bold",
3089
+ label: "text-xs",
3090
+ change: "text-xs",
3091
+ gap: "gap-1"
3092
+ },
3093
+ md: {
3094
+ padding: "md",
3095
+ icon: "size-10",
3096
+ iconInner: "size-5",
3097
+ value: "text-2xl sm:text-3xl font-bold",
3098
+ label: "text-xs sm:text-sm",
3099
+ change: "text-xs",
3100
+ gap: "gap-2"
3101
+ },
3102
+ lg: {
3103
+ padding: "lg",
3104
+ icon: "size-12",
3105
+ iconInner: "size-6",
3106
+ value: "text-3xl sm:text-4xl font-bold",
3107
+ label: "text-sm sm:text-base",
3108
+ change: "text-sm",
3109
+ gap: "gap-3"
3110
+ }
3111
+ };
3112
+ return sizes[props.size];
3113
+ });
3114
+ const iconBgClasses = computed(() => {
3115
+ if (props.variant === "glass") return "bg-white/20";
3116
+ const colors = {
3117
+ primary: "bg-primary-100 dark:bg-primary-900/30",
3118
+ secondary: "bg-secondary-100 dark:bg-secondary-900/30",
3119
+ success: "bg-emerald-100 dark:bg-emerald-900/30",
3120
+ warning: "bg-amber-100 dark:bg-amber-900/30",
3121
+ danger: "bg-red-100 dark:bg-red-900/30",
3122
+ info: "bg-blue-100 dark:bg-blue-900/30"
3123
+ };
3124
+ return colors[props.color];
3125
+ });
3126
+ const iconColorClasses = computed(() => {
3127
+ if (props.variant === "glass") return "text-white";
3128
+ const colors = {
3129
+ primary: "text-primary-600 dark:text-primary-400",
3130
+ secondary: "text-secondary-600 dark:text-secondary-400",
3131
+ success: "text-emerald-600 dark:text-emerald-400",
3132
+ warning: "text-amber-600 dark:text-amber-400",
3133
+ danger: "text-red-600 dark:text-red-400",
3134
+ info: "text-blue-600 dark:text-blue-400"
3135
+ };
3136
+ return colors[props.color];
3137
+ });
3138
+ const valueTextClasses = computed(() => {
3139
+ if (props.variant === "glass") return "text-white";
3140
+ return "text-gray-900 dark:text-white";
3141
+ });
3142
+ const labelTextClasses = computed(() => {
3143
+ if (props.variant === "glass") return "text-white/80";
3144
+ return "text-gray-500 dark:text-gray-400";
3145
+ });
3146
+ const trendColorClasses = computed(() => {
3147
+ if (!effectiveTrend.value || effectiveTrend.value === "neutral") {
3148
+ return "text-gray-500";
3149
+ }
3150
+ return effectiveTrend.value === "up" ? "text-emerald-500" : "text-red-500";
3151
+ });
3152
+ const trendIcon = computed(() => {
3153
+ if (!effectiveTrend.value || effectiveTrend.value === "neutral") {
3154
+ return "heroicons:minus";
3155
+ }
3156
+ return effectiveTrend.value === "up" ? "heroicons:arrow-trending-up" : "heroicons:arrow-trending-down";
3157
+ });
3158
+ const cardVariant = computed(() => {
3159
+ const map = {
3160
+ default: "default",
3161
+ glass: "glass",
3162
+ outline: "outline",
3163
+ flat: "flat"
3164
+ };
3165
+ return map[props.variant];
3166
+ });
3167
+ const layoutClasses = computed(() => {
3168
+ if (props.iconPosition === "top") {
3169
+ return isCentered.value ? "flex flex-col items-center text-center" : "flex flex-col";
3170
+ }
3171
+ if (props.iconPosition === "left") {
3172
+ return "flex flex-row items-center";
3173
+ }
3174
+ return "flex flex-row-reverse items-center";
3175
+ });
3176
+ const contentClasses = computed(() => {
3177
+ if (props.iconPosition === "top") {
3178
+ return "flex flex-col " + sizeClasses.value.gap;
3179
+ }
3180
+ return "flex flex-col flex-1 min-w-0 " + (props.iconPosition === "left" ? "ml-3" : "mr-3");
3181
+ });
2023
3182
  return (_ctx, _cache) => {
2024
- return openBlock(), createElementBlock("div", {
2025
- class: normalizeClass([
2026
- "rounded-2xl p-4 text-center transition-all",
2027
- __props.variant === "default" && "bg-white dark:bg-slate-800 border border-gray-100 dark:border-slate-700 shadow-sm",
2028
- __props.variant === "glass" && "bg-white/15 backdrop-blur-sm border border-white/20",
2029
- __props.variant === "outline" && "border-2 border-gray-200 dark:border-slate-600",
2030
- __props.variant === "solid" && __props.color === "primary" && "bg-primary-500 text-white",
2031
- __props.variant === "solid" && __props.color === "success" && "bg-emerald-500 text-white",
2032
- __props.variant === "solid" && __props.color === "warning" && "bg-amber-500 text-white",
2033
- __props.variant === "solid" && __props.color === "danger" && "bg-red-500 text-white",
2034
- __props.variant === "solid" && __props.color === "info" && "bg-blue-500 text-white"
2035
- ])
2036
- }, [
2037
- __props.icon ? (openBlock(), createElementBlock("div", {
2038
- key: 0,
2039
- class: normalizeClass([
2040
- "size-10 mx-auto mb-2 rounded-xl flex items-center justify-center",
2041
- __props.variant === "glass" && "bg-white/20",
2042
- __props.variant === "solid" && "bg-white/20",
2043
- __props.variant === "default" && __props.color === "primary" && "bg-primary-100 dark:bg-primary-900/30",
2044
- __props.variant === "default" && __props.color === "success" && "bg-emerald-100 dark:bg-emerald-900/30",
2045
- __props.variant === "default" && __props.color === "warning" && "bg-amber-100 dark:bg-amber-900/30",
2046
- __props.variant === "default" && __props.color === "danger" && "bg-red-100 dark:bg-red-900/30",
2047
- __props.variant === "default" && __props.color === "info" && "bg-blue-100 dark:bg-blue-900/30",
2048
- __props.variant === "outline" && "bg-gray-100 dark:bg-slate-700"
2049
- ])
2050
- }, [
2051
- createVNode(unref(Icon), {
2052
- icon: __props.icon,
2053
- class: normalizeClass([
2054
- "size-5",
2055
- (__props.variant === "glass" || __props.variant === "solid") && "text-white",
2056
- __props.variant === "default" && __props.color === "primary" && "text-primary-600 dark:text-primary-400",
2057
- __props.variant === "default" && __props.color === "success" && "text-emerald-600 dark:text-emerald-400",
2058
- __props.variant === "default" && __props.color === "warning" && "text-amber-600 dark:text-amber-400",
2059
- __props.variant === "default" && __props.color === "danger" && "text-red-600 dark:text-red-400",
2060
- __props.variant === "default" && __props.color === "info" && "text-blue-600 dark:text-blue-400",
2061
- __props.variant === "outline" && "text-gray-600 dark:text-gray-400"
2062
- ])
2063
- }, null, 8, ["icon", "class"])
2064
- ], 2)) : createCommentVNode("", true),
2065
- createElementVNode("div", {
2066
- class: normalizeClass([
2067
- "text-2xl sm:text-3xl font-bold",
2068
- (__props.variant === "glass" || __props.variant === "solid") && "text-white",
2069
- (__props.variant === "default" || __props.variant === "outline") && "text-gray-900 dark:text-white"
2070
- ])
2071
- }, [
2072
- renderSlot(_ctx.$slots, "value", {}, () => [
2073
- createTextVNode(toDisplayString(__props.value), 1)
2074
- ])
2075
- ], 2),
2076
- createElementVNode("div", {
2077
- class: normalizeClass([
2078
- "text-xs sm:text-sm",
2079
- __props.variant === "glass" && "text-white/80",
2080
- __props.variant === "solid" && "text-white/90",
2081
- (__props.variant === "default" || __props.variant === "outline") && "text-gray-500 dark:text-gray-400"
2082
- ])
2083
- }, [
2084
- renderSlot(_ctx.$slots, "label", {}, () => [
2085
- createTextVNode(toDisplayString(__props.label), 1)
2086
- ])
2087
- ], 2),
2088
- __props.change !== void 0 ? (openBlock(), createElementBlock("div", {
2089
- key: 1,
2090
- class: normalizeClass([
2091
- "mt-2 text-xs font-medium inline-flex items-center gap-1",
2092
- __props.change >= 0 ? "text-emerald-500" : "text-red-500"
2093
- ])
2094
- }, [
2095
- createVNode(unref(Icon), {
2096
- icon: __props.change >= 0 ? "heroicons:arrow-trending-up" : "heroicons:arrow-trending-down",
2097
- class: "size-3.5"
2098
- }, null, 8, ["icon"]),
2099
- createElementVNode("span", null, toDisplayString(__props.change >= 0 ? "+" : "") + toDisplayString(__props.change) + "%", 1),
2100
- __props.changeLabel ? (openBlock(), createElementBlock("span", _hoisted_1$1, toDisplayString(__props.changeLabel), 1)) : createCommentVNode("", true)
2101
- ], 2)) : createCommentVNode("", true)
2102
- ], 2);
3183
+ return openBlock(), createBlock(_sfc_main$z, {
3184
+ variant: cardVariant.value,
3185
+ padding: sizeClasses.value.padding,
3186
+ clickable: __props.clickable,
3187
+ shadow: __props.variant === "glass" ? "none" : "sm",
3188
+ border: __props.variant === "outline" ? "default" : "none",
3189
+ rounded: "xl",
3190
+ "header-divider": false,
3191
+ class: normalizeClass(__props.cardClass),
3192
+ onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("click", $event))
3193
+ }, {
3194
+ default: withCtx(() => [
3195
+ createElementVNode("div", {
3196
+ class: normalizeClass(layoutClasses.value)
3197
+ }, [
3198
+ __props.icon ? (openBlock(), createElementBlock("div", {
3199
+ key: 0,
3200
+ class: normalizeClass([
3201
+ "rounded-xl flex items-center justify-center flex-shrink-0",
3202
+ sizeClasses.value.icon,
3203
+ iconBgClasses.value,
3204
+ __props.iconPosition === "top" && "mb-2",
3205
+ __props.iconClass
3206
+ ])
3207
+ }, [
3208
+ renderSlot(_ctx.$slots, "icon", {}, () => [
3209
+ createVNode(unref(Icon), {
3210
+ icon: __props.icon,
3211
+ class: normalizeClass([sizeClasses.value.iconInner, iconColorClasses.value])
3212
+ }, null, 8, ["icon", "class"])
3213
+ ])
3214
+ ], 2)) : createCommentVNode("", true),
3215
+ createElementVNode("div", {
3216
+ class: normalizeClass(contentClasses.value)
3217
+ }, [
3218
+ createElementVNode("div", {
3219
+ class: normalizeClass([sizeClasses.value.value, valueTextClasses.value, __props.valueClass])
3220
+ }, [
3221
+ renderSlot(_ctx.$slots, "value", {}, () => [
3222
+ createTextVNode(toDisplayString(__props.value), 1)
3223
+ ])
3224
+ ], 2),
3225
+ createElementVNode("div", {
3226
+ class: normalizeClass([sizeClasses.value.label, labelTextClasses.value, __props.labelClass])
3227
+ }, [
3228
+ renderSlot(_ctx.$slots, "label", {}, () => [
3229
+ createTextVNode(toDisplayString(__props.label), 1)
3230
+ ])
3231
+ ], 2),
3232
+ __props.change !== void 0 || __props.trend ? (openBlock(), createElementBlock("div", {
3233
+ key: 0,
3234
+ class: normalizeClass([
3235
+ "mt-1 font-medium inline-flex items-center gap-1",
3236
+ sizeClasses.value.change,
3237
+ trendColorClasses.value
3238
+ ])
3239
+ }, [
3240
+ createVNode(unref(Icon), {
3241
+ icon: trendIcon.value,
3242
+ class: "size-3.5"
3243
+ }, null, 8, ["icon"]),
3244
+ !__props.trendOnly && __props.change !== void 0 ? (openBlock(), createElementBlock("span", _hoisted_1$1, toDisplayString(__props.change >= 0 ? "+" : "") + toDisplayString(__props.change) + "% ", 1)) : createCommentVNode("", true),
3245
+ __props.changeLabel ? (openBlock(), createElementBlock("span", _hoisted_2$1, toDisplayString(__props.changeLabel), 1)) : createCommentVNode("", true)
3246
+ ], 2)) : createCommentVNode("", true)
3247
+ ], 2)
3248
+ ], 2),
3249
+ renderSlot(_ctx.$slots, "extra")
3250
+ ]),
3251
+ _: 3
3252
+ }, 8, ["variant", "padding", "clickable", "shadow", "border", "class"]);
2103
3253
  };
2104
3254
  }
2105
3255
  });
2106
3256
  const _sfc_main$1 = /* @__PURE__ */ defineComponent({
2107
- __name: "StatsGrid",
3257
+ __name: "Stats",
2108
3258
  props: {
2109
3259
  stats: {},
2110
3260
  cols: {},
3261
+ gap: { default: "md" },
2111
3262
  variant: { default: "default" },
3263
+ size: { default: "md" },
3264
+ iconPosition: { default: "top" },
2112
3265
  color: { default: "primary" }
2113
3266
  },
2114
3267
  setup(__props) {
2115
3268
  return (_ctx, _cache) => {
3269
+ var _a, _b, _c, _d;
2116
3270
  return openBlock(), createElementBlock("div", {
2117
- class: normalizeClass(["grid gap-3 sm:gap-4", [
3271
+ class: normalizeClass(["grid", [
3272
+ // Gap classes
3273
+ __props.gap === "sm" && "gap-2 sm:gap-3",
3274
+ __props.gap === "md" && "gap-3 sm:gap-4",
3275
+ __props.gap === "lg" && "gap-4 sm:gap-6",
3276
+ // Column classes
3277
+ __props.cols === 1 && "grid-cols-1",
2118
3278
  __props.cols === 2 && "grid-cols-2",
2119
3279
  __props.cols === 3 && "grid-cols-3",
2120
3280
  __props.cols === 4 && "grid-cols-2 sm:grid-cols-4",
2121
- !__props.cols && __props.stats.length === 2 && "grid-cols-2",
2122
- !__props.cols && __props.stats.length === 3 && "grid-cols-3",
2123
- !__props.cols && __props.stats.length === 4 && "grid-cols-2 sm:grid-cols-4",
2124
- !__props.cols && __props.stats.length > 4 && "grid-cols-2 sm:grid-cols-3 lg:grid-cols-4"
3281
+ __props.cols === 5 && "grid-cols-2 sm:grid-cols-3 lg:grid-cols-5",
3282
+ __props.cols === 6 && "grid-cols-2 sm:grid-cols-3 lg:grid-cols-6",
3283
+ // Auto columns based on stats length
3284
+ !__props.cols && ((_a = __props.stats) == null ? void 0 : _a.length) === 1 && "grid-cols-1",
3285
+ !__props.cols && ((_b = __props.stats) == null ? void 0 : _b.length) === 2 && "grid-cols-2",
3286
+ !__props.cols && ((_c = __props.stats) == null ? void 0 : _c.length) === 3 && "grid-cols-3",
3287
+ !__props.cols && ((_d = __props.stats) == null ? void 0 : _d.length) === 4 && "grid-cols-2 sm:grid-cols-4",
3288
+ !__props.cols && __props.stats && __props.stats.length > 4 && "grid-cols-2 sm:grid-cols-3 lg:grid-cols-4"
2125
3289
  ]])
2126
3290
  }, [
2127
3291
  (openBlock(true), createElementBlock(Fragment, null, renderList(__props.stats, (stat, index) => {
@@ -2132,10 +3296,14 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
2132
3296
  icon: stat.icon,
2133
3297
  change: stat.change,
2134
3298
  "change-label": stat.changeLabel,
3299
+ trend: stat.trend,
2135
3300
  variant: __props.variant,
2136
- color: __props.color
2137
- }, null, 8, ["label", "value", "icon", "change", "change-label", "variant", "color"]);
2138
- }), 128))
3301
+ size: __props.size,
3302
+ "icon-position": __props.iconPosition,
3303
+ color: stat.color || __props.color
3304
+ }, null, 8, ["label", "value", "icon", "change", "change-label", "trend", "variant", "size", "icon-position", "color"]);
3305
+ }), 128)),
3306
+ renderSlot(_ctx.$slots, "default")
2139
3307
  ], 2);
2140
3308
  };
2141
3309
  }
@@ -2277,27 +3445,43 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2277
3445
  }
2278
3446
  });
2279
3447
  export {
2280
- _sfc_main$l as _,
2281
- _sfc_main$k as a,
2282
- _sfc_main$j as b,
2283
- _sfc_main$i as c,
2284
- _sfc_main$h as d,
2285
- _sfc_main$g as e,
2286
- _sfc_main$f as f,
2287
- _sfc_main$e as g,
2288
- _sfc_main$d as h,
2289
- _sfc_main$c as i,
2290
- _sfc_main$b as j,
2291
- _sfc_main$a as k,
2292
- _sfc_main$9 as l,
2293
- _sfc_main$8 as m,
2294
- _sfc_main$7 as n,
2295
- _sfc_main$6 as o,
2296
- _sfc_main$5 as p,
2297
- _sfc_main$4 as q,
2298
- _sfc_main$3 as r,
2299
- _sfc_main$2 as s,
2300
- _sfc_main$1 as t,
2301
- _sfc_main as u
3448
+ _sfc_main$9 as A,
3449
+ _sfc_main$8 as B,
3450
+ _sfc_main$7 as C,
3451
+ _sfc_main$6 as D,
3452
+ _sfc_main$5 as E,
3453
+ _sfc_main$4 as F,
3454
+ _sfc_main$3 as G,
3455
+ _sfc_main$2 as H,
3456
+ _sfc_main$1 as I,
3457
+ _sfc_main as J,
3458
+ TableContextKey as T,
3459
+ _sfc_main$A as _,
3460
+ _sfc_main$z as a,
3461
+ _sfc_main$y as b,
3462
+ _sfc_main$x as c,
3463
+ _sfc_main$w as d,
3464
+ _sfc_main$v as e,
3465
+ _sfc_main$u as f,
3466
+ _sfc_main$t as g,
3467
+ _sfc_main$s as h,
3468
+ _sfc_main$r as i,
3469
+ _sfc_main$q as j,
3470
+ _sfc_main$p as k,
3471
+ _sfc_main$o as l,
3472
+ _sfc_main$n as m,
3473
+ _sfc_main$m as n,
3474
+ _sfc_main$l as o,
3475
+ _sfc_main$k as p,
3476
+ _sfc_main$j as q,
3477
+ _sfc_main$i as r,
3478
+ _sfc_main$h as s,
3479
+ _sfc_main$g as t,
3480
+ _sfc_main$f as u,
3481
+ _sfc_main$e as v,
3482
+ _sfc_main$d as w,
3483
+ _sfc_main$c as x,
3484
+ _sfc_main$b as y,
3485
+ _sfc_main$a as z
2302
3486
  };
2303
- //# sourceMappingURL=FilterTabs.vue_vue_type_script_setup_true_lang-BmJHgkBs.js.map
3487
+ //# sourceMappingURL=FilterTabs.vue_vue_type_script_setup_true_lang-CJnvcF8Z.js.map