@squadbase/vantage 0.5.3 → 0.6.0-dev.3cc6138

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