@schandlergarcia/sf-web-components 1.7.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) 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/chat/ChatBar.d.ts +14 -11
  52. package/dist/components/library/chat/ChatBar.js +2 -3
  53. package/dist/components/library/chat/ChatBar.js.map +1 -1
  54. package/dist/components/library/chat/ChatInput.d.ts +9 -8
  55. package/dist/components/library/chat/ChatInput.js.map +1 -1
  56. package/dist/components/library/chat/ChatMessage.d.ts +17 -4
  57. package/dist/components/library/chat/ChatMessage.js.map +1 -1
  58. package/dist/components/library/chat/ChatMessageList.d.ts +11 -8
  59. package/dist/components/library/chat/ChatMessageList.js.map +1 -1
  60. package/dist/components/library/chat/ChatPanel.d.ts +16 -12
  61. package/dist/components/library/chat/ChatPanel.js +8 -9
  62. package/dist/components/library/chat/ChatPanel.js.map +1 -1
  63. package/dist/components/library/chat/ChatSuggestions.d.ts +5 -4
  64. package/dist/components/library/chat/ChatSuggestions.js +2 -3
  65. package/dist/components/library/chat/ChatSuggestions.js.map +1 -1
  66. package/dist/components/library/chat/ChatToolCall.d.ts +11 -3
  67. package/dist/components/library/chat/ChatToolCall.js.map +1 -1
  68. package/dist/components/library/chat/ChatTypingIndicator.d.ts +4 -3
  69. package/dist/components/library/chat/ChatTypingIndicator.js +2 -3
  70. package/dist/components/library/chat/ChatTypingIndicator.js.map +1 -1
  71. package/dist/components/library/chat/ChatWelcome.d.ts +9 -7
  72. package/dist/components/library/chat/ChatWelcome.js +6 -7
  73. package/dist/components/library/chat/ChatWelcome.js.map +1 -1
  74. package/dist/components/library/chat/index.d.ts +10 -0
  75. package/dist/components/library/chat/useChatState.d.ts +36 -11
  76. package/dist/components/library/chat/useChatState.js +63 -46
  77. package/dist/components/library/chat/useChatState.js.map +1 -1
  78. package/dist/components/library/data/DataModeProvider.d.ts +15 -11
  79. package/dist/components/library/data/DataModeProvider.js +1 -1
  80. package/dist/components/library/data/DataModeProvider.js.map +1 -1
  81. package/dist/components/library/data/DataModeToggle.d.ts +4 -3
  82. package/dist/components/library/data/DataModeToggle.js +4 -5
  83. package/dist/components/library/data/DataModeToggle.js.map +1 -1
  84. package/dist/components/library/data/chartDataProvider.d.ts +41 -3
  85. package/dist/components/library/data/filterUtils.d.ts +38 -9
  86. package/dist/components/library/data/filterUtils.js.map +1 -1
  87. package/dist/components/library/data/useDataSource.d.ts +6 -4
  88. package/dist/components/library/data/useDataSource.js.map +1 -1
  89. package/dist/components/library/data/usePageFilters.d.ts +31 -5
  90. package/dist/components/library/data/usePageFilters.js +6 -2
  91. package/dist/components/library/data/usePageFilters.js.map +1 -1
  92. package/dist/components/library/filters/FilterBar.d.ts +18 -8
  93. package/dist/components/library/filters/FilterBar.js +2 -3
  94. package/dist/components/library/filters/FilterBar.js.map +1 -1
  95. package/dist/components/library/filters/SearchFilter.d.ts +7 -6
  96. package/dist/components/library/filters/SearchFilter.js +2 -3
  97. package/dist/components/library/filters/SearchFilter.js.map +1 -1
  98. package/dist/components/library/filters/SelectFilter.d.ts +13 -7
  99. package/dist/components/library/filters/SelectFilter.js +2 -3
  100. package/dist/components/library/filters/SelectFilter.js.map +1 -1
  101. package/dist/components/library/filters/ToggleFilter.d.ts +7 -5
  102. package/dist/components/library/filters/ToggleFilter.js +2 -3
  103. package/dist/components/library/filters/ToggleFilter.js.map +1 -1
  104. package/dist/components/library/forms/FormField.d.ts +10 -8
  105. package/dist/components/library/forms/FormField.js +3 -4
  106. package/dist/components/library/forms/FormField.js.map +1 -1
  107. package/dist/components/library/forms/FormModal.d.ts +23 -14
  108. package/dist/components/library/forms/FormModal.js.map +1 -1
  109. package/dist/components/library/forms/FormRenderer.d.ts +29 -9
  110. package/dist/components/library/forms/FormRenderer.js +6 -7
  111. package/dist/components/library/forms/FormRenderer.js.map +1 -1
  112. package/dist/components/library/forms/FormSection.d.ts +10 -8
  113. package/dist/components/library/forms/FormSection.js +2 -3
  114. package/dist/components/library/forms/FormSection.js.map +1 -1
  115. package/dist/components/library/forms/index.d.ts +5 -0
  116. package/dist/components/library/forms/useFormState.d.ts +23 -15
  117. package/dist/components/library/forms/useFormState.js +53 -47
  118. package/dist/components/library/forms/useFormState.js.map +1 -1
  119. package/dist/components/library/index.d.ts +92 -73
  120. package/dist/components/library/index.js +25 -25
  121. package/dist/components/library/index.js.map +1 -1
  122. package/dist/components/library/layout/PageContainer.d.ts +6 -4
  123. package/dist/components/library/layout/PageContainer.js +4 -5
  124. package/dist/components/library/layout/PageContainer.js.map +1 -1
  125. package/dist/components/library/skeletons/CardSkeleton.d.ts +5 -4
  126. package/dist/components/library/skeletons/CardSkeleton.js +2 -3
  127. package/dist/components/library/skeletons/CardSkeleton.js.map +1 -1
  128. package/dist/components/library/theme/AppThemeProvider.d.ts +13 -50
  129. package/dist/components/library/theme/AppThemeProvider.js.map +1 -1
  130. package/dist/components/library/theme/tokens.d.ts +45 -44
  131. package/dist/components/library/theme/tokens.js.map +1 -1
  132. package/package.json +4 -1
  133. package/src/components/library/cards/{ActionList.jsx → ActionList.tsx} +13 -9
  134. package/src/components/library/cards/{ActivityCard.jsx → ActivityCard.tsx} +33 -4
  135. package/src/components/library/cards/{BaseCard.jsx → BaseCard.tsx} +33 -6
  136. package/src/components/library/cards/{CalloutCard.jsx → CalloutCard.tsx} +12 -10
  137. package/src/components/library/cards/{ChartCard.jsx → ChartCard.tsx} +32 -6
  138. package/src/components/library/cards/{FeedPanel.jsx → FeedPanel.tsx} +13 -2
  139. package/src/components/library/cards/{ListCard.jsx → ListCard.tsx} +43 -7
  140. package/src/components/library/cards/{MetricCard.jsx → MetricCard.tsx} +25 -6
  141. package/src/components/library/cards/{MetricsStrip.jsx → MetricsStrip.tsx} +22 -12
  142. package/src/components/library/cards/{SectionCard.jsx → SectionCard.tsx} +27 -8
  143. package/src/components/library/cards/{SemanticMetricCard.jsx → SemanticMetricCard.tsx} +18 -6
  144. package/src/components/library/cards/{SemanticMetricCardWithLoading.jsx → SemanticMetricCardWithLoading.tsx} +9 -3
  145. package/src/components/library/cards/{SemanticTableCard.jsx → SemanticTableCard.tsx} +16 -5
  146. package/src/components/library/cards/{SemanticTableCardWithLoading.jsx → SemanticTableCardWithLoading.tsx} +9 -5
  147. package/src/components/library/cards/{StatusCard.jsx → StatusCard.tsx} +61 -12
  148. package/src/components/library/cards/{TableCard.jsx → TableCard.tsx} +51 -12
  149. package/src/components/library/cards/{WidgetCard.jsx → WidgetCard.tsx} +28 -5
  150. package/src/components/library/charts/{D3Chart.jsx → D3Chart.tsx} +27 -7
  151. package/src/components/library/charts/{D3ChartTemplates.jsx → D3ChartTemplates.tsx} +60 -28
  152. package/src/components/library/charts/{GeoMap.jsx → GeoMap.tsx} +106 -17
  153. package/src/components/library/chat/{ChatBar.jsx → ChatBar.tsx} +19 -8
  154. package/src/components/library/chat/{ChatInput.jsx → ChatInput.tsx} +13 -11
  155. package/src/components/library/chat/{ChatMessage.jsx → ChatMessage.tsx} +22 -9
  156. package/src/components/library/chat/{ChatMessageList.jsx → ChatMessageList.tsx} +13 -11
  157. package/src/components/library/chat/{ChatPanel.jsx → ChatPanel.tsx} +16 -13
  158. package/src/components/library/chat/{ChatSuggestions.jsx → ChatSuggestions.tsx} +6 -5
  159. package/src/components/library/chat/{ChatToolCall.jsx → ChatToolCall.tsx} +14 -4
  160. package/src/components/library/chat/{ChatTypingIndicator.jsx → ChatTypingIndicator.tsx} +5 -2
  161. package/src/components/library/chat/{ChatWelcome.jsx → ChatWelcome.tsx} +9 -7
  162. package/src/components/library/chat/index.tsx +26 -0
  163. package/src/components/library/chat/useChatState.tsx +181 -0
  164. package/src/components/library/data/{DataModeProvider.jsx → DataModeProvider.tsx} +25 -8
  165. package/src/components/library/data/{DataModeToggle.jsx → DataModeToggle.tsx} +5 -2
  166. package/src/components/library/data/{chartDataProvider.jsx → chartDataProvider.tsx} +49 -5
  167. package/src/components/library/data/{filterUtils.jsx → filterUtils.tsx} +58 -12
  168. package/src/components/library/data/{useDataSource.jsx → useDataSource.tsx} +9 -2
  169. package/src/components/library/data/{usePageFilters.jsx → usePageFilters.tsx} +49 -9
  170. package/src/components/library/filters/{FilterBar.jsx → FilterBar.tsx} +21 -11
  171. package/src/components/library/filters/{SearchFilter.jsx → SearchFilter.tsx} +8 -2
  172. package/src/components/library/filters/{SelectFilter.jsx → SelectFilter.tsx} +15 -8
  173. package/src/components/library/filters/{ToggleFilter.jsx → ToggleFilter.tsx} +7 -6
  174. package/src/components/library/forms/{FormField.jsx → FormField.tsx} +91 -45
  175. package/src/components/library/forms/{FormModal.jsx → FormModal.tsx} +21 -20
  176. package/src/components/library/forms/{FormRenderer.jsx → FormRenderer.tsx} +32 -10
  177. package/src/components/library/forms/{FormSection.jsx → FormSection.tsx} +13 -7
  178. package/src/components/library/forms/index.tsx +11 -0
  179. package/src/components/library/forms/{useFormState.jsx → useFormState.tsx} +43 -23
  180. package/src/components/library/{index.jsx → index.ts} +14 -14
  181. package/src/components/library/layout/{PageContainer.jsx → PageContainer.tsx} +6 -3
  182. package/src/components/library/skeletons/{CardSkeleton.jsx → CardSkeleton.tsx} +5 -4
  183. package/src/components/library/theme/{AppThemeProvider.jsx → AppThemeProvider.tsx} +20 -7
  184. package/src/components/library/theme/{tokens.jsx → tokens.tsx} +37 -3
  185. package/src/components/library/chat/index.jsx +0 -10
  186. package/src/components/library/chat/useChatState.jsx +0 -130
  187. package/src/components/library/forms/index.jsx +0 -5
  188. /package/src/components/library/filters/{index.jsx → index.ts} +0 -0
