@schandlergarcia/sf-web-components 1.6.0 → 1.8.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 (162) hide show
  1. package/dist/components/library/cards/ActionList.d.ts +10 -10
  2. package/dist/components/library/cards/ActionList.js +2 -3
  3. package/dist/components/library/cards/ActionList.js.map +1 -1
  4. package/dist/components/library/cards/ActivityCard.d.ts +18 -5
  5. package/dist/components/library/cards/ActivityCard.js +3 -4
  6. package/dist/components/library/cards/ActivityCard.js.map +1 -1
  7. package/dist/components/library/cards/BaseCard.d.ts +30 -24
  8. package/dist/components/library/cards/BaseCard.js +2 -3
  9. package/dist/components/library/cards/BaseCard.js.map +1 -1
  10. package/dist/components/library/cards/CalloutCard.d.ts +11 -9
  11. package/dist/components/library/cards/CalloutCard.js +2 -3
  12. package/dist/components/library/cards/CalloutCard.js.map +1 -1
  13. package/dist/components/library/cards/ChartCard.d.ts +29 -17
  14. package/dist/components/library/cards/ChartCard.js +13 -14
  15. package/dist/components/library/cards/ChartCard.js.map +1 -1
  16. package/dist/components/library/cards/FeedPanel.d.ts +12 -11
  17. package/dist/components/library/cards/FeedPanel.js +3 -4
  18. package/dist/components/library/cards/FeedPanel.js.map +1 -1
  19. package/dist/components/library/cards/ListCard.d.ts +33 -20
  20. package/dist/components/library/cards/ListCard.js +35 -35
  21. package/dist/components/library/cards/ListCard.js.map +1 -1
  22. package/dist/components/library/cards/MetricCard.d.ts +23 -17
  23. package/dist/components/library/cards/MetricCard.js +10 -11
  24. package/dist/components/library/cards/MetricCard.js.map +1 -1
  25. package/dist/components/library/cards/MetricsStrip.d.ts +11 -11
  26. package/dist/components/library/cards/MetricsStrip.js +1 -1
  27. package/dist/components/library/cards/MetricsStrip.js.map +1 -1
  28. package/dist/components/library/cards/SectionCard.d.ts +17 -12
  29. package/dist/components/library/cards/SectionCard.js +18 -19
  30. package/dist/components/library/cards/SectionCard.js.map +1 -1
  31. package/dist/components/library/cards/SemanticMetricCard.d.ts +15 -20
  32. package/dist/components/library/cards/SemanticMetricCardWithLoading.d.ts +8 -7
  33. package/dist/components/library/cards/SemanticTableCard.d.ts +13 -18
  34. package/dist/components/library/cards/SemanticTableCardWithLoading.d.ts +8 -7
  35. package/dist/components/library/cards/StatusCard.d.ts +29 -15
  36. package/dist/components/library/cards/StatusCard.js +16 -17
  37. package/dist/components/library/cards/StatusCard.js.map +1 -1
  38. package/dist/components/library/cards/TableCard.d.ts +40 -23
  39. package/dist/components/library/cards/TableCard.js +59 -59
  40. package/dist/components/library/cards/TableCard.js.map +1 -1
  41. package/dist/components/library/cards/WidgetCard.d.ts +19 -11
  42. package/dist/components/library/cards/WidgetCard.js.map +1 -1
  43. package/dist/components/library/charts/D3Chart.d.ts +23 -16
  44. package/dist/components/library/charts/D3Chart.js.map +1 -1
  45. package/dist/components/library/charts/D3ChartTemplates.d.ts +33 -3
  46. package/dist/components/library/charts/D3ChartTemplates.js +7 -7
  47. package/dist/components/library/charts/D3ChartTemplates.js.map +1 -1
  48. package/dist/components/library/charts/GeoMap.d.ts +81 -18
  49. package/dist/components/library/charts/GeoMap.js +28 -26
  50. package/dist/components/library/charts/GeoMap.js.map +1 -1
  51. package/dist/components/library/filters/FilterBar.d.ts +18 -8
  52. package/dist/components/library/filters/FilterBar.js +2 -3
  53. package/dist/components/library/filters/FilterBar.js.map +1 -1
  54. package/dist/components/library/filters/SearchFilter.d.ts +7 -6
  55. package/dist/components/library/filters/SearchFilter.js +2 -3
  56. package/dist/components/library/filters/SearchFilter.js.map +1 -1
  57. package/dist/components/library/filters/SelectFilter.d.ts +13 -7
  58. package/dist/components/library/filters/SelectFilter.js +2 -3
  59. package/dist/components/library/filters/SelectFilter.js.map +1 -1
  60. package/dist/components/library/filters/ToggleFilter.d.ts +7 -5
  61. package/dist/components/library/filters/ToggleFilter.js +2 -3
  62. package/dist/components/library/filters/ToggleFilter.js.map +1 -1
  63. package/dist/components/library/forms/FormField.d.ts +10 -8
  64. package/dist/components/library/forms/FormField.js +3 -4
  65. package/dist/components/library/forms/FormField.js.map +1 -1
  66. package/dist/components/library/forms/FormModal.d.ts +23 -14
  67. package/dist/components/library/forms/FormModal.js.map +1 -1
  68. package/dist/components/library/forms/FormRenderer.d.ts +29 -9
  69. package/dist/components/library/forms/FormRenderer.js +6 -7
  70. package/dist/components/library/forms/FormRenderer.js.map +1 -1
  71. package/dist/components/library/forms/FormSection.d.ts +10 -8
  72. package/dist/components/library/forms/FormSection.js +2 -3
  73. package/dist/components/library/forms/FormSection.js.map +1 -1
  74. package/dist/components/library/forms/index.d.ts +5 -0
  75. package/dist/components/library/forms/useFormState.d.ts +23 -15
  76. package/dist/components/library/forms/useFormState.js +53 -47
  77. package/dist/components/library/forms/useFormState.js.map +1 -1
  78. package/dist/components/library/heroui/Accordion.d.ts +6 -5
  79. package/dist/components/library/heroui/Accordion.js +7 -8
  80. package/dist/components/library/heroui/Accordion.js.map +1 -1
  81. package/dist/components/library/heroui/Breadcrumbs.d.ts +5 -2
  82. package/dist/components/library/heroui/Breadcrumbs.js +4 -5
  83. package/dist/components/library/heroui/Breadcrumbs.js.map +1 -1
  84. package/dist/components/library/heroui/Collapsible.d.ts +19 -30
  85. package/dist/components/library/heroui/Collapsible.js +13 -13
  86. package/dist/components/library/heroui/Collapsible.js.map +1 -1
  87. package/dist/components/library/heroui/DatePicker.d.ts +24 -52
  88. package/dist/components/library/heroui/DatePicker.js +5 -6
  89. package/dist/components/library/heroui/DatePicker.js.map +1 -1
  90. package/dist/components/library/heroui/Dialog.d.ts +18 -32
  91. package/dist/components/library/heroui/Dialog.js +6 -7
  92. package/dist/components/library/heroui/Dialog.js.map +1 -1
  93. package/dist/components/library/heroui/Drawer.d.ts +6 -2
  94. package/dist/components/library/heroui/Drawer.js +2 -3
  95. package/dist/components/library/heroui/Drawer.js.map +1 -1
  96. package/dist/components/library/heroui/Dropdown.d.ts +6 -2
  97. package/dist/components/library/heroui/Dropdown.js +2 -3
  98. package/dist/components/library/heroui/Dropdown.js.map +1 -1
  99. package/dist/components/library/heroui/Field.d.ts +19 -38
  100. package/dist/components/library/heroui/Field.js +9 -10
  101. package/dist/components/library/heroui/Field.js.map +1 -1
  102. package/dist/components/library/heroui/Meter.d.ts +7 -5
  103. package/dist/components/library/heroui/Meter.js +4 -5
  104. package/dist/components/library/heroui/Meter.js.map +1 -1
  105. package/dist/components/library/heroui/Popover.d.ts +23 -38
  106. package/dist/components/library/heroui/Popover.js +12 -12
  107. package/dist/components/library/heroui/Popover.js.map +1 -1
  108. package/dist/components/library/heroui/Select.d.ts +31 -37
  109. package/dist/components/library/heroui/Select.js +3 -4
  110. package/dist/components/library/heroui/Select.js.map +1 -1
  111. package/dist/components/library/layout/PageContainer.d.ts +6 -4
  112. package/dist/components/library/layout/PageContainer.js +4 -5
  113. package/dist/components/library/layout/PageContainer.js.map +1 -1
  114. package/package.json +4 -1
  115. package/src/components/library/cards/{ActionList.jsx → ActionList.tsx} +13 -9
  116. package/src/components/library/cards/{ActivityCard.jsx → ActivityCard.tsx} +33 -4
  117. package/src/components/library/cards/{BaseCard.jsx → BaseCard.tsx} +33 -6
  118. package/src/components/library/cards/{CalloutCard.jsx → CalloutCard.tsx} +12 -10
  119. package/src/components/library/cards/{ChartCard.jsx → ChartCard.tsx} +32 -6
  120. package/src/components/library/cards/{FeedPanel.jsx → FeedPanel.tsx} +13 -2
  121. package/src/components/library/cards/{ListCard.jsx → ListCard.tsx} +43 -7
  122. package/src/components/library/cards/{MetricCard.jsx → MetricCard.tsx} +25 -6
  123. package/src/components/library/cards/{MetricsStrip.jsx → MetricsStrip.tsx} +22 -12
  124. package/src/components/library/cards/{SectionCard.jsx → SectionCard.tsx} +27 -8
  125. package/src/components/library/cards/{SemanticMetricCard.jsx → SemanticMetricCard.tsx} +17 -5
  126. package/src/components/library/cards/{SemanticMetricCardWithLoading.jsx → SemanticMetricCardWithLoading.tsx} +9 -3
  127. package/src/components/library/cards/{SemanticTableCard.jsx → SemanticTableCard.tsx} +14 -3
  128. package/src/components/library/cards/{SemanticTableCardWithLoading.jsx → SemanticTableCardWithLoading.tsx} +9 -5
  129. package/src/components/library/cards/{StatusCard.jsx → StatusCard.tsx} +61 -12
  130. package/src/components/library/cards/{TableCard.jsx → TableCard.tsx} +51 -12
  131. package/src/components/library/cards/{WidgetCard.jsx → WidgetCard.tsx} +28 -5
  132. package/src/components/library/charts/{D3Chart.jsx → D3Chart.tsx} +27 -7
  133. package/src/components/library/charts/{D3ChartTemplates.jsx → D3ChartTemplates.tsx} +60 -28
  134. package/src/components/library/charts/{GeoMap.jsx → GeoMap.tsx} +106 -17
  135. package/src/components/library/filters/{FilterBar.jsx → FilterBar.tsx} +21 -11
  136. package/src/components/library/filters/{SearchFilter.jsx → SearchFilter.tsx} +8 -2
  137. package/src/components/library/filters/{SelectFilter.jsx → SelectFilter.tsx} +15 -8
  138. package/src/components/library/filters/{ToggleFilter.jsx → ToggleFilter.tsx} +7 -6
  139. package/src/components/library/forms/{FormField.jsx → FormField.tsx} +91 -45
  140. package/src/components/library/forms/{FormModal.jsx → FormModal.tsx} +21 -20
  141. package/src/components/library/forms/{FormRenderer.jsx → FormRenderer.tsx} +32 -10
  142. package/src/components/library/forms/{FormSection.jsx → FormSection.tsx} +13 -7
  143. package/src/components/library/forms/index.tsx +11 -0
  144. package/src/components/library/forms/{useFormState.jsx → useFormState.tsx} +43 -23
  145. package/src/components/library/heroui/{Accordion.jsx → Accordion.tsx} +8 -3
  146. package/src/components/library/heroui/{Breadcrumbs.jsx → Breadcrumbs.tsx} +5 -2
  147. package/src/components/library/heroui/Collapsible.tsx +62 -0
  148. package/src/components/library/heroui/{DatePicker.jsx → DatePicker.tsx} +28 -4
  149. package/src/components/library/heroui/Dialog.tsx +43 -0
  150. package/src/components/library/heroui/{Drawer.jsx → Drawer.tsx} +6 -2
  151. package/src/components/library/heroui/{Dropdown.jsx → Dropdown.tsx} +6 -2
  152. package/src/components/library/heroui/{Field.jsx → Field.tsx} +23 -6
  153. package/src/components/library/heroui/Meter.tsx +13 -0
  154. package/src/components/library/heroui/{Popover.jsx → Popover.tsx} +29 -8
  155. package/src/components/library/heroui/Select.tsx +73 -0
  156. package/src/components/library/layout/{PageContainer.jsx → PageContainer.tsx} +6 -3
  157. package/src/components/library/forms/index.jsx +0 -5
  158. package/src/components/library/heroui/Collapsible.jsx +0 -42
  159. package/src/components/library/heroui/Dialog.jsx +0 -37
  160. package/src/components/library/heroui/Meter.jsx +0 -8
  161. package/src/components/library/heroui/Select.jsx +0 -37
  162. /package/src/components/library/filters/{index.jsx → index.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"TableCard.js","sources":["../../../../src/components/library/cards/TableCard.jsx"],"sourcesContent":["import React from \"react\";\nimport BaseCard from \"./BaseCard\";\nimport UIInput from \"../ui/UIInput\";\nimport UIButton from \"../ui/UIButton\";\nimport UIText from \"../ui/Text\";\n\nfunction defaultTypeFormat(type, value) {\n if (value == null) return \"\";\n if (!type) return String(value);\n\n if (type === \"currency\") {\n const n = Number(value);\n if (Number.isFinite(n)) return n.toLocaleString(undefined, { style: \"currency\", currency: \"USD\" });\n }\n if (type === \"percentage\") {\n const n = Number(value);\n if (Number.isFinite(n)) return `${n}%`;\n }\n if (type === \"number\") {\n const n = Number(value);\n if (Number.isFinite(n)) return n.toLocaleString();\n }\n return String(value);\n}\n\nfunction stableSort(data, compare) {\n return data\n .map((item, idx) => ({ item, idx }))\n .sort((a, b) => {\n const c = compare(a.item, b.item);\n return c !== 0 ? c : a.idx - b.idx;\n })\n .map((x) => x.item);\n}\n\nexport default function TableCard({\n data = [],\n columns = [],\n title,\n subtitle,\n searchable = false,\n sortable = false,\n paginated = false,\n selectable = false,\n pageSize = 10,\n actions,\n rowActions,\n onRowSelect,\n onSort,\n onSearch,\n loading = false,\n error,\n emptyMessage = \"No results.\",\n simulateInitialLoad = false,\n minInitialDelayMs = 350,\n maxInitialDelayMs = 900,\n ...cardProps\n}) {\n const [query, setQuery] = React.useState(\"\");\n const [sortKey, setSortKey] = React.useState(null);\n const [sortDir, setSortDir] = React.useState(\"asc\");\n const [page, setPage] = React.useState(1);\n const [selectedId, setSelectedId] = React.useState(null);\n const [simLoading, setSimLoading] = React.useState(simulateInitialLoad);\n\n React.useEffect(() => {\n if (!simulateInitialLoad) return;\n const delay =\n Math.floor(Math.random() * (maxInitialDelayMs - minInitialDelayMs + 1)) + minInitialDelayMs;\n const t = setTimeout(() => setSimLoading(false), delay);\n return () => clearTimeout(t);\n }, [simulateInitialLoad, minInitialDelayMs, maxInitialDelayMs]);\n\n const effectiveLoading = loading || simLoading;\n\n const filtered = React.useMemo(() => {\n if (!searchable || !query.trim()) return data;\n const q = query.trim().toLowerCase();\n return data.filter((row) =>\n columns.some((col) => {\n const raw = row?.[col.key];\n if (raw == null) return false;\n return String(raw).toLowerCase().includes(q);\n })\n );\n }, [data, columns, query, searchable]);\n\n const sorted = React.useMemo(() => {\n if (!sortable || !sortKey) return filtered;\n const col = columns.find((c) => c.key === sortKey);\n if (!col) return filtered;\n const dir = sortDir === \"desc\" ? -1 : 1;\n return stableSort(filtered, (a, b) => {\n const av = a?.[sortKey];\n const bv = b?.[sortKey];\n if (av == null && bv == null) return 0;\n if (av == null) return -1 * dir;\n if (bv == null) return 1 * dir;\n if (typeof av === \"number\" && typeof bv === \"number\") return (av - bv) * dir;\n return String(av).localeCompare(String(bv)) * dir;\n });\n }, [filtered, sortable, sortKey, sortDir, columns]);\n\n const total = sorted.length;\n const totalPages = paginated ? Math.max(1, Math.ceil(total / pageSize)) : 1;\n const clampedPage = Math.min(page, totalPages);\n\n const pageData = React.useMemo(() => {\n if (!paginated) return sorted;\n const start = (clampedPage - 1) * pageSize;\n return sorted.slice(start, start + pageSize);\n }, [sorted, paginated, clampedPage, pageSize]);\n\n React.useEffect(() => {\n if (page !== clampedPage) setPage(clampedPage);\n }, [page, clampedPage]);\n\n const header = (\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between\">\n <div className=\"min-w-0\">\n {title ? (\n <UIText as=\"div\" size=\"sm\" weight=\"medium\">\n {title}\n </UIText>\n ) : null}\n {subtitle ? (\n <UIText as=\"div\" size=\"xs\" muted className=\"mt-1\">\n {subtitle}\n </UIText>\n ) : null}\n </div>\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-end\">\n {searchable ? (\n <div className=\"w-full sm:w-64\">\n <UIInput\n value={query}\n onChange={(e) => {\n setQuery(e.target.value);\n setPage(1);\n onSearch?.(e.target.value);\n }}\n placeholder=\"Search…\"\n aria-label=\"Search table\"\n />\n </div>\n ) : null}\n {actions ? <div className=\"flex items-center gap-2\">{actions}</div> : null}\n </div>\n </div>\n );\n\n if (error) {\n return (\n <BaseCard\n header={header}\n body={\n <div className=\"mt-4 rounded-xl border border-rose-200 bg-rose-50 p-4 text-sm text-rose-900 dark:border-rose-900/40 dark:bg-rose-950/30 dark:text-rose-100\">\n {String(error)}\n </div>\n }\n {...cardProps}\n />\n );\n }\n\n const canSort = (col) => sortable && (col.sortable ?? true);\n\n return (\n <BaseCard\n variant=\"table\"\n header={header}\n body={\n <div className=\"mt-4 overflow-hidden rounded-xl border border-slate-200 dark:border-slate-800\">\n <div className=\"w-full overflow-x-auto\">\n <table className=\"min-w-full border-separate border-spacing-0\">\n <thead className=\"bg-slate-50 dark:bg-slate-950/30\">\n <tr>\n {columns.map((col) => {\n const active = sortKey === col.key;\n return (\n <th\n key={col.key}\n scope=\"col\"\n className={[\n \"whitespace-nowrap border-b border-slate-200 px-4 py-3 text-left text-xs font-semibold text-slate-600 dark:border-slate-800 dark:text-slate-300\",\n col.className ?? \"\"\n ]\n .filter(Boolean)\n .join(\" \")}\n >\n {canSort(col) ? (\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-2 hover:text-slate-900 dark:hover:text-slate-50\"\n onClick={() => {\n const nextDir = active && sortDir === \"asc\" ? \"desc\" : \"asc\";\n setSortKey(col.key);\n setSortDir(nextDir);\n onSort?.({ key: col.key, direction: nextDir });\n }}\n >\n <span>{col.label}</span>\n <span className=\"text-[10px] opacity-70\">\n {active ? (sortDir === \"asc\" ? \"▲\" : \"▼\") : \"↕\"}\n </span>\n </button>\n ) : (\n col.label\n )}\n </th>\n );\n })}\n {rowActions ? (\n <th className=\"border-b border-slate-200 px-4 py-3 text-right text-xs font-semibold text-slate-600 dark:border-slate-800 dark:text-slate-300\">\n Actions\n </th>\n ) : null}\n </tr>\n </thead>\n\n <tbody className=\"bg-white dark:bg-slate-900\">\n {effectiveLoading ? (\n Array.from({ length: Math.min(pageSize, 6) }).map((_, idx) => (\n <tr key={idx}>\n {columns.map((col) => (\n <td\n key={col.key}\n className=\"border-b border-slate-200 px-4 py-3 dark:border-slate-800\"\n >\n <div className=\"h-4 w-3/4 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n </td>\n ))}\n {rowActions ? (\n <td className=\"border-b border-slate-200 px-4 py-3 dark:border-slate-800\">\n <div className=\"h-4 w-10 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n </td>\n ) : null}\n </tr>\n ))\n ) : pageData.length === 0 ? (\n <tr>\n <td\n colSpan={columns.length + (rowActions ? 1 : 0)}\n className=\"px-4 py-10 text-center text-sm text-slate-600 dark:text-slate-300\"\n >\n {emptyMessage}\n </td>\n </tr>\n ) : (\n pageData.map((row, idx) => {\n const rowId = row?.id ?? idx;\n const selected = selectable && selectedId === rowId;\n return (\n <tr\n key={rowId}\n className={[\n \"group\",\n selectable ? \"cursor-pointer\" : \"\",\n selected ? \"bg-brand-50 dark:bg-brand-950/30\" : \"\"\n ]\n .filter(Boolean)\n .join(\" \")}\n onClick={() => {\n if (!selectable) return;\n setSelectedId(rowId);\n onRowSelect?.(row);\n }}\n >\n {columns.map((col) => {\n const raw = row?.[col.key];\n const content = col.render ? col.render(raw, row) : defaultTypeFormat(col.type, raw);\n return (\n <td\n key={col.key}\n className={[\n \"border-b border-slate-200 px-4 py-3 text-sm text-slate-700 dark:border-slate-800 dark:text-slate-200\",\n col.mono ? \"font-mono text-[13px]\" : \"\",\n col.className ?? \"\"\n ]\n .filter(Boolean)\n .join(\" \")}\n >\n {content}\n </td>\n );\n })}\n {rowActions ? (\n <td className=\"border-b border-slate-200 px-4 py-3 text-right text-sm dark:border-slate-800\">\n <div className=\"inline-flex items-center justify-end gap-2 opacity-100 sm:opacity-0 sm:group-hover:opacity-100\">\n {rowActions(row)}\n </div>\n </td>\n ) : null}\n </tr>\n );\n })\n )}\n </tbody>\n </table>\n </div>\n\n {paginated && !effectiveLoading ? (\n <div className=\"flex flex-col gap-2 border-t border-slate-200 bg-slate-50 px-4 py-3 dark:border-slate-800 dark:bg-slate-950/30 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"text-xs text-slate-600 dark:text-slate-300\">\n {total === 0 ? \"0 results\" : `Showing ${(clampedPage - 1) * pageSize + 1}-${Math.min(clampedPage * pageSize, total)} of ${total}`}\n </div>\n <div className=\"flex items-center gap-2\">\n <UIButton\n variant=\"outline\"\n size=\"sm\"\n disabled={clampedPage <= 1}\n onClick={() => setPage((p) => Math.max(1, p - 1))}\n >\n Prev\n </UIButton>\n <div className=\"text-xs text-slate-600 dark:text-slate-300\">\n Page {clampedPage} / {totalPages}\n </div>\n <UIButton\n variant=\"outline\"\n size=\"sm\"\n disabled={clampedPage >= totalPages}\n onClick={() => setPage((p) => Math.min(totalPages, p + 1))}\n >\n Next\n </UIButton>\n </div>\n </div>\n ) : null}\n </div>\n }\n {...cardProps}\n />\n );\n}\n\n\n"],"names":["defaultTypeFormat","type","value","n","stableSort","data","compare","item","idx","a","b","c","x","TableCard","columns","title","subtitle","searchable","sortable","paginated","selectable","pageSize","actions","rowActions","onRowSelect","onSort","onSearch","loading","error","emptyMessage","simulateInitialLoad","minInitialDelayMs","maxInitialDelayMs","cardProps","query","setQuery","React","sortKey","setSortKey","sortDir","setSortDir","page","setPage","selectedId","setSelectedId","simLoading","setSimLoading","delay","t","effectiveLoading","filtered","q","row","col","raw","sorted","dir","av","bv","total","totalPages","clampedPage","pageData","start","header","jsxs","jsx","UIText","UIInput","BaseCard","canSort","active","nextDir","_","rowId","content","UIButton","p"],"mappings":"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"}
