cisse-vue-ui 0.5.21 → 0.5.22

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 (88) hide show
  1. package/dist/{ListSkeleton.vue_vue_type_script_setup_true_lang-D3_Oddwt.js → Button.vue_vue_type_script_setup_true_lang-DKE8elsf.js} +102 -7
  2. package/dist/Button.vue_vue_type_script_setup_true_lang-DKE8elsf.js.map +1 -0
  3. package/dist/{ListSkeleton.vue_vue_type_script_setup_true_lang-CrEu33_J.cjs → Button.vue_vue_type_script_setup_true_lang-DrGM65ny.cjs} +101 -6
  4. package/dist/Button.vue_vue_type_script_setup_true_lang-DrGM65ny.cjs.map +1 -0
  5. package/dist/{RangeSlider.vue_vue_type_script_setup_true_lang-B79_S1JL.js → Combobox.vue_vue_type_script_setup_true_lang-DhcLb6DX.js} +408 -185
  6. package/dist/Combobox.vue_vue_type_script_setup_true_lang-DhcLb6DX.js.map +1 -0
  7. package/dist/{RangeSlider.vue_vue_type_script_setup_true_lang-ClH-pyK8.cjs → Combobox.vue_vue_type_script_setup_true_lang-FdUrjmSG.cjs} +435 -212
  8. package/dist/Combobox.vue_vue_type_script_setup_true_lang-FdUrjmSG.cjs.map +1 -0
  9. package/dist/{Skeleton.vue_vue_type_script_setup_true_lang-Q4PcIELi.js → ConfirmDialog.vue_vue_type_script_setup_true_lang-CNucAMQg.js} +234 -119
  10. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-CNucAMQg.js.map +1 -0
  11. package/dist/{Skeleton.vue_vue_type_script_setup_true_lang-CsDMGhaT.cjs → ConfirmDialog.vue_vue_type_script_setup_true_lang-DXb9wQQv.cjs} +233 -118
  12. package/dist/ConfirmDialog.vue_vue_type_script_setup_true_lang-DXb9wQQv.cjs.map +1 -0
  13. package/dist/{Timeline.vue_vue_type_script_setup_true_lang-ykGksWXN.js → DarkModeToggle.vue_vue_type_script_setup_true_lang-43fxlbro.js} +109 -357
  14. package/dist/DarkModeToggle.vue_vue_type_script_setup_true_lang-43fxlbro.js.map +1 -0
  15. package/dist/{Timeline.vue_vue_type_script_setup_true_lang-C5SKEGPG.cjs → DarkModeToggle.vue_vue_type_script_setup_true_lang-BoB48313.cjs} +148 -396
  16. package/dist/DarkModeToggle.vue_vue_type_script_setup_true_lang-BoB48313.cjs.map +1 -0
  17. package/dist/components/core/DarkModeToggle.stories.d.ts +15 -0
  18. package/dist/components/core/DarkModeToggle.test.d.ts +1 -0
  19. package/dist/components/core/DarkModeToggle.vue.d.ts +21 -0
  20. package/dist/components/core/index.cjs +22 -20
  21. package/dist/components/core/index.cjs.map +1 -1
  22. package/dist/components/core/index.d.ts +2 -0
  23. package/dist/components/core/index.js +16 -14
  24. package/dist/components/core/index.js.map +1 -1
  25. package/dist/components/feedback/ConfirmDialog.stories.d.ts +12 -0
  26. package/dist/components/feedback/ConfirmDialog.test.d.ts +1 -0
  27. package/dist/components/feedback/ConfirmDialog.vue.d.ts +53 -0
  28. package/dist/components/feedback/Modal.vue.d.ts +11 -2
  29. package/dist/components/feedback/Progress.vue.d.ts +1 -1
  30. package/dist/components/feedback/index.cjs +17 -16
  31. package/dist/components/feedback/index.cjs.map +1 -1
  32. package/dist/components/feedback/index.d.ts +2 -0
  33. package/dist/components/feedback/index.js +6 -5
  34. package/dist/components/form/ColorPicker.vue.d.ts +3 -0
  35. package/dist/components/form/Combobox.stories.d.ts +15 -0
  36. package/dist/components/form/Combobox.test.d.ts +1 -0
  37. package/dist/components/form/Combobox.vue.d.ts +46 -0
  38. package/dist/components/form/index.cjs +17 -16
  39. package/dist/components/form/index.cjs.map +1 -1
  40. package/dist/components/form/index.d.ts +2 -0
  41. package/dist/components/form/index.js +3 -2
  42. package/dist/components/index.cjs +55 -52
  43. package/dist/components/index.cjs.map +1 -1
  44. package/dist/components/index.js +33 -30
  45. package/dist/composables/index.cjs +3 -2
  46. package/dist/composables/index.cjs.map +1 -1
  47. package/dist/composables/index.js +9 -8
  48. package/dist/composables/index.js.map +1 -1
  49. package/dist/index-D7HVSFi2.cjs +337 -0
  50. package/dist/index-D7HVSFi2.cjs.map +1 -0
  51. package/dist/index-DZYqrXV0.js +75 -0
  52. package/dist/index-DZYqrXV0.js.map +1 -0
  53. package/dist/index-Dghdw1yo.js +338 -0
  54. package/dist/index-Dghdw1yo.js.map +1 -0
  55. package/dist/index-DjEv91o4.cjs +74 -0
  56. package/dist/index-DjEv91o4.cjs.map +1 -0
  57. package/dist/index.cjs +59 -55
  58. package/dist/index.cjs.map +1 -1
  59. package/dist/index.js +43 -39
  60. package/dist/index.js.map +1 -1
  61. package/dist/style.css +1 -1
  62. package/dist/useDarkMode-Cl5QWTlC.js +53 -0
  63. package/dist/useDarkMode-Cl5QWTlC.js.map +1 -0
  64. package/dist/useDarkMode-DLZcJEUQ.cjs +52 -0
  65. package/dist/useDarkMode-DLZcJEUQ.cjs.map +1 -0
  66. package/dist/{useToast-CRh_sG82.cjs → useToast-Bk60GArg.cjs} +1 -50
  67. package/dist/useToast-Bk60GArg.cjs.map +1 -0
  68. package/dist/{useToast-DwFOkewC.js → useToast-ina5g3mj.js} +6 -55
  69. package/dist/useToast-ina5g3mj.js.map +1 -0
  70. package/package.json +1 -1
  71. package/dist/Checkbox.vue_vue_type_script_setup_true_lang-B-nLCCNY.js +0 -54
  72. package/dist/Checkbox.vue_vue_type_script_setup_true_lang-B-nLCCNY.js.map +0 -1
  73. package/dist/Checkbox.vue_vue_type_script_setup_true_lang-DIoHDji4.cjs +0 -53
  74. package/dist/Checkbox.vue_vue_type_script_setup_true_lang-DIoHDji4.cjs.map +0 -1
  75. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-CrEu33_J.cjs.map +0 -1
  76. package/dist/ListSkeleton.vue_vue_type_script_setup_true_lang-D3_Oddwt.js.map +0 -1
  77. package/dist/RangeSlider.vue_vue_type_script_setup_true_lang-B79_S1JL.js.map +0 -1
  78. package/dist/RangeSlider.vue_vue_type_script_setup_true_lang-ClH-pyK8.cjs.map +0 -1
  79. package/dist/Skeleton.vue_vue_type_script_setup_true_lang-CsDMGhaT.cjs.map +0 -1
  80. package/dist/Skeleton.vue_vue_type_script_setup_true_lang-Q4PcIELi.js.map +0 -1
  81. package/dist/Timeline.vue_vue_type_script_setup_true_lang-C5SKEGPG.cjs.map +0 -1
  82. package/dist/Timeline.vue_vue_type_script_setup_true_lang-ykGksWXN.js.map +0 -1
  83. package/dist/index-C3NAM2ds.js +0 -72
  84. package/dist/index-C3NAM2ds.js.map +0 -1
  85. package/dist/index-Ti1RIOEG.cjs +0 -71
  86. package/dist/index-Ti1RIOEG.cjs.map +0 -1
  87. package/dist/useToast-CRh_sG82.cjs.map +0 -1
  88. package/dist/useToast-DwFOkewC.js.map +0 -1