@@ -17,7 +17,7 @@ function v({ initialMode: n = "sample", children: r }) {
17
17
  t.useEffect(() => {
18
18
  try {
19
19
  const e = window.localStorage.getItem(l);
20
- c.includes(e) && a(e);
20
+ e && c.includes(e) && a(e);
21
21
  } catch {
22
22
  }
23
23
  }, []), t.useEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"DataModeProvider.js","sources":["../../../../src/components/library/data/DataModeProvider.jsx"],"sourcesContent":["import React from \"react\";\n\nconst DataModeContext = React.createContext({\n mode: \"sample\",\n isSample: true,\n isLive: false,\n toggle: () => {},\n setMode: () => {},\n});\n\nconst STORAGE_KEY = \"app-data-mode\";\nconst VALID_MODES = [\"sample\", \"live\"];\n\n/**\n * Read the current data mode from any component.\n *\n * @returns {{ mode: \"sample\"|\"live\", isSample: boolean, isLive: boolean, toggle: () => void, setMode: (mode) => void }}\n */\nexport function useDataMode() {\n return React.useContext(DataModeContext);\n}\n\n/**\n * Provides global data-mode state (sample vs live) to the component tree.\n * Persists to localStorage so the choice survives page reloads.\n *\n * Wrap once in _app.js alongside AppThemeProvider.\n */\nexport default function DataModeProvider({ initialMode = \"sample\", children }) {\n const [mode, setModeState] = React.useState(initialMode);\n\n React.useEffect(() => {\n try {\n const stored = window.localStorage.getItem(STORAGE_KEY);\n if (VALID_MODES.includes(stored)) setModeState(stored);\n } catch {\n // SSR or storage unavailable\n }\n }, []);\n\n React.useEffect(() => {\n try {\n window.localStorage.setItem(STORAGE_KEY, mode);\n } catch {\n // ignore\n }\n }, [mode]);\n\n const setMode = React.useCallback((m) => {\n if (VALID_MODES.includes(m)) setModeState(m);\n }, []);\n\n const value = React.useMemo(\n () => ({\n mode,\n isSample: mode === \"sample\",\n isLive: mode === \"live\",\n toggle: () => setModeState((m) => (m === \"sample\" ? \"live\" : \"sample\")),\n setMode,\n }),\n [mode, setMode]\n );\n\n return (\n <DataModeContext.Provider value={value}>{children}</DataModeContext.Provider>\n );\n}\n"],"names":["DataModeContext","React","STORAGE_KEY","VALID_MODES","useDataMode","DataModeProvider","initialMode","children","mode","setModeState","stored","setMode","m","value","jsx"],"mappings":";;AAEA,MAAMA,IAAkBC,EAAM,cAAc;AAAA,EAC1C,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,QAAQ,MAAM;AAAA,EAAC;AAAA,EACf,SAAS,MAAM;AAAA,EAAC;AAClB,CAAC,GAEKC,IAAc,iBACdC,IAAc,CAAC,UAAU,MAAM;AAO9B,SAASC,IAAc;AAC5B,SAAOH,EAAM,WAAWD,CAAe;AACzC;AAQA,SAAwBK,EAAiB,EAAE,aAAAC,IAAc,UAAU,UAAAC,KAAY;AAC7E,QAAM,CAACC,GAAMC,CAAY,IAAIR,EAAM,SAASK,CAAW;AAEvDL,EAAAA,EAAM,UAAU,MAAM;AACpB,QAAI;AACF,YAAMS,IAAS,OAAO,aAAa,QAAQR,CAAW;AACtD,MAAIC,EAAY,SAASO,CAAM,OAAgBA,CAAM;AAAA,IACvD,QAAQ;AAAA,IAER;AAAA,EACF,GAAG,CAAA,CAAE,GAELT,EAAM,UAAU,MAAM;AACpB,QAAI;AACF,aAAO,aAAa,QAAQC,GAAaM,CAAI;AAAA,IAC/C,QAAQ;AAAA,IAER;AAAA,EACF,GAAG,CAACA,CAAI,CAAC;AAET,QAAMG,IAAUV,EAAM,YAAY,CAACW,MAAM;AACvC,IAAIT,EAAY,SAASS,CAAC,OAAgBA,CAAC;AAAA,EAC7C,GAAG,CAAA,CAAE,GAECC,IAAQZ,EAAM;AAAA,IAClB,OAAO;AAAA,MACL,MAAAO;AAAA,MACA,UAAUA,MAAS;AAAA,MACnB,QAAQA,MAAS;AAAA,MACjB,QAAQ,MAAMC,EAAa,CAACG,MAAOA,MAAM,WAAW,SAAS,QAAS;AAAA,MACtE,SAAAD;AAAA,IAAA;AAAA,IAEF,CAACH,GAAMG,CAAO;AAAA,EAAA;AAGhB,SACE,gBAAAG,EAACd,EAAgB,UAAhB,EAAyB,OAAAa,GAAe,UAAAN,EAAA,CAAS;AAEtD;"}