1
+ {"version":3,"file":"TableCard.js","sources":["../../../../src/components/library/cards/TableCard.tsx"],"sourcesContent":["import React from \"react\";\nimport BaseCard, { BaseCardProps } from \"./BaseCard\";\nimport UIInput from \"../ui/UIInput\";\nimport UIButton from \"../ui/UIButton\";\nimport UIText from \"../ui/Text\";\n\ntype ColumnType = \"currency\" | \"percentage\" | \"number\" | \"text\";\n\nfunction defaultTypeFormat(type: ColumnType | undefined, value: unknown): string {\n if (value == null) return \"\";\n if (!type) return String(value);\n\n if (type === \"currency\") {\n const n = Number(value);\n if (Number.isFinite(n)) return n.toLocaleString(undefined, { style: \"currency\", currency: \"USD\" });\n }\n if (type === \"percentage\") {\n const n = Number(value);\n if (Number.isFinite(n)) return `${n}%`;\n }\n if (type === \"number\") {\n const n = Number(value);\n if (Number.isFinite(n)) return n.toLocaleString();\n }\n return String(value);\n}\n\nfunction stableSort<T>(data: T[], compare: (a: T, b: T) => number): T[] {\n return data\n .map((item, idx) => ({ item, idx }))\n .sort((a, b) => {\n const c = compare(a.item, b.item);\n return c !== 0 ? c : a.idx - b.idx;\n })\n .map((x) => x.item);\n}\n\nexport interface TableColumn {\n key: string;\n label: string;\n type?: ColumnType;\n sortable?: boolean;\n mono?: boolean;\n className?: string;\n render?: (value: unknown, row: Record<string, unknown>) => React.ReactNode;\n}\n\nexport interface SortState {\n key: string;\n direction: \"asc\" | \"desc\";\n}\n\nexport interface TableCardProps extends Omit<BaseCardProps, \"variant\" | \"header\" | \"body\"> {\n data?: Record<string, unknown>[];\n columns?: TableColumn[];\n title?: string;\n subtitle?: string;\n searchable?: boolean;\n sortable?: boolean;\n paginated?: boolean;\n selectable?: boolean;\n pageSize?: number;\n actions?: React.ReactNode;\n rowActions?: (row: Record<string, unknown>) => React.ReactNode;\n onRowSelect?: (row: Record<string, unknown>) => void;\n onSort?: (sort: SortState) => void;\n onSearch?: (query: string) => void;\n loading?: boolean;\n error?: string | Error;\n emptyMessage?: string;\n simulateInitialLoad?: boolean;\n minInitialDelayMs?: number;\n maxInitialDelayMs?: number;\n}\n\nexport default function TableCard({\n data = [],\n columns = [],\n title,\n subtitle,\n searchable = false,\n sortable = false,\n paginated = false,\n selectable = false,\n pageSize = 10,\n actions,\n rowActions,\n onRowSelect,\n onSort,\n onSearch,\n loading = false,\n error,\n emptyMessage = \"No results.\",\n simulateInitialLoad = false,\n minInitialDelayMs = 350,\n maxInitialDelayMs = 900,\n ...cardProps\n}: TableCardProps) {\n const [query, setQuery] = React.useState(\"\");\n const [sortKey, setSortKey] = React.useState<string | null>(null);\n const [sortDir, setSortDir] = React.useState<\"asc\" | \"desc\">(\"asc\");\n const [page, setPage] = React.useState(1);\n const [selectedId, setSelectedId] = React.useState<string | number | undefined>(undefined);\n const [simLoading, setSimLoading] = React.useState(simulateInitialLoad);\n\n React.useEffect(() => {\n if (!simulateInitialLoad) return;\n const delay =\n Math.floor(Math.random() * (maxInitialDelayMs - minInitialDelayMs + 1)) + minInitialDelayMs;\n const t = setTimeout(() => setSimLoading(false), delay);\n return () => clearTimeout(t);\n }, [simulateInitialLoad, minInitialDelayMs, maxInitialDelayMs]);\n\n const effectiveLoading = loading || simLoading;\n\n const filtered = React.useMemo(() => {\n if (!searchable || !query.trim()) return data;\n const q = query.trim().toLowerCase();\n return data.filter((row) =>\n columns.some((col) => {\n const raw = row?.[col.key];\n if (raw == null) return false;\n return String(raw).toLowerCase().includes(q);\n })\n );\n }, [data, columns, query, searchable]);\n\n const sorted = React.useMemo(() => {\n if (!sortable || !sortKey) return filtered;\n const col = columns.find((c) => c.key === sortKey);\n if (!col) return filtered;\n const dir = sortDir === \"desc\" ? -1 : 1;\n return stableSort(filtered, (a, b) => {\n const av = a?.[sortKey];\n const bv = b?.[sortKey];\n if (av == null && bv == null) return 0;\n if (av == null) return -1 * dir;\n if (bv == null) return 1 * dir;\n if (typeof av === \"number\" && typeof bv === \"number\") return (av - bv) * dir;\n return String(av).localeCompare(String(bv)) * dir;\n });\n }, [filtered, sortable, sortKey, sortDir, columns]);\n\n const total = sorted.length;\n const totalPages = paginated ? Math.max(1, Math.ceil(total / pageSize)) : 1;\n const clampedPage = Math.min(page, totalPages);\n\n const pageData = React.useMemo(() => {\n if (!paginated) return sorted;\n const start = (clampedPage - 1) * pageSize;\n return sorted.slice(start, start + pageSize);\n }, [sorted, paginated, clampedPage, pageSize]);\n\n React.useEffect(() => {\n if (page !== clampedPage) setPage(clampedPage);\n }, [page, clampedPage]);\n\n const header = (\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between\">\n <div className=\"min-w-0\">\n {title ? (\n <UIText as=\"div\" size=\"sm\" weight=\"medium\">\n {title}\n </UIText>\n ) : null}\n {subtitle ? (\n <UIText as=\"div\" size=\"xs\" muted className=\"mt-1\">\n {subtitle}\n </UIText>\n ) : null}\n </div>\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-end\">\n {searchable ? (\n <div className=\"w-full sm:w-64\">\n <UIInput\n value={query}\n onChange={(e) => {\n setQuery(e.target.value);\n setPage(1);\n onSearch?.(e.target.value);\n }}\n placeholder=\"Search…\"\n aria-label=\"Search table\"\n />\n </div>\n ) : null}\n {actions ? <div className=\"flex items-center gap-2\">{actions}</div> : null}\n </div>\n </div>\n );\n\n if (error) {\n return (\n <BaseCard\n header={header}\n body={\n <div className=\"mt-4 rounded-xl border border-rose-200 bg-rose-50 p-4 text-sm text-rose-900 dark:border-rose-900/40 dark:bg-rose-950/30 dark:text-rose-100\">\n {String(error)}\n </div>\n }\n {...cardProps}\n />\n );\n }\n\n const canSort = (col: TableColumn) => sortable && (col.sortable ?? true);\n\n return (\n <BaseCard\n variant=\"table\"\n header={header}\n body={\n <div className=\"mt-4 overflow-hidden rounded-xl border border-slate-200 dark:border-slate-800\">\n <div className=\"w-full overflow-x-auto\">\n <table className=\"min-w-full border-separate border-spacing-0\">\n <thead className=\"bg-slate-50 dark:bg-slate-950/30\">\n <tr>\n {columns.map((col) => {\n const active = sortKey === col.key;\n return (\n <th\n key={col.key}\n scope=\"col\"\n className={[\n \"whitespace-nowrap border-b border-slate-200 px-4 py-3 text-left text-xs font-semibold text-slate-600 dark:border-slate-800 dark:text-slate-300\",\n col.className ?? \"\"\n ]\n .filter(Boolean)\n .join(\" \")}\n >\n {canSort(col) ? (\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-2 hover:text-slate-900 dark:hover:text-slate-50\"\n onClick={() => {\n const nextDir = active && sortDir === \"asc\" ? \"desc\" : \"asc\";\n setSortKey(col.key);\n setSortDir(nextDir);\n onSort?.({ key: col.key, direction: nextDir });\n }}\n >\n <span>{col.label}</span>\n <span className=\"text-[10px] opacity-70\">\n {active ? (sortDir === \"asc\" ? \"▲\" : \"▼\") : \"↕\"}\n </span>\n </button>\n ) : (\n col.label\n )}\n </th>\n );\n })}\n {rowActions ? (\n <th className=\"border-b border-slate-200 px-4 py-3 text-right text-xs font-semibold text-slate-600 dark:border-slate-800 dark:text-slate-300\">\n Actions\n </th>\n ) : null}\n </tr>\n </thead>\n\n <tbody className=\"bg-white dark:bg-slate-900\">\n {effectiveLoading ? (\n Array.from({ length: Math.min(pageSize, 6) }).map((_, idx) => (\n <tr key={idx}>\n {columns.map((col) => (\n <td\n key={col.key}\n className=\"border-b border-slate-200 px-4 py-3 dark:border-slate-800\"\n >\n <div className=\"h-4 w-3/4 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n </td>\n ))}\n {rowActions ? (\n <td className=\"border-b border-slate-200 px-4 py-3 dark:border-slate-800\">\n <div className=\"h-4 w-10 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n </td>\n ) : null}\n </tr>\n ))\n ) : pageData.length === 0 ? (\n <tr>\n <td\n colSpan={columns.length + (rowActions ? 1 : 0)}\n className=\"px-4 py-10 text-center text-sm text-slate-600 dark:text-slate-300\"\n >\n {emptyMessage}\n </td>\n </tr>\n ) : (\n pageData.map((row, idx) => {\n const rawId = row?.id;\n const rowId: string | number = typeof rawId === \"string\" || typeof rawId === \"number\" ? rawId : idx;\n const selected = selectable && selectedId === rowId;\n return (\n <tr\n key={String(rowId)}\n className={[\n \"group\",\n selectable ? \"cursor-pointer\" : \"\",\n selected ? \"bg-brand-50 dark:bg-brand-950/30\" : \"\"\n ]\n .filter(Boolean)\n .join(\" \")}\n onClick={() => {\n if (!selectable) return;\n setSelectedId(rowId);\n onRowSelect?.(row);\n }}\n >\n {columns.map((col) => {\n const raw = row?.[col.key];\n const content = col.render ? col.render(raw, row) : defaultTypeFormat(col.type, raw);\n return (\n <td\n key={col.key}\n className={[\n \"border-b border-slate-200 px-4 py-3 text-sm text-slate-700 dark:border-slate-800 dark:text-slate-200\",\n col.mono ? \"font-mono text-[13px]\" : \"\",\n col.className ?? \"\"\n ]\n .filter(Boolean)\n .join(\" \")}\n >\n {content}\n </td>\n );\n })}\n {rowActions ? (\n <td className=\"border-b border-slate-200 px-4 py-3 text-right text-sm dark:border-slate-800\">\n <div className=\"inline-flex items-center justify-end gap-2 opacity-100 sm:opacity-0 sm:group-hover:opacity-100\">\n {rowActions(row)}\n </div>\n </td>\n ) : null}\n </tr>\n );\n })\n )}\n </tbody>\n </table>\n </div>\n\n {paginated && !effectiveLoading ? (\n <div className=\"flex flex-col gap-2 border-t border-slate-200 bg-slate-50 px-4 py-3 dark:border-slate-800 dark:bg-slate-950/30 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"text-xs text-slate-600 dark:text-slate-300\">\n {total === 0 ? \"0 results\" : `Showing ${(clampedPage - 1) * pageSize + 1}-${Math.min(clampedPage * pageSize, total)} of ${total}`}\n </div>\n <div className=\"flex items-center gap-2\">\n <UIButton\n variant=\"outline\"\n size=\"sm\"\n disabled={clampedPage <= 1}\n onClick={() => setPage((p) => Math.max(1, p - 1))}\n >\n Prev\n </UIButton>\n <div className=\"text-xs text-slate-600 dark:text-slate-300\">\n Page {clampedPage} / {totalPages}\n </div>\n <UIButton\n variant=\"outline\"\n size=\"sm\"\n disabled={clampedPage >= totalPages}\n onClick={() => setPage((p) => Math.min(totalPages, p + 1))}\n >\n Next\n </UIButton>\n </div>\n </div>\n ) : null}\n </div>\n }\n {...cardProps}\n />\n );\n}\n"],"names":["defaultTypeFormat","type","value","n","stableSort","data","compare","item","idx","a","b","c","x","TableCard","columns","title","subtitle","searchable","sortable","paginated","selectable","pageSize","actions","rowActions","onRowSelect","onSort","onSearch","loading","error","emptyMessage","simulateInitialLoad","minInitialDelayMs","maxInitialDelayMs","cardProps","query","setQuery","React","sortKey","setSortKey","sortDir","setSortDir","page","setPage","selectedId","setSelectedId","simLoading","setSimLoading","delay","t","effectiveLoading","filtered","q","row","col","raw","sorted","dir","av","bv","total","totalPages","clampedPage","pageData","start","header","jsxs","jsx","UIText","UIInput","BaseCard","canSort","active","nextDir","_","rawId","rowId","content","UIButton","p"],"mappings":"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"}
@@ -1,11 +1,19 @@
1
- export default function WidgetCard({ header, sections, footer, divided, collapsible, defaultExpanded, loading, emptyMessage, ...cardProps }: {
2
- [x: string]: any;
3
- header: any;
4
- sections?: never[] | undefined;
5
- footer: any;
6
- divided?: boolean | undefined;
7
- collapsible?: boolean | undefined;
8
- defaultExpanded?: boolean | undefined;
9
- loading?: boolean | undefined;
10
- emptyMessage?: string | undefined;
11
- }): import("react/jsx-runtime").JSX.Element;
1
+ import React from "react";
2
+ import { BaseCardProps } from "./BaseCard";
3
+ export interface WidgetSection {
4
+ id?: string | number;
5
+ title?: string;
6
+ actions?: React.ReactNode;
7
+ content: React.ReactNode;
8
+ }
9
+ export interface WidgetCardProps extends Omit<BaseCardProps, "variant" | "header" | "body"> {
10
+ header: React.ReactNode;
11
+ sections?: WidgetSection[];
12
+ footer?: React.ReactNode;
13
+ divided?: boolean;
14
+ collapsible?: boolean;
15
+ defaultExpanded?: boolean;
16
+ loading?: boolean;
17
+ emptyMessage?: string;
18
+ }
19
+ export default function WidgetCard({ header, sections, footer, divided, collapsible, defaultExpanded, loading, emptyMessage, ...cardProps }: WidgetCardProps): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"WidgetCard.js","sources":["../../../../src/components/library/cards/WidgetCard.jsx"],"sourcesContent":["import React from \"react\";\nimport BaseCard from \"./BaseCard\";\nimport UIText from \"../ui/Text\";\n\nfunction Section({ title, actions, content, divided }) {\n return (\n <div className={divided ? \"border-t border-slate-200 pt-4 dark:border-slate-800\" : \"\"}>\n {(title || actions) ? (\n <div className=\"mb-3 flex items-start justify-between gap-3\">\n {title ? (\n <UIText as=\"div\" size=\"sm\" weight=\"medium\">\n {title}\n </UIText>\n ) : (\n <div />\n )}\n {actions ? <div className=\"shrink-0\">{actions}</div> : null}\n </div>\n ) : null}\n <div>{content}</div>\n </div>\n );\n}\n\nexport default function WidgetCard({\n header,\n sections = [],\n footer,\n divided = false,\n collapsible = false,\n defaultExpanded = true,\n loading = false,\n emptyMessage = \"No sections.\",\n ...cardProps\n}) {\n const [expanded, setExpanded] = React.useState(defaultExpanded);\n\n const hdr = (\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">{header}</div>\n {collapsible ? (\n <button\n type=\"button\"\n className=\"rounded-lg border border-slate-200 bg-white px-2 py-1 text-xs font-semibold text-slate-700 shadow-sm hover:bg-slate-50 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-200 dark:hover:bg-slate-800\"\n onClick={() => setExpanded((e) => !e)}\n aria-expanded={expanded}\n aria-label=\"Toggle widget\"\n >\n {expanded ? \"Collapse\" : \"Expand\"}\n </button>\n ) : null}\n </div>\n );\n\n const body = (\n <div className=\"mt-4 space-y-4\">\n {loading ? (\n <div className=\"space-y-3\">\n <div className=\"h-4 w-1/3 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n <div className=\"h-4 w-2/3 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n <div className=\"h-4 w-1/2 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n </div>\n ) : expanded ? (\n sections.length === 0 ? (\n <div className=\"rounded-xl border border-dashed border-slate-300 bg-slate-50 p-6 text-center text-sm text-slate-600 dark:border-slate-700 dark:bg-slate-950/30 dark:text-slate-300\">\n {emptyMessage}\n </div>\n ) : (\n sections.map((s, idx) => (\n <Section\n key={s?.id ?? idx}\n title={s?.title}\n actions={s?.actions}\n content={s?.content}\n divided={divided && idx !== 0}\n />\n ))\n )\n ) : (\n <div className=\"text-sm text-slate-600 dark:text-slate-300\">Collapsed.</div>\n )}\n\n {footer ? <div className={divided ? \"border-t border-slate-200 pt-4 dark:border-slate-800\" : \"\"}>{footer}</div> : null}\n </div>\n );\n\n return <BaseCard variant=\"widget\" header={hdr} body={body} {...cardProps} />;\n}\n\n\n"],"names":["Section","title","actions","content","divided","jsxs","jsx","UIText","WidgetCard","header","sections","footer","collapsible","defaultExpanded","loading","emptyMessage","cardProps","expanded","setExpanded","React","hdr","e","body","s","idx","BaseCard"],"mappings":";;;;AAIA,SAASA,EAAQ,EAAE,OAAAC,GAAO,SAAAC,GAAS,SAAAC,GAAS,SAAAC,KAAW;AACrD,SACE,gBAAAC,EAAC,OAAA,EAAI,WAAWD,IAAU,yDAAyD,IAC/E,UAAA;AAAA,IAAAH,KAASC,IACT,gBAAAG,EAAC,OAAA,EAAI,WAAU,+CACZ,UAAA;AAAA,MAAAJ,IACC,gBAAAK,EAACC,GAAA,EAAO,IAAG,OAAM,MAAK,MAAK,QAAO,UAC/B,UAAAN,EAAA,CACH,IAEA,gBAAAK,EAAC,OAAA,EAAI;AAAA,MAENJ,IAAU,gBAAAI,EAAC,OAAA,EAAI,WAAU,YAAY,aAAQ,IAAS;AAAA,IAAA,EAAA,CACzD,IACE;AAAA,IACJ,gBAAAA,EAAC,SAAK,UAAAH,EAAA,CAAQ;AAAA,EAAA,GAChB;AAEJ;AAEA,SAAwBK,EAAW;AAAA,EACjC,QAAAC;AAAA,EACA,UAAAC,IAAW,CAAA;AAAA,EACX,QAAAC;AAAA,EACA,SAAAP,IAAU;AAAA,EACV,aAAAQ,IAAc;AAAA,EACd,iBAAAC,IAAkB;AAAA,EAClB,SAAAC,IAAU;AAAA,EACV,cAAAC,IAAe;AAAA,EACf,GAAGC;AACL,GAAG;AACD,QAAM,CAACC,GAAUC,CAAW,IAAIC,EAAM,SAASN,CAAe,GAExDO,IACJ,gBAAAf,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,IAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,WAAW,UAAAG,GAAO;AAAA,IAChCG,IACC,gBAAAN;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAMY,EAAY,CAACG,MAAM,CAACA,CAAC;AAAA,QACpC,iBAAeJ;AAAA,QACf,cAAW;AAAA,QAEV,cAAW,aAAa;AAAA,MAAA;AAAA,IAAA,IAEzB;AAAA,EAAA,GACN,GAGIK,IACJ,gBAAAjB,EAAC,OAAA,EAAI,WAAU,kBACZ,UAAA;AAAA,IAAAS,IACC,gBAAAT,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,MAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,iEAAA,CAAiE;AAAA,MAChF,gBAAAA,EAAC,OAAA,EAAI,WAAU,iEAAA,CAAiE;AAAA,MAChF,gBAAAA,EAAC,OAAA,EAAI,WAAU,iEAAA,CAAiE;AAAA,IAAA,EAAA,CAClF,IACEW,IACFP,EAAS,WAAW,IAClB,gBAAAJ,EAAC,OAAA,EAAI,WAAU,sKACZ,aACH,IAEAI,EAAS,IAAI,CAACa,GAAGC,MACf,gBAAAlB;AAAA,MAACN;AAAA,MAAA;AAAA,QAEC,OAAOuB,GAAG;AAAA,QACV,SAASA,GAAG;AAAA,QACZ,SAASA,GAAG;AAAA,QACZ,SAASnB,KAAWoB,MAAQ;AAAA,MAAA;AAAA,MAJvBD,GAAG,MAAMC;AAAA,IAAA,CAMjB,IAGH,gBAAAlB,EAAC,OAAA,EAAI,WAAU,8CAA6C,UAAA,cAAU;AAAA,IAGvEK,sBAAU,OAAA,EAAI,WAAWP,IAAU,yDAAyD,IAAK,aAAO,IAAS;AAAA,EAAA,GACpH;AAGF,SAAO,gBAAAE,EAACmB,KAAS,SAAQ,UAAS,QAAQL,GAAK,MAAAE,GAAa,GAAGN,GAAW;AAC5E;"}
1
+ {"version":3,"file":"WidgetCard.js","sources":["../../../../src/components/library/cards/WidgetCard.tsx"],"sourcesContent":["import React from \"react\";\nimport BaseCard, { BaseCardProps } from \"./BaseCard\";\nimport UIText from \"../ui/Text\";\n\nexport interface WidgetSection {\n id?: string | number;\n title?: string;\n actions?: React.ReactNode;\n content: React.ReactNode;\n}\n\ninterface SectionProps {\n title?: string;\n actions?: React.ReactNode;\n content: React.ReactNode;\n divided: boolean;\n}\n\nfunction Section({ title, actions, content, divided }: SectionProps) {\n return (\n <div className={divided ? \"border-t border-slate-200 pt-4 dark:border-slate-800\" : \"\"}>\n {(title || actions) ? (\n <div className=\"mb-3 flex items-start justify-between gap-3\">\n {title ? (\n <UIText as=\"div\" size=\"sm\" weight=\"medium\">\n {title}\n </UIText>\n ) : (\n <div />\n )}\n {actions ? <div className=\"shrink-0\">{actions}</div> : null}\n </div>\n ) : null}\n <div>{content}</div>\n </div>\n );\n}\n\nexport interface WidgetCardProps extends Omit<BaseCardProps, \"variant\" | \"header\" | \"body\"> {\n header: React.ReactNode;\n sections?: WidgetSection[];\n footer?: React.ReactNode;\n divided?: boolean;\n collapsible?: boolean;\n defaultExpanded?: boolean;\n loading?: boolean;\n emptyMessage?: string;\n}\n\nexport default function WidgetCard({\n header,\n sections = [],\n footer,\n divided = false,\n collapsible = false,\n defaultExpanded = true,\n loading = false,\n emptyMessage = \"No sections.\",\n ...cardProps\n}: WidgetCardProps) {\n const [expanded, setExpanded] = React.useState(defaultExpanded);\n\n const hdr = (\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">{header}</div>\n {collapsible ? (\n <button\n type=\"button\"\n className=\"rounded-lg border border-slate-200 bg-white px-2 py-1 text-xs font-semibold text-slate-700 shadow-sm hover:bg-slate-50 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-200 dark:hover:bg-slate-800\"\n onClick={() => setExpanded((e) => !e)}\n aria-expanded={expanded}\n aria-label=\"Toggle widget\"\n >\n {expanded ? \"Collapse\" : \"Expand\"}\n </button>\n ) : null}\n </div>\n );\n\n const body = (\n <div className=\"mt-4 space-y-4\">\n {loading ? (\n <div className=\"space-y-3\">\n <div className=\"h-4 w-1/3 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n <div className=\"h-4 w-2/3 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n <div className=\"h-4 w-1/2 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n </div>\n ) : expanded ? (\n sections.length === 0 ? (\n <div className=\"rounded-xl border border-dashed border-slate-300 bg-slate-50 p-6 text-center text-sm text-slate-600 dark:border-slate-700 dark:bg-slate-950/30 dark:text-slate-300\">\n {emptyMessage}\n </div>\n ) : (\n sections.map((s, idx) => (\n <Section\n key={s?.id ?? idx}\n title={s?.title}\n actions={s?.actions}\n content={s?.content}\n divided={divided && idx !== 0}\n />\n ))\n )\n ) : (\n <div className=\"text-sm text-slate-600 dark:text-slate-300\">Collapsed.</div>\n )}\n\n {footer ? <div className={divided ? \"border-t border-slate-200 pt-4 dark:border-slate-800\" : \"\"}>{footer}</div> : null}\n </div>\n );\n\n return <BaseCard variant=\"widget\" header={hdr} body={body} {...cardProps} />;\n}\n"],"names":["Section","title","actions","content","divided","jsxs","jsx","UIText","WidgetCard","header","sections","footer","collapsible","defaultExpanded","loading","emptyMessage","cardProps","expanded","setExpanded","React","hdr","e","body","s","idx","BaseCard"],"mappings":";;;;AAkBA,SAASA,EAAQ,EAAE,OAAAC,GAAO,SAAAC,GAAS,SAAAC,GAAS,SAAAC,KAAyB;AACnE,SACE,gBAAAC,EAAC,OAAA,EAAI,WAAWD,IAAU,yDAAyD,IAC/E,UAAA;AAAA,IAAAH,KAASC,IACT,gBAAAG,EAAC,OAAA,EAAI,WAAU,+CACZ,UAAA;AAAA,MAAAJ,IACC,gBAAAK,EAACC,GAAA,EAAO,IAAG,OAAM,MAAK,MAAK,QAAO,UAC/B,UAAAN,EAAA,CACH,IAEA,gBAAAK,EAAC,OAAA,EAAI;AAAA,MAENJ,IAAU,gBAAAI,EAAC,OAAA,EAAI,WAAU,YAAY,aAAQ,IAAS;AAAA,IAAA,EAAA,CACzD,IACE;AAAA,IACJ,gBAAAA,EAAC,SAAK,UAAAH,EAAA,CAAQ;AAAA,EAAA,GAChB;AAEJ;AAaA,SAAwBK,EAAW;AAAA,EACjC,QAAAC;AAAA,EACA,UAAAC,IAAW,CAAA;AAAA,EACX,QAAAC;AAAA,EACA,SAAAP,IAAU;AAAA,EACV,aAAAQ,IAAc;AAAA,EACd,iBAAAC,IAAkB;AAAA,EAClB,SAAAC,IAAU;AAAA,EACV,cAAAC,IAAe;AAAA,EACf,GAAGC;AACL,GAAoB;AAClB,QAAM,CAACC,GAAUC,CAAW,IAAIC,EAAM,SAASN,CAAe,GAExDO,IACJ,gBAAAf,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,IAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,WAAW,UAAAG,GAAO;AAAA,IAChCG,IACC,gBAAAN;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAMY,EAAY,CAACG,MAAM,CAACA,CAAC;AAAA,QACpC,iBAAeJ;AAAA,QACf,cAAW;AAAA,QAEV,cAAW,aAAa;AAAA,MAAA;AAAA,IAAA,IAEzB;AAAA,EAAA,GACN,GAGIK,IACJ,gBAAAjB,EAAC,OAAA,EAAI,WAAU,kBACZ,UAAA;AAAA,IAAAS,IACC,gBAAAT,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,MAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,iEAAA,CAAiE;AAAA,MAChF,gBAAAA,EAAC,OAAA,EAAI,WAAU,iEAAA,CAAiE;AAAA,MAChF,gBAAAA,EAAC,OAAA,EAAI,WAAU,iEAAA,CAAiE;AAAA,IAAA,EAAA,CAClF,IACEW,IACFP,EAAS,WAAW,IAClB,gBAAAJ,EAAC,OAAA,EAAI,WAAU,sKACZ,aACH,IAEAI,EAAS,IAAI,CAACa,GAAGC,MACf,gBAAAlB;AAAA,MAACN;AAAA,MAAA;AAAA,QAEC,OAAOuB,GAAG;AAAA,QACV,SAASA,GAAG;AAAA,QACZ,SAASA,GAAG;AAAA,QACZ,SAASnB,KAAWoB,MAAQ;AAAA,MAAA;AAAA,MAJvBD,GAAG,MAAMC;AAAA,IAAA,CAMjB,IAGH,gBAAAlB,EAAC,OAAA,EAAI,WAAU,8CAA6C,UAAA,cAAU;AAAA,IAGvEK,sBAAU,OAAA,EAAI,WAAWP,IAAU,yDAAyD,IAAK,aAAO,IAAS;AAAA,EAAA,GACpH;AAGF,SAAO,gBAAAE,EAACmB,KAAS,SAAQ,UAAS,QAAQL,GAAK,MAAAE,GAAa,GAAGN,GAAW;AAC5E;"}
@@ -1,22 +1,29 @@
1
+ import React from "react";
2
+ interface Dimensions {
3
+ width: number;
4
+ height: number;
5
+ }
6
+ export interface D3ChartProps {
7
+ data: unknown;
8
+ renderChart?: (svg: SVGSVGElement, data: unknown, dims: Dimensions, options: Record<string, unknown>) => void;
9
+ options?: Record<string, unknown>;
10
+ width?: number;
11
+ height?: number;
12
+ responsive?: boolean;
13
+ aspectRatio?: number;
14
+ className?: string;
15
+ style?: React.CSSProperties;
16
+ containerStyle?: React.CSSProperties;
17
+ svgStyle?: React.CSSProperties;
18
+ loading?: boolean;
19
+ error?: string | Error;
20
+ ariaLabel?: string;
21
+ }
1
22
  /**
2
23
  * Minimal D3 chart host:
3
24
  * - Owns the <svg> element
4
25
  * - Computes responsive dimensions from container size
5
26
  * - Calls renderChart(svgEl, data, dims, options)
6
27
  */
7
- export default function D3Chart({ data, renderChart, options, width, height, responsive, aspectRatio, className, style, containerStyle, svgStyle, loading, error, ariaLabel }: {
8
- data: any;
9
- renderChart: any;
10
- options?: {} | undefined;
11
- width: any;
12
- height?: number | undefined;
13
- responsive?: boolean | undefined;
14
- aspectRatio: any;
15
- className?: string | undefined;
16
- style: any;
17
- containerStyle: any;
18
- svgStyle: any;
19
- loading?: boolean | undefined;
20
- error: any;
21
- ariaLabel?: string | undefined;
22
- }): import("react/jsx-runtime").JSX.Element;
28
+ export default function D3Chart({ data, renderChart, options, width, height, responsive, aspectRatio, className, style, containerStyle, svgStyle, loading, error, ariaLabel }: D3ChartProps): React.ReactElement;
29
+ export {};
@@ -1 +1 @@
1
- {"version":3,"file":"D3Chart.js","sources":["../../../../src/components/library/charts/D3Chart.jsx"],"sourcesContent":["import React from \"react\";\n\n/**\n * Minimal D3 chart host:\n * - Owns the <svg> element\n * - Computes responsive dimensions from container size\n * - Calls renderChart(svgEl, data, dims, options)\n */\nexport default function D3Chart({\n data,\n renderChart,\n options = {},\n width,\n height = 280,\n responsive = false,\n aspectRatio,\n className = \"\",\n style,\n containerStyle,\n svgStyle,\n loading = false,\n error,\n ariaLabel = \"Chart\"\n}) {\n const containerRef = React.useRef(null);\n const svgRef = React.useRef(null);\n const [containerWidth, setContainerWidth] = React.useState(null);\n\n React.useEffect(() => {\n if (!responsive) return;\n const el = containerRef.current;\n if (!el) return;\n\n const obs = new ResizeObserver((entries) => {\n const w = entries?.[0]?.contentRect?.width;\n if (typeof w === \"number\" && Number.isFinite(w)) setContainerWidth(w);\n });\n obs.observe(el);\n return () => obs.disconnect();\n }, [responsive]);\n\n const computedWidth = responsive ? containerWidth : width;\n const computedHeight = React.useMemo(() => {\n if (!responsive) return height;\n if (!containerWidth) return height;\n if (aspectRatio && Number.isFinite(aspectRatio) && aspectRatio > 0) return containerWidth / aspectRatio;\n return height;\n }, [responsive, containerWidth, height, aspectRatio]);\n\n React.useEffect(() => {\n if (loading || error) return;\n if (!renderChart) return;\n const svgEl = svgRef.current;\n if (!svgEl) return;\n\n const dims = {\n width: computedWidth ?? 0,\n height: computedHeight ?? 0\n };\n\n // Avoid calling renderChart before we have a measurable width in responsive mode\n if (responsive && (!dims.width || dims.width < 10)) return;\n if (!dims.height || dims.height < 10) return;\n\n renderChart(svgEl, data, dims, options);\n }, [data, renderChart, options, computedWidth, computedHeight, responsive, loading, error]);\n\n if (error) {\n return (\n <div\n ref={containerRef}\n className={[\"w-full rounded-xl border border-rose-200 bg-rose-50 p-4 text-sm text-rose-900 dark:border-rose-900/40 dark:bg-rose-950/30 dark:text-rose-100\", className]\n .filter(Boolean)\n .join(\" \")}\n style={containerStyle}\n >\n {String(error)}\n </div>\n );\n }\n\n return (\n <div\n ref={containerRef}\n className={[\"w-full\", className].filter(Boolean).join(\" \")}\n style={{ ...containerStyle, position: \"relative\" }}\n >\n {loading ? (\n <div className=\"h-full w-full rounded-xl border border-slate-200 bg-white p-5 shadow-sm dark:border-slate-800 dark:bg-slate-900\">\n <div className=\"space-y-3\">\n <div className=\"h-4 w-1/3 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n <div className=\"h-44 w-full animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n </div>\n </div>\n ) : (\n <svg\n ref={svgRef}\n role=\"img\"\n aria-label={ariaLabel}\n width={computedWidth ?? width ?? \"100%\"}\n height={computedHeight}\n style={{ ...svgStyle, ...style, display: \"block\" }}\n />\n )}\n </div>\n );\n}\n\n\n"],"names":["D3Chart","data","renderChart","options","width","height","responsive","aspectRatio","className","style","containerStyle","svgStyle","loading","error","ariaLabel","containerRef","React","svgRef","containerWidth","setContainerWidth","el","obs","entries","w","computedWidth","computedHeight","svgEl","dims","jsx","jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"D3Chart.js","sources":["../../../../src/components/library/charts/D3Chart.tsx"],"sourcesContent":["import React from \"react\";\n\ninterface Dimensions {\n width: number;\n height: number;\n}\n\nexport interface D3ChartProps {\n data: unknown;\n renderChart?: (svg: SVGSVGElement, data: unknown, dims: Dimensions, options: Record<string, unknown>) => void;\n options?: Record<string, unknown>;\n width?: number;\n height?: number;\n responsive?: boolean;\n aspectRatio?: number;\n className?: string;\n style?: React.CSSProperties;\n containerStyle?: React.CSSProperties;\n svgStyle?: React.CSSProperties;\n loading?: boolean;\n error?: string | Error;\n ariaLabel?: string;\n}\n\n/**\n * Minimal D3 chart host:\n * - Owns the <svg> element\n * - Computes responsive dimensions from container size\n * - Calls renderChart(svgEl, data, dims, options)\n */\nexport default function D3Chart({\n data,\n renderChart,\n options = {},\n width,\n height = 280,\n responsive = false,\n aspectRatio,\n className = \"\",\n style,\n containerStyle,\n svgStyle,\n loading = false,\n error,\n ariaLabel = \"Chart\"\n}: D3ChartProps): React.ReactElement {\n const containerRef = React.useRef<HTMLDivElement>(null);\n const svgRef = React.useRef<SVGSVGElement>(null);\n const [containerWidth, setContainerWidth] = React.useState<number | null>(null);\n\n React.useEffect(() => {\n if (!responsive) return;\n const el = containerRef.current;\n if (!el) return;\n\n const obs = new ResizeObserver((entries) => {\n const w = entries?.[0]?.contentRect?.width;\n if (typeof w === \"number\" && Number.isFinite(w)) setContainerWidth(w);\n });\n obs.observe(el);\n return () => obs.disconnect();\n }, [responsive]);\n\n const computedWidth = responsive ? containerWidth : width;\n const computedHeight = React.useMemo(() => {\n if (!responsive) return height;\n if (!containerWidth) return height;\n if (aspectRatio && Number.isFinite(aspectRatio) && aspectRatio > 0) return containerWidth / aspectRatio;\n return height;\n }, [responsive, containerWidth, height, aspectRatio]);\n\n React.useEffect(() => {\n if (loading || error) return;\n if (!renderChart) return;\n const svgEl = svgRef.current;\n if (!svgEl) return;\n\n const dims: Dimensions = {\n width: computedWidth ?? 0,\n height: computedHeight ?? 0\n };\n\n // Avoid calling renderChart before we have a measurable width in responsive mode\n if (responsive && (!dims.width || dims.width < 10)) return;\n if (!dims.height || dims.height < 10) return;\n\n renderChart(svgEl, data, dims, options);\n }, [data, renderChart, options, computedWidth, computedHeight, responsive, loading, error]);\n\n if (error) {\n return (\n <div\n ref={containerRef}\n className={[\"w-full rounded-xl border border-rose-200 bg-rose-50 p-4 text-sm text-rose-900 dark:border-rose-900/40 dark:bg-rose-950/30 dark:text-rose-100\", className]\n .filter(Boolean)\n .join(\" \")}\n style={containerStyle}\n >\n {String(error)}\n </div>\n );\n }\n\n return (\n <div\n ref={containerRef}\n className={[\"w-full\", className].filter(Boolean).join(\" \")}\n style={{ ...containerStyle, position: \"relative\" }}\n >\n {loading ? (\n <div className=\"h-full w-full rounded-xl border border-slate-200 bg-white p-5 shadow-sm dark:border-slate-800 dark:bg-slate-900\">\n <div className=\"space-y-3\">\n <div className=\"h-4 w-1/3 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n <div className=\"h-44 w-full animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n </div>\n </div>\n ) : (\n <svg\n ref={svgRef}\n role=\"img\"\n aria-label={ariaLabel}\n width={computedWidth ?? width ?? \"100%\"}\n height={computedHeight}\n style={{ ...svgStyle, ...style, display: \"block\" }}\n />\n )}\n </div>\n );\n}\n"],"names":["D3Chart","data","renderChart","options","width","height","responsive","aspectRatio","className","style","containerStyle","svgStyle","loading","error","ariaLabel","containerRef","React","svgRef","containerWidth","setContainerWidth","el","obs","entries","w","computedWidth","computedHeight","svgEl","dims","jsx","jsxs"],"mappings":"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"}
@@ -1,4 +1,34 @@
1
- export namespace D3ChartTemplates {
2
- function lineChart(svg: any, data: any, dims: any, opts?: {}): void;
3
- function groupedBarChart(svg: any, data: any, dims: any, opts?: {}): void;
1
+ interface Dimensions {
2
+ width: number;
3
+ height: number;
4
4
  }
5
+ interface Margin {
6
+ top: number;
7
+ right: number;
8
+ bottom: number;
9
+ left: number;
10
+ }
11
+ interface LineChartOptions {
12
+ xKey?: string;
13
+ yKey?: string;
14
+ margin?: Margin;
15
+ stroke?: string;
16
+ strokeWidth?: number;
17
+ showAxes?: boolean;
18
+ showGrid?: boolean;
19
+ }
20
+ interface GroupedBarChartOptions {
21
+ groups?: string[];
22
+ margin?: Margin;
23
+ xKey?: string;
24
+ colors?: string[];
25
+ barRadius?: number;
26
+ yFormat?: string;
27
+ showGrid?: boolean;
28
+ }
29
+ type DataPoint = Record<string, unknown>;
30
+ export declare const D3ChartTemplates: {
31
+ lineChart(svg: SVGSVGElement, data: DataPoint[], dims: Dimensions, opts?: LineChartOptions): void;
32
+ groupedBarChart(svg: SVGSVGElement, data: DataPoint[], dims: Dimensions, opts?: GroupedBarChartOptions): void;
33
+ };
34
+ export {};
@@ -14,8 +14,8 @@ const F = {
14
14
  showGrid: A = !0
15
15
  } = w;
16
16
  C(n);
17
- const p = c.width, m = c.height, h = Math.max(0, p - r.left - r.right), i = Math.max(0, m - r.top - r.bottom), d = e.select(n).attr("viewBox", `0 0 ${p} ${m}`).append("g").attr("transform", `translate(${r.left},${r.top})`), x = l.map((t) => t?.[s]).filter((t) => t != null), f = l.map((t) => t?.[a]).filter((t) => t != null), g = e.extent(x), u = e.extent(f), y = e.scaleLinear().domain(g).nice().range([0, h]), o = e.scaleLinear().domain(u).nice().range([i, 0]);
18
- A && d.append("g").attr("class", "grid").call(e.axisLeft(o).ticks(5).tickSize(-h).tickFormat("")).call((t) => t.selectAll("line").attr("stroke", "currentColor").attr("opacity", 0.12)).call((t) => t.selectAll("path").attr("stroke", "none"));
17
+ const p = c.width, m = c.height, h = Math.max(0, p - r.left - r.right), i = Math.max(0, m - r.top - r.bottom), d = e.select(n).attr("viewBox", `0 0 ${p} ${m}`).append("g").attr("transform", `translate(${r.left},${r.top})`), g = l.map((t) => t?.[s]).filter((t) => t != null), x = l.map((t) => t?.[a]).filter((t) => t != null), f = e.extent(g), u = e.extent(x), y = e.scaleLinear().domain(f).nice().range([0, h]), o = e.scaleLinear().domain(u).nice().range([i, 0]);
18
+ A && d.append("g").attr("class", "grid").call(e.axisLeft(o).ticks(5).tickSize(-h).tickFormat(() => "")).call((t) => t.selectAll("line").attr("stroke", "currentColor").attr("opacity", 0.12)).call((t) => t.selectAll("path").attr("stroke", "none"));
19
19
  const B = e.line().x((t) => y(t[s])).y((t) => o(t[a])).defined((t) => t?.[s] != null && t?.[a] != null);
20
20
  d.append("path").datum(l).attr("fill", "none").attr("stroke", k).attr("stroke-width", b).attr("d", B), $ && (d.append("g").attr("transform", `translate(0,${i})`).call(e.axisBottom(y).ticks(6)).call((t) => t.selectAll("text").attr("font-size", 10)), d.append("g").call(e.axisLeft(o).ticks(5)).call((t) => t.selectAll("text").attr("font-size", 10)));
21
21
  },
@@ -30,11 +30,11 @@ const F = {
30
30
  showGrid: A = !0
31
31
  } = w;
32
32
  C(n);
33
- const p = c.width, m = c.height, h = Math.max(0, p - a.left - a.right), i = Math.max(0, m - a.top - a.bottom), x = e.select(n).attr("viewBox", `0 0 ${p} ${m}`).append("g").attr("transform", `translate(${a.left},${a.top})`), f = s.length ? s : Object.keys(l[0] || {}).filter((t) => t !== r), g = e.scaleBand().domain(l.map((t) => t[r])).range([0, h]).padding(0.3), u = e.scaleBand().domain(f).range([0, g.bandwidth()]).padding(0.05), y = e.max(l, (t) => e.max(f, (z) => t[z])) * 1.15, o = e.scaleLinear().domain([0, y]).range([i, 0]);
34
- x.append("g").attr("transform", `translate(0,${i})`).call(e.axisBottom(g).tickSize(0)).call((t) => t.selectAll("text").attr("fill", "#94a3b8").attr("font-size", "11px")).call((t) => t.select(".domain").remove()), x.append("g").call(e.axisLeft(o).ticks(5).tickFormat(e.format($)).tickSize(A ? -h : 0)).call((t) => t.selectAll("text").attr("fill", "#94a3b8").attr("font-size", "10px")).call((t) => t.selectAll(".tick line").attr("stroke", "#e2e8f0").attr("stroke-dasharray", "2,2")).call((t) => t.select(".domain").remove());
35
- const B = x.selectAll(".bar-group").data(l).join("g").attr("class", "bar-group").attr("transform", (t) => `translate(${g(t[r])},0)`);
36
- f.forEach((t, z) => {
37
- B.append("rect").attr("x", u(t)).attr("y", (L) => o(L[t])).attr("width", u.bandwidth()).attr("height", (L) => i - o(L[t])).attr("rx", b).attr("fill", k[z % k.length]);
33
+ const p = c.width, m = c.height, h = Math.max(0, p - a.left - a.right), i = Math.max(0, m - a.top - a.bottom), g = e.select(n).attr("viewBox", `0 0 ${p} ${m}`).append("g").attr("transform", `translate(${a.left},${a.top})`), x = s.length ? s : Object.keys(l[0] || {}).filter((t) => t !== r), f = e.scaleBand().domain(l.map((t) => String(t[r]))).range([0, h]).padding(0.3), u = e.scaleBand().domain(x).range([0, f.bandwidth()]).padding(0.05), y = (e.max(l, (t) => e.max(x, (z) => t[z])) ?? 0) * 1.15, o = e.scaleLinear().domain([0, y]).range([i, 0]);
34
+ g.append("g").attr("transform", `translate(0,${i})`).call(e.axisBottom(f).tickSize(0)).call((t) => t.selectAll("text").attr("fill", "#94a3b8").attr("font-size", "11px")).call((t) => t.select(".domain").remove()), g.append("g").call(e.axisLeft(o).ticks(5).tickFormat(e.format($)).tickSize(A ? -h : 0)).call((t) => t.selectAll("text").attr("fill", "#94a3b8").attr("font-size", "10px")).call((t) => t.selectAll(".tick line").attr("stroke", "#e2e8f0").attr("stroke-dasharray", "2,2")).call((t) => t.select(".domain").remove());
35
+ const B = g.selectAll(".bar-group").data(l).join("g").attr("class", "bar-group").attr("transform", (t) => `translate(${f(String(t[r]))},0)`);
36
+ x.forEach((t, z) => {
37
+ B.append("rect").attr("x", u(t) ?? 0).attr("y", (L) => o(L[t])).attr("width", u.bandwidth()).attr("height", (L) => i - o(L[t])).attr("rx", b).attr("fill", k[z % k.length]);
38
38
  });
39
39
  }
40
40
  };
@@ -1 +1 @@
1
- {"version":3,"file":"D3ChartTemplates.js","sources":["../../../../src/components/library/charts/D3ChartTemplates.jsx"],"sourcesContent":["import * as d3 from \"d3\";\n\nfunction clear(svg) {\n d3.select(svg).selectAll(\"*\").remove();\n}\n\nexport const D3ChartTemplates = {\n lineChart(svg, data, dims, opts = {}) {\n const {\n xKey = \"x\",\n yKey = \"y\",\n margin = { top: 12, right: 16, bottom: 28, left: 40 },\n stroke = \"#6366F1\",\n strokeWidth = 2,\n showAxes = true,\n showGrid = true\n } = opts;\n\n clear(svg);\n\n const width = dims.width;\n const height = dims.height;\n const innerW = Math.max(0, width - margin.left - margin.right);\n const innerH = Math.max(0, height - margin.top - margin.bottom);\n\n const g = d3.select(svg).attr(\"viewBox\", `0 0 ${width} ${height}`).append(\"g\").attr(\"transform\", `translate(${margin.left},${margin.top})`);\n\n const xs = data.map((d) => d?.[xKey]).filter((v) => v != null);\n const ys = data.map((d) => d?.[yKey]).filter((v) => v != null);\n\n const xDomain = d3.extent(xs);\n const yDomain = d3.extent(ys);\n\n const x = d3.scaleLinear().domain(xDomain).nice().range([0, innerW]);\n const y = d3.scaleLinear().domain(yDomain).nice().range([innerH, 0]);\n\n if (showGrid) {\n g.append(\"g\")\n .attr(\"class\", \"grid\")\n .call(d3.axisLeft(y).ticks(5).tickSize(-innerW).tickFormat(\"\"))\n .call((grid) => grid.selectAll(\"line\").attr(\"stroke\", \"currentColor\").attr(\"opacity\", 0.12))\n .call((grid) => grid.selectAll(\"path\").attr(\"stroke\", \"none\"));\n }\n\n const line = d3\n .line()\n .x((d) => x(d[xKey]))\n .y((d) => y(d[yKey]))\n .defined((d) => d?.[xKey] != null && d?.[yKey] != null);\n\n g.append(\"path\")\n .datum(data)\n .attr(\"fill\", \"none\")\n .attr(\"stroke\", stroke)\n .attr(\"stroke-width\", strokeWidth)\n .attr(\"d\", line);\n\n if (showAxes) {\n g.append(\"g\")\n .attr(\"transform\", `translate(0,${innerH})`)\n .call(d3.axisBottom(x).ticks(6))\n .call((ax) => ax.selectAll(\"text\").attr(\"font-size\", 10));\n\n g.append(\"g\")\n .call(d3.axisLeft(y).ticks(5))\n .call((ax) => ax.selectAll(\"text\").attr(\"font-size\", 10));\n }\n },\n\n groupedBarChart(svg, data, dims, opts = {}) {\n const {\n groups = [],\n margin = { top: 20, right: 20, bottom: 40, left: 55 },\n xKey = \"x\",\n colors = [\"#6366F1\", \"#CBD5E1\"],\n barRadius = 4,\n yFormat = \",.0f\",\n showGrid = true,\n } = opts;\n\n clear(svg);\n\n const width = dims.width;\n const height = dims.height;\n const innerW = Math.max(0, width - margin.left - margin.right);\n const innerH = Math.max(0, height - margin.top - margin.bottom);\n\n const sel = d3.select(svg).attr(\"viewBox\", `0 0 ${width} ${height}`);\n const g = sel.append(\"g\").attr(\"transform\", `translate(${margin.left},${margin.top})`);\n\n const groupKeys = groups.length ? groups : Object.keys(data[0] || {}).filter((k) => k !== xKey);\n\n const x0 = d3.scaleBand().domain(data.map((d) => d[xKey])).range([0, innerW]).padding(0.3);\n const x1 = d3.scaleBand().domain(groupKeys).range([0, x0.bandwidth()]).padding(0.05);\n const yMax = d3.max(data, (d) => d3.max(groupKeys, (k) => d[k])) * 1.15;\n const y = d3.scaleLinear().domain([0, yMax]).range([innerH, 0]);\n\n g.append(\"g\")\n .attr(\"transform\", `translate(0,${innerH})`)\n .call(d3.axisBottom(x0).tickSize(0))\n .call((ax) => ax.selectAll(\"text\").attr(\"fill\", \"#94a3b8\").attr(\"font-size\", \"11px\"))\n .call((ax) => ax.select(\".domain\").remove());\n\n g.append(\"g\")\n .call(d3.axisLeft(y).ticks(5).tickFormat(d3.format(yFormat)).tickSize(showGrid ? -innerW : 0))\n .call((ax) => ax.selectAll(\"text\").attr(\"fill\", \"#94a3b8\").attr(\"font-size\", \"10px\"))\n .call((ax) => ax.selectAll(\".tick line\").attr(\"stroke\", \"#e2e8f0\").attr(\"stroke-dasharray\", \"2,2\"))\n .call((ax) => ax.select(\".domain\").remove());\n\n const rows = g.selectAll(\".bar-group\").data(data).join(\"g\")\n .attr(\"class\", \"bar-group\")\n .attr(\"transform\", (d) => `translate(${x0(d[xKey])},0)`);\n\n groupKeys.forEach((key, i) => {\n rows.append(\"rect\")\n .attr(\"x\", x1(key))\n .attr(\"y\", (d) => y(d[key]))\n .attr(\"width\", x1.bandwidth())\n .attr(\"height\", (d) => innerH - y(d[key]))\n .attr(\"rx\", barRadius)\n .attr(\"fill\", colors[i % colors.length]);\n });\n },\n};\n\n\n"],"names":["clear","svg","d3","D3ChartTemplates","data","dims","opts","xKey","yKey","margin","stroke","strokeWidth","showAxes","showGrid","width","height","innerW","innerH","g","xs","d","v","ys","xDomain","yDomain","x","y","grid","line","ax","groups","colors","barRadius","yFormat","groupKeys","k","x0","x1","yMax","rows","key","i"],"mappings":"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"}
1
+ {"version":3,"file":"D3ChartTemplates.js","sources":["../../../../src/components/library/charts/D3ChartTemplates.tsx"],"sourcesContent":["import * as d3 from \"d3\";\n\ninterface Dimensions {\n width: number;\n height: number;\n}\n\ninterface Margin {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\ninterface LineChartOptions {\n xKey?: string;\n yKey?: string;\n margin?: Margin;\n stroke?: string;\n strokeWidth?: number;\n showAxes?: boolean;\n showGrid?: boolean;\n}\n\ninterface GroupedBarChartOptions {\n groups?: string[];\n margin?: Margin;\n xKey?: string;\n colors?: string[];\n barRadius?: number;\n yFormat?: string;\n showGrid?: boolean;\n}\n\ntype DataPoint = Record<string, unknown>;\n\nfunction clear(svg: SVGSVGElement): void {\n d3.select(svg).selectAll(\"*\").remove();\n}\n\nexport const D3ChartTemplates = {\n lineChart(svg: SVGSVGElement, data: DataPoint[], dims: Dimensions, opts: LineChartOptions = {}): void {\n const {\n xKey = \"x\",\n yKey = \"y\",\n margin = { top: 12, right: 16, bottom: 28, left: 40 },\n stroke = \"#6366F1\",\n strokeWidth = 2,\n showAxes = true,\n showGrid = true\n } = opts;\n\n clear(svg);\n\n const width = dims.width;\n const height = dims.height;\n const innerW = Math.max(0, width - margin.left - margin.right);\n const innerH = Math.max(0, height - margin.top - margin.bottom);\n\n const g = d3.select(svg).attr(\"viewBox\", `0 0 ${width} ${height}`).append(\"g\").attr(\"transform\", `translate(${margin.left},${margin.top})`);\n\n const xs = data.map((d) => d?.[xKey]).filter((v) => v != null) as number[];\n const ys = data.map((d) => d?.[yKey]).filter((v) => v != null) as number[];\n\n const xDomain = d3.extent(xs) as [number, number];\n const yDomain = d3.extent(ys) as [number, number];\n\n const x = d3.scaleLinear().domain(xDomain).nice().range([0, innerW]);\n const y = d3.scaleLinear().domain(yDomain).nice().range([innerH, 0]);\n\n if (showGrid) {\n g.append(\"g\")\n .attr(\"class\", \"grid\")\n .call(d3.axisLeft(y).ticks(5).tickSize(-innerW).tickFormat(() => \"\"))\n .call((grid: d3.Selection<SVGGElement, unknown, null, undefined>) => grid.selectAll(\"line\").attr(\"stroke\", \"currentColor\").attr(\"opacity\", 0.12))\n .call((grid: d3.Selection<SVGGElement, unknown, null, undefined>) => grid.selectAll(\"path\").attr(\"stroke\", \"none\"));\n }\n\n const line = d3\n .line<DataPoint>()\n .x((d) => x(d[xKey] as number))\n .y((d) => y(d[yKey] as number))\n .defined((d) => d?.[xKey] != null && d?.[yKey] != null);\n\n g.append(\"path\")\n .datum(data)\n .attr(\"fill\", \"none\")\n .attr(\"stroke\", stroke)\n .attr(\"stroke-width\", strokeWidth)\n .attr(\"d\", line);\n\n if (showAxes) {\n g.append(\"g\")\n .attr(\"transform\", `translate(0,${innerH})`)\n .call(d3.axisBottom(x).ticks(6))\n .call((ax: d3.Selection<SVGGElement, unknown, null, undefined>) => ax.selectAll(\"text\").attr(\"font-size\", 10));\n\n g.append(\"g\")\n .call(d3.axisLeft(y).ticks(5))\n .call((ax: d3.Selection<SVGGElement, unknown, null, undefined>) => ax.selectAll(\"text\").attr(\"font-size\", 10));\n }\n },\n\n groupedBarChart(svg: SVGSVGElement, data: DataPoint[], dims: Dimensions, opts: GroupedBarChartOptions = {}): void {\n const {\n groups = [],\n margin = { top: 20, right: 20, bottom: 40, left: 55 },\n xKey = \"x\",\n colors = [\"#6366F1\", \"#CBD5E1\"],\n barRadius = 4,\n yFormat = \",.0f\",\n showGrid = true,\n } = opts;\n\n clear(svg);\n\n const width = dims.width;\n const height = dims.height;\n const innerW = Math.max(0, width - margin.left - margin.right);\n const innerH = Math.max(0, height - margin.top - margin.bottom);\n\n const sel = d3.select(svg).attr(\"viewBox\", `0 0 ${width} ${height}`);\n const g = sel.append(\"g\").attr(\"transform\", `translate(${margin.left},${margin.top})`);\n\n const groupKeys = groups.length ? groups : Object.keys(data[0] || {}).filter((k) => k !== xKey);\n\n const x0 = d3.scaleBand().domain(data.map((d: DataPoint) => String(d[xKey]))).range([0, innerW]).padding(0.3);\n const x1 = d3.scaleBand().domain(groupKeys).range([0, x0.bandwidth()]).padding(0.05);\n const yMax = (d3.max(data, (d: DataPoint) => d3.max(groupKeys, (k: string) => d[k] as number)) ?? 0) * 1.15;\n const y = d3.scaleLinear().domain([0, yMax]).range([innerH, 0]);\n\n g.append(\"g\")\n .attr(\"transform\", `translate(0,${innerH})`)\n .call(d3.axisBottom(x0).tickSize(0))\n .call((ax: d3.Selection<SVGGElement, unknown, null, undefined>) => ax.selectAll(\"text\").attr(\"fill\", \"#94a3b8\").attr(\"font-size\", \"11px\"))\n .call((ax: d3.Selection<SVGGElement, unknown, null, undefined>) => ax.select(\".domain\").remove());\n\n g.append(\"g\")\n .call(d3.axisLeft(y).ticks(5).tickFormat(d3.format(yFormat)).tickSize(showGrid ? -innerW : 0))\n .call((ax: d3.Selection<SVGGElement, unknown, null, undefined>) => ax.selectAll(\"text\").attr(\"fill\", \"#94a3b8\").attr(\"font-size\", \"10px\"))\n .call((ax: d3.Selection<SVGGElement, unknown, null, undefined>) => ax.selectAll(\".tick line\").attr(\"stroke\", \"#e2e8f0\").attr(\"stroke-dasharray\", \"2,2\"))\n .call((ax: d3.Selection<SVGGElement, unknown, null, undefined>) => ax.select(\".domain\").remove());\n\n const rows = g.selectAll(\".bar-group\").data(data).join(\"g\")\n .attr(\"class\", \"bar-group\")\n .attr(\"transform\", (d: DataPoint) => `translate(${x0(String(d[xKey]))},0)`);\n\n groupKeys.forEach((key, i) => {\n rows.append(\"rect\")\n .attr(\"x\", x1(key) ?? 0)\n .attr(\"y\", (d: DataPoint) => y(d[key] as number))\n .attr(\"width\", x1.bandwidth())\n .attr(\"height\", (d: DataPoint) => innerH - y(d[key] as number))\n .attr(\"rx\", barRadius)\n .attr(\"fill\", colors[i % colors.length]);\n });\n },\n};\n"],"names":["clear","svg","d3","D3ChartTemplates","data","dims","opts","xKey","yKey","margin","stroke","strokeWidth","showAxes","showGrid","width","height","innerW","innerH","g","xs","d","v","ys","xDomain","yDomain","x","y","grid","line","ax","groups","colors","barRadius","yFormat","groupKeys","k","x0","x1","yMax","rows","key","i"],"mappings":"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"}
@@ -1,18 +1,81 @@
1
- export default function GeoMap({ width, height, projection: projType, theme, markers, arcs, overlays, selectedId, onArcClick, onMarkerClick, zoomable, minZoom, maxZoom, initialBounds, className, children, }: {
2
- width?: number | undefined;
3
- height?: number | undefined;
4
- projection?: string | undefined;
5
- theme?: string | undefined;
6
- markers?: never[] | undefined;
7
- arcs?: never[] | undefined;
8
- overlays?: never[] | undefined;
9
- selectedId?: null | undefined;
10
- onArcClick: any;
11
- onMarkerClick: any;
12
- zoomable?: boolean | undefined;
13
- minZoom?: number | undefined;
14
- maxZoom?: number | undefined;
15
- initialBounds?: null | undefined;
16
- className?: string | undefined;
17
- children: any;
18
- }): import("react/jsx-runtime").JSX.Element;
1
+ import React from "react";
2
+ import * as d3 from "d3";
3
+ type ProjectionType = "naturalEarth" | "mercator" | "equirectangular";
4
+ interface Theme {
5
+ bg: string;
6
+ bgGradient: [string, string];
7
+ land: string;
8
+ landStroke: string;
9
+ sphere: string;
10
+ graticule: string;
11
+ graticuleOpacity: number;
12
+ markerActive: string;
13
+ markerInactive: string;
14
+ label: string;
15
+ labelInactive: string;
16
+ arc: string;
17
+ arcHighlight: string;
18
+ arcDanger: string;
19
+ dot: string;
20
+ dotDanger: string;
21
+ overlayFill: string;
22
+ overlayStroke: string;
23
+ }
24
+ type ThemeName = "dark" | "light";
25
+ export interface Marker {
26
+ id: string;
27
+ lon: number;
28
+ lat: number;
29
+ label?: string | false;
30
+ active?: boolean;
31
+ }
32
+ export interface Arc {
33
+ id: string;
34
+ from: [number, number];
35
+ to: [number, number];
36
+ danger?: boolean;
37
+ color?: string;
38
+ dotColor?: string;
39
+ progress?: number;
40
+ _path?: string | null;
41
+ }
42
+ export interface Overlay {
43
+ id: string;
44
+ center: [number, number];
45
+ radius?: number;
46
+ fill?: string;
47
+ stroke?: string;
48
+ }
49
+ export interface InitialBounds {
50
+ sw: [number, number];
51
+ ne: [number, number];
52
+ padding?: number;
53
+ }
54
+ interface ChildrenFunctionProps {
55
+ proj: d3.GeoProjection;
56
+ pathGen: d3.GeoPath;
57
+ theme: Theme;
58
+ width: number;
59
+ height: number;
60
+ transform: d3.ZoomTransform;
61
+ }
62
+ export interface GeoMapProps {
63
+ width?: number;
64
+ height?: number;
65
+ projection?: ProjectionType;
66
+ theme?: ThemeName;
67
+ markers?: Marker[];
68
+ arcs?: Arc[];
69
+ overlays?: Overlay[];
70
+ selectedId?: string | null;
71
+ onArcClick?: (arc: Arc) => void;
72
+ onMarkerClick?: (marker: Marker) => void;
73
+ zoomable?: boolean;
74
+ minZoom?: number;
75
+ maxZoom?: number;
76
+ initialBounds?: InitialBounds | null;
77
+ className?: string;
78
+ children?: React.ReactNode | ((props: ChildrenFunctionProps) => React.ReactNode);
79
+ }
80
+ export default function GeoMap({ width, height, projection: projType, theme, markers, arcs, overlays, selectedId, onArcClick, onMarkerClick, zoomable, minZoom, maxZoom, initialBounds, className, children, }: GeoMapProps): React.ReactElement;
81
+ export {};