@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.
- package/dist/components/library/cards/ActionList.d.ts +10 -10
- package/dist/components/library/cards/ActionList.js +2 -3
- package/dist/components/library/cards/ActionList.js.map +1 -1
- package/dist/components/library/cards/ActivityCard.d.ts +18 -5
- package/dist/components/library/cards/ActivityCard.js +3 -4
- package/dist/components/library/cards/ActivityCard.js.map +1 -1
- package/dist/components/library/cards/BaseCard.d.ts +30 -24
- package/dist/components/library/cards/BaseCard.js +2 -3
- package/dist/components/library/cards/BaseCard.js.map +1 -1
- package/dist/components/library/cards/CalloutCard.d.ts +11 -9
- package/dist/components/library/cards/CalloutCard.js +2 -3
- package/dist/components/library/cards/CalloutCard.js.map +1 -1
- package/dist/components/library/cards/ChartCard.d.ts +29 -17
- package/dist/components/library/cards/ChartCard.js +13 -14
- package/dist/components/library/cards/ChartCard.js.map +1 -1
- package/dist/components/library/cards/FeedPanel.d.ts +12 -11
- package/dist/components/library/cards/FeedPanel.js +3 -4
- package/dist/components/library/cards/FeedPanel.js.map +1 -1
- package/dist/components/library/cards/ListCard.d.ts +33 -20
- package/dist/components/library/cards/ListCard.js +35 -35
- package/dist/components/library/cards/ListCard.js.map +1 -1
- package/dist/components/library/cards/MetricCard.d.ts +23 -17
- package/dist/components/library/cards/MetricCard.js +10 -11
- package/dist/components/library/cards/MetricCard.js.map +1 -1
- package/dist/components/library/cards/MetricsStrip.d.ts +11 -11
- package/dist/components/library/cards/MetricsStrip.js +1 -1
- package/dist/components/library/cards/MetricsStrip.js.map +1 -1
- package/dist/components/library/cards/SectionCard.d.ts +17 -12
- package/dist/components/library/cards/SectionCard.js +18 -19
- package/dist/components/library/cards/SectionCard.js.map +1 -1
- package/dist/components/library/cards/SemanticMetricCard.d.ts +15 -20
- package/dist/components/library/cards/SemanticMetricCardWithLoading.d.ts +8 -7
- package/dist/components/library/cards/SemanticTableCard.d.ts +13 -18
- package/dist/components/library/cards/SemanticTableCardWithLoading.d.ts +8 -7
- package/dist/components/library/cards/StatusCard.d.ts +29 -15
- package/dist/components/library/cards/StatusCard.js +16 -17
- package/dist/components/library/cards/StatusCard.js.map +1 -1
- package/dist/components/library/cards/TableCard.d.ts +40 -23
- package/dist/components/library/cards/TableCard.js +59 -59
- package/dist/components/library/cards/TableCard.js.map +1 -1
- package/dist/components/library/cards/WidgetCard.d.ts +19 -11
- package/dist/components/library/cards/WidgetCard.js.map +1 -1
- package/dist/components/library/charts/D3Chart.d.ts +23 -16
- package/dist/components/library/charts/D3Chart.js.map +1 -1
- package/dist/components/library/charts/D3ChartTemplates.d.ts +33 -3
- package/dist/components/library/charts/D3ChartTemplates.js +7 -7
- package/dist/components/library/charts/D3ChartTemplates.js.map +1 -1
- package/dist/components/library/charts/GeoMap.d.ts +81 -18
- package/dist/components/library/charts/GeoMap.js +28 -26
- package/dist/components/library/charts/GeoMap.js.map +1 -1
- package/dist/components/library/chat/ChatBar.d.ts +14 -11
- package/dist/components/library/chat/ChatBar.js +2 -3
- package/dist/components/library/chat/ChatBar.js.map +1 -1
- package/dist/components/library/chat/ChatInput.d.ts +9 -8
- package/dist/components/library/chat/ChatInput.js.map +1 -1
- package/dist/components/library/chat/ChatMessage.d.ts +17 -4
- package/dist/components/library/chat/ChatMessage.js.map +1 -1
- package/dist/components/library/chat/ChatMessageList.d.ts +11 -8
- package/dist/components/library/chat/ChatMessageList.js.map +1 -1
- package/dist/components/library/chat/ChatPanel.d.ts +16 -12
- package/dist/components/library/chat/ChatPanel.js +8 -9
- package/dist/components/library/chat/ChatPanel.js.map +1 -1
- package/dist/components/library/chat/ChatSuggestions.d.ts +5 -4
- package/dist/components/library/chat/ChatSuggestions.js +2 -3
- package/dist/components/library/chat/ChatSuggestions.js.map +1 -1
- package/dist/components/library/chat/ChatToolCall.d.ts +11 -3
- package/dist/components/library/chat/ChatToolCall.js.map +1 -1
- package/dist/components/library/chat/ChatTypingIndicator.d.ts +4 -3
- package/dist/components/library/chat/ChatTypingIndicator.js +2 -3
- package/dist/components/library/chat/ChatTypingIndicator.js.map +1 -1
- package/dist/components/library/chat/ChatWelcome.d.ts +9 -7
- package/dist/components/library/chat/ChatWelcome.js +6 -7
- package/dist/components/library/chat/ChatWelcome.js.map +1 -1
- package/dist/components/library/chat/index.d.ts +10 -0
- package/dist/components/library/chat/useChatState.d.ts +36 -11
- package/dist/components/library/chat/useChatState.js +63 -46
- package/dist/components/library/chat/useChatState.js.map +1 -1
- package/dist/components/library/data/DataModeProvider.d.ts +15 -11
- package/dist/components/library/data/DataModeProvider.js +1 -1
- package/dist/components/library/data/DataModeProvider.js.map +1 -1
- package/dist/components/library/data/DataModeToggle.d.ts +4 -3
- package/dist/components/library/data/DataModeToggle.js +4 -5
- package/dist/components/library/data/DataModeToggle.js.map +1 -1
- package/dist/components/library/data/chartDataProvider.d.ts +41 -3
- package/dist/components/library/data/filterUtils.d.ts +38 -9
- package/dist/components/library/data/filterUtils.js.map +1 -1
- package/dist/components/library/data/useDataSource.d.ts +6 -4
- package/dist/components/library/data/useDataSource.js.map +1 -1
- package/dist/components/library/data/usePageFilters.d.ts +31 -5
- package/dist/components/library/data/usePageFilters.js +6 -2
- package/dist/components/library/data/usePageFilters.js.map +1 -1
- package/dist/components/library/filters/FilterBar.d.ts +18 -8
- package/dist/components/library/filters/FilterBar.js +2 -3
- package/dist/components/library/filters/FilterBar.js.map +1 -1
- package/dist/components/library/filters/SearchFilter.d.ts +7 -6
- package/dist/components/library/filters/SearchFilter.js +2 -3
- package/dist/components/library/filters/SearchFilter.js.map +1 -1
- package/dist/components/library/filters/SelectFilter.d.ts +13 -7
- package/dist/components/library/filters/SelectFilter.js +2 -3
- package/dist/components/library/filters/SelectFilter.js.map +1 -1
- package/dist/components/library/filters/ToggleFilter.d.ts +7 -5
- package/dist/components/library/filters/ToggleFilter.js +2 -3
- package/dist/components/library/filters/ToggleFilter.js.map +1 -1
- package/dist/components/library/forms/FormField.d.ts +10 -8
- package/dist/components/library/forms/FormField.js +3 -4
- package/dist/components/library/forms/FormField.js.map +1 -1
- package/dist/components/library/forms/FormModal.d.ts +23 -14
- package/dist/components/library/forms/FormModal.js.map +1 -1
- package/dist/components/library/forms/FormRenderer.d.ts +29 -9
- package/dist/components/library/forms/FormRenderer.js +6 -7
- package/dist/components/library/forms/FormRenderer.js.map +1 -1
- package/dist/components/library/forms/FormSection.d.ts +10 -8
- package/dist/components/library/forms/FormSection.js +2 -3
- package/dist/components/library/forms/FormSection.js.map +1 -1
- package/dist/components/library/forms/index.d.ts +5 -0
- package/dist/components/library/forms/useFormState.d.ts +23 -15
- package/dist/components/library/forms/useFormState.js +53 -47
- package/dist/components/library/forms/useFormState.js.map +1 -1
- package/dist/components/library/index.d.ts +92 -73
- package/dist/components/library/index.js +25 -25
- package/dist/components/library/index.js.map +1 -1
- package/dist/components/library/layout/PageContainer.d.ts +6 -4
- package/dist/components/library/layout/PageContainer.js +4 -5
- package/dist/components/library/layout/PageContainer.js.map +1 -1
- package/dist/components/library/skeletons/CardSkeleton.d.ts +5 -4
- package/dist/components/library/skeletons/CardSkeleton.js +2 -3
- package/dist/components/library/skeletons/CardSkeleton.js.map +1 -1
- package/dist/components/library/theme/AppThemeProvider.d.ts +13 -50
- package/dist/components/library/theme/AppThemeProvider.js.map +1 -1
- package/dist/components/library/theme/tokens.d.ts +45 -44
- package/dist/components/library/theme/tokens.js.map +1 -1
- package/package.json +4 -1
- package/src/components/library/cards/{ActionList.jsx → ActionList.tsx} +13 -9
- package/src/components/library/cards/{ActivityCard.jsx → ActivityCard.tsx} +33 -4
- package/src/components/library/cards/{BaseCard.jsx → BaseCard.tsx} +33 -6
- package/src/components/library/cards/{CalloutCard.jsx → CalloutCard.tsx} +12 -10
- package/src/components/library/cards/{ChartCard.jsx → ChartCard.tsx} +32 -6
- package/src/components/library/cards/{FeedPanel.jsx → FeedPanel.tsx} +13 -2
- package/src/components/library/cards/{ListCard.jsx → ListCard.tsx} +43 -7
- package/src/components/library/cards/{MetricCard.jsx → MetricCard.tsx} +25 -6
- package/src/components/library/cards/{MetricsStrip.jsx → MetricsStrip.tsx} +22 -12
- package/src/components/library/cards/{SectionCard.jsx → SectionCard.tsx} +27 -8
- package/src/components/library/cards/{SemanticMetricCard.jsx → SemanticMetricCard.tsx} +18 -6
- package/src/components/library/cards/{SemanticMetricCardWithLoading.jsx → SemanticMetricCardWithLoading.tsx} +9 -3
- package/src/components/library/cards/{SemanticTableCard.jsx → SemanticTableCard.tsx} +16 -5
- package/src/components/library/cards/{SemanticTableCardWithLoading.jsx → SemanticTableCardWithLoading.tsx} +9 -5
- package/src/components/library/cards/{StatusCard.jsx → StatusCard.tsx} +61 -12
- package/src/components/library/cards/{TableCard.jsx → TableCard.tsx} +51 -12
- package/src/components/library/cards/{WidgetCard.jsx → WidgetCard.tsx} +28 -5
- package/src/components/library/charts/{D3Chart.jsx → D3Chart.tsx} +27 -7
- package/src/components/library/charts/{D3ChartTemplates.jsx → D3ChartTemplates.tsx} +60 -28
- package/src/components/library/charts/{GeoMap.jsx → GeoMap.tsx} +106 -17
- package/src/components/library/chat/{ChatBar.jsx → ChatBar.tsx} +19 -8
- package/src/components/library/chat/{ChatInput.jsx → ChatInput.tsx} +13 -11
- package/src/components/library/chat/{ChatMessage.jsx → ChatMessage.tsx} +22 -9
- package/src/components/library/chat/{ChatMessageList.jsx → ChatMessageList.tsx} +13 -11
- package/src/components/library/chat/{ChatPanel.jsx → ChatPanel.tsx} +16 -13
- package/src/components/library/chat/{ChatSuggestions.jsx → ChatSuggestions.tsx} +6 -5
- package/src/components/library/chat/{ChatToolCall.jsx → ChatToolCall.tsx} +14 -4
- package/src/components/library/chat/{ChatTypingIndicator.jsx → ChatTypingIndicator.tsx} +5 -2
- package/src/components/library/chat/{ChatWelcome.jsx → ChatWelcome.tsx} +9 -7
- package/src/components/library/chat/index.tsx +26 -0
- package/src/components/library/chat/useChatState.tsx +181 -0
- package/src/components/library/data/{DataModeProvider.jsx → DataModeProvider.tsx} +25 -8
- package/src/components/library/data/{DataModeToggle.jsx → DataModeToggle.tsx} +5 -2
- package/src/components/library/data/{chartDataProvider.jsx → chartDataProvider.tsx} +49 -5
- package/src/components/library/data/{filterUtils.jsx → filterUtils.tsx} +58 -12
- package/src/components/library/data/{useDataSource.jsx → useDataSource.tsx} +9 -2
- package/src/components/library/data/{usePageFilters.jsx → usePageFilters.tsx} +49 -9
- package/src/components/library/filters/{FilterBar.jsx → FilterBar.tsx} +21 -11
- package/src/components/library/filters/{SearchFilter.jsx → SearchFilter.tsx} +8 -2
- package/src/components/library/filters/{SelectFilter.jsx → SelectFilter.tsx} +15 -8
- package/src/components/library/filters/{ToggleFilter.jsx → ToggleFilter.tsx} +7 -6
- package/src/components/library/forms/{FormField.jsx → FormField.tsx} +91 -45
- package/src/components/library/forms/{FormModal.jsx → FormModal.tsx} +21 -20
- package/src/components/library/forms/{FormRenderer.jsx → FormRenderer.tsx} +32 -10
- package/src/components/library/forms/{FormSection.jsx → FormSection.tsx} +13 -7
- package/src/components/library/forms/index.tsx +11 -0
- package/src/components/library/forms/{useFormState.jsx → useFormState.tsx} +43 -23
- package/src/components/library/{index.jsx → index.ts} +14 -14
- package/src/components/library/layout/{PageContainer.jsx → PageContainer.tsx} +6 -3
- package/src/components/library/skeletons/{CardSkeleton.jsx → CardSkeleton.tsx} +5 -4
- package/src/components/library/theme/{AppThemeProvider.jsx → AppThemeProvider.tsx} +20 -7
- package/src/components/library/theme/{tokens.jsx → tokens.tsx} +37 -3
- package/src/components/library/chat/index.jsx +0 -10
- package/src/components/library/chat/useChatState.jsx +0 -130
- package/src/components/library/forms/index.jsx +0 -5
- /package/src/components/library/filters/{index.jsx → index.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataModeProvider.js","sources":["../../../../src/components/library/data/DataModeProvider.
|
|
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
|
|
5
|
-
function
|
|
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(
|
|
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
|
-
|
|
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.
|
|
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
|
|
2
|
-
export
|
|
3
|
-
export
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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.
|
|
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":"AA0DO,SAASA,EAAkBC,GAAWC,GAAeC,IAAiB,CAAA,GAAS;AACpF,MAAI,CAACD,KAAS,CAACA,EAAM,KAAA,EAAQ,QAAOD;AACpC,QAAMG,IAAIF,EAAM,KAAA,EAAO,YAAA;AACvB,SAAOD,EAAK;AAAA,IAAO,CAACI,MAClBF,EAAK,KAAK,CAACG,MAAQ;AACjB,YAAMC,IAAOF,IAAcC,CAAG;AAC9B,aAAOC,KAAO,QAAQ,OAAOA,CAAG,EAAE,YAAA,EAAc,SAASH,CAAC;AAAA,IAC5D,CAAC;AAAA,EAAA;AAEL;AAUO,SAASI,EAAiBP,GAAWK,GAAaG,GAAiB;AACxE,SAAIA,KAAS,QAAQA,MAAU,MAAMA,MAAU,QAAcR,IACtDA,EAAK,OAAO,CAACI,MAAQ;AAC1B,UAAMK,IAAKL,IAAcC,CAAG;AAC5B,WAAI,OAAOI,KAAM,YAAY,OAAOD,KAAU,WACrCC,EAAE,kBAAkBD,EAAM,YAAA,IAE5BC,MAAMD;AAAA,EACf,CAAC;AACH;AAWO,SAASE,EAAkBV,GAAWK,GAAaM,GAAmBC,GAAuB;AAClG,SAAKD,IACEX,EAAK,OAAO,CAACI,MAAQ;AAC1B,UAAMK,IAAKL,IAAcC,CAAG;AAC5B,WAAIO,MAAe,SAAkBH,MAAMG,IACpC,EAAQH;AAAA,EACjB,CAAC,IALqBT;AAMxB;AASO,SAASa,EAAqBb,GAAWK,GAAaS,GAA8B;AACzF,MAAI,CAACA,EAAO,QAAOd;AACnB,QAAMe,IAAQD,EAAM,QAAQ,IAAI,KAAKA,EAAM,KAAK,IAAI,MAC9CE,IAAMF,EAAM,MAAM,IAAI,KAAKA,EAAM,GAAG,IAAI;AAC9C,SAAI,CAACC,KAAS,CAACC,IAAYhB,IAEpBA,EAAK,OAAO,CAACI,MAAQ;AAC1B,UAAMa,IAAOb,IAAcC,CAAG;AAC9B,QAAIY,KAAO,KAAM,QAAO;AACxB,UAAMC,IAAID,aAAe,OAAOA,IAAM,IAAI,KAAKA,CAAG;AAGlD,WAFI,SAAO,MAAMC,EAAE,QAAA,CAAS,KACxBH,KAASG,IAAIH,KACbC,KAAOE,IAAIF;AAAA,EAEjB,CAAC;AACH;AASO,SAASG,EAAanB,GAAWK,GAAae,IAA2B,OAAY;AAC1F,MAAI,CAACf,EAAK,QAAOL;AACjB,QAAMqB,IAAMD,MAAc,SAAS,KAAK;AACxC,SAAO,CAAC,GAAGpB,CAAI,EAAE,KAAK,CAACsB,GAAGC,MAAM;AAC9B,UAAMC,IAAMF,IAAYjB,CAAG,GACrBoB,IAAMF,IAAYlB,CAAG;AAC3B,WAAImB,KAAM,QAAQC,KAAM,OAAa,IACjCD,KAAM,OAAa,KAAKH,IACxBI,KAAM,OAAa,IAAIJ,IACvB,OAAOG,KAAO,YAAY,OAAOC,KAAO,YAAkBD,IAAKC,KAAMJ,IAClE,OAAOG,CAAE,EAAE,cAAc,OAAOC,CAAE,CAAC,IAAIJ;AAAA,EAChD,CAAC;AACH;AAWO,SAASK,EAAgB1B,GAAW2B,IAA8B,CAAA,GAAIC,IAAuB,CAAA,GAAS;AAC3G,MAAIC,IAAS7B;AAEb,aAAW8B,KAAUH,GAAS;AAC5B,UAAMrB,IAAMsB,EAAOE,EAAO,EAAE;AAC5B,QAAyBxB,KAAQ;AAEjC,cAAQwB,EAAO,MAAA;AAAA,QACb,KAAK;AACH,UAAAD,IAAS9B,EAAe8B,GAAQvB,GAAKwB,EAAO,QAAQ,EAAE;AACtD;AAAA,QACF,KAAK;AACH,UAAAD,IAAStB,EAAcsB,GAAQC,EAAO,KAAKxB,CAAG;AAC9C;AAAA,QACF,KAAK;AACH,UAAAuB,IAASnB,EAAemB,GAAQC,EAAO,KAAKxB,GAAKwB,EAAO,UAAU;AAClE;AAAA,QACF,KAAK;AACH,UAAAD,IAAShB,EAAkBgB,GAAQC,EAAO,KAAKxB,CAAG;AAClD;AAAA,MAEA;AAAA,EAEN;AAEA,SAAOuB;AACT;"}
|
|
@@ -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.
|
|
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({
|
|
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.
|
|
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, }:
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
|
2
|
-
value?: string
|
|
3
|
-
onChange:
|
|
4
|
-
placeholder?: string
|
|
5
|
-
className?: string
|
|
6
|
-
}
|
|
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
|
|
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
|
-
|
|
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.
|
|
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, }:
|
|
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
|
|
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
|
-
|
|
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.
|
|
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, }:
|
|
10
|
+
export default function ToggleFilter({ value, onChange, label, className, }: ToggleFilterProps): import("react/jsx-runtime").JSX.Element;
|