@squadbase/vantage 0.6.2-dev1.a7c4a3e → 0.6.2-dev1.b28a4df

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 (225) hide show
  1. package/dist/add-4GHF2TX2.js +6 -0
  2. package/dist/add-4GHF2TX2.js.map +1 -0
  3. package/dist/{build-JB4VOMUI.js → build-X5NVCQKT.js} +9 -9
  4. package/dist/{build-JB4VOMUI.js.map → build-X5NVCQKT.js.map} +1 -1
  5. package/dist/{check-ZJYK6RLG.js → check-ZBIH422T.js} +7 -7
  6. package/dist/{check-ZJYK6RLG.js.map → check-ZBIH422T.js.map} +1 -1
  7. package/dist/chunk-2ICNHUG6.js +1820 -0
  8. package/dist/chunk-2ICNHUG6.js.map +1 -0
  9. package/dist/{chunk-5ZOP4SQR.js → chunk-2N72FKLB.js} +12 -7
  10. package/dist/chunk-2N72FKLB.js.map +1 -0
  11. package/dist/{chunk-BCE22JSM.js → chunk-7DZGJQ3P.js} +33 -14
  12. package/dist/chunk-7DZGJQ3P.js.map +1 -0
  13. package/dist/{chunk-U2M6HGKQ.js → chunk-AABMKHEU.js} +4 -4
  14. package/dist/{chunk-U2M6HGKQ.js.map → chunk-AABMKHEU.js.map} +1 -1
  15. package/dist/{chunk-KLEIVDUV.js → chunk-CEXAQQ5W.js} +150 -11
  16. package/dist/chunk-CEXAQQ5W.js.map +1 -0
  17. package/dist/{chunk-QI3XQKHS.js → chunk-GNXCX4WE.js} +10 -3
  18. package/dist/chunk-GNXCX4WE.js.map +1 -0
  19. package/dist/{chunk-JGRMRXXZ.js → chunk-JKLLFVEU.js} +3 -3
  20. package/dist/{chunk-JGRMRXXZ.js.map → chunk-JKLLFVEU.js.map} +1 -1
  21. package/dist/{chunk-PXRX5PEC.js → chunk-PDOBHMUQ.js} +3 -3
  22. package/dist/chunk-PDOBHMUQ.js.map +1 -0
  23. package/dist/{chunk-ZVANIULZ.js → chunk-RNTDBX6S.js} +4 -4
  24. package/dist/{chunk-ZVANIULZ.js.map → chunk-RNTDBX6S.js.map} +1 -1
  25. package/dist/{chunk-A2UUGASH.js → chunk-U736PVHY.js} +2 -2
  26. package/dist/chunk-U736PVHY.js.map +1 -0
  27. package/dist/chunk-UNCSBSO4.js +7866 -0
  28. package/dist/chunk-UNCSBSO4.js.map +1 -0
  29. package/dist/{chunk-PVTHHV7X.js → chunk-V3LF7BE7.js} +27 -5
  30. package/dist/chunk-V3LF7BE7.js.map +1 -0
  31. package/dist/{chunk-EP6JHXSR.js → chunk-WAMZWZJB.js} +54 -9
  32. package/dist/chunk-WAMZWZJB.js.map +1 -0
  33. package/dist/{chunk-RPZAALCX.js → chunk-XPQSTZUU.js} +254 -164
  34. package/dist/chunk-XPQSTZUU.js.map +1 -0
  35. package/dist/{chunk-DTDVSFRY.js → chunk-XQUSGIDG.js} +17 -3
  36. package/dist/chunk-XQUSGIDG.js.map +1 -0
  37. package/dist/cli.js +12 -11
  38. package/dist/cli.js.map +1 -1
  39. package/dist/client/index.d.ts +32 -3
  40. package/dist/client/index.js +205 -12
  41. package/dist/client/index.js.map +1 -1
  42. package/dist/components/index.d.ts +1975 -28
  43. package/dist/components/index.js +4 -4
  44. package/dist/{dev-FCEC3UKQ.js → dev-4XEDTELV.js} +10 -10
  45. package/dist/dev-4XEDTELV.js.map +1 -0
  46. package/dist/doc/index.js +2 -2
  47. package/dist/doc/index.js.map +1 -1
  48. package/dist/{docs-EJJ3BECT.js → docs-JVP4RPKT.js} +3 -3
  49. package/dist/{docs-EJJ3BECT.js.map → docs-JVP4RPKT.js.map} +1 -1
  50. package/dist/{doctor-WHZXPERA.js → doctor-5E2VEZPK.js} +7 -7
  51. package/dist/{doctor-WHZXPERA.js.map → doctor-5E2VEZPK.js.map} +1 -1
  52. package/dist/markdown/index.js +1 -1
  53. package/dist/markdown/index.js.map +1 -1
  54. package/dist/{preview-OGMCNQUO.js → preview-T6CLSQVX.js} +3 -3
  55. package/dist/{preview-OGMCNQUO.js.map → preview-T6CLSQVX.js.map} +1 -1
  56. package/dist/query/index.d.ts +0 -11
  57. package/dist/query/index.js +2 -2
  58. package/dist/{routes-GTFO5PUF.js → routes-3SGAFDMC.js} +6 -6
  59. package/dist/{routes-GTFO5PUF.js.map → routes-3SGAFDMC.js.map} +1 -1
  60. package/dist/{search-6Y422SV6.js → search-5LC4XPB5.js} +3 -3
  61. package/dist/{search-6Y422SV6.js.map → search-5LC4XPB5.js.map} +1 -1
  62. package/dist/slide/index.js +49 -12
  63. package/dist/slide/index.js.map +1 -1
  64. package/dist/table/index.js +11 -10
  65. package/dist/table/index.js.map +1 -1
  66. package/dist/ui/index.d.ts +144 -11
  67. package/dist/ui/index.js +1339 -87
  68. package/dist/ui/index.js.map +1 -1
  69. package/dist/{upgrade-AL4KZZR4.js → upgrade-JHXZBGQS.js} +7 -7
  70. package/dist/{upgrade-AL4KZZR4.js.map → upgrade-JHXZBGQS.js.map} +1 -1
  71. package/dist/vite/index.d.ts +10 -0
  72. package/dist/vite/index.js +4 -4
  73. package/docs/en/components.md +29 -15
  74. package/docs/en/parts/data-table.md +22 -0
  75. package/docs/en/parts/delta.md +50 -0
  76. package/docs/en/parts/format.md +43 -0
  77. package/docs/en/parts/kpi-card.md +57 -0
  78. package/docs/en/parts/metric-value.md +3 -2
  79. package/docs/en/parts/sparkline.md +1 -1
  80. package/docs/en/parts/trend-indicator.md +17 -1
  81. package/docs/en/ui-and-theming.md +1 -1
  82. package/docs/index.json +366 -76
  83. package/docs/ja/changelog.md +31 -0
  84. package/docs/ja/components.md +57 -101
  85. package/docs/ja/page-types/csv.md +83 -0
  86. package/docs/ja/page-types/doc.md +83 -0
  87. package/docs/ja/page-types/excel.md +82 -0
  88. package/docs/ja/page-types/slide.md +132 -0
  89. package/docs/ja/page-types.md +47 -0
  90. package/docs/ja/parts/area-chart.md +61 -0
  91. package/docs/ja/parts/bar-chart.md +69 -0
  92. package/docs/ja/parts/bar-list.md +35 -0
  93. package/docs/ja/parts/category-bar.md +36 -0
  94. package/docs/ja/parts/data-table.md +22 -0
  95. package/docs/ja/parts/delta.md +50 -0
  96. package/docs/ja/parts/donut-chart.md +47 -0
  97. package/docs/ja/parts/echart.md +3 -0
  98. package/docs/ja/parts/format.md +44 -0
  99. package/docs/ja/parts/kpi-card.md +55 -0
  100. package/docs/ja/parts/line-chart.md +58 -0
  101. package/docs/ja/parts/metric-value.md +3 -2
  102. package/docs/ja/parts/progress-circle.md +34 -0
  103. package/docs/ja/parts/sparkline.md +2 -2
  104. package/docs/ja/parts/tracker.md +32 -0
  105. package/docs/ja/parts/trend-indicator.md +17 -1
  106. package/docs/ja/routing.md +8 -86
  107. package/docs/ja/ui/alert-dialog.md +41 -0
  108. package/docs/ja/ui/avatar.md +31 -0
  109. package/docs/ja/ui/combobox.md +74 -0
  110. package/docs/ja/ui/drawer.md +41 -0
  111. package/docs/ja/ui/field.md +42 -0
  112. package/docs/ja/ui/hover-card.md +21 -0
  113. package/docs/ja/ui/kbd.md +16 -0
  114. package/docs/ja/ui/pagination.md +36 -0
  115. package/docs/ja/ui/radio-group.md +21 -0
  116. package/docs/ja/ui/toast.md +46 -0
  117. package/docs/ja/ui-and-theming.md +14 -7
  118. package/package.json +43 -29
  119. package/registry/ui/accordion.tsx +76 -0
  120. package/registry/ui/alert-dialog.tsx +189 -0
  121. package/registry/ui/alert.tsx +80 -0
  122. package/registry/ui/app-shell.tsx +287 -0
  123. package/registry/ui/area-chart.tsx +3639 -0
  124. package/registry/ui/avatar.tsx +110 -0
  125. package/registry/ui/badge.tsx +56 -0
  126. package/registry/ui/bar-chart.tsx +3636 -0
  127. package/registry/ui/bar-list.tsx +3680 -0
  128. package/registry/ui/breadcrumb.tsx +128 -0
  129. package/registry/ui/button.tsx +62 -0
  130. package/registry/ui/calendar.tsx +223 -0
  131. package/registry/ui/card.tsx +107 -0
  132. package/registry/ui/category-bar.tsx +1255 -0
  133. package/registry/ui/chart-frame.tsx +1358 -0
  134. package/registry/ui/checkbox.tsx +30 -0
  135. package/registry/ui/collapsible.tsx +23 -0
  136. package/registry/ui/combobox.tsx +310 -0
  137. package/registry/ui/command.tsx +198 -0
  138. package/registry/ui/dashboard-card.tsx +217 -0
  139. package/registry/ui/data-table.tsx +693 -146
  140. package/registry/ui/date-range-picker.tsx +390 -0
  141. package/registry/ui/delta.tsx +188 -0
  142. package/registry/ui/dialog.tsx +161 -0
  143. package/registry/ui/donut-chart.tsx +3688 -0
  144. package/registry/ui/drawer.tsx +229 -0
  145. package/registry/ui/dropdown-menu.tsx +274 -0
  146. package/registry/ui/echart.tsx +890 -0
  147. package/registry/ui/field.tsx +240 -0
  148. package/registry/ui/filter-bar.tsx +392 -0
  149. package/registry/ui/funnel-steps.tsx +3541 -0
  150. package/registry/ui/heatmap.tsx +1752 -0
  151. package/registry/ui/hover-card.tsx +52 -0
  152. package/registry/ui/input-group.tsx +160 -0
  153. package/registry/ui/input.tsx +24 -0
  154. package/registry/ui/kbd.tsx +30 -0
  155. package/registry/ui/kpi-card.tsx +677 -0
  156. package/registry/ui/label.tsx +22 -0
  157. package/registry/ui/legend.tsx +3500 -0
  158. package/registry/ui/line-chart.tsx +3637 -0
  159. package/registry/ui/metric-value.tsx +62 -0
  160. package/registry/ui/multi-select.tsx +232 -0
  161. package/registry/ui/page-shell.tsx +282 -0
  162. package/registry/ui/pagination.tsx +140 -0
  163. package/registry/ui/placeholder.tsx +36 -0
  164. package/registry/ui/popover.tsx +92 -0
  165. package/registry/ui/progress-circle.tsx +867 -0
  166. package/registry/ui/progress.tsx +85 -0
  167. package/registry/ui/radio-group.tsx +39 -0
  168. package/registry/ui/sample-data.tsx +86 -0
  169. package/registry/ui/scatter-chart.tsx +4150 -0
  170. package/registry/ui/scroll-area.tsx +56 -0
  171. package/registry/ui/searchable-select.tsx +214 -0
  172. package/registry/ui/section-header.tsx +43 -0
  173. package/registry/ui/segmented-control.tsx +76 -0
  174. package/registry/ui/select.tsx +255 -0
  175. package/registry/ui/separator.tsx +27 -0
  176. package/registry/ui/sheet.tsx +139 -0
  177. package/registry/ui/sidebar.tsx +725 -0
  178. package/registry/ui/skeleton.tsx +17 -0
  179. package/registry/ui/slider.tsx +56 -0
  180. package/registry/ui/sparkline.tsx +230 -0
  181. package/registry/ui/spinner.tsx +14 -0
  182. package/registry/ui/states.tsx +90 -0
  183. package/registry/ui/status-badge.tsx +121 -0
  184. package/registry/ui/switch.tsx +34 -0
  185. package/registry/ui/table.tsx +118 -0
  186. package/registry/ui/tabs.tsx +84 -0
  187. package/registry/ui/textarea.tsx +22 -0
  188. package/registry/ui/toast.tsx +250 -0
  189. package/registry/ui/toggle-group.tsx +91 -0
  190. package/registry/ui/toggle.tsx +47 -0
  191. package/registry/ui/tooltip.tsx +68 -0
  192. package/registry/ui/tracker.tsx +843 -0
  193. package/registry/ui/trend-indicator.tsx +74 -0
  194. package/registry/ui/updated-at.tsx +122 -0
  195. package/registry/ui/waterfall-chart.tsx +4186 -0
  196. package/skills/vantage-add-feature/SKILL.md +9 -7
  197. package/skills/vantage-design/SKILL.md +12 -2
  198. package/skills/vantage-design/references/format.md +1 -1
  199. package/skills/vantage-pitfalls/SKILL.md +5 -1
  200. package/skills/vantage-slide/SKILL.md +17 -0
  201. package/templates/AGENTS.md +22 -1
  202. package/templates/agents/api.md +29 -0
  203. package/templates/agents/csv.md +2 -1
  204. package/templates/agents/doc.md +4 -3
  205. package/templates/agents/page.md +32 -8
  206. package/templates/agents/slide.md +13 -1
  207. package/templates/agents/xlsx.md +2 -1
  208. package/theme.css +241 -130
  209. package/dist/add-DY4AXANK.js +0 -6
  210. package/dist/add-DY4AXANK.js.map +0 -1
  211. package/dist/chunk-5ZOP4SQR.js.map +0 -1
  212. package/dist/chunk-A2UUGASH.js.map +0 -1
  213. package/dist/chunk-BCE22JSM.js.map +0 -1
  214. package/dist/chunk-DTDVSFRY.js.map +0 -1
  215. package/dist/chunk-EP6JHXSR.js.map +0 -1
  216. package/dist/chunk-KLEIVDUV.js.map +0 -1
  217. package/dist/chunk-MP3QSOXL.js +0 -2232
  218. package/dist/chunk-MP3QSOXL.js.map +0 -1
  219. package/dist/chunk-PVTHHV7X.js.map +0 -1
  220. package/dist/chunk-PXRX5PEC.js.map +0 -1
  221. package/dist/chunk-QI3XQKHS.js.map +0 -1
  222. package/dist/chunk-RPZAALCX.js.map +0 -1
  223. package/dist/chunk-T3FLAGI6.js +0 -316
  224. package/dist/chunk-T3FLAGI6.js.map +0 -1
  225. package/dist/dev-FCEC3UKQ.js.map +0 -1
