@rio-cloud/rio-uikit 1.10.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/.DS_Store +0 -0
  2. package/components/assetTree/AssetTree.js +1 -1
  3. package/components/assetTree/Tree.d.ts +6 -0
  4. package/components/assetTree/Tree.js +2 -2
  5. package/components/assetTree/TreeNode.d.ts +1 -0
  6. package/components/assetTree/TreeNode.js +3 -2
  7. package/components/dialog/SplitDialog.d.ts +6 -0
  8. package/components/dialog/SplitDialog.js +2 -2
  9. package/components/filepicker/FilePicker.d.ts +1 -1
  10. package/components/formLabel/FormLabel.js +1 -1
  11. package/components/map/components/Map.js +70 -68
  12. package/components/map/components/features/settings/builtinSettings/MapTypeSettings.d.ts +1 -1
  13. package/components/map/utils/rendering.d.ts +1 -1
  14. package/components/map/utils/rendering.js +7 -11
  15. package/hooks/useAverage.d.ts +18 -0
  16. package/hooks/useAverage.js +28 -0
  17. package/hooks/useCount.d.ts +22 -0
  18. package/hooks/useCount.js +31 -0
  19. package/hooks/useMax.d.ts +18 -0
  20. package/hooks/useMax.js +24 -0
  21. package/hooks/useMin.d.ts +18 -0
  22. package/hooks/useMin.js +24 -0
  23. package/hooks/useSum.d.ts +18 -0
  24. package/hooks/useSum.js +23 -0
  25. package/lib/es/components/assetTree/AssetTree.js +1 -1
  26. package/lib/es/components/assetTree/Tree.d.ts +6 -0
  27. package/lib/es/components/assetTree/Tree.js +2 -2
  28. package/lib/es/components/assetTree/TreeNode.d.ts +1 -0
  29. package/lib/es/components/assetTree/TreeNode.js +3 -2
  30. package/lib/es/components/dialog/SplitDialog.d.ts +6 -0
  31. package/lib/es/components/dialog/SplitDialog.js +2 -2
  32. package/lib/es/components/filepicker/FilePicker.d.ts +1 -1
  33. package/lib/es/components/formLabel/FormLabel.js +1 -1
  34. package/lib/es/components/map/components/Map.js +70 -68
  35. package/lib/es/components/map/components/features/settings/builtinSettings/MapTypeSettings.d.ts +1 -1
  36. package/lib/es/components/map/utils/rendering.d.ts +1 -1
  37. package/lib/es/components/map/utils/rendering.js +7 -11
  38. package/lib/es/hooks/useAverage.d.ts +18 -0
  39. package/lib/es/hooks/useAverage.js +30 -0
  40. package/lib/es/hooks/useCount.d.ts +22 -0
  41. package/lib/es/hooks/useCount.js +33 -0
  42. package/lib/es/hooks/useMax.d.ts +18 -0
  43. package/lib/es/hooks/useMax.js +26 -0
  44. package/lib/es/hooks/useMin.d.ts +18 -0
  45. package/lib/es/hooks/useMin.js +26 -0
  46. package/lib/es/hooks/useSum.d.ts +18 -0
  47. package/lib/es/hooks/useSum.js +25 -0
  48. package/lib/es/useAverage.d.ts +2 -0
  49. package/lib/es/useAverage.js +7 -0
  50. package/lib/es/useCount.d.ts +2 -0
  51. package/lib/es/useCount.js +7 -0
  52. package/lib/es/useMax.d.ts +2 -0
  53. package/lib/es/useMax.js +7 -0
  54. package/lib/es/useMin.d.ts +2 -0
  55. package/lib/es/useMin.js +7 -0
  56. package/lib/es/useSum.d.ts +2 -0
  57. package/lib/es/useSum.js +7 -0
  58. package/lib/es/utils/formatUtils.d.ts +16 -0
  59. package/lib/es/utils/formatUtils.js +55 -0
  60. package/lib/es/version.json +1 -1
  61. package/package.json +6 -6
  62. package/useAverage.d.ts +2 -0
  63. package/useAverage.js +2 -0
  64. package/useCount.d.ts +2 -0
  65. package/useCount.js +2 -0
  66. package/useMax.d.ts +2 -0
  67. package/useMax.js +2 -0
  68. package/useMin.d.ts +2 -0
  69. package/useMin.js +2 -0
  70. package/useSum.d.ts +2 -0
  71. package/useSum.js +2 -0
  72. package/utils/formatUtils.d.ts +16 -0
  73. package/utils/formatUtils.js +49 -0
  74. package/version.json +1 -1
