@sentropic/dataviz-react 0.1.0 → 0.2.1

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 (61) hide show
  1. package/dist/adapter.d.ts +25 -0
  2. package/dist/adapter.d.ts.map +1 -0
  3. package/dist/adapter.js +18 -0
  4. package/dist/adapter.js.map +1 -0
  5. package/dist/index.d.ts +32 -22
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +21 -15
  8. package/dist/index.js.map +1 -1
  9. package/dist/lib/CrossfilteredBarChart.d.ts +35 -0
  10. package/dist/lib/CrossfilteredBarChart.d.ts.map +1 -0
  11. package/dist/lib/CrossfilteredBarChart.js +19 -0
  12. package/dist/lib/CrossfilteredBarChart.js.map +1 -0
  13. package/dist/lib/DashboardFilterBar.d.ts +16 -0
  14. package/dist/lib/DashboardFilterBar.d.ts.map +1 -0
  15. package/dist/lib/DashboardFilterBar.js +22 -0
  16. package/dist/lib/DashboardFilterBar.js.map +1 -0
  17. package/dist/lib/DrillBarChart.d.ts +26 -0
  18. package/dist/lib/DrillBarChart.d.ts.map +1 -0
  19. package/dist/lib/DrillBarChart.js +30 -0
  20. package/dist/lib/DrillBarChart.js.map +1 -0
  21. package/dist/lib/DrillBreadcrumb.d.ts +20 -0
  22. package/dist/lib/DrillBreadcrumb.d.ts.map +1 -0
  23. package/dist/lib/DrillBreadcrumb.js +25 -0
  24. package/dist/lib/DrillBreadcrumb.js.map +1 -0
  25. package/dist/lib/ExportMenu.d.ts +25 -0
  26. package/dist/lib/ExportMenu.d.ts.map +1 -0
  27. package/dist/lib/ExportMenu.js +44 -0
  28. package/dist/lib/ExportMenu.js.map +1 -0
  29. package/dist/lib/FieldPane.d.ts +13 -0
  30. package/dist/lib/FieldPane.d.ts.map +1 -0
  31. package/dist/lib/FieldPane.js +8 -0
  32. package/dist/lib/FieldPane.js.map +1 -0
  33. package/dist/lib/KpiCardGroup.d.ts +15 -0
  34. package/dist/lib/KpiCardGroup.d.ts.map +1 -0
  35. package/dist/lib/KpiCardGroup.js +15 -0
  36. package/dist/lib/KpiCardGroup.js.map +1 -0
  37. package/dist/lib/PivotDataTable.d.ts +14 -0
  38. package/dist/lib/PivotDataTable.d.ts.map +1 -0
  39. package/dist/lib/PivotDataTable.js +29 -0
  40. package/dist/lib/PivotDataTable.js.map +1 -0
  41. package/dist/lib/RecordsTable.d.ts +19 -0
  42. package/dist/lib/RecordsTable.d.ts.map +1 -0
  43. package/dist/lib/RecordsTable.js +28 -0
  44. package/dist/lib/RecordsTable.js.map +1 -0
  45. package/dist/lib/SelectionLegend.d.ts +16 -0
  46. package/dist/lib/SelectionLegend.d.ts.map +1 -0
  47. package/dist/lib/SelectionLegend.js +16 -0
  48. package/dist/lib/SelectionLegend.js.map +1 -0
  49. package/dist/lib/SmallMultiples.d.ts +28 -0
  50. package/dist/lib/SmallMultiples.d.ts.map +1 -0
  51. package/dist/lib/SmallMultiples.js +43 -0
  52. package/dist/lib/SmallMultiples.js.map +1 -0
  53. package/dist/lib/TopNFilter.d.ts +20 -0
  54. package/dist/lib/TopNFilter.d.ts.map +1 -0
  55. package/dist/lib/TopNFilter.js +28 -0
  56. package/dist/lib/TopNFilter.js.map +1 -0
  57. package/dist/lib/ValueSlicer.d.ts +17 -0
  58. package/dist/lib/ValueSlicer.d.ts.map +1 -0
  59. package/dist/lib/ValueSlicer.js +32 -0
  60. package/dist/lib/ValueSlicer.js.map +1 -0
  61. package/package.json +3 -3
@@ -0,0 +1,25 @@
1
+ /**
2
+ * React adapter for the framework-agnostic dataviz-core store. Exposes
3
+ * `useDashboard`, which subscribes a component to the store via React's
4
+ * `useSyncExternalStore` (concurrent-safe, SSR-safe). All presentation comes
5
+ * from `@sentropic/design-system-react`; this module only wires state.
6
+ */
7
+ import { type DashboardState, type DashboardStore } from '@sentropic/dataviz-core';
8
+ export * from '@sentropic/dataviz-core';
9
+ export type { ButtonProps } from '@sentropic/design-system-react';
10
+ export type { TenantTheme } from '@sentropic/design-system-themes';
11
+ /**
12
+ * Subscribe a React component to a dashboard store.
13
+ *
14
+ * Without a selector it returns the whole {@link DashboardState} snapshot.
15
+ * With a `selector` it returns a derived value; the component re-renders only
16
+ * when that derived value changes by `Object.is` (the standard
17
+ * `useSyncExternalStore` semantics). Because the core hands out a new frozen
18
+ * state object on every mutation, identity comparison is reliable.
19
+ *
20
+ * The same `subscribe` reference is used for the server snapshot, so this is
21
+ * SSR/hydration safe.
22
+ */
23
+ export declare function useDashboard(store: DashboardStore): DashboardState;
24
+ export declare function useDashboard<T>(store: DashboardStore, selector: (state: DashboardState) => T): T;
25
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGnF,cAAc,yBAAyB,CAAC;AAGxC,YAAY,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAClE,YAAY,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAEnE;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,cAAc,CAAC;AACpE,wBAAgB,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,CAAC,GAAG,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * React adapter for the framework-agnostic dataviz-core store. Exposes
3
+ * `useDashboard`, which subscribes a component to the store via React's
4
+ * `useSyncExternalStore` (concurrent-safe, SSR-safe). All presentation comes
5
+ * from `@sentropic/design-system-react`; this module only wires state.
6
+ */
7
+ import { useSyncExternalStore } from 'react';
8
+ import {} from '@sentropic/dataviz-core';
9
+ // Re-export the full core surface so consumers need a single import.
10
+ export * from '@sentropic/dataviz-core';
11
+ export function useDashboard(store, selector) {
12
+ const getSnapshot = () => {
13
+ const state = store.getState();
14
+ return selector ? selector(state) : state;
15
+ };
16
+ return useSyncExternalStore(store.subscribe, getSnapshot, getSnapshot);
17
+ }
18
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAA4C,MAAM,yBAAyB,CAAC;AAEnF,qEAAqE;AACrE,cAAc,yBAAyB,CAAC;AAoBxC,MAAM,UAAU,YAAY,CAC1B,KAAqB,EACrB,QAAuC;IAEvC,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC/B,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC5C,CAAC,CAAC;IACF,OAAO,oBAAoB,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;AACzE,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,27 +1,37 @@
1
1
  /**
2
2
  * @sentropic/dataviz-react
3
3
  *
4
- * React adapter for the framework-agnostic dataviz-core store. Exposes
5
- * `useDashboard`, which subscribes a component to the store via React's
6
- * `useSyncExternalStore` (concurrent-safe, SSR-safe). All presentation comes
7
- * from `@sentropic/design-system-react`; this package only wires state.
4
+ * React adapter + dashboard components for @sentropic/dataviz-core, built on
5
+ * @sentropic/design-system-react. The adapter wires the core's observable store
6
+ * onto React (`useSyncExternalStore`); the components compose design-system
7
+ * presentational pieces and bind them to the shared dashboard state. No
8
+ * presentation is authored here — it all comes from the design system.
8
9
  */
