@schandlergarcia/sf-web-components 1.7.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 (114) 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/layout/PageContainer.d.ts +6 -4
  79. package/dist/components/library/layout/PageContainer.js +4 -5
  80. package/dist/components/library/layout/PageContainer.js.map +1 -1
  81. package/package.json +4 -1
  82. package/src/components/library/cards/{ActionList.jsx → ActionList.tsx} +13 -9
  83. package/src/components/library/cards/{ActivityCard.jsx → ActivityCard.tsx} +33 -4
  84. package/src/components/library/cards/{BaseCard.jsx → BaseCard.tsx} +33 -6
  85. package/src/components/library/cards/{CalloutCard.jsx → CalloutCard.tsx} +12 -10
  86. package/src/components/library/cards/{ChartCard.jsx → ChartCard.tsx} +32 -6
  87. package/src/components/library/cards/{FeedPanel.jsx → FeedPanel.tsx} +13 -2
  88. package/src/components/library/cards/{ListCard.jsx → ListCard.tsx} +43 -7
  89. package/src/components/library/cards/{MetricCard.jsx → MetricCard.tsx} +25 -6
  90. package/src/components/library/cards/{MetricsStrip.jsx → MetricsStrip.tsx} +22 -12
  91. package/src/components/library/cards/{SectionCard.jsx → SectionCard.tsx} +27 -8
  92. package/src/components/library/cards/{SemanticMetricCard.jsx → SemanticMetricCard.tsx} +17 -5
  93. package/src/components/library/cards/{SemanticMetricCardWithLoading.jsx → SemanticMetricCardWithLoading.tsx} +9 -3
  94. package/src/components/library/cards/{SemanticTableCard.jsx → SemanticTableCard.tsx} +14 -3
  95. package/src/components/library/cards/{SemanticTableCardWithLoading.jsx → SemanticTableCardWithLoading.tsx} +9 -5
  96. package/src/components/library/cards/{StatusCard.jsx → StatusCard.tsx} +61 -12
  97. package/src/components/library/cards/{TableCard.jsx → TableCard.tsx} +51 -12
  98. package/src/components/library/cards/{WidgetCard.jsx → WidgetCard.tsx} +28 -5
  99. package/src/components/library/charts/{D3Chart.jsx → D3Chart.tsx} +27 -7
  100. package/src/components/library/charts/{D3ChartTemplates.jsx → D3ChartTemplates.tsx} +60 -28
  101. package/src/components/library/charts/{GeoMap.jsx → GeoMap.tsx} +106 -17
  102. package/src/components/library/filters/{FilterBar.jsx → FilterBar.tsx} +21 -11
  103. package/src/components/library/filters/{SearchFilter.jsx → SearchFilter.tsx} +8 -2
  104. package/src/components/library/filters/{SelectFilter.jsx → SelectFilter.tsx} +15 -8
  105. package/src/components/library/filters/{ToggleFilter.jsx → ToggleFilter.tsx} +7 -6
  106. package/src/components/library/forms/{FormField.jsx → FormField.tsx} +91 -45
  107. package/src/components/library/forms/{FormModal.jsx → FormModal.tsx} +21 -20
  108. package/src/components/library/forms/{FormRenderer.jsx → FormRenderer.tsx} +32 -10
  109. package/src/components/library/forms/{FormSection.jsx → FormSection.tsx} +13 -7
  110. package/src/components/library/forms/index.tsx +11 -0
  111. package/src/components/library/forms/{useFormState.jsx → useFormState.tsx} +43 -23
  112. package/src/components/library/layout/{PageContainer.jsx → PageContainer.tsx} +6 -3
  113. package/src/components/library/forms/index.jsx +0 -5
  114. /package/src/components/library/filters/{index.jsx → index.ts} +0 -0
@@ -1,4 +1,4 @@
1
- import { jsxs as p, jsx as o } from "react/jsx-runtime";
1
+ import { jsxs as p, jsx as n } from "react/jsx-runtime";
2
2
  import { useRef as P, useState as ce, useMemo as w, useEffect as F, useCallback as le } from "react";
3
3
  import * as a from "d3";
4
4
  import { feature as se } from "topojson-client";