1
+ {"version":3,"file":"DataModeProvider.js","sources":["../../../../src/components/library/data/DataModeProvider.tsx"],"sourcesContent":["import React from \"react\";\n\nexport type DataMode = \"sample\" | \"live\";\n\nexport interface DataModeContextValue {\n mode: DataMode;\n isSample: boolean;\n isLive: boolean;\n toggle: () => void;\n setMode: (mode: DataMode) => void;\n}\n\nconst DataModeContext = React.createContext<DataModeContextValue>({\n mode: \"sample\",\n isSample: true,\n isLive: false,\n toggle: () => {},\n setMode: () => {},\n});\n\nconst STORAGE_KEY = \"app-data-mode\";\nconst VALID_MODES: DataMode[] = [\"sample\", \"live\"];\n\n/**\n * Read the current data mode from any component.\n *\n * @returns {{ mode: \"sample\"|\"live\", isSample: boolean, isLive: boolean, toggle: () => void, setMode: (mode) => void }}\n */\nexport function useDataMode(): DataModeContextValue {\n return React.useContext(DataModeContext);\n}\n\nexport interface DataModeProviderProps {\n initialMode?: DataMode;\n children: React.ReactNode;\n}\n\n/**\n * Provides global data-mode state (sample vs live) to the component tree.\n * Persists to localStorage so the choice survives page reloads.\n *\n * Wrap once in _app.js alongside AppThemeProvider.\n */\nexport default function DataModeProvider({ initialMode = \"sample\", children }: DataModeProviderProps) {\n const [mode, setModeState] = React.useState<DataMode>(initialMode);\n\n React.useEffect(() => {\n try {\n const stored = window.localStorage.getItem(STORAGE_KEY);\n if (stored && VALID_MODES.includes(stored as DataMode)) {\n setModeState(stored as DataMode);\n }\n } catch {\n // SSR or storage unavailable\n }\n }, []);\n\n React.useEffect(() => {\n try {\n window.localStorage.setItem(STORAGE_KEY, mode);\n } catch {\n // ignore\n }\n }, [mode]);\n\n const setMode = React.useCallback((m: DataMode) => {\n if (VALID_MODES.includes(m)) setModeState(m);\n }, []);\n\n const value = React.useMemo<DataModeContextValue>(\n () => ({\n mode,\n isSample: mode === \"sample\",\n isLive: mode === \"live\",\n toggle: () => setModeState((m) => (m === \"sample\" ? \"live\" : \"sample\")),\n setMode,\n }),\n [mode, setMode]\n );\n\n return (\n <DataModeContext.Provider value={value}>{children}</DataModeContext.Provider>\n );\n}\n"],"names":["DataModeContext","React","STORAGE_KEY","VALID_MODES","useDataMode","DataModeProvider","initialMode","children","mode","setModeState","stored","setMode","m","value","jsx"],"mappings":";;AAYA,MAAMA,IAAkBC,EAAM,cAAoC;AAAA,EAChE,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,QAAQ,MAAM;AAAA,EAAC;AAAA,EACf,SAAS,MAAM;AAAA,EAAC;AAClB,CAAC,GAEKC,IAAc,iBACdC,IAA0B,CAAC,UAAU,MAAM;AAO1C,SAASC,IAAoC;AAClD,SAAOH,EAAM,WAAWD,CAAe;AACzC;AAaA,SAAwBK,EAAiB,EAAE,aAAAC,IAAc,UAAU,UAAAC,KAAmC;AACpG,QAAM,CAACC,GAAMC,CAAY,IAAIR,EAAM,SAAmBK,CAAW;AAEjEL,EAAAA,EAAM,UAAU,MAAM;AACpB,QAAI;AACF,YAAMS,IAAS,OAAO,aAAa,QAAQR,CAAW;AACtD,MAAIQ,KAAUP,EAAY,SAASO,CAAkB,KACnDD,EAAaC,CAAkB;AAAA,IAEnC,QAAQ;AAAA,IAER;AAAA,EACF,GAAG,CAAA,CAAE,GAELT,EAAM,UAAU,MAAM;AACpB,QAAI;AACF,aAAO,aAAa,QAAQC,GAAaM,CAAI;AAAA,IAC/C,QAAQ;AAAA,IAER;AAAA,EACF,GAAG,CAACA,CAAI,CAAC;AAET,QAAMG,IAAUV,EAAM,YAAY,CAACW,MAAgB;AACjD,IAAIT,EAAY,SAASS,CAAC,OAAgBA,CAAC;AAAA,EAC7C,GAAG,CAAA,CAAE,GAECC,IAAQZ,EAAM;AAAA,IAClB,OAAO;AAAA,MACL,MAAAO;AAAA,MACA,UAAUA,MAAS;AAAA,MACnB,QAAQA,MAAS;AAAA,MACjB,QAAQ,MAAMC,EAAa,CAACG,MAAOA,MAAM,WAAW,SAAS,QAAS;AAAA,MACtE,SAAAD;AAAA,IAAA;AAAA,IAEF,CAACH,GAAMG,CAAO;AAAA,EAAA;AAGhB,SACE,gBAAAG,EAACd,EAAgB,UAAhB,EAAyB,OAAAa,GAAe,UAAAN,EAAA,CAAS;AAEtD;"}
@@ -1,7 +1,8 @@
1
+ export interface DataModeToggleProps {
2
+ className?: string;
3
+ }
1
4
  /**
2
5
  * Pill toggle for switching between sample and live data modes.
3
6
  * Place in the AppShell header next to the theme toggle.
4
7
  */
5
- export default function DataModeToggle({ className }: {
6
- className?: string | undefined;
7
- }): import("react/jsx-runtime").JSX.Element;
8
+ export default function DataModeToggle({ className }: DataModeToggleProps): import("react/jsx-runtime").JSX.Element;
@@ -1,8 +1,7 @@
1
1
  import { jsxs as d, jsx as a } from "react/jsx-runtime";
2
- import "react";
3
2
  import { useDataMode as m } from "./DataModeProvider.js";