9
- import { type DashboardState, type DashboardStore } from '@sentropic/dataviz-core';
10
- export * from '@sentropic/dataviz-core';
11
- export type { ButtonProps } from '@sentropic/design-system-react';
12
- export type { TenantTheme } from '@sentropic/design-system-themes';
13
- /**
14
- * Subscribe a React component to a dashboard store.
15
- *
16
- * Without a selector it returns the whole {@link DashboardState} snapshot.
17
- * With a `selector` it returns a derived value; the component re-renders only
18
- * when that derived value changes by `Object.is` (the standard
19
- * `useSyncExternalStore` semantics). Because the core hands out a new frozen
20
- * state object on every mutation, identity comparison is reliable.
21
- *
22
- * The same `subscribe` reference is used for the server snapshot, so this is
23
- * SSR/hydration safe.
24
- */
25
- export declare function useDashboard(store: DashboardStore): DashboardState;
26
- export declare function useDashboard<T>(store: DashboardStore, selector: (state: DashboardState) => T): T;
10
+ export * from './adapter.js';
11
+ export { DashboardFilterBar } from './lib/DashboardFilterBar.js';
12
+ export type { DashboardFilterBarProps } from './lib/DashboardFilterBar.js';
13
+ export { SelectionLegend } from './lib/SelectionLegend.js';
14
+ export type { SelectionLegendProps } from './lib/SelectionLegend.js';
15
+ export { CrossfilteredBarChart } from './lib/CrossfilteredBarChart.js';
16
+ export type { CrossfilteredBarChartProps } from './lib/CrossfilteredBarChart.js';
17
+ export { SmallMultiples } from './lib/SmallMultiples.js';
18
+ export type { SmallMultiplesProps } from './lib/SmallMultiples.js';
19
+ export { FieldPane } from './lib/FieldPane.js';
20
+ export type { FieldPaneProps } from './lib/FieldPane.js';
21
+ export { PivotDataTable } from './lib/PivotDataTable.js';
22
+ export type { PivotDataTableProps } from './lib/PivotDataTable.js';
23
+ export { KpiCardGroup } from './lib/KpiCardGroup.js';
24
+ export type { KpiCardGroupProps } from './lib/KpiCardGroup.js';
25
+ export { RecordsTable } from './lib/RecordsTable.js';
26
+ export type { RecordsTableProps } from './lib/RecordsTable.js';
27
+ export { DrillBarChart } from './lib/DrillBarChart.js';
28
+ export type { DrillBarChartProps } from './lib/DrillBarChart.js';
29
+ export { DrillBreadcrumb } from './lib/DrillBreadcrumb.js';
30
+ export type { DrillBreadcrumbProps } from './lib/DrillBreadcrumb.js';
31
+ export { TopNFilter } from './lib/TopNFilter.js';
32
+ export type { TopNFilterProps } from './lib/TopNFilter.js';
33
+ export { ValueSlicer } from './lib/ValueSlicer.js';
34
+ export type { ValueSlicerProps } from './lib/ValueSlicer.js';
35
+ export { ExportMenu, rowsToCsv } from './lib/ExportMenu.js';
36
+ export type { ExportMenuProps } from './lib/ExportMenu.js';
27
37
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAGjC,cAAc,yBAAyB,CAAC;AAGxC,YAAY,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAClE,YAAY,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAEnE;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,cAAc,CAAC;AACpE,wBAAgB,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,CAAC,GAAG,CAAC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,cAAc,cAAc,CAAC;AAG7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,YAAY,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,YAAY,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC5D,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -1,20 +1,26 @@
1
1
  /**
2
2
  * @sentropic/dataviz-react
3
3
  *
4
- * React adapter for the framework-agnostic dataviz-core store. Exposes
5
- * `useDashboard`, which subscribes a component to the store via React's
6
- * `useSyncExternalStore` (concurrent-safe, SSR-safe). All presentation comes
7
- * from `@sentropic/design-system-react`; this package only wires state.
4
+ * React adapter + dashboard components for @sentropic/dataviz-core, built on
5
+ * @sentropic/design-system-react. The adapter wires the core's observable store
6
+ * onto React (`useSyncExternalStore`); the components compose design-system
7
+ * presentational pieces and bind them to the shared dashboard state. No
8
+ * presentation is authored here — it all comes from the design system.
8
9
  */