@@ -70,7 +70,7 @@ function he({
70
70
  className: B = "",
71
71
  children: N
72
72
  }) {
73
- const n = q[D] ?? q.dark, g = P(null), [d, J] = ce(a.zoomIdentity), b = P(null), { proj: l, pathGen: Y, graticulePath: K, spherePath: L, landPath: Q } = w(() => {
73
+ const o = q[D] ?? q.dark, g = P(null), [d, J] = ce(a.zoomIdentity), b = P(null), { proj: l, pathGen: Y, graticulePath: K, spherePath: L, landPath: Q } = w(() => {
74
74
  const e = fe(k, s, i), t = a.geoPath(e);
75
75
  return {
76
76
  proj: e,
@@ -83,7 +83,9 @@ function he({
83
83
  F(() => {
84
84
  if (!x || !g.current) return;
85
85
  const e = a.select(g.current), t = a.zoom().scaleExtent([S, M]).on("zoom", (r) => J(r.transform));
86
- return b.current = t, e.call(t), () => e.on(".zoom", null);
86
+ return b.current = t, e.call(t), () => {
87
+ e.on(".zoom", null);
88
+ };
87
89
  }, [x, S, M]);
88
90
  const C = P(!1);
89
91
  F(() => {
@@ -92,7 +94,7 @@ function he({
92
94
  if (!c || !u) return;
93
95
  const m = Math.min(c[0], u[0]), h = Math.min(c[1], u[1]), y = Math.max(c[0], u[0]), W = Math.max(c[1], u[1]), O = y - m, A = W - h;
94
96
  if (O < 1 || A < 1) return;
95
- const I = Math.min((s - r * 2) / O, (i - r * 2) / A), ee = (m + y) / 2, te = (h + W) / 2, re = s / 2 - ee * I, ne = i / 2 - te * I, oe = Math.max(S, Math.min(M, I)), ae = a.zoomIdentity.translate(re, ne).scale(oe);
97
+ const I = Math.min((s - r * 2) / O, (i - r * 2) / A), ee = (m + y) / 2, te = (h + W) / 2, re = s / 2 - ee * I, oe = i / 2 - te * I, ne = Math.max(S, Math.min(M, I)), ae = a.zoomIdentity.translate(re, oe).scale(ne);
96
98
  a.select(g.current).call(b.current.transform, ae), C.current = !0;
97
99
  }, [$, l, s, i, S, M]);
98
100
  const U = le(() => {
@@ -119,44 +121,44 @@ function he({
119
121
  t.active && e.add(t.id);
120
122
  }), e;
121
123
  }, [G]), Z = `translate(${d.x},${d.y}) scale(${d.k})`, f = 1 / d.k;
122
- return /* @__PURE__ */ p("div", { className: `relative overflow-hidden ${B}`, style: { background: n.bg }, children: [
124
+ return /* @__PURE__ */ p("div", { className: `relative overflow-hidden ${B}`, style: { background: o.bg }, children: [
123
125
  /* @__PURE__ */ p("svg", { ref: g, viewBox: `0 0 ${s} ${i}`, className: "h-full w-full", preserveAspectRatio: "xMidYMid slice", style: x ? { cursor: "grab" } : void 0, children: [
124
126
  /* @__PURE__ */ p("defs", { children: [
125
127
  /* @__PURE__ */ p("radialGradient", { id: "geo-bg", cx: "50%", cy: "50%", r: "55%", children: [
126
- /* @__PURE__ */ o("stop", { offset: "0%", stopColor: n.bgGradient[0] }),
127
- /* @__PURE__ */ o("stop", { offset: "100%", stopColor: n.bgGradient[1] })
128
+ /* @__PURE__ */ n("stop", { offset: "0%", stopColor: o.bgGradient[0] }),
129
+ /* @__PURE__ */ n("stop", { offset: "100%", stopColor: o.bgGradient[1] })
128
130
  ] }),
129
131
  /* @__PURE__ */ p("filter", { id: "geo-glow", x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
130
- /* @__PURE__ */ o("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "3", result: "b" }),
132
+ /* @__PURE__ */ n("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "3", result: "b" }),
131
133
  /* @__PURE__ */ p("feMerge", { children: [
132
- /* @__PURE__ */ o("feMergeNode", { in: "b" }),
133
- /* @__PURE__ */ o("feMergeNode", { in: "SourceGraphic" })
134
+ /* @__PURE__ */ n("feMergeNode", { in: "b" }),
135
+ /* @__PURE__ */ n("feMergeNode", { in: "SourceGraphic" })
134
136
  ] })
135
137
  ] })
136
138
  ] }),
137
- /* @__PURE__ */ o("style", { children: `
139
+ /* @__PURE__ */ n("style", { children: `
138
140
  .geo-arc{stroke-dasharray:8,6;animation:geo-flow 1.5s linear infinite}
139
141
  @keyframes geo-flow{to{stroke-dashoffset:-14}}
140
142
  .geo-dot{animation:geo-pulse 2s ease-in-out infinite}
141
143
  @keyframes geo-pulse{0%,100%{opacity:1}50%{opacity:.5}}
142
144
  ` }),
143
- /* @__PURE__ */ o("rect", { width: s, height: i, fill: "url(#geo-bg)" }),
145
+ /* @__PURE__ */ n("rect", { width: s, height: i, fill: "url(#geo-bg)" }),
144
146
  /* @__PURE__ */ p("g", { transform: Z, children: [
145
- /* @__PURE__ */ o("path", { d: L, fill: "none", stroke: n.sphere, strokeWidth: 0.8 * f }),
146
- /* @__PURE__ */ o("path", { d: Q, fill: n.land, stroke: n.landStroke, strokeWidth: 0.4 * f }),
147
- /* @__PURE__ */ o("path", { d: K, fill: "none", stroke: n.graticule, strokeWidth: 0.3 * f, opacity: n.graticuleOpacity }),
147
+ /* @__PURE__ */ n("path", { d: L ?? void 0, fill: "none", stroke: o.sphere, strokeWidth: 0.8 * f }),
148
+ /* @__PURE__ */ n("path", { d: Q ?? void 0, fill: o.land, stroke: o.landStroke, strokeWidth: 0.4 * f }),
149
+ /* @__PURE__ */ n("path", { d: K ?? void 0, fill: "none", stroke: o.graticule, strokeWidth: 0.3 * f, opacity: o.graticuleOpacity }),
148
150
  T.map((e) => {
149
151
  const t = l(e.center);
150
152
  if (!t) return null;
151
153
  const r = l([e.center[0] + (e.radius ?? 5), e.center[1]]), c = r ? Math.abs(r[0] - t[0]) : 30;
152
- return /* @__PURE__ */ o(
154
+ return /* @__PURE__ */ n(
153
155
  "circle",
154
156
  {
155
157
  cx: t[0],
156
158
  cy: t[1],
157
159
  r: c,
158
- fill: e.fill ?? n.overlayFill,
159
- stroke: e.stroke ?? n.overlayStroke,
160
+ fill: e.fill ?? o.overlayFill,
161
+ stroke: e.stroke ?? o.overlayStroke,
160
162
  strokeWidth: 1 * f,
161
163
  strokeDasharray: "5,5",
162
164
  className: "animate-pulse"
@@ -167,12 +169,12 @@ function he({
167
169
  R.map((e) => {
168
170
  if (!e._path) return null;
169
171
  const t = v === e.id, r = e.danger;
170
- return /* @__PURE__ */ o(
172
+ return /* @__PURE__ */ n(
171
173
  "path",
172
174
  {
173
175
  d: e._path,
174
176
  fill: "none",
175
- stroke: r ? n.arcDanger : t ? n.arcHighlight : e.color ?? n.arc,
177
+ stroke: r ? o.arcDanger : t ? o.arcHighlight : e.color ?? o.arc,
176
178
  strokeWidth: (t ? 3 : 2) * f,
177
179
  opacity: v != null && !t ? 0.15 : r ? 0.85 : 0.65,
178
180
  className: "geo-arc cursor-pointer",
@@ -186,8 +188,8 @@ function he({
186
188
  if (!t) return null;
187
189
  const r = e.active ?? X.has(e.id);
188
190
  return /* @__PURE__ */ p("g", { className: z ? "cursor-pointer" : "", onClick: () => z?.(e), children: [
189
- /* @__PURE__ */ o("circle", { cx: t[0], cy: t[1], r: (r ? 3 : 2) * f, fill: r ? n.markerActive : n.markerInactive }),
190
- e.label !== !1 && /* @__PURE__ */ o("text", { x: t[0] + 6 * f, y: t[1] + 4 * f, fontSize: 8 * f, fill: r ? n.label : n.labelInactive, fontFamily: "sans-serif", fontWeight: 600, children: e.label ?? e.id })
191
+ /* @__PURE__ */ n("circle", { cx: t[0], cy: t[1], r: (r ? 3 : 2) * f, fill: r ? o.markerActive : o.markerInactive }),
192
+ e.label !== !1 && /* @__PURE__ */ n("text", { x: t[0] + 6 * f, y: t[1] + 4 * f, fontSize: 8 * f, fill: r ? o.label : o.labelInactive, fontFamily: "sans-serif", fontWeight: 600, children: e.label ?? e.id })
191
193
  ] }, e.id);
192
194
  }),
193
195
  R.map((e) => {
@@ -195,13 +197,13 @@ function he({
195
197
  const t = a.geoInterpolate(e.from, e.to), r = l(t(Math.min(e.progress, 0.99)));
196
198
  if (!r) return null;
197
199
  const c = v === e.id;
198
- return /* @__PURE__ */ o(
200
+ return /* @__PURE__ */ n(
199
201
  "circle",
200
202
  {
201
203
  cx: r[0],
202
204
  cy: r[1],
203
205
  r: (c ? 6 : 4.5) * f,
204
- fill: e.danger ? n.dotDanger : e.dotColor ?? n.dot,
206
+ fill: e.danger ? o.dotDanger : e.dotColor ?? o.dot,
205
207
  filter: "url(#geo-glow)",
206
208
  className: "geo-dot cursor-pointer",
207
209
  opacity: v != null && !c ? 0.3 : 1,
@@ -210,10 +212,10 @@ function he({
210
212
  `dot-${e.id}`
211
213
  );
212
214
  }),
213
- typeof N == "function" ? N({ proj: l, pathGen: Y, theme: n, width: s, height: i, transform: d }) : N
215
+ typeof N == "function" ? N({ proj: l, pathGen: Y, theme: o, width: s, height: i, transform: d }) : N
214
216
  ] })
215
217
  ] }),
216
- x && V && /* @__PURE__ */ o(
218
+ x && V && /* @__PURE__ */ n(
217
219
  "button",
218
220
  {
219
221
  onClick: U,
@@ -1 +1 @@
1
- {"version":3,"file":"GeoMap.js","sources":["../../../../src/components/library/charts/GeoMap.jsx"],"sourcesContent":["import React, { useMemo, useRef, useEffect, useState, useCallback } from \"react\";\nimport * as d3 from \"d3\";\nimport { feature } from \"topojson-client\";\nimport world from \"world-atlas/land-110m.json\";\n\nconst land = feature(world, world.objects.land);\n\nconst PROJECTIONS = {\n naturalEarth: d3.geoNaturalEarth1,\n mercator: d3.geoMercator,\n equirectangular: d3.geoEquirectangular,\n};\n\nconst THEMES = {\n dark: {\n bg: \"#050b15\",\n bgGradient: [\"#0a1628\", \"#050b15\"],\n land: \"#1a2d4a\",\n landStroke: \"#2a4060\",\n sphere: \"#1e3a5f\",\n graticule: \"#162a45\",\n graticuleOpacity: 0.35,\n markerActive: \"#cbd5e1\",\n markerInactive: \"#64748b\",\n label: \"#cbd5e1\",\n labelInactive: \"#64748b\",\n arc: \"#818cf8\",\n arcHighlight: \"#c4b5fd\",\n arcDanger: \"#f87171\",\n dot: \"#a5b4fc\",\n dotDanger: \"#f87171\",\n overlayFill: \"rgba(248,113,113,0.10)\",\n overlayStroke: \"rgba(248,113,113,0.30)\",\n },\n light: {\n bg: \"#f8fafc\",\n bgGradient: [\"#f8fafc\", \"#f1f5f9\"],\n land: \"#e2e8f0\",\n landStroke: \"#cbd5e1\",\n sphere: \"#cbd5e1\",\n graticule: \"#e2e8f0\",\n graticuleOpacity: 0.6,\n markerActive: \"#334155\",\n markerInactive: \"#94a3b8\",\n label: \"#334155\",\n labelInactive: \"#94a3b8\",\n arc: \"#6366f1\",\n arcHighlight: \"#4f46e5\",\n arcDanger: \"#ef4444\",\n dot: \"#6366f1\",\n dotDanger: \"#ef4444\",\n overlayFill: \"rgba(239,68,68,0.08)\",\n overlayStroke: \"rgba(239,68,68,0.3)\",\n },\n};\n\nfunction buildProjection(type, width, height) {\n const factory = PROJECTIONS[type] ?? PROJECTIONS.naturalEarth;\n return factory().fitSize([width, height], { type: \"Sphere\" });\n}\n\nexport default function GeoMap({\n width = 960,\n height = 480,\n projection: projType = \"naturalEarth\",\n theme = \"dark\",\n markers = [],\n arcs = [],\n overlays = [],\n selectedId = null,\n onArcClick,\n onMarkerClick,\n zoomable = true,\n minZoom = 1,\n maxZoom = 8,\n initialBounds = null,\n className = \"\",\n children,\n}) {\n const t = THEMES[theme] ?? THEMES.dark;\n const svgRef = useRef(null);\n const [transform, setTransform] = useState(d3.zoomIdentity);\n const zoomRef = useRef(null);\n\n const { proj, pathGen, graticulePath, spherePath, landPath } = useMemo(() => {\n const proj = buildProjection(projType, width, height);\n const pathGen = d3.geoPath(proj);\n return {\n proj,\n pathGen,\n graticulePath: pathGen(d3.geoGraticule10()),\n spherePath: pathGen({ type: \"Sphere\" }),\n landPath: pathGen(land),\n };\n }, [projType, width, height]);\n\n // D3 zoom behavior\n useEffect(() => {\n if (!zoomable || !svgRef.current) return;\n const svg = d3.select(svgRef.current);\n const zoom = d3.zoom()\n .scaleExtent([minZoom, maxZoom])\n .on(\"zoom\", (e) => setTransform(e.transform));\n zoomRef.current = zoom;\n svg.call(zoom);\n return () => svg.on(\".zoom\", null);\n }, [zoomable, minZoom, maxZoom]);\n\n // Apply initial zoom to fit bounds (markers/region) on mount\n const initialBoundsApplied = useRef(false);\n useEffect(() => {\n if (!initialBounds || initialBoundsApplied.current) return;\n if (!svgRef.current || !zoomRef.current || !proj) return;\n const { sw, ne, padding = 40 } = initialBounds; // sw=[lonMin,latMin], ne=[lonMax,latMax]\n const p0 = proj(sw);\n const p1 = proj(ne);\n if (!p0 || !p1) return;\n const bx0 = Math.min(p0[0], p1[0]);\n const by0 = Math.min(p0[1], p1[1]);\n const bx1 = Math.max(p0[0], p1[0]);\n const by1 = Math.max(p0[1], p1[1]);\n const bw = bx1 - bx0;\n const bh = by1 - by0;\n if (bw < 1 || bh < 1) return;\n const scale = Math.min((width - padding * 2) / bw, (height - padding * 2) / bh);\n const cx = (bx0 + bx1) / 2;\n const cy = (by0 + by1) / 2;\n const tx = width / 2 - cx * scale;\n const ty = height / 2 - cy * scale;\n const clampedScale = Math.max(minZoom, Math.min(maxZoom, scale));\n const t = d3.zoomIdentity.translate(tx, ty).scale(clampedScale);\n d3.select(svgRef.current).call(zoomRef.current.transform, t);\n initialBoundsApplied.current = true;\n }, [initialBounds, proj, width, height, minZoom, maxZoom]);\n\n const resetZoom = useCallback(() => {\n if (!svgRef.current || !zoomRef.current) return;\n d3.select(svgRef.current)\n .transition()\n .duration(400)\n .call(zoomRef.current.transform, d3.zoomIdentity);\n }, []);\n\n const isZoomed = transform.k !== 1 || transform.x !== 0 || transform.y !== 0;\n\n const arcPaths = useMemo(() => {\n const cache = {};\n arcs.forEach(a => {\n const key = `${a.from[0]},${a.from[1]}-${a.to[0]},${a.to[1]}`;\n if (cache[key]) { a._path = cache[key]; return; }\n const interp = d3.geoInterpolate(a.from, a.to);\n const pts = [];\n for (let i = 0; i <= 1; i += 0.02) {\n const p = proj(interp(i));\n if (p) pts.push(p);\n }\n const path = pts.length > 1 ? d3.line()(pts) : null;\n cache[key] = path;\n a._path = path;\n });\n return arcs;\n }, [arcs, proj]);\n\n const activeMarkerIds = useMemo(() => {\n const s = new Set();\n markers.forEach(m => { if (m.active) s.add(m.id); });\n return s;\n }, [markers]);\n\n const txStr = `translate(${transform.x},${transform.y}) scale(${transform.k})`;\n const invScale = 1 / transform.k;\n\n return (\n <div className={`relative overflow-hidden ${className}`} style={{ background: t.bg }}>\n <svg ref={svgRef} viewBox={`0 0 ${width} ${height}`} className=\"h-full w-full\" preserveAspectRatio=\"xMidYMid slice\" style={zoomable ? { cursor: \"grab\" } : undefined}>\n <defs>\n <radialGradient id=\"geo-bg\" cx=\"50%\" cy=\"50%\" r=\"55%\">\n <stop offset=\"0%\" stopColor={t.bgGradient[0]} />\n <stop offset=\"100%\" stopColor={t.bgGradient[1]} />\n </radialGradient>\n <filter id=\"geo-glow\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"3\" result=\"b\" />\n <feMerge><feMergeNode in=\"b\" /><feMergeNode in=\"SourceGraphic\" /></feMerge>\n </filter>\n </defs>\n <style>{`\n .geo-arc{stroke-dasharray:8,6;animation:geo-flow 1.5s linear infinite}\n @keyframes geo-flow{to{stroke-dashoffset:-14}}\n .geo-dot{animation:geo-pulse 2s ease-in-out infinite}\n @keyframes geo-pulse{0%,100%{opacity:1}50%{opacity:.5}}\n `}</style>\n\n <rect width={width} height={height} fill=\"url(#geo-bg)\" />\n\n {/* Zoomable content group */}\n <g transform={txStr}>\n <path d={spherePath} fill=\"none\" stroke={t.sphere} strokeWidth={0.8 * invScale} />\n <path d={landPath} fill={t.land} stroke={t.landStroke} strokeWidth={0.4 * invScale} />\n <path d={graticulePath} fill=\"none\" stroke={t.graticule} strokeWidth={0.3 * invScale} opacity={t.graticuleOpacity} />\n\n {/* Overlay zones (disruptions, weather) */}\n {overlays.map(o => {\n const c = proj(o.center);\n if (!c) return null;\n const edge = proj([o.center[0] + (o.radius ?? 5), o.center[1]]);\n const r = edge ? Math.abs(edge[0] - c[0]) : 30;\n return (\n <circle\n key={o.id}\n cx={c[0]} cy={c[1]} r={r}\n fill={o.fill ?? t.overlayFill}\n stroke={o.stroke ?? t.overlayStroke}\n strokeWidth={1 * invScale}\n strokeDasharray=\"5,5\"\n className=\"animate-pulse\"\n />\n );\n })}\n\n {/* Arcs */}\n {arcPaths.map(a => {\n if (!a._path) return null;\n const sel = selectedId === a.id;\n const danger = a.danger;\n return (\n <path\n key={`arc-${a.id}`}\n d={a._path}\n fill=\"none\"\n stroke={danger ? t.arcDanger : sel ? t.arcHighlight : a.color ?? t.arc}\n strokeWidth={(sel ? 3 : 2) * invScale}\n opacity={selectedId != null && !sel ? 0.15 : danger ? 0.85 : 0.65}\n className=\"geo-arc cursor-pointer\"\n onClick={() => onArcClick?.(a)}\n />\n );\n })}\n\n {/* Markers */}\n {markers.map(m => {\n const p = proj([m.lon, m.lat]);\n if (!p) return null;\n const active = m.active ?? activeMarkerIds.has(m.id);\n return (\n <g key={m.id} className={onMarkerClick ? \"cursor-pointer\" : \"\"} onClick={() => onMarkerClick?.(m)}>\n <circle cx={p[0]} cy={p[1]} r={(active ? 3 : 2) * invScale} fill={active ? t.markerActive : t.markerInactive} />\n {m.label !== false && (\n <text x={p[0] + 6 * invScale} y={p[1] + 4 * invScale} fontSize={8 * invScale} fill={active ? t.label : t.labelInactive} fontFamily=\"sans-serif\" fontWeight={600}>\n {m.label ?? m.id}\n </text>\n )}\n </g>\n );\n })}\n\n {/* Moving dots (flight positions) */}\n {arcPaths.map(a => {\n if (a.progress == null || a.progress <= 0) return null;\n const interp = d3.geoInterpolate(a.from, a.to);\n const p = proj(interp(Math.min(a.progress, 0.99)));\n if (!p) return null;\n const sel = selectedId === a.id;\n return (\n <circle\n key={`dot-${a.id}`}\n cx={p[0]} cy={p[1]}\n r={(sel ? 6 : 4.5) * invScale}\n fill={a.danger ? t.dotDanger : a.dotColor ?? t.dot}\n filter=\"url(#geo-glow)\"\n className=\"geo-dot cursor-pointer\"\n opacity={selectedId != null && !sel ? 0.3 : 1}\n onClick={() => onArcClick?.(a)}\n />\n );\n })}\n\n {/* Custom children get access to projection */}\n {typeof children === \"function\" ? children({ proj, pathGen, theme: t, width, height, transform }) : children}\n </g>\n </svg>\n\n {/* Reset zoom button */}\n {zoomable && isZoomed && (\n <button\n onClick={resetZoom}\n className=\"absolute bottom-3 right-3 rounded-lg border border-white/15 bg-black/50 px-2.5 py-1.5 text-[11px] font-medium text-white/80 backdrop-blur-md transition hover:bg-black/70 hover:text-white\"\n >\n Reset view\n </button>\n )}\n </div>\n );\n}\n"],"names":["land","feature","world","PROJECTIONS","d3","THEMES","buildProjection","type","width","height","GeoMap","projType","theme","markers","arcs","overlays","selectedId","onArcClick","onMarkerClick","zoomable","minZoom","maxZoom","initialBounds","className","children","t","svgRef","useRef","transform","setTransform","useState","zoomRef","proj","pathGen","graticulePath","spherePath","landPath","useMemo","useEffect","svg","zoom","e","initialBoundsApplied","sw","ne","padding","p0","p1","bx0","by0","bx1","by1","bw","bh","scale","cx","cy","tx","ty","clampedScale","resetZoom","useCallback","isZoomed","arcPaths","cache","a","key","interp","pts","i","p","path","activeMarkerIds","s","m","txStr","invScale","jsxs","jsx","o","c","edge","r","sel","danger","active"],"mappings":"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"}
1
+ {"version":3,"file":"GeoMap.js","sources":["../../../../src/components/library/charts/GeoMap.tsx"],"sourcesContent":["import React, { useMemo, useRef, useEffect, useState, useCallback } from \"react\";\nimport * as d3 from \"d3\";\nimport { feature } from \"topojson-client\";\nimport type { Topology, GeometryCollection } from \"topojson-specification\";\nimport world from \"world-atlas/land-110m.json\";\n\nconst land = feature(world as unknown as Topology<{ land: GeometryCollection }>, (world.objects.land as unknown) as GeometryCollection);\n\ntype ProjectionType = \"naturalEarth\" | \"mercator\" | \"equirectangular\";\n\nconst PROJECTIONS = {\n naturalEarth: d3.geoNaturalEarth1,\n mercator: d3.geoMercator,\n equirectangular: d3.geoEquirectangular,\n};\n\ninterface Theme {\n bg: string;\n bgGradient: [string, string];\n land: string;\n landStroke: string;\n sphere: string;\n graticule: string;\n graticuleOpacity: number;\n markerActive: string;\n markerInactive: string;\n label: string;\n labelInactive: string;\n arc: string;\n arcHighlight: string;\n arcDanger: string;\n dot: string;\n dotDanger: string;\n overlayFill: string;\n overlayStroke: string;\n}\n\ntype ThemeName = \"dark\" | \"light\";\n\nconst THEMES: Record<ThemeName, Theme> = {\n dark: {\n bg: \"#050b15\",\n bgGradient: [\"#0a1628\", \"#050b15\"],\n land: \"#1a2d4a\",\n landStroke: \"#2a4060\",\n sphere: \"#1e3a5f\",\n graticule: \"#162a45\",\n graticuleOpacity: 0.35,\n markerActive: \"#cbd5e1\",\n markerInactive: \"#64748b\",\n label: \"#cbd5e1\",\n labelInactive: \"#64748b\",\n arc: \"#818cf8\",\n arcHighlight: \"#c4b5fd\",\n arcDanger: \"#f87171\",\n dot: \"#a5b4fc\",\n dotDanger: \"#f87171\",\n overlayFill: \"rgba(248,113,113,0.10)\",\n overlayStroke: \"rgba(248,113,113,0.30)\",\n },\n light: {\n bg: \"#f8fafc\",\n bgGradient: [\"#f8fafc\", \"#f1f5f9\"],\n land: \"#e2e8f0\",\n landStroke: \"#cbd5e1\",\n sphere: \"#cbd5e1\",\n graticule: \"#e2e8f0\",\n graticuleOpacity: 0.6,\n markerActive: \"#334155\",\n markerInactive: \"#94a3b8\",\n label: \"#334155\",\n labelInactive: \"#94a3b8\",\n arc: \"#6366f1\",\n arcHighlight: \"#4f46e5\",\n arcDanger: \"#ef4444\",\n dot: \"#6366f1\",\n dotDanger: \"#ef4444\",\n overlayFill: \"rgba(239,68,68,0.08)\",\n overlayStroke: \"rgba(239,68,68,0.3)\",\n },\n};\n\nfunction buildProjection(type: ProjectionType, width: number, height: number): d3.GeoProjection {\n const factory = PROJECTIONS[type] ?? PROJECTIONS.naturalEarth;\n return factory().fitSize([width, height], { type: \"Sphere\" });\n}\n\nexport interface Marker {\n id: string;\n lon: number;\n lat: number;\n label?: string | false;\n active?: boolean;\n}\n\nexport interface Arc {\n id: string;\n from: [number, number];\n to: [number, number];\n danger?: boolean;\n color?: string;\n dotColor?: string;\n progress?: number;\n _path?: string | null;\n}\n\nexport interface Overlay {\n id: string;\n center: [number, number];\n radius?: number;\n fill?: string;\n stroke?: string;\n}\n\nexport interface InitialBounds {\n sw: [number, number];\n ne: [number, number];\n padding?: number;\n}\n\ninterface ChildrenFunctionProps {\n proj: d3.GeoProjection;\n pathGen: d3.GeoPath;\n theme: Theme;\n width: number;\n height: number;\n transform: d3.ZoomTransform;\n}\n\nexport interface GeoMapProps {\n width?: number;\n height?: number;\n projection?: ProjectionType;\n theme?: ThemeName;\n markers?: Marker[];\n arcs?: Arc[];\n overlays?: Overlay[];\n selectedId?: string | null;\n onArcClick?: (arc: Arc) => void;\n onMarkerClick?: (marker: Marker) => void;\n zoomable?: boolean;\n minZoom?: number;\n maxZoom?: number;\n initialBounds?: InitialBounds | null;\n className?: string;\n children?: React.ReactNode | ((props: ChildrenFunctionProps) => React.ReactNode);\n}\n\nexport default function GeoMap({\n width = 960,\n height = 480,\n projection: projType = \"naturalEarth\",\n theme = \"dark\",\n markers = [],\n arcs = [],\n overlays = [],\n selectedId = null,\n onArcClick,\n onMarkerClick,\n zoomable = true,\n minZoom = 1,\n maxZoom = 8,\n initialBounds = null,\n className = \"\",\n children,\n}: GeoMapProps): React.ReactElement {\n const t = THEMES[theme] ?? THEMES.dark;\n const svgRef = useRef<SVGSVGElement>(null);\n const [transform, setTransform] = useState<d3.ZoomTransform>(d3.zoomIdentity);\n const zoomRef = useRef<d3.ZoomBehavior<SVGSVGElement, unknown> | null>(null);\n\n const { proj, pathGen, graticulePath, spherePath, landPath } = useMemo(() => {\n const proj = buildProjection(projType, width, height);\n const pathGen = d3.geoPath(proj);\n return {\n proj,\n pathGen,\n graticulePath: pathGen(d3.geoGraticule10()),\n spherePath: pathGen({ type: \"Sphere\" }),\n landPath: pathGen(land),\n };\n }, [projType, width, height]);\n\n // D3 zoom behavior\n useEffect(() => {\n if (!zoomable || !svgRef.current) return;\n const svg = d3.select(svgRef.current);\n const zoom = d3.zoom<SVGSVGElement, unknown>()\n .scaleExtent([minZoom, maxZoom])\n .on(\"zoom\", (e: d3.D3ZoomEvent<SVGSVGElement, unknown>) => setTransform(e.transform));\n zoomRef.current = zoom;\n svg.call(zoom);\n return () => {\n svg.on(\".zoom\", null);\n };\n }, [zoomable, minZoom, maxZoom]);\n\n // Apply initial zoom to fit bounds (markers/region) on mount\n const initialBoundsApplied = useRef(false);\n useEffect(() => {\n if (!initialBounds || initialBoundsApplied.current) return;\n if (!svgRef.current || !zoomRef.current || !proj) return;\n const { sw, ne, padding = 40 } = initialBounds; // sw=[lonMin,latMin], ne=[lonMax,latMax]\n const p0 = proj(sw);\n const p1 = proj(ne);\n if (!p0 || !p1) return;\n const bx0 = Math.min(p0[0], p1[0]);\n const by0 = Math.min(p0[1], p1[1]);\n const bx1 = Math.max(p0[0], p1[0]);\n const by1 = Math.max(p0[1], p1[1]);\n const bw = bx1 - bx0;\n const bh = by1 - by0;\n if (bw < 1 || bh < 1) return;\n const scale = Math.min((width - padding * 2) / bw, (height - padding * 2) / bh);\n const cx = (bx0 + bx1) / 2;\n const cy = (by0 + by1) / 2;\n const tx = width / 2 - cx * scale;\n const ty = height / 2 - cy * scale;\n const clampedScale = Math.max(minZoom, Math.min(maxZoom, scale));\n const t = d3.zoomIdentity.translate(tx, ty).scale(clampedScale);\n d3.select(svgRef.current).call(zoomRef.current.transform, t);\n initialBoundsApplied.current = true;\n }, [initialBounds, proj, width, height, minZoom, maxZoom]);\n\n const resetZoom = useCallback(() => {\n if (!svgRef.current || !zoomRef.current) return;\n d3.select(svgRef.current)\n .transition()\n .duration(400)\n .call(zoomRef.current.transform, d3.zoomIdentity);\n }, []);\n\n const isZoomed = transform.k !== 1 || transform.x !== 0 || transform.y !== 0;\n\n const arcPaths = useMemo(() => {\n const cache: Record<string, string | null> = {};\n arcs.forEach(a => {\n const key = `${a.from[0]},${a.from[1]}-${a.to[0]},${a.to[1]}`;\n if (cache[key]) { a._path = cache[key]; return; }\n const interp = d3.geoInterpolate(a.from, a.to);\n const pts: [number, number][] = [];\n for (let i = 0; i <= 1; i += 0.02) {\n const p = proj(interp(i));\n if (p) pts.push(p as [number, number]);\n }\n const path = pts.length > 1 ? d3.line()(pts) : null;\n cache[key] = path;\n a._path = path;\n });\n return arcs;\n }, [arcs, proj]);\n\n const activeMarkerIds = useMemo(() => {\n const s = new Set<string>();\n markers.forEach(m => { if (m.active) s.add(m.id); });\n return s;\n }, [markers]);\n\n const txStr = `translate(${transform.x},${transform.y}) scale(${transform.k})`;\n const invScale = 1 / transform.k;\n\n return (\n <div className={`relative overflow-hidden ${className}`} style={{ background: t.bg }}>\n <svg ref={svgRef} viewBox={`0 0 ${width} ${height}`} className=\"h-full w-full\" preserveAspectRatio=\"xMidYMid slice\" style={zoomable ? { cursor: \"grab\" } : undefined}>\n <defs>\n <radialGradient id=\"geo-bg\" cx=\"50%\" cy=\"50%\" r=\"55%\">\n <stop offset=\"0%\" stopColor={t.bgGradient[0]} />\n <stop offset=\"100%\" stopColor={t.bgGradient[1]} />\n </radialGradient>\n <filter id=\"geo-glow\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"3\" result=\"b\" />\n <feMerge><feMergeNode in=\"b\" /><feMergeNode in=\"SourceGraphic\" /></feMerge>\n </filter>\n </defs>\n <style>{`\n .geo-arc{stroke-dasharray:8,6;animation:geo-flow 1.5s linear infinite}\n @keyframes geo-flow{to{stroke-dashoffset:-14}}\n .geo-dot{animation:geo-pulse 2s ease-in-out infinite}\n @keyframes geo-pulse{0%,100%{opacity:1}50%{opacity:.5}}\n `}</style>\n\n <rect width={width} height={height} fill=\"url(#geo-bg)\" />\n\n {/* Zoomable content group */}\n <g transform={txStr}>\n <path d={spherePath ?? undefined} fill=\"none\" stroke={t.sphere} strokeWidth={0.8 * invScale} />\n <path d={landPath ?? undefined} fill={t.land} stroke={t.landStroke} strokeWidth={0.4 * invScale} />\n <path d={graticulePath ?? undefined} fill=\"none\" stroke={t.graticule} strokeWidth={0.3 * invScale} opacity={t.graticuleOpacity} />\n\n {/* Overlay zones (disruptions, weather) */}\n {overlays.map(o => {\n const c = proj(o.center);\n if (!c) return null;\n const edge = proj([o.center[0] + (o.radius ?? 5), o.center[1]]);\n const r = edge ? Math.abs(edge[0] - c[0]) : 30;\n return (\n <circle\n key={o.id}\n cx={c[0]} cy={c[1]} r={r}\n fill={o.fill ?? t.overlayFill}\n stroke={o.stroke ?? t.overlayStroke}\n strokeWidth={1 * invScale}\n strokeDasharray=\"5,5\"\n className=\"animate-pulse\"\n />\n );\n })}\n\n {/* Arcs */}\n {arcPaths.map(a => {\n if (!a._path) return null;\n const sel = selectedId === a.id;\n const danger = a.danger;\n return (\n <path\n key={`arc-${a.id}`}\n d={a._path}\n fill=\"none\"\n stroke={danger ? t.arcDanger : sel ? t.arcHighlight : a.color ?? t.arc}\n strokeWidth={(sel ? 3 : 2) * invScale}\n opacity={selectedId != null && !sel ? 0.15 : danger ? 0.85 : 0.65}\n className=\"geo-arc cursor-pointer\"\n onClick={() => onArcClick?.(a)}\n />\n );\n })}\n\n {/* Markers */}\n {markers.map(m => {\n const p = proj([m.lon, m.lat]);\n if (!p) return null;\n const active = m.active ?? activeMarkerIds.has(m.id);\n return (\n <g key={m.id} className={onMarkerClick ? \"cursor-pointer\" : \"\"} onClick={() => onMarkerClick?.(m)}>\n <circle cx={p[0]} cy={p[1]} r={(active ? 3 : 2) * invScale} fill={active ? t.markerActive : t.markerInactive} />\n {m.label !== false && (\n <text x={p[0] + 6 * invScale} y={p[1] + 4 * invScale} fontSize={8 * invScale} fill={active ? t.label : t.labelInactive} fontFamily=\"sans-serif\" fontWeight={600}>\n {m.label ?? m.id}\n </text>\n )}\n </g>\n );\n })}\n\n {/* Moving dots (flight positions) */}\n {arcPaths.map(a => {\n if (a.progress == null || a.progress <= 0) return null;\n const interp = d3.geoInterpolate(a.from, a.to);\n const p = proj(interp(Math.min(a.progress, 0.99)));\n if (!p) return null;\n const sel = selectedId === a.id;\n return (\n <circle\n key={`dot-${a.id}`}\n cx={p[0]} cy={p[1]}\n r={(sel ? 6 : 4.5) * invScale}\n fill={a.danger ? t.dotDanger : a.dotColor ?? t.dot}\n filter=\"url(#geo-glow)\"\n className=\"geo-dot cursor-pointer\"\n opacity={selectedId != null && !sel ? 0.3 : 1}\n onClick={() => onArcClick?.(a)}\n />\n );\n })}\n\n {/* Custom children get access to projection */}\n {typeof children === \"function\" ? children({ proj, pathGen, theme: t, width, height, transform }) : children}\n </g>\n </svg>\n\n {/* Reset zoom button */}\n {zoomable && isZoomed && (\n <button\n onClick={resetZoom}\n className=\"absolute bottom-3 right-3 rounded-lg border border-white/15 bg-black/50 px-2.5 py-1.5 text-[11px] font-medium text-white/80 backdrop-blur-md transition hover:bg-black/70 hover:text-white\"\n >\n Reset view\n </button>\n )}\n </div>\n );\n}\n"],"names":["land","feature","world","PROJECTIONS","d3","THEMES","buildProjection","type","width","height","GeoMap","projType","theme","markers","arcs","overlays","selectedId","onArcClick","onMarkerClick","zoomable","minZoom","maxZoom","initialBounds","className","children","t","svgRef","useRef","transform","setTransform","useState","zoomRef","proj","pathGen","graticulePath","spherePath","landPath","useMemo","useEffect","svg","zoom","e","initialBoundsApplied","sw","ne","padding","p0","p1","bx0","by0","bx1","by1","bw","bh","scale","cx","cy","tx","ty","clampedScale","resetZoom","useCallback","isZoomed","arcPaths","cache","a","key","interp","pts","i","p","path","activeMarkerIds","s","m","txStr","invScale","jsxs","jsx","o","c","edge","r","sel","danger","active"],"mappings":"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"}
@@ -1,12 +1,22 @@
1
+ import { SelectOption } from "./SelectFilter";
2
+ export interface FilterDefinition {
3
+ id: string;
4
+ type: "search" | "select" | "toggle";
5
+ label?: string;
6
+ placeholder?: string;
7
+ options?: (string | SelectOption)[];
8
+ className?: string;
9
+ }
10
+ export interface FilterBarProps {
11
+ filters?: FilterDefinition[];
12
+ values?: Record<string, any>;
13
+ onChange?: (filterId: string, value: any) => void;
14
+ onReset?: () => void;
15
+ activeCount?: number;
16
+ layout?: "inline" | "stacked";
17
+ }
1
18
  /**
2
19
  * Renders a row of filter controls from a definitions array.
3
20
  * Pairs with usePageFilters hook for state management.
4
- *
5
- * @param {Array} filters — filter definitions [{ id, type, ... }]
6
- * @param {Object} values — current filter values keyed by filter id
7
- * @param {Function} onChange — (filterId, value) => void
8
- * @param {Function} onReset — () => void
9
- * @param {number} activeCount — number of active filters (for badge)
10
- * @param {string} layout — "inline" (default) or "stacked"
11
21
  */
12
- export default function FilterBar({ filters, values, onChange, onReset, activeCount, layout, }: any[]): import("react/jsx-runtime").JSX.Element | null;
22
+ export default function FilterBar({ filters, values, onChange, onReset, activeCount, layout, }: FilterBarProps): import("react/jsx-runtime").JSX.Element | null;
@@ -1,10 +1,9 @@
1
1
  import { jsxs as m, jsx as a } from "react/jsx-runtime";
2
- import "react";
3
2
  import p from "./SearchFilter.js";
4
3
  import u from "./SelectFilter.js";
5
4
  import h from "./ToggleFilter.js";
6
5
  import { XMarkIcon as x } from "@heroicons/react/24/outline";
7
- function f({
6
+ function w({
8
7
  filters: o = [],
9
8
  values: d = {},
10
9
  onChange: s,
@@ -84,6 +83,6 @@ function f({
84
83
  );
85
84
  }
86
85
  export {
87
- f as default
86
+ w as default
88
87
  };
89
88
  //# sourceMappingURL=FilterBar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FilterBar.js","sources":["../../../../src/components/library/filters/FilterBar.jsx"],"sourcesContent":["import React from \"react\";\nimport SearchFilter from \"./SearchFilter\";\nimport SelectFilter from \"./SelectFilter\";\nimport ToggleFilter from \"./ToggleFilter\";\nimport { FunnelIcon, XMarkIcon } from \"@heroicons/react/24/outline\";\n\n/**\n * Renders a row of filter controls from a definitions array.\n * Pairs with usePageFilters hook for state management.\n *\n * @param {Array} filters — filter definitions [{ id, type, ... }]\n * @param {Object} values — current filter values keyed by filter id\n * @param {Function} onChange (filterId, value) => void\n * @param {Function} onReset () => void\n * @param {number} activeCount number of active filters (for badge)\n * @param {string} layout \"inline\" (default) or \"stacked\"\n */\nexport default function FilterBar({\n filters = [],\n values = {},\n onChange,\n onReset,\n activeCount = 0,\n layout = \"inline\",\n}) {\n if (!filters.length) return null;\n\n const isStacked = layout === \"stacked\";\n\n return (\n <div\n className={[\n \"flex gap-3\",\n isStacked\n ? \"flex-col\"\n : \"flex-col sm:flex-row sm:flex-wrap sm:items-center\",\n ].join(\" \")}\n >\n {filters.map((filter) => {\n const val = values[filter.id];\n\n switch (filter.type) {\n case \"search\":\n return (\n <SearchFilter\n key={filter.id}\n value={val ?? \"\"}\n onChange={(v) => onChange?.(filter.id, v)}\n placeholder={filter.placeholder ?? \"Search…\"}\n className={filter.className ?? (isStacked ? \"w-full\" : \"w-full sm:w-64\")}\n />\n );\n\n case \"select\":\n return (\n <SelectFilter\n key={filter.id}\n value={val ?? \"all\"}\n onChange={(v) => onChange?.(filter.id, v)}\n options={filter.options ?? []}\n label={filter.label}\n placeholder={filter.placeholder ?? \"All\"}\n className={filter.className}\n />\n );\n\n case \"toggle\":\n return (\n <ToggleFilter\n key={filter.id}\n value={val ?? false}\n onChange={(v) => onChange?.(filter.id, v)}\n label={filter.label}\n className={filter.className}\n />\n );\n\n default:\n return null;\n }\n })}\n\n {activeCount > 0 && onReset ? (\n <button\n type=\"button\"\n onClick={onReset}\n className=\"inline-flex items-center gap-1.5 rounded-lg px-2.5 py-1.5 text-xs font-medium text-slate-500 transition hover:bg-slate-100 hover:text-slate-700 dark:text-slate-400 dark:hover:bg-slate-800 dark:hover:text-slate-200\"\n >\n <XMarkIcon className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n Clear {activeCount} {activeCount === 1 ? \"filter\" : \"filters\"}\n </button>\n ) : null}\n </div>\n );\n}\n"],"names":["FilterBar","filters","values","onChange","onReset","activeCount","layout","isStacked","jsxs","filter","val","jsx","SearchFilter","v","SelectFilter","ToggleFilter","XMarkIcon"],"mappings":";;;;;;AAiBA,SAAwBA,EAAU;AAAA,EAChC,SAAAC,IAAU,CAAA;AAAA,EACV,QAAAC,IAAS,CAAA;AAAA,EACT,UAAAC;AAAA,EACA,SAAAC;AAAA,EACA,aAAAC,IAAc;AAAA,EACd,QAAAC,IAAS;AACX,GAAG;AACD,MAAI,CAACL,EAAQ,OAAQ,QAAO;AAE5B,QAAMM,IAAYD,MAAW;AAE7B,SACE,gBAAAE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACAD,IACI,aACA;AAAA,MAAA,EACJ,KAAK,GAAG;AAAA,MAET,UAAA;AAAA,QAAAN,EAAQ,IAAI,CAACQ,MAAW;AACvB,gBAAMC,IAAMR,EAAOO,EAAO,EAAE;AAE5B,kBAAQA,EAAO,MAAA;AAAA,YACb,KAAK;AACH,qBACE,gBAAAE;AAAA,gBAACC;AAAA,gBAAA;AAAA,kBAEC,OAAOF,KAAO;AAAA,kBACd,UAAU,CAACG,MAAMV,IAAWM,EAAO,IAAII,CAAC;AAAA,kBACxC,aAAaJ,EAAO,eAAe;AAAA,kBACnC,WAAWA,EAAO,cAAcF,IAAY,WAAW;AAAA,gBAAA;AAAA,gBAJlDE,EAAO;AAAA,cAAA;AAAA,YAQlB,KAAK;AACH,qBACE,gBAAAE;AAAA,gBAACG;AAAA,gBAAA;AAAA,kBAEC,OAAOJ,KAAO;AAAA,kBACd,UAAU,CAACG,MAAMV,IAAWM,EAAO,IAAII,CAAC;AAAA,kBACxC,SAASJ,EAAO,WAAW,CAAA;AAAA,kBAC3B,OAAOA,EAAO;AAAA,kBACd,aAAaA,EAAO,eAAe;AAAA,kBACnC,WAAWA,EAAO;AAAA,gBAAA;AAAA,gBANbA,EAAO;AAAA,cAAA;AAAA,YAUlB,KAAK;AACH,qBACE,gBAAAE;AAAA,gBAACI;AAAA,gBAAA;AAAA,kBAEC,OAAOL,KAAO;AAAA,kBACd,UAAU,CAACG,MAAMV,IAAWM,EAAO,IAAII,CAAC;AAAA,kBACxC,OAAOJ,EAAO;AAAA,kBACd,WAAWA,EAAO;AAAA,gBAAA;AAAA,gBAJbA,EAAO;AAAA,cAAA;AAAA,YAQlB;AACE,qBAAO;AAAA,UAAA;AAAA,QAEb,CAAC;AAAA,QAEAJ,IAAc,KAAKD,IAClB,gBAAAI;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,SAASJ;AAAA,YACT,WAAU;AAAA,YAEV,UAAA;AAAA,cAAA,gBAAAO,EAACK,GAAA,EAAU,WAAU,eAAc,eAAY,QAAO;AAAA,cAAE;AAAA,cACjDX;AAAA,cAAY;AAAA,cAAEA,MAAgB,IAAI,WAAW;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA,IAEpD;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGV;"}
1
+ {"version":3,"file":"FilterBar.js","sources":["../../../../src/components/library/filters/FilterBar.tsx"],"sourcesContent":["import SearchFilter from \"./SearchFilter\";\nimport SelectFilter, { SelectOption } from \"./SelectFilter\";\nimport ToggleFilter from \"./ToggleFilter\";\nimport { XMarkIcon } from \"@heroicons/react/24/outline\";\n\nexport interface FilterDefinition {\n id: string;\n type: \"search\" | \"select\" | \"toggle\";\n label?: string;\n placeholder?: string;\n options?: (string | SelectOption)[];\n className?: string;\n}\n\nexport interface FilterBarProps {\n filters?: FilterDefinition[];\n values?: Record<string, any>;\n onChange?: (filterId: string, value: any) => void;\n onReset?: () => void;\n activeCount?: number;\n layout?: \"inline\" | \"stacked\";\n}\n\n/**\n * Renders a row of filter controls from a definitions array.\n * Pairs with usePageFilters hook for state management.\n */\nexport default function FilterBar({\n filters = [],\n values = {},\n onChange,\n onReset,\n activeCount = 0,\n layout = \"inline\",\n}: FilterBarProps) {\n if (!filters.length) return null;\n\n const isStacked = layout === \"stacked\";\n\n return (\n <div\n className={[\n \"flex gap-3\",\n isStacked\n ? \"flex-col\"\n : \"flex-col sm:flex-row sm:flex-wrap sm:items-center\",\n ].join(\" \")}\n >\n {filters.map((filter) => {\n const val = values[filter.id];\n\n switch (filter.type) {\n case \"search\":\n return (\n <SearchFilter\n key={filter.id}\n value={val ?? \"\"}\n onChange={(v) => onChange?.(filter.id, v)}\n placeholder={filter.placeholder ?? \"Search…\"}\n className={filter.className ?? (isStacked ? \"w-full\" : \"w-full sm:w-64\")}\n />\n );\n\n case \"select\":\n return (\n <SelectFilter\n key={filter.id}\n value={val ?? \"all\"}\n onChange={(v) => onChange?.(filter.id, v)}\n options={filter.options ?? []}\n label={filter.label}\n placeholder={filter.placeholder ?? \"All\"}\n className={filter.className}\n />\n );\n\n case \"toggle\":\n return (\n <ToggleFilter\n key={filter.id}\n value={val ?? false}\n onChange={(v) => onChange?.(filter.id, v)}\n label={filter.label}\n className={filter.className}\n />\n );\n\n default:\n return null;\n }\n })}\n\n {activeCount > 0 && onReset ? (\n <button\n type=\"button\"\n onClick={onReset}\n className=\"inline-flex items-center gap-1.5 rounded-lg px-2.5 py-1.5 text-xs font-medium text-slate-500 transition hover:bg-slate-100 hover:text-slate-700 dark:text-slate-400 dark:hover:bg-slate-800 dark:hover:text-slate-200\"\n >\n <XMarkIcon className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n Clear {activeCount} {activeCount === 1 ? \"filter\" : \"filters\"}\n </button>\n ) : null}\n </div>\n );\n}\n"],"names":["FilterBar","filters","values","onChange","onReset","activeCount","layout","isStacked","jsxs","filter","val","jsx","SearchFilter","v","SelectFilter","ToggleFilter","XMarkIcon"],"mappings":";;;;;AA2BA,SAAwBA,EAAU;AAAA,EAChC,SAAAC,IAAU,CAAA;AAAA,EACV,QAAAC,IAAS,CAAA;AAAA,EACT,UAAAC;AAAA,EACA,SAAAC;AAAA,EACA,aAAAC,IAAc;AAAA,EACd,QAAAC,IAAS;AACX,GAAmB;AACjB,MAAI,CAACL,EAAQ,OAAQ,QAAO;AAE5B,QAAMM,IAAYD,MAAW;AAE7B,SACE,gBAAAE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACAD,IACI,aACA;AAAA,MAAA,EACJ,KAAK,GAAG;AAAA,MAET,UAAA;AAAA,QAAAN,EAAQ,IAAI,CAACQ,MAAW;AACvB,gBAAMC,IAAMR,EAAOO,EAAO,EAAE;AAE5B,kBAAQA,EAAO,MAAA;AAAA,YACb,KAAK;AACH,qBACE,gBAAAE;AAAA,gBAACC;AAAA,gBAAA;AAAA,kBAEC,OAAOF,KAAO;AAAA,kBACd,UAAU,CAACG,MAAMV,IAAWM,EAAO,IAAII,CAAC;AAAA,kBACxC,aAAaJ,EAAO,eAAe;AAAA,kBACnC,WAAWA,EAAO,cAAcF,IAAY,WAAW;AAAA,gBAAA;AAAA,gBAJlDE,EAAO;AAAA,cAAA;AAAA,YAQlB,KAAK;AACH,qBACE,gBAAAE;AAAA,gBAACG;AAAA,gBAAA;AAAA,kBAEC,OAAOJ,KAAO;AAAA,kBACd,UAAU,CAACG,MAAMV,IAAWM,EAAO,IAAII,CAAC;AAAA,kBACxC,SAASJ,EAAO,WAAW,CAAA;AAAA,kBAC3B,OAAOA,EAAO;AAAA,kBACd,aAAaA,EAAO,eAAe;AAAA,kBACnC,WAAWA,EAAO;AAAA,gBAAA;AAAA,gBANbA,EAAO;AAAA,cAAA;AAAA,YAUlB,KAAK;AACH,qBACE,gBAAAE;AAAA,gBAACI;AAAA,gBAAA;AAAA,kBAEC,OAAOL,KAAO;AAAA,kBACd,UAAU,CAACG,MAAMV,IAAWM,EAAO,IAAII,CAAC;AAAA,kBACxC,OAAOJ,EAAO;AAAA,kBACd,WAAWA,EAAO;AAAA,gBAAA;AAAA,gBAJbA,EAAO;AAAA,cAAA;AAAA,YAQlB;AACE,qBAAO;AAAA,UAAA;AAAA,QAEb,CAAC;AAAA,QAEAJ,IAAc,KAAKD,IAClB,gBAAAI;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,SAASJ;AAAA,YACT,WAAU;AAAA,YAEV,UAAA;AAAA,cAAA,gBAAAO,EAACK,GAAA,EAAU,WAAU,eAAc,eAAY,QAAO;AAAA,cAAE;AAAA,cACjDX;AAAA,cAAY;AAAA,cAAEA,MAAgB,IAAI,WAAW;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA,IAEpD;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGV;"}
@@ -1,6 +1,7 @@
1
- export default function SearchFilter({ value, onChange, placeholder, className, }: {
2
- value?: string | undefined;
3
- onChange: any;
4
- placeholder?: string | undefined;
5
- className?: string | undefined;
6
- }): import("react/jsx-runtime").JSX.Element;
1
+ export interface SearchFilterProps {
2
+ value?: string;
3
+ onChange?: (value: string) => void;
4
+ placeholder?: string;
5
+ className?: string;
6
+ }
7
+ export default function SearchFilter({ value, onChange, placeholder, className, }: SearchFilterProps): import("react/jsx-runtime").JSX.Element;
@@ -1,7 +1,6 @@
1
1
  import { jsxs as o, jsx as e } from "react/jsx-runtime";
2
- import "react";
3
2
  import { MagnifyingGlassIcon as n, XMarkIcon as i } from "@heroicons/react/24/outline";
4
- function f({
3
+ function u({
5
4
  value: t = "",
6
5
  onChange: a,
7
6
  placeholder: r = "Search…",
@@ -39,6 +38,6 @@ function f({
39
38
  ] });
40
39
  }
41
40
  export {
42
- f as default
41
+ u as default
43
42
  };
44
43
  //# sourceMappingURL=SearchFilter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SearchFilter.js","sources":["../../../../src/components/library/filters/SearchFilter.jsx"],"sourcesContent":["import React from \"react\";\nimport { MagnifyingGlassIcon, XMarkIcon } from \"@heroicons/react/24/outline\";\n\nexport default function SearchFilter({\n value = \"\",\n onChange,\n placeholder = \"Search…\",\n className = \"\",\n}) {\n return (\n <div className={[\"relative\", className].filter(Boolean).join(\" \")}>\n <MagnifyingGlassIcon\n className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400 dark:text-slate-500\"\n aria-hidden=\"true\"\n />\n <input\n type=\"text\"\n value={value}\n onChange={(e) => onChange?.(e.target.value)}\n placeholder={placeholder}\n className=\"h-9 w-full rounded-lg border border-slate-200 bg-white pl-9 pr-8 text-sm text-slate-900 shadow-sm placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:ring-offset-2 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-50 dark:placeholder:text-slate-500 dark:focus:ring-offset-slate-950\"\n aria-label={placeholder}\n />\n {value ? (\n <button\n type=\"button\"\n onClick={() => onChange?.(\"\")}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 rounded p-0.5 text-slate-400 hover:text-slate-600 dark:text-slate-500 dark:hover:text-slate-300\"\n aria-label=\"Clear search\"\n >\n <XMarkIcon className=\"h-4 w-4\" />\n </button>\n ) : null}\n </div>\n );\n}\n"],"names":["SearchFilter","value","onChange","placeholder","className","jsxs","jsx","MagnifyingGlassIcon","e","XMarkIcon"],"mappings":";;;AAGA,SAAwBA,EAAa;AAAA,EACnC,OAAAC,IAAQ;AAAA,EACR,UAAAC;AAAA,EACA,aAAAC,IAAc;AAAA,EACd,WAAAC,IAAY;AACd,GAAG;AACD,SACE,gBAAAC,EAAC,OAAA,EAAI,WAAW,CAAC,YAAYD,CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAC9D,UAAA;AAAA,IAAA,gBAAAE;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,eAAY;AAAA,MAAA;AAAA,IAAA;AAAA,IAEd,gBAAAD;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,OAAAL;AAAA,QACA,UAAU,CAACO,MAAMN,IAAWM,EAAE,OAAO,KAAK;AAAA,QAC1C,aAAAL;AAAA,QACA,WAAU;AAAA,QACV,cAAYA;AAAA,MAAA;AAAA,IAAA;AAAA,IAEbF,IACC,gBAAAK;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS,MAAMJ,IAAW,EAAE;AAAA,QAC5B,WAAU;AAAA,QACV,cAAW;AAAA,QAEX,UAAA,gBAAAI,EAACG,GAAA,EAAU,WAAU,UAAA,CAAU;AAAA,MAAA;AAAA,IAAA,IAE/B;AAAA,EAAA,GACN;AAEJ;"}
1
+ {"version":3,"file":"SearchFilter.js","sources":["../../../../src/components/library/filters/SearchFilter.tsx"],"sourcesContent":["import { MagnifyingGlassIcon, XMarkIcon } from \"@heroicons/react/24/outline\";\n\nexport interface SearchFilterProps {\n value?: string;\n onChange?: (value: string) => void;\n placeholder?: string;\n className?: string;\n}\n\nexport default function SearchFilter({\n value = \"\",\n onChange,\n placeholder = \"Search…\",\n className = \"\",\n}: SearchFilterProps) {\n return (\n <div className={[\"relative\", className].filter(Boolean).join(\" \")}>\n <MagnifyingGlassIcon\n className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400 dark:text-slate-500\"\n aria-hidden=\"true\"\n />\n <input\n type=\"text\"\n value={value}\n onChange={(e) => onChange?.(e.target.value)}\n placeholder={placeholder}\n className=\"h-9 w-full rounded-lg border border-slate-200 bg-white pl-9 pr-8 text-sm text-slate-900 shadow-sm placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:ring-offset-2 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-50 dark:placeholder:text-slate-500 dark:focus:ring-offset-slate-950\"\n aria-label={placeholder}\n />\n {value ? (\n <button\n type=\"button\"\n onClick={() => onChange?.(\"\")}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 rounded p-0.5 text-slate-400 hover:text-slate-600 dark:text-slate-500 dark:hover:text-slate-300\"\n aria-label=\"Clear search\"\n >\n <XMarkIcon className=\"h-4 w-4\" />\n </button>\n ) : null}\n </div>\n );\n}\n"],"names":["SearchFilter","value","onChange","placeholder","className","jsxs","jsx","MagnifyingGlassIcon","e","XMarkIcon"],"mappings":";;AASA,SAAwBA,EAAa;AAAA,EACnC,OAAAC,IAAQ;AAAA,EACR,UAAAC;AAAA,EACA,aAAAC,IAAc;AAAA,EACd,WAAAC,IAAY;AACd,GAAsB;AACpB,SACE,gBAAAC,EAAC,OAAA,EAAI,WAAW,CAAC,YAAYD,CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAC9D,UAAA;AAAA,IAAA,gBAAAE;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,eAAY;AAAA,MAAA;AAAA,IAAA;AAAA,IAEd,gBAAAD;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,OAAAL;AAAA,QACA,UAAU,CAACO,MAAMN,IAAWM,EAAE,OAAO,KAAK;AAAA,QAC1C,aAAAL;AAAA,QACA,WAAU;AAAA,QACV,cAAYA;AAAA,MAAA;AAAA,IAAA;AAAA,IAEbF,IACC,gBAAAK;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS,MAAMJ,IAAW,EAAE;AAAA,QAC5B,WAAU;AAAA,QACV,cAAW;AAAA,QAEX,UAAA,gBAAAI,EAACG,GAAA,EAAU,WAAU,UAAA,CAAU;AAAA,MAAA;AAAA,IAAA,IAE/B;AAAA,EAAA,GACN;AAEJ;"}
@@ -1,10 +1,16 @@
1
+ export interface SelectOption {
2
+ value: string;
3
+ label: string;
4
+ }
5
+ export interface SelectFilterProps {
6
+ value?: string;
7
+ onChange?: (value: string) => void;
8
+ options?: (string | SelectOption)[];
9
+ label?: string;
10
+ placeholder?: string;
11
+ className?: string;
12
+ }
1
13
  /**
2
14
  * Dropdown select filter.
3
- *
4
- * @param {string} value — current selected value
5
- * @param {Function} onChange — (value) => void
6
- * @param {Array} options — [{ value, label }] or ["string", ...]
7
- * @param {string} label — visible label
8
- * @param {string} placeholder — placeholder when no value selected
9
15
  */
10
- export default function SelectFilter({ value, onChange, options, label, placeholder, className, }: string): import("react/jsx-runtime").JSX.Element;
16
+ export default function SelectFilter({ value, onChange, options, label, placeholder, className, }: SelectFilterProps): import("react/jsx-runtime").JSX.Element;
@@ -1,7 +1,6 @@
1
1
  import { jsxs as n, jsx as t } from "react/jsx-runtime";
2
- import "react";
3
2
  import { ChevronDownIcon as u } from "@heroicons/react/24/outline";
4
- function h({
3
+ function f({
5
4
  value: r = "all",
6
5
  onChange: s,
7
6
  options: i = [],
@@ -39,6 +38,6 @@ function h({
39
38
  ] });
40
39
  }
41
40
  export {
42
- h as default
41
+ f as default
43
42
  };
44
43
  //# sourceMappingURL=SelectFilter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SelectFilter.js","sources":["../../../../src/components/library/filters/SelectFilter.jsx"],"sourcesContent":["import React from \"react\";\nimport { ChevronDownIcon } from \"@heroicons/react/24/outline\";\n\n/**\n * Dropdown select filter.\n *\n * @param {string} value — current selected value\n * @param {Function} onChange (value) => void\n * @param {Array} options — [{ value, label }] or [\"string\", ...]\n * @param {string} label — visible label\n * @param {string} placeholder — placeholder when no value selected\n */\nexport default function SelectFilter({\n value = \"all\",\n onChange,\n options = [],\n label,\n placeholder,\n className = \"\",\n}) {\n const normalizedOptions = options.map((opt) =>\n typeof opt === \"string\" ? { value: opt, label: opt } : opt\n );\n\n return (\n <div className={[\"relative inline-flex items-center gap-2\", className].filter(Boolean).join(\" \")}>\n {label ? (\n <span className=\"shrink-0 text-xs font-medium text-slate-500 dark:text-slate-400\">\n {label}\n </span>\n ) : null}\n <div className=\"relative\">\n <select\n value={value}\n onChange={(e) => onChange?.(e.target.value)}\n className=\"h-9 appearance-none rounded-lg border border-slate-200 bg-white py-0 pl-3 pr-8 text-sm font-medium text-slate-700 shadow-sm focus:outline-none focus:ring-2 focus:ring-brand-500 focus:ring-offset-2 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-200 dark:focus:ring-offset-slate-950\"\n aria-label={label ?? placeholder ?? \"Filter\"}\n >\n {placeholder ? (\n <option value=\"all\">{placeholder}</option>\n ) : null}\n {normalizedOptions.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n <ChevronDownIcon\n className=\"pointer-events-none absolute right-2 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400 dark:text-slate-500\"\n aria-hidden=\"true\"\n />\n </div>\n </div>\n );\n}\n"],"names":["SelectFilter","value","onChange","options","label","placeholder","className","normalizedOptions","opt","jsxs","jsx","ChevronDownIcon"],"mappings":";;;AAYA,SAAwBA,EAAa;AAAA,EACnC,OAAAC,IAAQ;AAAA,EACR,UAAAC;AAAA,EACA,SAAAC,IAAU,CAAA;AAAA,EACV,OAAAC;AAAA,EACA,aAAAC;AAAA,EACA,WAAAC,IAAY;AACd,GAAG;AACD,QAAMC,IAAoBJ,EAAQ;AAAA,IAAI,CAACK,MACrC,OAAOA,KAAQ,WAAW,EAAE,OAAOA,GAAK,OAAOA,MAAQA;AAAA,EAAA;AAGzD,SACE,gBAAAC,EAAC,OAAA,EAAI,WAAW,CAAC,2CAA2CH,CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAC5F,UAAA;AAAA,IAAAF,IACC,gBAAAM,EAAC,QAAA,EAAK,WAAU,mEACb,aACH,IACE;AAAA,IACJ,gBAAAD,EAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,MAAA,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAAR;AAAA,UACA,UAAU,CAAC,MAAMC,IAAW,EAAE,OAAO,KAAK;AAAA,UAC1C,WAAU;AAAA,UACV,cAAYE,KAASC,KAAe;AAAA,UAEnC,UAAA;AAAA,YAAAA,IACC,gBAAAK,EAAC,UAAA,EAAO,OAAM,OAAO,aAAY,IAC/B;AAAA,YACHH,EAAkB,IAAI,CAACC,MACtB,gBAAAE,EAAC,UAAA,EAAuB,OAAOF,EAAI,OAChC,UAAAA,EAAI,MAAA,GADMA,EAAI,KAEjB,CACD;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAEH,gBAAAE;AAAA,QAACC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,eAAY;AAAA,QAAA;AAAA,MAAA;AAAA,IACd,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;"}
1
+ {"version":3,"file":"SelectFilter.js","sources":["../../../../src/components/library/filters/SelectFilter.tsx"],"sourcesContent":["import { ChevronDownIcon } from \"@heroicons/react/24/outline\";\n\nexport interface SelectOption {\n value: string;\n label: string;\n}\n\nexport interface SelectFilterProps {\n value?: string;\n onChange?: (value: string) => void;\n options?: (string | SelectOption)[];\n label?: string;\n placeholder?: string;\n className?: string;\n}\n\n/**\n * Dropdown select filter.\n */\nexport default function SelectFilter({\n value = \"all\",\n onChange,\n options = [],\n label,\n placeholder,\n className = \"\",\n}: SelectFilterProps) {\n const normalizedOptions = options.map((opt) =>\n typeof opt === \"string\" ? { value: opt, label: opt } : opt\n );\n\n return (\n <div className={[\"relative inline-flex items-center gap-2\", className].filter(Boolean).join(\" \")}>\n {label ? (\n <span className=\"shrink-0 text-xs font-medium text-slate-500 dark:text-slate-400\">\n {label}\n </span>\n ) : null}\n <div className=\"relative\">\n <select\n value={value}\n onChange={(e) => onChange?.(e.target.value)}\n className=\"h-9 appearance-none rounded-lg border border-slate-200 bg-white py-0 pl-3 pr-8 text-sm font-medium text-slate-700 shadow-sm focus:outline-none focus:ring-2 focus:ring-brand-500 focus:ring-offset-2 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-200 dark:focus:ring-offset-slate-950\"\n aria-label={label ?? placeholder ?? \"Filter\"}\n >\n {placeholder ? (\n <option value=\"all\">{placeholder}</option>\n ) : null}\n {normalizedOptions.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n <ChevronDownIcon\n className=\"pointer-events-none absolute right-2 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400 dark:text-slate-500\"\n aria-hidden=\"true\"\n />\n </div>\n </div>\n );\n}\n"],"names":["SelectFilter","value","onChange","options","label","placeholder","className","normalizedOptions","opt","jsxs","jsx","ChevronDownIcon"],"mappings":";;AAmBA,SAAwBA,EAAa;AAAA,EACnC,OAAAC,IAAQ;AAAA,EACR,UAAAC;AAAA,EACA,SAAAC,IAAU,CAAA;AAAA,EACV,OAAAC;AAAA,EACA,aAAAC;AAAA,EACA,WAAAC,IAAY;AACd,GAAsB;AACpB,QAAMC,IAAoBJ,EAAQ;AAAA,IAAI,CAACK,MACrC,OAAOA,KAAQ,WAAW,EAAE,OAAOA,GAAK,OAAOA,MAAQA;AAAA,EAAA;AAGzD,SACE,gBAAAC,EAAC,OAAA,EAAI,WAAW,CAAC,2CAA2CH,CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAC5F,UAAA;AAAA,IAAAF,IACC,gBAAAM,EAAC,QAAA,EAAK,WAAU,mEACb,aACH,IACE;AAAA,IACJ,gBAAAD,EAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,MAAA,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAAR;AAAA,UACA,UAAU,CAAC,MAAMC,IAAW,EAAE,OAAO,KAAK;AAAA,UAC1C,WAAU;AAAA,UACV,cAAYE,KAASC,KAAe;AAAA,UAEnC,UAAA;AAAA,YAAAA,IACC,gBAAAK,EAAC,UAAA,EAAO,OAAM,OAAO,aAAY,IAC/B;AAAA,YACHH,EAAkB,IAAI,CAACC,MACtB,gBAAAE,EAAC,UAAA,EAAuB,OAAOF,EAAI,OAChC,UAAAA,EAAI,MAAA,GADMA,EAAI,KAEjB,CACD;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAEH,gBAAAE;AAAA,QAACC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,eAAY;AAAA,QAAA;AAAA,MAAA;AAAA,IACd,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;"}
@@ -1,8 +1,10 @@
1
+ export interface ToggleFilterProps {
2
+ value?: boolean;
3
+ onChange?: (value: boolean) => void;
4
+ label?: string;
5
+ className?: string;
6
+ }
1
7
  /**
2
8
  * Toggle switch filter.
3
- *
4
- * @param {boolean} value — current on/off state
5
- * @param {Function} onChange — (boolean) => void
6
- * @param {string} label — visible label
7
9
  */
8
- export default function ToggleFilter({ value, onChange, label, className, }: boolean): import("react/jsx-runtime").JSX.Element;
10
+ export default function ToggleFilter({ value, onChange, label, className, }: ToggleFilterProps): import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,5 @@
1
1
  import { jsxs as o, jsx as n } from "react/jsx-runtime";
2
- import "react";
3
- function l({
2
+ function a({
4
3
  value: e = !1,
5
4
  onChange: r,
6
5
  label: t,
@@ -43,6 +42,6 @@ function l({
43
42
  );
44
43
  }
45
44
  export {
46
- l as default
45
+ a as default
47
46
  };
48
47
  //# sourceMappingURL=ToggleFilter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToggleFilter.js","sources":["../../../../src/components/library/filters/ToggleFilter.jsx"],"sourcesContent":["import React from \"react\";\n\n/**\n * Toggle switch filter.\n *\n * @param {boolean} value — current on/off state\n * @param {Function} onChange (boolean) => void\n * @param {string} label visible label\n */\nexport default function ToggleFilter({\n value = false,\n onChange,\n label,\n className = \"\",\n}) {\n return (\n <label\n className={[\n \"inline-flex cursor-pointer items-center gap-2\",\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n >\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={value}\n onClick={() => onChange?.(!value)}\n className={[\n \"relative inline-flex h-5 w-9 shrink-0 rounded-full border-2 border-transparent transition-colors focus:outline-none focus:ring-2 focus:ring-brand-500 focus:ring-offset-2 dark:focus:ring-offset-slate-950\",\n value\n ? \"bg-brand-500\"\n : \"bg-slate-200 dark:bg-slate-700\",\n ].join(\" \")}\n >\n <span\n aria-hidden=\"true\"\n className={[\n \"pointer-events-none inline-block h-4 w-4 rounded-full bg-white shadow ring-0 transition-transform\",\n value ? \"translate-x-4\" : \"translate-x-0\",\n ].join(\" \")}\n />\n </button>\n {label ? (\n <span className=\"text-sm font-medium text-slate-700 dark:text-slate-200\">\n {label}\n </span>\n ) : null}\n </label>\n );\n}\n"],"names":["ToggleFilter","value","onChange","label","className","jsxs","jsx"],"mappings":";;AASA,SAAwBA,EAAa;AAAA,EACnC,OAAAC,IAAQ;AAAA,EACR,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAC,IAAY;AACd,GAAG;AACD,SACE,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACAD;AAAA,MAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,MAEX,UAAA;AAAA,QAAA,gBAAAE;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,MAAK;AAAA,YACL,gBAAcL;AAAA,YACd,SAAS,MAAMC,IAAW,CAACD,CAAK;AAAA,YAChC,WAAW;AAAA,cACT;AAAA,cACAA,IACI,iBACA;AAAA,YAAA,EACJ,KAAK,GAAG;AAAA,YAEV,UAAA,gBAAAK;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,eAAY;AAAA,gBACZ,WAAW;AAAA,kBACT;AAAA,kBACAL,IAAQ,kBAAkB;AAAA,gBAAA,EAC1B,KAAK,GAAG;AAAA,cAAA;AAAA,YAAA;AAAA,UACZ;AAAA,QAAA;AAAA,QAEDE,IACC,gBAAAG,EAAC,QAAA,EAAK,WAAU,0DACb,aACH,IACE;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGV;"}
1
+ {"version":3,"file":"ToggleFilter.js","sources":["../../../../src/components/library/filters/ToggleFilter.tsx"],"sourcesContent":["export interface ToggleFilterProps {\n value?: boolean;\n onChange?: (value: boolean) => void;\n label?: string;\n className?: string;\n}\n\n/**\n * Toggle switch filter.\n */\nexport default function ToggleFilter({\n value = false,\n onChange,\n label,\n className = \"\",\n}: ToggleFilterProps) {\n return (\n <label\n className={[\n \"inline-flex cursor-pointer items-center gap-2\",\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n >\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={value}\n onClick={() => onChange?.(!value)}\n className={[\n \"relative inline-flex h-5 w-9 shrink-0 rounded-full border-2 border-transparent transition-colors focus:outline-none focus:ring-2 focus:ring-brand-500 focus:ring-offset-2 dark:focus:ring-offset-slate-950\",\n value\n ? \"bg-brand-500\"\n : \"bg-slate-200 dark:bg-slate-700\",\n ].join(\" \")}\n >\n <span\n aria-hidden=\"true\"\n className={[\n \"pointer-events-none inline-block h-4 w-4 rounded-full bg-white shadow ring-0 transition-transform\",\n value ? \"translate-x-4\" : \"translate-x-0\",\n ].join(\" \")}\n />\n </button>\n {label ? (\n <span className=\"text-sm font-medium text-slate-700 dark:text-slate-200\">\n {label}\n </span>\n ) : null}\n </label>\n );\n}\n"],"names":["ToggleFilter","value","onChange","label","className","jsxs","jsx"],"mappings":";AAUA,SAAwBA,EAAa;AAAA,EACnC,OAAAC,IAAQ;AAAA,EACR,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAC,IAAY;AACd,GAAsB;AACpB,SACE,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACAD;AAAA,MAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,MAEX,UAAA;AAAA,QAAA,gBAAAE;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,MAAK;AAAA,YACL,gBAAcL;AAAA,YACd,SAAS,MAAMC,IAAW,CAACD,CAAK;AAAA,YAChC,WAAW;AAAA,cACT;AAAA,cACAA,IACI,iBACA;AAAA,YAAA,EACJ,KAAK,GAAG;AAAA,YAEV,UAAA,gBAAAK;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,eAAY;AAAA,gBACZ,WAAW;AAAA,kBACT;AAAA,kBACAL,IAAQ,kBAAkB;AAAA,gBAAA,EAC1B,KAAK,GAAG;AAAA,cAAA;AAAA,YAAA;AAAA,UACZ;AAAA,QAAA;AAAA,QAEDE,IACC,gBAAAG,EAAC,QAAA,EAAK,WAAU,0DACb,aACH,IACE;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGV;"}
@@ -1,12 +1,14 @@
1
+ import type { FormField as FormFieldType } from "./FormRenderer";
2
+ export interface FormFieldProps {
3
+ field: FormFieldType & Record<string, unknown>;
4
+ value: unknown;
5
+ error?: string;
6
+ touched?: boolean;
7
+ onChange: (value: unknown) => void;
8
+ onBlur: () => void;
9
+ }
1
10
  /**
2
11
  * Renders a single form field with label, description, error message,
3
12
  * and the appropriate input type.
4
13
  */
5
- export default function FormField({ field, value, error, touched, onChange, onBlur }: {
6
- field: any;
7
- value: any;
8
- error: any;
9
- touched: any;
10
- onChange: any;
11
- onBlur: any;
12
- }): import("react/jsx-runtime").JSX.Element | null;
14
+ export default function FormField({ field, value, error, touched, onChange, onBlur }: FormFieldProps): import("react/jsx-runtime").JSX.Element | null;
@@ -1,5 +1,4 @@
1
1
  import { jsxs as c, jsx as r } from "react/jsx-runtime";
2
- import "react";
3
2
  import { ChevronDownIcon as m } from "@heroicons/react/24/outline";
4
3
  const p = "h-10 w-full rounded-lg border border-slate-200 bg-white px-3 text-sm text-slate-900 shadow-sm placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:ring-offset-2 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-50 dark:placeholder:text-slate-500 dark:focus:ring-offset-slate-950", x = "border-red-300 focus:ring-red-500 dark:border-red-700 dark:focus:ring-red-500";
5
4
  function i(...e) {
@@ -229,7 +228,7 @@ const E = {
229
228
  checkboxGroup: F,
230
229
  toggle: C
231
230
  };
232
- function O({ field: e, value: n, error: s, touched: a, onChange: d, onBlur: t }) {
231
+ function L({ field: e, value: n, error: s, touched: a, onChange: d, onBlur: t }) {
233
232
  const o = E[e.type];
234
233
  if (!o) return null;
235
234
  const l = s && a, b = e.type === "checkbox";
@@ -243,7 +242,7 @@ function O({ field: e, value: n, error: s, touched: a, onChange: d, onBlur: t })
243
242
  value: n,
244
243
  onChange: d,
245
244
  onBlur: t,
246
- error: l
245
+ error: !!l
247
246
  }
248
247
  ),
249
248
  e.type === "toggle" && e.description ? /* @__PURE__ */ r(g, { description: e.description }) : null,
@@ -251,6 +250,6 @@ function O({ field: e, value: n, error: s, touched: a, onChange: d, onBlur: t })
251
250
  ] });
252
251
  }
253
252
  export {
254
- O as default
253
+ L as default
255
254
  };
256
255
  //# sourceMappingURL=FormField.js.map