4
- import { BeakerIcon as l, SignalIcon as i } from "@heroicons/react/24/outline";
5
- function c({ className: o = "" }) {
3
+ import { BeakerIcon as l, SignalIcon as b } from "@heroicons/react/24/outline";
4
+ function g({ className: o = "" }) {
6
5
  const { mode: r, toggle: t } = m(), e = r === "sample";
7
6
  return /* @__PURE__ */ d(
8
7
  "button",
@@ -16,13 +15,13 @@ function c({ className: o = "" }) {
16
15
  ].filter(Boolean).join(" "),
17
16
  "aria-label": `Data mode: ${r}. Click to switch to ${e ? "live" : "sample"}.`,
18
17
  children: [
19
- e ? /* @__PURE__ */ a(l, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) : /* @__PURE__ */ a(i, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
18
+ e ? /* @__PURE__ */ a(l, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) : /* @__PURE__ */ a(b, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
20
19
  e ? "Sample" : "Live"
21
20
  ]
22
21
  }
23
22
  );
24
23
  }
25
24
  export {
26
- c as default
25
+ g as default
27
26
  };
28
27
  //# sourceMappingURL=DataModeToggle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DataModeToggle.js","sources":["../../../../src/components/library/data/DataModeToggle.jsx"],"sourcesContent":["import React from \"react\";\nimport { useDataMode } from \"./DataModeProvider\";\nimport { BeakerIcon, SignalIcon } from \"@heroicons/react/24/outline\";\n\n/**\n * Pill toggle for switching between sample and live data modes.\n * Place in the AppShell header next to the theme toggle.\n */\nexport default function DataModeToggle({ className = \"\" }) {\n const { mode, toggle } = useDataMode();\n const isSample = mode === \"sample\";\n\n return (\n <button\n type=\"button\"\n onClick={toggle}\n className={[\n \"inline-flex items-center gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs font-semibold shadow-sm transition\",\n isSample\n ? \"border-amber-200 bg-amber-50 text-amber-700 hover:bg-amber-100 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-300 dark:hover:bg-amber-950/60\"\n : \"border-emerald-200 bg-emerald-50 text-emerald-700 hover:bg-emerald-100 dark:border-emerald-800 dark:bg-emerald-950/40 dark:text-emerald-300 dark:hover:bg-emerald-950/60\",\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n aria-label={`Data mode: ${mode}. Click to switch to ${isSample ? \"live\" : \"sample\"}.`}\n >\n {isSample ? (\n <BeakerIcon className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n ) : (\n <SignalIcon className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n )}\n {isSample ? \"Sample\" : \"Live\"}\n </button>\n );\n}\n"],"names":["DataModeToggle","className","mode","toggle","useDataMode","isSample","jsxs","jsx","BeakerIcon","SignalIcon"],"mappings":";;;;AAQA,SAAwBA,EAAe,EAAE,WAAAC,IAAY,MAAM;AACzD,QAAM,EAAE,MAAAC,GAAM,QAAAC,EAAA,IAAWC,EAAA,GACnBC,IAAWH,MAAS;AAE1B,SACE,gBAAAI;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,SAASH;AAAA,MACT,WAAW;AAAA,QACT;AAAA,QACAE,IACI,6JACA;AAAA,QACJJ;AAAA,MAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,MACX,cAAY,cAAcC,CAAI,wBAAwBG,IAAW,SAAS,QAAQ;AAAA,MAEjF,UAAA;AAAA,QAAAA,IACC,gBAAAE,EAACC,GAAA,EAAW,WAAU,eAAc,eAAY,OAAA,CAAO,IAEvD,gBAAAD,EAACE,GAAA,EAAW,WAAU,eAAc,eAAY,QAAO;AAAA,QAExDJ,IAAW,WAAW;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAG7B;"}
1
+ {"version":3,"file":"DataModeToggle.js","sources":["../../../../src/components/library/data/DataModeToggle.tsx"],"sourcesContent":["import { useDataMode } from \"./DataModeProvider\";\nimport { BeakerIcon, SignalIcon } from \"@heroicons/react/24/outline\";\n\nexport interface DataModeToggleProps {\n className?: string;\n}\n\n/**\n * Pill toggle for switching between sample and live data modes.\n * Place in the AppShell header next to the theme toggle.\n */\nexport default function DataModeToggle({ className = \"\" }: DataModeToggleProps) {\n const { mode, toggle } = useDataMode();\n const isSample = mode === \"sample\";\n\n return (\n <button\n type=\"button\"\n onClick={toggle}\n className={[\n \"inline-flex items-center gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs font-semibold shadow-sm transition\",\n isSample\n ? \"border-amber-200 bg-amber-50 text-amber-700 hover:bg-amber-100 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-300 dark:hover:bg-amber-950/60\"\n : \"border-emerald-200 bg-emerald-50 text-emerald-700 hover:bg-emerald-100 dark:border-emerald-800 dark:bg-emerald-950/40 dark:text-emerald-300 dark:hover:bg-emerald-950/60\",\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n aria-label={`Data mode: ${mode}. Click to switch to ${isSample ? \"live\" : \"sample\"}.`}\n >\n {isSample ? (\n <BeakerIcon className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n ) : (\n <SignalIcon className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n )}\n {isSample ? \"Sample\" : \"Live\"}\n </button>\n );\n}\n"],"names":["DataModeToggle","className","mode","toggle","useDataMode","isSample","jsxs","jsx","BeakerIcon","SignalIcon"],"mappings":";;;AAWA,SAAwBA,EAAe,EAAE,WAAAC,IAAY,MAA2B;AAC9E,QAAM,EAAE,MAAAC,GAAM,QAAAC,EAAA,IAAWC,EAAA,GACnBC,IAAWH,MAAS;AAE1B,SACE,gBAAAI;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,SAASH;AAAA,MACT,WAAW;AAAA,QACT;AAAA,QACAE,IACI,6JACA;AAAA,QACJJ;AAAA,MAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,MACX,cAAY,cAAcC,CAAI,wBAAwBG,IAAW,SAAS,QAAQ;AAAA,MAEjF,UAAA;AAAA,QAAAA,IACC,gBAAAE,EAACC,GAAA,EAAW,WAAU,eAAc,eAAY,OAAA,CAAO,IAEvD,gBAAAD,EAACE,GAAA,EAAW,WAAU,eAAc,eAAY,QAAO;AAAA,QAExDJ,IAAW,WAAW;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAG7B;"}
@@ -1,3 +1,41 @@
1
- export function listSemanticIds(): string[];
2
- export function getSemanticDataset(semanticId: any): any;
3
- export function getSemanticMetric(semanticId: any, metricId: any): any;
1
+ export type ChangeType = "positive" | "negative" | "neutral";
2
+ export type MetricColor = "primary" | "success" | "warning" | "danger";
3
+ export type ColumnType = "currency" | "percentage" | "number" | "text";
4
+ export interface SemanticMetric {
5
+ metricId: string;
6
+ title: string;
7
+ subtitle: string;
8
+ value: string;
9
+ change?: string;
10
+ changeType?: ChangeType;
11
+ color?: MetricColor;
12
+ trend?: string;
13
+ }
14
+ export interface TableColumn {
15
+ key: string;
16
+ label: string;
17
+ type?: ColumnType;
18
+ sortable?: boolean;
19
+ mono?: boolean;
20
+ }
21
+ export interface TableRow {
22
+ id: number;
23
+ [key: string]: any;
24
+ }
25
+ export interface SemanticTable {
26
+ title: string;
27
+ subtitle: string;
28
+ columns: TableColumn[];
29
+ rows: TableRow[];
30
+ }
31
+ export interface SemanticDataset {
32
+ title: string;
33
+ metrics?: SemanticMetric[];
34
+ table?: SemanticTable;
35
+ }
36
+ export interface SemanticDatasets {
37
+ [key: string]: SemanticDataset;
38
+ }
39
+ export declare function listSemanticIds(): string[];
40
+ export declare function getSemanticDataset(semanticId: string): SemanticDataset | null;
41
+ export declare function getSemanticMetric(semanticId: string, metricId: string): SemanticMetric | null;
@@ -2,6 +2,38 @@
2
2
  * Pure data utilities for filtering, sorting, and searching.
3
3
  * Stateless — combine with usePageFilters hook for state management.
4
4
  */
5
+ export type SortDirection = "asc" | "desc";
6
+ export interface DateRange {
7
+ start?: Date | string;
8
+ end?: Date | string;
9
+ }
10
+ export type FilterType = "search" | "select" | "toggle" | "dateRange";
11
+ export interface BaseFilterDefinition {
12
+ id: string;
13
+ type: FilterType;
14
+ defaultValue?: any;
15
+ }
16
+ export interface SearchFilterDefinition extends BaseFilterDefinition {
17
+ type: "search";
18
+ keys: string[];
19
+ }
20
+ export interface SelectFilterDefinition extends BaseFilterDefinition {
21
+ type: "select";
22
+ key: string;
23
+ }
24
+ export interface ToggleFilterDefinition extends BaseFilterDefinition {
25
+ type: "toggle";
26
+ key: string;
27
+ matchValue?: any;
28
+ }
29
+ export interface DateRangeFilterDefinition extends BaseFilterDefinition {
30
+ type: "dateRange";
31
+ key: string;
32
+ }
33
+ export type FilterDefinition = SearchFilterDefinition | SelectFilterDefinition | ToggleFilterDefinition | DateRangeFilterDefinition;
34
+ export interface FilterValues {
35
+ [key: string]: any;
36
+ }
5
37
  /**
6
38
  * Text search across multiple keys.
7
39
  * @param {Array} data
@@ -9,7 +41,7 @@
9
41
  * @param {string[]} keys — object keys to search within
10
42
  * @returns {Array} filtered data
11
43
  */
12
- export function filterBySearch(data: any[], query: string, keys?: string[]): any[];
44
+ export declare function filterBySearch<T>(data: T[], query: string, keys?: string[]): T[];
13
45
  /**
14
46
  * Filter rows where key matches a specific value.
15
47
  * Pass "all" or "" to skip filtering.
@@ -18,7 +50,7 @@ export function filterBySearch(data: any[], query: string, keys?: string[]): any
18
50
  * @param {*} value — value to match (exact, case-insensitive for strings)
19
51
  * @returns {Array}
20
52
  */
21
- export function filterByValue(data: any[], key: string, value: any): any[];
53
+ export declare function filterByValue<T>(data: T[], key: string, value: any): T[];
22
54
  /**
23
55
  * Filter rows where a boolean condition is met.
24
56
  * When toggle is off, returns all data (no filtering).
@@ -28,7 +60,7 @@ export function filterByValue(data: any[], key: string, value: any): any[];
28
60
  * @param {*} matchValue — value that key should equal when active (default: truthy check)
29
61
  * @returns {Array}
30
62
  */
31
- export function filterByToggle(data: any[], key: string, isActive: boolean, matchValue: any): any[];
63
+ export declare function filterByToggle<T>(data: T[], key: string, isActive: boolean, matchValue?: any): T[];
32
64
  /**
33
65
  * Filter rows where a date field falls within a range.
34
66
  * @param {Array} data
@@ -36,10 +68,7 @@ export function filterByToggle(data: any[], key: string, isActive: boolean, matc
36
68
  * @param {{ start?: Date|string, end?: Date|string }} range
37
69
  * @returns {Array}
38
70
  */
39
- export function filterByDateRange(data: any[], key: string, range: {
40
- start?: Date | string;
41
- end?: Date | string;
42
- }): any[];
71
+ export declare function filterByDateRange<T>(data: T[], key: string, range: DateRange | null): T[];
43
72
  /**
44
73
  * Sort data by a key.
45
74
  * @param {Array} data
@@ -47,7 +76,7 @@ export function filterByDateRange(data: any[], key: string, range: {
47
76
  * @param {"asc"|"desc"} direction
48
77
  * @returns {Array} new sorted array
49
78
  */
50
- export function sortByKey(data: any[], key: string, direction?: "asc" | "desc"): any[];
79
+ export declare function sortByKey<T>(data: T[], key: string, direction?: SortDirection): T[];
51
80
  /**
52
81
  * Apply a set of filter definitions to data.
53
82
  * Each filter in `filters` has { id, type, key/keys } and `values` holds the current state.
@@ -57,4 +86,4 @@ export function sortByKey(data: any[], key: string, direction?: "asc" | "desc"):
57
86
  * @param {Object} values — current filter values keyed by filter id
58
87
  * @returns {Array} filtered data
59
88
  */
60
- export function applyFilters(data: any[], filters?: any[], values?: Object): any[];
89
+ export declare function applyFilters<T>(data: T[], filters?: FilterDefinition[], values?: FilterValues): T[];
@@ -1 +1 @@
1
- {"version":3,"file":"filterUtils.js","sources":["../../../../src/components/library/data/filterUtils.jsx"],"sourcesContent":["/**\n * Pure data utilities for filtering, sorting, and searching.\n * Stateless — combine with usePageFilters hook for state management.\n */\n\n/**\n * Text search across multiple keys.\n * @param {Array} data\n * @param {string} query — search string\n * @param {string[]} keys — object keys to search within\n * @returns {Array} filtered data\n */\nexport function filterBySearch(data, query, keys = []) {\n if (!query || !query.trim()) return data;\n const q = query.trim().toLowerCase();\n return data.filter((row) =>\n keys.some((key) => {\n const val = row?.[key];\n return val != null && String(val).toLowerCase().includes(q);\n })\n );\n}\n\n/**\n * Filter rows where key matches a specific value.\n * Pass \"all\" or \"\" to skip filtering.\n * @param {Array} data\n * @param {string} key — object key to match\n * @param {*} value — value to match (exact, case-insensitive for strings)\n * @returns {Array}\n */\nexport function filterByValue(data, key, value) {\n if (value == null || value === \"\" || value === \"all\") return data;\n return data.filter((row) => {\n const v = row?.[key];\n if (typeof v === \"string\" && typeof value === \"string\") {\n return v.toLowerCase() === value.toLowerCase();\n }\n return v === value;\n });\n}\n\n/**\n * Filter rows where a boolean condition is met.\n * When toggle is off, returns all data (no filtering).\n * @param {Array} data\n * @param {string} key — object key to check\n * @param {boolean} isActive — whether the toggle is on\n * @param {*} matchValue — value that key should equal when active (default: truthy check)\n * @returns {Array}\n */\nexport function filterByToggle(data, key, isActive, matchValue) {\n if (!isActive) return data;\n return data.filter((row) => {\n const v = row?.[key];\n if (matchValue !== undefined) return v === matchValue;\n return Boolean(v);\n });\n}\n\n/**\n * Filter rows where a date field falls within a range.\n * @param {Array} data\n * @param {string} key — object key containing date (ISO string or Date)\n * @param {{ start?: Date|string, end?: Date|string }} range\n * @returns {Array}\n */\nexport function filterByDateRange(data, key, range) {\n if (!range) return data;\n const start = range.start ? new Date(range.start) : null;\n const end = range.end ? new Date(range.end) : null;\n if (!start && !end) return data;\n\n return data.filter((row) => {\n const raw = row?.[key];\n if (raw == null) return false;\n const d = raw instanceof Date ? raw : new Date(raw);\n if (Number.isNaN(d.getTime())) return false;\n if (start && d < start) return false;\n if (end && d > end) return false;\n return true;\n });\n}\n\n/**\n * Sort data by a key.\n * @param {Array} data\n * @param {string} key — object key to sort by\n * @param {\"asc\"|\"desc\"} direction\n * @returns {Array} new sorted array\n */\nexport function sortByKey(data, key, direction = \"asc\") {\n if (!key) return data;\n const dir = direction === \"desc\" ? -1 : 1;\n return [...data].sort((a, b) => {\n const av = a?.[key];\n const bv = b?.[key];\n if (av == null && bv == null) return 0;\n if (av == null) return -1 * dir;\n if (bv == null) return 1 * dir;\n if (typeof av === \"number\" && typeof bv === \"number\") return (av - bv) * dir;\n return String(av).localeCompare(String(bv)) * dir;\n });\n}\n\n/**\n * Apply a set of filter definitions to data.\n * Each filter in `filters` has { id, type, key/keys } and `values` holds the current state.\n *\n * @param {Array} data\n * @param {Array} filters — filter definitions [{ id, type, key?, keys? }]\n * @param {Object} values — current filter values keyed by filter id\n * @returns {Array} filtered data\n */\nexport function applyFilters(data, filters = [], values = {}) {\n let result = data;\n\n for (const filter of filters) {\n const val = values[filter.id];\n if (val === undefined || val === null) continue;\n\n switch (filter.type) {\n case \"search\":\n result = filterBySearch(result, val, filter.keys ?? []);\n break;\n case \"select\":\n result = filterByValue(result, filter.key, val);\n break;\n case \"toggle\":\n result = filterByToggle(result, filter.key, val, filter.matchValue);\n break;\n case \"dateRange\":\n result = filterByDateRange(result, filter.key, val);\n break;\n default:\n break;\n }\n }\n\n return result;\n}\n"],"names":["filterBySearch","data","query","keys","q","row","key","val","filterByValue","value","v","filterByToggle","isActive","matchValue","filterByDateRange","range","start","end","raw","d","sortByKey","direction","dir","a","b","av","bv","applyFilters","filters","values","result","filter"],"mappings":"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"}
1
+ {"version":3,"file":"filterUtils.js","sources":["../../../../src/components/library/data/filterUtils.tsx"],"sourcesContent":["/**\n * Pure data utilities for filtering, sorting, and searching.\n * Stateless — combine with usePageFilters hook for state management.\n */\n\nexport type SortDirection = \"asc\" | \"desc\";\n\nexport interface DateRange {\n start?: Date | string;\n end?: Date | string;\n}\n\nexport type FilterType = \"search\" | \"select\" | \"toggle\" | \"dateRange\";\n\nexport interface BaseFilterDefinition {\n id: string;\n type: FilterType;\n defaultValue?: any;\n}\n\nexport interface SearchFilterDefinition extends BaseFilterDefinition {\n type: \"search\";\n keys: string[];\n}\n\nexport interface SelectFilterDefinition extends BaseFilterDefinition {\n type: \"select\";\n key: string;\n}\n\nexport interface ToggleFilterDefinition extends BaseFilterDefinition {\n type: \"toggle\";\n key: string;\n matchValue?: any;\n}\n\nexport interface DateRangeFilterDefinition extends BaseFilterDefinition {\n type: \"dateRange\";\n key: string;\n}\n\nexport type FilterDefinition =\n | SearchFilterDefinition\n | SelectFilterDefinition\n | ToggleFilterDefinition\n | DateRangeFilterDefinition;\n\nexport interface FilterValues {\n [key: string]: any;\n}\n\n/**\n * Text search across multiple keys.\n * @param {Array} data\n * @param {string} query — search string\n * @param {string[]} keys — object keys to search within\n * @returns {Array} filtered data\n */\nexport function filterBySearch<T>(data: T[], query: string, keys: string[] = []): T[] {\n if (!query || !query.trim()) return data;\n const q = query.trim().toLowerCase();\n return data.filter((row) =>\n keys.some((key) => {\n const val = (row as any)?.[key];\n return val != null && String(val).toLowerCase().includes(q);\n })\n );\n}\n\n/**\n * Filter rows where key matches a specific value.\n * Pass \"all\" or \"\" to skip filtering.\n * @param {Array} data\n * @param {string} key — object key to match\n * @param {*} value — value to match (exact, case-insensitive for strings)\n * @returns {Array}\n */\nexport function filterByValue<T>(data: T[], key: string, value: any): T[] {\n if (value == null || value === \"\" || value === \"all\") return data;\n return data.filter((row) => {\n const v = (row as any)?.[key];\n if (typeof v === \"string\" && typeof value === \"string\") {\n return v.toLowerCase() === value.toLowerCase();\n }\n return v === value;\n });\n}\n\n/**\n * Filter rows where a boolean condition is met.\n * When toggle is off, returns all data (no filtering).\n * @param {Array} data\n * @param {string} key — object key to check\n * @param {boolean} isActive — whether the toggle is on\n * @param {*} matchValue — value that key should equal when active (default: truthy check)\n * @returns {Array}\n */\nexport function filterByToggle<T>(data: T[], key: string, isActive: boolean, matchValue?: any): T[] {\n if (!isActive) return data;\n return data.filter((row) => {\n const v = (row as any)?.[key];\n if (matchValue !== undefined) return v === matchValue;\n return Boolean(v);\n });\n}\n\n/**\n * Filter rows where a date field falls within a range.\n * @param {Array} data\n * @param {string} key — object key containing date (ISO string or Date)\n * @param {{ start?: Date|string, end?: Date|string }} range\n * @returns {Array}\n */\nexport function filterByDateRange<T>(data: T[], key: string, range: DateRange | null): T[] {\n if (!range) return data;\n const start = range.start ? new Date(range.start) : null;\n const end = range.end ? new Date(range.end) : null;\n if (!start && !end) return data;\n\n return data.filter((row) => {\n const raw = (row as any)?.[key];\n if (raw == null) return false;\n const d = raw instanceof Date ? raw : new Date(raw);\n if (Number.isNaN(d.getTime())) return false;\n if (start && d < start) return false;\n if (end && d > end) return false;\n return true;\n });\n}\n\n/**\n * Sort data by a key.\n * @param {Array} data\n * @param {string} key — object key to sort by\n * @param {\"asc\"|\"desc\"} direction\n * @returns {Array} new sorted array\n */\nexport function sortByKey<T>(data: T[], key: string, direction: SortDirection = \"asc\"): T[] {\n if (!key) return data;\n const dir = direction === \"desc\" ? -1 : 1;\n return [...data].sort((a, b) => {\n const av = (a as any)?.[key];\n const bv = (b as any)?.[key];\n if (av == null && bv == null) return 0;\n if (av == null) return -1 * dir;\n if (bv == null) return 1 * dir;\n if (typeof av === \"number\" && typeof bv === \"number\") return (av - bv) * dir;\n return String(av).localeCompare(String(bv)) * dir;\n });\n}\n\n/**\n * Apply a set of filter definitions to data.\n * Each filter in `filters` has { id, type, key/keys } and `values` holds the current state.\n *\n * @param {Array} data\n * @param {Array} filters — filter definitions [{ id, type, key?, keys? }]\n * @param {Object} values — current filter values keyed by filter id\n * @returns {Array} filtered data\n */\nexport function applyFilters<T>(data: T[], filters: FilterDefinition[] = [], values: FilterValues = {}): T[] {\n let result = data;\n\n for (const filter of filters) {\n const val = values[filter.id];\n if (val === undefined || val === null) continue;\n\n switch (filter.type) {\n case \"search\":\n result = filterBySearch(result, val, filter.keys ?? []);\n break;\n case \"select\":\n result = filterByValue(result, filter.key, val);\n break;\n case \"toggle\":\n result = filterByToggle(result, filter.key, val, filter.matchValue);\n break;\n case \"dateRange\":\n result = filterByDateRange(result, filter.key, val);\n break;\n default:\n break;\n }\n }\n\n return result;\n}\n"],"names":["filterBySearch","data","query","keys","q","row","key","val","filterByValue","value","v","filterByToggle","isActive","matchValue","filterByDateRange","range","start","end","raw","d","sortByKey","direction","dir","a","b","av","bv","applyFilters","filters","values","result","filter"],"mappings":"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"}
@@ -1,3 +1,8 @@
1
+ export type DataSourceValue<T> = T | (() => T);
2
+ export interface UseDataSourceOptions<T> {
3
+ sample: DataSourceValue<T>;
4
+ live: DataSourceValue<T>;
5
+ }
1
6
  /**
2
7
  * Select between sample and live data based on the global data mode.
3
8
  *
@@ -20,7 +25,4 @@
20
25
  * live: () => computeFromAPI(apiData),
21
26
  * });
22
27
  */
23
- export default function useDataSource({ sample, live }: {
24
- sample: any | (() => any);
25
- live: any | (() => any);
26
- }): any;
28
+ export default function useDataSource<T>({ sample, live }: UseDataSourceOptions<T>): T;
@@ -1 +1 @@
1
- {"version":3,"file":"useDataSource.js","sources":["../../../../src/components/library/data/useDataSource.jsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useDataMode } from \"./DataModeProvider\";\n\n/**\n * Select between sample and live data based on the global data mode.\n *\n * Values can be plain data or functions (lazy-evaluated only when active).\n *\n * @param {{ sample: any | () => any, live: any | () => any }} sources\n * @returns {any} the resolved value for the active mode\n *\n * @example\n * // Static data\n * const incidents = useDataSource({\n * sample: sampleIncidents,\n * live: fetchedIncidents,\n * });\n *\n * @example\n * // Lazy — factory only runs when that mode is active\n * const metrics = useDataSource({\n * sample: () => generateSampleMetrics(),\n * live: () => computeFromAPI(apiData),\n * });\n */\nexport default function useDataSource({ sample, live }) {\n const { mode } = useDataMode();\n\n return useMemo(() => {\n const source = mode === \"sample\" ? sample : live;\n return typeof source === \"function\" ? source() : source;\n }, [mode, sample, live]);\n}\n"],"names":["useDataSource","sample","live","mode","useDataMode","useMemo","source"],"mappings":";;AAyBA,SAAwBA,EAAc,EAAE,QAAAC,GAAQ,MAAAC,KAAQ;AACtD,QAAM,EAAE,MAAAC,EAAA,IAASC,EAAA;AAEjB,SAAOC,EAAQ,MAAM;AACnB,UAAMC,IAASH,MAAS,WAAWF,IAASC;AAC5C,WAAO,OAAOI,KAAW,aAAaA,EAAA,IAAWA;AAAA,EACnD,GAAG,CAACH,GAAMF,GAAQC,CAAI,CAAC;AACzB;"}
1
+ {"version":3,"file":"useDataSource.js","sources":["../../../../src/components/library/data/useDataSource.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useDataMode } from \"./DataModeProvider\";\n\nexport type DataSourceValue<T> = T | (() => T);\n\nexport interface UseDataSourceOptions<T> {\n sample: DataSourceValue<T>;\n live: DataSourceValue<T>;\n}\n\n/**\n * Select between sample and live data based on the global data mode.\n *\n * Values can be plain data or functions (lazy-evaluated only when active).\n *\n * @param {{ sample: any | () => any, live: any | () => any }} sources\n * @returns {any} the resolved value for the active mode\n *\n * @example\n * // Static data\n * const incidents = useDataSource({\n * sample: sampleIncidents,\n * live: fetchedIncidents,\n * });\n *\n * @example\n * // Lazy — factory only runs when that mode is active\n * const metrics = useDataSource({\n * sample: () => generateSampleMetrics(),\n * live: () => computeFromAPI(apiData),\n * });\n */\nexport default function useDataSource<T>({ sample, live }: UseDataSourceOptions<T>): T {\n const { mode } = useDataMode();\n\n return useMemo(() => {\n const source = mode === \"sample\" ? sample : live;\n return typeof source === \"function\" ? (source as () => T)() : source;\n }, [mode, sample, live]);\n}\n"],"names":["useDataSource","sample","live","mode","useDataMode","useMemo","source"],"mappings":";;AAgCA,SAAwBA,EAAiB,EAAE,QAAAC,GAAQ,MAAAC,KAAoC;AACrF,QAAM,EAAE,MAAAC,EAAA,IAASC,EAAA;AAEjB,SAAOC,EAAQ,MAAM;AACnB,UAAMC,IAASH,MAAS,WAAWF,IAASC;AAC5C,WAAO,OAAOI,KAAW,aAAcA,EAAA,IAAuBA;AAAA,EAChE,GAAG,CAACH,GAAMF,GAAQC,CAAI,CAAC;AACzB;"}
@@ -1,3 +1,33 @@
1
+ import { FilterDefinition } from "./filterUtils";
2
+ export type SortDirection = "asc" | "desc";
3
+ export interface SortState {
4
+ key: string;
5
+ direction: SortDirection;
6
+ }
7
+ export interface DateRange {
8
+ start?: Date | string;
9
+ end?: Date | string;
10
+ }
11
+ export type FilterValue = string | boolean | DateRange | null;
12
+ export interface FilterValues {
13
+ [key: string]: FilterValue;
14
+ }
15
+ export interface UsePageFiltersOptions<T> {
16
+ data?: T[];
17
+ filters?: FilterDefinition[];
18
+ defaultSort?: SortState | null;
19
+ }
20
+ export interface UsePageFiltersReturn<T> {
21
+ values: FilterValues;
22
+ setFilter: (id: string, value: FilterValue) => void;
23
+ resetFilters: () => void;
24
+ sort: SortState | null;
25
+ setSort: (key: string | null, direction?: SortDirection) => void;
26
+ toggleSort: (key: string) => void;
27
+ filteredData: T[];
28
+ sortedData: T[];
29
+ activeFilterCount: number;
30
+ }
1
31
  /**
2
32
  * Hook for managing page-level filter and sort state.
3
33
  *
@@ -18,8 +48,4 @@
18
48
  * defaultSort: { key: "timestamp", direction: "desc" },
19
49
  * });
20
50
  */
21
- export default function usePageFilters({ data, filters, defaultSort }?: {
22
- data: any[];
23
- filters: any[];
24
- defaultSort: Object;
25
- }): Object;
51
+ export default function usePageFilters<T = any>({ data, filters, defaultSort, }?: UsePageFiltersOptions<T>): UsePageFiltersReturn<T>;
@@ -1,6 +1,10 @@
1
1
  import { useMemo as r, useState as p, useCallback as a } from "react";
2
2
  import { applyFilters as h, sortByKey as C } from "./filterUtils.js";
3
- function b({ data: u = [], filters: o = [], defaultSort: y = null } = {}) {
3
+ function b({
4
+ data: u = [],
5
+ filters: o = [],
6
+ defaultSort: y = null
7
+ } = {}) {
4
8
  const c = r(() => {
5
9
  const t = {};
6
10
  for (const e of o)
@@ -24,7 +28,7 @@ function b({ data: u = [], filters: o = [], defaultSort: y = null } = {}) {
24
28
  let t = 0;
25
29
  for (const e of o) {
26
30
  const s = l[e.id];
27
- (e.type === "search" && s && s.trim() || e.type === "select" && s && s !== "all" || e.type === "toggle" && s || e.type === "dateRange" && s) && t++;
31
+ (e.type === "search" && s && typeof s == "string" && s.trim() || e.type === "select" && s && s !== "all" || e.type === "toggle" && s || e.type === "dateRange" && s) && t++;
28
32
  }
29
33
  return t;
30
34
  }, [o, l]);
@@ -1 +1 @@
1
- {"version":3,"file":"usePageFilters.js","sources":["../../../../src/components/library/data/usePageFilters.jsx"],"sourcesContent":["import { useState, useMemo, useCallback } from \"react\";\nimport { applyFilters, sortByKey } from \"./filterUtils\";\n\n/**\n * Hook for managing page-level filter and sort state.\n *\n * @param {Object} options\n * @param {Array} options.data — raw data array\n * @param {Array} options.filters — filter definitions [{ id, type, key?, keys?, defaultValue? }]\n * @param {Object} options.defaultSort — { key, direction } or null\n * @returns {Object} { values, setFilter, resetFilters, sort, setSort, filteredData, sortedData, activeFilterCount }\n *\n * @example\n * const { values, setFilter, resetFilters, sortedData } = usePageFilters({\n * data: incidents,\n * filters: [\n * { id: \"search\", type: \"search\", keys: [\"title\", \"description\"] },\n * { id: \"severity\", type: \"select\", key: \"severity\", defaultValue: \"all\" },\n * { id: \"active\", type: \"toggle\", key: \"resolved\", matchValue: false },\n * ],\n * defaultSort: { key: \"timestamp\", direction: \"desc\" },\n * });\n */\nexport default function usePageFilters({ data = [], filters = [], defaultSort = null } = {}) {\n const initialValues = useMemo(() => {\n const v = {};\n for (const f of filters) {\n if (f.defaultValue !== undefined) {\n v[f.id] = f.defaultValue;\n } else if (f.type === \"search\") {\n v[f.id] = \"\";\n } else if (f.type === \"select\") {\n v[f.id] = \"all\";\n } else if (f.type === \"toggle\") {\n v[f.id] = false;\n } else if (f.type === \"dateRange\") {\n v[f.id] = null;\n }\n }\n return v;\n }, [filters]);\n\n const [values, setValues] = useState(initialValues);\n const [sort, setSortState] = useState(defaultSort);\n\n const setFilter = useCallback((id, value) => {\n setValues((prev) => ({ ...prev, [id]: value }));\n }, []);\n\n const resetFilters = useCallback(() => {\n setValues(initialValues);\n }, [initialValues]);\n\n const setSort = useCallback((key, direction) => {\n setSortState(key ? { key, direction: direction ?? \"asc\" } : null);\n }, []);\n\n const toggleSort = useCallback((key) => {\n setSortState((prev) => {\n if (prev?.key !== key) return { key, direction: \"asc\" };\n if (prev.direction === \"asc\") return { key, direction: \"desc\" };\n return null;\n });\n }, []);\n\n const filteredData = useMemo(\n () => applyFilters(data, filters, values),\n [data, filters, values]\n );\n\n const sortedData = useMemo(\n () => (sort ? sortByKey(filteredData, sort.key, sort.direction) : filteredData),\n [filteredData, sort]\n );\n\n const activeFilterCount = useMemo(() => {\n let count = 0;\n for (const f of filters) {\n const v = values[f.id];\n if (f.type === \"search\" && v && v.trim()) count++;\n else if (f.type === \"select\" && v && v !== \"all\") count++;\n else if (f.type === \"toggle\" && v) count++;\n else if (f.type === \"dateRange\" && v) count++;\n }\n return count;\n }, [filters, values]);\n\n return {\n values,\n setFilter,\n resetFilters,\n sort,\n setSort,\n toggleSort,\n filteredData,\n sortedData,\n activeFilterCount,\n };\n}\n"],"names":["usePageFilters","data","filters","defaultSort","initialValues","useMemo","v","f","values","setValues","useState","sort","setSortState","setFilter","useCallback","id","value","prev","resetFilters","setSort","key","direction","toggleSort","filteredData","applyFilters","sortedData","sortByKey","activeFilterCount","count"],"mappings":";;AAuBA,SAAwBA,EAAe,EAAE,MAAAC,IAAO,IAAI,SAAAC,IAAU,CAAA,GAAI,aAAAC,IAAc,KAAA,IAAS,IAAI;AAC3F,QAAMC,IAAgBC,EAAQ,MAAM;AAClC,UAAMC,IAAI,CAAA;AACV,eAAWC,KAAKL;AACd,MAAIK,EAAE,iBAAiB,SACrBD,EAAEC,EAAE,EAAE,IAAIA,EAAE,eACHA,EAAE,SAAS,WACpBD,EAAEC,EAAE,EAAE,IAAI,KACDA,EAAE,SAAS,WACpBD,EAAEC,EAAE,EAAE,IAAI,QACDA,EAAE,SAAS,WACpBD,EAAEC,EAAE,EAAE,IAAI,KACDA,EAAE,SAAS,gBACpBD,EAAEC,EAAE,EAAE,IAAI;AAGd,WAAOD;AAAA,EACT,GAAG,CAACJ,CAAO,CAAC,GAEN,CAACM,GAAQC,CAAS,IAAIC,EAASN,CAAa,GAC5C,CAACO,GAAMC,CAAY,IAAIF,EAASP,CAAW,GAE3CU,IAAYC,EAAY,CAACC,GAAIC,MAAU;AAC3C,IAAAP,EAAU,CAACQ,OAAU,EAAE,GAAGA,GAAM,CAACF,CAAE,GAAGC,EAAA,EAAQ;AAAA,EAChD,GAAG,CAAA,CAAE,GAECE,IAAeJ,EAAY,MAAM;AACrC,IAAAL,EAAUL,CAAa;AAAA,EACzB,GAAG,CAACA,CAAa,CAAC,GAEZe,IAAUL,EAAY,CAACM,GAAKC,MAAc;AAC9C,IAAAT,EAAaQ,IAAM,EAAE,KAAAA,GAAK,WAAWC,KAAa,MAAA,IAAU,IAAI;AAAA,EAClE,GAAG,CAAA,CAAE,GAECC,IAAaR,EAAY,CAACM,MAAQ;AACtC,IAAAR,EAAa,CAACK,MACRA,GAAM,QAAQG,IAAY,EAAE,KAAAA,GAAK,WAAW,MAAA,IAC5CH,EAAK,cAAc,QAAc,EAAE,KAAAG,GAAK,WAAW,OAAA,IAChD,IACR;AAAA,EACH,GAAG,CAAA,CAAE,GAECG,IAAelB;AAAA,IACnB,MAAMmB,EAAavB,GAAMC,GAASM,CAAM;AAAA,IACxC,CAACP,GAAMC,GAASM,CAAM;AAAA,EAAA,GAGlBiB,IAAapB;AAAA,IACjB,MAAOM,IAAOe,EAAUH,GAAcZ,EAAK,KAAKA,EAAK,SAAS,IAAIY;AAAA,IAClE,CAACA,GAAcZ,CAAI;AAAA,EAAA,GAGfgB,IAAoBtB,EAAQ,MAAM;AACtC,QAAIuB,IAAQ;AACZ,eAAWrB,KAAKL,GAAS;AACvB,YAAMI,IAAIE,EAAOD,EAAE,EAAE;AACrB,OAAIA,EAAE,SAAS,YAAYD,KAAKA,EAAE,UACzBC,EAAE,SAAS,YAAYD,KAAKA,MAAM,SAClCC,EAAE,SAAS,YAAYD,KACvBC,EAAE,SAAS,eAAeD,MAAGsB;AAAA,IACxC;AACA,WAAOA;AAAA,EACT,GAAG,CAAC1B,GAASM,CAAM,CAAC;AAEpB,SAAO;AAAA,IACL,QAAAA;AAAA,IACA,WAAAK;AAAA,IACA,cAAAK;AAAA,IACA,MAAAP;AAAA,IACA,SAAAQ;AAAA,IACA,YAAAG;AAAA,IACA,cAAAC;AAAA,IACA,YAAAE;AAAA,IACA,mBAAAE;AAAA,EAAA;AAEJ;"}
1
+ {"version":3,"file":"usePageFilters.js","sources":["../../../../src/components/library/data/usePageFilters.tsx"],"sourcesContent":["import { useState, useMemo, useCallback } from \"react\";\nimport { applyFilters, sortByKey, FilterDefinition } from \"./filterUtils\";\n\nexport type SortDirection = \"asc\" | \"desc\";\n\nexport interface SortState {\n key: string;\n direction: SortDirection;\n}\n\nexport interface DateRange {\n start?: Date | string;\n end?: Date | string;\n}\n\nexport type FilterValue = string | boolean | DateRange | null;\n\nexport interface FilterValues {\n [key: string]: FilterValue;\n}\n\nexport interface UsePageFiltersOptions<T> {\n data?: T[];\n filters?: FilterDefinition[];\n defaultSort?: SortState | null;\n}\n\nexport interface UsePageFiltersReturn<T> {\n values: FilterValues;\n setFilter: (id: string, value: FilterValue) => void;\n resetFilters: () => void;\n sort: SortState | null;\n setSort: (key: string | null, direction?: SortDirection) => void;\n toggleSort: (key: string) => void;\n filteredData: T[];\n sortedData: T[];\n activeFilterCount: number;\n}\n\n/**\n * Hook for managing page-level filter and sort state.\n *\n * @param {Object} options\n * @param {Array} options.data — raw data array\n * @param {Array} options.filters — filter definitions [{ id, type, key?, keys?, defaultValue? }]\n * @param {Object} options.defaultSort — { key, direction } or null\n * @returns {Object} { values, setFilter, resetFilters, sort, setSort, filteredData, sortedData, activeFilterCount }\n *\n * @example\n * const { values, setFilter, resetFilters, sortedData } = usePageFilters({\n * data: incidents,\n * filters: [\n * { id: \"search\", type: \"search\", keys: [\"title\", \"description\"] },\n * { id: \"severity\", type: \"select\", key: \"severity\", defaultValue: \"all\" },\n * { id: \"active\", type: \"toggle\", key: \"resolved\", matchValue: false },\n * ],\n * defaultSort: { key: \"timestamp\", direction: \"desc\" },\n * });\n */\nexport default function usePageFilters<T = any>({\n data = [],\n filters = [],\n defaultSort = null,\n}: UsePageFiltersOptions<T> = {}): UsePageFiltersReturn<T> {\n const initialValues = useMemo(() => {\n const v: FilterValues = {};\n for (const f of filters) {\n if (f.defaultValue !== undefined) {\n v[f.id] = f.defaultValue;\n } else if (f.type === \"search\") {\n v[f.id] = \"\";\n } else if (f.type === \"select\") {\n v[f.id] = \"all\";\n } else if (f.type === \"toggle\") {\n v[f.id] = false;\n } else if (f.type === \"dateRange\") {\n v[f.id] = null;\n }\n }\n return v;\n }, [filters]);\n\n const [values, setValues] = useState<FilterValues>(initialValues);\n const [sort, setSortState] = useState<SortState | null>(defaultSort);\n\n const setFilter = useCallback((id: string, value: FilterValue) => {\n setValues((prev) => ({ ...prev, [id]: value }));\n }, []);\n\n const resetFilters = useCallback(() => {\n setValues(initialValues);\n }, [initialValues]);\n\n const setSort = useCallback((key: string | null, direction?: SortDirection) => {\n setSortState(key ? { key, direction: direction ?? \"asc\" } : null);\n }, []);\n\n const toggleSort = useCallback((key: string) => {\n setSortState((prev) => {\n if (prev?.key !== key) return { key, direction: \"asc\" };\n if (prev.direction === \"asc\") return { key, direction: \"desc\" };\n return null;\n });\n }, []);\n\n const filteredData = useMemo(\n () => applyFilters(data, filters, values),\n [data, filters, values]\n );\n\n const sortedData = useMemo(\n () => (sort ? sortByKey(filteredData, sort.key, sort.direction) : filteredData),\n [filteredData, sort]\n );\n\n const activeFilterCount = useMemo(() => {\n let count = 0;\n for (const f of filters) {\n const v = values[f.id];\n if (f.type === \"search\" && v && typeof v === \"string\" && v.trim()) count++;\n else if (f.type === \"select\" && v && v !== \"all\") count++;\n else if (f.type === \"toggle\" && v) count++;\n else if (f.type === \"dateRange\" && v) count++;\n }\n return count;\n }, [filters, values]);\n\n return {\n values,\n setFilter,\n resetFilters,\n sort,\n setSort,\n toggleSort,\n filteredData,\n sortedData,\n activeFilterCount,\n };\n}\n"],"names":["usePageFilters","data","filters","defaultSort","initialValues","useMemo","v","f","values","setValues","useState","sort","setSortState","setFilter","useCallback","id","value","prev","resetFilters","setSort","key","direction","toggleSort","filteredData","applyFilters","sortedData","sortByKey","activeFilterCount","count"],"mappings":";;AA2DA,SAAwBA,EAAwB;AAAA,EAC9C,MAAAC,IAAO,CAAA;AAAA,EACP,SAAAC,IAAU,CAAA;AAAA,EACV,aAAAC,IAAc;AAChB,IAA8B,IAA6B;AACzD,QAAMC,IAAgBC,EAAQ,MAAM;AAClC,UAAMC,IAAkB,CAAA;AACxB,eAAWC,KAAKL;AACd,MAAIK,EAAE,iBAAiB,SACrBD,EAAEC,EAAE,EAAE,IAAIA,EAAE,eACHA,EAAE,SAAS,WACpBD,EAAEC,EAAE,EAAE,IAAI,KACDA,EAAE,SAAS,WACpBD,EAAEC,EAAE,EAAE,IAAI,QACDA,EAAE,SAAS,WACpBD,EAAEC,EAAE,EAAE,IAAI,KACDA,EAAE,SAAS,gBACpBD,EAAEC,EAAE,EAAE,IAAI;AAGd,WAAOD;AAAA,EACT,GAAG,CAACJ,CAAO,CAAC,GAEN,CAACM,GAAQC,CAAS,IAAIC,EAAuBN,CAAa,GAC1D,CAACO,GAAMC,CAAY,IAAIF,EAA2BP,CAAW,GAE7DU,IAAYC,EAAY,CAACC,GAAYC,MAAuB;AAChE,IAAAP,EAAU,CAACQ,OAAU,EAAE,GAAGA,GAAM,CAACF,CAAE,GAAGC,EAAA,EAAQ;AAAA,EAChD,GAAG,CAAA,CAAE,GAECE,IAAeJ,EAAY,MAAM;AACrC,IAAAL,EAAUL,CAAa;AAAA,EACzB,GAAG,CAACA,CAAa,CAAC,GAEZe,IAAUL,EAAY,CAACM,GAAoBC,MAA8B;AAC7E,IAAAT,EAAaQ,IAAM,EAAE,KAAAA,GAAK,WAAWC,KAAa,MAAA,IAAU,IAAI;AAAA,EAClE,GAAG,CAAA,CAAE,GAECC,IAAaR,EAAY,CAACM,MAAgB;AAC9C,IAAAR,EAAa,CAACK,MACRA,GAAM,QAAQG,IAAY,EAAE,KAAAA,GAAK,WAAW,MAAA,IAC5CH,EAAK,cAAc,QAAc,EAAE,KAAAG,GAAK,WAAW,OAAA,IAChD,IACR;AAAA,EACH,GAAG,CAAA,CAAE,GAECG,IAAelB;AAAA,IACnB,MAAMmB,EAAavB,GAAMC,GAASM,CAAM;AAAA,IACxC,CAACP,GAAMC,GAASM,CAAM;AAAA,EAAA,GAGlBiB,IAAapB;AAAA,IACjB,MAAOM,IAAOe,EAAUH,GAAcZ,EAAK,KAAKA,EAAK,SAAS,IAAIY;AAAA,IAClE,CAACA,GAAcZ,CAAI;AAAA,EAAA,GAGfgB,IAAoBtB,EAAQ,MAAM;AACtC,QAAIuB,IAAQ;AACZ,eAAWrB,KAAKL,GAAS;AACvB,YAAMI,IAAIE,EAAOD,EAAE,EAAE;AACrB,OAAIA,EAAE,SAAS,YAAYD,KAAK,OAAOA,KAAM,YAAYA,EAAE,KAAA,KAClDC,EAAE,SAAS,YAAYD,KAAKA,MAAM,SAClCC,EAAE,SAAS,YAAYD,KACvBC,EAAE,SAAS,eAAeD,MAAGsB;AAAA,IACxC;AACA,WAAOA;AAAA,EACT,GAAG,CAAC1B,GAASM,CAAM,CAAC;AAEpB,SAAO;AAAA,IACL,QAAAA;AAAA,IACA,WAAAK;AAAA,IACA,cAAAK;AAAA,IACA,MAAAP;AAAA,IACA,SAAAQ;AAAA,IACA,YAAAG;AAAA,IACA,cAAAC;AAAA,IACA,YAAAE;AAAA,IACA,mBAAAE;AAAA,EAAA;AAEJ;"}
@@ -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;