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

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 (186) hide show
  1. package/dist/add-4GHF2TX2.js +6 -0
  2. package/dist/add-4GHF2TX2.js.map +1 -0
  3. package/dist/{build-JB4VOMUI.js → build-MFWRPYKW.js} +9 -9
  4. package/dist/{build-JB4VOMUI.js.map → build-MFWRPYKW.js.map} +1 -1
  5. package/dist/{check-ZJYK6RLG.js → check-ZBIH422T.js} +7 -7
  6. package/dist/{check-ZJYK6RLG.js.map → check-ZBIH422T.js.map} +1 -1
  7. package/dist/{chunk-BCE22JSM.js → chunk-7DZGJQ3P.js} +33 -14
  8. package/dist/chunk-7DZGJQ3P.js.map +1 -0
  9. package/dist/{chunk-U2M6HGKQ.js → chunk-AABMKHEU.js} +4 -4
  10. package/dist/{chunk-U2M6HGKQ.js.map → chunk-AABMKHEU.js.map} +1 -1
  11. package/dist/{chunk-MP3QSOXL.js → chunk-AG6RZ2RR.js} +992 -16
  12. package/dist/chunk-AG6RZ2RR.js.map +1 -0
  13. package/dist/{chunk-KLEIVDUV.js → chunk-CEXAQQ5W.js} +150 -11
  14. package/dist/chunk-CEXAQQ5W.js.map +1 -0
  15. package/dist/{chunk-QI3XQKHS.js → chunk-GNXCX4WE.js} +10 -3
  16. package/dist/chunk-GNXCX4WE.js.map +1 -0
  17. package/dist/chunk-IBGOCWJB.js +1716 -0
  18. package/dist/chunk-IBGOCWJB.js.map +1 -0
  19. package/dist/{chunk-JGRMRXXZ.js → chunk-JKLLFVEU.js} +3 -3
  20. package/dist/{chunk-JGRMRXXZ.js.map → chunk-JKLLFVEU.js.map} +1 -1
  21. package/dist/{chunk-RPZAALCX.js → chunk-OB6UBJXF.js} +153 -153
  22. package/dist/{chunk-RPZAALCX.js.map → chunk-OB6UBJXF.js.map} +1 -1
  23. package/dist/{chunk-EP6JHXSR.js → chunk-QEWCYW3I.js} +44 -9
  24. package/dist/chunk-QEWCYW3I.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-PVTHHV7X.js → chunk-V3LF7BE7.js} +27 -5
  28. package/dist/chunk-V3LF7BE7.js.map +1 -0
  29. package/dist/{chunk-DTDVSFRY.js → chunk-XQUSGIDG.js} +17 -3
  30. package/dist/chunk-XQUSGIDG.js.map +1 -0
  31. package/dist/cli.js +12 -11
  32. package/dist/cli.js.map +1 -1
  33. package/dist/client/index.d.ts +32 -3
  34. package/dist/client/index.js +205 -12
  35. package/dist/client/index.js.map +1 -1
  36. package/dist/components/index.d.ts +216 -1
  37. package/dist/components/index.js +2 -2
  38. package/dist/{dev-FCEC3UKQ.js → dev-DCTOHQ6W.js} +10 -10
  39. package/dist/dev-DCTOHQ6W.js.map +1 -0
  40. package/dist/{docs-EJJ3BECT.js → docs-JVP4RPKT.js} +3 -3
  41. package/dist/{docs-EJJ3BECT.js.map → docs-JVP4RPKT.js.map} +1 -1
  42. package/dist/{doctor-WHZXPERA.js → doctor-5E2VEZPK.js} +7 -7
  43. package/dist/{doctor-WHZXPERA.js.map → doctor-5E2VEZPK.js.map} +1 -1
  44. package/dist/{preview-OGMCNQUO.js → preview-T6CLSQVX.js} +3 -3
  45. package/dist/{preview-OGMCNQUO.js.map → preview-T6CLSQVX.js.map} +1 -1
  46. package/dist/query/index.d.ts +0 -11
  47. package/dist/query/index.js +2 -2
  48. package/dist/{routes-GTFO5PUF.js → routes-3SGAFDMC.js} +6 -6
  49. package/dist/{routes-GTFO5PUF.js.map → routes-3SGAFDMC.js.map} +1 -1
  50. package/dist/{search-6Y422SV6.js → search-5LC4XPB5.js} +3 -3
  51. package/dist/{search-6Y422SV6.js.map → search-5LC4XPB5.js.map} +1 -1
  52. package/dist/slide/index.js +47 -10
  53. package/dist/slide/index.js.map +1 -1
  54. package/dist/table/index.js +8 -7
  55. package/dist/table/index.js.map +1 -1
  56. package/dist/ui/index.d.ts +140 -10
  57. package/dist/ui/index.js +1405 -63
  58. package/dist/ui/index.js.map +1 -1
  59. package/dist/{upgrade-AL4KZZR4.js → upgrade-DBBE6GIR.js} +7 -7
  60. package/dist/{upgrade-AL4KZZR4.js.map → upgrade-DBBE6GIR.js.map} +1 -1
  61. package/dist/vite/index.d.ts +10 -0
  62. package/dist/vite/index.js +4 -4
  63. package/docs/index.json +291 -61
  64. package/docs/ja/changelog.md +26 -0
  65. package/docs/ja/components.md +33 -89
  66. package/docs/ja/page-types/csv.md +83 -0
  67. package/docs/ja/page-types/doc.md +83 -0
  68. package/docs/ja/page-types/excel.md +82 -0
  69. package/docs/ja/page-types/slide.md +132 -0
  70. package/docs/ja/page-types.md +47 -0
  71. package/docs/ja/parts/area-chart.md +61 -0
  72. package/docs/ja/parts/bar-chart.md +69 -0
  73. package/docs/ja/parts/bar-list.md +35 -0
  74. package/docs/ja/parts/category-bar.md +36 -0
  75. package/docs/ja/parts/donut-chart.md +47 -0
  76. package/docs/ja/parts/echart.md +3 -0
  77. package/docs/ja/parts/line-chart.md +58 -0
  78. package/docs/ja/parts/progress-circle.md +34 -0
  79. package/docs/ja/parts/sparkline.md +1 -1
  80. package/docs/ja/parts/tracker.md +32 -0
  81. package/docs/ja/routing.md +8 -86
  82. package/docs/ja/ui/alert-dialog.md +41 -0
  83. package/docs/ja/ui/avatar.md +31 -0
  84. package/docs/ja/ui/combobox.md +74 -0
  85. package/docs/ja/ui/drawer.md +41 -0
  86. package/docs/ja/ui/field.md +42 -0
  87. package/docs/ja/ui/hover-card.md +21 -0
  88. package/docs/ja/ui/kbd.md +16 -0
  89. package/docs/ja/ui/pagination.md +36 -0
  90. package/docs/ja/ui/radio-group.md +21 -0
  91. package/docs/ja/ui/toast.md +46 -0
  92. package/docs/ja/ui-and-theming.md +14 -7
  93. package/package.json +25 -13
  94. package/registry/ui/accordion.tsx +74 -0
  95. package/registry/ui/alert-dialog.tsx +189 -0
  96. package/registry/ui/alert.tsx +78 -0
  97. package/registry/ui/app-shell.tsx +281 -0
  98. package/registry/ui/area-chart.tsx +1015 -0
  99. package/registry/ui/avatar.tsx +110 -0
  100. package/registry/ui/badge.tsx +54 -0
  101. package/registry/ui/bar-chart.tsx +1013 -0
  102. package/registry/ui/bar-list.tsx +302 -0
  103. package/registry/ui/breadcrumb.tsx +126 -0
  104. package/registry/ui/button.tsx +60 -0
  105. package/registry/ui/calendar.tsx +221 -0
  106. package/registry/ui/card.tsx +105 -0
  107. package/registry/ui/category-bar.tsx +281 -0
  108. package/registry/ui/checkbox.tsx +28 -0
  109. package/registry/ui/collapsible.tsx +21 -0
  110. package/registry/ui/combobox.tsx +310 -0
  111. package/registry/ui/command.tsx +196 -0
  112. package/registry/ui/dashboard-card.tsx +174 -0
  113. package/registry/ui/data-table.tsx +16 -91
  114. package/registry/ui/date-range-picker.tsx +209 -0
  115. package/registry/ui/dialog.tsx +159 -0
  116. package/registry/ui/donut-chart.tsx +1004 -0
  117. package/registry/ui/drawer.tsx +229 -0
  118. package/registry/ui/dropdown-menu.tsx +272 -0
  119. package/registry/ui/echart.tsx +486 -0
  120. package/registry/ui/field.tsx +240 -0
  121. package/registry/ui/filter-bar.tsx +365 -0
  122. package/registry/ui/funnel-steps.tsx +274 -0
  123. package/registry/ui/hover-card.tsx +52 -0
  124. package/registry/ui/input-group.tsx +158 -0
  125. package/registry/ui/input.tsx +22 -0
  126. package/registry/ui/kbd.tsx +28 -0
  127. package/registry/ui/label.tsx +20 -0
  128. package/registry/ui/line-chart.tsx +1007 -0
  129. package/registry/ui/metric-value.tsx +54 -0
  130. package/registry/ui/multi-select.tsx +226 -0
  131. package/registry/ui/page-shell.tsx +227 -0
  132. package/registry/ui/pagination.tsx +138 -0
  133. package/registry/ui/placeholder.tsx +30 -0
  134. package/registry/ui/popover.tsx +90 -0
  135. package/registry/ui/progress-circle.tsx +272 -0
  136. package/registry/ui/progress.tsx +83 -0
  137. package/registry/ui/radio-group.tsx +39 -0
  138. package/registry/ui/scroll-area.tsx +55 -0
  139. package/registry/ui/searchable-select.tsx +209 -0
  140. package/registry/ui/section-header.tsx +41 -0
  141. package/registry/ui/segmented-control.tsx +71 -0
  142. package/registry/ui/select.tsx +253 -0
  143. package/registry/ui/separator.tsx +25 -0
  144. package/registry/ui/sheet.tsx +137 -0
  145. package/registry/ui/sidebar.tsx +723 -0
  146. package/registry/ui/skeleton.tsx +15 -0
  147. package/registry/ui/slider.tsx +54 -0
  148. package/registry/ui/sparkline.tsx +155 -0
  149. package/registry/ui/spinner.tsx +12 -0
  150. package/registry/ui/states.tsx +61 -0
  151. package/registry/ui/status-badge.tsx +79 -0
  152. package/registry/ui/switch.tsx +32 -0
  153. package/registry/ui/table.tsx +116 -0
  154. package/registry/ui/tabs.tsx +82 -0
  155. package/registry/ui/textarea.tsx +20 -0
  156. package/registry/ui/toast.tsx +250 -0
  157. package/registry/ui/toggle-group.tsx +89 -0
  158. package/registry/ui/toggle.tsx +45 -0
  159. package/registry/ui/tooltip.tsx +66 -0
  160. package/registry/ui/tracker.tsx +236 -0
  161. package/registry/ui/trend-indicator.tsx +62 -0
  162. package/skills/vantage-add-feature/SKILL.md +9 -7
  163. package/skills/vantage-design/SKILL.md +3 -1
  164. package/skills/vantage-design/references/format.md +1 -1
  165. package/skills/vantage-pitfalls/SKILL.md +5 -1
  166. package/skills/vantage-slide/SKILL.md +17 -0
  167. package/templates/AGENTS.md +10 -1
  168. package/templates/agents/api.md +29 -0
  169. package/templates/agents/csv.md +2 -1
  170. package/templates/agents/doc.md +4 -3
  171. package/templates/agents/page.md +22 -8
  172. package/templates/agents/slide.md +13 -1
  173. package/templates/agents/xlsx.md +2 -1
  174. package/theme.css +7 -1
  175. package/dist/add-DY4AXANK.js +0 -6
  176. package/dist/add-DY4AXANK.js.map +0 -1
  177. package/dist/chunk-BCE22JSM.js.map +0 -1
  178. package/dist/chunk-DTDVSFRY.js.map +0 -1
  179. package/dist/chunk-EP6JHXSR.js.map +0 -1
  180. package/dist/chunk-KLEIVDUV.js.map +0 -1
  181. package/dist/chunk-MP3QSOXL.js.map +0 -1
  182. package/dist/chunk-PVTHHV7X.js.map +0 -1
  183. package/dist/chunk-QI3XQKHS.js.map +0 -1
  184. package/dist/chunk-T3FLAGI6.js +0 -316
  185. package/dist/chunk-T3FLAGI6.js.map +0 -1
  186. package/dist/dev-FCEC3UKQ.js.map +0 -1
