@squadbase/vantage 0.6.1 → 0.6.2-dev1.25d59a0

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