@handled-ai/design-system 0.8.0 → 0.9.0

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 (336) hide show
  1. package/README.md +14 -4
  2. package/dist/charts/bar-chart-component.d.ts +24 -0
  3. package/dist/charts/bar-chart-component.js +123 -0
  4. package/dist/charts/bar-chart-component.js.map +1 -0
  5. package/dist/charts/chart-tooltip.d.ts +26 -0
  6. package/dist/charts/chart-tooltip.js +69 -0
  7. package/dist/charts/chart-tooltip.js.map +1 -0
  8. package/dist/charts/chart.d.ts +64 -0
  9. package/dist/charts/chart.js +285 -0
  10. package/dist/charts/chart.js.map +1 -0
  11. package/dist/charts/donut-chart.d.ts +21 -0
  12. package/dist/charts/donut-chart.js +96 -0
  13. package/dist/charts/donut-chart.js.map +1 -0
  14. package/dist/charts/index.d.ts +11 -0
  15. package/dist/charts/index.js +10 -0
  16. package/dist/charts/index.js.map +1 -0
  17. package/dist/charts/pipeline-overview.d.ts +76 -0
  18. package/dist/charts/pipeline-overview.js +372 -0
  19. package/dist/charts/pipeline-overview.js.map +1 -0
  20. package/dist/charts/sankey-chart.d.ts +52 -0
  21. package/dist/charts/sankey-chart.js +219 -0
  22. package/dist/charts/sankey-chart.js.map +1 -0
  23. package/dist/charts/top-line-metrics.d.ts +26 -0
  24. package/dist/charts/top-line-metrics.js +224 -0
  25. package/dist/charts/top-line-metrics.js.map +1 -0
  26. package/dist/charts/trend-area-chart.d.ts +21 -0
  27. package/dist/charts/trend-area-chart.js +150 -0
  28. package/dist/charts/trend-area-chart.js.map +1 -0
  29. package/dist/charts/volume-analysis-chart.d.ts +19 -0
  30. package/dist/charts/volume-analysis-chart.js +121 -0
  31. package/dist/charts/volume-analysis-chart.js.map +1 -0
  32. package/dist/components/activity-detail.d.ts +38 -0
  33. package/dist/components/activity-detail.js +163 -0
  34. package/dist/components/activity-detail.js.map +1 -0
  35. package/dist/components/activity-log.d.ts +21 -0
  36. package/dist/components/activity-log.js +61 -0
  37. package/dist/components/activity-log.js.map +1 -0
  38. package/dist/components/agent-popover.d.ts +71 -0
  39. package/dist/components/agent-popover.js +282 -0
  40. package/dist/components/agent-popover.js.map +1 -0
  41. package/dist/components/agent-widget.d.ts +24 -0
  42. package/dist/components/agent-widget.js +117 -0
  43. package/dist/components/agent-widget.js.map +1 -0
  44. package/dist/components/avatar.d.ts +13 -0
  45. package/dist/components/avatar.js +140 -0
  46. package/dist/components/avatar.js.map +1 -0
  47. package/dist/components/badge.d.ts +12 -0
  48. package/dist/components/badge.js +75 -0
  49. package/dist/components/badge.js.map +1 -0
  50. package/dist/components/button.d.ts +13 -0
  51. package/dist/components/button.js +83 -0
  52. package/dist/components/button.js.map +1 -0
  53. package/dist/components/card.d.ts +11 -0
  54. package/dist/components/card.js +119 -0
  55. package/dist/components/card.js.map +1 -0
  56. package/dist/components/contact-list.d.ts +34 -0
  57. package/dist/components/contact-list.js +84 -0
  58. package/dist/components/contact-list.js.map +1 -0
  59. package/dist/components/dashboard-cards.d.ts +10 -0
  60. package/dist/components/dashboard-cards.js +164 -0
  61. package/dist/components/dashboard-cards.js.map +1 -0
  62. package/dist/components/data-table-display.d.ts +19 -0
  63. package/dist/components/data-table-display.js +109 -0
  64. package/dist/components/data-table-display.js.map +1 -0
  65. package/dist/components/data-table-filter.d.ts +18 -0
  66. package/dist/components/data-table-filter.js +107 -0
  67. package/dist/components/data-table-filter.js.map +1 -0
  68. package/dist/components/data-table-quick-views.d.ts +13 -0
  69. package/dist/components/data-table-quick-views.js +90 -0
  70. package/dist/components/data-table-quick-views.js.map +1 -0
  71. package/dist/components/data-table-toolbar.d.ts +18 -0
  72. package/dist/components/data-table-toolbar.js +45 -0
  73. package/dist/components/data-table-toolbar.js.map +1 -0
  74. package/dist/components/data-table.d.ts +39 -0
  75. package/dist/components/data-table.js +821 -0
  76. package/dist/components/data-table.js.map +1 -0
  77. package/dist/components/detail-view.d.ts +44 -0
  78. package/dist/components/detail-view.js +165 -0
  79. package/dist/components/detail-view.js.map +1 -0
  80. package/dist/components/dialog.d.ts +19 -0
  81. package/dist/components/dialog.js +188 -0
  82. package/dist/components/dialog.js.map +1 -0
  83. package/dist/components/dropdown-menu.d.ts +27 -0
  84. package/dist/components/dropdown-menu.js +279 -0
  85. package/dist/components/dropdown-menu.js.map +1 -0
  86. package/dist/components/entity-panel.d.ts +69 -0
  87. package/dist/components/entity-panel.js +584 -0
  88. package/dist/components/entity-panel.js.map +1 -0
  89. package/dist/components/inbox-row.d.ts +27 -0
  90. package/dist/components/inbox-row.js +139 -0
  91. package/dist/components/inbox-row.js.map +1 -0
  92. package/dist/components/inbox-toolbar.d.ts +21 -0
  93. package/dist/components/inbox-toolbar.js +203 -0
  94. package/dist/components/inbox-toolbar.js.map +1 -0
  95. package/dist/components/input.d.ts +5 -0
  96. package/dist/components/input.js +50 -0
  97. package/dist/components/input.js.map +1 -0
  98. package/dist/components/insights-filter-bar.d.ts +21 -0
  99. package/dist/components/insights-filter-bar.js +99 -0
  100. package/dist/components/insights-filter-bar.js.map +1 -0
  101. package/dist/components/item-list-display.d.ts +22 -0
  102. package/dist/components/item-list-display.js +240 -0
  103. package/dist/components/item-list-display.js.map +1 -0
  104. package/dist/components/item-list-filter.d.ts +16 -0
  105. package/dist/components/item-list-filter.js +87 -0
  106. package/dist/components/item-list-filter.js.map +1 -0
  107. package/dist/components/item-list-toolbar.d.ts +25 -0
  108. package/dist/components/item-list-toolbar.js +79 -0
  109. package/dist/components/item-list-toolbar.js.map +1 -0
  110. package/dist/components/item-list.d.ts +20 -0
  111. package/dist/components/item-list.js +702 -0
  112. package/dist/components/item-list.js.map +1 -0
  113. package/dist/components/label.d.ts +6 -0
  114. package/dist/components/label.js +55 -0
  115. package/dist/components/label.js.map +1 -0
  116. package/dist/components/message.d.ts +23 -0
  117. package/dist/components/message.js +117 -0
  118. package/dist/components/message.js.map +1 -0
  119. package/dist/components/metric-card.d.ts +25 -0
  120. package/dist/components/metric-card.js +107 -0
  121. package/dist/components/metric-card.js.map +1 -0
  122. package/dist/components/performance-metrics-table.d.ts +38 -0
  123. package/dist/components/performance-metrics-table.js +342 -0
  124. package/dist/components/performance-metrics-table.js.map +1 -0
  125. package/dist/components/preview-list.d.ts +14 -0
  126. package/dist/components/preview-list.js +83 -0
  127. package/dist/components/preview-list.js.map +1 -0
  128. package/dist/components/progress.d.ts +6 -0
  129. package/dist/components/progress.js +69 -0
  130. package/dist/components/progress.js.map +1 -0
  131. package/dist/components/quick-action-chat-area.d.ts +24 -0
  132. package/dist/components/quick-action-chat-area.js +178 -0
  133. package/dist/components/quick-action-chat-area.js.map +1 -0
  134. package/dist/components/quick-action-modal.d.ts +30 -0
  135. package/dist/components/quick-action-modal.js +288 -0
  136. package/dist/components/quick-action-modal.js.map +1 -0
  137. package/dist/components/quick-action-sidebar-nav.d.ts +51 -0
  138. package/dist/components/quick-action-sidebar-nav.js +528 -0
  139. package/dist/components/quick-action-sidebar-nav.js.map +1 -0
  140. package/dist/components/recommended-actions-section.d.ts +23 -0
  141. package/dist/components/recommended-actions-section.js +215 -0
  142. package/dist/components/recommended-actions-section.js.map +1 -0
  143. package/dist/components/report-card.d.ts +26 -0
  144. package/dist/components/report-card.js +69 -0
  145. package/dist/components/report-card.js.map +1 -0
  146. package/dist/components/score-analysis-modal.d.ts +26 -0
  147. package/dist/components/score-analysis-modal.js +141 -0
  148. package/dist/components/score-analysis-modal.js.map +1 -0
  149. package/dist/components/score-breakdown.d.ts +17 -0
  150. package/dist/components/score-breakdown.js +162 -0
  151. package/dist/components/score-breakdown.js.map +1 -0
  152. package/dist/components/score-feedback.d.ts +40 -0
  153. package/dist/components/score-feedback.js +209 -0
  154. package/dist/components/score-feedback.js.map +1 -0
  155. package/dist/components/score-ring.d.ts +14 -0
  156. package/dist/components/score-ring.js +79 -0
  157. package/dist/components/score-ring.js.map +1 -0
  158. package/dist/components/scroll-area.d.ts +7 -0
  159. package/dist/components/scroll-area.js +101 -0
  160. package/dist/components/scroll-area.js.map +1 -0
  161. package/dist/components/select.d.ts +17 -0
  162. package/dist/components/select.js +228 -0
  163. package/dist/components/select.js.map +1 -0
  164. package/dist/components/separator.d.ts +6 -0
  165. package/dist/components/separator.js +61 -0
  166. package/dist/components/separator.js.map +1 -0
  167. package/dist/components/sheet.d.ts +16 -0
  168. package/dist/components/sheet.js +168 -0
  169. package/dist/components/sheet.js.map +1 -0
  170. package/dist/components/sidebar.d.ts +73 -0
  171. package/dist/components/sidebar.js +723 -0
  172. package/dist/components/sidebar.js.map +1 -0
  173. package/dist/components/signal-feedback-inline.d.ts +51 -0
  174. package/dist/components/signal-feedback-inline.js +548 -0
  175. package/dist/components/signal-feedback-inline.js.map +1 -0
  176. package/dist/components/simple-data-table.d.ts +15 -0
  177. package/dist/components/simple-data-table.js +91 -0
  178. package/dist/components/simple-data-table.js.map +1 -0
  179. package/dist/components/skeleton.d.ts +5 -0
  180. package/dist/components/skeleton.js +44 -0
  181. package/dist/components/skeleton.js.map +1 -0
  182. package/dist/components/status-badge.d.ts +10 -0
  183. package/dist/components/status-badge.js +82 -0
  184. package/dist/components/status-badge.js.map +1 -0
  185. package/dist/components/styled-bar-list.d.ts +20 -0
  186. package/dist/components/styled-bar-list.js +59 -0
  187. package/dist/components/styled-bar-list.js.map +1 -0
  188. package/dist/components/suggested-actions.d.ts +110 -0
  189. package/dist/components/suggested-actions.js +1538 -0
  190. package/dist/components/suggested-actions.js.map +1 -0
  191. package/dist/components/table.d.ts +12 -0
  192. package/dist/components/table.js +147 -0
  193. package/dist/components/table.js.map +1 -0
  194. package/dist/components/tabs.d.ts +14 -0
  195. package/dist/components/tabs.js +129 -0
  196. package/dist/components/tabs.js.map +1 -0
  197. package/dist/components/textarea.d.ts +5 -0
  198. package/dist/components/textarea.js +47 -0
  199. package/dist/components/textarea.js.map +1 -0
  200. package/dist/components/timeline-activity.d.ts +34 -0
  201. package/dist/components/timeline-activity.js +181 -0
  202. package/dist/components/timeline-activity.js.map +1 -0
  203. package/dist/components/tooltip.d.ts +9 -0
  204. package/dist/components/tooltip.js +93 -0
  205. package/dist/components/tooltip.js.map +1 -0
  206. package/dist/components/view-mode-toggle.d.ts +16 -0
  207. package/dist/components/view-mode-toggle.js +24 -0
  208. package/dist/components/view-mode-toggle.js.map +1 -0
  209. package/dist/hooks/use-mobile.d.ts +3 -0
  210. package/dist/hooks/use-mobile.js +21 -0
  211. package/dist/hooks/use-mobile.js.map +1 -0
  212. package/dist/index.d.ts +68 -1878
  213. package/dist/index.js +69 -10918
  214. package/dist/index.js.map +1 -1
  215. package/dist/lib/icons.d.ts +18 -0
  216. package/dist/lib/icons.js +21 -0
  217. package/dist/lib/icons.js.map +1 -0
  218. package/dist/lib/utils.d.ts +5 -0
  219. package/dist/lib/utils.js +9 -0
  220. package/dist/lib/utils.js.map +1 -0
  221. package/dist/prototype/index.d.ts +20 -0
  222. package/dist/prototype/index.js +8 -0
  223. package/dist/prototype/index.js.map +1 -0
  224. package/dist/prototype/prototype-accounts-view.d.ts +22 -0
  225. package/dist/prototype/prototype-accounts-view.js +70 -0
  226. package/dist/prototype/prototype-accounts-view.js.map +1 -0
  227. package/dist/prototype/prototype-admin-view.d.ts +21 -0
  228. package/dist/prototype/prototype-admin-view.js +53 -0
  229. package/dist/prototype/prototype-admin-view.js.map +1 -0
  230. package/dist/prototype/prototype-config.d.ts +226 -0
  231. package/dist/prototype/prototype-config.js +1 -0
  232. package/dist/prototype/prototype-config.js.map +1 -0
  233. package/dist/prototype/prototype-inbox-view.d.ts +48 -0
  234. package/dist/prototype/prototype-inbox-view.js +701 -0
  235. package/dist/prototype/prototype-inbox-view.js.map +1 -0
  236. package/dist/prototype/prototype-insights-view.d.ts +23 -0
  237. package/dist/prototype/prototype-insights-view.js +335 -0
  238. package/dist/prototype/prototype-insights-view.js.map +1 -0
  239. package/dist/prototype/prototype-shell.d.ts +40 -0
  240. package/dist/prototype/prototype-shell.js +190 -0
  241. package/dist/prototype/prototype-shell.js.map +1 -0
  242. package/dist/prototype/prototype-work-queue-view.d.ts +8 -0
  243. package/dist/prototype/prototype-work-queue-view.js +17 -0
  244. package/dist/prototype/prototype-work-queue-view.js.map +1 -0
  245. package/dist/three/agent-orb.d.ts +39 -0
  246. package/dist/three/agent-orb.js +500 -0
  247. package/dist/three/agent-orb.js.map +1 -0
  248. package/dist/three/index.d.ts +2 -0
  249. package/dist/three/index.js +2 -0
  250. package/dist/three/index.js.map +1 -0
  251. package/package.json +98 -17
  252. package/src/charts/bar-chart-component.tsx +150 -0
  253. package/src/charts/chart-tooltip.tsx +86 -0
  254. package/src/charts/chart.tsx +371 -0
  255. package/src/charts/donut-chart.tsx +112 -0
  256. package/src/charts/index.ts +13 -0
  257. package/src/charts/pipeline-overview.tsx +476 -0
  258. package/src/charts/sankey-chart.tsx +290 -0
  259. package/src/charts/top-line-metrics.tsx +261 -0
  260. package/src/charts/trend-area-chart.tsx +150 -0
  261. package/src/charts/volume-analysis-chart.tsx +124 -0
  262. package/src/components/activity-detail.tsx +233 -0
  263. package/src/components/activity-log.tsx +89 -0
  264. package/src/components/agent-popover.tsx +373 -0
  265. package/src/components/agent-widget.tsx +163 -0
  266. package/src/components/avatar.tsx +109 -0
  267. package/src/components/badge.tsx +48 -0
  268. package/src/components/button.tsx +59 -0
  269. package/src/components/card.tsx +92 -0
  270. package/src/components/contact-list.tsx +121 -0
  271. package/src/components/dashboard-cards.tsx +170 -0
  272. package/src/components/data-table-display.tsx +139 -0
  273. package/src/components/data-table-filter.tsx +138 -0
  274. package/src/components/data-table-quick-views.tsx +103 -0
  275. package/src/components/data-table-toolbar.tsx +56 -0
  276. package/src/components/data-table.tsx +915 -0
  277. package/src/components/detail-view.tsx +237 -0
  278. package/src/components/dialog.tsx +158 -0
  279. package/src/components/dropdown-menu.tsx +257 -0
  280. package/src/components/entity-panel.tsx +767 -0
  281. package/src/components/inbox-row.tsx +132 -0
  282. package/src/components/inbox-toolbar.tsx +213 -0
  283. package/src/components/input.tsx +21 -0
  284. package/src/components/insights-filter-bar.tsx +132 -0
  285. package/src/components/item-list-display.tsx +278 -0
  286. package/src/components/item-list-filter.tsx +118 -0
  287. package/src/components/item-list-toolbar.tsx +97 -0
  288. package/src/components/item-list.tsx +843 -0
  289. package/src/components/label.tsx +24 -0
  290. package/src/components/message.tsx +83 -0
  291. package/src/components/metric-card.tsx +178 -0
  292. package/src/components/performance-metrics-table.tsx +442 -0
  293. package/src/components/preview-list.tsx +62 -0
  294. package/src/components/progress.tsx +31 -0
  295. package/src/components/quick-action-chat-area.tsx +156 -0
  296. package/src/components/quick-action-modal.tsx +331 -0
  297. package/src/components/quick-action-sidebar-nav.tsx +592 -0
  298. package/src/components/recommended-actions-section.tsx +258 -0
  299. package/src/components/report-card.tsx +106 -0
  300. package/src/components/score-analysis-modal.tsx +172 -0
  301. package/src/components/score-breakdown.tsx +179 -0
  302. package/src/components/score-feedback.tsx +288 -0
  303. package/src/components/score-ring.tsx +87 -0
  304. package/src/components/scroll-area.tsx +58 -0
  305. package/src/components/select.tsx +190 -0
  306. package/src/components/separator.tsx +28 -0
  307. package/src/components/sheet.tsx +143 -0
  308. package/src/components/sidebar.tsx +726 -0
  309. package/src/components/signal-feedback-inline.tsx +591 -0
  310. package/src/components/simple-data-table.tsx +124 -0
  311. package/src/components/skeleton.tsx +15 -0
  312. package/src/components/status-badge.tsx +63 -0
  313. package/src/components/styled-bar-list.tsx +70 -0
  314. package/src/components/suggested-actions.tsx +1985 -0
  315. package/src/components/table.tsx +116 -0
  316. package/src/components/tabs.tsx +91 -0
  317. package/src/components/textarea.tsx +18 -0
  318. package/src/components/timeline-activity.tsx +234 -0
  319. package/src/components/tooltip.tsx +57 -0
  320. package/src/components/view-mode-toggle.tsx +39 -0
  321. package/src/hooks/use-mobile.ts +21 -0
  322. package/src/index.ts +77 -0
  323. package/src/lib/icons.ts +18 -0
  324. package/src/lib/utils.ts +6 -0
  325. package/src/prototype/index.ts +11 -0
  326. package/src/prototype/prototype-accounts-view.tsx +112 -0
  327. package/src/prototype/prototype-admin-view.tsx +67 -0
  328. package/src/prototype/prototype-config.ts +243 -0
  329. package/src/prototype/prototype-inbox-view.tsx +810 -0
  330. package/src/prototype/prototype-insights-view.tsx +379 -0
  331. package/src/prototype/prototype-shell.tsx +219 -0
  332. package/src/prototype/prototype-work-queue-view.tsx +30 -0
  333. package/src/styles/globals.css +299 -0
  334. package/src/three/agent-orb.tsx +557 -0
  335. package/src/three/index.ts +5 -0
  336. package/src/types/r3f.d.ts +8 -0
