@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,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