@@ -1,2232 +0,0 @@
1
- import { SidebarProvider, Sidebar, SidebarContent, SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarFooter, SidebarRail, SidebarInset, SidebarTrigger, Separator, Input, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuCheckboxItem, useIsMobile, Popover, PopoverTrigger, PopoverContent, Calendar, ToggleGroup, ToggleGroupItem, Badge, SelectGroup, SelectLabel, Collapsible, CollapsibleTrigger, SidebarMenuButton, SidebarMenuBadge, CollapsibleContent, SidebarMenuSub, SidebarMenuSubItem, SidebarMenuSubButton, SidebarMenuItem, Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, Skeleton, Checkbox } from './chunk-RPZAALCX.js';
2
- import { Button } from './chunk-PXRX5PEC.js';
3
- import { cn } from './chunk-A2UUGASH.js';
4
- import { forwardRef, useRef, useState, useEffect, useMemo, useCallback, Fragment, createContext, useId, useContext } from 'react';
5
- import { cva } from 'class-variance-authority';
6
- import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
7
- import { Check, Copy, Download, Search, ArrowUp, ArrowDown, ArrowUpDown, Columns3, CalendarIcon, ChevronDownIcon, Minus, ChevronRight, XIcon, LoaderIcon, CheckIcon, ChevronDown, X } from 'lucide-react';
8
- import * as echarts from 'echarts';
9
- import { flexRender, useReactTable, getPaginationRowModel, getFilteredRowModel, getSortedRowModel, getCoreRowModel } from '@tanstack/react-table';
10
- import { format, endOfDay, startOfDay, subDays, startOfMonth, subMonths, endOfMonth } from 'date-fns';
11
- import { ja } from 'date-fns/locale';
12
-
13
- // @squadbase/vantage — generated build. Do not edit.
14
- var PageShell = forwardRef(
15
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, "data-slot": "page-shell", className: cn("flex flex-col", className), ...props })
16
- );
17
- PageShell.displayName = "PageShell";
18
- var PageShellHeader = forwardRef(
19
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
20
- "div",
21
- {
22
- ref,
23
- "data-slot": "page-shell-header",
24
- className: cn("flex flex-wrap items-start gap-x-4 gap-y-6 border-b px-6 py-12", className),
25
- ...props
26
- }
27
- )
28
- );
29
- PageShellHeader.displayName = "PageShellHeader";
30
- var PageShellHeading = forwardRef(
31
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
32
- "div",
33
- {
34
- ref,
35
- "data-slot": "page-shell-heading",
36
- className: cn("min-w-0 grow basis-80", className),
37
- ...props
38
- }
39
- )
40
- );
41
- PageShellHeading.displayName = "PageShellHeading";
42
- var PageShellTitle = forwardRef(
43
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
44
- "h1",
45
- {
46
- ref,
47
- "data-slot": "page-shell-title",
48
- className: cn("text-2xl font-bold tracking-tight text-foreground", className),
49
- ...props
50
- }
51
- )
52
- );
53
- PageShellTitle.displayName = "PageShellTitle";
54
- var PageShellDescription = forwardRef(
55
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
56
- "p",
57
- {
58
- ref,
59
- "data-slot": "page-shell-description",
60
- className: cn("mt-1 text-sm text-muted-foreground", className),
61
- ...props
62
- }
63
- )
64
- );
65
- PageShellDescription.displayName = "PageShellDescription";
66
- var PageShellHeaderEnd = forwardRef(
67
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
68
- "div",
69
- {
70
- ref,
71
- "data-slot": "page-shell-header-end",
72
- className: cn("flex max-w-full shrink-0 flex-col flex-wrap items-end gap-2", className),
73
- ...props
74
- }
75
- )
76
- );
77
- PageShellHeaderEnd.displayName = "PageShellHeaderEnd";
78
- var PageShellMeta = forwardRef(
79
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
80
- "div",
81
- {
82
- ref,
83
- "data-slot": "page-shell-meta",
84
- className: cn("text-sm text-muted-foreground", className),
85
- ...props
86
- }
87
- )
88
- );
89
- PageShellMeta.displayName = "PageShellMeta";
90
- var PageShellActions = forwardRef(
91
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
92
- "div",
93
- {
94
- ref,
95
- "data-slot": "page-shell-actions",
96
- className: cn("flex items-center gap-2", className),
97
- ...props
98
- }
99
- )
100
- );
101
- PageShellActions.displayName = "PageShellActions";
102
- var PageShellSummary = forwardRef(
103
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
104
- "div",
105
- {
106
- ref,
107
- "data-slot": "page-shell-summary",
108
- className: cn(
109
- "grid basis-full grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4",
110
- className
111
- ),
112
- ...props
113
- }
114
- )
115
- );
116
- PageShellSummary.displayName = "PageShellSummary";
117
- var pageShellSummaryCardVariants = cva(
118
- "relative flex items-start gap-3 rounded-lg border bg-background px-4 py-3 text-sm [&>svg]:mt-0.5 [&>svg]:size-4 [&>svg]:shrink-0",
119
- {
120
- variants: {
121
- accent: {
122
- default: "text-card-foreground",
123
- accent: "border-[var(--chart-1)]/30 bg-linear-to-r from-[var(--chart-1)]/5 to-[var(--chart-1)]/5 [&>svg]:text-[var(--chart-1)]",
124
- amber: "border-amber-300 bg-amber-50 [&>svg]:text-amber-600 dark:border-amber-800 dark:bg-amber-950/50 dark:[&>svg]:text-amber-400",
125
- blue: "border-blue-300 bg-blue-50 [&>svg]:text-blue-600 dark:border-blue-800 dark:bg-blue-950/50 dark:[&>svg]:text-blue-400",
126
- emerald: "border-emerald-300 bg-emerald-50 [&>svg]:text-emerald-600 dark:border-emerald-800 dark:bg-emerald-950/50 dark:[&>svg]:text-emerald-400",
127
- red: "border-red-300 bg-red-50 [&>svg]:text-red-600 dark:border-red-800 dark:bg-red-950/50 dark:[&>svg]:text-red-400",
128
- violet: "border-violet-300 bg-violet-50 [&>svg]:text-violet-600 dark:border-violet-800 dark:bg-violet-950/50 dark:[&>svg]:text-violet-400",
129
- orange: "border-orange-300 bg-orange-50 [&>svg]:text-orange-600 dark:border-orange-800 dark:bg-orange-950/50 dark:[&>svg]:text-orange-400",
130
- cyan: "border-cyan-300 bg-cyan-50 [&>svg]:text-cyan-600 dark:border-cyan-800 dark:bg-cyan-950/50 dark:[&>svg]:text-cyan-400",
131
- slate: "border-slate-300 bg-slate-50 [&>svg]:text-slate-600 dark:border-slate-800 dark:bg-slate-950/50 dark:[&>svg]:text-slate-400",
132
- green: "border-green-300 bg-green-50 [&>svg]:text-green-600 dark:border-green-800 dark:bg-green-950/50 dark:[&>svg]:text-green-400",
133
- teal: "border-teal-300 bg-teal-50 [&>svg]:text-teal-600 dark:border-teal-800 dark:bg-teal-950/50 dark:[&>svg]:text-teal-400",
134
- sky: "border-sky-300 bg-sky-50 [&>svg]:text-sky-600 dark:border-sky-800 dark:bg-sky-950/50 dark:[&>svg]:text-sky-400",
135
- indigo: "border-indigo-300 bg-indigo-50 [&>svg]:text-indigo-600 dark:border-indigo-800 dark:bg-indigo-950/50 dark:[&>svg]:text-indigo-400",
136
- purple: "border-purple-300 bg-purple-50 [&>svg]:text-purple-600 dark:border-purple-800 dark:bg-purple-950/50 dark:[&>svg]:text-purple-400",
137
- pink: "border-pink-300 bg-pink-50 [&>svg]:text-pink-600 dark:border-pink-800 dark:bg-pink-950/50 dark:[&>svg]:text-pink-400",
138
- rose: "border-rose-300 bg-rose-50 [&>svg]:text-rose-600 dark:border-rose-800 dark:bg-rose-950/50 dark:[&>svg]:text-rose-400",
139
- yellow: "border-yellow-300 bg-yellow-50 [&>svg]:text-yellow-600 dark:border-yellow-800 dark:bg-yellow-950/50 dark:[&>svg]:text-yellow-400",
140
- lime: "border-lime-300 bg-lime-50 [&>svg]:text-lime-600 dark:border-lime-800 dark:bg-lime-950/50 dark:[&>svg]:text-lime-400",
141
- gray: "border-gray-300 bg-gray-50 [&>svg]:text-gray-600 dark:border-gray-800 dark:bg-gray-950/50 dark:[&>svg]:text-gray-400",
142
- zinc: "border-zinc-300 bg-zinc-50 [&>svg]:text-zinc-600 dark:border-zinc-800 dark:bg-zinc-950/50 dark:[&>svg]:text-zinc-400",
143
- neutral: "border-neutral-300 bg-neutral-50 [&>svg]:text-neutral-600 dark:border-neutral-800 dark:bg-neutral-950/50 dark:[&>svg]:text-neutral-400",
144
- stone: "border-stone-300 bg-stone-50 [&>svg]:text-stone-600 dark:border-stone-800 dark:bg-stone-950/50 dark:[&>svg]:text-stone-400",
145
- fuchsia: "border-fuchsia-300 bg-fuchsia-50 [&>svg]:text-fuchsia-600 dark:border-fuchsia-800 dark:bg-fuchsia-950/50 dark:[&>svg]:text-fuchsia-400"
146
- }
147
- },
148
- defaultVariants: {
149
- accent: "default"
150
- }
151
- }
152
- );
153
- var PageShellSummaryCard = forwardRef(
154
- ({ className, accent, ...props }, ref) => /* @__PURE__ */ jsx(
155
- "div",
156
- {
157
- ref,
158
- "data-slot": "page-shell-summary-card",
159
- className: cn(pageShellSummaryCardVariants({ accent }), className),
160
- ...props
161
- }
162
- )
163
- );
164
- PageShellSummaryCard.displayName = "PageShellSummaryCard";
165
- var PageShellContent = forwardRef(
166
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
167
- "div",
168
- {
169
- ref,
170
- "data-slot": "page-shell-content",
171
- className: cn("flex-1 p-6", className),
172
- ...props
173
- }
174
- )
175
- );
176
- PageShellContent.displayName = "PageShellContent";
177
- function flattenItems(item) {
178
- if (item.children && item.children.length > 0) {
179
- return item.children.flatMap(flattenItems);
180
- }
181
- return [item];
182
- }
183
- function NavSelect({
184
- groups,
185
- onNavigate
186
- }) {
187
- const allItems = groups.flatMap((g) => g.items.flatMap(flattenItems));
188
- const currentValue = allItems.find((item) => item.isActive)?.href ?? "";
189
- return /* @__PURE__ */ jsxs(
190
- Select,
191
- {
192
- value: currentValue,
193
- onValueChange: (href) => {
194
- if (href !== null) onNavigate(href);
195
- },
196
- children: [
197
- /* @__PURE__ */ jsx(SelectTrigger, { size: "sm", className: "w-48", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "\u30DA\u30FC\u30B8\u3092\u9078\u629E" }) }),
198
- /* @__PURE__ */ jsx(
199
- SelectContent,
200
- {
201
- align: "start",
202
- className: "w-auto min-w-(--anchor-width) max-w-[min(24rem,var(--available-width))]",
203
- children: groups.map((group, index) => /* @__PURE__ */ jsxs(SelectGroup, { children: [
204
- group.label && /* @__PURE__ */ jsx(SelectLabel, { children: group.label }),
205
- group.items.flatMap(flattenItems).map((item) => /* @__PURE__ */ jsx(SelectItem, { value: item.href, disabled: item.disabled, children: item.label }, item.href))
206
- ] }, group.label ?? index))
207
- }
208
- )
209
- ]
210
- }
211
- );
212
- }
213
- function NavItemWithChildren({
214
- item,
215
- linkComponent: LinkComponent = "a"
216
- }) {
217
- return /* @__PURE__ */ jsxs(
218
- Collapsible,
219
- {
220
- defaultOpen: item.isActive,
221
- className: "group/collapsible",
222
- render: /* @__PURE__ */ jsx(SidebarMenuItem, {}),
223
- children: [
224
- /* @__PURE__ */ jsxs(
225
- CollapsibleTrigger,
226
- {
227
- render: /* @__PURE__ */ jsx(
228
- SidebarMenuButton,
229
- {
230
- tooltip: item.label,
231
- "aria-disabled": item.disabled,
232
- className: cn(item.disabled && "pointer-events-none")
233
- }
234
- ),
235
- children: [
236
- item.icon && /* @__PURE__ */ jsx(item.icon, {}),
237
- /* @__PURE__ */ jsx("span", { children: item.label }),
238
- /* @__PURE__ */ jsx(ChevronRight, { className: "ml-auto transition-transform duration-200 group-data-open/collapsible:rotate-90" })
239
- ]
240
- }
241
- ),
242
- item.badge && /* @__PURE__ */ jsx(SidebarMenuBadge, { children: item.badge }),
243
- /* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx(SidebarMenuSub, { children: item.children.map((child) => /* @__PURE__ */ jsx(SidebarMenuSubItem, { children: /* @__PURE__ */ jsxs(
244
- SidebarMenuSubButton,
245
- {
246
- isActive: child.isActive,
247
- render: /* @__PURE__ */ jsx(
248
- LinkComponent,
249
- {
250
- href: child.href,
251
- "aria-disabled": child.disabled,
252
- tabIndex: child.disabled ? -1 : void 0,
253
- className: cn(child.disabled && "pointer-events-none opacity-50")
254
- }
255
- ),
256
- children: [
257
- child.icon && /* @__PURE__ */ jsx(child.icon, {}),
258
- /* @__PURE__ */ jsx("span", { children: child.label })
259
- ]
260
- }
261
- ) }, child.href)) }) })
262
- ]
263
- }
264
- );
265
- }
266
- function NavItemLink({
267
- item,
268
- linkComponent: LinkComponent = "a"
269
- }) {
270
- return /* @__PURE__ */ jsxs(SidebarMenuItem, { children: [
271
- /* @__PURE__ */ jsxs(
272
- SidebarMenuButton,
273
- {
274
- tooltip: item.label,
275
- isActive: item.isActive,
276
- render: /* @__PURE__ */ jsx(
277
- LinkComponent,
278
- {
279
- href: item.href,
280
- "aria-disabled": item.disabled,
281
- tabIndex: item.disabled ? -1 : void 0,
282
- className: cn(item.disabled && "pointer-events-none")
283
- }
284
- ),
285
- children: [
286
- item.icon && /* @__PURE__ */ jsx(item.icon, {}),
287
- /* @__PURE__ */ jsx("span", { children: item.label })
288
- ]
289
- }
290
- ),
291
- item.badge && /* @__PURE__ */ jsx(SidebarMenuBadge, { children: item.badge })
292
- ] });
293
- }
294
- var defaultNavigate = (href) => {
295
- window.location.assign(href);
296
- };
297
- var AppShell = forwardRef((props, ref) => {
298
- const {
299
- variant = "sidebar",
300
- groups,
301
- actions,
302
- header,
303
- children,
304
- className,
305
- linkComponent,
306
- onNavigate = defaultNavigate
307
- } = props;
308
- if (variant === "header") {
309
- return /* @__PURE__ */ jsxs("div", { ref, "data-slot": "app-shell", className: cn("flex h-full flex-col", className), children: [
310
- header !== void 0 ? header : /* @__PURE__ */ jsxs("header", { className: "flex h-14 shrink-0 items-center gap-3 border-b px-4", children: [
311
- groups.length > 0 && /* @__PURE__ */ jsx(NavSelect, { groups, onNavigate }),
312
- actions && /* @__PURE__ */ jsx("div", { className: "ml-auto flex items-center gap-2", children: actions })
313
- ] }),
314
- /* @__PURE__ */ jsx("main", { className: "flex-1 overflow-auto", children })
315
- ] });
316
- }
317
- const { defaultOpen = true } = props;
318
- return /* @__PURE__ */ jsxs(SidebarProvider, { defaultOpen, children: [
319
- /* @__PURE__ */ jsxs(Sidebar, { "data-slot": "app-sidebar", collapsible: "offcanvas", children: [
320
- /* @__PURE__ */ jsx(SidebarContent, { children: groups.map((group, index) => /* @__PURE__ */ jsxs(SidebarGroup, { children: [
321
- group.label && /* @__PURE__ */ jsx(SidebarGroupLabel, { children: group.label }),
322
- /* @__PURE__ */ jsx(SidebarMenu, { children: group.items.map(
323
- (item) => item.children && item.children.length > 0 ? /* @__PURE__ */ jsx(
324
- NavItemWithChildren,
325
- {
326
- item,
327
- linkComponent
328
- },
329
- item.href
330
- ) : /* @__PURE__ */ jsx(NavItemLink, { item, linkComponent }, item.href)
331
- ) })
332
- ] }, group.label ?? index)) }),
333
- actions && /* @__PURE__ */ jsx(SidebarFooter, { children: actions }),
334
- /* @__PURE__ */ jsx(SidebarRail, {})
335
- ] }),
336
- /* @__PURE__ */ jsxs(SidebarInset, { ref, "data-slot": "app-shell", className, children: [
337
- header !== void 0 ? header : /* @__PURE__ */ jsxs("header", { className: "flex h-14 shrink-0 items-center gap-2 border-b px-4", children: [
338
- /* @__PURE__ */ jsx(SidebarTrigger, {}),
339
- /* @__PURE__ */ jsx(Separator, { orientation: "vertical", className: "h-4" })
340
- ] }),
341
- /* @__PURE__ */ jsx("main", { className: "flex-1 overflow-auto", children })
342
- ] })
343
- ] });
344
- });
345
- AppShell.displayName = "AppShell";
346
- var headingStyles = {
347
- h1: "text-3xl font-bold tracking-tight",
348
- h2: "text-2xl font-semibold tracking-tight",
349
- h3: "text-xl font-semibold",
350
- h4: "text-lg font-semibold"
351
- };
352
- var SectionHeader = forwardRef(
353
- ({ title, description, actions, className, as: Comp = "h2" }, ref) => /* @__PURE__ */ jsxs(
354
- "div",
355
- {
356
- ref,
357
- "data-slot": "section-header",
358
- className: cn("flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between", className),
359
- children: [
360
- /* @__PURE__ */ jsxs("div", { children: [
361
- /* @__PURE__ */ jsx(Comp, { className: headingStyles[Comp], children: title }),
362
- description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: description })
363
- ] }),
364
- actions && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: actions })
365
- ]
366
- }
367
- )
368
- );
369
- SectionHeader.displayName = "SectionHeader";
370
- var DashboardCard = forwardRef(
371
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
372
- "div",
373
- {
374
- ref,
375
- "data-slot": "dashboard-card",
376
- className: cn(
377
- "group rounded-lg border bg-card px-1 py-1 text-card-foreground",
378
- className
379
- ),
380
- ...props
381
- }
382
- )
383
- );
384
- DashboardCard.displayName = "DashboardCard";
385
- var DashboardCardHeader = forwardRef(
386
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
387
- "div",
388
- {
389
- ref,
390
- "data-slot": "dashboard-card-header",
391
- className: cn("flex flex-row items-start justify-between gap-4 px-3 py-3", className),
392
- ...props
393
- }
394
- )
395
- );
396
- DashboardCardHeader.displayName = "DashboardCardHeader";
397
- var DashboardCardTitle = forwardRef(
398
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
399
- "h3",
400
- {
401
- ref,
402
- "data-slot": "dashboard-card-title",
403
- className: cn("text-sm leading-none font-semibold tracking-tight", className),
404
- ...props
405
- }
406
- )
407
- );
408
- DashboardCardTitle.displayName = "DashboardCardTitle";
409
- var DashboardCardDescription = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
410
- "p",
411
- {
412
- ref,
413
- "data-slot": "dashboard-card-description",
414
- className: cn("text-xs text-muted-foreground", className),
415
- ...props
416
- }
417
- ));
418
- DashboardCardDescription.displayName = "DashboardCardDescription";
419
- var DashboardCardAction = forwardRef(
420
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
421
- "div",
422
- {
423
- ref,
424
- "data-slot": "dashboard-card-action",
425
- className: cn("ml-auto shrink-0", className),
426
- ...props
427
- }
428
- )
429
- );
430
- DashboardCardAction.displayName = "DashboardCardAction";
431
- var DashboardCardContent = forwardRef(
432
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, "data-slot": "dashboard-card-content", className: cn("p-3", className), ...props })
433
- );
434
- DashboardCardContent.displayName = "DashboardCardContent";
435
- var DashboardCardFooter = forwardRef(
436
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
437
- "div",
438
- {
439
- ref,
440
- "data-slot": "dashboard-card-footer",
441
- className: cn("flex items-center px-3 py-1.5", className),
442
- ...props
443
- }
444
- )
445
- );
446
- DashboardCardFooter.displayName = "DashboardCardFooter";
447
- function DashboardCardSkeleton({ className }) {
448
- return /* @__PURE__ */ jsxs(
449
- "div",
450
- {
451
- "data-slot": "dashboard-card-skeleton",
452
- className: cn("rounded-lg border bg-card p-6 shadow-sm", className),
453
- children: [
454
- /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4 pb-4", children: [
455
- /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-32" }),
456
- /* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-8 rounded-md" })
457
- ] }),
458
- /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full" }),
459
- /* @__PURE__ */ jsx(Skeleton, { className: "mt-2 h-4 w-3/4" })
460
- ]
461
- }
462
- );
463
- }
464
- function DashboardCardPreset({
465
- title,
466
- description,
467
- actions,
468
- footer,
469
- children,
470
- headerClassName,
471
- contentClassName,
472
- footerClassName,
473
- className,
474
- ...props
475
- }) {
476
- const hasHeader = title || description || actions;
477
- return /* @__PURE__ */ jsxs(DashboardCard, { className, ...props, children: [
478
- hasHeader && /* @__PURE__ */ jsxs(DashboardCardHeader, { className: headerClassName, children: [
479
- (title || description) && /* @__PURE__ */ jsxs("div", { children: [
480
- title && /* @__PURE__ */ jsx(DashboardCardTitle, { children: title }),
481
- description && /* @__PURE__ */ jsx(DashboardCardDescription, { children: description })
482
- ] }),
483
- actions && /* @__PURE__ */ jsx(DashboardCardAction, { children: actions })
484
- ] }),
485
- children && /* @__PURE__ */ jsx(DashboardCardContent, { className: contentClassName, children }),
486
- footer && /* @__PURE__ */ jsx(DashboardCardFooter, { className: footerClassName, children: footer })
487
- ] });
488
- }
489
-
490
- // src/components/chart-theme.ts
491
- var SERIES_TOKENS = ["--chart-1", "--chart-2", "--chart-3", "--chart-4", "--chart-5"];
492
- var normalizeContext;
493
- function toCanvasColor(value) {
494
- const raw = value.trim();
495
- if (!raw) return null;
496
- if (normalizeContext === void 0) {
497
- normalizeContext = document.createElement("canvas").getContext("2d");
498
- }
499
- const ctx = normalizeContext;
500
- if (!ctx) return raw;
501
- ctx.fillStyle = "#000000";
502
- ctx.fillStyle = raw;
503
- const onBlack = ctx.fillStyle;
504
- ctx.fillStyle = "#ffffff";
505
- ctx.fillStyle = raw;
506
- return onBlack === ctx.fillStyle ? onBlack : null;
507
- }
508
- function readChartTokens(el) {
509
- if (typeof document === "undefined") return null;
510
- const target = document.documentElement;
511
- if (!target) return null;
512
- const styles = getComputedStyle(target);
513
- const read = (name) => toCanvasColor(styles.getPropertyValue(name));
514
- const series = [];
515
- for (const token of SERIES_TOKENS) {
516
- const color = read(token);
517
- if (color) series.push(color);
518
- }
519
- return {
520
- series,
521
- foreground: read("--foreground"),
522
- mutedForeground: read("--muted-foreground"),
523
- border: read("--border"),
524
- popover: read("--popover"),
525
- popoverForeground: read("--popover-foreground")
526
- };
527
- }
528
- function sameChartTokens(a, b) {
529
- if (a === b) return true;
530
- if (!a || !b) return false;
531
- return a.series.length === b.series.length && a.series.every((color, i) => color === b.series[i]) && a.foreground === b.foreground && a.mutedForeground === b.mutedForeground && a.border === b.border && a.popover === b.popover && a.popoverForeground === b.popoverForeground;
532
- }
533
- function watchChartTokens(onChange) {
534
- if (typeof document === "undefined") return () => {
535
- };
536
- let frame = 0;
537
- const schedule = () => {
538
- if (frame) return;
539
- frame = requestAnimationFrame(() => {
540
- frame = 0;
541
- onChange();
542
- });
543
- };
544
- const themeObserver = new MutationObserver(schedule);
545
- const attributeFilter = ["class", "style", "data-theme"];
546
- themeObserver.observe(document.documentElement, { attributes: true, attributeFilter });
547
- if (document.body) themeObserver.observe(document.body, { attributes: true, attributeFilter });
548
- const styleObserver = new MutationObserver(schedule);
549
- if (document.head) {
550
- styleObserver.observe(document.head, {
551
- childList: true,
552
- subtree: true,
553
- characterData: true,
554
- attributes: true,
555
- attributeFilter: ["href", "media", "disabled"]
556
- });
557
- }
558
- const onLoad = (event) => {
559
- if (event.target instanceof HTMLLinkElement) schedule();
560
- };
561
- document.addEventListener("load", onLoad, true);
562
- const media = window.matchMedia("(prefers-color-scheme: dark)");
563
- media.addEventListener("change", schedule);
564
- return () => {
565
- if (frame) cancelAnimationFrame(frame);
566
- themeObserver.disconnect();
567
- styleObserver.disconnect();
568
- document.removeEventListener("load", onLoad, true);
569
- media.removeEventListener("change", schedule);
570
- };
571
- }
572
- function axisTheme(tokens, splitLine) {
573
- const line = tokens.border ?? void 0;
574
- return {
575
- axisLine: { show: true, lineStyle: { color: line } },
576
- axisTick: { show: true, lineStyle: { color: line } },
577
- axisLabel: { show: true, color: tokens.mutedForeground ?? void 0 },
578
- splitLine: { show: splitLine, lineStyle: { color: line ? [line] : void 0 } },
579
- splitArea: { show: false }
580
- };
581
- }
582
- function buildChartTheme(tokens) {
583
- const text = tokens.foreground ?? void 0;
584
- const muted = tokens.mutedForeground ?? void 0;
585
- const line = tokens.border ?? void 0;
586
- return {
587
- // Let the page background show through: charts sit on cards, not on a canvas.
588
- backgroundColor: "transparent",
589
- ...tokens.series.length > 0 ? { color: tokens.series } : {},
590
- textStyle: { color: text },
591
- title: { textStyle: { color: text }, subtextStyle: { color: muted } },
592
- legend: { textStyle: { color: muted } },
593
- categoryAxis: axisTheme(tokens, false),
594
- valueAxis: axisTheme(tokens, true),
595
- logAxis: axisTheme(tokens, true),
596
- timeAxis: axisTheme(tokens, true),
597
- tooltip: {
598
- backgroundColor: tokens.popover ?? void 0,
599
- borderColor: line,
600
- borderWidth: 1,
601
- textStyle: { color: tokens.popoverForeground ?? void 0 },
602
- axisPointer: { lineStyle: { color: line }, crossStyle: { color: line } }
603
- }
604
- };
605
- }
606
- var EChart = forwardRef(function EChart2({
607
- option,
608
- height,
609
- loading = false,
610
- theme,
611
- onEvents,
612
- ariaLabel,
613
- className,
614
- actions = false,
615
- fileName = "chart.png"
616
- }, ref) {
617
- const containerRef = useRef(null);
618
- const [instance, setInstance] = useState(null);
619
- const [copied, setCopied] = useState(false);
620
- const [tokens, setTokens] = useState(() => readChartTokens());
621
- useEffect(() => {
622
- if (theme !== void 0) return;
623
- const sync = () => {
624
- setTokens((prev) => {
625
- const next = readChartTokens();
626
- return sameChartTokens(prev, next) ? prev : next;
627
- });
628
- };
629
- sync();
630
- return watchChartTokens(sync);
631
- }, [theme]);
632
- const autoTheme = useMemo(() => tokens ? buildChartTheme(tokens) : void 0, [tokens]);
633
- const resolvedTheme = theme ?? autoTheme;
634
- useEffect(() => {
635
- const container = containerRef.current;
636
- if (!container) return;
637
- const inst = echarts.init(container, resolvedTheme, { renderer: "canvas" });
638
- container.dataset.rendering = "";
639
- inst.on("finished", () => {
640
- delete container.dataset.rendering;
641
- });
642
- setInstance(inst);
643
- const observer = new ResizeObserver(() => inst.resize());
644
- observer.observe(container);
645
- return () => {
646
- observer.disconnect();
647
- inst.dispose();
648
- };
649
- }, [resolvedTheme]);
650
- useEffect(() => {
651
- if (!instance) return;
652
- if (containerRef.current) containerRef.current.dataset.rendering = "";
653
- instance.setOption(option, { notMerge: true, lazyUpdate: true });
654
- }, [instance, option]);
655
- useEffect(() => {
656
- if (!instance) return;
657
- if (loading) instance.showLoading();
658
- else instance.hideLoading();
659
- }, [instance, loading]);
660
- useEffect(() => {
661
- if (!instance || !onEvents) return;
662
- const entries = Object.entries(onEvents);
663
- for (const [event, handler] of entries) {
664
- instance.on(event, handler);
665
- }
666
- return () => {
667
- if (instance.isDisposed()) return;
668
- for (const [event, handler] of entries) {
669
- instance.off(event, handler);
670
- }
671
- };
672
- }, [instance, onEvents]);
673
- const getPngDataUrl = useCallback(() => {
674
- if (!instance) return null;
675
- const pageBg = getComputedStyle(document.documentElement).backgroundColor;
676
- return instance.getDataURL({
677
- type: "png",
678
- pixelRatio: 2,
679
- backgroundColor: pageBg && pageBg !== "rgba(0, 0, 0, 0)" ? pageBg : "#ffffff"
680
- });
681
- }, [instance]);
682
- const handleCopy = useCallback(async () => {
683
- const dataUrl = getPngDataUrl();
684
- if (!dataUrl) return;
685
- try {
686
- const blob = await (await fetch(dataUrl)).blob();
687
- await navigator.clipboard.write([new ClipboardItem({ "image/png": blob })]);
688
- setCopied(true);
689
- setTimeout(() => setCopied(false), 2e3);
690
- } catch {
691
- }
692
- }, [getPngDataUrl]);
693
- const handleDownload = useCallback(() => {
694
- const dataUrl = getPngDataUrl();
695
- if (!dataUrl) return;
696
- const link = document.createElement("a");
697
- link.href = dataUrl;
698
- link.download = fileName;
699
- link.click();
700
- }, [getPngDataUrl, fileName]);
701
- const styleHeight = height == null ? void 0 : typeof height === "number" ? `${height}px` : height;
702
- return /* @__PURE__ */ jsxs(
703
- "div",
704
- {
705
- ref,
706
- "data-slot": "echart",
707
- className: cn("group relative w-full", height == null && "h-[400px]", className),
708
- style: styleHeight != null ? { height: styleHeight } : void 0,
709
- role: "img",
710
- "aria-label": ariaLabel ?? "\u30C1\u30E3\u30FC\u30C8",
711
- children: [
712
- /* @__PURE__ */ jsx("div", { ref: containerRef, "data-slot": "echart-canvas", className: "h-full w-full" }),
713
- actions && /* @__PURE__ */ jsxs(
714
- "div",
715
- {
716
- "data-slot": "echart-actions",
717
- className: "absolute top-2 right-2 z-10 flex gap-1 opacity-0 transition-opacity group-hover:opacity-100 focus-within:opacity-100",
718
- children: [
719
- /* @__PURE__ */ jsx(
720
- Button,
721
- {
722
- type: "button",
723
- variant: "ghost",
724
- size: "icon-sm",
725
- onClick: handleCopy,
726
- "aria-label": copied ? "\u30B3\u30D4\u30FC\u3057\u307E\u3057\u305F" : "PNG \u3092\u30AF\u30EA\u30C3\u30D7\u30DC\u30FC\u30C9\u306B\u30B3\u30D4\u30FC",
727
- children: copied ? /* @__PURE__ */ jsx(Check, { className: "size-4" }) : /* @__PURE__ */ jsx(Copy, { className: "size-4" })
728
- }
729
- ),
730
- /* @__PURE__ */ jsx(
731
- Button,
732
- {
733
- type: "button",
734
- variant: "ghost",
735
- size: "icon-sm",
736
- onClick: handleDownload,
737
- "aria-label": "PNG \u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9",
738
- children: /* @__PURE__ */ jsx(Download, { className: "size-4" })
739
- }
740
- )
741
- ]
742
- }
743
- )
744
- ]
745
- }
746
- );
747
- });
748
- EChart.displayName = "EChart";
749
- var DEFAULT_COLORS = [
750
- "bg-chart-1",
751
- "bg-chart-2",
752
- "bg-chart-3",
753
- "bg-chart-4",
754
- "bg-chart-5"
755
- ];
756
- var funnelStepsVariants = cva("flex w-full", {
757
- variants: {
758
- size: {
759
- sm: "",
760
- md: "",
761
- lg: ""
762
- },
763
- direction: {
764
- vertical: "flex-col",
765
- horizontal: "flex-row"
766
- }
767
- },
768
- compoundVariants: [
769
- { direction: "vertical", size: "sm", className: "gap-1" },
770
- { direction: "vertical", size: "md", className: "gap-1.5" },
771
- { direction: "vertical", size: "lg", className: "gap-2" },
772
- { direction: "horizontal", size: "sm", className: "gap-2" },
773
- { direction: "horizontal", size: "md", className: "gap-3" },
774
- { direction: "horizontal", size: "lg", className: "gap-4" }
775
- ],
776
- defaultVariants: {
777
- size: "md",
778
- direction: "vertical"
779
- }
780
- });
781
- var funnelBarVariants = cva("rounded-sm transition-[width] ease-out", {
782
- variants: {
783
- size: {
784
- sm: "h-6",
785
- md: "h-8",
786
- lg: "h-10"
787
- }
788
- },
789
- defaultVariants: {
790
- size: "md"
791
- }
792
- });
793
- var funnelBarContainerHorizontalVariants = cva(
794
- "relative flex w-full items-end overflow-hidden rounded-sm bg-muted",
795
- {
796
- variants: {
797
- size: {
798
- sm: "h-20",
799
- md: "h-28",
800
- lg: "h-36"
801
- }
802
- },
803
- defaultVariants: {
804
- size: "md"
805
- }
806
- }
807
- );
808
- var funnelLabelVariants = cva("flex w-full items-center justify-between text-muted-foreground", {
809
- variants: {
810
- size: {
811
- sm: "text-xs",
812
- md: "text-sm",
813
- lg: "text-sm"
814
- }
815
- },
816
- defaultVariants: {
817
- size: "md"
818
- }
819
- });
820
- var funnelConversionVariants = cva("flex items-center text-muted-foreground", {
821
- variants: {
822
- size: {
823
- sm: "text-[10px]",
824
- md: "text-xs",
825
- lg: "text-xs"
826
- },
827
- direction: {
828
- vertical: "justify-end",
829
- horizontal: "shrink-0 justify-center self-center"
830
- }
831
- },
832
- compoundVariants: [
833
- { direction: "vertical", size: "sm", className: "py-0" },
834
- { direction: "vertical", size: "md", className: "py-0.5" },
835
- { direction: "vertical", size: "lg", className: "py-0.5" }
836
- ],
837
- defaultVariants: {
838
- size: "md",
839
- direction: "vertical"
840
- }
841
- });
842
- function defaultFormatValue(value) {
843
- return value.toLocaleString();
844
- }
845
- function computeConversionRate(current, previous) {
846
- if (previous === 0) return "--";
847
- return `${(current / previous * 100).toFixed(1)}%`;
848
- }
849
- var FunnelSteps = forwardRef(function FunnelSteps2({
850
- data,
851
- showConversion = false,
852
- formatValue = defaultFormatValue,
853
- animate = false,
854
- size = "md",
855
- direction = "vertical",
856
- className,
857
- ...props
858
- }, ref) {
859
- const [mounted, setMounted] = useState(false);
860
- const isHorizontal = direction === "horizontal";
861
- useEffect(() => {
862
- if (animate) setMounted(true);
863
- }, [animate]);
864
- const maxValue = data.length > 0 ? data[0].value : 0;
865
- return /* @__PURE__ */ jsx(
866
- "div",
867
- {
868
- ref,
869
- "data-slot": "funnel-steps",
870
- role: "list",
871
- "aria-label": "\u30D5\u30A1\u30CD\u30EB",
872
- className: cn(funnelStepsVariants({ size, direction }), className),
873
- ...props,
874
- children: data.map((step, index) => {
875
- const percentage = maxValue > 0 ? step.value / maxValue * 100 : 0;
876
- const barSize = step.value > 0 && percentage < 2 ? 2 : percentage;
877
- const color = step.color ?? DEFAULT_COLORS[index % DEFAULT_COLORS.length];
878
- const isClickable = !!step.onClick;
879
- const barInteractionProps = isClickable ? {
880
- role: "button",
881
- tabIndex: 0,
882
- onClick: step.onClick,
883
- onKeyDown: (e) => {
884
- if (e.key === "Enter" || e.key === " ") {
885
- e.preventDefault();
886
- step.onClick?.();
887
- }
888
- }
889
- } : {};
890
- const barInteractionClasses = isClickable ? "cursor-pointer hover:brightness-110 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none" : void 0;
891
- return /* @__PURE__ */ jsxs(Fragment, { children: [
892
- isHorizontal ? /* @__PURE__ */ jsxs(
893
- "div",
894
- {
895
- role: "listitem",
896
- className: "flex min-w-0 flex-1 flex-col items-center gap-1",
897
- "aria-label": `${step.label}: ${formatValue(step.value)}`,
898
- children: [
899
- /* @__PURE__ */ jsx(
900
- "span",
901
- {
902
- "data-slot": "funnel-value",
903
- className: cn(
904
- "text-muted-foreground tabular-nums",
905
- size === "sm" ? "text-xs" : "text-sm"
906
- ),
907
- children: formatValue(step.value)
908
- }
909
- ),
910
- /* @__PURE__ */ jsx("div", { className: funnelBarContainerHorizontalVariants({ size }), children: /* @__PURE__ */ jsx(
911
- "div",
912
- {
913
- ...barInteractionProps,
914
- className: cn(
915
- "w-full rounded-sm transition-[height] ease-out",
916
- color,
917
- barInteractionClasses
918
- ),
919
- style: {
920
- height: animate ? mounted ? `${barSize}%` : "0%" : `${barSize}%`,
921
- transitionDuration: "0.5s",
922
- transitionDelay: animate ? `${index * 0.08}s` : void 0
923
- }
924
- }
925
- ) }),
926
- /* @__PURE__ */ jsx(
927
- "span",
928
- {
929
- className: cn(
930
- "w-full truncate text-center text-muted-foreground",
931
- size === "sm" ? "text-[10px]" : "text-xs"
932
- ),
933
- children: step.label
934
- }
935
- )
936
- ]
937
- }
938
- ) : /* @__PURE__ */ jsxs("div", { role: "listitem", "aria-label": `${step.label}: ${formatValue(step.value)}`, children: [
939
- /* @__PURE__ */ jsxs("div", { className: funnelLabelVariants({ size }), children: [
940
- /* @__PURE__ */ jsx("span", { className: "truncate", children: step.label }),
941
- /* @__PURE__ */ jsx("span", { "data-slot": "funnel-value", className: "tabular-nums", children: formatValue(step.value) })
942
- ] }),
943
- /* @__PURE__ */ jsx("div", { className: "relative w-full overflow-hidden rounded-sm bg-muted", children: /* @__PURE__ */ jsx(
944
- "div",
945
- {
946
- ...barInteractionProps,
947
- className: cn(funnelBarVariants({ size }), color, barInteractionClasses),
948
- style: {
949
- width: animate ? mounted ? `${barSize}%` : "0%" : `${barSize}%`,
950
- transitionDuration: "0.5s",
951
- transitionDelay: animate ? `${index * 0.08}s` : void 0
952
- }
953
- }
954
- ) })
955
- ] }),
956
- showConversion && index < data.length - 1 && /* @__PURE__ */ jsx("div", { className: funnelConversionVariants({ size, direction }), "aria-hidden": "true", children: /* @__PURE__ */ jsxs("span", { children: [
957
- "\u2192 ",
958
- computeConversionRate(data[index + 1].value, step.value)
959
- ] }) })
960
- ] }, index);
961
- })
962
- }
963
- );
964
- });
965
- FunnelSteps.displayName = "FunnelSteps";
966
- var VB_WIDTH = 100;
967
- function normalizeData(values, height, vPad = 2) {
968
- const min = Math.min(...values);
969
- const max = Math.max(...values);
970
- const range = max - min;
971
- const drawHeight = height - vPad * 2;
972
- if (range === 0) return values.map(() => vPad + drawHeight / 2);
973
- return values.map((v) => height - vPad - (v - min) / range * drawHeight);
974
- }
975
- function buildLinePath(ys) {
976
- if (ys.length === 0) return "";
977
- const step = ys.length > 1 ? VB_WIDTH / (ys.length - 1) : 0;
978
- return ys.map((y, i) => `${i === 0 ? "M" : "L"}${(i * step).toFixed(2)},${y.toFixed(2)}`).join(" ");
979
- }
980
- function buildAreaPath(ys, height) {
981
- if (ys.length === 0) return "";
982
- const step = ys.length > 1 ? VB_WIDTH / (ys.length - 1) : 0;
983
- const lastX = ((ys.length - 1) * step).toFixed(2);
984
- return `${buildLinePath(ys)} L${lastX},${height} L0,${height} Z`;
985
- }
986
- function buildBarRects(ys, height, gap = 1) {
987
- const barW = Math.max(1, VB_WIDTH / ys.length - gap);
988
- return ys.map((y, i) => ({ x: i * (barW + gap), y, w: barW, h: height - y }));
989
- }
990
- var Sparkline = forwardRef(function Sparkline2({
991
- data,
992
- variant = "line",
993
- height = 40,
994
- color = "text-chart-1",
995
- area = false,
996
- animate = false,
997
- className,
998
- ...props
999
- }, ref) {
1000
- const [mounted, setMounted] = useState(false);
1001
- useEffect(() => {
1002
- if (animate) setMounted(true);
1003
- }, [animate]);
1004
- if (data.length === 0) return null;
1005
- const ys = normalizeData(
1006
- data.map((d) => d.value),
1007
- height
1008
- );
1009
- return /* @__PURE__ */ jsxs(
1010
- "svg",
1011
- {
1012
- ref,
1013
- "data-slot": "sparkline",
1014
- viewBox: `0 0 ${VB_WIDTH} ${height}`,
1015
- preserveAspectRatio: "none",
1016
- width: "100%",
1017
- height,
1018
- "aria-hidden": "true",
1019
- className: cn("overflow-visible", className),
1020
- ...props,
1021
- children: [
1022
- variant === "line" && /* @__PURE__ */ jsxs(Fragment$1, { children: [
1023
- area && /* @__PURE__ */ jsx(
1024
- "path",
1025
- {
1026
- d: buildAreaPath(ys, height),
1027
- strokeWidth: 0,
1028
- className: cn("fill-current opacity-15", color)
1029
- }
1030
- ),
1031
- /* @__PURE__ */ jsx(
1032
- "path",
1033
- {
1034
- d: buildLinePath(ys),
1035
- fill: "none",
1036
- strokeWidth: 1.5,
1037
- strokeLinecap: "round",
1038
- strokeLinejoin: "round",
1039
- vectorEffect: "non-scaling-stroke",
1040
- pathLength: animate ? 1 : void 0,
1041
- strokeDasharray: animate ? 1 : void 0,
1042
- strokeDashoffset: animate ? mounted ? 0 : 1 : void 0,
1043
- className: cn("stroke-current", color),
1044
- style: animate ? { transition: "stroke-dashoffset 0.6s ease-in-out" } : void 0
1045
- }
1046
- )
1047
- ] }),
1048
- variant === "bar" && buildBarRects(ys, height).map((rect, i) => /* @__PURE__ */ jsx(
1049
- "rect",
1050
- {
1051
- x: rect.x,
1052
- y: animate ? mounted ? rect.y : height : rect.y,
1053
- width: rect.w,
1054
- height: animate ? mounted ? rect.h : 0 : rect.h,
1055
- rx: 0.5,
1056
- className: cn("fill-current", color),
1057
- style: animate ? {
1058
- transition: `height 0.4s ease-out ${i * 0.02}s, y 0.4s ease-out ${i * 0.02}s`
1059
- } : void 0
1060
- },
1061
- i
1062
- ))
1063
- ]
1064
- }
1065
- );
1066
- });
1067
- Sparkline.displayName = "Sparkline";
1068
- function useControlledState(controlledValue, defaultValue, onChange) {
1069
- const [internalValue, setInternalValue] = useState(defaultValue);
1070
- const isControlled = controlledValue !== void 0;
1071
- const value = isControlled ? controlledValue : internalValue;
1072
- const setValue = useCallback(
1073
- (updaterOrValue) => {
1074
- onChange?.(updaterOrValue);
1075
- if (!isControlled) {
1076
- setInternalValue(updaterOrValue);
1077
- }
1078
- },
1079
- [onChange, isControlled]
1080
- );
1081
- return [value, setValue];
1082
- }
1083
- var DataTableContext = createContext(null);
1084
- function useDataTable() {
1085
- const ctx = useContext(DataTableContext);
1086
- if (!ctx) throw new Error("useDataTable must be used inside <DataTable>");
1087
- return ctx;
1088
- }
1089
- function DataTable({
1090
- columns,
1091
- data,
1092
- enableSorting = true,
1093
- sorting: sortingProp,
1094
- onSortingChange,
1095
- enableFiltering = false,
1096
- columnFilters: columnFiltersProp,
1097
- onColumnFiltersChange,
1098
- globalFilter: globalFilterProp,
1099
- onGlobalFilterChange,
1100
- enablePagination = false,
1101
- pagination: paginationProp,
1102
- onPaginationChange,
1103
- pageCount,
1104
- enableRowSelection = false,
1105
- rowSelection: rowSelectionProp,
1106
- onRowSelectionChange,
1107
- columnVisibility: columnVisibilityProp,
1108
- onColumnVisibilityChange,
1109
- meta,
1110
- className,
1111
- children
1112
- }) {
1113
- const [sorting, setSorting] = useControlledState(sortingProp, [], onSortingChange);
1114
- const [columnFilters, setColumnFilters] = useControlledState(
1115
- columnFiltersProp,
1116
- [],
1117
- onColumnFiltersChange
1118
- );
1119
- const [globalFilter, setGlobalFilter] = useControlledState(
1120
- globalFilterProp,
1121
- "",
1122
- onGlobalFilterChange
1123
- );
1124
- const [rowSelection, setRowSelection] = useControlledState(
1125
- rowSelectionProp,
1126
- {},
1127
- onRowSelectionChange
1128
- );
1129
- const [columnVisibility, setColumnVisibility] = useControlledState(
1130
- columnVisibilityProp,
1131
- {},
1132
- onColumnVisibilityChange
1133
- );
1134
- const [pagination, setPagination] = useControlledState(
1135
- paginationProp,
1136
- { pageIndex: 0, pageSize: 10 },
1137
- onPaginationChange
1138
- );
1139
- const allColumns = useMemo(() => {
1140
- if (!enableRowSelection) return columns;
1141
- const selectionColumn = {
1142
- id: "_select",
1143
- header: ({ table: table2 }) => /* @__PURE__ */ jsx(
1144
- Checkbox,
1145
- {
1146
- checked: table2.getIsAllPageRowsSelected(),
1147
- indeterminate: table2.getIsSomePageRowsSelected(),
1148
- onCheckedChange: (checked) => table2.toggleAllPageRowsSelected(checked),
1149
- "aria-label": "\u5168\u3066\u9078\u629E"
1150
- }
1151
- ),
1152
- cell: ({ row }) => /* @__PURE__ */ jsx(
1153
- Checkbox,
1154
- {
1155
- checked: row.getIsSelected(),
1156
- onCheckedChange: (checked) => row.toggleSelected(checked),
1157
- "aria-label": "\u884C\u3092\u9078\u629E"
1158
- }
1159
- ),
1160
- enableSorting: false,
1161
- enableHiding: false
1162
- };
1163
- return [selectionColumn, ...columns];
1164
- }, [columns, enableRowSelection]);
1165
- const table = useReactTable({
1166
- data,
1167
- columns: allColumns,
1168
- state: {
1169
- sorting,
1170
- columnFilters,
1171
- globalFilter,
1172
- rowSelection,
1173
- columnVisibility,
1174
- ...enablePagination ? { pagination } : {}
1175
- },
1176
- enableSorting,
1177
- enableRowSelection,
1178
- onSortingChange: setSorting,
1179
- onColumnFiltersChange: setColumnFilters,
1180
- onGlobalFilterChange: setGlobalFilter,
1181
- onRowSelectionChange: setRowSelection,
1182
- onColumnVisibilityChange: setColumnVisibility,
1183
- ...enablePagination ? { onPaginationChange: setPagination } : {},
1184
- ...pageCount !== void 0 ? { pageCount, manualPagination: true } : {},
1185
- getCoreRowModel: getCoreRowModel(),
1186
- getSortedRowModel: getSortedRowModel(),
1187
- getFilteredRowModel: getFilteredRowModel(),
1188
- ...enablePagination ? { getPaginationRowModel: getPaginationRowModel() } : {},
1189
- meta
1190
- });
1191
- const selectedRows = useMemo(
1192
- () => table.getFilteredSelectedRowModel().rows.map((row) => row.original),
1193
- // `table` is a stable reference, so the selection state is the real input.
1194
- // eslint-disable-next-line react-hooks/exhaustive-deps
1195
- [rowSelection, data]
1196
- );
1197
- const hasSelection = selectedRows.length > 0;
1198
- const contextValue = useMemo(
1199
- () => ({
1200
- table,
1201
- selectedRows,
1202
- hasSelection,
1203
- globalFilter,
1204
- setGlobalFilter,
1205
- enableFiltering,
1206
- enablePagination,
1207
- enableRowSelection,
1208
- visibleColumnCount: allColumns.length
1209
- }),
1210
- // `useReactTable` returns the same object every render, so each piece of
1211
- // table state has to be tracked explicitly to re-render the consumers.
1212
- // eslint-disable-next-line react-hooks/exhaustive-deps
1213
- [
1214
- table,
1215
- selectedRows,
1216
- hasSelection,
1217
- globalFilter,
1218
- setGlobalFilter,
1219
- enableFiltering,
1220
- enablePagination,
1221
- enableRowSelection,
1222
- allColumns.length,
1223
- sorting,
1224
- columnFilters,
1225
- columnVisibility,
1226
- pagination,
1227
- rowSelection
1228
- ]
1229
- );
1230
- return /* @__PURE__ */ jsx(DataTableContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx("div", { "data-slot": "data-table", className: cn("space-y-4", className), children }) });
1231
- }
1232
- DataTable.displayName = "DataTable";
1233
- var DataTableToolbar = forwardRef(
1234
- ({ showSearch, toolbar, bulkActions, className, ...props }, ref) => {
1235
- const { globalFilter, setGlobalFilter, hasSelection, selectedRows, enableFiltering } = useDataTable();
1236
- const showSearchEffective = showSearch ?? enableFiltering;
1237
- const hasContent = showSearchEffective || toolbar != null || hasSelection && bulkActions != null;
1238
- if (!hasContent) return null;
1239
- return /* @__PURE__ */ jsxs(
1240
- "div",
1241
- {
1242
- ref,
1243
- "data-slot": "data-table-toolbar",
1244
- className: cn("flex flex-wrap items-center gap-2", className),
1245
- ...props,
1246
- children: [
1247
- showSearchEffective && /* @__PURE__ */ jsxs("div", { className: "relative", children: [
1248
- /* @__PURE__ */ jsx(Search, { className: "absolute top-2.5 left-2.5 size-4 text-muted-foreground" }),
1249
- /* @__PURE__ */ jsx(
1250
- Input,
1251
- {
1252
- value: globalFilter,
1253
- onChange: (e) => setGlobalFilter(e.target.value),
1254
- className: "max-w-sm pl-8"
1255
- }
1256
- )
1257
- ] }),
1258
- toolbar,
1259
- hasSelection && bulkActions && /* @__PURE__ */ jsx("div", { className: "ml-auto flex items-center gap-2", children: bulkActions(selectedRows) })
1260
- ]
1261
- }
1262
- );
1263
- }
1264
- );
1265
- DataTableToolbar.displayName = "DataTableToolbar";
1266
- var DataTableContent = forwardRef(
1267
- ({ className, ...props }, ref) => {
1268
- const { table, visibleColumnCount } = useDataTable();
1269
- return /* @__PURE__ */ jsx(
1270
- "div",
1271
- {
1272
- ref,
1273
- "data-slot": "data-table-content",
1274
- className: cn("overflow-x-auto", className),
1275
- ...props,
1276
- children: /* @__PURE__ */ jsxs(Table, { children: [
1277
- /* @__PURE__ */ jsx(TableHeader, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx(TableRow, { children: headerGroup.headers.map((header) => /* @__PURE__ */ jsx(TableHead, { children: header.isPlaceholder ? null : header.column.getCanSort() ? /* @__PURE__ */ jsxs(
1278
- "button",
1279
- {
1280
- type: "button",
1281
- className: "inline-flex items-center gap-1 rounded hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none",
1282
- onClick: header.column.getToggleSortingHandler(),
1283
- "aria-sort": header.column.getIsSorted() === "asc" ? "ascending" : header.column.getIsSorted() === "desc" ? "descending" : "none",
1284
- children: [
1285
- flexRender(header.column.columnDef.header, header.getContext()),
1286
- header.column.getIsSorted() === "asc" ? /* @__PURE__ */ jsx(ArrowUp, { className: "size-4" }) : header.column.getIsSorted() === "desc" ? /* @__PURE__ */ jsx(ArrowDown, { className: "size-4" }) : /* @__PURE__ */ jsx(ArrowUpDown, { className: "size-4 text-muted-foreground" })
1287
- ]
1288
- }
1289
- ) : flexRender(header.column.columnDef.header, header.getContext()) }, header.id)) }, headerGroup.id)) }),
1290
- /* @__PURE__ */ jsx(TableBody, { children: table.getRowModel().rows.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx(TableRow, { "data-state": row.getIsSelected() ? "selected" : void 0, children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx(TableCell, { children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id)) }, row.id)) : /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(
1291
- TableCell,
1292
- {
1293
- colSpan: visibleColumnCount,
1294
- className: "h-24 text-center text-muted-foreground",
1295
- children: "\u30C7\u30FC\u30BF\u304C\u3042\u308A\u307E\u305B\u3093"
1296
- }
1297
- ) }) })
1298
- ] })
1299
- }
1300
- );
1301
- }
1302
- );
1303
- DataTableContent.displayName = "DataTableContent";
1304
- var DataTablePagination = forwardRef(
1305
- ({ pageSizeOptions = [10, 20, 50], className, ...props }, ref) => {
1306
- const { table } = useDataTable();
1307
- const totalRows = table.getFilteredRowModel().rows.length;
1308
- const currentPageSize = table.getState().pagination.pageSize;
1309
- const currentPageIndex = table.getState().pagination.pageIndex;
1310
- const rangeStart = currentPageIndex * currentPageSize + 1;
1311
- const rangeEnd = Math.min((currentPageIndex + 1) * currentPageSize, totalRows);
1312
- return /* @__PURE__ */ jsxs(
1313
- "div",
1314
- {
1315
- ref,
1316
- "data-slot": "data-table-pagination",
1317
- className: cn("flex flex-wrap items-center justify-between gap-4", className),
1318
- ...props,
1319
- children: [
1320
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
1321
- /* @__PURE__ */ jsxs("span", { children: [
1322
- totalRows,
1323
- "\u4EF6\u4E2D ",
1324
- rangeStart,
1325
- " - ",
1326
- rangeEnd,
1327
- " \u3092\u8868\u793A"
1328
- ] }),
1329
- /* @__PURE__ */ jsxs(
1330
- Select,
1331
- {
1332
- value: String(currentPageSize),
1333
- onValueChange: (value) => table.setPageSize(Number(value)),
1334
- children: [
1335
- /* @__PURE__ */ jsx(SelectTrigger, { size: "sm", className: "w-[80px]", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
1336
- /* @__PURE__ */ jsx(SelectContent, { children: pageSizeOptions.map((size) => /* @__PURE__ */ jsxs(SelectItem, { value: String(size), children: [
1337
- size,
1338
- "\u4EF6"
1339
- ] }, size)) })
1340
- ]
1341
- }
1342
- )
1343
- ] }),
1344
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
1345
- /* @__PURE__ */ jsx(
1346
- Button,
1347
- {
1348
- variant: "outline",
1349
- size: "sm",
1350
- onClick: () => table.firstPage(),
1351
- disabled: !table.getCanPreviousPage(),
1352
- children: "\u6700\u521D"
1353
- }
1354
- ),
1355
- /* @__PURE__ */ jsx(
1356
- Button,
1357
- {
1358
- variant: "outline",
1359
- size: "sm",
1360
- onClick: () => table.previousPage(),
1361
- disabled: !table.getCanPreviousPage(),
1362
- children: "\u524D\u3078"
1363
- }
1364
- ),
1365
- /* @__PURE__ */ jsx(
1366
- Button,
1367
- {
1368
- variant: "outline",
1369
- size: "sm",
1370
- onClick: () => table.nextPage(),
1371
- disabled: !table.getCanNextPage(),
1372
- children: "\u6B21\u3078"
1373
- }
1374
- ),
1375
- /* @__PURE__ */ jsx(
1376
- Button,
1377
- {
1378
- variant: "outline",
1379
- size: "sm",
1380
- onClick: () => table.lastPage(),
1381
- disabled: !table.getCanNextPage(),
1382
- children: "\u6700\u5F8C"
1383
- }
1384
- )
1385
- ] })
1386
- ]
1387
- }
1388
- );
1389
- }
1390
- );
1391
- DataTablePagination.displayName = "DataTablePagination";
1392
- var DataTableColumnVisibility = forwardRef(({ columnLabels, className }, ref) => {
1393
- const { table } = useDataTable();
1394
- const hideableColumns = table.getAllColumns().filter((column) => column.getCanHide());
1395
- if (hideableColumns.length === 0) return null;
1396
- return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
1397
- /* @__PURE__ */ jsx(
1398
- DropdownMenuTrigger,
1399
- {
1400
- ref,
1401
- render: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", className: cn(className) }),
1402
- "data-slot": "data-table-column-visibility",
1403
- children: /* @__PURE__ */ jsx(Columns3, { className: "size-4" })
1404
- }
1405
- ),
1406
- /* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", className: "min-w-[10rem]", children: hideableColumns.map((column) => {
1407
- const label = columnLabels?.[column.id] ?? (typeof column.columnDef.header === "string" ? column.columnDef.header : column.id);
1408
- return /* @__PURE__ */ jsx(
1409
- DropdownMenuCheckboxItem,
1410
- {
1411
- checked: column.getIsVisible(),
1412
- onCheckedChange: (checked) => column.toggleVisibility(checked),
1413
- children: label
1414
- },
1415
- column.id
1416
- );
1417
- }) })
1418
- ] });
1419
- });
1420
- DataTableColumnVisibility.displayName = "DataTableColumnVisibility";
1421
- function DataTablePreset({
1422
- enableColumnVisibility = false,
1423
- columnLabels,
1424
- toolbar,
1425
- bulkActions,
1426
- ...tableProps
1427
- }) {
1428
- const toolbarSlot = toolbar || enableColumnVisibility ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
1429
- toolbar,
1430
- enableColumnVisibility && /* @__PURE__ */ jsx(DataTableColumnVisibility, { columnLabels })
1431
- ] }) : void 0;
1432
- return /* @__PURE__ */ jsxs(DataTable, { ...tableProps, children: [
1433
- /* @__PURE__ */ jsx(
1434
- DataTableToolbar,
1435
- {
1436
- showSearch: tableProps.enableFiltering,
1437
- toolbar: toolbarSlot,
1438
- bulkActions
1439
- }
1440
- ),
1441
- /* @__PURE__ */ jsx(DataTableContent, {}),
1442
- tableProps.enablePagination && /* @__PURE__ */ jsx(DataTablePagination, {})
1443
- ] });
1444
- }
1445
- DataTablePreset.displayName = "DataTablePreset";
1446
- var FilterBarContext = createContext(null);
1447
- function useFilterBar() {
1448
- const ctx = useContext(FilterBarContext);
1449
- if (!ctx) throw new Error("useFilterBar must be used within <FilterBar>");
1450
- return ctx;
1451
- }
1452
- var FilterBar = forwardRef(
1453
- ({ value, onChange, onClear, className, children, ...props }, ref) => /* @__PURE__ */ jsx(FilterBarContext.Provider, { value: { value, onChange, onClear }, children: /* @__PURE__ */ jsx(
1454
- "div",
1455
- {
1456
- ref,
1457
- role: "search",
1458
- "aria-label": "\u30D5\u30A3\u30EB\u30BF\u30FC",
1459
- "data-slot": "filter-bar",
1460
- className: cn("flex flex-wrap items-center gap-2", className),
1461
- ...props,
1462
- children
1463
- }
1464
- ) })
1465
- );
1466
- FilterBar.displayName = "FilterBar";
1467
- function FilterBarSelect({
1468
- filterKey,
1469
- label,
1470
- options,
1471
- placeholder,
1472
- className
1473
- }) {
1474
- const { value, onChange } = useFilterBar();
1475
- const handleChange = (selected) => onChange({ ...value, [filterKey]: selected ?? void 0 });
1476
- return /* @__PURE__ */ jsxs(Select, { value: value[filterKey] ?? "", onValueChange: handleChange, children: [
1477
- /* @__PURE__ */ jsx(SelectTrigger, { size: "sm", "aria-label": label, "data-slot": "filter-bar-select", className, children: /* @__PURE__ */ jsx(SelectValue, { placeholder: placeholder ?? label }) }),
1478
- /* @__PURE__ */ jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, disabled: option.disabled, children: option.label }, option.value)) })
1479
- ] });
1480
- }
1481
- FilterBarSelect.displayName = "FilterBarSelect";
1482
- function FilterBarMultiSelect({
1483
- filterKey,
1484
- label,
1485
- options,
1486
- placeholder,
1487
- className
1488
- }) {
1489
- const { value, onChange } = useFilterBar();
1490
- const selected = value[filterKey] ?? [];
1491
- const handleToggle = (option) => {
1492
- const next = selected.includes(option) ? selected.filter((v) => v !== option) : [...selected, option];
1493
- onChange({ ...value, [filterKey]: next.length > 0 ? next : void 0 });
1494
- };
1495
- return /* @__PURE__ */ jsxs(Popover, { children: [
1496
- /* @__PURE__ */ jsxs(
1497
- PopoverTrigger,
1498
- {
1499
- render: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", className: cn("h-8 gap-1", className) }),
1500
- "aria-label": `${placeholder ?? label}${selected.length > 0 ? ` (${selected.length}\u4EF6\u9078\u629E\u4E2D)` : ""}`,
1501
- "data-slot": "filter-bar-multi-select",
1502
- children: [
1503
- placeholder ?? label,
1504
- selected.length > 0 && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "ml-1 px-1.5 py-0 text-xs", children: selected.length }),
1505
- /* @__PURE__ */ jsx(ChevronDown, { className: "size-3.5 opacity-50", "aria-hidden": "true" })
1506
- ]
1507
- }
1508
- ),
1509
- /* @__PURE__ */ jsx(PopoverContent, { align: "start", className: "w-56 p-2", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", role: "group", "aria-label": label, children: options.map((option) => /* @__PURE__ */ jsxs(
1510
- "label",
1511
- {
1512
- className: "flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm hover:bg-accent",
1513
- children: [
1514
- /* @__PURE__ */ jsx(
1515
- Checkbox,
1516
- {
1517
- checked: selected.includes(option.value),
1518
- disabled: option.disabled,
1519
- onCheckedChange: () => handleToggle(option.value)
1520
- }
1521
- ),
1522
- option.label
1523
- ]
1524
- },
1525
- option.value
1526
- )) }) })
1527
- ] });
1528
- }
1529
- FilterBarMultiSelect.displayName = "FilterBarMultiSelect";
1530
- function FilterBarActiveChips({ filters, className }) {
1531
- const { value, onChange } = useFilterBar();
1532
- const getActiveChips = () => {
1533
- const chips = [];
1534
- const pushRaw = (key, v) => {
1535
- if (typeof v === "string") {
1536
- chips.push({ key, filterLabel: key, optionLabel: v, isMulti: false });
1537
- } else {
1538
- for (const val of v) {
1539
- chips.push({ key, filterLabel: key, optionLabel: val, optionValue: val, isMulti: true });
1540
- }
1541
- }
1542
- };
1543
- for (const [key, v] of Object.entries(value)) {
1544
- if (v === void 0 || v === "") continue;
1545
- const filter = filters?.find((f) => f.key === key);
1546
- if (!filter) {
1547
- pushRaw(key, v);
1548
- continue;
1549
- }
1550
- if (filter.type === "select" && typeof v === "string") {
1551
- const option = filter.options?.find((o) => o.value === v);
1552
- chips.push({
1553
- key,
1554
- filterLabel: filter.label,
1555
- optionLabel: option?.label ?? v,
1556
- isMulti: false
1557
- });
1558
- } else if (filter.type === "multi-select" && Array.isArray(v)) {
1559
- for (const val of v) {
1560
- const option = filter.options?.find((o) => o.value === val);
1561
- chips.push({
1562
- key,
1563
- filterLabel: filter.label,
1564
- optionLabel: option?.label ?? val,
1565
- optionValue: val,
1566
- isMulti: true
1567
- });
1568
- }
1569
- }
1570
- }
1571
- return chips;
1572
- };
1573
- const handleRemoveFilter = (key, optionValue) => {
1574
- if (optionValue !== void 0) {
1575
- const current = value[key] ?? [];
1576
- const next = current.filter((v) => v !== optionValue);
1577
- onChange({ ...value, [key]: next.length > 0 ? next : void 0 });
1578
- } else {
1579
- onChange({ ...value, [key]: void 0 });
1580
- }
1581
- };
1582
- const activeChips = getActiveChips();
1583
- if (activeChips.length === 0) return null;
1584
- return /* @__PURE__ */ jsx(Fragment$1, { children: activeChips.map((chip) => /* @__PURE__ */ jsxs(
1585
- Badge,
1586
- {
1587
- variant: "secondary",
1588
- className: cn("gap-1 pr-1", className),
1589
- "data-slot": "filter-bar-chip",
1590
- children: [
1591
- /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
1592
- chip.filterLabel,
1593
- ":"
1594
- ] }),
1595
- chip.optionLabel,
1596
- /* @__PURE__ */ jsx(
1597
- "button",
1598
- {
1599
- type: "button",
1600
- className: "ml-0.5 rounded-full p-0.5 hover:bg-muted-foreground/20",
1601
- onClick: () => handleRemoveFilter(chip.key, chip.optionValue),
1602
- "aria-label": `${chip.filterLabel}: ${chip.optionLabel} \u3092\u524A\u9664`,
1603
- children: /* @__PURE__ */ jsx(X, { className: "size-3", "aria-hidden": "true" })
1604
- }
1605
- )
1606
- ]
1607
- },
1608
- `${chip.key}-${chip.optionValue ?? "single"}`
1609
- )) });
1610
- }
1611
- FilterBarActiveChips.displayName = "FilterBarActiveChips";
1612
- function FilterBarClearButton({ label = "\u30AF\u30EA\u30A2", className }) {
1613
- const { value, onClear } = useFilterBar();
1614
- const hasActiveFilters = Object.values(value).some(
1615
- (v) => Array.isArray(v) ? v.length > 0 : v !== void 0 && v !== ""
1616
- );
1617
- if (!hasActiveFilters || !onClear) return null;
1618
- return /* @__PURE__ */ jsx(
1619
- Button,
1620
- {
1621
- variant: "ghost",
1622
- size: "sm",
1623
- className: cn("h-7 px-2 text-xs", className),
1624
- onClick: onClear,
1625
- "aria-label": "\u3059\u3079\u3066\u306E\u30D5\u30A3\u30EB\u30BF\u30FC\u3092\u30AF\u30EA\u30A2",
1626
- "data-slot": "filter-bar-clear-button",
1627
- children: label
1628
- }
1629
- );
1630
- }
1631
- FilterBarClearButton.displayName = "FilterBarClearButton";
1632
- function FilterBarPreset({
1633
- filters,
1634
- value,
1635
- onChange,
1636
- onClear,
1637
- className
1638
- }) {
1639
- return /* @__PURE__ */ jsxs(FilterBar, { value, onChange, onClear, className, children: [
1640
- filters.map((filter) => {
1641
- if (filter.type === "select") {
1642
- return /* @__PURE__ */ jsx(
1643
- FilterBarSelect,
1644
- {
1645
- filterKey: filter.key,
1646
- label: filter.label,
1647
- placeholder: filter.placeholder,
1648
- options: filter.options ?? []
1649
- },
1650
- filter.key
1651
- );
1652
- }
1653
- if (filter.type === "multi-select") {
1654
- return /* @__PURE__ */ jsx(
1655
- FilterBarMultiSelect,
1656
- {
1657
- filterKey: filter.key,
1658
- label: filter.label,
1659
- placeholder: filter.placeholder,
1660
- options: filter.options ?? []
1661
- },
1662
- filter.key
1663
- );
1664
- }
1665
- return null;
1666
- }),
1667
- /* @__PURE__ */ jsx(FilterBarActiveChips, { filters }),
1668
- onClear && /* @__PURE__ */ jsx(FilterBarClearButton, {})
1669
- ] });
1670
- }
1671
- FilterBarPreset.displayName = "FilterBarPreset";
1672
- var defaultPresets = [
1673
- {
1674
- label: "Today",
1675
- getValue: () => {
1676
- const today = /* @__PURE__ */ new Date();
1677
- return { from: startOfDay(today), to: endOfDay(today) };
1678
- }
1679
- },
1680
- {
1681
- label: "Yesterday",
1682
- getValue: () => {
1683
- const yesterday = subDays(/* @__PURE__ */ new Date(), 1);
1684
- return { from: startOfDay(yesterday), to: endOfDay(yesterday) };
1685
- }
1686
- },
1687
- {
1688
- label: "Last 7 days",
1689
- getValue: () => {
1690
- const today = /* @__PURE__ */ new Date();
1691
- return { from: startOfDay(subDays(today, 6)), to: endOfDay(today) };
1692
- }
1693
- },
1694
- {
1695
- label: "Last 14 days",
1696
- getValue: () => {
1697
- const today = /* @__PURE__ */ new Date();
1698
- return { from: startOfDay(subDays(today, 13)), to: endOfDay(today) };
1699
- }
1700
- },
1701
- {
1702
- label: "Last 30 days",
1703
- getValue: () => {
1704
- const today = /* @__PURE__ */ new Date();
1705
- return { from: startOfDay(subDays(today, 29)), to: endOfDay(today) };
1706
- }
1707
- },
1708
- {
1709
- label: "Last 90 days",
1710
- getValue: () => {
1711
- const today = /* @__PURE__ */ new Date();
1712
- return { from: startOfDay(subDays(today, 89)), to: endOfDay(today) };
1713
- }
1714
- },
1715
- {
1716
- label: "This month",
1717
- getValue: () => {
1718
- const today = /* @__PURE__ */ new Date();
1719
- return { from: startOfMonth(today), to: endOfDay(today) };
1720
- }
1721
- },
1722
- {
1723
- label: "Last month",
1724
- getValue: () => {
1725
- const lastMonth = subMonths(/* @__PURE__ */ new Date(), 1);
1726
- return { from: startOfMonth(lastMonth), to: endOfMonth(lastMonth) };
1727
- }
1728
- }
1729
- ];
1730
- var DateRangePicker = forwardRef(
1731
- function DateRangePicker2({
1732
- value,
1733
- onChange,
1734
- presets = defaultPresets,
1735
- showPresets = true,
1736
- maxDate,
1737
- minDate,
1738
- placeholder = "Select date range",
1739
- disabled = false,
1740
- className,
1741
- align = "start"
1742
- }, ref) {
1743
- const [open, setOpen] = useState(false);
1744
- const isMobile = useIsMobile();
1745
- const handleCalendarSelect = useCallback(
1746
- (range) => {
1747
- onChange?.({ from: range?.from, to: range?.to });
1748
- },
1749
- [onChange]
1750
- );
1751
- const handlePresetClick = useCallback(
1752
- (preset) => {
1753
- onChange?.(preset.getValue());
1754
- setOpen(false);
1755
- },
1756
- [onChange]
1757
- );
1758
- const formatDateRange = () => {
1759
- if (!value?.from) return placeholder;
1760
- if (!value.to) return format(value.from, "yyyy/MM/dd", { locale: ja });
1761
- return `${format(value.from, "yyyy/MM/dd", { locale: ja })} - ${format(value.to, "yyyy/MM/dd", { locale: ja })}`;
1762
- };
1763
- const calendarSelected = value?.from ? { from: value.from, to: value.to ?? void 0 } : void 0;
1764
- return /* @__PURE__ */ jsx("div", { ref, "data-slot": "date-range-picker", children: /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
1765
- /* @__PURE__ */ jsxs(
1766
- PopoverTrigger,
1767
- {
1768
- render: /* @__PURE__ */ jsx(
1769
- Button,
1770
- {
1771
- variant: "outline",
1772
- disabled,
1773
- className: cn(
1774
- "w-auto justify-start text-left font-normal",
1775
- !value?.from && "text-muted-foreground",
1776
- className
1777
- )
1778
- }
1779
- ),
1780
- "aria-label": formatDateRange(),
1781
- "aria-expanded": open,
1782
- children: [
1783
- /* @__PURE__ */ jsx(CalendarIcon, { className: "size-4", "aria-hidden": "true" }),
1784
- /* @__PURE__ */ jsx("span", { children: formatDateRange() })
1785
- ]
1786
- }
1787
- ),
1788
- /* @__PURE__ */ jsxs(
1789
- PopoverContent,
1790
- {
1791
- align,
1792
- className: cn("w-auto p-0", isMobile ? "flex flex-col" : "flex"),
1793
- children: [
1794
- showPresets && /* @__PURE__ */ jsx("div", { className: cn("flex flex-col gap-1 p-3", isMobile ? "border-b" : "border-r"), children: presets.map((preset) => /* @__PURE__ */ jsx(
1795
- Button,
1796
- {
1797
- variant: "ghost",
1798
- size: "sm",
1799
- className: "justify-start text-xs",
1800
- onClick: () => handlePresetClick(preset),
1801
- children: preset.label
1802
- },
1803
- preset.label
1804
- )) }),
1805
- /* @__PURE__ */ jsx("div", { className: "p-3", children: /* @__PURE__ */ jsx(
1806
- Calendar,
1807
- {
1808
- mode: "range",
1809
- numberOfMonths: isMobile ? 1 : 2,
1810
- selected: calendarSelected,
1811
- onSelect: handleCalendarSelect,
1812
- disabled: (date) => {
1813
- if (maxDate && date > maxDate) return true;
1814
- if (minDate && date < minDate) return true;
1815
- return false;
1816
- }
1817
- }
1818
- ) })
1819
- ]
1820
- }
1821
- )
1822
- ] }) });
1823
- }
1824
- );
1825
- DateRangePicker.displayName = "DateRangePicker";
1826
- var iconSizes = {
1827
- sm: "size-3.5",
1828
- default: "size-4",
1829
- lg: "size-5"
1830
- };
1831
- var SegmentedControl = forwardRef(
1832
- function SegmentedControl2({ options, value, onChange, size = "default", fullWidth = false, ariaLabel, className }, ref) {
1833
- return /* @__PURE__ */ jsx(
1834
- ToggleGroup,
1835
- {
1836
- ref,
1837
- "data-slot": "segmented-control",
1838
- value: [value],
1839
- onValueChange: (next) => {
1840
- const picked = next.find((item) => item !== value) ?? next[0];
1841
- if (typeof picked === "string") onChange(picked);
1842
- },
1843
- variant: "outline",
1844
- size,
1845
- spacing: 0,
1846
- "aria-label": ariaLabel,
1847
- className: cn(fullWidth && "w-full", className),
1848
- children: options.map((option) => {
1849
- const Icon = option.icon;
1850
- return /* @__PURE__ */ jsxs(
1851
- ToggleGroupItem,
1852
- {
1853
- value: option.value,
1854
- disabled: option.disabled,
1855
- "aria-label": option.label,
1856
- className: cn(fullWidth && "flex-1"),
1857
- children: [
1858
- Icon && /* @__PURE__ */ jsx(Icon, { className: iconSizes[size], "aria-hidden": "true" }),
1859
- option.label
1860
- ]
1861
- },
1862
- option.value
1863
- );
1864
- })
1865
- }
1866
- );
1867
- }
1868
- );
1869
- SegmentedControl.displayName = "SegmentedControl";
1870
-
1871
- // src/components/types.ts
1872
- function isGroupedOptions(options) {
1873
- return options.length > 0 && "options" in options[0];
1874
- }
1875
- function flattenOptions(options) {
1876
- if (isGroupedOptions(options)) {
1877
- return options.flatMap((group) => group.options);
1878
- }
1879
- return options;
1880
- }
1881
- function OptionCommandList({
1882
- options,
1883
- isSelected,
1884
- onSelect,
1885
- onSearch,
1886
- isLoading,
1887
- searchPlaceholder,
1888
- emptyText
1889
- }) {
1890
- const renderOptions = (items) => items.map((option) => /* @__PURE__ */ jsxs(
1891
- CommandItem,
1892
- {
1893
- value: option.value,
1894
- keywords: [option.label],
1895
- disabled: option.disabled,
1896
- onSelect,
1897
- children: [
1898
- option.icon && /* @__PURE__ */ jsx(option.icon, { className: "size-4 shrink-0" }),
1899
- /* @__PURE__ */ jsxs("span", { className: "flex-1 truncate", children: [
1900
- option.label,
1901
- option.description && /* @__PURE__ */ jsx("span", { className: "ml-2 text-xs text-muted-foreground", children: option.description })
1902
- ] }),
1903
- /* @__PURE__ */ jsx(
1904
- CheckIcon,
1905
- {
1906
- className: cn("size-4 shrink-0", isSelected(option.value) ? "opacity-100" : "opacity-0")
1907
- }
1908
- )
1909
- ]
1910
- },
1911
- option.value
1912
- ));
1913
- return /* @__PURE__ */ jsxs(Command, { shouldFilter: !onSearch, children: [
1914
- /* @__PURE__ */ jsx(CommandInput, { placeholder: searchPlaceholder, onValueChange: onSearch }),
1915
- /* @__PURE__ */ jsx(CommandList, { children: isLoading ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-6", children: /* @__PURE__ */ jsx(LoaderIcon, { className: "size-4 animate-spin text-muted-foreground" }) }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
1916
- /* @__PURE__ */ jsx(CommandEmpty, { children: emptyText }),
1917
- isGroupedOptions(options) ? options.map((group) => /* @__PURE__ */ jsx(CommandGroup, { heading: group.label, children: renderOptions(group.options) }, group.label)) : renderOptions(options)
1918
- ] }) })
1919
- ] });
1920
- }
1921
- function RemoveButton({ label, onRemove, iconClassName }) {
1922
- const handle = (e) => {
1923
- e.stopPropagation();
1924
- onRemove();
1925
- };
1926
- return /* @__PURE__ */ jsx(
1927
- "span",
1928
- {
1929
- role: "button",
1930
- tabIndex: 0,
1931
- "aria-label": label,
1932
- className: "rounded-sm opacity-50 hover:opacity-100 focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
1933
- onClick: handle,
1934
- onKeyDown: (e) => {
1935
- if (e.key === "Enter" || e.key === " ") handle(e);
1936
- },
1937
- children: /* @__PURE__ */ jsx(XIcon, { className: cn("size-3.5", iconClassName) })
1938
- }
1939
- );
1940
- }
1941
- var SearchableSelect = forwardRef(
1942
- function SearchableSelect2({
1943
- options,
1944
- value,
1945
- onChange,
1946
- onSearch,
1947
- placeholder = "\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044",
1948
- searchPlaceholder = "\u691C\u7D22...",
1949
- emptyText = "\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F",
1950
- isLoading = false,
1951
- disabled = false,
1952
- clearable = true,
1953
- className
1954
- }, ref) {
1955
- const [open, setOpen] = useState(false);
1956
- const allOptions = useMemo(() => flattenOptions(options), [options]);
1957
- const selectedOption = useMemo(
1958
- () => allOptions.find((opt) => opt.value === value),
1959
- [allOptions, value]
1960
- );
1961
- function handleSelect(selectedValue) {
1962
- onChange?.(selectedValue === value ? void 0 : selectedValue);
1963
- setOpen(false);
1964
- }
1965
- return /* @__PURE__ */ jsx("div", { ref, "data-slot": "searchable-select", children: /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
1966
- /* @__PURE__ */ jsxs(
1967
- PopoverTrigger,
1968
- {
1969
- render: /* @__PURE__ */ jsx(
1970
- Button,
1971
- {
1972
- variant: "outline",
1973
- disabled,
1974
- className: cn(
1975
- "w-full justify-between font-normal",
1976
- !selectedOption && "text-muted-foreground",
1977
- className
1978
- )
1979
- }
1980
- ),
1981
- role: "combobox",
1982
- "aria-expanded": open,
1983
- children: [
1984
- /* @__PURE__ */ jsx("span", { className: "truncate", children: selectedOption ? selectedOption.label : placeholder }),
1985
- /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [
1986
- clearable && value && /* @__PURE__ */ jsx(RemoveButton, { label: "\u30AF\u30EA\u30A2", onRemove: () => onChange?.(void 0) }),
1987
- /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 opacity-50" })
1988
- ] })
1989
- ]
1990
- }
1991
- ),
1992
- /* @__PURE__ */ jsx(PopoverContent, { className: "w-(--anchor-width) p-0", align: "start", children: /* @__PURE__ */ jsx(
1993
- OptionCommandList,
1994
- {
1995
- options,
1996
- isSelected: (v) => value === v,
1997
- onSelect: handleSelect,
1998
- onSearch,
1999
- isLoading,
2000
- searchPlaceholder,
2001
- emptyText
2002
- }
2003
- ) })
2004
- ] }) });
2005
- }
2006
- );
2007
- SearchableSelect.displayName = "SearchableSelect";
2008
- var MultiSelect = forwardRef(function MultiSelect2({
2009
- options,
2010
- value,
2011
- onChange,
2012
- onSearch,
2013
- maxCount = 3,
2014
- placeholder = "\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044",
2015
- searchPlaceholder = "\u691C\u7D22...",
2016
- emptyText = "\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F",
2017
- isLoading = false,
2018
- disabled = false,
2019
- className
2020
- }, ref) {
2021
- const [open, setOpen] = useState(false);
2022
- const listId = useId();
2023
- const allOptions = useMemo(() => flattenOptions(options), [options]);
2024
- const selectedOptions = useMemo(
2025
- () => allOptions.filter((opt) => value.includes(opt.value)),
2026
- [allOptions, value]
2027
- );
2028
- function handleSelect(selectedValue) {
2029
- if (value.includes(selectedValue)) {
2030
- onChange?.(value.filter((v) => v !== selectedValue));
2031
- } else {
2032
- onChange?.([...value, selectedValue]);
2033
- }
2034
- }
2035
- const visibleBadges = selectedOptions.slice(0, maxCount);
2036
- const overflowCount = selectedOptions.length - maxCount;
2037
- return /* @__PURE__ */ jsx("div", { ref, "data-slot": "multi-select", children: /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
2038
- /* @__PURE__ */ jsxs(
2039
- PopoverTrigger,
2040
- {
2041
- role: "combobox",
2042
- "aria-expanded": open,
2043
- "aria-controls": listId,
2044
- disabled,
2045
- className: cn(
2046
- "inline-flex min-h-9 w-full items-center justify-between gap-2 rounded-md border bg-background px-3 py-1.5 text-sm shadow-xs transition-all outline-none hover:bg-accent hover:text-accent-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
2047
- className
2048
- ),
2049
- children: [
2050
- /* @__PURE__ */ jsx("span", { className: "flex min-w-0 flex-1 flex-wrap items-center gap-1", children: selectedOptions.length === 0 ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: placeholder }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
2051
- visibleBadges.map((option) => /* @__PURE__ */ jsxs(Badge, { variant: "secondary", className: "shrink-0 gap-1 pr-1", children: [
2052
- /* @__PURE__ */ jsx("span", { className: "max-w-[120px] truncate", children: option.label }),
2053
- /* @__PURE__ */ jsx(
2054
- RemoveButton,
2055
- {
2056
- label: `${option.label}\u3092\u524A\u9664`,
2057
- onRemove: () => onChange?.(value.filter((v) => v !== option.value)),
2058
- iconClassName: "size-3"
2059
- }
2060
- )
2061
- ] }, option.value)),
2062
- overflowCount > 0 && /* @__PURE__ */ jsxs(Badge, { variant: "secondary", className: "shrink-0", children: [
2063
- "+",
2064
- overflowCount,
2065
- "\u4EF6"
2066
- ] })
2067
- ] }) }),
2068
- /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 shrink-0 opacity-50" })
2069
- ]
2070
- }
2071
- ),
2072
- /* @__PURE__ */ jsx(PopoverContent, { id: listId, className: "w-(--anchor-width) p-0", align: "start", children: /* @__PURE__ */ jsx(
2073
- OptionCommandList,
2074
- {
2075
- options,
2076
- isSelected: (v) => value.includes(v),
2077
- onSelect: handleSelect,
2078
- onSearch,
2079
- isLoading,
2080
- searchPlaceholder,
2081
- emptyText
2082
- }
2083
- ) })
2084
- ] }) });
2085
- });
2086
- MultiSelect.displayName = "MultiSelect";
2087
- var metricValueVariants = cva("font-medium tracking-tight", {
2088
- variants: {
2089
- size: {
2090
- sm: "text-base",
2091
- md: "text-2xl",
2092
- lg: "text-3xl",
2093
- xl: "text-4xl"
2094
- }
2095
- },
2096
- defaultVariants: {
2097
- size: "md"
2098
- }
2099
- });
2100
- var MetricValue = forwardRef(
2101
- ({ className, size, ...props }, ref) => /* @__PURE__ */ jsx(
2102
- "div",
2103
- {
2104
- ref,
2105
- "data-slot": "metric-value",
2106
- className: cn("my-4", metricValueVariants({ size }), className),
2107
- ...props
2108
- }
2109
- )
2110
- );
2111
- MetricValue.displayName = "MetricValue";
2112
- var MetricUnit = forwardRef(
2113
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2114
- "span",
2115
- {
2116
- ref,
2117
- "data-slot": "metric-unit",
2118
- className: cn("text-sm font-normal text-muted-foreground", className),
2119
- ...props
2120
- }
2121
- )
2122
- );
2123
- MetricUnit.displayName = "MetricUnit";
2124
- var trendIndicatorVariants = cva("inline-flex items-center gap-0.5 text-sm font-medium", {
2125
- variants: {
2126
- sentiment: {
2127
- positive: "text-chart-1",
2128
- negative: "text-primary",
2129
- neutral: "text-muted-foreground"
2130
- }
2131
- },
2132
- defaultVariants: {
2133
- sentiment: "neutral"
2134
- }
2135
- });
2136
- var TrendIndicator = forwardRef(
2137
- ({ value, direction, positiveIsGood = true, className }, ref) => {
2138
- const isGood = direction === "neutral" ? null : direction === "up" === positiveIsGood;
2139
- const sentiment = isGood === null ? "neutral" : isGood ? "positive" : "negative";
2140
- const Icon = direction === "up" ? ArrowUp : direction === "down" ? ArrowDown : Minus;
2141
- const ariaLabel = direction === "neutral" ? `\u5909\u5316\u306A\u3057 ${value}%` : direction === "up" ? `${value}% \u5897\u52A0` : `${value}% \u6E1B\u5C11`;
2142
- return /* @__PURE__ */ jsxs(
2143
- "span",
2144
- {
2145
- ref,
2146
- "data-slot": "trend-indicator",
2147
- className: cn(trendIndicatorVariants({ sentiment }), className),
2148
- "aria-label": ariaLabel,
2149
- children: [
2150
- /* @__PURE__ */ jsx(Icon, { className: "size-3.5", "aria-hidden": "true" }),
2151
- /* @__PURE__ */ jsxs("span", { children: [
2152
- value,
2153
- "%"
2154
- ] })
2155
- ]
2156
- }
2157
- );
2158
- }
2159
- );
2160
- TrendIndicator.displayName = "TrendIndicator";
2161
- var defaultColorMap = {
2162
- active: "green",
2163
- inactive: "gray",
2164
- warning: "yellow",
2165
- error: "red",
2166
- pending: "blue"
2167
- };
2168
- var colorStyles = {
2169
- green: {
2170
- dot: "bg-green-500",
2171
- bg: "bg-green-50 dark:bg-green-950",
2172
- text: "text-green-700 dark:text-green-300"
2173
- },
2174
- gray: {
2175
- dot: "bg-gray-500",
2176
- bg: "bg-gray-50 dark:bg-gray-950",
2177
- text: "text-gray-700 dark:text-gray-300"
2178
- },
2179
- yellow: {
2180
- dot: "bg-yellow-500",
2181
- bg: "bg-yellow-50 dark:bg-yellow-950",
2182
- text: "text-yellow-700 dark:text-yellow-300"
2183
- },
2184
- red: {
2185
- dot: "bg-red-500",
2186
- bg: "bg-red-50 dark:bg-red-950",
2187
- text: "text-red-700 dark:text-red-300"
2188
- },
2189
- blue: {
2190
- dot: "bg-blue-500",
2191
- bg: "bg-blue-50 dark:bg-blue-950",
2192
- text: "text-blue-700 dark:text-blue-300"
2193
- }
2194
- };
2195
- var fallbackStyle = colorStyles.gray;
2196
- var StatusBadge = forwardRef(function StatusBadge2({ status, label, colorMap, className }, ref) {
2197
- const mergedColorMap = { ...defaultColorMap, ...colorMap };
2198
- const color = mergedColorMap[status] ?? "gray";
2199
- const style = colorStyles[color] ?? fallbackStyle;
2200
- const displayLabel = label ?? status;
2201
- return /* @__PURE__ */ jsxs(
2202
- Badge,
2203
- {
2204
- ref,
2205
- "data-slot": "status-badge",
2206
- variant: "outline",
2207
- className: cn("gap-1.5 border-transparent", style.bg, style.text, className),
2208
- "aria-label": displayLabel,
2209
- children: [
2210
- /* @__PURE__ */ jsx("span", { className: cn("inline-block size-2 rounded-full", style.dot), "aria-hidden": "true" }),
2211
- displayLabel
2212
- ]
2213
- }
2214
- );
2215
- });
2216
- StatusBadge.displayName = "StatusBadge";
2217
- var Placeholder = forwardRef(function Placeholder2({ className, ...props }, ref) {
2218
- return /* @__PURE__ */ jsx(
2219
- "span",
2220
- {
2221
- ref,
2222
- "data-slot": "placeholder",
2223
- className: cn("inline-block animate-pulse text-muted-foreground", className),
2224
- ...props
2225
- }
2226
- );
2227
- });
2228
- Placeholder.displayName = "Placeholder";
2229
-
2230
- export { AppShell, DashboardCard, DashboardCardAction, DashboardCardContent, DashboardCardDescription, DashboardCardFooter, DashboardCardHeader, DashboardCardPreset, DashboardCardSkeleton, DashboardCardTitle, DataTable, DataTableColumnVisibility, DataTableContent, DataTablePagination, DataTablePreset, DataTableToolbar, DateRangePicker, EChart, FilterBar, FilterBarActiveChips, FilterBarClearButton, FilterBarMultiSelect, FilterBarPreset, FilterBarSelect, FunnelSteps, MetricUnit, MetricValue, MultiSelect, PageShell, PageShellActions, PageShellContent, PageShellDescription, PageShellHeader, PageShellHeaderEnd, PageShellHeading, PageShellMeta, PageShellSummary, PageShellSummaryCard, PageShellTitle, Placeholder, SearchableSelect, SectionHeader, SegmentedControl, Sparkline, StatusBadge, TrendIndicator, defaultPresets, flattenOptions, funnelStepsVariants, isGroupedOptions, metricValueVariants, pageShellSummaryCardVariants, useDataTable };
2231
- //# sourceMappingURL=chunk-MP3QSOXL.js.map
2232
- //# sourceMappingURL=chunk-MP3QSOXL.js.map