@@ -0,0 +1,138 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { ListFilter, Search } from "lucide-react"
5
+
6
+ import { Button } from "./button"
7
+ import {
8
+ DropdownMenu,
9
+ DropdownMenuContent,
10
+ DropdownMenuItem,
11
+ DropdownMenuSub,
12
+ DropdownMenuSubContent,
13
+ DropdownMenuSubTrigger,
14
+ DropdownMenuTrigger,
15
+ } from "./dropdown-menu"
16
+
17
+ export interface DataTableFilterCategory {
18
+ id: string
19
+ label: string
20
+ icon: React.ComponentType<{ className?: string }>
21
+ options: string[]
22
+ }
23
+
24
+ interface DataTableFilterProps {
25
+ categories: DataTableFilterCategory[]
26
+ selectedFilters: Record<string, string[]>
27
+ onToggleFilter: (categoryId: string, option: string) => void
28
+ }
29
+
30
+ export function DataTableFilter({
31
+ categories,
32
+ selectedFilters,
33
+ onToggleFilter,
34
+ }: DataTableFilterProps) {
35
+ const [query, setQuery] = React.useState("")
36
+
37
+ const visibleCategories = React.useMemo(() => {
38
+ const normalized = query.trim().toLowerCase()
39
+ if (!normalized) {
40
+ return categories
41
+ }
42
+
43
+ return categories.filter((category) => {
44
+ if (category.label.toLowerCase().includes(normalized)) {
45
+ return true
46
+ }
47
+
48
+ return category.options.some((option) =>
49
+ option.toLowerCase().includes(normalized)
50
+ )
51
+ })
52
+ }, [categories, query])
53
+
54
+ const activeCount = React.useMemo(
55
+ () =>
56
+ Object.values(selectedFilters).reduce(
57
+ (count, selected) => count + selected.length,
58
+ 0
59
+ ),
60
+ [selectedFilters]
61
+ )
62
+
63
+ return (
64
+ <DropdownMenu>
65
+ <DropdownMenuTrigger asChild>
66
+ <Button
67
+ variant="outline"
68
+ size="sm"
69
+ className="h-8 gap-2 rounded-md border-border/60 bg-background text-xs font-normal shadow-none hover:bg-muted/50"
70
+ >
71
+ <ListFilter className="h-3.5 w-3.5" />
72
+ Filter
73
+ {activeCount > 0 ? (
74
+ <span className="rounded bg-muted px-1.5 py-0 text-[10px] font-semibold">
75
+ {activeCount}
76
+ </span>
77
+ ) : null}
78
+ </Button>
79
+ </DropdownMenuTrigger>
80
+ <DropdownMenuContent align="start" className="w-[240px] p-0">
81
+ <div className="sticky top-0 z-10 border-b border-border bg-popover p-2">
82
+ <div className="relative">
83
+ <Search className="absolute left-2 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" />
84
+ <input
85
+ className="h-8 w-full rounded-md bg-muted/50 py-1 pr-2 pl-7 text-xs outline-none transition-colors placeholder:text-muted-foreground/70 focus:bg-muted"
86
+ placeholder="Search filters..."
87
+ value={query}
88
+ onChange={(event) => setQuery(event.target.value)}
89
+ onClick={(event) => event.stopPropagation()}
90
+ onKeyDown={(event) => event.stopPropagation()}
91
+ />
92
+ </div>
93
+ </div>
94
+
95
+ <div className="max-h-[320px] overflow-y-auto p-1">
96
+ {visibleCategories.map((category) => (
97
+ <DropdownMenuSub key={category.id}>
98
+ <DropdownMenuSubTrigger className="cursor-pointer py-1.5 text-xs">
99
+ <category.icon className="mr-2 h-3.5 w-3.5 text-muted-foreground" />
100
+ {category.label}
101
+ </DropdownMenuSubTrigger>
102
+ <DropdownMenuSubContent className="w-52 p-1">
103
+ {category.options.map((option) => {
104
+ const selected =
105
+ selectedFilters[category.id]?.includes(option) ?? false
106
+
107
+ return (
108
+ <DropdownMenuItem
109
+ key={option}
110
+ className="cursor-pointer justify-between text-xs"
111
+ onSelect={(event) => {
112
+ event.preventDefault()
113
+ onToggleFilter(category.id, option)
114
+ }}
115
+ >
116
+ {option}
117
+ {selected ? (
118
+ <span className="text-[10px] font-semibold text-brand-purple">
119
+ Applied
120
+ </span>
121
+ ) : null}
122
+ </DropdownMenuItem>
123
+ )
124
+ })}
125
+ </DropdownMenuSubContent>
126
+ </DropdownMenuSub>
127
+ ))}
128
+
129
+ {visibleCategories.length === 0 ? (
130
+ <div className="p-2 text-center text-xs text-muted-foreground">
131
+ No filters found
132
+ </div>
133
+ ) : null}
134
+ </div>
135
+ </DropdownMenuContent>
136
+ </DropdownMenu>
137
+ )
138
+ }
@@ -0,0 +1,103 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { ChevronDown, X } from "lucide-react"
5
+
6
+ import { cn } from "../lib/utils"
7
+ import {
8
+ DropdownMenu,
9
+ DropdownMenuContent,
10
+ DropdownMenuItem,
11
+ DropdownMenuTrigger,
12
+ } from "./dropdown-menu"
13
+
14
+ export type DataTableQuickViewValue = string | null
15
+
16
+ interface DataTableQuickViewsProps {
17
+ quickViews: string[]
18
+ moreViews: string[]
19
+ activeView: DataTableQuickViewValue
20
+ onViewChange: (next: DataTableQuickViewValue) => void
21
+ className?: string
22
+ }
23
+
24
+ export function DataTableQuickViews({
25
+ quickViews,
26
+ moreViews,
27
+ activeView,
28
+ onViewChange,
29
+ className,
30
+ }: DataTableQuickViewsProps) {
31
+ const isMoreActive = Boolean(activeView && moreViews.includes(activeView))
32
+
33
+ return (
34
+ <div
35
+ className={cn(
36
+ "flex items-center gap-2 overflow-x-auto border-b border-border px-4 pb-3 pt-2",
37
+ className
38
+ )}
39
+ >
40
+ <span className="mr-1 shrink-0 text-xs font-medium text-muted-foreground/80">
41
+ Quick views:
42
+ </span>
43
+
44
+ {quickViews.map((view) => {
45
+ const isActive = activeView === view
46
+ return (
47
+ <button
48
+ key={view}
49
+ onClick={() => onViewChange(isActive ? null : view)}
50
+ className={cn(
51
+ "whitespace-nowrap rounded-full border px-3 py-1 text-xs transition-colors",
52
+ isActive
53
+ ? "border-brand-purple/30 bg-brand-purple/10 font-medium text-brand-purple"
54
+ : "border-border bg-background text-muted-foreground hover:bg-muted hover:text-foreground"
55
+ )}
56
+ >
57
+ {view}
58
+ </button>
59
+ )
60
+ })}
61
+
62
+ <DropdownMenu>
63
+ <DropdownMenuTrigger asChild>
64
+ <button
65
+ className={cn(
66
+ "flex items-center gap-1 whitespace-nowrap rounded-full border px-3 py-1 text-xs transition-colors",
67
+ isMoreActive
68
+ ? "border-brand-purple/30 bg-brand-purple/10 font-medium text-brand-purple"
69
+ : "border-border bg-background text-muted-foreground hover:bg-muted hover:text-foreground"
70
+ )}
71
+ >
72
+ {isMoreActive ? activeView : "More..."}
73
+ <ChevronDown className="h-3 w-3 opacity-60" />
74
+ </button>
75
+ </DropdownMenuTrigger>
76
+ <DropdownMenuContent align="start" className="w-56">
77
+ {moreViews.map((view) => (
78
+ <DropdownMenuItem
79
+ key={view}
80
+ className={cn(
81
+ "cursor-pointer text-xs",
82
+ activeView === view && "bg-brand-purple/5 font-medium text-brand-purple"
83
+ )}
84
+ onSelect={() => onViewChange(view)}
85
+ >
86
+ {view}
87
+ </DropdownMenuItem>
88
+ ))}
89
+ </DropdownMenuContent>
90
+ </DropdownMenu>
91
+
92
+ {activeView ? (
93
+ <button
94
+ onClick={() => onViewChange(null)}
95
+ className="ml-auto flex items-center gap-1 rounded-md px-2 py-1 text-xs text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
96
+ >
97
+ <X className="h-3 w-3" />
98
+ Clear
99
+ </button>
100
+ ) : null}
101
+ </div>
102
+ )
103
+ }
@@ -0,0 +1,56 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import type { SortingState } from "@tanstack/react-table"
5
+
6
+ import {
7
+ DataTableFilter,
8
+ type DataTableFilterCategory,
9
+ } from "./data-table-filter"
10
+ import {
11
+ DataTableDisplay,
12
+ type DataTableDisplayColumn,
13
+ } from "./data-table-display"
14
+
15
+ interface DataTableToolbarProps {
16
+ categories: DataTableFilterCategory[]
17
+ selectedFilters: Record<string, string[]>
18
+ onToggleFilter: (categoryId: string, option: string) => void
19
+ sorting: SortingState
20
+ onSortingChange: (next: SortingState) => void
21
+ displayColumns: DataTableDisplayColumn[]
22
+ onToggleColumn: (columnId: string) => void
23
+ onResetDisplay: () => void
24
+ }
25
+
26
+ export function DataTableToolbar({
27
+ categories,
28
+ selectedFilters,
29
+ onToggleFilter,
30
+ sorting,
31
+ onSortingChange,
32
+ displayColumns,
33
+ onToggleColumn,
34
+ onResetDisplay,
35
+ }: DataTableToolbarProps) {
36
+ return (
37
+ <div className="flex items-center justify-between gap-2 border-b border-border px-4 py-2">
38
+ <div className="flex items-center gap-2">
39
+ <DataTableFilter
40
+ categories={categories}
41
+ selectedFilters={selectedFilters}
42
+ onToggleFilter={onToggleFilter}
43
+ />
44
+ </div>
45
+ <div className="flex items-center gap-2">
46
+ <DataTableDisplay
47
+ sorting={sorting}
48
+ onSortingChange={onSortingChange}
49
+ columns={displayColumns}
50
+ onToggleColumn={onToggleColumn}
51
+ onReset={onResetDisplay}
52
+ />
53
+ </div>
54
+ </div>
55
+ )
56
+ }