9
- import { useSyncExternalStore } from 'react';
10
- import {} from '@sentropic/dataviz-core';
11
- // Re-export the full core surface so consumers need a single import.
12
- export * from '@sentropic/dataviz-core';
13
- export function useDashboard(store, selector) {
14
- const getSnapshot = () => {
15
- const state = store.getState();
16
- return selector ? selector(state) : state;
17
- };
18
- return useSyncExternalStore(store.subscribe, getSnapshot, getSnapshot);
19
- }
10
+ // Adapter + full core surface re-export (incl. the core's `describeFilterSpec`).
11
+ export * from './adapter.js';
12
+ // Dashboard components (state consumers built on the design system).
13
+ export { DashboardFilterBar } from './lib/DashboardFilterBar.js';
14
+ export { SelectionLegend } from './lib/SelectionLegend.js';
15
+ export { CrossfilteredBarChart } from './lib/CrossfilteredBarChart.js';
16
+ export { SmallMultiples } from './lib/SmallMultiples.js';
17
+ export { FieldPane } from './lib/FieldPane.js';
18
+ export { PivotDataTable } from './lib/PivotDataTable.js';
19
+ export { KpiCardGroup } from './lib/KpiCardGroup.js';
20
+ export { RecordsTable } from './lib/RecordsTable.js';
21
+ export { DrillBarChart } from './lib/DrillBarChart.js';
22
+ export { DrillBreadcrumb } from './lib/DrillBreadcrumb.js';
23
+ export { TopNFilter } from './lib/TopNFilter.js';
24
+ export { ValueSlicer } from './lib/ValueSlicer.js';
25
+ export { ExportMenu, rowsToCsv } from './lib/ExportMenu.js';
20
26
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAGN,MAAM,yBAAyB,CAAC;AAEjC,qEAAqE;AACrE,cAAc,yBAAyB,CAAC;AAoBxC,MAAM,UAAU,YAAY,CAC1B,KAAqB,EACrB,QAAuC;IAEvC,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC/B,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC5C,CAAC,CAAC;IACF,OAAO,oBAAoB,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;AACzE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,iFAAiF;AACjF,cAAc,cAAc,CAAC;AAE7B,qEAAqE;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAEvE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { type BarChartTone } from '@sentropic/design-system-react';
2
+ import { type DashboardStore } from '@sentropic/dataviz-core';
3
+ export type CrossfilteredBarChartProps = {
4
+ /** The dashboard store to bind to. */
5
+ store: DashboardStore;
6
+ /** This chart's view id in the cross-filter graph. */
7
+ viewId: string;
8
+ /** Dimension id to group rows by (one bar per distinct value). */
9
+ dimension: string;
10
+ /** Measure id to aggregate into each bar's value. */
11
+ measure: string;
12
+ /** Accessible label of the chart (required by the design-system BarChart). */
13
+ label: string;
14
+ /** Bar colour tone from the design system. */
15
+ tone?: BarChartTone;
16
+ /**
17
+ * When true (default) clicking a bar toggles this view's selection (brushing
18
+ * input → `store.toggleSelection`); selected bars are highlighted. Set false
19
+ * for an output-only facet.
20
+ */
21
+ selectable?: boolean;
22
+ /** Fixed value-axis domain `[min, max]` for a shared scale across facets. */
23
+ domain?: [number, number];
24
+ orientation?: 'vertical' | 'horizontal';
25
+ width?: number;
26
+ height?: number;
27
+ className?: string;
28
+ };
29
+ /**
30
+ * A design-system `BarChart` whose data is the cross-filtered, aggregated view
31
+ * of the shared store. Clicking a bar brushes this view's selection (unless
32
+ * `selectable` is false), and the chart re-aggregates as the shared state moves.
33
+ */
34
+ export declare function CrossfilteredBarChart({ store, viewId, dimension, measure, label, tone, selectable, domain, orientation, width, height, className, }: CrossfilteredBarChartProps): import("react").JSX.Element;
35
+ //# sourceMappingURL=CrossfilteredBarChart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CrossfilteredBarChart.d.ts","sourceRoot":"","sources":["../../src/lib/CrossfilteredBarChart.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAGjC,MAAM,MAAM,0BAA0B,GAAG;IACvC,sCAAsC;IACtC,KAAK,EAAE,cAAc,CAAC;IACtB,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1B,WAAW,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,KAAK,EACL,MAAM,EACN,SAAS,EACT,OAAO,EACP,KAAK,EACL,IAAI,EACJ,UAAiB,EACjB,MAAM,EACN,WAAwB,EACxB,KAAK,EACL,MAAM,EACN,SAAS,GACV,EAAE,0BAA0B,+BAuB5B"}
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { BarChart, } from '@sentropic/design-system-react';
3
+ import { findDimension, findMeasure, groupAggregate, } from '@sentropic/dataviz-core';
4
+ import { useDashboard } from '../adapter.js';
5
+ /**
6
+ * A design-system `BarChart` whose data is the cross-filtered, aggregated view
7
+ * of the shared store. Clicking a bar brushes this view's selection (unless
8
+ * `selectable` is false), and the chart re-aggregates as the shared state moves.
9
+ */
10
+ export function CrossfilteredBarChart({ store, viewId, dimension, measure, label, tone, selectable = true, domain, orientation = 'vertical', width, height, className, }) {
11
+ const state = useDashboard(store);
12
+ const dim = findDimension(store.model, dimension);
13
+ const m = findMeasure(store.model, measure);
14
+ const data = dim && m
15
+ ? groupAggregate(store.applyCrossfilter(viewId), dimension, m).map(({ key, value }) => tone ? { label: key, value, tone } : { label: key, value })
16
+ : [];
17
+ return (_jsx(BarChart, { data: data, label: label, orientation: orientation, width: width, height: height, domain: domain, className: className, selectedKeys: selectable ? (state.selections[viewId] ?? []) : [], onSelect: selectable ? (key) => store.toggleSelection(viewId, key) : undefined }));
18
+ }
19
+ //# sourceMappingURL=CrossfilteredBarChart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CrossfilteredBarChart.js","sourceRoot":"","sources":["../../src/lib/CrossfilteredBarChart.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,QAAQ,GAGT,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,aAAa,EACb,WAAW,EACX,cAAc,GAEf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AA6B7C;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,EACpC,KAAK,EACL,MAAM,EACN,SAAS,EACT,OAAO,EACP,KAAK,EACL,IAAI,EACJ,UAAU,GAAG,IAAI,EACjB,MAAM,EACN,WAAW,GAAG,UAAU,EACxB,KAAK,EACL,MAAM,EACN,SAAS,GACkB;IAC3B,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAClD,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC5C,MAAM,IAAI,GACR,GAAG,IAAI,CAAC;QACN,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CAClF,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAC3D;QACH,CAAC,CAAC,EAAE,CAAC;IACT,OAAO,CACL,KAAC,QAAQ,IACP,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAChE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,GAC9E,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { type DashboardStore } from '@sentropic/dataviz-core';
2
+ export type DashboardFilterBarProps = {
3
+ /** The dashboard store to bind to. */
4
+ store: DashboardStore;
5
+ /** Aria-label of the filter group. */
6
+ label?: string;
7
+ /** Label of the "clear all" button (design-system default otherwise). */
8
+ clearAllLabel?: string;
9
+ className?: string;
10
+ };
11
+ /**
12
+ * Active filters rendered as design-system `FilterPill`s wired to the store.
13
+ * "Clear all" clears only the filters, leaving any selections intact.
14
+ */
15
+ export declare function DashboardFilterBar({ store, label, clearAllLabel, className, }: DashboardFilterBarProps): import("react").JSX.Element;
16
+ //# sourceMappingURL=DashboardFilterBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DashboardFilterBar.d.ts","sourceRoot":"","sources":["../../src/lib/DashboardFilterBar.tsx"],"names":[],"mappings":"AACA,OAAO,EAAqC,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGjG,MAAM,MAAM,uBAAuB,GAAG;IACpC,sCAAsC;IACtC,KAAK,EAAE,cAAc,CAAC;IACtB,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,KAAwB,EACxB,aAAa,EACb,SAAS,GACV,EAAE,uBAAuB,+BA6BzB"}
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { FilterBar, FilterPill } from '@sentropic/design-system-react';
3
+ import { describeFilterSpec, findDimension } from '@sentropic/dataviz-core';
4
+ import { useDashboard } from '../adapter.js';
5
+ /**
6
+ * Active filters rendered as design-system `FilterPill`s wired to the store.
7
+ * "Clear all" clears only the filters, leaving any selections intact.
8
+ */
9
+ export function DashboardFilterBar({ store, label = 'Filtres actifs', clearAllLabel, className, }) {
10
+ const state = useDashboard(store);
11
+ const entries = Object.entries(state.filters);
12
+ return (_jsx(FilterBar, { label: label, clearAllLabel: clearAllLabel, className: className, onClearAll: entries.length > 0
13
+ ? () => {
14
+ for (const id of Object.keys(store.getState().filters))
15
+ store.clearFilter(id);
16
+ }
17
+ : undefined, children: entries.map(([dimensionId, spec]) => {
18
+ const dimension = findDimension(store.model, dimensionId);
19
+ return (_jsx(FilterPill, { field: dimension?.label ?? dimensionId, value: describeFilterSpec(spec, dimension), onRemove: () => store.clearFilter(dimensionId) }, dimensionId));
20
+ }) }));
21
+ }
22
+ //# sourceMappingURL=DashboardFilterBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DashboardFilterBar.js","sourceRoot":"","sources":["../../src/lib/DashboardFilterBar.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAuB,MAAM,yBAAyB,CAAC;AACjG,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAY7C;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,EACjC,KAAK,EACL,KAAK,GAAG,gBAAgB,EACxB,aAAa,EACb,SAAS,GACe;IACxB,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9C,OAAO,CACL,KAAC,SAAS,IACR,KAAK,EAAE,KAAK,EACZ,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,SAAS,EACpB,UAAU,EACR,OAAO,CAAC,MAAM,GAAG,CAAC;YAChB,CAAC,CAAC,GAAG,EAAE;gBACH,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC;oBAAE,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YAChF,CAAC;YACH,CAAC,CAAC,SAAS,YAGd,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE;YACnC,MAAM,SAAS,GAAG,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YAC1D,OAAO,CACL,KAAC,UAAU,IAET,KAAK,EAAE,SAAS,EAAE,KAAK,IAAI,WAAW,EACtC,KAAK,EAAE,kBAAkB,CAAC,IAAI,EAAE,SAAS,CAAC,EAC1C,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,IAHzC,WAAW,CAIhB,CACH,CAAC;QACJ,CAAC,CAAC,GACQ,CACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { type BarChartTone } from '@sentropic/design-system-react';
2
+ import { type DashboardStore } from '@sentropic/dataviz-core';
3
+ export type DrillBarChartProps = {
4
+ /** The dashboard store to bind to. */
5
+ store: DashboardStore;
6
+ /** This view's id (drill state + cross-filter scope live under it). */
7
+ viewId: string;
8
+ /** Ordered dimension hierarchy; bars group by the current drill level. */
9
+ hierarchy: string[];
10
+ /** Measure id aggregated into each bar's value. */
11
+ measure: string;
12
+ /** Accessible label of the chart. */
13
+ label: string;
14
+ tone?: BarChartTone;
15
+ orientation?: 'vertical' | 'horizontal';
16
+ width?: number;
17
+ height?: number;
18
+ className?: string;
19
+ };
20
+ /**
21
+ * A bar chart that drills through a dimension hierarchy: clicking a bar filters
22
+ * the clicked value and pushes the next level as group-by. At the deepest level
23
+ * a click toggles this view's selection (brushing) instead.
24
+ */
25
+ export declare function DrillBarChart({ store, viewId, hierarchy, measure, label, tone, orientation, width, height, className, }: DrillBarChartProps): import("react").JSX.Element;
26
+ //# sourceMappingURL=DrillBarChart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DrillBarChart.d.ts","sourceRoot":"","sources":["../../src/lib/DrillBarChart.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAA+B,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAG3F,MAAM,MAAM,kBAAkB,GAAG;IAC/B,sCAAsC;IACtC,KAAK,EAAE,cAAc,CAAC;IACtB,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,WAAW,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,MAAM,EACN,SAAS,EACT,OAAO,EACP,KAAK,EACL,IAAI,EACJ,WAAwB,EACxB,KAAK,EACL,MAAM,EACN,SAAS,GACV,EAAE,kBAAkB,+BAgCpB"}
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { BarChart, } from '@sentropic/design-system-react';
3
+ import { findMeasure, groupAggregate } from '@sentropic/dataviz-core';
4
+ import { useDashboard } from '../adapter.js';
5
+ /**
6
+ * A bar chart that drills through a dimension hierarchy: clicking a bar filters
7
+ * the clicked value and pushes the next level as group-by. At the deepest level
8
+ * a click toggles this view's selection (brushing) instead.
9
+ */
10
+ export function DrillBarChart({ store, viewId, hierarchy, measure, label, tone, orientation = 'vertical', width, height, className, }) {
11
+ const state = useDashboard(store);
12
+ const level = Math.min((state.drill[viewId] ?? []).length, Math.max(hierarchy.length - 1, 0));
13
+ const currentDim = hierarchy[level];
14
+ const canDrill = level < hierarchy.length - 1;
15
+ const m = findMeasure(store.model, measure);
16
+ const data = m && currentDim
17
+ ? groupAggregate(store.applyCrossfilter(viewId), currentDim, m).map(({ key, value }) => tone ? { label: key, value, tone } : { label: key, value })
18
+ : [];
19
+ const onSelect = (key) => {
20
+ if (canDrill) {
21
+ store.setFilter(currentDim, { kind: 'include', values: [key] });
22
+ store.drillDown(viewId, hierarchy[level + 1]);
23
+ }
24
+ else {
25
+ store.toggleSelection(viewId, key);
26
+ }
27
+ };
28
+ return (_jsx(BarChart, { data: data, label: label, orientation: orientation, width: width, height: height, className: className, selectedKeys: canDrill ? [] : (state.selections[viewId] ?? []), onSelect: onSelect }));
29
+ }
30
+ //# sourceMappingURL=DrillBarChart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DrillBarChart.js","sourceRoot":"","sources":["../../src/lib/DrillBarChart.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,QAAQ,GAGT,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAuB,MAAM,yBAAyB,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAoB7C;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,KAAK,EACL,MAAM,EACN,SAAS,EACT,OAAO,EACP,KAAK,EACL,IAAI,EACJ,WAAW,GAAG,UAAU,EACxB,KAAK,EACL,MAAM,EACN,SAAS,GACU;IACnB,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9F,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;IAC9C,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC5C,MAAM,IAAI,GACR,CAAC,IAAI,UAAU;QACb,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CACnF,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAC3D;QACH,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,EAAE;QAC/B,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChE,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC;IACH,CAAC,CAAC;IACF,OAAO,CACL,KAAC,QAAQ,IACP,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAC9D,QAAQ,EAAE,QAAQ,GAClB,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { type DashboardStore } from '@sentropic/dataviz-core';
2
+ export type DrillBreadcrumbProps = {
3
+ /** The dashboard store to bind to. */
4
+ store: DashboardStore;
5
+ /** This view's id (must match the DrillBarChart it accompanies). */
6
+ viewId: string;
7
+ /** The same ordered dimension hierarchy used by the DrillBarChart. */
8
+ hierarchy: string[];
9
+ /** Aria-label of the breadcrumb trail. */
10
+ label?: string;
11
+ /** Label of the "go up one level" button. */
12
+ backLabel?: string;
13
+ className?: string;
14
+ };
15
+ /**
16
+ * Drill trail (design-system Breadcrumb) plus a "go up one level" button that
17
+ * pops the drill path and clears the value-filter applied at that level.
18
+ */
19
+ export declare function DrillBreadcrumb({ store, viewId, hierarchy, label, backLabel, className, }: DrillBreadcrumbProps): import("react").JSX.Element;
20
+ //# sourceMappingURL=DrillBreadcrumb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DrillBreadcrumb.d.ts","sourceRoot":"","sources":["../../src/lib/DrillBreadcrumb.tsx"],"names":[],"mappings":"AACA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAG7E,MAAM,MAAM,oBAAoB,GAAG;IACjC,sCAAsC;IACtC,KAAK,EAAE,cAAc,CAAC;IACtB,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAyB,EACzB,SAAsB,EACtB,SAAS,GACV,EAAE,oBAAoB,+BAuBtB"}
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Breadcrumb, Button, Inline } from '@sentropic/design-system-react';
3
+ import { findDimension } from '@sentropic/dataviz-core';
4
+ import { useDashboard } from '../adapter.js';
5
+ /**
6
+ * Drill trail (design-system Breadcrumb) plus a "go up one level" button that
7
+ * pops the drill path and clears the value-filter applied at that level.
8
+ */
9
+ export function DrillBreadcrumb({ store, viewId, hierarchy, label = 'Chemin de drill', backLabel = 'Remonter', className, }) {
10
+ const state = useDashboard(store);
11
+ const path = state.drill[viewId] ?? [];
12
+ const dimLabel = (id) => findDimension(store.model, id)?.label ?? id;
13
+ const items = hierarchy
14
+ .slice(0, path.length + 1)
15
+ .map((dim, i) => ({ label: dimLabel(dim), current: i === path.length }));
16
+ const back = () => {
17
+ const p = store.getState().drill[viewId] ?? [];
18
+ if (p.length === 0)
19
+ return;
20
+ store.drillUp(viewId);
21
+ store.clearFilter(hierarchy[p.length - 1]);
22
+ };
23
+ return (_jsxs(Inline, { gap: 2, className: className, children: [_jsx(Breadcrumb, { items: items, label: label }), path.length > 0 && (_jsx(Button, { variant: "ghost", onClick: back, children: backLabel }))] }));
24
+ }
25
+ //# sourceMappingURL=DrillBreadcrumb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DrillBreadcrumb.js","sourceRoot":"","sources":["../../src/lib/DrillBreadcrumb.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAuB,MAAM,yBAAyB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAgB7C;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,GAAG,iBAAiB,EACzB,SAAS,GAAG,UAAU,EACtB,SAAS,GACY;IACrB,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACvC,MAAM,QAAQ,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;IAC7E,MAAM,KAAK,GAAG,SAAS;SACpB,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SACzB,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC3E,MAAM,IAAI,GAAG,GAAG,EAAE;QAChB,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC/C,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC3B,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACtB,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC;IACF,OAAO,CACL,MAAC,MAAM,IAAC,GAAG,EAAE,CAAC,EAAE,SAAS,EAAE,SAAS,aAClC,KAAC,UAAU,IAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAI,EACzC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAClB,KAAC,MAAM,IAAC,OAAO,EAAC,OAAO,EAAC,OAAO,EAAE,IAAI,YAClC,SAAS,GACH,CACV,IACM,CACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { type DashboardStore, type Row } from '@sentropic/dataviz-core';
2
+ export type ExportMenuProps = {
3
+ /** The dashboard store to bind to. */
4
+ store: DashboardStore;
5
+ /** View whose cross-filtered rows are exported (omit for global filters). */
6
+ viewId?: string;
7
+ /** Field ids (and order) to export; defaults to all model fields. */
8
+ fields?: string[];
9
+ /** Downloaded file name. */
10
+ filename?: string;
11
+ /** Button label. */
12
+ label?: string;
13
+ className?: string;
14
+ };
15
+ /** Pure: rows + columns → a CSV string (RFC-4180-ish escaping). */
16
+ export declare function rowsToCsv(rows: readonly Row[], columns: {
17
+ key: string;
18
+ label: string;
19
+ }[]): string;
20
+ /**
21
+ * Exports the current cross-filtered rows of a view as a downloaded CSV, via a
22
+ * design-system Button. The CSV serialisation is pure and exported for testing.
23
+ */
24
+ export declare function ExportMenu({ store, viewId, fields, filename, label, className, }: ExportMenuProps): import("react").JSX.Element;
25
+ //# sourceMappingURL=ExportMenu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExportMenu.d.ts","sourceRoot":"","sources":["../../src/lib/ExportMenu.tsx"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,cAAc,EAAE,KAAK,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAErF,MAAM,MAAM,eAAe,GAAG;IAC5B,sCAAsC;IACtC,KAAK,EAAE,cAAc,CAAC;IACtB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAOF,mEAAmE;AACnE,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,EAAE,OAAO,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,MAAM,CAIjG;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,MAAM,EACN,MAAM,EACN,QAAuB,EACvB,KAAwB,EACxB,SAAS,GACV,EAAE,eAAe,+BA4BjB"}
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Button } from '@sentropic/design-system-react';
3
+ import { findMeasure } from '@sentropic/dataviz-core';
4
+ function escapeCsv(value) {
5
+ const s = value == null ? '' : String(value);
6
+ return /[",\n\r]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
7
+ }
8
+ /** Pure: rows + columns → a CSV string (RFC-4180-ish escaping). */
9
+ export function rowsToCsv(rows, columns) {
10
+ const header = columns.map((c) => escapeCsv(c.label)).join(',');
11
+ const body = rows.map((r) => columns.map((c) => escapeCsv(r[c.key] ?? '')).join(',')).join('\n');
12
+ return body ? `${header}\n${body}` : header;
13
+ }
14
+ /**
15
+ * Exports the current cross-filtered rows of a view as a downloaded CSV, via a
16
+ * design-system Button. The CSV serialisation is pure and exported for testing.
17
+ */
18
+ export function ExportMenu({ store, viewId, fields, filename = 'export.csv', label = 'Exporter (CSV)', className, }) {
19
+ const columns = () => {
20
+ const ids = fields ?? [
21
+ ...store.model.dimensions.map((d) => d.id),
22
+ ...store.model.measures.map((m) => m.id),
23
+ ];
24
+ return ids.map((id) => {
25
+ const dim = store.model.dimensions.find((d) => d.id === id);
26
+ const meas = findMeasure(store.model, id);
27
+ return { key: id, label: dim?.label ?? meas?.label ?? id };
28
+ });
29
+ };
30
+ const exportCsv = () => {
31
+ const csv = rowsToCsv(store.applyCrossfilter(viewId), columns());
32
+ if (typeof URL === 'undefined' || typeof URL.createObjectURL !== 'function')
33
+ return;
34
+ const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
35
+ const url = URL.createObjectURL(blob);
36
+ const a = document.createElement('a');
37
+ a.href = url;
38
+ a.download = filename;
39
+ a.click();
40
+ URL.revokeObjectURL(url);
41
+ };
42
+ return (_jsx(Button, { variant: "secondary", className: className, onClick: exportCsv, children: label }));
43
+ }
44
+ //# sourceMappingURL=ExportMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExportMenu.js","sourceRoot":"","sources":["../../src/lib/ExportMenu.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type TreeViewProps } from '@sentropic/design-system-react';
2
+ import { type DataModel, type FieldId } from '@sentropic/dataviz-core';
3
+ export type FieldPaneProps = Omit<TreeViewProps, 'nodes' | 'selectedId' | 'expandedIds' | 'defaultExpandedIds'> & {
4
+ model: DataModel;
5
+ includeDimensions?: boolean;
6
+ includeMeasures?: boolean;
7
+ selectedId?: FieldId | string;
8
+ expandedIds?: TreeViewProps['expandedIds'];
9
+ defaultExpandedIds?: TreeViewProps['defaultExpandedIds'];
10
+ label?: string;
11
+ };
12
+ export declare function FieldPane({ model, includeDimensions, includeMeasures, selectedId, expandedIds, defaultExpandedIds, label, ...rest }: FieldPaneProps): import("react").JSX.Element;
13
+ //# sourceMappingURL=FieldPane.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FieldPane.d.ts","sourceRoot":"","sources":["../../src/lib/FieldPane.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,OAAO,EACb,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,cAAc,GAAG,IAAI,CAC/B,aAAa,EACb,OAAO,GAAG,YAAY,GAAG,aAAa,GAAG,oBAAoB,CAC9D,GAAG;IACF,KAAK,EAAE,SAAS,CAAC;IACjB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC9B,WAAW,CAAC,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IAC3C,kBAAkB,CAAC,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,KAAgB,EAChB,GAAG,IAAI,EACR,EAAE,cAAc,+BAahB"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { TreeView, } from '@sentropic/design-system-react';
3
+ import { buildFieldPaneTree, } from '@sentropic/dataviz-core';
4
+ export function FieldPane({ model, includeDimensions, includeMeasures, selectedId, expandedIds, defaultExpandedIds, label = 'Fields', ...rest }) {
5
+ const tree = buildFieldPaneTree(model, { includeDimensions, includeMeasures });
6
+ return (_jsx(TreeView, { ...rest, nodes: tree.nodes, selectedId: selectedId, expandedIds: expandedIds, defaultExpandedIds: defaultExpandedIds ?? tree.defaultExpandedIds, "aria-label": rest['aria-label'] ?? label }));
7
+ }
8
+ //# sourceMappingURL=FieldPane.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FieldPane.js","sourceRoot":"","sources":["../../src/lib/FieldPane.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,QAAQ,GAET,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,kBAAkB,GAGnB,MAAM,yBAAyB,CAAC;AAejC,MAAM,UAAU,SAAS,CAAC,EACxB,KAAK,EACL,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,KAAK,GAAG,QAAQ,EAChB,GAAG,IAAI,EACQ;IACf,MAAM,IAAI,GAAG,kBAAkB,CAAC,KAAK,EAAE,EAAE,iBAAiB,EAAE,eAAe,EAAE,CAAC,CAAC;IAE/E,OAAO,CACL,KAAC,QAAQ,OACH,IAAI,EACR,KAAK,EAAE,IAAI,CAAC,KAAK,EACjB,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,WAAW,EACxB,kBAAkB,EAAE,kBAAkB,IAAI,IAAI,CAAC,kBAAkB,gBACrD,IAAI,CAAC,YAAY,CAAC,IAAI,KAAK,GACvC,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { type KpiCardDeltaFormat, type KpiCardFormat, type KpiCardSize, type KpiCardTone } from '@sentropic/design-system-react';
2
+ import { type DashboardStore, type KpiCardConfig, type Row } from '@sentropic/dataviz-core';
3
+ export type KpiCardGroupProps = {
4
+ store: DashboardStore;
5
+ viewId?: string;
6
+ configs: KpiCardConfig[];
7
+ comparisonData?: readonly Row[];
8
+ format?: KpiCardFormat;
9
+ deltaFormat?: KpiCardDeltaFormat;
10
+ size?: KpiCardSize;
11
+ tone?: KpiCardTone;
12
+ className?: string;
13
+ };
14
+ export declare function KpiCardGroup({ store, viewId, configs, comparisonData, format, deltaFormat, size, tone, className, }: KpiCardGroupProps): import("react").JSX.Element;
15
+ //# sourceMappingURL=KpiCardGroup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KpiCardGroup.d.ts","sourceRoot":"","sources":["../../src/lib/KpiCardGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,WAAW,EACjB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,GAAG,EACT,MAAM,yBAAyB,CAAC;AAGjC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,cAAc,CAAC,EAAE,SAAS,GAAG,EAAE,CAAC;IAChC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAMF,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,MAAM,EACN,OAAO,EACP,cAAc,EACd,MAAM,EACN,WAAuB,EACvB,IAAI,EACJ,IAAI,EACJ,SAAS,GACV,EAAE,iBAAiB,+BAuBnB"}
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { KpiCard, } from '@sentropic/design-system-react';
3
+ import { buildKpiCards, } from '@sentropic/dataviz-core';
4
+ import { useDashboard } from '../adapter.js';
5
+ function finite(value) {
6
+ return value === undefined || !Number.isFinite(value) ? undefined : value;
7
+ }
8
+ export function KpiCardGroup({ store, viewId, configs, comparisonData, format, deltaFormat = 'percent', size, tone, className, }) {
9
+ useDashboard(store);
10
+ const cards = buildKpiCards(store.model, store.applyCrossfilter(viewId), configs, {
11
+ comparisonData,
12
+ });
13
+ return (_jsx("div", { className: className, children: cards.map((card) => (_jsx(KpiCard, { value: card.value, label: card.label, delta: finite(deltaFormat === 'absolute' ? card.delta : card.deltaPercent), deltaFormat: deltaFormat, format: format, size: size, tone: tone, sparkline: card.sparkline?.map((point) => point.value) }, card.id))) }));
14
+ }
15
+ //# sourceMappingURL=KpiCardGroup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KpiCardGroup.js","sourceRoot":"","sources":["../../src/lib/KpiCardGroup.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,OAAO,GAKR,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,aAAa,GAId,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAc7C,SAAS,MAAM,CAAC,KAAyB;IACvC,OAAO,KAAK,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAC3B,KAAK,EACL,MAAM,EACN,OAAO,EACP,cAAc,EACd,MAAM,EACN,WAAW,GAAG,SAAS,EACvB,IAAI,EACJ,IAAI,EACJ,SAAS,GACS;IAClB,YAAY,CAAC,KAAK,CAAC,CAAC;IACpB,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE;QAChF,cAAc;KACf,CAAC,CAAC;IAEH,OAAO,CACL,cAAK,SAAS,EAAE,SAAS,YACtB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACnB,KAAC,OAAO,IAEN,KAAK,EAAE,IAAI,CAAC,KAAK,EACjB,KAAK,EAAE,IAAI,CAAC,KAAK,EACjB,KAAK,EAAE,MAAM,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,EAC1E,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IARjD,IAAI,CAAC,EAAE,CASZ,CACH,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { type DataTableProps } from '@sentropic/design-system-react';
2
+ import { type DashboardStore, type PivotConfig } from '@sentropic/dataviz-core';
3
+ export type PivotDataTableProps = {
4
+ store: DashboardStore;
5
+ viewId?: string;
6
+ rows: PivotConfig['rows'];
7
+ columns?: PivotConfig['columns'];
8
+ measures: PivotConfig['measures'];
9
+ caption?: DataTableProps['caption'];
10
+ size?: DataTableProps['size'];
11
+ className?: string;
12
+ };
13
+ export declare function PivotDataTable({ store, viewId, rows, columns, measures, caption, size, className, }: PivotDataTableProps): import("react").JSX.Element;
14
+ //# sourceMappingURL=PivotDataTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PivotDataTable.d.ts","sourceRoot":"","sources":["../../src/lib/PivotDataTable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,WAAW,EAEjB,MAAM,yBAAyB,CAAC;AAGjC,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1B,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACjC,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;IAClC,OAAO,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC;IACpC,IAAI,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAWF,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,MAAM,EACN,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,OAAO,EACP,IAAI,EACJ,SAAS,GACV,EAAE,mBAAmB,+BAuBrB"}
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { DataTable, } from '@sentropic/design-system-react';
3
+ import { buildPivotTable, } from '@sentropic/dataviz-core';
4
+ import { useDashboard } from '../adapter.js';
5
+ function toColumns(columns) {
6
+ return columns.map((column) => ({
7
+ key: column.key,
8
+ label: column.label,
9
+ sortable: true,
10
+ align: column.kind === 'value' ? 'end' : 'start',
11
+ }));
12
+ }
13
+ export function PivotDataTable({ store, viewId, rows, columns, measures, caption, size, className, }) {
14
+ useDashboard(store);
15
+ let table;
16
+ try {
17
+ const pivot = buildPivotTable(store.model, store.applyCrossfilter(viewId), {
18
+ rows,
19
+ columns,
20
+ measures,
21
+ });
22
+ table = { columns: toColumns(pivot.columns), rows: pivot.rows };
23
+ }
24
+ catch {
25
+ table = { columns: [], rows: [] };
26
+ }
27
+ return (_jsx(DataTable, { columns: table.columns, rows: table.rows, caption: caption, size: size, className: className }));
28
+ }
29
+ //# sourceMappingURL=PivotDataTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PivotDataTable.js","sourceRoot":"","sources":["../../src/lib/PivotDataTable.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,SAAS,GAIV,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,eAAe,GAIhB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAa7C,SAAS,SAAS,CAAC,OAAsD;IACvE,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC9B,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO;KACjD,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAC7B,KAAK,EACL,MAAM,EACN,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,OAAO,EACP,IAAI,EACJ,SAAS,GACW;IACpB,YAAY,CAAC,KAAK,CAAC,CAAC;IACpB,IAAI,KAA2D,CAAC;IAChE,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE;YACzE,IAAI;YACJ,OAAO;YACP,QAAQ;SACT,CAAC,CAAC;QACH,KAAK,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAuB,EAAE,CAAC;IACrF,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IACpC,CAAC;IAED,OAAO,CACL,KAAC,SAAS,IACR,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,SAAS,GACpB,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { type DashboardStore } from '@sentropic/dataviz-core';
2
+ export type RecordsTableProps = {
3
+ /** The dashboard store to bind to. */
4
+ store: DashboardStore;
5
+ /** This view's id in the cross-filter graph (rows shown are its visible rows). */
6
+ viewId?: string;
7
+ /** Field ids (and order) to show as columns; defaults to all model fields. */
8
+ fields?: string[];
9
+ caption?: string;
10
+ size?: 'sm' | 'md' | 'lg';
11
+ pageSize?: number;
12
+ className?: string;
13
+ };
14
+ /**
15
+ * The underlying ("show records") rows for a view — the cross-filtered data
16
+ * rendered as a design-system DataTable. Columns come from the data model.
17
+ */
18
+ export declare function RecordsTable({ store, viewId, fields, caption, size, pageSize, className, }: RecordsTableProps): import("react").JSX.Element;
19
+ //# sourceMappingURL=RecordsTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecordsTable.d.ts","sourceRoot":"","sources":["../../src/lib/RecordsTable.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAG3E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,sCAAsC;IACtC,KAAK,EAAE,cAAc,CAAC;IACtB,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,MAAM,EACN,MAAM,EACN,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,SAAS,GACV,EAAE,iBAAiB,+BA2BnB"}
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { DataTable, } from '@sentropic/design-system-react';
3
+ import { findMeasure } from '@sentropic/dataviz-core';
4
+ import { useDashboard } from '../adapter.js';
5
+ /**
6
+ * The underlying ("show records") rows for a view — the cross-filtered data
7
+ * rendered as a design-system DataTable. Columns come from the data model.
8
+ */
9
+ export function RecordsTable({ store, viewId, fields, caption, size, pageSize, className, }) {
10
+ useDashboard(store);
11
+ const ids = fields ?? [
12
+ ...store.model.dimensions.map((d) => d.id),
13
+ ...store.model.measures.map((m) => m.id),
14
+ ];
15
+ const columns = ids.map((id) => {
16
+ const dim = store.model.dimensions.find((d) => d.id === id);
17
+ const meas = findMeasure(store.model, id);
18
+ return {
19
+ key: id,
20
+ label: dim?.label ?? meas?.label ?? id,
21
+ sortable: true,
22
+ align: meas ? 'end' : 'start',
23
+ };
24
+ });
25
+ const rows = store.applyCrossfilter(viewId).map((row, i) => ({ ...row, id: String(i) }));
26
+ return (_jsx(DataTable, { columns: columns, rows: rows, caption: caption, size: size, pageSize: pageSize, className: className }));
27
+ }
28
+ //# sourceMappingURL=RecordsTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecordsTable.js","sourceRoot":"","sources":["../../src/lib/RecordsTable.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,SAAS,GAGV,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,WAAW,EAAuB,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAe7C;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,EAC3B,KAAK,EACL,MAAM,EACN,MAAM,EACN,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,SAAS,GACS;IAClB,YAAY,CAAC,KAAK,CAAC,CAAC;IACpB,MAAM,GAAG,GAAG,MAAM,IAAI;QACpB,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1C,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACzC,CAAC;IACF,MAAM,OAAO,GAAsB,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;QAChD,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5D,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC1C,OAAO;YACL,GAAG,EAAE,EAAE;YACP,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,EAAE;YACtC,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO;SAC9B,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,MAAM,IAAI,GAAmB,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzG,OAAO,CACL,KAAC,SAAS,IACR,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,GACpB,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { type DashboardStore } from '@sentropic/dataviz-core';
2
+ export type SelectionLegendProps = {
3
+ /** The dashboard store to bind to. */
4
+ store: DashboardStore;
5
+ /** Map of viewId -> human label for the legend chips (falls back to the id). */
6
+ labels?: Record<string, string>;
7
+ /** Aria-label of the legend group. */
8
+ label?: string;
9
+ className?: string;
10
+ };
11
+ /**
12
+ * Per-view selections rendered as design-system `SelectionChip`s. Renders
13
+ * nothing while there is no active selection.
14
+ */
15
+ export declare function SelectionLegend({ store, labels, label, className, }: SelectionLegendProps): import("react").JSX.Element | null;
16
+ //# sourceMappingURL=SelectionLegend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectionLegend.d.ts","sourceRoot":"","sources":["../../src/lib/SelectionLegend.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAG9D,MAAM,MAAM,oBAAoB,GAAG;IACjC,sCAAsC;IACtC,KAAK,EAAE,cAAc,CAAC;IACtB,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,MAAW,EACX,KAA4B,EAC5B,SAAS,GACV,EAAE,oBAAoB,sCAgBtB"}
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Inline, SelectionChip } from '@sentropic/design-system-react';
3
+ import {} from '@sentropic/dataviz-core';
4
+ import { useDashboard } from '../adapter.js';
5
+ /**
6
+ * Per-view selections rendered as design-system `SelectionChip`s. Renders
7
+ * nothing while there is no active selection.
8
+ */
9
+ export function SelectionLegend({ store, labels = {}, label = 'Sélections actives', className, }) {
10
+ const state = useDashboard(store);
11
+ const entries = Object.entries(state.selections).filter(([, keys]) => keys.length > 0);
12
+ if (entries.length === 0)
13
+ return null;
14
+ return (_jsx(Inline, { role: "group", "aria-label": label, gap: 2, wrap: true, className: className, children: entries.map(([viewId, keys]) => (_jsx(SelectionChip, { label: labels[viewId] ?? viewId, count: keys.length, onClear: () => store.clearSelection(viewId) }, viewId))) }));
15
+ }
16
+ //# sourceMappingURL=SelectionLegend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectionLegend.js","sourceRoot":"","sources":["../../src/lib/SelectionLegend.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAuB,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAY7C;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,KAAK,EACL,MAAM,GAAG,EAAE,EACX,KAAK,GAAG,oBAAoB,EAC5B,SAAS,GACY;IACrB,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,OAAO,CACL,KAAC,MAAM,IAAC,IAAI,EAAC,OAAO,gBAAa,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,QAAC,SAAS,EAAE,SAAS,YACtE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAC/B,KAAC,aAAa,IAEZ,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,EAC/B,KAAK,EAAE,IAAI,CAAC,MAAM,EAClB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,IAHtC,MAAM,CAIX,CACH,CAAC,GACK,CACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { type BarChartTone } from '@sentropic/design-system-react';
2
+ import { type DashboardStore } from '@sentropic/dataviz-core';
3
+ export type SmallMultiplesProps = {
4
+ /** The dashboard store to bind to. */
5
+ store: DashboardStore;
6
+ /** This view's id in the cross-filter graph. */
7
+ viewId: string;
8
+ /** Dimension whose distinct values each produce one facet (panel). */
9
+ facetBy: string;
10
+ /** Dimension to group rows by inside each facet (bar categories). */
11
+ dimension: string;
12
+ /** Measure id aggregated into each bar's value. */
13
+ measure: string;
14
+ /** Accessible label; each facet chart is "<label> — <facet key>". */
15
+ label: string;
16
+ /** Number of grid columns (design-system Grid). Defaults to 2. */
17
+ columns?: number;
18
+ /** Bar colour tone from the design system. */
19
+ tone?: BarChartTone;
20
+ className?: string;
21
+ };
22
+ /**
23
+ * Faceting / trellis: one design-system `BarChart` per distinct `facetBy`
24
+ * value, laid out in a `Grid`, all sharing a single value `domain` so the
25
+ * facets are visually comparable.
26
+ */
27
+ export declare function SmallMultiples({ store, viewId, facetBy, dimension, measure, label, columns, tone, className, }: SmallMultiplesProps): import("react").JSX.Element;
28
+ //# sourceMappingURL=SmallMultiples.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SmallMultiples.d.ts","sourceRoot":"","sources":["../../src/lib/SmallMultiples.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAGjC,MAAM,MAAM,mBAAmB,GAAG;IAChC,sCAAsC;IACtC,KAAK,EAAE,cAAc,CAAC;IACtB,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAIF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,MAAM,EACN,OAAO,EACP,SAAS,EACT,OAAO,EACP,KAAK,EACL,OAAW,EACX,IAAI,EACJ,SAAS,GACV,EAAE,mBAAmB,+BAoCrB"}
@@ -0,0 +1,43 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Grid, BarChart, } from '@sentropic/design-system-react';
3
+ import { findDimension, findMeasure, groupAggregate, } from '@sentropic/dataviz-core';
4
+ import { useDashboard } from '../adapter.js';
5
+ const keyOf = (v) => (v == null ? 'null' : String(v));
6
+ /**
7
+ * Faceting / trellis: one design-system `BarChart` per distinct `facetBy`
8
+ * value, laid out in a `Grid`, all sharing a single value `domain` so the
9
+ * facets are visually comparable.
10
+ */
11
+ export function SmallMultiples({ store, viewId, facetBy, dimension, measure, label, columns = 2, tone, className, }) {
12
+ useDashboard(store);
13
+ const fdim = findDimension(store.model, facetBy);
14
+ const dim = findDimension(store.model, dimension);
15
+ const m = findMeasure(store.model, measure);
16
+ let panels = [];
17
+ let domain;
18
+ if (fdim && dim && m) {
19
+ const rows = store.applyCrossfilter(viewId);
20
+ const keys = [];
21
+ const seen = new Set();
22
+ for (const row of rows) {
23
+ const k = keyOf(row[facetBy]);
24
+ if (!seen.has(k)) {
25
+ seen.add(k);
26
+ keys.push(k);
27
+ }
28
+ }
29
+ let max = 0;
30
+ panels = keys.map((k) => {
31
+ const facetRows = rows.filter((row) => keyOf(row[facetBy]) === k);
32
+ const data = groupAggregate(facetRows, dimension, m).map(({ key: barKey, value }) => {
33
+ if (value > max)
34
+ max = value;
35
+ return tone ? { label: barKey, value, tone } : { label: barKey, value };
36
+ });
37
+ return { key: k, data };
38
+ });
39
+ domain = panels.length ? [0, max] : undefined;
40
+ }
41
+ return (_jsx(Grid, { columns: columns, gap: 4, className: className, role: "group", "aria-label": label, children: panels.map((panel) => (_jsx(BarChart, { data: panel.data, label: `${label} — ${panel.key}`, domain: domain }, panel.key))) }));
42
+ }
43
+ //# sourceMappingURL=SmallMultiples.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SmallMultiples.js","sourceRoot":"","sources":["../../src/lib/SmallMultiples.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { type DashboardStore } from '@sentropic/dataviz-core';
2
+ export type TopNFilterProps = {
3
+ /** The dashboard store to bind to. */
4
+ store: DashboardStore;
5
+ /** Dimension to restrict to its top-N values. */
6
+ dimension: string;
7
+ /** Measure used to rank the dimension's values (descending). */
8
+ measure: string;
9
+ /** Initial N. Defaults to 5. */
10
+ defaultN?: number;
11
+ /** Field label of the number input. */
12
+ label?: string;
13
+ className?: string;
14
+ };
15
+ /**
16
+ * Restricts a dimension to its top-N values by a measure (ranked over the full
17
+ * dataset), via a design-system NumberInput. Applies on mount and on change.
18
+ */
19
+ export declare function TopNFilter({ store, dimension, measure, defaultN, label, className, }: TopNFilterProps): import("react").JSX.Element;
20
+ //# sourceMappingURL=TopNFilter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TopNFilter.d.ts","sourceRoot":"","sources":["../../src/lib/TopNFilter.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA+B,KAAK,cAAc,EAAY,MAAM,yBAAyB,CAAC;AAErG,MAAM,MAAM,eAAe,GAAG;IAC5B,sCAAsC;IACtC,KAAK,EAAE,cAAc,CAAC;IACtB,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,SAAS,EACT,OAAO,EACP,QAAY,EACZ,KAAe,EACf,SAAS,GACV,EAAE,eAAe,+BAyBjB"}
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { NumberInput } from '@sentropic/design-system-react';
4
+ import { findMeasure, groupAggregate } from '@sentropic/dataviz-core';
5
+ /**
6
+ * Restricts a dimension to its top-N values by a measure (ranked over the full
7
+ * dataset), via a design-system NumberInput. Applies on mount and on change.
8
+ */
9
+ export function TopNFilter({ store, dimension, measure, defaultN = 5, label = 'Top N', className, }) {
10
+ const [n, setN] = useState(defaultN);
11
+ useEffect(() => {
12
+ const m = findMeasure(store.model, measure);
13
+ if (!m || !Number.isFinite(n) || n < 1)
14
+ return;
15
+ const ranked = groupAggregate([...store.data], dimension, m)
16
+ .slice()
17
+ .sort((a, b) => b.value - a.value)
18
+ .slice(0, n)
19
+ .map((r) => r.key);
20
+ store.setFilter(dimension, { kind: 'include', values: ranked });
21
+ }, [store, dimension, measure, n]);
22
+ return (_jsx(NumberInput, { label: label, value: n, min: 1, step: 1, className: className, onChange: (e) => {
23
+ const v = Number(e.target.value);
24
+ if (Number.isFinite(v))
25
+ setN(v);
26
+ } }));
27
+ }
28
+ //# sourceMappingURL=TopNFilter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TopNFilter.js","sourceRoot":"","sources":["../../src/lib/TopNFilter.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAiC,MAAM,yBAAyB,CAAC;AAgBrG;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,EACzB,KAAK,EACL,SAAS,EACT,OAAO,EACP,QAAQ,GAAG,CAAC,EACZ,KAAK,GAAG,OAAO,EACf,SAAS,GACO;IAChB,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACrC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC5C,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO;QAC/C,MAAM,MAAM,GAAG,cAAc,CAAC,CAAC,GAAI,KAAK,CAAC,IAAuB,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;aAC7E,KAAK,EAAE;aACP,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;aACjC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACrB,KAAK,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAClE,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IACnC,OAAO,CACL,KAAC,WAAW,IACV,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,CAAC,EACR,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,CAAC,EACP,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;YACd,MAAM,CAAC,GAAG,MAAM,CAAE,CAAC,CAAC,MAA2B,CAAC,KAAK,CAAC,CAAC;YACvD,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC,GACD,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { type DashboardStore } from '@sentropic/dataviz-core';
2
+ export type ValueSlicerProps = {
3
+ /** The dashboard store to bind to. */
4
+ store: DashboardStore;
5
+ /** Dimension whose distinct values become the slicer's checkboxes. */
6
+ dimension: string;
7
+ /** Legend; defaults to the dimension label. */
8
+ legend?: string;
9
+ orientation?: 'vertical' | 'horizontal';
10
+ className?: string;
11
+ };
12
+ /**
13
+ * A checkbox slicer over a dimension's distinct values: checked values become an
14
+ * `include` filter (an OR within the dimension). Design-system CheckboxGroup.
15
+ */
16
+ export declare function ValueSlicer({ store, dimension, legend, orientation, className, }: ValueSlicerProps): import("react").JSX.Element;
17
+ //# sourceMappingURL=ValueSlicer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValueSlicer.d.ts","sourceRoot":"","sources":["../../src/lib/ValueSlicer.tsx"],"names":[],"mappings":"AACA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAG7E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,sCAAsC;IACtC,KAAK,EAAE,cAAc,CAAC;IACtB,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAIF;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,SAAS,EACT,MAAM,EACN,WAAwB,EACxB,SAAS,GACV,EAAE,gBAAgB,+BA4BlB"}
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { CheckboxGroup } from '@sentropic/design-system-react';
3
+ import { findDimension } from '@sentropic/dataviz-core';
4
+ import { useDashboard } from '../adapter.js';
5
+ const keyOf = (v) => (v == null ? 'null' : String(v));
6
+ /**
7
+ * A checkbox slicer over a dimension's distinct values: checked values become an
8
+ * `include` filter (an OR within the dimension). Design-system CheckboxGroup.
9
+ */
10
+ export function ValueSlicer({ store, dimension, legend, orientation = 'vertical', className, }) {
11
+ const state = useDashboard(store);
12
+ const resolvedLegend = legend ?? findDimension(store.model, dimension)?.label ?? dimension;
13
+ const seen = new Set();
14
+ const options = [];
15
+ for (const row of store.data) {
16
+ const k = keyOf(row[dimension]);
17
+ if (!seen.has(k)) {
18
+ seen.add(k);
19
+ options.push({ label: k, value: k });
20
+ }
21
+ }
22
+ const f = state.filters[dimension];
23
+ const value = f && f.kind === 'include' ? [...f.values] : [];
24
+ const onChange = (values) => {
25
+ if (values.length)
26
+ store.setFilter(dimension, { kind: 'include', values });
27
+ else
28
+ store.clearFilter(dimension);
29
+ };
30
+ return (_jsx(CheckboxGroup, { legend: resolvedLegend, options: options, value: value, orientation: orientation, className: className, onChange: onChange }));
31
+ }
32
+ //# sourceMappingURL=ValueSlicer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValueSlicer.js","sourceRoot":"","sources":["../../src/lib/ValueSlicer.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAA4B,MAAM,gCAAgC,CAAC;AACzF,OAAO,EAAE,aAAa,EAAuB,MAAM,yBAAyB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAa7C,MAAM,KAAK,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAE/D;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,EAC1B,KAAK,EACL,SAAS,EACT,MAAM,EACN,WAAW,GAAG,UAAU,EACxB,SAAS,GACQ;IACjB,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,cAAc,GAAG,MAAM,IAAI,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,IAAI,SAAS,CAAC;IAC3F,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,OAAO,GAA0B,EAAE,CAAC;IAC1C,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACjB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IACD,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7D,MAAM,QAAQ,GAAG,CAAC,MAAgB,EAAE,EAAE;QACpC,IAAI,MAAM,CAAC,MAAM;YAAE,KAAK,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;;YACtE,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC,CAAC;IACF,OAAO,CACL,KAAC,aAAa,IACZ,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,GAClB,CACH,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentropic/dataviz-react",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "React adapter for @sentropic/dataviz-core, built on @sentropic/design-system-react.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -27,8 +27,8 @@
27
27
  "test": "vitest run"
28
28
  },
29
29
  "dependencies": {
30
- "@sentropic/dataviz-core": "0.1.0",
31
- "@sentropic/design-system-react": "0.16.0",
30
+ "@sentropic/dataviz-core": "0.2.1",
31
+ "@sentropic/design-system-react": "0.18.0",
32
32
  "@sentropic/design-system-themes": "0.11.0"
33
33
  },
34
34
  "peerDependencies": {