@@ -1,4 +1,5 @@
1
- import { defineComponent, createElementBlock, openBlock, createCommentVNode, createElementVNode, Fragment, renderList, normalizeStyle } from "vue";
1
+ import { defineComponent, createElementBlock, openBlock, createCommentVNode, createElementVNode, Fragment, renderList, normalizeStyle, computed, resolveComponent, createBlock, resolveDynamicComponent, mergeProps, withCtx, renderSlot, unref, normalizeClass } from "vue";
2
+ import { Icon } from "@iconify/vue";
2
3
  const _hoisted_1$2 = { class: "bg-white dark:bg-gray-900 rounded-lg shadow-md p-4 space-y-4" };
3
4
  const _hoisted_2$2 = {
4
5
  key: 0,
@@ -9,7 +10,7 @@ const _hoisted_4$1 = {
9
10
  key: 1,
10
11
  class: "flex justify-end gap-2 pt-2"
11
12
  };
12
- const _sfc_main$2 = /* @__PURE__ */ defineComponent({
13
+ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
13
14
  __name: "CardSkeleton",
14
15
  props: {
15
16
  showAvatar: { type: Boolean, default: false },
@@ -48,7 +49,7 @@ const _hoisted_2$1 = {
48
49
  key: 0,
49
50
  class: "flex gap-4 px-4 py-3 border-b border-gray-200 dark:border-gray-700"
50
51
  };
51
- const _sfc_main$1 = /* @__PURE__ */ defineComponent({
52
+ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
52
53
  __name: "TableSkeleton",
53
54
  props: {
54
55
  rows: { default: 5 },
@@ -98,7 +99,7 @@ const _hoisted_4 = {
98
99
  key: 1,
99
100
  class: "flex-shrink-0 w-8 h-8 rounded bg-gray-200 dark:bg-gray-700 animate-pulse"
100
101
  };
101
- const _sfc_main = /* @__PURE__ */ defineComponent({
102
+ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
102
103
  __name: "ListSkeleton",
103
104
  props: {
104
105
  items: { default: 5 },
@@ -133,9 +134,103 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
133
134
  };
134
135
  }
135
136
  });
137
+ const _sfc_main = /* @__PURE__ */ defineComponent({
138
+ __name: "Button",
139
+ props: {
140
+ variant: { default: "primary" },
141
+ size: { default: "md" },
142
+ icon: {},
143
+ iconRight: {},
144
+ loading: { type: Boolean },
145
+ disabled: { type: Boolean },
146
+ block: { type: Boolean },
147
+ href: {},
148
+ to: {},
149
+ type: { default: "button" }
150
+ },
151
+ emits: ["click"],
152
+ setup(__props, { emit: __emit }) {
153
+ const props = __props;
154
+ const emit = __emit;
155
+ const variantClasses = {
156
+ primary: "bg-primary text-primary-foreground hover:bg-primary/90 focus:ring-primary",
157
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/90 focus:ring-secondary",
158
+ outline: "border border-gray-300 bg-transparent text-gray-700 hover:bg-gray-50 focus:ring-primary dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-800",
159
+ ghost: "bg-transparent text-gray-700 hover:bg-gray-100 focus:ring-primary dark:text-gray-300 dark:hover:bg-gray-800",
160
+ danger: "bg-red-500 text-white hover:bg-red-600 focus:ring-red-500",
161
+ success: "bg-green-500 text-white hover:bg-green-600 focus:ring-green-500"
162
+ };
163
+ const sizeClasses = {
164
+ xs: "px-2 py-1 text-xs gap-1",
165
+ sm: "px-3 py-1.5 text-sm gap-1.5",
166
+ md: "px-4 py-2 text-sm gap-2",
167
+ lg: "px-5 py-2.5 text-base gap-2",
168
+ xl: "px-6 py-3 text-lg gap-2.5"
169
+ };
170
+ const iconSizeClasses = {
171
+ xs: "size-3",
172
+ sm: "size-4",
173
+ md: "size-4",
174
+ lg: "size-5",
175
+ xl: "size-6"
176
+ };
177
+ const classes = computed(() => [
178
+ "inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed",
179
+ variantClasses[props.variant],
180
+ sizeClasses[props.size],
181
+ props.block && "w-full"
182
+ ]);
183
+ const component = computed(() => {
184
+ if (props.to) {
185
+ try {
186
+ const RouterLink = resolveComponent("RouterLink");
187
+ if (typeof RouterLink !== "string") return RouterLink;
188
+ } catch {
189
+ }
190
+ }
191
+ if (props.href) return "a";
192
+ return "button";
193
+ });
194
+ const componentProps = computed(() => {
195
+ if (props.to) return { to: props.to };
196
+ if (props.href) return { href: props.href };
197
+ return { type: props.type, disabled: props.disabled || props.loading };
198
+ });
199
+ const handleClick = (event) => {
200
+ if (props.disabled || props.loading) return;
201
+ emit("click", event);
202
+ };
203
+ return (_ctx, _cache) => {
204
+ return openBlock(), createBlock(resolveDynamicComponent(component.value), mergeProps(componentProps.value, {
205
+ class: classes.value,
206
+ onClick: handleClick
207
+ }), {
208
+ default: withCtx(() => [
209
+ __props.loading ? (openBlock(), createBlock(unref(Icon), {
210
+ key: 0,
211
+ icon: "lucide:loader-2",
212
+ class: normalizeClass([iconSizeClasses[__props.size], "animate-spin"])
213
+ }, null, 8, ["class"])) : __props.icon ? (openBlock(), createBlock(unref(Icon), {
214
+ key: 1,
215
+ icon: __props.icon,
216
+ class: normalizeClass(iconSizeClasses[__props.size])
217
+ }, null, 8, ["icon", "class"])) : createCommentVNode("", true),
218
+ renderSlot(_ctx.$slots, "default"),
219
+ __props.iconRight && !__props.loading ? (openBlock(), createBlock(unref(Icon), {
220
+ key: 2,
221
+ icon: __props.iconRight,
222
+ class: normalizeClass(iconSizeClasses[__props.size])
223
+ }, null, 8, ["icon", "class"])) : createCommentVNode("", true)
224
+ ]),
225
+ _: 3
226
+ }, 16, ["class"]);
227
+ };
228
+ }
229
+ });
136
230
  export {
137
- _sfc_main$1 as _,
231
+ _sfc_main as _,
138
232
  _sfc_main$2 as a,
139
- _sfc_main as b
233
+ _sfc_main$3 as b,
234
+ _sfc_main$1 as c
140
235
  };
141
- //# sourceMappingURL=ListSkeleton.vue_vue_type_script_setup_true_lang-D3_Oddwt.js.map
236
+ //# sourceMappingURL=Button.vue_vue_type_script_setup_true_lang-DKE8elsf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.vue_vue_type_script_setup_true_lang-DKE8elsf.js","sources":["../src/components/feedback/CardSkeleton.vue","../src/components/feedback/TableSkeleton.vue","../src/components/feedback/ListSkeleton.vue","../src/components/core/Button.vue"],"sourcesContent":["<script lang=\"ts\" setup>\r\nwithDefaults(\r\n defineProps<{\r\n /** Show avatar/icon placeholder */\r\n showAvatar?: boolean\r\n /** Number of text lines */\r\n lines?: number\r\n /** Show action buttons */\r\n showActions?: boolean\r\n }>(),\r\n {\r\n showAvatar: false,\r\n lines: 3,\r\n showActions: false,\r\n },\r\n)\r\n</script>\r\n\r\n<template>\r\n <div class=\"bg-white dark:bg-gray-900 rounded-lg shadow-md p-4 space-y-4\">\r\n <!-- Header with avatar -->\r\n <div v-if=\"showAvatar\" class=\"flex items-center gap-3\">\r\n <div class=\"w-10 h-10 rounded-full bg-gray-200 dark:bg-gray-700 animate-pulse\" />\r\n <div class=\"flex-1 space-y-2\">\r\n <div class=\"h-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse w-1/2\" />\r\n <div class=\"h-3 bg-gray-200 dark:bg-gray-700 rounded animate-pulse w-1/3\" />\r\n </div>\r\n </div>\r\n\r\n <!-- Content lines -->\r\n <div class=\"space-y-2\">\r\n <div\r\n v-for=\"line in lines\"\r\n :key=\"line\"\r\n class=\"h-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse\"\r\n :style=\"{ width: line === lines ? '60%' : '100%' }\"\r\n />\r\n </div>\r\n\r\n <!-- Actions -->\r\n <div v-if=\"showActions\" class=\"flex justify-end gap-2 pt-2\">\r\n <div class=\"h-8 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse\" />\r\n <div class=\"h-8 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse\" />\r\n </div>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nwithDefaults(\r\n defineProps<{\r\n /** Number of rows */\r\n rows?: number\r\n /** Number of columns */\r\n columns?: number\r\n /** Show header */\r\n showHeader?: boolean\r\n }>(),\r\n {\r\n rows: 5,\r\n columns: 4,\r\n showHeader: true,\r\n },\r\n)\r\n</script>\r\n\r\n<template>\r\n <div class=\"w-full\">\r\n <!-- Header -->\r\n <div\r\n v-if=\"showHeader\"\r\n class=\"flex gap-4 px-4 py-3 border-b border-gray-200 dark:border-gray-700\"\r\n >\r\n <div\r\n v-for=\"col in columns\"\r\n :key=\"`header-${col}`\"\r\n class=\"flex-1 h-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse\"\r\n :style=\"{ maxWidth: col === 1 ? '30%' : '20%' }\"\r\n />\r\n </div>\r\n <!-- Rows -->\r\n <div\r\n v-for=\"row in rows\"\r\n :key=\"`row-${row}`\"\r\n class=\"flex items-center gap-4 px-4 py-4 border-b border-gray-100 dark:border-gray-800\"\r\n >\r\n <div\r\n v-for=\"col in columns\"\r\n :key=\"`cell-${row}-${col}`\"\r\n class=\"flex-1 h-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse\"\r\n :style=\"{\r\n maxWidth: col === 1 ? '40%' : col === columns ? '15%' : '25%',\r\n opacity: 1 - (row * 0.1)\r\n }\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nwithDefaults(\r\n defineProps<{\r\n /** Number of items */\r\n items?: number\r\n /** Show avatar/icon placeholder */\r\n showAvatar?: boolean\r\n /** Show secondary text */\r\n showSecondary?: boolean\r\n /** Show action button */\r\n showAction?: boolean\r\n }>(),\r\n {\r\n items: 5,\r\n showAvatar: true,\r\n showSecondary: true,\r\n showAction: false,\r\n },\r\n)\r\n</script>\r\n\r\n<template>\r\n <div class=\"divide-y divide-gray-200 dark:divide-gray-700\">\r\n <div\r\n v-for=\"item in items\"\r\n :key=\"item\"\r\n class=\"flex items-center gap-4 py-4 px-4\"\r\n >\r\n <!-- Avatar -->\r\n <div\r\n v-if=\"showAvatar\"\r\n class=\"flex-shrink-0 w-10 h-10 rounded-full bg-gray-200 dark:bg-gray-700 animate-pulse\"\r\n />\r\n\r\n <!-- Content -->\r\n <div class=\"flex-1 min-w-0 space-y-2\">\r\n <div\r\n class=\"h-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse\"\r\n :style=\"{ width: `${60 + Math.random() * 30}%` }\"\r\n />\r\n <div\r\n v-if=\"showSecondary\"\r\n class=\"h-3 bg-gray-200 dark:bg-gray-700 rounded animate-pulse\"\r\n :style=\"{ width: `${40 + Math.random() * 20}%` }\"\r\n />\r\n </div>\r\n\r\n <!-- Action -->\r\n <div\r\n v-if=\"showAction\"\r\n class=\"flex-shrink-0 w-8 h-8 rounded bg-gray-200 dark:bg-gray-700 animate-pulse\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\nimport { computed, resolveComponent } from 'vue'\nimport { Icon } from '@iconify/vue'\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' | 'success'\nexport type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n\nconst props = withDefaults(\n defineProps<{\n /** Button variant */\n variant?: ButtonVariant\n /** Button size */\n size?: ButtonSize\n /** Icon to show (left side) */\n icon?: string\n /** Icon on right side */\n iconRight?: string\n /** Loading state */\n loading?: boolean\n /** Disabled state */\n disabled?: boolean\n /** Full width */\n block?: boolean\n /** Link href (renders as <a>) */\n href?: string\n /** Router link (renders as RouterLink) */\n to?: string\n /** Button type */\n type?: 'button' | 'submit' | 'reset'\n }>(),\n {\n variant: 'primary',\n size: 'md',\n type: 'button',\n },\n)\n\nconst emit = defineEmits<{\n click: [event: MouseEvent]\n}>()\n\nconst variantClasses: Record<ButtonVariant, string> = {\n primary: 'bg-primary text-primary-foreground hover:bg-primary/90 focus:ring-primary',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/90 focus:ring-secondary',\n outline: 'border border-gray-300 bg-transparent text-gray-700 hover:bg-gray-50 focus:ring-primary dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-800',\n ghost: 'bg-transparent text-gray-700 hover:bg-gray-100 focus:ring-primary dark:text-gray-300 dark:hover:bg-gray-800',\n danger: 'bg-red-500 text-white hover:bg-red-600 focus:ring-red-500',\n success: 'bg-green-500 text-white hover:bg-green-600 focus:ring-green-500',\n}\n\nconst sizeClasses: Record<ButtonSize, string> = {\n xs: 'px-2 py-1 text-xs gap-1',\n sm: 'px-3 py-1.5 text-sm gap-1.5',\n md: 'px-4 py-2 text-sm gap-2',\n lg: 'px-5 py-2.5 text-base gap-2',\n xl: 'px-6 py-3 text-lg gap-2.5',\n}\n\nconst iconSizeClasses: Record<ButtonSize, string> = {\n xs: 'size-3',\n sm: 'size-4',\n md: 'size-4',\n lg: 'size-5',\n xl: 'size-6',\n}\n\nconst classes = computed(() => [\n 'inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed',\n variantClasses[props.variant],\n sizeClasses[props.size],\n props.block && 'w-full',\n])\n\nconst component = computed(() => {\n if (props.to) {\n try {\n const RouterLink = resolveComponent('RouterLink')\n if (typeof RouterLink !== 'string') return RouterLink\n } catch {\n // RouterLink not available\n }\n }\n if (props.href) return 'a'\n return 'button'\n})\n\nconst componentProps = computed(() => {\n if (props.to) return { to: props.to }\n if (props.href) return { href: props.href }\n return { type: props.type, disabled: props.disabled || props.loading }\n})\n\nconst handleClick = (event: MouseEvent) => {\n if (props.disabled || props.loading) return\n emit('click', event)\n}\n</script>\n\n<template>\n <component\n :is=\"component\"\n v-bind=\"componentProps\"\n :class=\"classes\"\n @click=\"handleClick\"\n >\n <Icon\n v-if=\"loading\"\n icon=\"lucide:loader-2\"\n :class=\"[iconSizeClasses[size], 'animate-spin']\"\n />\n <Icon\n v-else-if=\"icon\"\n :icon=\"icon\"\n :class=\"iconSizeClasses[size]\"\n />\n <slot />\n <Icon\n v-if=\"iconRight && !loading\"\n :icon=\"iconRight\"\n :class=\"iconSizeClasses[size]\"\n />\n </component>\n</template>\n"],"names":["_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","_createElementVNode","_hoisted_3","_Fragment","_renderList","_normalizeStyle","_hoisted_4","_createBlock","_resolveDynamicComponent","_mergeProps","_unref","_normalizeClass","_renderSlot"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  const vue = require("vue");
3
+ const vue$1 = require("@iconify/vue");
3
4
  const _hoisted_1$2 = { class: "bg-white dark:bg-gray-900 rounded-lg shadow-md p-4 space-y-4" };
4
5
  const _hoisted_2$2 = {
5
6
  key: 0,
@@ -10,7 +11,7 @@ const _hoisted_4$1 = {
10
11
  key: 1,
11
12
  class: "flex justify-end gap-2 pt-2"
12
13
  };
13
- const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
14
+ const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
14
15
  __name: "CardSkeleton",
15
16
  props: {
16
17
  showAvatar: { type: Boolean, default: false },
@@ -49,7 +50,7 @@ const _hoisted_2$1 = {
49
50
  key: 0,
50
51
  class: "flex gap-4 px-4 py-3 border-b border-gray-200 dark:border-gray-700"
51
52
  };
52
- const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
53
+ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
53
54
  __name: "TableSkeleton",
54
55
  props: {
55
56
  rows: { default: 5 },
@@ -99,7 +100,7 @@ const _hoisted_4 = {
99
100
  key: 1,
100
101
  class: "flex-shrink-0 w-8 h-8 rounded bg-gray-200 dark:bg-gray-700 animate-pulse"
101
102
  };
102
- const _sfc_main = /* @__PURE__ */ vue.defineComponent({
103
+ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
103
104
  __name: "ListSkeleton",
104
105
  props: {
105
106
  items: { default: 5 },
@@ -134,7 +135,101 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
134
135
  };
135
136
  }
136
137
  });
137
- exports._sfc_main = _sfc_main$1;
138
+ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
139
+ __name: "Button",
140
+ props: {
141
+ variant: { default: "primary" },
142
+ size: { default: "md" },
143
+ icon: {},
144
+ iconRight: {},
145
+ loading: { type: Boolean },
146
+ disabled: { type: Boolean },
147
+ block: { type: Boolean },
148
+ href: {},
149
+ to: {},
150
+ type: { default: "button" }
151
+ },
152
+ emits: ["click"],
153
+ setup(__props, { emit: __emit }) {
154
+ const props = __props;
155
+ const emit = __emit;
156
+ const variantClasses = {
157
+ primary: "bg-primary text-primary-foreground hover:bg-primary/90 focus:ring-primary",
158
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/90 focus:ring-secondary",
159
+ outline: "border border-gray-300 bg-transparent text-gray-700 hover:bg-gray-50 focus:ring-primary dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-800",
160
+ ghost: "bg-transparent text-gray-700 hover:bg-gray-100 focus:ring-primary dark:text-gray-300 dark:hover:bg-gray-800",
161
+ danger: "bg-red-500 text-white hover:bg-red-600 focus:ring-red-500",
162
+ success: "bg-green-500 text-white hover:bg-green-600 focus:ring-green-500"
163
+ };
164
+ const sizeClasses = {
165
+ xs: "px-2 py-1 text-xs gap-1",
166
+ sm: "px-3 py-1.5 text-sm gap-1.5",
167
+ md: "px-4 py-2 text-sm gap-2",
168
+ lg: "px-5 py-2.5 text-base gap-2",
169
+ xl: "px-6 py-3 text-lg gap-2.5"
170
+ };
171
+ const iconSizeClasses = {
172
+ xs: "size-3",
173
+ sm: "size-4",
174
+ md: "size-4",
175
+ lg: "size-5",
176
+ xl: "size-6"
177
+ };
178
+ const classes = vue.computed(() => [
179
+ "inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed",
180
+ variantClasses[props.variant],
181
+ sizeClasses[props.size],
182
+ props.block && "w-full"
183
+ ]);
184
+ const component = vue.computed(() => {
185
+ if (props.to) {
186
+ try {
187
+ const RouterLink = vue.resolveComponent("RouterLink");
188
+ if (typeof RouterLink !== "string") return RouterLink;
189
+ } catch {
190
+ }
191
+ }
192
+ if (props.href) return "a";
193
+ return "button";
194
+ });
195
+ const componentProps = vue.computed(() => {
196
+ if (props.to) return { to: props.to };
197
+ if (props.href) return { href: props.href };
198
+ return { type: props.type, disabled: props.disabled || props.loading };
199
+ });
200
+ const handleClick = (event) => {
201
+ if (props.disabled || props.loading) return;
202
+ emit("click", event);
203
+ };
204
+ return (_ctx, _cache) => {
205
+ return vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(component.value), vue.mergeProps(componentProps.value, {
206
+ class: classes.value,
207
+ onClick: handleClick
208
+ }), {
209
+ default: vue.withCtx(() => [
210
+ __props.loading ? (vue.openBlock(), vue.createBlock(vue.unref(vue$1.Icon), {
211
+ key: 0,
212
+ icon: "lucide:loader-2",
213
+ class: vue.normalizeClass([iconSizeClasses[__props.size], "animate-spin"])
214
+ }, null, 8, ["class"])) : __props.icon ? (vue.openBlock(), vue.createBlock(vue.unref(vue$1.Icon), {
215
+ key: 1,
216
+ icon: __props.icon,
217
+ class: vue.normalizeClass(iconSizeClasses[__props.size])
218
+ }, null, 8, ["icon", "class"])) : vue.createCommentVNode("", true),
219
+ vue.renderSlot(_ctx.$slots, "default"),
220
+ __props.iconRight && !__props.loading ? (vue.openBlock(), vue.createBlock(vue.unref(vue$1.Icon), {
221
+ key: 2,
222
+ icon: __props.iconRight,
223
+ class: vue.normalizeClass(iconSizeClasses[__props.size])
224
+ }, null, 8, ["icon", "class"])) : vue.createCommentVNode("", true)
225
+ ]),
226
+ _: 3
227
+ }, 16, ["class"]);
228
+ };
229
+ }
230
+ });
231
+ exports._sfc_main = _sfc_main;
138
232
  exports._sfc_main$1 = _sfc_main$2;
139
- exports._sfc_main$2 = _sfc_main;
140
- //# sourceMappingURL=ListSkeleton.vue_vue_type_script_setup_true_lang-CrEu33_J.cjs.map
233
+ exports._sfc_main$2 = _sfc_main$3;
234
+ exports._sfc_main$3 = _sfc_main$1;
235
+ //# sourceMappingURL=Button.vue_vue_type_script_setup_true_lang-DrGM65ny.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.vue_vue_type_script_setup_true_lang-DrGM65ny.cjs","sources":["../src/components/feedback/CardSkeleton.vue","../src/components/feedback/TableSkeleton.vue","../src/components/feedback/ListSkeleton.vue","../src/components/core/Button.vue"],"sourcesContent":["<script lang=\"ts\" setup>\r\nwithDefaults(\r\n defineProps<{\r\n /** Show avatar/icon placeholder */\r\n showAvatar?: boolean\r\n /** Number of text lines */\r\n lines?: number\r\n /** Show action buttons */\r\n showActions?: boolean\r\n }>(),\r\n {\r\n showAvatar: false,\r\n lines: 3,\r\n showActions: false,\r\n },\r\n)\r\n</script>\r\n\r\n<template>\r\n <div class=\"bg-white dark:bg-gray-900 rounded-lg shadow-md p-4 space-y-4\">\r\n <!-- Header with avatar -->\r\n <div v-if=\"showAvatar\" class=\"flex items-center gap-3\">\r\n <div class=\"w-10 h-10 rounded-full bg-gray-200 dark:bg-gray-700 animate-pulse\" />\r\n <div class=\"flex-1 space-y-2\">\r\n <div class=\"h-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse w-1/2\" />\r\n <div class=\"h-3 bg-gray-200 dark:bg-gray-700 rounded animate-pulse w-1/3\" />\r\n </div>\r\n </div>\r\n\r\n <!-- Content lines -->\r\n <div class=\"space-y-2\">\r\n <div\r\n v-for=\"line in lines\"\r\n :key=\"line\"\r\n class=\"h-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse\"\r\n :style=\"{ width: line === lines ? '60%' : '100%' }\"\r\n />\r\n </div>\r\n\r\n <!-- Actions -->\r\n <div v-if=\"showActions\" class=\"flex justify-end gap-2 pt-2\">\r\n <div class=\"h-8 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse\" />\r\n <div class=\"h-8 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse\" />\r\n </div>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nwithDefaults(\r\n defineProps<{\r\n /** Number of rows */\r\n rows?: number\r\n /** Number of columns */\r\n columns?: number\r\n /** Show header */\r\n showHeader?: boolean\r\n }>(),\r\n {\r\n rows: 5,\r\n columns: 4,\r\n showHeader: true,\r\n },\r\n)\r\n</script>\r\n\r\n<template>\r\n <div class=\"w-full\">\r\n <!-- Header -->\r\n <div\r\n v-if=\"showHeader\"\r\n class=\"flex gap-4 px-4 py-3 border-b border-gray-200 dark:border-gray-700\"\r\n >\r\n <div\r\n v-for=\"col in columns\"\r\n :key=\"`header-${col}`\"\r\n class=\"flex-1 h-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse\"\r\n :style=\"{ maxWidth: col === 1 ? '30%' : '20%' }\"\r\n />\r\n </div>\r\n <!-- Rows -->\r\n <div\r\n v-for=\"row in rows\"\r\n :key=\"`row-${row}`\"\r\n class=\"flex items-center gap-4 px-4 py-4 border-b border-gray-100 dark:border-gray-800\"\r\n >\r\n <div\r\n v-for=\"col in columns\"\r\n :key=\"`cell-${row}-${col}`\"\r\n class=\"flex-1 h-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse\"\r\n :style=\"{\r\n maxWidth: col === 1 ? '40%' : col === columns ? '15%' : '25%',\r\n opacity: 1 - (row * 0.1)\r\n }\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\r\nwithDefaults(\r\n defineProps<{\r\n /** Number of items */\r\n items?: number\r\n /** Show avatar/icon placeholder */\r\n showAvatar?: boolean\r\n /** Show secondary text */\r\n showSecondary?: boolean\r\n /** Show action button */\r\n showAction?: boolean\r\n }>(),\r\n {\r\n items: 5,\r\n showAvatar: true,\r\n showSecondary: true,\r\n showAction: false,\r\n },\r\n)\r\n</script>\r\n\r\n<template>\r\n <div class=\"divide-y divide-gray-200 dark:divide-gray-700\">\r\n <div\r\n v-for=\"item in items\"\r\n :key=\"item\"\r\n class=\"flex items-center gap-4 py-4 px-4\"\r\n >\r\n <!-- Avatar -->\r\n <div\r\n v-if=\"showAvatar\"\r\n class=\"flex-shrink-0 w-10 h-10 rounded-full bg-gray-200 dark:bg-gray-700 animate-pulse\"\r\n />\r\n\r\n <!-- Content -->\r\n <div class=\"flex-1 min-w-0 space-y-2\">\r\n <div\r\n class=\"h-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse\"\r\n :style=\"{ width: `${60 + Math.random() * 30}%` }\"\r\n />\r\n <div\r\n v-if=\"showSecondary\"\r\n class=\"h-3 bg-gray-200 dark:bg-gray-700 rounded animate-pulse\"\r\n :style=\"{ width: `${40 + Math.random() * 20}%` }\"\r\n />\r\n </div>\r\n\r\n <!-- Action -->\r\n <div\r\n v-if=\"showAction\"\r\n class=\"flex-shrink-0 w-8 h-8 rounded bg-gray-200 dark:bg-gray-700 animate-pulse\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n","<script lang=\"ts\" setup>\nimport { computed, resolveComponent } from 'vue'\nimport { Icon } from '@iconify/vue'\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' | 'success'\nexport type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n\nconst props = withDefaults(\n defineProps<{\n /** Button variant */\n variant?: ButtonVariant\n /** Button size */\n size?: ButtonSize\n /** Icon to show (left side) */\n icon?: string\n /** Icon on right side */\n iconRight?: string\n /** Loading state */\n loading?: boolean\n /** Disabled state */\n disabled?: boolean\n /** Full width */\n block?: boolean\n /** Link href (renders as <a>) */\n href?: string\n /** Router link (renders as RouterLink) */\n to?: string\n /** Button type */\n type?: 'button' | 'submit' | 'reset'\n }>(),\n {\n variant: 'primary',\n size: 'md',\n type: 'button',\n },\n)\n\nconst emit = defineEmits<{\n click: [event: MouseEvent]\n}>()\n\nconst variantClasses: Record<ButtonVariant, string> = {\n primary: 'bg-primary text-primary-foreground hover:bg-primary/90 focus:ring-primary',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/90 focus:ring-secondary',\n outline: 'border border-gray-300 bg-transparent text-gray-700 hover:bg-gray-50 focus:ring-primary dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-800',\n ghost: 'bg-transparent text-gray-700 hover:bg-gray-100 focus:ring-primary dark:text-gray-300 dark:hover:bg-gray-800',\n danger: 'bg-red-500 text-white hover:bg-red-600 focus:ring-red-500',\n success: 'bg-green-500 text-white hover:bg-green-600 focus:ring-green-500',\n}\n\nconst sizeClasses: Record<ButtonSize, string> = {\n xs: 'px-2 py-1 text-xs gap-1',\n sm: 'px-3 py-1.5 text-sm gap-1.5',\n md: 'px-4 py-2 text-sm gap-2',\n lg: 'px-5 py-2.5 text-base gap-2',\n xl: 'px-6 py-3 text-lg gap-2.5',\n}\n\nconst iconSizeClasses: Record<ButtonSize, string> = {\n xs: 'size-3',\n sm: 'size-4',\n md: 'size-4',\n lg: 'size-5',\n xl: 'size-6',\n}\n\nconst classes = computed(() => [\n 'inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed',\n variantClasses[props.variant],\n sizeClasses[props.size],\n props.block && 'w-full',\n])\n\nconst component = computed(() => {\n if (props.to) {\n try {\n const RouterLink = resolveComponent('RouterLink')\n if (typeof RouterLink !== 'string') return RouterLink\n } catch {\n // RouterLink not available\n }\n }\n if (props.href) return 'a'\n return 'button'\n})\n\nconst componentProps = computed(() => {\n if (props.to) return { to: props.to }\n if (props.href) return { href: props.href }\n return { type: props.type, disabled: props.disabled || props.loading }\n})\n\nconst handleClick = (event: MouseEvent) => {\n if (props.disabled || props.loading) return\n emit('click', event)\n}\n</script>\n\n<template>\n <component\n :is=\"component\"\n v-bind=\"componentProps\"\n :class=\"classes\"\n @click=\"handleClick\"\n >\n <Icon\n v-if=\"loading\"\n icon=\"lucide:loader-2\"\n :class=\"[iconSizeClasses[size], 'animate-spin']\"\n />\n <Icon\n v-else-if=\"icon\"\n :icon=\"icon\"\n :class=\"iconSizeClasses[size]\"\n />\n <slot />\n <Icon\n v-if=\"iconRight && !loading\"\n :icon=\"iconRight\"\n :class=\"iconSizeClasses[size]\"\n />\n </component>\n</template>\n"],"names":["_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","_createElementVNode","_hoisted_3","_Fragment","_renderList","_normalizeStyle","_hoisted_4","computed","resolveComponent","_createBlock","_resolveDynamicComponent","_mergeProps","_unref","Icon","_normalizeClass","_renderSlot"],"mappings":"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"}