vome-core 0.1.77 → 0.1.79

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 (203) hide show
  1. package/dist/admin/api/client.js +2 -3
  2. package/dist/admin/components/layout/vm-app-header.vue +341 -0
  3. package/dist/admin/components/layout/vm-app-sidebar.vue +187 -0
  4. package/dist/admin/components/layout/vm-sidebar-flyout.vue +268 -0
  5. package/dist/admin/components/layout/vm-sidebar-nav-item.vue +490 -0
  6. package/dist/admin/components/layout/vm-sidebar-nav.vue +104 -0
  7. package/dist/admin/components/layout/vm-tags-view.vue +233 -0
  8. package/dist/admin/components/ui/avatar/Avatar.vue +18 -0
  9. package/dist/admin/components/ui/avatar/AvatarFallback.vue +21 -0
  10. package/dist/admin/components/ui/avatar/AvatarImage.vue +16 -0
  11. package/dist/admin/components/ui/avatar/index.d.ts +3 -0
  12. package/dist/admin/components/ui/avatar/index.js +1 -0
  13. package/dist/admin/components/ui/badge/Badge.vue +26 -0
  14. package/dist/admin/components/ui/badge/index.d.ts +6 -0
  15. package/dist/admin/components/ui/badge/index.js +1 -0
  16. package/dist/admin/components/ui/button/Button.vue +31 -0
  17. package/dist/admin/components/ui/button/index.d.ts +7 -0
  18. package/dist/admin/components/ui/button/index.js +1 -0
  19. package/dist/admin/components/ui/checkbox/Checkbox.vue +35 -0
  20. package/dist/admin/components/ui/checkbox/index.d.ts +1 -0
  21. package/dist/admin/components/ui/checkbox/index.js +1 -0
  22. package/dist/admin/components/ui/dialog/Dialog.vue +19 -0
  23. package/dist/admin/components/ui/dialog/DialogClose.vue +15 -0
  24. package/dist/admin/components/ui/dialog/DialogContent.vue +135 -0
  25. package/dist/admin/components/ui/dialog/DialogDescription.vue +23 -0
  26. package/dist/admin/components/ui/dialog/DialogFooter.vue +27 -0
  27. package/dist/admin/components/ui/dialog/DialogHeader.vue +17 -0
  28. package/dist/admin/components/ui/dialog/DialogOverlay.vue +21 -0
  29. package/dist/admin/components/ui/dialog/DialogScrollContent.vue +60 -0
  30. package/dist/admin/components/ui/dialog/DialogTitle.vue +23 -0
  31. package/dist/admin/components/ui/dialog/DialogTrigger.vue +15 -0
  32. package/dist/admin/components/ui/dialog/index.d.ts +10 -0
  33. package/dist/admin/components/ui/dialog/index.js +1 -0
  34. package/dist/admin/components/ui/dropdown-menu/DropdownMenu.vue +19 -0
  35. package/dist/admin/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +39 -0
  36. package/dist/admin/components/ui/dropdown-menu/DropdownMenuContent.vue +39 -0
  37. package/dist/admin/components/ui/dropdown-menu/DropdownMenuGroup.vue +15 -0
  38. package/dist/admin/components/ui/dropdown-menu/DropdownMenuItem.vue +31 -0
  39. package/dist/admin/components/ui/dropdown-menu/DropdownMenuLabel.vue +23 -0
  40. package/dist/admin/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +21 -0
  41. package/dist/admin/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +40 -0
  42. package/dist/admin/components/ui/dropdown-menu/DropdownMenuSeparator.vue +23 -0
  43. package/dist/admin/components/ui/dropdown-menu/DropdownMenuShortcut.vue +17 -0
  44. package/dist/admin/components/ui/dropdown-menu/DropdownMenuSub.vue +18 -0
  45. package/dist/admin/components/ui/dropdown-menu/DropdownMenuSubContent.vue +27 -0
  46. package/dist/admin/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +31 -0
  47. package/dist/admin/components/ui/dropdown-menu/DropdownMenuTrigger.vue +17 -0
  48. package/dist/admin/components/ui/dropdown-menu/index.d.ts +15 -0
  49. package/dist/admin/components/ui/dropdown-menu/index.js +1 -0
  50. package/dist/admin/components/ui/input/Input.vue +34 -0
  51. package/dist/admin/components/ui/input/index.d.ts +1 -0
  52. package/dist/admin/components/ui/input/index.js +1 -0
  53. package/dist/admin/components/ui/label/Label.vue +26 -0
  54. package/dist/admin/components/ui/label/index.d.ts +1 -0
  55. package/dist/admin/components/ui/label/index.js +1 -0
  56. package/dist/admin/components/ui/scroll-area/ScrollArea.vue +33 -0
  57. package/dist/admin/components/ui/scroll-area/ScrollBar.vue +32 -0
  58. package/dist/admin/components/ui/scroll-area/index.d.ts +2 -0
  59. package/dist/admin/components/ui/scroll-area/index.js +1 -0
  60. package/dist/admin/components/ui/select/Select.vue +19 -0
  61. package/dist/admin/components/ui/select/SelectContent.vue +51 -0
  62. package/dist/admin/components/ui/select/SelectGroup.vue +15 -0
  63. package/dist/admin/components/ui/select/SelectItem.vue +44 -0
  64. package/dist/admin/components/ui/select/SelectItemText.vue +15 -0
  65. package/dist/admin/components/ui/select/SelectLabel.vue +17 -0
  66. package/dist/admin/components/ui/select/SelectScrollDownButton.vue +26 -0
  67. package/dist/admin/components/ui/select/SelectScrollUpButton.vue +26 -0
  68. package/dist/admin/components/ui/select/SelectSeparator.vue +19 -0
  69. package/dist/admin/components/ui/select/SelectTrigger.vue +33 -0
  70. package/dist/admin/components/ui/select/SelectValue.vue +15 -0
  71. package/dist/admin/components/ui/select/index.d.ts +11 -0
  72. package/dist/admin/components/ui/select/index.js +1 -0
  73. package/dist/admin/components/ui/separator/Separator.vue +29 -0
  74. package/dist/admin/components/ui/separator/index.d.ts +1 -0
  75. package/dist/admin/components/ui/separator/index.js +1 -0
  76. package/dist/admin/components/ui/sheet/Sheet.vue +19 -0
  77. package/dist/admin/components/ui/sheet/SheetClose.vue +15 -0
  78. package/dist/admin/components/ui/sheet/SheetContent.vue +63 -0
  79. package/dist/admin/components/ui/sheet/SheetDescription.vue +21 -0
  80. package/dist/admin/components/ui/sheet/SheetFooter.vue +16 -0
  81. package/dist/admin/components/ui/sheet/SheetHeader.vue +15 -0
  82. package/dist/admin/components/ui/sheet/SheetOverlay.vue +21 -0
  83. package/dist/admin/components/ui/sheet/SheetTitle.vue +21 -0
  84. package/dist/admin/components/ui/sheet/SheetTrigger.vue +15 -0
  85. package/dist/admin/components/ui/sheet/index.d.ts +8 -0
  86. package/dist/admin/components/ui/sheet/index.js +1 -0
  87. package/dist/admin/components/ui/sonner/Toaster.vue +117 -0
  88. package/dist/admin/components/ui/sonner/index.d.ts +1 -0
  89. package/dist/admin/components/ui/sonner/index.js +1 -0
  90. package/dist/admin/components/ui/table/Table.vue +16 -0
  91. package/dist/admin/components/ui/table/TableBody.vue +17 -0
  92. package/dist/admin/components/ui/table/TableCaption.vue +17 -0
  93. package/dist/admin/components/ui/table/TableCell.vue +22 -0
  94. package/dist/admin/components/ui/table/TableEmpty.vue +34 -0
  95. package/dist/admin/components/ui/table/TableFooter.vue +17 -0
  96. package/dist/admin/components/ui/table/TableHead.vue +17 -0
  97. package/dist/admin/components/ui/table/TableHeader.vue +17 -0
  98. package/dist/admin/components/ui/table/TableRow.vue +17 -0
  99. package/dist/admin/components/ui/table/index.d.ts +9 -0
  100. package/dist/admin/components/ui/table/index.js +1 -0
  101. package/dist/admin/components/ui/tabs/Tabs.vue +24 -0
  102. package/dist/admin/components/ui/tabs/TabsContent.vue +21 -0
  103. package/dist/admin/components/ui/tabs/TabsList.vue +24 -0
  104. package/dist/admin/components/ui/tabs/TabsTrigger.vue +26 -0
  105. package/dist/admin/components/ui/tabs/index.d.ts +4 -0
  106. package/dist/admin/components/ui/tabs/index.js +1 -0
  107. package/dist/admin/components/ui/tooltip/Tooltip.vue +19 -0
  108. package/dist/admin/components/ui/tooltip/TooltipContent.vue +34 -0
  109. package/dist/admin/components/ui/tooltip/TooltipProvider.vue +14 -0
  110. package/dist/admin/components/ui/tooltip/TooltipTrigger.vue +15 -0
  111. package/dist/admin/components/ui/tooltip/index.d.ts +4 -0
  112. package/dist/admin/components/ui/tooltip/index.js +1 -0
  113. package/dist/admin/crud/components/vm-color-picker.vue +0 -3
  114. package/dist/admin/crud/components/vm-richtext-extensions.js +1 -1
  115. package/dist/admin/crud/config.js +1 -1
  116. package/dist/admin/crud/confirm.d.ts +8 -0
  117. package/dist/admin/crud/confirm.js +1 -1
  118. package/dist/admin/crud/crud-page-request.js +1 -1
  119. package/dist/admin/crud/dict.js +1 -1
  120. package/dist/admin/crud/export-fetch.js +1 -1
  121. package/dist/admin/crud/key.js +1 -1
  122. package/dist/admin/crud/plugins.js +1 -1
  123. package/dist/admin/crud/span.js +1 -1
  124. package/dist/admin/crud/style.d.ts +4 -0
  125. package/dist/admin/crud/style.js +1 -1
  126. package/dist/admin/crud/validate.js +1 -1
  127. package/dist/admin/directives/perm.js +1 -1
  128. package/dist/admin/env.d.ts +0 -4
  129. package/dist/admin/hooks/useUpload.js +1 -1
  130. package/dist/admin/index.d.ts +11 -9
  131. package/dist/admin/index.js +16 -27
  132. package/dist/admin/lib/browser.js +1 -1
  133. package/dist/admin/lib/cn.js +1 -1
  134. package/dist/admin/lib/dialog-float.js +1 -1
  135. package/dist/admin/lib/document-title.d.ts +6 -0
  136. package/dist/admin/lib/document-title.js +1 -0
  137. package/dist/admin/lib/export-excel.js +1 -1
  138. package/dist/admin/lib/import-excel.js +1 -1
  139. package/dist/admin/lib/json.js +1 -1
  140. package/dist/admin/lib/menu.js +1 -1
  141. package/dist/admin/lib/micro-locale.d.ts +5 -0
  142. package/dist/admin/lib/micro-locale.js +1 -0
  143. package/dist/admin/lib/micro-theme.d.ts +14 -0
  144. package/dist/admin/lib/micro-theme.js +1 -0
  145. package/dist/admin/lib/setup-crud-defaults.d.ts +2 -0
  146. package/dist/admin/lib/setup-crud-defaults.js +1 -0
  147. package/dist/admin/lib/shell.d.ts +13 -0
  148. package/dist/admin/lib/shell.js +1 -0
  149. package/dist/admin/lib/theme-color-options.js +1 -1
  150. package/dist/admin/lib/tree.js +1 -1
  151. package/dist/admin/lib/upload.js +1 -1
  152. package/dist/admin/lib/video-frame.js +1 -1
  153. package/dist/admin/router/create.d.ts +16 -0
  154. package/dist/admin/router/create.js +1 -0
  155. package/dist/admin/router/guards.d.ts +6 -0
  156. package/dist/admin/router/guards.js +1 -0
  157. package/dist/admin/router/index.d.ts +5 -3
  158. package/dist/admin/router/index.js +5 -80
  159. package/dist/admin/router/menu-routes.d.ts +7 -2
  160. package/dist/admin/router/menu-routes.js +10 -12
  161. package/dist/admin/service/index.js +0 -3
  162. package/dist/admin/stores/dict.d.ts +13 -0
  163. package/dist/admin/stores/dict.js +1 -0
  164. package/dist/admin/stores/locale.d.ts +3 -0
  165. package/dist/admin/stores/locale.js +1 -0
  166. package/dist/admin/stores/theme.d.ts +1 -0
  167. package/dist/admin/stores/theme.js +1 -0
  168. package/dist/admin/themes/dark.d.ts +2 -0
  169. package/dist/admin/themes/dark.js +1 -0
  170. package/dist/admin/themes/index.d.ts +9 -0
  171. package/dist/admin/themes/index.js +1 -0
  172. package/dist/admin/themes/light.d.ts +2 -0
  173. package/dist/admin/themes/light.js +1 -0
  174. package/dist/client/configure.d.ts +3 -0
  175. package/dist/client/configure.js +8 -1
  176. package/dist/client/vite-admin.js +2 -4
  177. package/dist/client/vite-auto-import.js +4 -4
  178. package/dist/client/vite-resolve.d.ts +3 -3
  179. package/dist/client/vite-resolve.js +10 -15
  180. package/dist/ext/plugin-market-urls.d.ts +8 -0
  181. package/dist/index.js +1 -1
  182. package/dist/server/index.js +1 -1
  183. package/dist/shared/datetime-picker.js +1 -1
  184. package/dist/shared/excel.js +1 -1
  185. package/dist/shared/index.js +1 -1
  186. package/dist/shared/locale-json.js +1 -1
  187. package/dist/shared/tree.js +1 -1
  188. package/package.json +13 -4
  189. package/typings/admin/theme.ts +10 -0
  190. package/dist/admin/config/plugin-dev.d.ts +0 -52
  191. package/dist/admin/config/plugin-dev.js +0 -1
  192. package/dist/comm/chinese-segments.test.d.ts +0 -1
  193. package/dist/comm/path.test.d.ts +0 -1
  194. package/typings/admin/base/auth.d.ts +0 -21
  195. package/typings/admin/base/permission.d.ts +0 -19
  196. package/typings/admin/comm/crud.d.ts +0 -343
  197. package/typings/admin/comm/eps.d.ts +0 -66
  198. package/typings/admin/comm/request.d.ts +0 -13
  199. package/typings/admin/comm/service.d.ts +0 -48
  200. package/typings/admin/comm/upload.d.ts +0 -26
  201. package/typings/admin/host.d.ts +0 -66
  202. package/typings/admin/vome/browser.d.ts +0 -10
  203. package/typings/admin/vome/module.d.ts +0 -13