@@ -0,0 +1,221 @@
1
+ // Copied by `vantage add ui calendar`. This file is yours to edit.
2
+ // Generated from @squadbase/vantage src/ui/calendar.tsx by `npm run registry` (in Vantage, edit src/, not registry/).
3
+ import * as React from "react"
4
+ import {
5
+ DayPicker,
6
+ getDefaultClassNames,
7
+ type DayButton,
8
+ type Locale,
9
+ } from "react-day-picker"
10
+
11
+ import { cn } from "@squadbase/vantage/ui"
12
+ import { Button, buttonVariants } from "@squadbase/vantage/ui"
13
+ import { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from "lucide-react"
14
+
15
+ function Calendar({
16
+ className,
17
+ classNames,
18
+ showOutsideDays = true,
19
+ captionLayout = "label",
20
+ buttonVariant = "ghost",
21
+ locale,
22
+ formatters,
23
+ components,
24
+ ...props
25
+ }: React.ComponentProps<typeof DayPicker> & {
26
+ buttonVariant?: React.ComponentProps<typeof Button>["variant"]
27
+ }) {
28
+ const defaultClassNames = getDefaultClassNames()
29
+
30
+ return (
31
+ <DayPicker
32
+ showOutsideDays={showOutsideDays}
33
+ className={cn(
34
+ "group/calendar bg-background p-2 [--cell-radius:var(--radius-md)] [--cell-size:--spacing(7)] in-data-[slot=card-content]:bg-transparent in-data-[slot=popover-content]:bg-transparent",
35
+ String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
36
+ String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
37
+ className
38
+ )}
39
+ captionLayout={captionLayout}
40
+ locale={locale}
41
+ formatters={{
42
+ formatMonthDropdown: (date) =>
43
+ date.toLocaleString(locale?.code, { month: "short" }),
44
+ ...formatters,
45
+ }}
46
+ classNames={{
47
+ root: cn("w-fit", defaultClassNames.root),
48
+ months: cn(
49
+ "relative flex flex-col gap-4 md:flex-row",
50
+ defaultClassNames.months
51
+ ),
52
+ month: cn("flex w-full flex-col gap-4", defaultClassNames.month),
53
+ nav: cn(
54
+ "absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1",
55
+ defaultClassNames.nav
56
+ ),
57
+ button_previous: cn(
58
+ buttonVariants({ variant: buttonVariant }),
59
+ "size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
60
+ defaultClassNames.button_previous
61
+ ),
62
+ button_next: cn(
63
+ buttonVariants({ variant: buttonVariant }),
64
+ "size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
65
+ defaultClassNames.button_next
66
+ ),
67
+ month_caption: cn(
68
+ "flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)",
69
+ defaultClassNames.month_caption
70
+ ),
71
+ dropdowns: cn(
72
+ "flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium",
73
+ defaultClassNames.dropdowns
74
+ ),
75
+ dropdown_root: cn(
76
+ "cn-calendar-dropdown-root relative rounded-(--cell-radius)",
77
+ defaultClassNames.dropdown_root
78
+ ),
79
+ dropdown: cn(
80
+ "absolute inset-0 bg-popover opacity-0",
81
+ defaultClassNames.dropdown
82
+ ),
83
+ caption_label: cn(
84
+ "font-medium select-none",
85
+ captionLayout === "label"
86
+ ? "cn-calendar-caption text-sm"
87
+ : "cn-calendar-caption-label flex items-center gap-1 rounded-(--cell-radius) text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground",
88
+ defaultClassNames.caption_label
89
+ ),
90
+ month_grid: cn("w-full border-collapse", defaultClassNames.month_grid),
91
+ weekdays: cn("flex", defaultClassNames.weekdays),
92
+ weekday: cn(
93
+ "flex-1 rounded-(--cell-radius) text-[0.8rem] font-normal text-muted-foreground select-none",
94
+ defaultClassNames.weekday
95
+ ),
96
+ week: cn("mt-2 flex w-full", defaultClassNames.week),
97
+ week_number_header: cn(
98
+ "w-(--cell-size) select-none",
99
+ defaultClassNames.week_number_header
100
+ ),
101
+ week_number: cn(
102
+ "text-[0.8rem] text-muted-foreground select-none",
103
+ defaultClassNames.week_number
104
+ ),
105
+ day: cn(
106
+ "group/day relative aspect-square h-full w-full rounded-(--cell-radius) p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-(--cell-radius)",
107
+ props.showWeekNumber
108
+ ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-(--cell-radius)"
109
+ : "[&:first-child[data-selected=true]_button]:rounded-l-(--cell-radius)",
110
+ defaultClassNames.day
111
+ ),
112
+ range_start: cn(
113
+ "relative isolate z-0 rounded-l-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:right-0 after:w-4 after:bg-muted",
114
+ defaultClassNames.range_start
115
+ ),
116
+ range_middle: cn("rounded-none", defaultClassNames.range_middle),
117
+ range_end: cn(
118
+ "relative isolate z-0 rounded-r-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:left-0 after:w-4 after:bg-muted",
119
+ defaultClassNames.range_end
120
+ ),
121
+ today: cn(
122
+ "rounded-(--cell-radius) bg-muted text-foreground data-[selected=true]:rounded-none",
123
+ defaultClassNames.today
124
+ ),
125
+ outside: cn(
126
+ "text-muted-foreground aria-selected:text-muted-foreground",
127
+ defaultClassNames.outside
128
+ ),
129
+ disabled: cn(
130
+ "text-muted-foreground opacity-50",
131
+ defaultClassNames.disabled
132
+ ),
133
+ hidden: cn("invisible", defaultClassNames.hidden),
134
+ ...classNames,
135
+ }}
136
+ components={{
137
+ Root: ({ className, rootRef, ...props }) => {
138
+ return (
139
+ <div
140
+ data-slot="calendar"
141
+ ref={rootRef}
142
+ className={cn(className)}
143
+ {...props}
144
+ />
145
+ )
146
+ },
147
+ Chevron: ({ className, orientation, ...props }) => {
148
+ if (orientation === "left") {
149
+ return (
150
+ <ChevronLeftIcon className={cn("cn-rtl-flip size-4", className)} {...props} />
151
+ )
152
+ }
153
+
154
+ if (orientation === "right") {
155
+ return (
156
+ <ChevronRightIcon className={cn("cn-rtl-flip size-4", className)} {...props} />
157
+ )
158
+ }
159
+
160
+ return (
161
+ <ChevronDownIcon className={cn("size-4", className)} {...props} />
162
+ )
163
+ },
164
+ DayButton: ({ ...props }) => (
165
+ <CalendarDayButton locale={locale} {...props} />
166
+ ),
167
+ WeekNumber: ({ children, ...props }) => {
168
+ return (
169
+ <td {...props}>
170
+ <div className="flex size-(--cell-size) items-center justify-center text-center">
171
+ {children}
172
+ </div>
173
+ </td>
174
+ )
175
+ },
176
+ ...components,
177
+ }}
178
+ {...props}
179
+ />
180
+ )
181
+ }
182
+
183
+ function CalendarDayButton({
184
+ className,
185
+ day,
186
+ modifiers,
187
+ locale,
188
+ ...props
189
+ }: React.ComponentProps<typeof DayButton> & { locale?: Partial<Locale> }) {
190
+ const defaultClassNames = getDefaultClassNames()
191
+
192
+ const ref = React.useRef<HTMLButtonElement>(null)
193
+ React.useEffect(() => {
194
+ if (modifiers.focused) ref.current?.focus()
195
+ }, [modifiers.focused])
196
+
197
+ return (
198
+ <Button
199
+ variant="ghost"
200
+ size="icon"
201
+ data-day={day.date.toLocaleDateString(locale?.code)}
202
+ data-selected-single={
203
+ modifiers.selected &&
204
+ !modifiers.range_start &&
205
+ !modifiers.range_end &&
206
+ !modifiers.range_middle
207
+ }
208
+ data-range-start={modifiers.range_start}
209
+ data-range-end={modifiers.range_end}
210
+ data-range-middle={modifiers.range_middle}
211
+ className={cn(
212
+ "relative isolate z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 border-0 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-(--cell-radius) data-[range-end=true]:rounded-r-(--cell-radius) data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-muted data-[range-middle=true]:text-foreground data-[range-start=true]:rounded-(--cell-radius) data-[range-start=true]:rounded-l-(--cell-radius) data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-foreground [&>span]:text-xs [&>span]:opacity-70",
213
+ defaultClassNames.day,
214
+ className
215
+ )}
216
+ {...props}
217
+ />
218
+ )
219
+ }
220
+
221
+ export { Calendar, CalendarDayButton }
@@ -0,0 +1,105 @@
1
+ // Copied by `vantage add ui card`. This file is yours to edit.
2
+ // Generated from @squadbase/vantage src/ui/card.tsx by `npm run registry` (in Vantage, edit src/, not registry/).
3
+ import * as React from "react"
4
+
5
+ import { cn } from "@squadbase/vantage/ui"
6
+
7
+ function Card({
8
+ className,
9
+ size = "default",
10
+ ...props
11
+ }: React.ComponentProps<"div"> & { size?: "default" | "sm" }) {
12
+ return (
13
+ <div
14
+ data-slot="card"
15
+ data-size={size}
16
+ className={cn(
17
+ "group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl",
18
+ className
19
+ )}
20
+ {...props}
21
+ />
22
+ )
23
+ }
24
+
25
+ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
26
+ return (
27
+ <div
28
+ data-slot="card-header"
29
+ className={cn(
30
+ "group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)",
31
+ className
32
+ )}
33
+ {...props}
34
+ />
35
+ )
36
+ }
37
+
38
+ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
39
+ return (
40
+ <div
41
+ data-slot="card-title"
42
+ className={cn(
43
+ "cn-font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
44
+ className
45
+ )}
46
+ {...props}
47
+ />
48
+ )
49
+ }
50
+
51
+ function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
52
+ return (
53
+ <div
54
+ data-slot="card-description"
55
+ className={cn("text-sm text-muted-foreground", className)}
56
+ {...props}
57
+ />
58
+ )
59
+ }
60
+
61
+ function CardAction({ className, ...props }: React.ComponentProps<"div">) {
62
+ return (
63
+ <div
64
+ data-slot="card-action"
65
+ className={cn(
66
+ "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
67
+ className
68
+ )}
69
+ {...props}
70
+ />
71
+ )
72
+ }
73
+
74
+ function CardContent({ className, ...props }: React.ComponentProps<"div">) {
75
+ return (
76
+ <div
77
+ data-slot="card-content"
78
+ className={cn("px-(--card-spacing)", className)}
79
+ {...props}
80
+ />
81
+ )
82
+ }
83
+
84
+ function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
85
+ return (
86
+ <div
87
+ data-slot="card-footer"
88
+ className={cn(
89
+ "flex items-center rounded-b-xl border-t bg-muted/50 p-(--card-spacing)",
90
+ className
91
+ )}
92
+ {...props}
93
+ />
94
+ )
95
+ }
96
+
97
+ export {
98
+ Card,
99
+ CardHeader,
100
+ CardFooter,
101
+ CardTitle,
102
+ CardAction,
103
+ CardDescription,
104
+ CardContent,
105
+ }
@@ -0,0 +1,281 @@
1
+ // Copied by `vantage add ui category-bar`. This file is yours to edit.
2
+ // Generated from @squadbase/vantage src/components/category-bar.tsx by `npm run registry` (in Vantage, edit src/, not registry/).
3
+ /**
4
+ * CategoryBar — one bar split into coloured segments by `values`, with the
5
+ * running totals underneath and an optional marker: a score against bands
6
+ * (要改善 / 標準 / 良好), budget consumption, a share breakdown. Plain HTML/CSS.
7
+ */
8
+ import { forwardRef, type ComponentProps } from "react"
9
+
10
+ import { cn } from "@squadbase/vantage/ui"
11
+ import { Tooltip, TooltipContent, TooltipTrigger } from "@squadbase/vantage/ui"
12
+ import type { ChartColor, ValueFormatter } from "@squadbase/vantage/components"
13
+
14
+ /* ---------- inlined from src/components/chart-utils.ts (internal to @squadbase/vantage) ---------- */
15
+
16
+ /** The series tokens, in palette order — the default `colors` of every typed chart. */
17
+ const DEFAULT_CHART_COLORS: readonly ChartColor[] = [
18
+ "chart-1",
19
+ "chart-2",
20
+ "chart-3",
21
+ "chart-4",
22
+ "chart-5",
23
+ ]
24
+
25
+ const TOKEN_NAME_RE = /^chart-[1-5]$/
26
+
27
+ /**
28
+ * A chart colour as a CSS value: `"chart-2"` → `var(--chart-2)` (so it follows
29
+ * light/dark on its own), anything else passes through unchanged.
30
+ */
31
+ function chartColorToCss(color: ChartColor): string {
32
+ const value = color.trim()
33
+ return TOKEN_NAME_RE.test(value) ? `var(--${value})` : value
34
+ }
35
+
36
+ /** The `i`-th colour, cycling through `colors` (the token palette when empty). */
37
+ function chartColorAt(colors: readonly ChartColor[] | undefined, i: number): ChartColor {
38
+ const palette = colors && colors.length > 0 ? colors : DEFAULT_CHART_COLORS
39
+ return palette[i % palette.length]!
40
+ }
41
+
42
+ /** `colors` extended (by cycling) to exactly `count` entries. */
43
+ function chartColorsFor(colors: readonly ChartColor[] | undefined, count: number): ChartColor[] {
44
+ return Array.from({ length: count }, (_, i) => chartColorAt(colors, i))
45
+ }
46
+
47
+ /** A translucent version of a CSS colour (works for `var(--…)` too). */
48
+ function tintCss(cssColor: string, percent: number): string {
49
+ return `color-mix(in oklab, ${cssColor} ${percent}%, transparent)`
50
+ }
51
+
52
+ const numberFormat = new Intl.NumberFormat("ja-JP", { maximumFractionDigits: 2 })
53
+
54
+ /** Default `valueFormatter`: grouped digits, up to two decimals (`1,234.5`). */
55
+ const defaultValueFormatter: ValueFormatter = (value) => numberFormat.format(value)
56
+
57
+ /**
58
+ * A data cell as a number, or `null` for a gap. Numeric strings count — SQL
59
+ * `DECIMAL` / `BIGINT` columns usually arrive as strings.
60
+ */
61
+ function toChartNumber(value: unknown): number | null {
62
+ if (typeof value === "number") return Number.isFinite(value) ? value : null
63
+ if (typeof value === "bigint") return Number(value)
64
+ if (typeof value === "string" && value.trim() !== "") {
65
+ const n = Number(value)
66
+ return Number.isFinite(n) ? n : null
67
+ }
68
+ return null
69
+ }
70
+
71
+ /** Clamp `value` into `[min, max]`. */
72
+ function clamp(value: number, min: number, max: number): number {
73
+ return Math.min(max, Math.max(min, value))
74
+ }
75
+
76
+ /* ---------------------------------------------------------------- BarList */
77
+
78
+ type BarListSortOrder = "ascending" | "descending" | "none"
79
+
80
+ /** Sort a copy of the rows by value; `"none"` keeps the given order. */
81
+ function sortBarListData<T extends { value: number }>(data: readonly T[], sortOrder: BarListSortOrder): T[] {
82
+ const rows = [...data]
83
+ if (sortOrder === "ascending") rows.sort((a, b) => a.value - b.value)
84
+ else if (sortOrder === "descending") rows.sort((a, b) => b.value - a.value)
85
+ return rows
86
+ }
87
+
88
+ /** Bar widths in percent of the largest value (at least a sliver for non-zero values). */
89
+ function barListWidths(values: readonly number[]): number[] {
90
+ const max = Math.max(0, ...values)
91
+ if (max === 0) return values.map(() => 0)
92
+ return values.map((v) => (v <= 0 ? 0 : Math.max(1, (v / max) * 100)))
93
+ }
94
+
95
+ /* ------------------------------------------------------------ CategoryBar */
96
+
97
+ interface CategoryBarSegment {
98
+ /** Width in percent of the whole bar. */
99
+ width: number
100
+ /** Where the segment starts, in percent. */
101
+ start: number
102
+ /** The running total at the segment's end — what its right-hand label shows. */
103
+ end: number
104
+ }
105
+
106
+ /** Lay the values side by side; negative values count as zero. */
107
+ function categoryBarSegments(values: readonly number[]): CategoryBarSegment[] {
108
+ const clean = values.map((v) => (Number.isFinite(v) && v > 0 ? v : 0))
109
+ const total = clean.reduce((sum, v) => sum + v, 0)
110
+ let running = 0
111
+ return clean.map((v) => {
112
+ const start = total === 0 ? 0 : (running / total) * 100
113
+ running += v
114
+ return { width: total === 0 ? 0 : (v / total) * 100, start, end: running }
115
+ })
116
+ }
117
+
118
+ interface CategoryBarLabel {
119
+ /** Position in percent of the bar. */
120
+ position: number
121
+ /** The running total printed there. */
122
+ value: number
123
+ }
124
+
125
+ /**
126
+ * Tick labels under the bar: `0` at the start, then the running total at each
127
+ * segment's end. A label closer than `minGap` percent to the one before is
128
+ * dropped so narrow segments don't print on top of each other — except the
129
+ * last one (the total), which replaces its neighbour instead.
130
+ */
131
+ function categoryBarLabels(values: readonly number[], minGap = 8): CategoryBarLabel[] {
132
+ const segments = categoryBarSegments(values).filter((s) => s.width > 0)
133
+ if (segments.length === 0) return []
134
+ const labels: CategoryBarLabel[] = [{ position: 0, value: 0 }]
135
+ segments.forEach((s, i) => {
136
+ const label = { position: s.start + s.width, value: s.end }
137
+ const prev = labels[labels.length - 1]!
138
+ if (label.position - prev.position >= minGap) labels.push(label)
139
+ else if (i === segments.length - 1 && labels.length > 1) labels[labels.length - 1] = label
140
+ })
141
+ return labels
142
+ }
143
+
144
+ /** Marker position in percent of the bar, clamped to its ends. */
145
+ function categoryBarMarkerPosition(value: number, values: readonly number[]): number {
146
+ const total = values.reduce((sum, v) => sum + (Number.isFinite(v) && v > 0 ? v : 0), 0)
147
+ if (total === 0) return 0
148
+ return clamp((value / total) * 100, 0, 100)
149
+ }
150
+
151
+ /** Index of the segment the marker sits on (the last one for a value past the end). */
152
+ function categoryBarMarkerSegment(value: number, values: readonly number[]): number {
153
+ const segments = categoryBarSegments(values)
154
+ const index = segments.findIndex((s) => s.width > 0 && value <= s.end)
155
+ if (index !== -1) return index
156
+ for (let i = segments.length - 1; i >= 0; i--) if (segments[i]!.width > 0) return i
157
+ return 0
158
+ }
159
+
160
+ /* --------------------------------------------------------- ProgressCircle */
161
+
162
+ interface ProgressCircleGeometry {
163
+ /** SVG width/height. */
164
+ size: number
165
+ /** Radius of the stroke's centre line. */
166
+ normalizedRadius: number
167
+ circumference: number
168
+ /** `stroke-dashoffset` for the value arc. */
169
+ offset: number
170
+ /** The value as a fraction of `max`, clamped to `[0, 1]`. */
171
+ ratio: number
172
+ }
173
+
174
+ function progressCircleGeometry(
175
+ value: number,
176
+ max: number,
177
+ radius: number,
178
+ strokeWidth: number,
179
+ ): ProgressCircleGeometry {
180
+ const ratio = max > 0 && Number.isFinite(value) ? clamp(value / max, 0, 1) : 0
181
+ const normalizedRadius = Math.max(0, radius - strokeWidth / 2)
182
+ const circumference = 2 * Math.PI * normalizedRadius
183
+ return { size: radius * 2, normalizedRadius, circumference, offset: circumference * (1 - ratio), ratio }
184
+ }
185
+
186
+ /* ---------- end of inlined code ---------- */
187
+
188
+ export interface CategoryBarMarker {
189
+ /** マーカーの位置(`values` の合計と同じ尺度)。 */
190
+ value: number
191
+ /** ホバーで出す説明。 */
192
+ tooltip?: string
193
+ /** 位置の変化をアニメーションする。 */
194
+ showAnimation?: boolean
195
+ }
196
+
197
+ export interface CategoryBarProps extends Omit<ComponentProps<"div">, "children"> {
198
+ /** 各区間の幅(相対値)。合計が 100 である必要はない。負の値は 0 扱い。 */
199
+ values: number[]
200
+ /** 区間の色(順に対応)。`"chart-1"`〜`"chart-5"` か CSS カラー。省略時はトークン順。 */
201
+ colors?: ChartColor[]
202
+ marker?: CategoryBarMarker
203
+ /** バーの上に区切りの累計値を出す。既定 `true`。 */
204
+ showLabels?: boolean
205
+ /** 区切りの数値の書式。 */
206
+ valueFormatter?: ValueFormatter
207
+ }
208
+
209
+ export const CategoryBar = forwardRef<HTMLDivElement, CategoryBarProps>(function CategoryBar(
210
+ { values, colors, marker, showLabels = true, valueFormatter = defaultValueFormatter, className, ...props },
211
+ ref,
212
+ ) {
213
+ const segments = categoryBarSegments(values)
214
+ const labels = showLabels ? categoryBarLabels(values) : []
215
+ const markerPosition = marker ? categoryBarMarkerPosition(marker.value, values) : 0
216
+ const markerColor = marker ? chartColorToCss(chartColorAt(colors, categoryBarMarkerSegment(marker.value, values))) : ""
217
+
218
+ const markerDot = (
219
+ <span
220
+ className="block h-4 w-1 rounded-full ring-2 ring-background"
221
+ style={{ background: markerColor }}
222
+ />
223
+ )
224
+
225
+ return (
226
+ <div ref={ref} data-slot="category-bar" className={cn("w-full", className)} {...props}>
227
+ {showLabels && labels.length > 0 && (
228
+ <div data-slot="category-bar-labels" className="relative mb-2 h-4 text-xs text-muted-foreground tabular-nums">
229
+ {labels.map((label, i) => (
230
+ <span
231
+ key={i}
232
+ className={cn(
233
+ "absolute top-0",
234
+ label.position <= 0 ? "left-0" : label.position >= 100 ? "right-0" : "-translate-x-1/2",
235
+ )}
236
+ style={label.position > 0 && label.position < 100 ? { left: `${label.position}%` } : undefined}
237
+ >
238
+ {valueFormatter(label.value)}
239
+ </span>
240
+ ))}
241
+ </div>
242
+ )}
243
+ <div className="relative flex h-2 w-full items-center">
244
+ <div className="flex h-full w-full gap-0.5 overflow-hidden rounded-full">
245
+ {segments.map((segment, i) =>
246
+ segment.width > 0 ? (
247
+ <span
248
+ key={i}
249
+ data-slot="category-bar-segment"
250
+ className="h-full"
251
+ style={{ flex: `${segment.width} 1 0%`, background: chartColorToCss(chartColorAt(colors, i)) }}
252
+ />
253
+ ) : null,
254
+ )}
255
+ </div>
256
+ {marker && (
257
+ <div
258
+ data-slot="category-bar-marker"
259
+ className={cn(
260
+ "absolute -translate-x-1/2",
261
+ marker.showAnimation && "transition-[left] duration-700 ease-out",
262
+ )}
263
+ style={{ left: `${markerPosition}%` }}
264
+ >
265
+ {marker.tooltip ? (
266
+ <Tooltip>
267
+ <TooltipTrigger render={<span aria-label={marker.tooltip} className="block py-1" />}>
268
+ {markerDot}
269
+ </TooltipTrigger>
270
+ <TooltipContent>{marker.tooltip}</TooltipContent>
271
+ </Tooltip>
272
+ ) : (
273
+ markerDot
274
+ )}
275
+ </div>
276
+ )}
277
+ </div>
278
+ </div>
279
+ )
280
+ })
281
+ CategoryBar.displayName = "CategoryBar"
@@ -0,0 +1,28 @@
1
+ // Copied by `vantage add ui checkbox`. This file is yours to edit.
2
+ // Generated from @squadbase/vantage src/ui/checkbox.tsx by `npm run registry` (in Vantage, edit src/, not registry/).
3
+ import { Checkbox as CheckboxPrimitive } from "@base-ui/react/checkbox"
4
+
5
+ import { cn } from "@squadbase/vantage/ui"
6
+ import { CheckIcon } from "lucide-react"
7
+
8
+ function Checkbox({ className, ...props }: CheckboxPrimitive.Root.Props) {
9
+ return (
10
+ <CheckboxPrimitive.Root
11
+ data-slot="checkbox"
12
+ className={cn(
13
+ "peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input transition-colors outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary",
14
+ className
15
+ )}
16
+ {...props}
17
+ >
18
+ <CheckboxPrimitive.Indicator
19
+ data-slot="checkbox-indicator"
20
+ className="grid place-content-center text-current transition-none [&>svg]:size-3.5"
21
+ >
22
+ <CheckIcon />
23
+ </CheckboxPrimitive.Indicator>
24
+ </CheckboxPrimitive.Root>
25
+ )
26
+ }
27
+
28
+ export { Checkbox }
@@ -0,0 +1,21 @@
1
+ // Copied by `vantage add ui collapsible`. This file is yours to edit.
2
+ // Generated from @squadbase/vantage src/ui/collapsible.tsx by `npm run registry` (in Vantage, edit src/, not registry/).
3
+ import { Collapsible as CollapsiblePrimitive } from "@base-ui/react/collapsible"
4
+
5
+ function Collapsible({ ...props }: CollapsiblePrimitive.Root.Props) {
6
+ return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />
7
+ }
8
+
9
+ function CollapsibleTrigger({ ...props }: CollapsiblePrimitive.Trigger.Props) {
10
+ return (
11
+ <CollapsiblePrimitive.Trigger data-slot="collapsible-trigger" {...props} />
12
+ )
13
+ }
14
+
15
+ function CollapsibleContent({ ...props }: CollapsiblePrimitive.Panel.Props) {
16
+ return (
17
+ <CollapsiblePrimitive.Panel data-slot="collapsible-content" {...props} />
18
+ )
19
+ }
20
+
21
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent }