@squadbase/vantage 0.6.2-dev1.9365dcd → 0.6.2-dev1.9d7130b

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 (230) hide show
  1. package/dist/{build-X5NVCQKT.js → build-U7GO26HR.js} +7 -7
  2. package/dist/{build-X5NVCQKT.js.map → build-U7GO26HR.js.map} +1 -1
  3. package/dist/{check-ZBIH422T.js → check-MRVAIHG5.js} +5 -5
  4. package/dist/{check-ZBIH422T.js.map → check-MRVAIHG5.js.map} +1 -1
  5. package/dist/chunk-2IAPIOPS.js +152 -0
  6. package/dist/chunk-2IAPIOPS.js.map +1 -0
  7. package/dist/chunk-3RJEOP3J.js +174 -0
  8. package/dist/chunk-3RJEOP3J.js.map +1 -0
  9. package/dist/{chunk-HKSVYMYJ.js → chunk-77CISBMG.js} +1049 -1387
  10. package/dist/chunk-77CISBMG.js.map +1 -0
  11. package/dist/{chunk-V3LF7BE7.js → chunk-ANZLVSEP.js} +4 -5
  12. package/dist/chunk-ANZLVSEP.js.map +1 -0
  13. package/dist/{chunk-XQUSGIDG.js → chunk-CKWPK4RO.js} +10 -3
  14. package/dist/chunk-CKWPK4RO.js.map +1 -0
  15. package/dist/chunk-EG4PX726.js +678 -0
  16. package/dist/chunk-EG4PX726.js.map +1 -0
  17. package/dist/{chunk-2N72FKLB.js → chunk-NZ5QIIG4.js} +33 -11
  18. package/dist/chunk-NZ5QIIG4.js.map +1 -0
  19. package/dist/{chunk-7DZGJQ3P.js → chunk-PJ4SPXHS.js} +23 -6
  20. package/dist/chunk-PJ4SPXHS.js.map +1 -0
  21. package/dist/{chunk-XPQSTZUU.js → chunk-QNOX7WLZ.js} +5 -4
  22. package/dist/chunk-QNOX7WLZ.js.map +1 -0
  23. package/dist/{chunk-PDOBHMUQ.js → chunk-ROHNXP7J.js} +72 -3
  24. package/dist/chunk-ROHNXP7J.js.map +1 -0
  25. package/dist/{chunk-CEXAQQ5W.js → chunk-S5MDTHH7.js} +180 -18
  26. package/dist/chunk-S5MDTHH7.js.map +1 -0
  27. package/dist/{chunk-2ICNHUG6.js → chunk-SDJTTMLK.js} +64 -7
  28. package/dist/chunk-SDJTTMLK.js.map +1 -0
  29. package/dist/{chunk-WAMZWZJB.js → chunk-SHZM3EXB.js} +19 -8
  30. package/dist/chunk-SHZM3EXB.js.map +1 -0
  31. package/dist/chunk-TRMHNMMZ.js +61 -0
  32. package/dist/chunk-TRMHNMMZ.js.map +1 -0
  33. package/dist/{chunk-JKLLFVEU.js → chunk-UWSQUHX6.js} +4 -99
  34. package/dist/chunk-UWSQUHX6.js.map +1 -0
  35. package/dist/cli.js +6 -6
  36. package/dist/client/index.d.ts +2 -0
  37. package/dist/client/index.js +8 -2
  38. package/dist/client/index.js.map +1 -1
  39. package/dist/components/index.d.ts +57 -273
  40. package/dist/components/index.js +6 -3
  41. package/dist/delta-text-CbrOaW83.d.ts +17 -0
  42. package/dist/{dev-4XEDTELV.js → dev-O42JFQ64.js} +7 -7
  43. package/dist/{dev-4XEDTELV.js.map → dev-O42JFQ64.js.map} +1 -1
  44. package/dist/doc/index.d.ts +215 -2
  45. package/dist/doc/index.js +422 -4
  46. package/dist/doc/index.js.map +1 -1
  47. package/dist/{doctor-5E2VEZPK.js → doctor-YD3XAAOT.js} +5 -5
  48. package/dist/{doctor-5E2VEZPK.js.map → doctor-YD3XAAOT.js.map} +1 -1
  49. package/dist/format-DihQkL1N.d.ts +249 -0
  50. package/dist/query/index.js +2 -2
  51. package/dist/{routes-3SGAFDMC.js → routes-PVKNT777.js} +4 -4
  52. package/dist/{routes-3SGAFDMC.js.map → routes-PVKNT777.js.map} +1 -1
  53. package/dist/slide/index.d.ts +272 -1
  54. package/dist/slide/index.js +1023 -2
  55. package/dist/slide/index.js.map +1 -1
  56. package/dist/table/index.js +9 -6
  57. package/dist/table/index.js.map +1 -1
  58. package/dist/ui/index.d.ts +5 -2
  59. package/dist/ui/index.js +6 -6
  60. package/dist/ui/index.js.map +1 -1
  61. package/dist/{upgrade-JHXZBGQS.js → upgrade-6DT7ADRP.js} +4 -4
  62. package/dist/{upgrade-JHXZBGQS.js.map → upgrade-6DT7ADRP.js.map} +1 -1
  63. package/dist/vite/index.js +3 -3
  64. package/docs/en/agent-skills.md +1 -1
  65. package/docs/en/changelog.md +2 -0
  66. package/docs/en/components.md +13 -2
  67. package/docs/en/doc/delta-text.md +40 -0
  68. package/docs/en/doc/doc-action-items.md +49 -0
  69. package/docs/en/doc/doc-callout.md +38 -0
  70. package/docs/en/doc/doc-data-table.md +60 -0
  71. package/docs/en/doc/doc-executive-summary.md +64 -0
  72. package/docs/en/doc/doc-figure.md +56 -0
  73. package/docs/en/doc/doc-key-findings.md +61 -0
  74. package/docs/en/doc/doc-kpi-scorecard.md +80 -0
  75. package/docs/en/doc/doc-notes-and-sources.md +43 -0
  76. package/docs/en/doc/doc-report-header.md +46 -0
  77. package/docs/en/pages-and-metadata.md +15 -0
  78. package/docs/en/parts/area-chart.md +99 -0
  79. package/docs/en/parts/bar-chart.md +91 -0
  80. package/docs/en/parts/bar-list.md +50 -0
  81. package/docs/en/parts/category-bar.md +37 -0
  82. package/docs/en/parts/chart-frame.md +39 -0
  83. package/docs/en/parts/delta.md +4 -3
  84. package/docs/en/parts/donut-chart.md +72 -0
  85. package/docs/en/parts/funnel-steps.md +2 -1
  86. package/docs/en/parts/heatmap.md +53 -0
  87. package/docs/en/parts/kpi-card.md +2 -1
  88. package/docs/en/parts/legend.md +35 -0
  89. package/docs/en/parts/line-chart.md +94 -0
  90. package/docs/en/parts/progress-circle.md +33 -0
  91. package/docs/en/parts/sample-data.md +39 -0
  92. package/docs/en/parts/scatter-chart.md +56 -0
  93. package/docs/en/parts/tracker.md +36 -0
  94. package/docs/en/parts/updated-at.md +30 -0
  95. package/docs/en/parts/waterfall-chart.md +56 -0
  96. package/docs/en/slide/slide-chart-full.md +48 -0
  97. package/docs/en/slide/slide-chart-insight.md +52 -0
  98. package/docs/en/slide/slide-columns.md +46 -0
  99. package/docs/en/slide/slide-comparison.md +68 -0
  100. package/docs/en/slide/slide-cover.md +39 -0
  101. package/docs/en/slide/slide-exec-summary.md +47 -0
  102. package/docs/en/slide/slide-heading.md +38 -0
  103. package/docs/en/slide/slide-kpi-grid.md +55 -0
  104. package/docs/en/slide/slide-kpi-hero.md +58 -0
  105. package/docs/en/slide/slide-next-actions.md +49 -0
  106. package/docs/en/slide/slide-scorecard-table.md +54 -0
  107. package/docs/en/slide/slide-section.md +44 -0
  108. package/docs/en/slide/slide-source-line.md +34 -0
  109. package/docs/en/ui/alert-dialog.md +42 -0
  110. package/docs/en/ui/avatar.md +31 -0
  111. package/docs/en/ui/combobox.md +74 -0
  112. package/docs/en/ui/drawer.md +41 -0
  113. package/docs/en/ui/empty.md +1 -1
  114. package/docs/en/ui/error-state.md +4 -3
  115. package/docs/en/ui/field.md +42 -0
  116. package/docs/en/ui/hover-card.md +21 -0
  117. package/docs/en/ui/kbd.md +17 -0
  118. package/docs/en/ui/loading.md +1 -1
  119. package/docs/en/ui/pagination.md +36 -0
  120. package/docs/en/ui/radio-group.md +21 -0
  121. package/docs/en/ui/toast.md +44 -0
  122. package/docs/en/ui/toggle-group.md +4 -3
  123. package/docs/index.json +857 -77
  124. package/docs/ja/agent-skills.md +1 -1
  125. package/docs/ja/changelog.md +2 -0
  126. package/docs/ja/components.md +12 -1
  127. package/docs/ja/doc/delta-text.md +40 -0
  128. package/docs/ja/doc/doc-action-items.md +49 -0
  129. package/docs/ja/doc/doc-callout.md +38 -0
  130. package/docs/ja/doc/doc-data-table.md +60 -0
  131. package/docs/ja/doc/doc-executive-summary.md +64 -0
  132. package/docs/ja/doc/doc-figure.md +56 -0
  133. package/docs/ja/doc/doc-key-findings.md +61 -0
  134. package/docs/ja/doc/doc-kpi-scorecard.md +80 -0
  135. package/docs/ja/doc/doc-notes-and-sources.md +43 -0
  136. package/docs/ja/doc/doc-report-header.md +46 -0
  137. package/docs/ja/page-types/slide.md +1 -0
  138. package/docs/ja/pages-and-metadata.md +15 -0
  139. package/docs/ja/parts/area-chart.md +49 -25
  140. package/docs/ja/parts/bar-chart.md +50 -24
  141. package/docs/ja/parts/bar-list.md +31 -8
  142. package/docs/ja/parts/chart-frame.md +36 -0
  143. package/docs/ja/parts/delta.md +5 -4
  144. package/docs/ja/parts/donut-chart.md +45 -26
  145. package/docs/ja/parts/funnel-steps.md +27 -8
  146. package/docs/ja/parts/heatmap.md +45 -0
  147. package/docs/ja/parts/kpi-card.md +2 -1
  148. package/docs/ja/parts/legend.md +36 -0
  149. package/docs/ja/parts/line-chart.md +48 -22
  150. package/docs/ja/parts/sample-data.md +61 -0
  151. package/docs/ja/parts/scatter-chart.md +69 -0
  152. package/docs/ja/parts/updated-at.md +27 -0
  153. package/docs/ja/parts/waterfall-chart.md +61 -0
  154. package/docs/ja/slide/slide-chart-full.md +48 -0
  155. package/docs/ja/slide/slide-chart-insight.md +52 -0
  156. package/docs/ja/slide/slide-columns.md +46 -0
  157. package/docs/ja/slide/slide-comparison.md +68 -0
  158. package/docs/ja/slide/slide-cover.md +39 -0
  159. package/docs/ja/slide/slide-exec-summary.md +47 -0
  160. package/docs/ja/slide/slide-heading.md +38 -0
  161. package/docs/ja/slide/slide-kpi-grid.md +55 -0
  162. package/docs/ja/slide/slide-kpi-hero.md +58 -0
  163. package/docs/ja/slide/slide-next-actions.md +49 -0
  164. package/docs/ja/slide/slide-scorecard-table.md +54 -0
  165. package/docs/ja/slide/slide-section.md +44 -0
  166. package/docs/ja/slide/slide-source-line.md +34 -0
  167. package/docs/ja/ui/empty.md +1 -1
  168. package/docs/ja/ui/error-state.md +4 -3
  169. package/docs/ja/ui/loading.md +1 -1
  170. package/docs/ja/ui/toggle-group.md +4 -3
  171. package/package.json +2 -2
  172. package/registry/ui/app-shell.tsx +138 -1
  173. package/registry/ui/area-chart.tsx +389 -104
  174. package/registry/ui/attention-list.tsx +177 -15
  175. package/registry/ui/bar-chart.tsx +386 -104
  176. package/registry/ui/bar-list.tsx +376 -94
  177. package/registry/ui/box-plot-chart.tsx +450 -116
  178. package/registry/ui/category-bar.tsx +292 -57
  179. package/registry/ui/chart-frame.tsx +301 -63
  180. package/registry/ui/data-table.tsx +229 -37
  181. package/registry/ui/date-range-picker.tsx +190 -36
  182. package/registry/ui/delta.tsx +181 -19
  183. package/registry/ui/donut-chart.tsx +385 -103
  184. package/registry/ui/echart.tsx +313 -58
  185. package/registry/ui/filter-bar.tsx +179 -20
  186. package/registry/ui/funnel-steps.tsx +354 -80
  187. package/registry/ui/heatmap.tsx +338 -71
  188. package/registry/ui/histogram-chart.tsx +440 -116
  189. package/registry/ui/kpi-card.tsx +254 -48
  190. package/registry/ui/legend.tsx +374 -93
  191. package/registry/ui/line-chart.tsx +389 -104
  192. package/registry/ui/multi-select.tsx +159 -9
  193. package/registry/ui/page-shell.tsx +148 -10
  194. package/registry/ui/paired-chart.tsx +394 -109
  195. package/registry/ui/progress-circle.tsx +205 -39
  196. package/registry/ui/sample-data.tsx +154 -10
  197. package/registry/ui/scatter-chart.tsx +436 -119
  198. package/registry/ui/searchable-select.tsx +145 -7
  199. package/registry/ui/slider.tsx +1 -1
  200. package/registry/ui/states.tsx +170 -13
  201. package/registry/ui/status-badge.tsx +201 -36
  202. package/registry/ui/tooltip.tsx +6 -2
  203. package/registry/ui/tracker.tsx +214 -42
  204. package/registry/ui/trend-indicator.tsx +151 -8
  205. package/registry/ui/updated-at.tsx +170 -16
  206. package/registry/ui/waterfall-chart.tsx +460 -121
  207. package/skills/vantage-add-feature/SKILL.md +5 -0
  208. package/skills/vantage-design/SKILL.md +54 -54
  209. package/skills/vantage-design/references/extract.md +26 -27
  210. package/skills/vantage-design/references/format.md +12 -172
  211. package/skills/vantage-design/references/presets.md +50 -110
  212. package/skills/vantage-pitfalls/SKILL.md +5 -0
  213. package/skills/vantage-slide/SKILL.md +54 -36
  214. package/templates/AGENTS.md +35 -18
  215. package/templates/agents/api.md +7 -0
  216. package/templates/agents/doc.md +48 -0
  217. package/templates/agents/page.md +59 -2
  218. package/templates/agents/slide.md +77 -3
  219. package/theme.css +23 -19
  220. package/dist/chunk-2ICNHUG6.js.map +0 -1
  221. package/dist/chunk-2N72FKLB.js.map +0 -1
  222. package/dist/chunk-7DZGJQ3P.js.map +0 -1
  223. package/dist/chunk-CEXAQQ5W.js.map +0 -1
  224. package/dist/chunk-HKSVYMYJ.js.map +0 -1
  225. package/dist/chunk-JKLLFVEU.js.map +0 -1
  226. package/dist/chunk-PDOBHMUQ.js.map +0 -1
  227. package/dist/chunk-V3LF7BE7.js.map +0 -1
  228. package/dist/chunk-WAMZWZJB.js.map +0 -1
  229. package/dist/chunk-XPQSTZUU.js.map +0 -1
  230. package/dist/chunk-XQUSGIDG.js.map +0 -1
@@ -24,6 +24,140 @@ import { Checkbox } from "@squadbase/vantage/ui"
24
24
  import { Popover, PopoverContent, PopoverTrigger } from "@squadbase/vantage/ui"
25
25
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@squadbase/vantage/ui"
26
26
  import type { FilterConfig, FilterOption, FilterValues } from "@squadbase/vantage/components"
27
+ import { useSyncExternalStore } from "react"
28
+
29
+ /* ---------- inlined from @squadbase/squadkit registry/lib/locale.ts (internal to @squadbase/vantage) ---------- */
30
+
31
+ /**
32
+ * The display language of the parts and the defaults that follow it.
33
+ *
34
+ * The language comes from `<html lang>`: a tag starting with `ja` reads Japanese, anything else English.
35
+ * Without a usable `lang` (missing, invalid, or no `document` — SSR, Node) the locale is `FALLBACK_LOCALE`
36
+ * (`en-US`). A `locale` passed explicitly (a prop, an argument) always wins.
37
+ *
38
+ * Parts read the locale through `useLocale` (`hooks/use-locale`) and pass it down; the pure helpers here
39
+ * and in `format` / `comparison` / `chart-*` take it as an argument and fall back to `documentLocale()`.
40
+ */
41
+
42
+ /** The language of the built-in wording: Japanese or English. */
43
+ type UiLanguage = "ja" | "en"
44
+
45
+ /** The locale used when `<html lang>` gives none (and on the server). */
46
+ const FALLBACK_LOCALE = "en-US"
47
+
48
+ /** `"ja"` when `locale` starts with `ja` (`ja`, `ja-JP`), else `"en"`. A missing locale is `"en"`. */
49
+ function uiLanguage(locale: string | null | undefined): UiLanguage {
50
+ return typeof locale === "string" && locale.trim().toLowerCase().startsWith("ja") ? "ja" : "en"
51
+ }
52
+
53
+ /** A BCP 47 tag in its canonical form (`en-gb` → `en-GB`), or `FALLBACK_LOCALE` when it is empty or invalid. */
54
+ function normalizeLocale(tag: string | null | undefined): string {
55
+ const value = tag?.trim()
56
+ if (!value) return FALLBACK_LOCALE
57
+ try {
58
+ return Intl.getCanonicalLocales(value)[0] ?? FALLBACK_LOCALE
59
+ } catch {
60
+ return FALLBACK_LOCALE
61
+ }
62
+ }
63
+
64
+ /**
65
+ * The locale of the page: `document.documentElement.lang`, canonicalized. `FALLBACK_LOCALE` when it is empty or
66
+ * invalid, or there is no `document`. Parts read it through `useLocale`, never while rendering.
67
+ */
68
+ function documentLocale(): string {
69
+ if (typeof document === "undefined") return FALLBACK_LOCALE
70
+ return normalizeLocale(document.documentElement?.getAttribute("lang"))
71
+ }
72
+
73
+ /** `locale` when given, else the page's locale (`documentLocale()`). */
74
+ function resolveLocale(locale?: string | null): string {
75
+ return locale || documentLocale()
76
+ }
77
+
78
+ /** Picks the wording table of the locale's language. */
79
+ function pickLocale<T>(table: { ja: T; en: T }, locale?: string | null): T {
80
+ return table[uiLanguage(resolveLocale(locale))]
81
+ }
82
+
83
+ /** The currency `format="currency"` uses without a `currency`: JPY for Japanese, USD otherwise. */
84
+ function defaultCurrency(locale?: string | null): string {
85
+ return uiLanguage(resolveLocale(locale)) === "ja" ? "JPY" : "USD"
86
+ }
87
+
88
+ /** The month a fiscal year starts in (1–12) when none is given: April for Japanese, January otherwise. */
89
+ function defaultFiscalYearStartMonth(locale?: string | null): number {
90
+ return uiLanguage(resolveLocale(locale)) === "ja" ? 4 : 1
91
+ }
92
+
93
+ /** A day of the week, 0 = Sunday … 6 = Saturday (the `Date#getDay` / date-fns numbering). */
94
+ type WeekDay = 0 | 1 | 2 | 3 | 4 | 5 | 6
95
+
96
+ /** Locales whose week starts on Sunday when the runtime has no week data. */
97
+ const SUNDAY_FIRST = new Set(["en", "en-US", "en-CA"])
98
+
99
+ /**
100
+ * The first day of the week: Monday for Japanese; otherwise the locale's convention from `Intl.Locale`
101
+ * (`en-US` Sunday, `en-GB` Monday). Without week data in the runtime: Sunday for `en` / `en-US` / `en-CA`,
102
+ * Monday for the rest.
103
+ */
104
+ function weekStartsOn(locale?: string | null): WeekDay {
105
+ const tag = normalizeLocale(resolveLocale(locale))
106
+ if (uiLanguage(tag) === "ja") return 1
107
+ try {
108
+ const info = new Intl.Locale(tag) as Intl.Locale & {
109
+ getWeekInfo?: () => { firstDay: number }
110
+ weekInfo?: { firstDay: number }
111
+ }
112
+ const firstDay = info.getWeekInfo?.().firstDay ?? info.weekInfo?.firstDay
113
+ if (typeof firstDay === "number" && firstDay >= 1 && firstDay <= 7) return (firstDay % 7) as WeekDay
114
+ } catch {
115
+ // Fall through to the table below.
116
+ }
117
+ return SUNDAY_FIRST.has(tag) ? 0 : 1
118
+ }
119
+
120
+ /* ---------- inlined from @squadbase/squadkit registry/hooks/use-locale.ts (internal to @squadbase/vantage) ---------- */
121
+
122
+ const listeners = new Set<() => void>()
123
+ let observer: MutationObserver | null = null
124
+
125
+ /** One observer on `<html lang>` for every subscribed part. */
126
+ function subscribe(onChange: () => void): () => void {
127
+ if (typeof document === "undefined" || typeof MutationObserver === "undefined") return () => {}
128
+ listeners.add(onChange)
129
+ if (!observer) {
130
+ observer = new MutationObserver(() => {
131
+ for (const listener of [...listeners]) listener()
132
+ })
133
+ observer.observe(document.documentElement, { attributes: true, attributeFilter: ["lang"] })
134
+ }
135
+ return () => {
136
+ listeners.delete(onChange)
137
+ if (listeners.size === 0 && observer) {
138
+ observer.disconnect()
139
+ observer = null
140
+ }
141
+ }
142
+ }
143
+
144
+ const serverLocale = () => FALLBACK_LOCALE
145
+
146
+ /**
147
+ * The page's locale (`<html lang>`), following changes made while the page runs. On the server and during
148
+ * hydration it is `FALLBACK_LOCALE` (`en-US`), so the markup matches; it switches right after.
149
+ */
150
+ function useDocumentLocale(): string {
151
+ return useSyncExternalStore(subscribe, documentLocale, serverLocale)
152
+ }
153
+
154
+ /** The locale a part renders in: its `locale` prop when given, else the page's (`useDocumentLocale`). */
155
+ function useLocale(locale?: string | null): string {
156
+ const page = useDocumentLocale()
157
+ return locale || page
158
+ }
159
+
160
+ /* ---------- end of inlined code ---------- */
27
161
 