@@ -0,0 +1,233 @@
1
+ <template>
2
+ <div ref="rootRef" class="vm-tags">
3
+ <div ref="trackRef" class="vm-tags__track" :style="trackStyle">
4
+ <button
5
+ v-for="tag in list"
6
+ :key="tag.path"
7
+ type="button"
8
+ class="vm-tags__item"
9
+ :class="{ 'is-active': route.path === tag.path }"
10
+ @click="router.push(tag.fullPath)"
11
+ @click.middle="close(tag.path, $event)"
12
+ >
13
+ <span class="vm-tags__title">{{ tagTitle(tag) }}</span>
14
+ <i
15
+ v-if="tag.path !== '/'"
16
+ class="ri-close-line vm-tags__close"
17
+ @click="close(tag.path, $event)"
18
+ />
19
+ </button>
20
+ </div>
21
+ </div>
22
+ </template>
23
+
24
+ <script setup lang="ts">
25
+ import { useLocaleStore } from '../../stores/locale'
26
+
27
+ defineOptions({ name: 'vm-tags-view' })
28
+
29
+ const tags = useTagsStore()
30
+ const user = useUserStore()
31
+ const locale = useLocaleStore()
32
+ const route = useRoute()
33
+ const router = useRouter()
34
+
35
+ const rootRef = ref<HTMLElement | null>(null)
36
+ const trackRef = ref<HTMLElement | null>(null)
37
+ const offset = ref(0)
38
+
39
+ /** 首页由顶栏按钮进入,tabs 不再塞首页项 */
40
+ const list = computed(() => tags.list.filter((t) => t.path !== '/'))
41
+
42
+ function findMenuByPath(
43
+ nodes: MenuTreeNode[],
44
+ path: string,
45
+ ): MenuTreeNode | null {
46
+ for (const n of nodes) {
47
+ if (n.router === path) return n
48
+ if (n.children?.length) {
49
+ const hit = findMenuByPath(n.children, path)
50
+ if (hit) return hit
51
+ }
52
+ }
53
+ return null
54
+ }
55
+
56
+ function tagTitle(tag: { path: string; title: string }) {
57
+ const node = findMenuByPath(user.menus, tag.path)
58
+ return node ? locale.tMenu(node) : tag.title
59
+ }
60
+
61
+ const trackStyle = computed(() =>
62
+ offset.value > 0 ? { transform: `translateX(-${offset.value}px)` } : undefined,
63
+ )
64
+
65
+ function measureTabs() {
66
+ const root = rootRef.value
67
+ const track = trackRef.value
68
+ if (!root || !track) return
69
+
70
+ const containerWidth = root.clientWidth
71
+ const items = track.querySelectorAll<HTMLElement>('.vm-tags__item')
72
+ if (!items.length || containerWidth <= 0) {
73
+ offset.value = 0
74
+ return
75
+ }
76
+
77
+ const gap = 4
78
+ const positions: number[] = []
79
+ const widths: number[] = []
80
+ let total = 0
81
+
82
+ items.forEach((el, i) => {
83
+ positions.push(total)
84
+ const w = el.offsetWidth
85
+ widths.push(w)
86
+ total += w + (i < items.length - 1 ? gap : 0)
87
+ })
88
+
89
+ const maxOffset = Math.max(0, total - containerWidth)
90
+ if (maxOffset === 0) {
91
+ offset.value = 0
92
+ return
93
+ }
94
+
95
+ const activeIndex = list.value.findIndex((t) => t.path === route.path)
96
+ // 默认贴右:左侧最早打开的 tab 被裁切隐藏
97
+ let next = maxOffset
98
+
99
+ if (activeIndex >= 0) {
100
+ const left = positions[activeIndex]!
101
+ const right = left + widths[activeIndex]!
102
+ if (left < next) next = left
103
+ if (right > next + containerWidth) next = right - containerWidth
104
+ next = Math.min(maxOffset, Math.max(0, next))
105
+ }
106
+
107
+ offset.value = next
108
+ }
109
+
110
+ let ro: ResizeObserver | undefined
111
+
112
+ function scheduleMeasure() {
113
+ nextTick(() => measureTabs())
114
+ }
115
+
116
+ function close(path: string, e: Event) {
117
+ e.preventDefault()
118
+ e.stopPropagation()
119
+ if (path === '/') return
120
+ const i = list.value.findIndex((t) => t.path === path)
121
+ tags.remove(path)
122
+ if (route.path === path) {
123
+ const next = list.value[i - 1] || list.value[i] || null
124
+ void router.push(next?.fullPath || '/')
125
+ }
126
+ scheduleMeasure()
127
+ }
128
+
129
+ watch(
130
+ () => [list.value.length, route.path, ...list.value.map((t) => t.title)] as const,
131
+ scheduleMeasure,
132
+ )
133
+
134
+ onMounted(() => {
135
+ scheduleMeasure()
136
+ ro = new ResizeObserver(scheduleMeasure)
137
+ if (rootRef.value) ro.observe(rootRef.value)
138
+ if (trackRef.value) ro.observe(trackRef.value)
139
+ })
140
+
141
+ onUnmounted(() => {
142
+ ro?.disconnect()
143
+ })
144
+ </script>
145
+
146
+ <style lang="scss" scoped>
147
+ .vm-tags {
148
+ min-width: 0;
149
+ flex: 1;
150
+ overflow: hidden;
151
+ margin-left: 4px;
152
+ padding: 0;
153
+ }
154
+
155
+ .vm-tags__track {
156
+ display: flex;
157
+ width: max-content;
158
+ align-items: center;
159
+ gap: 4px;
160
+ transition: transform 0.15s ease;
161
+ }
162
+
163
+ .vm-tags__item {
164
+ display: inline-flex;
165
+ height: 32px;
166
+ flex-shrink: 0;
167
+ align-items: center;
168
+ gap: 0;
169
+ padding: 0 10px;
170
+ border: none;
171
+ border-radius: 8px;
172
+ background: var(--muted);
173
+ color: var(--muted-foreground);
174
+ font-size: 12px;
175
+ font-weight: 600;
176
+ line-height: 1;
177
+ cursor: pointer;
178
+ transition:
179
+ background 0.15s ease,
180
+ color 0.15s ease,
181
+ box-shadow 0.15s ease,
182
+ gap 0.15s ease,
183
+ padding 0.15s ease;
184
+
185
+ &:hover {
186
+ gap: 4px;
187
+ padding-right: 8px;
188
+ color: var(--foreground);
189
+ }
190
+
191
+ &.is-active {
192
+ background: #fff;
193
+ color: var(--brand);
194
+ box-shadow: var(--shadow-card);
195
+
196
+ .dark & {
197
+ background: var(--card);
198
+ }
199
+ }
200
+ }
201
+
202
+ .vm-tags__title {
203
+ white-space: nowrap;
204
+ }
205
+
206
+ /* 默认占 0 宽;悬停展开关闭按钮宽度 */
207
+ .vm-tags__close {
208
+ display: inline-flex;
209
+ width: 0;
210
+ height: 14px;
211
+ flex-shrink: 0;
212
+ align-items: center;
213
+ justify-content: center;
214
+ overflow: hidden;
215
+ font-size: 14px;
216
+ line-height: 1;
217
+ opacity: 0;
218
+ transition:
219
+ width 0.15s ease,
220
+ opacity 0.15s ease,
221
+ color 0.15s ease;
222
+
223
+ .vm-tags__item:hover & {
224
+ width: 14px;
225
+ opacity: 0.55;
226
+ }
227
+
228
+ .vm-tags__item:hover &:hover {
229
+ opacity: 1;
230
+ color: var(--destructive);
231
+ }
232
+ }
233
+ </style>
@@ -0,0 +1,18 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { AvatarRoot } from "reka-ui"
4
+ import { cn } from "../../../lib/cn"
5
+
6
+ const props = defineProps<{
7
+ class?: HTMLAttributes["class"]
8
+ }>()
9
+ </script>
10
+
11
+ <template>
12
+ <AvatarRoot
13
+ data-slot="avatar"
14
+ :class="cn('relative flex size-8 shrink-0 overflow-hidden rounded-full', props.class)"
15
+ >
16
+ <slot />
17
+ </AvatarRoot>
18
+ </template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ import type { AvatarFallbackProps } from "reka-ui"
3
+ import type { HTMLAttributes } from "vue"
4
+ import { reactiveOmit } from "@vueuse/core"
5
+ import { AvatarFallback } from "reka-ui"
6
+ import { cn } from "../../../lib/cn"
7
+
8
+ const props = defineProps<AvatarFallbackProps & { class?: HTMLAttributes["class"] }>()
9
+
10
+ const delegatedProps = reactiveOmit(props, "class")
11
+ </script>
12
+
13
+ <template>
14
+ <AvatarFallback
15
+ data-slot="avatar-fallback"
16
+ v-bind="delegatedProps"
17
+ :class="cn('bg-muted flex size-full items-center justify-center rounded-full', props.class)"
18
+ >
19
+ <slot />
20
+ </AvatarFallback>
21
+ </template>
@@ -0,0 +1,16 @@
1
+ <script setup lang="ts">
2
+ import type { AvatarImageProps } from "reka-ui"
3
+ import { AvatarImage } from "reka-ui"
4
+
5
+ const props = defineProps<AvatarImageProps>()
6
+ </script>
7
+
8
+ <template>
9
+ <AvatarImage
10
+ data-slot="avatar-image"
11
+ v-bind="props"
12
+ class="aspect-square size-full"
13
+ >
14
+ <slot />
15
+ </AvatarImage>
16
+ </template>
@@ -0,0 +1,3 @@
1
+ export { default as Avatar } from "./Avatar.vue";
2
+ export { default as AvatarFallback } from "./AvatarFallback.vue";
3
+ export { default as AvatarImage } from "./AvatarImage.vue";
@@ -0,0 +1 @@
1
+ function _0x3c11(_0x5f428c,_0x33dfe1){_0x5f428c=_0x5f428c-0x1d3;var _0x15660b=_0x1566();var _0x3c1179=_0x15660b[_0x5f428c];if(_0x3c11['DidZRj']===undefined){var _0x10d285=function(_0x7c43f5){var _0x266c31='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var _0x550ded='',_0x43274e='';for(var _0x389e59=0x0,_0x31fa87,_0x18aab3,_0x204e34=0x0;_0x18aab3=_0x7c43f5['charAt'](_0x204e34++);~_0x18aab3&&(_0x31fa87=_0x389e59%0x4?_0x31fa87*0x40+_0x18aab3:_0x18aab3,_0x389e59++%0x4)?_0x550ded+=String['fromCharCode'](0xff&_0x31fa87>>(-0x2*_0x389e59&0x6)):0x0){_0x18aab3=_0x266c31['indexOf'](_0x18aab3);}for(var _0x1f2f07=0x0,_0x5870eb=_0x550ded['length'];_0x1f2f07<_0x5870eb;_0x1f2f07++){_0x43274e+='%'+('00'+_0x550ded['charCodeAt'](_0x1f2f07)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x43274e);};_0x3c11['TpveSY']=_0x10d285,_0x3c11['ykRkOh']={},_0x3c11['DidZRj']=!![];}var _0x1af474=_0x15660b[0x0],_0x473033=_0x5f428c+_0x1af474,_0x23449f=_0x3c11['ykRkOh'][_0x473033];return!_0x23449f?(_0x3c1179=_0x3c11['TpveSY'](_0x3c1179),_0x3c11['ykRkOh'][_0x473033]=_0x3c1179):_0x3c1179=_0x23449f,_0x3c1179;}(function(_0x26c3a1,_0x23e5f7){var _0x49dbfd=_0x3c11,_0x57de02=_0x26c3a1();while(!![]){try{var _0x1adbac=parseInt(_0x49dbfd(0x1d3))/0x1*(parseInt(_0x49dbfd(0x1d6))/0x2)+parseInt(_0x49dbfd(0x1d7))/0x3+parseInt(_0x49dbfd(0x1d8))/0x4*(parseInt(_0x49dbfd(0x1d9))/0x5)+parseInt(_0x49dbfd(0x1db))/0x6*(-parseInt(_0x49dbfd(0x1d5))/0x7)+-parseInt(_0x49dbfd(0x1da))/0x8+-parseInt(_0x49dbfd(0x1dc))/0x9+parseInt(_0x49dbfd(0x1d4))/0xa;if(_0x1adbac===_0x23e5f7)break;else _0x57de02['push'](_0x57de02['shift']());}catch(_0x1e69c7){_0x57de02['push'](_0x57de02['shift']());}}}(_0x1566,0xdc609));export{default as Avatar}from'./Avatar.vue';function _0x1566(){var _0x5457cc=['mZiYmerOy1rcyG','otC2mMr3sNLkza','mtaXndm5m0PPz0LUtG','mZG1ndbgAurbyva','ndvjs3PZEhK','ndy1otCZnKvRCeznBq','mteZnZbSr0fAEfe','ntyYndq3ohPUyMjTqq','mtuXBuftzvPc','mtGXotG5nZbXz1vfEgi'];_0x1566=function(){return _0x5457cc;};return _0x1566();}export{default as AvatarFallback}from'./AvatarFallback.vue';export{default as AvatarImage}from'./AvatarImage.vue';
@@ -0,0 +1,26 @@
1
+ <script setup lang="ts">
2
+ import type { PrimitiveProps } from "reka-ui"
3
+ import type { HTMLAttributes } from "vue"
4
+ import type { BadgeVariants } from "."
5
+ import { reactiveOmit } from "@vueuse/core"
6
+ import { Primitive } from "reka-ui"
7
+ import { cn } from "../../../lib/cn"
8
+ import { badgeVariants } from "."
9
+
10
+ const props = defineProps<PrimitiveProps & {
11
+ variant?: BadgeVariants["variant"]
12
+ class?: HTMLAttributes["class"]
13
+ }>()
14
+
15
+ const delegatedProps = reactiveOmit(props, "class")
16
+ </script>
17
+
18
+ <template>
19
+ <Primitive
20
+ data-slot="badge"
21
+ :class="cn(badgeVariants({ variant }), props.class)"
22
+ v-bind="delegatedProps"
23
+ >
24
+ <slot />
25
+ </Primitive>
26
+ </template>
@@ -0,0 +1,6 @@
1
+ import type { VariantProps } from "class-variance-authority";
2
+ export { default as Badge } from "./Badge.vue";
3
+ export declare const badgeVariants: (props?: {
4
+ variant?: "default" | "outline" | "secondary" | "destructive";
5
+ } & import("class-variance-authority/types").ClassProp) => string;
6
+ export type BadgeVariants = VariantProps<typeof badgeVariants>;
@@ -0,0 +1 @@
1
+ const _0xb52dc7=_0x5c96;function _0x5c96(_0x2ebea5,_0x3628e1){_0x2ebea5=_0x2ebea5-0x1d4;const _0x408337=_0x4083();let _0x5c9649=_0x408337[_0x2ebea5];if(_0x5c96['fjCFHb']===undefined){var _0x1afef7=function(_0x2fc7de){const _0x3fbef4='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x12aeae='',_0x2ff191='';for(let _0x55e046=0x0,_0x134ab0,_0x5872fe,_0xa4c905=0x0;_0x5872fe=_0x2fc7de['charAt'](_0xa4c905++);~_0x5872fe&&(_0x134ab0=_0x55e046%0x4?_0x134ab0*0x40+_0x5872fe:_0x5872fe,_0x55e046++%0x4)?_0x12aeae+=String['fromCharCode'](0xff&_0x134ab0>>(-0x2*_0x55e046&0x6)):0x0){_0x5872fe=_0x3fbef4['indexOf'](_0x5872fe);}for(let _0x56e2a4=0x0,_0x16336a=_0x12aeae['length'];_0x56e2a4<_0x16336a;_0x56e2a4++){_0x2ff191+='%'+('00'+_0x12aeae['charCodeAt'](_0x56e2a4)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x2ff191);};_0x5c96['QHKcuW']=_0x1afef7,_0x5c96['gwXBRC']={},_0x5c96['fjCFHb']=!![];}const _0x35ab87=_0x408337[0x0],_0x81487d=_0x2ebea5+_0x35ab87,_0x159aeb=_0x5c96['gwXBRC'][_0x81487d];return!_0x159aeb?(_0x5c9649=_0x5c96['QHKcuW'](_0x5c9649),_0x5c96['gwXBRC'][_0x81487d]=_0x5c9649):_0x5c9649=_0x159aeb,_0x5c9649;}(function(_0xcd5e34,_0x497daf){const _0x387f8f=_0x5c96,_0x538327=_0xcd5e34();while(!![]){try{const _0x4b5688=parseInt(_0x387f8f(0x1d5))/0x1+parseInt(_0x387f8f(0x1d8))/0x2+-parseInt(_0x387f8f(0x1d6))/0x3+parseInt(_0x387f8f(0x1d4))/0x4+-parseInt(_0x387f8f(0x1dd))/0x5*(parseInt(_0x387f8f(0x1da))/0x6)+parseInt(_0x387f8f(0x1d9))/0x7*(parseInt(_0x387f8f(0x1dc))/0x8)+-parseInt(_0x387f8f(0x1d7))/0x9;if(_0x4b5688===_0x497daf)break;else _0x538327['push'](_0x538327['shift']());}catch(_0x44cba7){_0x538327['push'](_0x538327['shift']());}}}(_0x4083,0x4370c));import{cva}from'class-variance-authority';function _0x4083(){const _0x11b3da=['Dgv4Dc1MB3jLz3jVDw5KifTHjL06Ag92zxi6yMCTywnJzw50ifTHjL06Ag92zxi6Dgv4Dc1Hy2nLBNqTzM9YzwDYB3vUza','mtG4otiZmMzzwhnPvW','mJK1nMnqrgXSza','otG3mti5q21YsgTx','mZaWmdC4oxHIwK1hqq','odG0otG2q3fozLH1','n0j3EMDNtW','odrvr2LHsu0','yM9YzgvYlxrYyw5ZCgfYzw50igjNlxnLy29UzgfYEsb0zxH0lxnLy29UzgfYEs1MB3jLz3jVDw5KifTHjL06Ag92zxi6yMCTC2vJB25Kyxj5lZKW','mZyZmZq5nLvvBxvArG','mtu0nZmWyMHzuMXZ'];_0x4083=function(){return _0x11b3da;};return _0x4083();}export{default as Badge}from'./Badge.vue';export const badgeVariants=cva('inline-flex\x20items-center\x20justify-center\x20rounded-full\x20border\x20px-2\x20py-0.5\x20text-xs\x20font-medium\x20w-fit\x20whitespace-nowrap\x20shrink-0\x20[&>svg]:size-3\x20gap-1\x20[&>svg]:pointer-events-none\x20focus-visible:border-ring\x20focus-visible:ring-ring/50\x20focus-visible:ring-3\x20aria-invalid:ring-destructive/20\x20dark:aria-invalid:ring-destructive/40\x20aria-invalid:border-destructive\x20transition-[color,box-shadow]\x20overflow-hidden',{'variants':{'variant':{'default':'border-transparent\x20bg-primary\x20text-primary-foreground\x20[a&]:hover:bg-primary/90','secondary':_0xb52dc7(0x1db),'destructive':'border-transparent\x20bg-destructive\x20text-white\x20[a&]:hover:bg-destructive/90\x20focus-visible:ring-destructive/20\x20dark:focus-visible:ring-destructive/40\x20dark:bg-destructive/60','outline':_0xb52dc7(0x1de)}},'defaultVariants':{'variant':'default'}});
@@ -0,0 +1,31 @@
1
+ <script setup lang="ts">
2
+ import type { PrimitiveProps } from "reka-ui"
3
+ import type { HTMLAttributes } from "vue"
4
+ import type { ButtonVariants } from "."
5
+ import { Primitive } from "reka-ui"
6
+ import { cn } from "../../../lib/cn"
7
+ import { buttonVariants } from "."
8
+
9
+ interface Props extends PrimitiveProps {
10
+ variant?: ButtonVariants["variant"]
11
+ size?: ButtonVariants["size"]
12
+ class?: HTMLAttributes["class"]
13
+ }
14
+
15
+ const props = withDefaults(defineProps<Props>(), {
16
+ as: "button",
17
+ })
18
+ </script>
19
+
20
+ <template>
21
+ <Primitive
22
+ data-slot="button"
23
+ :data-variant="variant"
24
+ :data-size="size"
25
+ :as="as"
26
+ :as-child="asChild"
27
+ :class="cn(buttonVariants({ variant, size }), props.class)"
28
+ >
29
+ <slot />
30
+ </Primitive>
31
+ </template>
@@ -0,0 +1,7 @@
1
+ import type { VariantProps } from "class-variance-authority";
2
+ export { default as Button } from "./Button.vue";
3
+ export declare const buttonVariants: (props?: {
4
+ variant?: "default" | "softPrimary" | "softDestructive" | "softSuccess" | "ghost" | "outline" | "secondary" | "destructive" | "link";
5
+ size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg";
6
+ } & import("class-variance-authority/types").ClassProp) => string;
7
+ export type ButtonVariants = VariantProps<typeof buttonVariants>;
@@ -0,0 +1 @@
1
+ function _0x6128(_0xd8c402,_0x120dcc){_0xd8c402=_0xd8c402-0x156;const _0x2ed87d=_0x2ed8();let _0x612832=_0x2ed87d[_0xd8c402];if(_0x6128['mueZmn']===undefined){var _0x341327=function(_0x5d9157){const _0x29412e='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0xc66d2f='',_0x34cf8b='';for(let _0x176e98=0x0,_0x8e564c,_0x1a80cf,_0x5c9948=0x0;_0x1a80cf=_0x5d9157['charAt'](_0x5c9948++);~_0x1a80cf&&(_0x8e564c=_0x176e98%0x4?_0x8e564c*0x40+_0x1a80cf:_0x1a80cf,_0x176e98++%0x4)?_0xc66d2f+=String['fromCharCode'](0xff&_0x8e564c>>(-0x2*_0x176e98&0x6)):0x0){_0x1a80cf=_0x29412e['indexOf'](_0x1a80cf);}for(let _0x3a93b7=0x0,_0x2e3ed3=_0xc66d2f['length'];_0x3a93b7<_0x2e3ed3;_0x3a93b7++){_0x34cf8b+='%'+('00'+_0xc66d2f['charCodeAt'](_0x3a93b7)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x34cf8b);};_0x6128['RqdToB']=_0x341327,_0x6128['kJrbpV']={},_0x6128['mueZmn']=!![];}const _0x1a2f03=_0x2ed87d[0x0],_0x3f650c=_0xd8c402+_0x1a2f03,_0x5961f6=_0x6128['kJrbpV'][_0x3f650c];return!_0x5961f6?(_0x612832=_0x6128['RqdToB'](_0x612832),_0x6128['kJrbpV'][_0x3f650c]=_0x612832):_0x612832=_0x5961f6,_0x612832;}const _0x43799c=_0x6128;(function(_0x2041dd,_0x3079bf){const _0x877bb9=_0x6128,_0x3a645c=_0x2041dd();while(!![]){try{const _0x4595c7=parseInt(_0x877bb9(0x167))/0x1+-parseInt(_0x877bb9(0x164))/0x2+parseInt(_0x877bb9(0x166))/0x3*(-parseInt(_0x877bb9(0x161))/0x4)+-parseInt(_0x877bb9(0x162))/0x5*(parseInt(_0x877bb9(0x15d))/0x6)+parseInt(_0x877bb9(0x15a))/0x7+-parseInt(_0x877bb9(0x163))/0x8*(-parseInt(_0x877bb9(0x159))/0x9)+parseInt(_0x877bb9(0x160))/0xa*(parseInt(_0x877bb9(0x15b))/0xb);if(_0x4595c7===_0x3079bf)break;else _0x3a645c['push'](_0x3a645c['shift']());}catch(_0x56f803){_0x3a645c['push'](_0x3a645c['shift']());}}}(_0x2ed8,0x34f7e));import{cva}from'class-variance-authority';function _0x2ed8(){const _0x208d87=['ndi5mti2mhLKyLLjEG','nZa2mdG0CxvrAgr3','nu10AKvbuW','nZKYnZuYy3nZBg1t','ndqXnta2r2z4wu1V','C2L6zs02ihjVDw5KzwqTwZeWChHDifSMx3n2zZPUB3qOw2nSyxnZkJ0NC2L6zs0NxsLDoNnPEMuTmW','nNPQzfnwzq','ndy2mtDlt3bAv1y','yM9YzgvYigjNlwjHy2TNCM91BMqGC2HHzg93lxHZigHVDMvYoMjNlwfJy2vUDcbOB3zLCJP0zxH0lwfJy2vUDc1MB3jLz3jVDw5KigrHCMS6yMCTAw5WDxqVmZaGzgfYAZPIB3jKzxiTAw5WDxqGzgfYAZPOB3zLCJPIzY1PBNb1Dc81ma','Ac05ihb4ltqGChKTmIbOyxmTwZ5ZDMDDoNb4ltm','zgvMyxvSDa','C2L6zs04ihjVDw5KzwqTwZeYChHD','Ac0XmcbYB3vUzgvKlvSXmNb4xsbWEc02igHHCY1BpNn2z106ChGTna','Dgv4Dc1WCMLTyxj5ihvUzgvYBgLUzs1VzMzZzxqTncbOB3zLCJP1BMrLCMXPBMu','Ac04ihjVDw5KzwqTwZeYChHDigDHCc0XlJuGChGTmYbOyxmTwZ5ZDMDDoNb4ltiUnq','yM9YzgvYigjVCMrLCI1BDMfYkc0TyNjHBMqPxsbIzY10CMfUC3bHCMvUDcb0zxH0lvT2yxiOls1ICMfUzcLDigHVDMvYoMjNlvT2yxiOls1ICMfUzc1ZB2z0kv0','C2L6zs05ihjVDw5KzwqTwZeYChHD','yMCTChjPBwfYEsb0zxH0lxbYAw1HCNKTzM9YzwDYB3vUzcbOB3zLCJPIzY1WCMLTyxj5lZKW','Aw5SAw5LlwzSzxGGAxrLBxmTy2vUDgvYigP1C3rPzNKTy2vUDgvYigDHCc0YihDOAxrLC3bHy2uTBM93CMfWihjVDw5KzwqTwZeYChHDihrLEhqTC20GzM9UDc1Zzw1PyM9Szcb0CMfUC2L0Aw9UlwfSBcbKAxnHyMXLzdPWB2LUDgvYlwv2zw50CY1UB25LigrPC2fIBgvKoM9WywnPDhKTntaGwYzFC3zNxtPWB2LUDgvYlwv2zw50CY1UB25LifSMx3n2zZPUB3qOw2nSyxnZkJ0NC2L6zs0NxsLDoNnPEMuTncbZAhjPBMSTmcbBjL9ZDMDDoNnOCMLUAY0Wig91DgXPBMuTBM9UzsbMB2n1CY12AxnPyMXLoMjVCMrLCI1YAw5NigzVy3vZlxzPC2LIBgu6CMLUzY1YAw5NlZuWigzVy3vZlxzPC2LIBgu6CMLUzY0ZigfYAweTAw52ywXPzdPYAw5NlwrLC3rYDwn0AxzLlZiWigrHCMS6yxjPys1PBNzHBgLKoNjPBMCTzgvZDhj1y3rPDMuVndaGyxjPys1PBNzHBgLKoMjVCMrLCI1Kzxn0CNvJDgL2zq','yM9YzgvYigjVCMrLCI1BDMfYkc0TzgfUz2vYkv0GyMCTDhjHBNnWyxjLBNqGDgv4Dc1BDMfYkc0TzgfUz2vYkv0GAg92zxi6yMCTw3zHCIGTlwrHBMDLCI1ZB2z0kv0','ouXyBM9ezW','mJG2mtaZm29fuvHIsW','mtfyD0v3CgG','yMCTBxv0zwqGDgv4Dc1MB3jLz3jVDw5KigHVDMvYoMjNlw11DgvKlZGWigrHCMS6Ag92zxi6yMCTBxv0zwqVnZa','mte1nJGXohbusfv1vW','yMCTzgvZDhj1y3rPDMuGDgv4Dc13AgL0zsbOB3zLCJPIzY1Kzxn0CNvJDgL2zs85mcbMB2n1CY12AxnPyMXLoNjPBMCTzgvZDhj1y3rPDMuVmJaGzgfYAZPMB2n1CY12AxnPyMXLoNjPBMCTzgvZDhj1y3rPDMuVndaGzgfYAZPIzY1Kzxn0CNvJDgL2zs82ma','C2L6zs0XmcbYB3vUzgvKlvSXmNb4xq'];_0x2ed8=function(){return _0x208d87;};return _0x2ed8();}export{default as Button}from'./Button.vue';export const buttonVariants=cva(_0x43799c(0x157),{'variants':{'variant':{'default':_0x43799c(0x156),'destructive':_0x43799c(0x15e),'outline':_0x43799c(0x168),'secondary':'bg-secondary\x20text-secondary-foreground\x20hover:bg-secondary/80','ghost':_0x43799c(0x15c),'softPrimary':_0x43799c(0x16f),'softSuccess':'border\x20border-[var(--success)]\x20bg-transparent\x20text-[var(--success)]\x20hover:bg-[var(--success-soft)]','softDestructive':_0x43799c(0x158),'link':_0x43799c(0x16d)},'size':{'default':_0x43799c(0x169),'xs':'h-8\x20gap-1\x20rounded-[12px]\x20px-3.5\x20text-[13px]\x20has-[>svg]:px-2.5\x20[&_svg:not([class*=\x27size-\x27])]:size-3.5','sm':_0x43799c(0x16e),'lg':_0x43799c(0x16c),'icon':_0x43799c(0x170),'icon-xs':_0x43799c(0x165),'icon-sm':_0x43799c(0x16b),'icon-lg':_0x43799c(0x15f)}},'defaultVariants':{'variant':_0x43799c(0x16a),'size':_0x43799c(0x16a)}});
@@ -0,0 +1,35 @@
1
+ <script setup lang="ts">
2
+ import type { CheckboxRootEmits, CheckboxRootProps } from "reka-ui"
3
+ import type { HTMLAttributes } from "vue"
4
+ import { Check } from "@lucide/vue"
5
+ import { reactiveOmit } from "@vueuse/core"
6
+ import { CheckboxIndicator, CheckboxRoot, useForwardPropsEmits } from "reka-ui"
7
+ import { cn } from "../../../lib/cn"
8
+
9
+ const props = defineProps<CheckboxRootProps & { class?: HTMLAttributes["class"] }>()
10
+ const emits = defineEmits<CheckboxRootEmits>()
11
+
12
+ const delegatedProps = reactiveOmit(props, "class")
13
+
14
+ const forwarded = useForwardPropsEmits(delegatedProps, emits)
15
+ </script>
16
+
17
+ <template>
18
+ <CheckboxRoot
19
+ v-slot="slotProps"
20
+ data-slot="checkbox"
21
+ v-bind="forwarded"
22
+ :class="
23
+ cn('peer border-input data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-3 disabled:cursor-not-allowed disabled:opacity-50',
24
+ props.class)"
25
+ >
26
+ <CheckboxIndicator
27
+ data-slot="checkbox-indicator"
28
+ class="grid place-content-center text-current transition-none"
29
+ >
30
+ <slot v-bind="slotProps">
31
+ <Check class="size-3.5" />
32
+ </slot>
33
+ </CheckboxIndicator>
34
+ </CheckboxRoot>
35
+ </template>
@@ -0,0 +1 @@
1
+ export { default as Checkbox } from "./Checkbox.vue";
@@ -0,0 +1 @@
1
+ (function(_0x317fb3,_0x3cb5a1){var _0x1267d4=_0x11f2,_0x2ca121=_0x317fb3();while(!![]){try{var _0x39ee78=parseInt(_0x1267d4(0x1a5))/0x1+-parseInt(_0x1267d4(0x1a2))/0x2+parseInt(_0x1267d4(0x1a3))/0x3*(parseInt(_0x1267d4(0x1a6))/0x4)+-parseInt(_0x1267d4(0x1a4))/0x5+parseInt(_0x1267d4(0x1a9))/0x6*(parseInt(_0x1267d4(0x1a8))/0x7)+parseInt(_0x1267d4(0x1a1))/0x8+-parseInt(_0x1267d4(0x1a7))/0x9;if(_0x39ee78===_0x3cb5a1)break;else _0x2ca121['push'](_0x2ca121['shift']());}catch(_0x146d54){_0x2ca121['push'](_0x2ca121['shift']());}}}(_0x1b55,0x77929));export{default as Checkbox}from'./Checkbox.vue';function _0x11f2(_0x5b27c5,_0x2ae9bc){_0x5b27c5=_0x5b27c5-0x1a1;var _0x1b5546=_0x1b55();var _0x11f290=_0x1b5546[_0x5b27c5];if(_0x11f2['kHBCaZ']===undefined){var _0x1a47ee=function(_0x58191b){var _0x6edb9b='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var _0x294e8a='',_0x4f82ad='';for(var _0x1626f2=0x0,_0x4ade24,_0x1aaf01,_0x465660=0x0;_0x1aaf01=_0x58191b['charAt'](_0x465660++);~_0x1aaf01&&(_0x4ade24=_0x1626f2%0x4?_0x4ade24*0x40+_0x1aaf01:_0x1aaf01,_0x1626f2++%0x4)?_0x294e8a+=String['fromCharCode'](0xff&_0x4ade24>>(-0x2*_0x1626f2&0x6)):0x0){_0x1aaf01=_0x6edb9b['indexOf'](_0x1aaf01);}for(var _0x3485a3=0x0,_0x14ba4e=_0x294e8a['length'];_0x3485a3<_0x14ba4e;_0x3485a3++){_0x4f82ad+='%'+('00'+_0x294e8a['charCodeAt'](_0x3485a3)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x4f82ad);};_0x11f2['dUmKih']=_0x1a47ee,_0x11f2['xzwuiz']={},_0x11f2['kHBCaZ']=!![];}var _0x842900=_0x1b5546[0x0],_0xbfc4d0=_0x5b27c5+_0x842900,_0x100269=_0x11f2['xzwuiz'][_0xbfc4d0];return!_0x100269?(_0x11f290=_0x11f2['dUmKih'](_0x11f290),_0x11f2['xzwuiz'][_0xbfc4d0]=_0x11f290):_0x11f290=_0x100269,_0x11f290;}function _0x1b55(){var _0x58366b=['mJfbru1iyK4','mJe1nZy3mfj4rvD6yq','nJuZnZy1vePtEM51','mZe5mdC2t3vlrgLf','mJK3nZq0m2zoCvruuW','mJe3AvvWqNbU','otaWnJbzyNHPtfO','nZK0nde2u3DABwjh','mta0oti2mgnyAuHHzq'];_0x1b55=function(){return _0x58366b;};return _0x1b55();}
@@ -0,0 +1,19 @@
1
+ <script setup lang="ts">
2
+ import type { DialogRootEmits, DialogRootProps } from "reka-ui"
3
+ import { DialogRoot, useForwardPropsEmits } from "reka-ui"
4
+
5
+ const props = defineProps<DialogRootProps>()
6
+ const emits = defineEmits<DialogRootEmits>()
7
+
8
+ const forwarded = useForwardPropsEmits(props, emits)
9
+ </script>
10
+
11
+ <template>
12
+ <DialogRoot
13
+ v-slot="slotProps"
14
+ data-slot="dialog"
15
+ v-bind="forwarded"
16
+ >
17
+ <slot v-bind="slotProps" />
18
+ </DialogRoot>
19
+ </template>
@@ -0,0 +1,15 @@
1
+ <script setup lang="ts">
2
+ import type { DialogCloseProps } from "reka-ui"
3
+ import { DialogClose } from "reka-ui"
4
+
5
+ const props = defineProps<DialogCloseProps>()
6
+ </script>
7
+
8
+ <template>
9
+ <DialogClose
10
+ data-slot="dialog-close"
11
+ v-bind="props"
12
+ >
13
+ <slot />
14
+ </DialogClose>
15
+ </template>
@@ -0,0 +1,135 @@
1
+ <script setup lang="ts">
2
+ import type { DialogContentEmits, DialogContentProps } from "reka-ui"
3
+ import type { HTMLAttributes } from "vue"
4
+ import { X } from "@lucide/vue"
5
+ import { reactiveOmit } from "@vueuse/core"
6
+ import {
7
+ DialogClose,
8
+ DialogContent,
9
+ DialogPortal,
10
+ useForwardPropsEmits,
11
+ } from "reka-ui"
12
+ import { cn } from "../../../lib/cn"
13
+ import DialogOverlay from "./DialogOverlay.vue"
14
+
15
+ defineOptions({
16
+ inheritAttrs: false,
17
+ })
18
+
19
+ const props = withDefaults(
20
+ defineProps<
21
+ DialogContentProps & {
22
+ class?: HTMLAttributes["class"]
23
+ showCloseButton?: boolean
24
+ /** CRUD 弹窗:桌面 50vw,≤768px 全屏 */
25
+ shell?: "crud" | "default"
26
+ }
27
+ >(),
28
+ {
29
+ showCloseButton: true,
30
+ shell: "default",
31
+ },
32
+ )
33
+ const emits = defineEmits<DialogContentEmits>()
34
+
35
+ const delegatedProps = reactiveOmit(props, "class", "shell", "showCloseButton")
36
+
37
+ const forwarded = useForwardPropsEmits(delegatedProps, emits)
38
+ </script>
39
+
40
+ <template>
41
+ <DialogPortal>
42
+ <DialogOverlay />
43
+ <DialogContent
44
+ data-slot="dialog-content"
45
+ :data-shell="shell"
46
+ v-bind="{ ...$attrs, ...forwarded }"
47
+ :aria-describedby="undefined"
48
+ :class="
49
+ cn(
50
+ 'bg-card data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed z-50 duration-200',
51
+ // default:居中卡片;crud:定位交给下方 CSS(避免 top/translate 与移动端全屏打架)
52
+ shell === 'default' &&
53
+ 'top-[50%] left-[50%] grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg',
54
+ shell === 'crud' && 'vm-dialog-shell-crud',
55
+ props.class,
56
+ )
57
+ "
58
+ >
59
+ <slot />
60
+
61
+ <DialogClose
62
+ v-if="showCloseButton"
63
+ data-slot="dialog-close"
64
+ class="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-3 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
65
+ >
66
+ <X />
67
+ <span class="sr-only">Close</span>
68
+ </DialogClose>
69
+ </DialogContent>
70
+ </DialogPortal>
71
+ </template>
72
+
73
+ <!--
74
+ 宽度写死在此:reka DismissableLayer 会覆盖透传的 style;
75
+ Tailwind w-full 在 max-w 失效时会撑满视口。CRUD 壳层用属性选择器 + !important。
76
+ -->
77
+ <style>
78
+ .vm-dialog-shell-crud[data-slot='dialog-content'],
79
+ [data-slot='dialog-content'][data-shell='crud'] {
80
+ top: 50%;
81
+ left: 50%;
82
+ display: flex !important;
83
+ width: 50vw !important;
84
+ max-width: 50vw !important;
85
+ min-width: 0 !important;
86
+ min-height: 400px;
87
+ max-height: 800px;
88
+ height: auto;
89
+ flex-direction: column;
90
+ gap: 0 !important;
91
+ padding: 0 !important;
92
+ overflow: hidden;
93
+ border: none !important;
94
+ border-radius: 24px !important;
95
+ box-shadow: var(--shadow-soft) !important;
96
+ translate: -50% -50%;
97
+ }
98
+
99
+ /* 列表类弹窗:直接拉满规范最高高度 */
100
+ .vm-dialog-shell-crud.is-fill[data-slot='dialog-content'],
101
+ [data-slot='dialog-content'][data-shell='crud'].is-fill {
102
+ height: 800px !important;
103
+ max-height: 800px !important;
104
+ }
105
+
106
+ /* 指定高度:--vm-dialog-height(如 800px) */
107
+ .vm-dialog-shell-crud.is-height[data-slot='dialog-content'],
108
+ [data-slot='dialog-content'][data-shell='crud'].is-height {
109
+ height: var(--vm-dialog-height) !important;
110
+ max-height: var(--vm-dialog-height) !important;
111
+ }
112
+
113
+ /* 移动端:铺满视口(无上下边距、无圆角) */
114
+ @media (max-width: 768px) {
115
+ .vm-dialog-shell-crud[data-slot='dialog-content'],
116
+ [data-slot='dialog-content'][data-shell='crud'] {
117
+ inset: 0 !important;
118
+ top: 0 !important;
119
+ right: 0 !important;
120
+ bottom: 0 !important;
121
+ left: 0 !important;
122
+ width: 100vw !important;
123
+ max-width: 100vw !important;
124
+ height: 100dvh !important;
125
+ max-height: 100dvh !important;
126
+ min-height: 100dvh !important;
127
+ margin: 0 !important;
128
+ border-radius: 0 !important;
129
+ overflow: hidden !important;
130
+ translate: none !important;
131
+ transform: none !important;
132
+ animation: none !important;
133
+ }
134
+ }
135
+ </style>
@@ -0,0 +1,23 @@
1
+ <script setup lang="ts">
2
+ import type { DialogDescriptionProps } from "reka-ui"
3
+ import type { HTMLAttributes } from "vue"
4
+ import { reactiveOmit } from "@vueuse/core"
5
+ import { DialogDescription, useForwardProps } from "reka-ui"
6
+ import { cn } from "../../../lib/cn"
7
+
8
+ const props = defineProps<DialogDescriptionProps & { class?: HTMLAttributes["class"] }>()
9
+
10
+ const delegatedProps = reactiveOmit(props, "class")
11
+
12
+ const forwardedProps = useForwardProps(delegatedProps)
13
+ </script>
14
+
15
+ <template>
16
+ <DialogDescription
17
+ data-slot="dialog-description"
18
+ v-bind="forwardedProps"
19
+ :class="cn('text-muted-foreground text-sm', props.class)"
20
+ >
21
+ <slot />
22
+ </DialogDescription>
23
+ </template>
@@ -0,0 +1,27 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { DialogClose } from "reka-ui"
4
+ import { cn } from "../../../lib/cn"
5
+ import { Button } from '../button'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ class?: HTMLAttributes["class"]
9
+ showCloseButton?: boolean
10
+ }>(), {
11
+ showCloseButton: false,
12
+ })
13
+ </script>
14
+
15
+ <template>
16
+ <div
17
+ data-slot="dialog-footer"
18
+ :class="cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', props.class)"
19
+ >
20
+ <slot />
21
+ <DialogClose v-if="showCloseButton" as-child>
22
+ <Button variant="outline">
23
+ Close
24
+ </Button>
25
+ </DialogClose>
26
+ </div>
27
+ </template>