@@ -4,6 +4,7 @@ export type TreeNodeProps = {
4
4
  node: GroupedItem;
5
5
  hasMultiselect?: boolean;
6
6
  isSelected?: boolean;
7
+ isOpen?: boolean;
7
8
  isIndeterminate?: boolean;
8
9
  onToggleNode: (nodeId: string) => void;
9
10
  onSelect: (node: GroupedItem, isIndeterminate: boolean) => void;
@@ -13,10 +13,11 @@ const withRioglyphPrefix = (name) => {
13
13
  return name.startsWith('rioglyph-') ? name : `rioglyph-${name}`;
14
14
  };
15
15
  const TreeNode = react_1.default.memo((props) => {
16
- const { node, hasMultiselect = false, isSelected = false, isIndeterminate = false, onToggleNode, onSelect } = props;
16
+ const { node, hasMultiselect = false, isSelected = false, isOpen = false, isIndeterminate = false, onToggleNode, onSelect, } = props;
17
17
  const treeNodeClassNames = (0, classnames_1.default)('TreeNode', 'from-group', isSelected && 'checked', node.className && node.className);
18
18
  const hasChildren = !!node.items.length;
19
- const iconName = withRioglyphPrefix(node.icon);
19
+ const expandedIcon = node.expandedIcon || node.icon;
20
+ const iconName = isOpen ? withRioglyphPrefix(expandedIcon) : withRioglyphPrefix(node.icon);
20
21
  return ((0, jsx_runtime_1.jsxs)("div", { className: treeNodeClassNames, "data-key": node.id, onClick: () => hasChildren && onToggleNode(node.id), children: [hasMultiselect && ((0, jsx_runtime_1.jsx)(Checkbox_1.default, { className: 'TreeCheckbox', checked: isSelected, disabled: node.disabled, indeterminate: isIndeterminate, onClick: () => onSelect(node, isIndeterminate) })), (0, jsx_runtime_1.jsxs)("span", { className: 'TreeLabel TreeLabelName', children: [iconName && (0, jsx_runtime_1.jsx)("span", { className: `rioglyph ${iconName}` }), (0, jsx_runtime_1.jsx)("span", { className: 'TreeLabelNameText', children: (0, jsx_runtime_1.jsx)("span", { className: 'TreeLabelNameTextHeadline', children: node.name }) }), (0, jsx_runtime_1.jsx)("span", { className: 'TreeLabelCount label label-muted label-filled label-condensed', children: node.items.length }), (0, jsx_runtime_1.jsx)("span", { className: `TreeLabelExpander rioglyph rioglyph-chevron-down ${hasChildren ? '' : 'text-color-light'}` })] })] }));
21
22
  });
22
23
  exports.default = TreeNode;
@@ -37,6 +37,12 @@ export type SplitDialogProps = Omit<BaseDialogProps, 'useOverflow'> & {
37
37
  * @default true
38
38
  */
39
39
  useOverflow?: boolean;
40
+ /**
41
+ * Allows to disable the divider.
42
+ *
43
+ * @default true
44
+ */
45
+ showDivider?: boolean;
40
46
  };
41
47
  declare const SplitDialog: (props: SplitDialogProps) => import("react/jsx-runtime").JSX.Element;
42
48
  export default SplitDialog;
@@ -5,10 +5,10 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const classnames_1 = tslib_1.__importDefault(require("classnames"));
6
6
  const Dialog_1 = tslib_1.__importDefault(require("./Dialog"));
7
7
  const SplitDialog = (props) => {
8
- const { leftContent, rightContent, leftContentClassName = '', rightContentClassName = '', className = '', useOverflow = true, ...remainingProps } = props;
8
+ const { leftContent, rightContent, leftContentClassName = '', rightContentClassName = '', className = '', useOverflow = true, showDivider = true, ...remainingProps } = props;
9
9
  const dialogClassName = `split-dialog ${className}`;
10
10
  const dividerClasses = (0, classnames_1.default)('split-divider', 'bg-lighter');
11
- const body = ((0, jsx_runtime_1.jsxs)("div", { className: 'split-wrapper', children: [(0, jsx_runtime_1.jsxs)("div", { className: `split-left ${leftContentClassName}`, children: [leftContent, (0, jsx_runtime_1.jsx)("div", { className: dividerClasses })] }), (0, jsx_runtime_1.jsx)("div", { className: `split-right ${rightContentClassName}`, children: rightContent })] }));
11
+ const body = ((0, jsx_runtime_1.jsxs)("div", { className: 'split-wrapper', children: [(0, jsx_runtime_1.jsxs)("div", { className: `split-left ${leftContentClassName}`, children: [leftContent, showDivider && (0, jsx_runtime_1.jsx)("div", { className: dividerClasses })] }), (0, jsx_runtime_1.jsx)("div", { className: `split-right ${rightContentClassName}`, children: rightContent })] }));
12
12
  return (0, jsx_runtime_1.jsx)(Dialog_1.default, { ...remainingProps, body: body, className: dialogClassName, useOverflow: useOverflow });
13
13
  };
14
14
  exports.default = SplitDialog;
@@ -25,7 +25,7 @@ export type FilePickerProps = {
25
25
  */
26
26
  label?: string | ReactNode;
27
27
  /**
28
- * Maximum file size.
28
+ * Maximum file size in byte. 5 MB = 5,242,880 byte
29
29
  */
30
30
  maxSize?: number;
31
31
  /**
@@ -26,7 +26,7 @@ const FormLabel = (props) => {
26
26
  }
27
27
  }, []);
28
28
  const supportingTextClasses = (0, classnames_1.default)('text-color-gray', 'text-italic', parentSize === 'sm' && 'text-size-10', parentSize === 'lg' && 'text-size-14', !parentSize && 'text-size-12');
29
- if (isLabel) {
29
+ if (isLabel && remainingProps.htmlFor) {
30
30
  const labelClasses = (0, classnames_1.default)(!supportingText && 'display-inline-block', supportingText && 'display-inline-flex flex-wrap justify-content-between width-100pct', className);
31
31
  return (
32
32
  // biome-ignore lint/a11y/noLabelWithoutControl: <explanation>
@@ -44,6 +44,15 @@ const Map = (props) => {
44
44
  else {
45
45
  console.debug('initialize here map');
46
46
  }
47
+ if (api?.map) {
48
+ // Cleanup any previously initialized map before doing anything else
49
+ console.debug('disposing previous map');
50
+ (0, eventHandling_1.removeEventListenerMap)(api.map);
51
+ if (api.mapEvents) {
52
+ api.mapEvents.dispose();
53
+ }
54
+ api.map.dispose();
55
+ }
47
56
  const bounds = boundingBox && (0, mapUtils_1.getMapBounds)(boundingBox);
48
57
  // Initialize communication with the platform
49
58
  const platform = (0, rendering_1.getPlatform)(credentials);
@@ -56,7 +65,7 @@ const Map = (props) => {
56
65
  // @ts-ignore-next-line: according to the Here docs, the engine type exists
57
66
  // see https://www.here.com/docs/bundle/maps-api-for-javascript-developer-guide/page/topics/harp-migrate.html
58
67
  const defaultLayers = platform.createDefaultLayers({ engineType, lg: language, pois: true });
59
- const defaultLayerMap = (0, rendering_1.getBaseLayer)({
68
+ (0, rendering_1.getBaseLayer)({
60
69
  baseLayerName: baseLayer,
61
70
  defaultLayers,
62
71
  enableWebGL,
@@ -66,76 +75,69 @@ const Map = (props) => {
66
75
  language,
67
76
  minZoom,
68
77
  maxZoom: safeMaxZoom,
69
- });
70
- // Initialize the map
71
- const hereMap = new H.Map(mapRef.current, defaultLayerMap.baseLayer, {
72
- zoom,
73
- center,
74
- bounds,
75
- engineType,
76
- pixelRatio: devicePixelRatio,
77
- fixedCenter: true,
78
- });
79
- if (defaultLayerMap.overlayLayer) {
80
- // Special case for satellite map where we render street labels and road signs as well as additional pois as vector data
81
- hereMap.addLayer(defaultLayerMap.overlayLayer);
82
- }
83
- setMapInitialized(true);
84
- let hereMapEvents = false;
85
- let hereBehavior;
86
- // Enable the map event system
87
- if (!disableMapEvents) {
88
- hereMapEvents = new H.mapevents.MapEvents(hereMap);
89
- }
90
- if (!(disableMapEvents || disableBehavior)) {
91
- hereBehavior = new H.mapevents.Behavior(hereMapEvents);
92
- // @ts-ignore-next-line
93
- hereBehavior.disable(H.mapevents.Behavior.Feature.FRACTIONAL_ZOOM);
94
- if (disableZoomMomentum) {
95
- // Disable the inertia that occurs on WebGL maps when scrolling/zooming.
96
- // This resulted in a very high scroll sensitivity.
97
- // @ts-ignore-next-line
98
- hereBehavior.disable(H.mapevents.Behavior.Feature.ZOOM_MOMENTUM);
78
+ }).then(defaultLayerMap => {
79
+ // Initialize the map
80
+ const hereMap = new H.Map(mapRef.current, defaultLayerMap.baseLayer, {
81
+ zoom,
82
+ center,
83
+ bounds,
84
+ engineType,
85
+ pixelRatio: devicePixelRatio,
86
+ fixedCenter: true,
87
+ });
88
+ if (defaultLayerMap.overlayLayer) {
89
+ // Special case for satellite map where we render street labels and road signs as well as additional pois as vector data
90
+ // hereMap.setBaseLayer(defaultLayerMap.baseLayer);
91
+ hereMap.addLayer(defaultLayerMap.overlayLayer);
99
92
  }
100
- }
101
- (0, eventHandling_1.addEventListenerMap)(hereMap, eventListenerMap, hereMap);
102
- const hereUi = (0, mapUi_1.getHereUi)(hereMap, defaultLayers, showScaleBar, language);
103
- // The api will be passed to services when using a render function.
104
- // This allows the service to access the map internals
105
- setApi({
106
- credentials,
107
- defaultLayers,
108
- map: hereMap,
109
- mapEvents: hereMapEvents,
110
- behavior: hereBehavior,
111
- platform,
112
- ui: hereUi,
113
- utils: (0, mapUtils_1.createUtils)(hereMap),
114
- // Put settings back into the map API object so the invoking service
115
- // can check on these settings for instance inside a test
116
- settings: {
117
- enableWebGL,
118
- baseLayer,
119
- activeLayers,
120
- showCluster,
121
- minZoom,
122
- maxZoom: safeMaxZoom,
123
- },
124
- });
125
- // If the base layer changed, re-add all previous objects again,
126
- // otherwise the map would be empty
127
- if (allMapObjects) {
128
- hereMap.addObjects(allMapObjects);
129
- }
130
- return () => {
131
- if (hereMap) {
132
- (0, eventHandling_1.removeEventListenerMap)(hereMap);
133
- if (hereMapEvents) {
134
- hereMapEvents.dispose();
93
+ setMapInitialized(true);
94
+ let hereMapEvents = false;
95
+ let hereBehavior;
96
+ if (!disableMapEvents) {
97
+ // Enable the map event system
98
+ hereMapEvents = new H.mapevents.MapEvents(hereMap);
99
+ }
100
+ if (!(disableMapEvents || disableBehavior)) {
101
+ hereBehavior = new H.mapevents.Behavior(hereMapEvents);
102
+ // @ts-ignore-next-line
103
+ hereBehavior.disable(H.mapevents.Behavior.Feature.FRACTIONAL_ZOOM);
104
+ if (disableZoomMomentum) {
105
+ // Disable the inertia that occurs on WebGL maps when scrolling/zooming.
106
+ // This resulted in a very high scroll sensitivity.
107
+ // @ts-ignore-next-line
108
+ hereBehavior.disable(H.mapevents.Behavior.Feature.ZOOM_MOMENTUM);
135
109
  }
136
- hereMap.dispose();
137
110
  }
138
- };
111
+ (0, eventHandling_1.addEventListenerMap)(hereMap, eventListenerMap, hereMap);
112
+ const hereUi = (0, mapUi_1.getHereUi)(hereMap, defaultLayers, showScaleBar, language);
113
+ // The api will be passed to services when using a render function.
114
+ // This allows the service to access the map internals
115
+ setApi({
116
+ credentials,
117
+ defaultLayers,
118
+ map: hereMap,
119
+ mapEvents: hereMapEvents,
120
+ behavior: hereBehavior,
121
+ platform,
122
+ ui: hereUi,
123
+ utils: (0, mapUtils_1.createUtils)(hereMap),
124
+ // Put settings back into the map API object so the invoking service
125
+ // can check on these settings for instance inside a test
126
+ settings: {
127
+ enableWebGL,
128
+ baseLayer,
129
+ activeLayers,
130
+ showCluster,
131
+ minZoom,
132
+ maxZoom: safeMaxZoom,
133
+ },
134
+ });
135
+ if (allMapObjects) {
136
+ // If the base layer changed, re-add all previous objects again,
137
+ // otherwise the map would be empty
138
+ hereMap.addObjects(allMapObjects);
139
+ }
140
+ });
139
141
  }, [enableWebGL, enableDevicePixelRatio, language, baseLayer, minZoom, maxZoom]);
140
142
  const isDarkMode = (0, useDarkMode_1.default)();
141
143
  (0, react_1.useEffect)(() => {
@@ -3,7 +3,7 @@ import type { MapType } from '../../../../utils/mapTypes';
3
3
  export type MapTypeSettingsProps = {
4
4
  mapType?: string;
5
5
  enableNightMap?: boolean;
6
- onMapTypeChange?: () => MapType;
6
+ onMapTypeChange?: (type: MapType) => void;
7
7
  defaultTypeLabel?: string | JSX.Element;
8
8
  truckTypeLabel?: string | JSX.Element;
9
9
  terrainTypeLabel?: string | JSX.Element;
@@ -20,4 +20,4 @@ export type BaseLayerResponse = {
20
20
  baseLayer: H.map.layer.Layer;
21
21
  overlayLayer?: H.map.layer.Layer;
22
22
  };
23
- export declare const getBaseLayer: ({ baseLayerName, defaultLayers, enableWebGL, platform, engineType, language, vehicleRestrictions, minZoom, maxZoom, }: BaseLayer) => BaseLayerResponse;
23
+ export declare const getBaseLayer: ({ baseLayerName, defaultLayers, enableWebGL, platform, engineType, language, vehicleRestrictions, minZoom, maxZoom, }: BaseLayer) => Promise<BaseLayerResponse>;
@@ -55,7 +55,7 @@ const getEngineType = (baseLayerName, enableWebGL) => {
55
55
  }
56
56
  };
57
57
  exports.getEngineType = getEngineType;
58
- const getBaseLayer = ({ baseLayerName, defaultLayers, enableWebGL, platform, engineType, language, vehicleRestrictions, minZoom, maxZoom, }) => {
58
+ const getBaseLayer = async ({ baseLayerName, defaultLayers, enableWebGL, platform, engineType, language, vehicleRestrictions, minZoom, maxZoom, }) => {
59
59
  const restriction = 'disabled'; // vehicleRestrictions ? 'active_and_inactive' : 'disabled';
60
60
  const features = `pois:all,environmental_zones:all,congestion_zones:all,vehicle_restrictions:${restriction}`;
61
61
  if (enableWebGL && baseLayerName === constants_1.MAP_TYPE_DEFAULT) {
@@ -70,7 +70,7 @@ const getBaseLayer = ({ baseLayerName, defaultLayers, enableWebGL, platform, eng
70
70
  if (enableWebGL) {
71
71
  // This is a workaround for setting the min and max zoom limit for satellite map
72
72
  // since the setMin/setMax cannot be set on the "defaultLayers.hybrid.liteday.raster".
73
- // The HERE support suggests to create a hybrid layer for that and set the zoom limits
73
+ // The HERE support suggested to create a hybrid layer for that and set the zoom limits
74
74
  // on the two layers.
75
75
  const hybridStyleConfig = {
76
76
  base: {
@@ -78,24 +78,20 @@ const getBaseLayer = ({ baseLayerName, defaultLayers, enableWebGL, platform, eng
78
78
  scheme: 'hybrid.day',
79
79
  },
80
80
  };
81
- let baseLayer;
82
- let overlayLayer;
83
81
  // This method creates hybrid map layers. A hybrid map consists of raster satellite base layer and vector layers on top.
84
82
  // Layers created by this method can be used only when the Map is instantiated with H.Map.EngineType.HARP engineType.
85
83
  // See https://www.here.com/docs/bundle/maps-api-for-javascript-api-reference/page/H.service.Platform_4.html#createHybridLayers
86
84
  // @ts-ignore-next-line
87
- platform.createHybridLayers(hybridStyleConfig, (layers) => {
85
+ await platform.createHybridLayers(hybridStyleConfig, (layers) => {
88
86
  layers.raster.setMin(minZoom);
89
87
  layers.raster.setMax(maxZoom);
90
88
  layers.vector.setMin(minZoom);
91
89
  layers.vector.setMax(maxZoom);
92
- baseLayer = layers.raster;
93
- overlayLayer = layers.vector;
90
+ return {
91
+ baseLayer: layers.raster,
92
+ overlayLayer: layers.vector,
93
+ };
94
94
  }, console.error);
95
- return {
96
- baseLayer,
97
- overlayLayer,
98
- };
99
95
  }
100
96
  return {
101
97
  baseLayer: (0, exports.getBaseTileLayer)((0, exports.getBaseRasterTileService)(platform, 'explore.satellite.day', features, language), engineType, minZoom, maxZoom),
@@ -0,0 +1,18 @@
1
+ export type UseAverageOptions = {
2
+ /**
3
+ * The locale used to parse localized number formats (e.g. "de-DE", "en-GB").
4
+ * @default "en-GB".
5
+ */
6
+ locale?: string;
7
+ };
8
+ /**
9
+ * Calculates the average of numeric values from a list of objects.
10
+ * Values are extracted using a dot-separated path and parsed with locale awareness.
11
+ *
12
+ * @param items - The list of objects to aggregate.
13
+ * @param path - Dot-separated path to the value in each object.
14
+ * @param options - Optional configuration (e.g. locale for number parsing).
15
+ * @returns The average of all valid values as a number. Returns 0 if no values are valid.
16
+ */
17
+ declare const useAverage: (items: unknown[], path: string, options?: UseAverageOptions) => number;
18
+ export default useAverage;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const react_1 = require("react");
4
+ const formatUtils_1 = require("../utils/formatUtils");
5
+ /**
6
+ * Calculates the average of numeric values from a list of objects.
7
+ * Values are extracted using a dot-separated path and parsed with locale awareness.
8
+ *
9
+ * @param items - The list of objects to aggregate.
10
+ * @param path - Dot-separated path to the value in each object.
11
+ * @param options - Optional configuration (e.g. locale for number parsing).
12
+ * @returns The average of all valid values as a number. Returns 0 if no values are valid.
13
+ */
14
+ const useAverage = (items, path, options = {}) => {
15
+ const { locale = 'en-GB' } = options;
16
+ return (0, react_1.useMemo)(() => {
17
+ const values = items
18
+ .map(item => {
19
+ const raw = (0, formatUtils_1.getValueByPath)(item, path);
20
+ return (0, formatUtils_1.parseNumberFromValue)(raw, locale);
21
+ })
22
+ .filter(num => !Number.isNaN(num) && num !== 0);
23
+ if (values.length === 0) {
24
+ return 0;
25
+ }
26
+ const sum = values.reduce((total, value) => total + value, 0);
27
+ return sum / values.length;
28
+ }, [items, path, locale]);
29
+ };
30
+ exports.default = useAverage;
@@ -0,0 +1,22 @@
1
+ export type UseCountOptions = {
2
+ /**
3
+ * Count only values that strictly equal this value.
4
+ * If omitted and no `match` is provided, any value that is not null or undefined will be counted.
5
+ */
6
+ equals?: unknown;
7
+ /**
8
+ * A custom matcher function. If provided, it overrides the `equals` option.
9
+ */
10
+ match?: (value: unknown) => boolean;
11
+ };
12
+ /**
13
+ * Counts how many items in a list match a specific condition at a given path.
14
+ * Supports exact value comparison or custom predicate logic.
15
+ *
16
+ * @param items - The list of objects to evaluate.
17
+ * @param path - Dot-separated path to the target property.
18
+ * @param options - Optional config with `equals` or a custom `match` function.
19
+ * @returns Number of items that satisfy the condition.
20
+ */
21
+ declare const useCount: (items: unknown[], path: string, options?: UseCountOptions) => number;
22
+ export default useCount;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const react_1 = require("react");
4
+ const formatUtils_1 = require("../utils/formatUtils");
5
+ /**
6
+ * Counts how many items in a list match a specific condition at a given path.
7
+ * Supports exact value comparison or custom predicate logic.
8
+ *
9
+ * @param items - The list of objects to evaluate.
10
+ * @param path - Dot-separated path to the target property.
11
+ * @param options - Optional config with `equals` or a custom `match` function.
12
+ * @returns Number of items that satisfy the condition.
13
+ */
14
+ const useCount = (items, path, options = {}) => {
15
+ const { equals, match } = options;
16
+ return (0, react_1.useMemo)(() => {
17
+ return items.reduce((count, item) => {
18
+ const value = (0, formatUtils_1.getValueByPath)(item, path);
19
+ let shouldCount = false;
20
+ if (typeof match === 'function') {
21
+ shouldCount = match(value);
22
+ }
23
+ else if (equals !== undefined) {
24
+ shouldCount = value === equals;
25
+ }
26
+ else {
27
+ shouldCount = value != null; // fallback: count all defined values
28
+ }
29
+ return shouldCount ? count + 1 : count;
30
+ }, 0);
31
+ }, [items, path, equals, match]);
32
+ };
33
+ exports.default = useCount;
@@ -0,0 +1,18 @@
1
+ export type UseMaxOptions = {
2
+ /**
3
+ * The locale used to parse localized number formats (e.g. "de-DE", "en-GB").
4
+ * @default "en-GB".
5
+ */
6
+ locale?: string;
7
+ };
8
+ /**
9
+ * Finds the maximum numeric value from a list of objects.
10
+ * Values are extracted using a dot-separated path and parsed with locale awareness.
11
+ *
12
+ * @param items - The list of objects to evaluate.
13
+ * @param path - Dot-separated path to the value in each object.
14
+ * @param options - Optional configuration (e.g. locale for number parsing).
15
+ * @returns The largest of all valid values, or 0 if none are valid.
16
+ */
17
+ declare const useMax: (items: unknown[], path: string, options?: UseMaxOptions) => number;
18
+ export default useMax;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const react_1 = require("react");
4
+ const formatUtils_1 = require("../utils/formatUtils");
5
+ /**
6
+ * Finds the maximum numeric value from a list of objects.
7
+ * Values are extracted using a dot-separated path and parsed with locale awareness.
8
+ *
9
+ * @param items - The list of objects to evaluate.
10
+ * @param path - Dot-separated path to the value in each object.
11
+ * @param options - Optional configuration (e.g. locale for number parsing).
12
+ * @returns The largest of all valid values, or 0 if none are valid.
13
+ */
14
+ const useMax = (items, path, options = {}) => {
15
+ const { locale = 'en-GB' } = options;
16
+ return (0, react_1.useMemo)(() => {
17
+ const values = items
18
+ .map(item => {
19
+ const valueFromPath = (0, formatUtils_1.getValueByPath)(item, path);
20
+ return (0, formatUtils_1.parseNumberFromValue)(valueFromPath, locale);
21
+ })
22
+ .filter(num => !Number.isNaN(num));
23
+ return values.length > 0 ? Math.max(...values) : 0;
24
+ }, [items, path, locale]);
25
+ };
26
+ exports.default = useMax;
@@ -0,0 +1,18 @@
1
+ export type UseMinOptions = {
2
+ /**
3
+ * The locale used to parse localized number formats (e.g. "de-DE", "en-GB").
4
+ * @default "en-GB".
5
+ */
6
+ locale?: string;
7
+ };
8
+ /**
9
+ * Finds the minimum numeric value from a list of objects.
10
+ * Values are extracted using a dot-separated path and parsed with locale awareness.
11
+ *
12
+ * @param items - The list of objects to evaluate.
13
+ * @param path - Dot-separated path to the value in each object.
14
+ * @param options - Optional configuration (e.g. locale for number parsing).
15
+ * @returns The smallest of all valid values, or 0 if none are valid.
16
+ */
17
+ declare const useMin: (items: unknown[], path: string, options?: UseMinOptions) => number;
18
+ export default useMin;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const react_1 = require("react");
4
+ const formatUtils_1 = require("../utils/formatUtils");
5
+ /**
6
+ * Finds the minimum numeric value from a list of objects.
7
+ * Values are extracted using a dot-separated path and parsed with locale awareness.
8
+ *
9
+ * @param items - The list of objects to evaluate.
10
+ * @param path - Dot-separated path to the value in each object.
11
+ * @param options - Optional configuration (e.g. locale for number parsing).
12
+ * @returns The smallest of all valid values, or 0 if none are valid.
13
+ */
14
+ const useMin = (items, path, options = {}) => {
15
+ const { locale = 'en-GB' } = options;
16
+ return (0, react_1.useMemo)(() => {
17
+ const values = items
18
+ .map(item => {
19
+ const valueFromPath = (0, formatUtils_1.getValueByPath)(item, path);
20
+ return (0, formatUtils_1.parseNumberFromValue)(valueFromPath, locale);
21
+ })
22
+ .filter(num => !Number.isNaN(num));
23
+ return values.length > 0 ? Math.min(...values) : 0;
24
+ }, [items, path, locale]);
25
+ };
26
+ exports.default = useMin;
@@ -0,0 +1,18 @@
1
+ export type UseSumOptions = {
2
+ /**
3
+ * The locale used to parse localized number formats (e.g. "de-DE", "en-GB").
4
+ * @default "en-GB".
5
+ */
6
+ locale?: string;
7
+ };
8
+ /**
9
+ * Calculates the sum of numeric values from a list of objects, using a defined property path.
10
+ * Supports localized number strings (e.g. "1.234,56 €", "1,000.75").
11
+ *
12
+ * @param items - The list of objects to sum values from.
13
+ * @param path - The dot-separated path to the target value in each object.
14
+ * @param options - Optional configuration such as locale for parsing.
15
+ * @returns The total sum of all valid parsed values as a number.
16
+ */
17
+ declare const useSum: (items: unknown[], path: string, options?: UseSumOptions) => number;
18
+ export default useSum;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const react_1 = require("react");
4
+ const formatUtils_1 = require("../utils/formatUtils");
5
+ /**
6
+ * Calculates the sum of numeric values from a list of objects, using a defined property path.
7
+ * Supports localized number strings (e.g. "1.234,56 €", "1,000.75").
8
+ *
9
+ * @param items - The list of objects to sum values from.
10
+ * @param path - The dot-separated path to the target value in each object.
11
+ * @param options - Optional configuration such as locale for parsing.
12
+ * @returns The total sum of all valid parsed values as a number.
13
+ */
14
+ const useSum = (items, path, options = {}) => {
15
+ const { locale = 'en-GB' } = options;
16
+ const sum = (0, react_1.useMemo)(() => {
17
+ return items.reduce((total, item) => {
18
+ const raw = (0, formatUtils_1.getValueByPath)(item, path);
19
+ const value = (0, formatUtils_1.parseNumberFromValue)(raw, locale);
20
+ return total + value;
21
+ }, 0);
22
+ }, [items, path, locale]);
23
+ return sum;
24
+ };
25
+ exports.default = useSum;
@@ -0,0 +1,2 @@
1
+ export { default } from './hooks/useAverage';
2
+ export * from './hooks/useAverage';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = void 0;
4
+ const tslib_1 = require("tslib");
5
+ var useAverage_1 = require("./hooks/useAverage");
6
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return tslib_1.__importDefault(useAverage_1).default; } });
7
+ tslib_1.__exportStar(require("./hooks/useAverage"), exports);
@@ -0,0 +1,2 @@
1
+ export { default } from './hooks/useCount';
2
+ export * from './hooks/useCount';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = void 0;
4
+ const tslib_1 = require("tslib");
5
+ var useCount_1 = require("./hooks/useCount");
6
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return tslib_1.__importDefault(useCount_1).default; } });
7
+ tslib_1.__exportStar(require("./hooks/useCount"), exports);
@@ -0,0 +1,2 @@
1
+ export { default } from './hooks/useMax';
2
+ export * from './hooks/useMax';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = void 0;
4
+ const tslib_1 = require("tslib");
5
+ var useMax_1 = require("./hooks/useMax");
6
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return tslib_1.__importDefault(useMax_1).default; } });
7
+ tslib_1.__exportStar(require("./hooks/useMax"), exports);
@@ -0,0 +1,2 @@
1
+ export { default } from './hooks/useMin';
2
+ export * from './hooks/useMin';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = void 0;
4
+ const tslib_1 = require("tslib");
5
+ var useMin_1 = require("./hooks/useMin");
6
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return tslib_1.__importDefault(useMin_1).default; } });
7
+ tslib_1.__exportStar(require("./hooks/useMin"), exports);
@@ -0,0 +1,2 @@
1
+ export { default } from './hooks/useSum';
2
+ export * from './hooks/useSum';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = void 0;
4
+ const tslib_1 = require("tslib");
5
+ var useSum_1 = require("./hooks/useSum");
6
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return tslib_1.__importDefault(useSum_1).default; } });
7
+ tslib_1.__exportStar(require("./hooks/useSum"), exports);
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Helper to extract a number from a string that may have units or grouping delimiters. It take localization into account.
3
+ *
4
+ * @param value
5
+ * @param locale
6
+ * @returns parsed number
7
+ */
8
+ export declare const parseNumberFromValue: (value: unknown, locale: string) => number;
9
+ /**
10
+ * Retrieves a nested property value from an object using dot-notation.
11
+ *
12
+ * @param obj - The object to retrieve the value from.
13
+ * @param path - Dot-separated path to the desired property (e.g. "price.amount").
14
+ * @returns The value at the given path or undefined if not found.
15
+ */
16
+ export declare const getValueByPath: (obj: unknown, path: string) => unknown;