28
162
  /* --------------------------------------------------------------- context */
29
163
 
@@ -38,6 +172,25 @@ interface FilterBarContextValue {
38
172
 
39
173
  const FilterBarContext = createContext<FilterBarContextValue | null>(null)
40
174
 
175
+ const TEXT = {
176
+ ja: {
177
+ filters: "フィルター",
178
+ selected: (count: number) => ` (${count}件選択中)`,
179
+ remove: (filter: string, option: string) => `${filter}: ${option} を削除`,
180
+ clear: "クリア",
181
+ clearAll: "すべてのフィルターをクリア",
182
+ },
183
+ en: {
184
+ filters: "Filters",
185
+ selected: (count: number) => ` (${count} selected)`,
186
+ remove: (filter: string, option: string) => `Remove ${filter}: ${option}`,
187
+ clear: "Clear",
188
+ clearAll: "Clear all filters",
189
+ },
190
+ }
191
+
192
+ const useText = () => TEXT[uiLanguage(useLocale())]
193
+
41
194
  function useFilterBar(): FilterBarContextValue {
42
195
  const ctx = useContext(FilterBarContext)
43
196
  if (!ctx) throw new Error("useFilterBar must be used within <FilterBar>")
@@ -55,20 +208,23 @@ export interface FilterBarProps extends Omit<HTMLAttributes<HTMLDivElement>, "on
55
208
  }
56
209
 
57
210
  export const FilterBar = forwardRef<HTMLDivElement, FilterBarProps>(
58
- ({ value, onChange, onClear, className, children, ...props }, ref) => (
59
- <FilterBarContext.Provider value={{ value, onChange, onClear }}>
60
- <div
61
- ref={ref}
62
- role="search"
63
- aria-label="フィルター"
64
- data-slot="filter-bar"
65
- className={cn("flex flex-wrap items-center gap-2", className)}
66
- {...props}
67
- >
68
- {children}
69
- </div>
70
- </FilterBarContext.Provider>
71
- ),
211
+ ({ value, onChange, onClear, className, children, ...props }, ref) => {
212
+ const t = useText()
213
+ return (
214
+ <FilterBarContext.Provider value={{ value, onChange, onClear }}>
215
+ <div
216
+ ref={ref}
217
+ role="search"
218
+ aria-label={t.filters}
219
+ data-slot="filter-bar"
220
+ className={cn("flex flex-wrap items-center gap-2", className)}
221
+ {...props}
222
+ >
223
+ {children}
224
+ </div>
225
+ </FilterBarContext.Provider>
226
+ )
227
+ },
72
228
  )
73
229
  FilterBar.displayName = "FilterBar"
74
230
 
@@ -151,6 +307,7 @@ export function FilterBarMultiSelect({
151
307
  className,
152
308
  }: FilterBarMultiSelectProps) {
153
309
  const { value, onChange } = useFilterBar()
310
+ const t = useText()
154
311
  const selected = (value[filterKey] as string[] | undefined) ?? []
155
312
 
156
313
  const handleToggle = (option: string) => {
@@ -165,7 +322,7 @@ export function FilterBarMultiSelect({
165
322
  <Popover>
166
323
  <PopoverTrigger
167
324
  render={<Button variant="outline" size="sm" className={cn("h-8 gap-1", className)} />}
168
- aria-label={`${placeholder ?? label}${selected.length > 0 ? ` (${selected.length}件選択中)` : ""}`}
325
+ aria-label={`${placeholder ?? label}${selected.length > 0 ? t.selected(selected.length) : ""}`}
169
326
  data-slot="filter-bar-multi-select"
170
327
  >
171
328
  {placeholder ?? label}
@@ -216,6 +373,7 @@ interface ActiveChip {
216
373
 
217
374
  export function FilterBarActiveChips({ filters, className }: FilterBarActiveChipsProps) {
218
375
  const { value, onChange } = useFilterBar()
376
+ const t = useText()
219
377
 
220
378
  const getActiveChips = (): ActiveChip[] => {
221
379
  const chips: ActiveChip[] = []
@@ -293,7 +451,7 @@ export function FilterBarActiveChips({ filters, className }: FilterBarActiveChip
293
451
  type="button"
294
452
  className="ml-0.5 rounded-full p-0.5 hover:bg-muted-foreground/20"
295
453
  onClick={() => handleRemoveFilter(chip.key, chip.optionValue)}
296
- aria-label={`${chip.filterLabel}: ${chip.optionLabel} を削除`}
454
+ aria-label={t.remove(chip.filterLabel, chip.optionLabel)}
297
455
  >
298
456
  <X className="size-3" aria-hidden="true" />
299
457
  </button>
@@ -307,13 +465,14 @@ FilterBarActiveChips.displayName = "FilterBarActiveChips"
307
465
  /* ----------------------------------------------------------- clear button */
308
466
 
309
467
  export interface FilterBarClearButtonProps {
310
- /** Override the button label. Defaults to "クリア". */
468
+ /** Override the button label. Defaults to "Clear" (ja: "クリア"). */
311
469
  label?: string
312
470
  className?: string
313
471
  }
314
472
 
315
- export function FilterBarClearButton({ label = "クリア", className }: FilterBarClearButtonProps) {
473
+ export function FilterBarClearButton({ label, className }: FilterBarClearButtonProps) {
316
474
  const { value, onClear } = useFilterBar()
475
+ const t = useText()
317
476
  const hasActiveFilters = Object.values(value).some((v) =>
318
477
  Array.isArray(v) ? v.length > 0 : v !== undefined && v !== "",
319
478
  )
@@ -325,10 +484,10 @@ export function FilterBarClearButton({ label = "クリア", className }: FilterB
325
484
  size="sm"
326
485
  className={cn("h-7 px-2 text-xs", className)}
327
486
  onClick={onClear}
328
- aria-label="すべてのフィルターをクリア"
487
+ aria-label={t.clearAll}
329
488
  data-slot="filter-bar-clear-button"
330
489
  >
331
- {label}
490
+ {label ?? t.clear}
332
491
  </Button>
333
492
  )
334
493
  }