@rio-cloud/rio-uikit 1.3.0 → 1.4.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 (125) hide show
  1. package/ChartLabel.d.ts +2 -0
  2. package/ChartLabel.js +2 -0
  3. package/ComposedChart.d.ts +2 -0
  4. package/ComposedChart.js +2 -0
  5. package/GroupedItemList.d.ts +2 -0
  6. package/GroupedItemList.js +2 -0
  7. package/LicensePlate.d.ts +2 -0
  8. package/LicensePlate.js +2 -0
  9. package/ReferenceLine.d.ts +2 -0
  10. package/ReferenceLine.js +2 -0
  11. package/components/assetTree/TreeOptions.js +7 -3
  12. package/components/charts/Area.d.ts +5 -0
  13. package/components/charts/Area.js +1 -9
  14. package/components/charts/AreaChart.d.ts +2 -0
  15. package/components/charts/AreaChart.js +9 -6
  16. package/components/charts/BarChart.js +4 -4
  17. package/components/charts/ChartLabel.d.ts +5 -0
  18. package/components/charts/ChartLabel.js +2 -0
  19. package/components/charts/ComposedChart.d.ts +34 -0
  20. package/components/charts/ComposedChart.js +30 -0
  21. package/components/charts/Legend.d.ts +8 -10
  22. package/components/charts/Legend.js +4 -13
  23. package/components/charts/Line.d.ts +5 -0
  24. package/components/charts/Line.js +1 -9
  25. package/components/charts/LineChart.d.ts +2 -0
  26. package/components/charts/LineChart.js +8 -5
  27. package/components/charts/PieChart.js +5 -5
  28. package/components/charts/RadialBarChart.js +5 -5
  29. package/components/charts/ReferenceLine.d.ts +7 -0
  30. package/components/charts/ReferenceLine.js +2 -0
  31. package/components/dialog/Dialog.d.ts +12 -4
  32. package/components/dialog/SplitDialog.d.ts +3 -3
  33. package/components/dropdown/ButtonDropdown.d.ts +3 -1
  34. package/components/dropdown/ButtonDropdown.js +6 -5
  35. package/components/dropdown/DropdownToggleButton.d.ts +1 -0
  36. package/components/dropdown/DropdownToggleButton.js +4 -2
  37. package/components/groupedItemList/GroupedItemList.d.ts +79 -0
  38. package/components/groupedItemList/GroupedItemList.js +77 -0
  39. package/components/licensePlate/LicensePlate.d.ts +19 -0
  40. package/components/licensePlate/LicensePlate.js +14 -0
  41. package/components/selects/BaseSelectDropdown.d.ts +1 -0
  42. package/components/selects/BaseSelectDropdown.js +16 -14
  43. package/components/selects/Multiselect.d.ts +5 -0
  44. package/components/selects/Multiselect.js +2 -2
  45. package/components/selects/Select.d.ts +5 -0
  46. package/components/selects/Select.js +2 -2
  47. package/components/switch/Switch.d.ts +6 -5
  48. package/components/switch/Switch.js +5 -5
  49. package/components/tag/Tag.d.ts +2 -2
  50. package/components/tag/Tag.js +5 -6
  51. package/hooks/useDOMNodeCount.d.ts +2 -0
  52. package/hooks/useDOMNodeCount.js +29 -0
  53. package/hooks/useEventListenerCount.d.ts +5 -0
  54. package/hooks/useEventListenerCount.js +42 -0
  55. package/hooks/useKey.d.ts +7 -4
  56. package/hooks/useKey.js +36 -8
  57. package/lib/es/ChartLabel.d.ts +2 -0
  58. package/lib/es/ChartLabel.js +7 -0
  59. package/lib/es/ComposedChart.d.ts +2 -0
  60. package/lib/es/ComposedChart.js +7 -0
  61. package/lib/es/GroupedItemList.d.ts +2 -0
  62. package/lib/es/GroupedItemList.js +7 -0
  63. package/lib/es/LicensePlate.d.ts +2 -0
  64. package/lib/es/LicensePlate.js +7 -0
  65. package/lib/es/ReferenceLine.d.ts +2 -0
  66. package/lib/es/ReferenceLine.js +7 -0
  67. package/lib/es/components/assetTree/TreeOptions.js +7 -3
  68. package/lib/es/components/charts/Area.d.ts +5 -0
  69. package/lib/es/components/charts/Area.js +1 -9
  70. package/lib/es/components/charts/AreaChart.d.ts +2 -0
  71. package/lib/es/components/charts/AreaChart.js +7 -4
  72. package/lib/es/components/charts/BarChart.js +3 -3
  73. package/lib/es/components/charts/ChartLabel.d.ts +5 -0
  74. package/lib/es/components/charts/ChartLabel.js +4 -0
  75. package/lib/es/components/charts/ComposedChart.d.ts +34 -0
  76. package/lib/es/components/charts/ComposedChart.js +32 -0
  77. package/lib/es/components/charts/Legend.d.ts +8 -10
  78. package/lib/es/components/charts/Legend.js +6 -13
  79. package/lib/es/components/charts/Line.d.ts +5 -0
  80. package/lib/es/components/charts/Line.js +1 -9
  81. package/lib/es/components/charts/LineChart.d.ts +2 -0
  82. package/lib/es/components/charts/LineChart.js +7 -4
  83. package/lib/es/components/charts/PieChart.js +4 -4
  84. package/lib/es/components/charts/RadialBarChart.js +4 -4
  85. package/lib/es/components/charts/ReferenceLine.d.ts +7 -0
  86. package/lib/es/components/charts/ReferenceLine.js +4 -0
  87. package/lib/es/components/dialog/Dialog.d.ts +12 -4
  88. package/lib/es/components/dialog/SplitDialog.d.ts +3 -3
  89. package/lib/es/components/dropdown/ButtonDropdown.d.ts +3 -1
  90. package/lib/es/components/dropdown/ButtonDropdown.js +5 -4
  91. package/lib/es/components/dropdown/DropdownToggleButton.d.ts +1 -0
  92. package/lib/es/components/dropdown/DropdownToggleButton.js +4 -2
  93. package/lib/es/components/groupedItemList/GroupedItemList.d.ts +79 -0
  94. package/lib/es/components/groupedItemList/GroupedItemList.js +80 -0
  95. package/lib/es/components/licensePlate/LicensePlate.d.ts +19 -0
  96. package/lib/es/components/licensePlate/LicensePlate.js +16 -0
  97. package/lib/es/components/selects/BaseSelectDropdown.d.ts +1 -0
  98. package/lib/es/components/selects/BaseSelectDropdown.js +16 -14
  99. package/lib/es/components/selects/Multiselect.d.ts +5 -0
  100. package/lib/es/components/selects/Multiselect.js +2 -2
  101. package/lib/es/components/selects/Select.d.ts +5 -0
  102. package/lib/es/components/selects/Select.js +2 -2
  103. package/lib/es/components/switch/Switch.d.ts +6 -5
  104. package/lib/es/components/switch/Switch.js +5 -5
  105. package/lib/es/components/tag/Tag.d.ts +2 -2
  106. package/lib/es/components/tag/Tag.js +5 -6
  107. package/lib/es/hooks/useDOMNodeCount.d.ts +2 -0
  108. package/lib/es/hooks/useDOMNodeCount.js +31 -0
  109. package/lib/es/hooks/useEventListenerCount.d.ts +5 -0
  110. package/lib/es/hooks/useEventListenerCount.js +45 -0
  111. package/lib/es/hooks/useKey.d.ts +7 -4
  112. package/lib/es/hooks/useKey.js +35 -7
  113. package/lib/es/useDOMNodeCount.d.ts +2 -0
  114. package/lib/es/useDOMNodeCount.js +7 -0
  115. package/lib/es/useEventListenerCount.d.ts +2 -0
  116. package/lib/es/useEventListenerCount.js +7 -0
  117. package/lib/es/utils/colorScheme.js +10 -8
  118. package/lib/es/version.json +1 -1
  119. package/package.json +14 -22
  120. package/useDOMNodeCount.d.ts +2 -0
  121. package/useDOMNodeCount.js +2 -0
  122. package/useEventListenerCount.d.ts +2 -0
  123. package/useEventListenerCount.js +2 -0
  124. package/utils/colorScheme.js +10 -8
  125. package/version.json +1 -1
@@ -5,9 +5,11 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const classnames_1 = tslib_1.__importDefault(require("classnames"));
7
7
  const Button_1 = tslib_1.__importDefault(require("../button/Button"));
8
+ const useMergeRefs_1 = tslib_1.__importDefault(require("../../hooks/useMergeRefs"));
8
9
  const DropdownToggleButton = (0, react_1.forwardRef)((props, ref) => {
9
- const { id, disabled, bsSize, bsStyle, variant, splitButton = false, onClick, className = '', children } = props, remainingProps = tslib_1.__rest(props, ["id", "disabled", "bsSize", "bsStyle", "variant", "splitButton", "onClick", "className", "children"]);
10
+ const { id, disabled, bsSize, bsStyle, variant, splitButton = false, onClick, className = '', children, outerRef } = props, remainingProps = tslib_1.__rest(props, ["id", "disabled", "bsSize", "bsStyle", "variant", "splitButton", "onClick", "className", "children", "outerRef"]);
11
+ const toggleRef = (0, useMergeRefs_1.default)(outerRef, ref);
10
12
  const labelButtonClasses = (0, classnames_1.default)(!splitButton && 'dropdown-toggle', !splitButton && className);
11
- return ((0, jsx_runtime_1.jsx)(Button_1.default, Object.assign({}, remainingProps, { id: splitButton ? `button-${id}` : id, type: 'button', ref: ref, disabled: disabled, bsStyle: bsStyle, bsSize: bsSize, variant: variant, onClick: onClick, className: labelButtonClasses }, { children: children })));
13
+ return ((0, jsx_runtime_1.jsx)(Button_1.default, Object.assign({}, remainingProps, { id: splitButton ? `button-${id}` : id, type: 'button', ref: toggleRef, disabled: disabled, bsStyle: bsStyle, bsSize: bsSize, variant: variant, onClick: onClick, className: labelButtonClasses }, { children: children })));
12
14
  });
13
15
  exports.default = DropdownToggleButton;
@@ -0,0 +1,79 @@
1
+ import React from 'react';
2
+ import { SortDirectionType } from '../../SortUtils';
3
+ export type Group = {
4
+ groupKey: string;
5
+ items: any[];
6
+ };
7
+ export type GroupedItemListProps<T> = {
8
+ /**
9
+ * The list of items to be grouped and rendered.
10
+ *
11
+ * By default, the component assumes an item object containing an 'id' and 'name' property
12
+ * plus some other attributes.
13
+ */
14
+ items: T[];
15
+ /**
16
+ * The property of the items to group by as a string, or a custom group function.
17
+ * Defaults to 'name' if not provided.
18
+ *
19
+ * @default 'name'
20
+ */
21
+ groupBy?: keyof T | ((item: T) => string);
22
+ /**
23
+ * The order in which to sort the groups. Accepts 'asc' for ascending or 'desc' for descending.
24
+ * @default 'asc'.
25
+ */
26
+ groupSortOrder?: SortDirectionType;
27
+ /**
28
+ * The order in which to sort the items inside a group. Accepts 'asc' for ascending or 'desc' for descending.
29
+ * @default 'asc'.
30
+ */
31
+ itemSortOrder?: SortDirectionType;
32
+ /**
33
+ * Sorting function for the groups.
34
+ */
35
+ groupSortFunction?: (groups: Group[]) => Group[];
36
+ /**
37
+ * Sorting function for the items within each group.
38
+ */
39
+ itemSortFunction?: (items: T[]) => T[];
40
+ /**
41
+ * A custom render function for the group divider.
42
+ * Receives the group key (e.g., letter or date) as a parameter.
43
+ */
44
+ renderDivider?: (groupKey: string) => React.ReactNode;
45
+ /**
46
+ * A custom render function for individual list items.
47
+ * Receives an item as a parameter.
48
+ */
49
+ renderItem?: (item: T) => React.ReactNode;
50
+ /**
51
+ * Specifies the HTML element to use for the list inside each group.
52
+ * Default is 'div'. Use 'ul' for rendering the list items as `<li>` elements.
53
+ */
54
+ listElement?: 'div' | 'ul';
55
+ /**
56
+ * Optional class name for the list element inside each group.
57
+ * Applied to the `div` or `ul` wrapping the items.
58
+ */
59
+ listElementClassName?: string;
60
+ /**
61
+ * Optional class name for the divider element in each group.
62
+ * Applied to the `div` wrapping each group divider.
63
+ */
64
+ dividerElementClassName?: string;
65
+ /**
66
+ * Optional class name for the outer wrapper element.
67
+ * Applied to the outer `div` wrapping the entire component.
68
+ */
69
+ className?: string;
70
+ };
71
+ /**
72
+ * A React component that groups and renders a list of items based on a specified property.
73
+ * The component can be customized to render dividers and list items in different styles.
74
+ *
75
+ * @param {GroupedItemListProps} props - The props for the component.
76
+ * @returns {JSX.Element} The grouped and rendered list component.
77
+ */
78
+ declare const GroupedItemList: <T>(props: GroupedItemListProps<T>) => import("react/jsx-runtime").JSX.Element;
79
+ export default GroupedItemList;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = tslib_1.__importStar(require("react"));
6
+ const SortUtils_1 = require("../../SortUtils");
7
+ /**
8
+ * A React component that groups and renders a list of items based on a specified property.
9
+ * The component can be customized to render dividers and list items in different styles.
10
+ *
11
+ * @param {GroupedItemListProps} props - The props for the component.
12
+ * @returns {JSX.Element} The grouped and rendered list component.
13
+ */
14
+ const GroupedItemList = (props) => {
15
+ const { items, groupBy = 'name', groupSortOrder = 'asc', // Default to ascending order if not specified
16
+ groupSortFunction, itemSortFunction, itemSortOrder = 'asc', // Default to ascending order if not specified
17
+ renderDivider, renderItem, listElement = 'div', // Default to 'div' if not specified
18
+ listElementClassName, dividerElementClassName, className, } = props;
19
+ // Default group sorting function or specific function provided
20
+ const groupSortFn = groupSortFunction
21
+ ? groupSortFunction
22
+ : (groups) => (0, SortUtils_1.naturalSortByProperty)(groups, 'groupKey', groupSortOrder);
23
+ // Default item sorting within groups or specific function provided
24
+ const itemSortFn = itemSortFunction
25
+ ? itemSortFunction
26
+ : (itemsToSort) => (0, SortUtils_1.sortByProperty)(itemsToSort, groupBy, itemSortOrder);
27
+ // Determine the grouping function based on the type of groupBy
28
+ // const getGroupKey = (item: T): string => {
29
+ // if (typeof groupBy === 'string') {
30
+ // if (groupBy === 'name') {
31
+ // return (item as any).name?.[0]?.toUpperCase() ?? '';
32
+ // }
33
+ // return (item as any)[groupBy]?.toString() ?? '';
34
+ // } else if (typeof groupBy === 'function') {
35
+ // return groupBy(item);
36
+ // }
37
+ // throw new Error('Please define a "groupBy" property as a string or function.');
38
+ // };
39
+ const getGroupKey = typeof groupBy === 'function'
40
+ ? groupBy
41
+ : (item) => { var _a, _b, _c; return (_c = (_b = (_a = item[groupBy]) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.toUpperCase()) !== null && _c !== void 0 ? _c : ''; };
42
+ // Group items by the specified property
43
+ // const allGroups = useMemo(
44
+ // () =>
45
+ // items.reduce<Record<string, T[]>>((acc, item) => {
46
+ // const groupKey = getGroupKey(item);
47
+ // if (!acc[groupKey]) {
48
+ // acc[groupKey] = [];
49
+ // }
50
+ // acc[groupKey].push(item);
51
+ // return acc;
52
+ // }, {}),
53
+ // [items, getGroupKey]
54
+ // );
55
+ // Group items by the specified property
56
+ const groupedItems = (0, react_1.useMemo)(() => {
57
+ // Explicitly typing the accumulator as Record<string, T[]>
58
+ const groups = items.reduce((acc, item) => {
59
+ const groupKey = getGroupKey(item);
60
+ if (!acc[groupKey]) {
61
+ acc[groupKey] = [];
62
+ }
63
+ acc[groupKey].push(item);
64
+ return acc;
65
+ }, {});
66
+ return Object.keys(groups).map(groupKey => ({
67
+ groupKey,
68
+ items: groups[groupKey],
69
+ }));
70
+ }, [items, getGroupKey]);
71
+ // Assign the specified list element ('div' or 'ul')
72
+ const ListElement = listElement;
73
+ // Sort groups using the provided sort function
74
+ const sortedGroups = (0, react_1.useMemo)(() => groupSortFn(groupedItems), [groupedItems, groupSortFn]);
75
+ return ((0, jsx_runtime_1.jsx)("div", Object.assign({ className: `grouped-item-list ${className !== null && className !== void 0 ? className : ''}` }, { children: sortedGroups.map(group => ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ className: `group-divider ${dividerElementClassName !== null && dividerElementClassName !== void 0 ? dividerElementClassName : ''}` }, { children: renderDivider ? renderDivider(group.groupKey) : group.groupKey })), (0, jsx_runtime_1.jsx)(ListElement, Object.assign({ className: listElementClassName }, { children: itemSortFn(group.items).map(item => {
76
+ var _a;
77
+ return renderItem ? (renderItem(item)) : ((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: (0, jsx_runtime_1.jsx)("div", Object.assign({ className: 'item-name' }, { children: item.name })) }, (_a = item.id) !== null && _a !== void 0 ? _a : crypto.randomUUID()));
78
+ }) }))] }, group.groupKey))) })));
79
+ };
80
+ exports.default = GroupedItemList;
@@ -0,0 +1,19 @@
1
+ import { type PropsWithChildren } from 'react';
2
+ export type LicensePlateProps = {
3
+ /**
4
+ * The country code.
5
+ *
6
+ * Should be a string with 1-3 capital letters.
7
+ */
8
+ countryCode?: string;
9
+ /**
10
+ * Whether the EU stars should be hidden.
11
+ */
12
+ hideStars?: boolean;
13
+ /**
14
+ * Additional classes added to the wrapping element.
15
+ */
16
+ className?: string;
17
+ };
18
+ declare const LicensePlate: (props: PropsWithChildren<LicensePlateProps>) => import("react/jsx-runtime").JSX.Element;
19
+ export default LicensePlate;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const jsx_runtime_1 = require("react/jsx-runtime");
4
+ // @ts-ignore-next-line importsNotUsedAsValues
5
+ require("react");
6
+ const euStars = ((0, jsx_runtime_1.jsx)("svg", Object.assign({ xmlns: 'http://www.w3.org/2000/svg', width: '10', height: '10' }, { children: (0, jsx_runtime_1.jsx)("path", { fill: '#FFC200', fillRule: 'nonzero', d: 'M5.143.439H5.6L5.23.71l.141.438L5 .88l-.371.27.14-.438L4.4.439h.459L5 0zm2.198.594h.458l-.37.272.141.44-.371-.271-.372.27.142-.439-.372-.271h.46l.142-.44zm1.607 1.625h.458l-.37.272.141.44-.371-.271-.372.27.142-.438-.371-.272.459-.001.142-.438zm.593 2.208H10l-.37.272.14.44-.37-.272-.372.271.14-.438-.37-.272.46-.001.141-.438zm-.59 2.214h.459l-.37.271.14.44-.37-.271-.372.271.141-.439-.371-.271.46-.001.141-.439zM7.337 8.701h.459l-.371.272.141.44-.371-.27-.371.27.14-.44-.37-.27.459-.002.142-.438zm-2.201.588h.458l-.37.272.141.439-.371-.27-.372.27.142-.439-.372-.271.46-.001.142-.438zM2.938 8.7h.458l-.37.273.141.439-.371-.27-.372.27.141-.44-.37-.27h.459l.142-.44zM1.33 7.083h.458l-.37.272.14.44-.371-.271-.372.27.142-.439-.37-.271h.458l.143-.44zM.743 4.869H1.2l-.37.272.141.439-.371-.27-.372.27.142-.439L0 4.87l.459-.001L.6 4.43zm.581-2.217h.459l-.37.272.14.439-.37-.27-.372.27.14-.439-.37-.271h.459l.142-.44zM2.94 1.03h.459l-.37.272.14.44-.37-.272-.372.271.14-.439-.37-.271.458-.001.143-.439z' }) })));
7
+ const LicensePlate = (props) => {
8
+ const { countryCode, hideStars, className = '', children } = props;
9
+ let letterCount = '';
10
+ if ((countryCode === null || countryCode === void 0 ? void 0 : countryCode.length) === 2)
11
+ letterCount = 'two-letters';
12
+ if ((countryCode === null || countryCode === void 0 ? void 0 : countryCode.length) === 3)
13
+ letterCount = 'three-letters';
14
+ return ((0, jsx_runtime_1.jsx)("div", Object.assign({ className: `license-plate ${className}` }, { children: (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: 'plate-content' }, { children: [countryCode && ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: 'plate-country' }, { children: [!hideStars && (0, jsx_runtime_1.jsx)("span", Object.assign({ className: 'stars' }, { children: euStars })), (0, jsx_runtime_1.jsx)("span", Object.assign({ className: `plate-country-code ${letterCount}` }, { children: countryCode }))] }))), (0, jsx_runtime_1.jsx)("div", Object.assign({ className: 'plate-number' }, { children: children }))] })) })));
15
+ };
16
+ exports.default = LicensePlate;
@@ -36,6 +36,7 @@ export type SelectOption = {
36
36
  export type BaseSelectDropdownProps<T extends SelectOption> = {
37
37
  options?: T[];
38
38
  isOpen?: boolean;
39
+ isLoading?: boolean;
39
40
  updateDOMValues?: (values: OptionDOMValue[] | undefined) => void;
40
41
  onOpen?: (hasDropup: boolean) => void;
41
42
  onSelect?: (selectedItem: T | undefined) => void;
@@ -14,11 +14,12 @@ const useEffectOnce_1 = tslib_1.__importDefault(require("../../hooks/useEffectOn
14
14
  const useKey_1 = tslib_1.__importDefault(require("../../useKey"));
15
15
  const DropdownHeader_1 = tslib_1.__importDefault(require("./DropdownHeader"));
16
16
  const NoItemMessage_1 = tslib_1.__importDefault(require("./NoItemMessage"));
17
+ const Spinner_1 = tslib_1.__importDefault(require("../spinner/Spinner"));
17
18
  const DATA_ATTRIBUTE_ID = 'data-item-id';
18
19
  const DEFAULT_FOCUSED_ITEM_INDEX = 0;
19
20
  const HIGHLIGHT_CLASS = 'focus';
20
21
  const BaseSelectDropdown = (props) => {
21
- const { isOpen = false, updateDOMValues = noop_1.default, onOpen = noop_1.default, onSelect = noop_1.default, onClose = noop_1.default, options = [], autoDropDirection = true, dropup = false, pullRight = false, useActiveClass = false, focusedItemIndex: externalFocusedItemIndex, keyboardUsed: externalKeyboardUsed, noItemMessage, dropdownClassName, } = props;
22
+ const { isOpen = false, isLoading = false, updateDOMValues = noop_1.default, onOpen = noop_1.default, onSelect = noop_1.default, onClose = noop_1.default, options = [], autoDropDirection = true, dropup = false, pullRight = false, useActiveClass = false, focusedItemIndex: externalFocusedItemIndex, keyboardUsed: externalKeyboardUsed, noItemMessage, dropdownClassName, } = props;
22
23
  const [focusedItemIndex, setFocusedItemIndex] = (0, react_1.useState)(externalFocusedItemIndex || DEFAULT_FOCUSED_ITEM_INDEX);
23
24
  const [keyboardUsed, setKeyboardUsed] = (0, react_1.useState)(externalKeyboardUsed);
24
25
  const dropdownMenuRef = (0, react_1.useRef)(null);
@@ -154,19 +155,20 @@ const BaseSelectDropdown = (props) => {
154
155
  if ((0, isEmpty_1.default)(options)) {
155
156
  return (0, jsx_runtime_1.jsx)(NoItemMessage_1.default, { noItemMessage: noItemMessage, className: dropdownMenuClasses });
156
157
  }
157
- return ((0, jsx_runtime_1.jsx)("ul", Object.assign({ className: dropdownMenuClasses, ref: dropdownMenuRef, role: 'menu' }, { children: options.map((option, index) => {
158
- if (option.header) {
159
- return (0, jsx_runtime_1.jsx)(DropdownHeader_1.default, { icon: option.icon, label: option.label }, option.id);
160
- }
161
- // Show focused style only when keyboard is in use
162
- const anchorClassNames = (0, classnames_1.default)('display-flex align-items-center', keyboardUsed && focusedItemIndex === index ? HIGHLIGHT_CLASS : '', option.disabled && 'pointer-events-none');
163
- const wrapperClassNames = (0, classnames_1.default)(option.disabled && 'disabled', useActiveClass && option.selected && 'active');
164
- return ((0, jsx_runtime_1.jsx)("li", Object.assign({ className: wrapperClassNames, role: 'listitem' }, { children: (0, jsx_runtime_1.jsxs)("a", Object.assign({ role: 'menuitem', className: anchorClassNames, "data-item-id": option.id, "data-item-index": index,
165
- // Note, we need to assign the click callback only when it's not disabled
166
- // otherwise the functions is still triggered
167
- // biome-ignore lint/a11y/useValidAnchor: due to old structure and backwards compatibility
168
- onClick: option.disabled ? undefined : handleOptionChange }, { children: [(0, jsx_runtime_1.jsxs)("span", { children: [option.icon && (0, jsx_runtime_1.jsx)("span", Object.assign({ className: 'margin-right-5' }, { children: option.icon })), option.label] }), (0, jsx_runtime_1.jsx)("input", { type: 'hidden', value: option.id })] })) }), option.id));
169
- }) })));
158
+ return ((0, jsx_runtime_1.jsxs)("ul", Object.assign({ className: dropdownMenuClasses, ref: dropdownMenuRef, role: 'menu' }, { children: [isLoading && ((0, jsx_runtime_1.jsx)("div", Object.assign({ className: 'display-flex justify-content-center padding-10' }, { children: (0, jsx_runtime_1.jsx)(Spinner_1.default, {}) }))), !isLoading &&
159
+ options.map((option, index) => {
160
+ if (option.header) {
161
+ return (0, jsx_runtime_1.jsx)(DropdownHeader_1.default, { icon: option.icon, label: option.label }, option.id);
162
+ }
163
+ // Show focused style only when keyboard is in use
164
+ const anchorClassNames = (0, classnames_1.default)('display-flex align-items-center', keyboardUsed && focusedItemIndex === index ? HIGHLIGHT_CLASS : '', option.disabled && 'pointer-events-none');
165
+ const wrapperClassNames = (0, classnames_1.default)(option.disabled && 'disabled', useActiveClass && option.selected && 'active');
166
+ return ((0, jsx_runtime_1.jsx)("li", Object.assign({ className: wrapperClassNames, role: 'listitem' }, { children: (0, jsx_runtime_1.jsxs)("a", Object.assign({ role: 'menuitem', className: anchorClassNames, "data-item-id": option.id, "data-item-index": index,
167
+ // Note, we need to assign the click callback only when it's not disabled
168
+ // otherwise the functions is still triggered
169
+ // biome-ignore lint/a11y/useValidAnchor: due to old structure + backwards compatibility
170
+ onClick: option.disabled ? undefined : handleOptionChange }, { children: [(0, jsx_runtime_1.jsxs)("span", { children: [option.icon && (0, jsx_runtime_1.jsx)("span", Object.assign({ className: 'margin-right-5' }, { children: option.icon })), option.label] }), (0, jsx_runtime_1.jsx)("input", { type: 'hidden', value: option.id })] })) }), option.id));
171
+ })] })));
170
172
  };
171
173
  const filterOptions = (itemDOMValues, filterValue, options) => {
172
174
  const filteredDOMValues = itemDOMValues.filter(item => item.text.toLowerCase().includes(filterValue.toLowerCase()));
@@ -69,6 +69,11 @@ export type MultiselectProps<T extends MultiselectOption> = Omit<WithFeedbackAnd
69
69
  * @default true
70
70
  */
71
71
  autoDropDirection?: boolean;
72
+ /**
73
+ * Shows a loading spinner instead of the menu items if set to true.
74
+ * @default false
75
+ */
76
+ isLoading?: boolean;
72
77
  /**
73
78
  * Defines the size of the select to be rendered.
74
79
  *
@@ -18,7 +18,7 @@ const useMergeRefs_1 = tslib_1.__importDefault(require("../../hooks/useMergeRefs
18
18
  const WithFeedbackAndAddon_1 = tslib_1.__importDefault(require("./WithFeedbackAndAddon"));
19
19
  const DEFAULT_FOCUSED_ITEM_INDEX = -1;
20
20
  const Multiselect = (props) => {
21
- const { name, id = name, options = [], value, onChange = noop_1.default, placeholder, dropup = false, pullRight = false, autoDropDirection = true, bsSize = 'md', disabled = false, tabIndex = 0, hasError = false, useFilter = false, multiline = false, noItemMessage, counterMessage, renderCounterMessage, showSelectedItemIcon = false, showUnselectedItemIcons = false, className, inputAddon, errorMessage, warningMessage, messageWhiteSpace = 'normal' } = props, remainingProps = tslib_1.__rest(props, ["name", "id", "options", "value", "onChange", "placeholder", "dropup", "pullRight", "autoDropDirection", "bsSize", "disabled", "tabIndex", "hasError", "useFilter", "multiline", "noItemMessage", "counterMessage", "renderCounterMessage", "showSelectedItemIcon", "showUnselectedItemIcons", "className", "inputAddon", "errorMessage", "warningMessage", "messageWhiteSpace"]);
21
+ const { name, id = name, options = [], value, onChange = noop_1.default, placeholder, isLoading = false, dropup = false, pullRight = false, autoDropDirection = true, bsSize = 'md', disabled = false, tabIndex = 0, hasError = false, useFilter = false, multiline = false, noItemMessage, counterMessage, renderCounterMessage, showSelectedItemIcon = false, showUnselectedItemIcons = false, className, inputAddon, errorMessage, warningMessage, messageWhiteSpace = 'normal' } = props, remainingProps = tslib_1.__rest(props, ["name", "id", "options", "value", "onChange", "placeholder", "isLoading", "dropup", "pullRight", "autoDropDirection", "bsSize", "disabled", "tabIndex", "hasError", "useFilter", "multiline", "noItemMessage", "counterMessage", "renderCounterMessage", "showSelectedItemIcon", "showUnselectedItemIcons", "className", "inputAddon", "errorMessage", "warningMessage", "messageWhiteSpace"]);
22
22
  const [isOpen, setIsOpen] = (0, react_1.useState)(false);
23
23
  const [selectedItemIds, setSelectedItemIds] = (0, react_1.useState)(value || []);
24
24
  const [isFilterActive, setIsFilterActive] = (0, react_1.useState)(false);
@@ -88,7 +88,7 @@ const Multiselect = (props) => {
88
88
  option.selected = selectedItemIds.indexOf(option.id) !== -1;
89
89
  return option;
90
90
  });
91
- return ((0, jsx_runtime_1.jsx)(BaseSelectDropdown_1.default, { isOpen: isOpen, options: nonSelectedOptions, focusedItemIndex: focusedItemIndex, keyboardUsed: keyboardUsed, updateDOMValues: updateDOMValues, onSelect: onOptionChange, onClose: closeMenu, noItemMessage: noItemMessage, pullRight: pullRight, useActiveClass: true, dropup: dropup, autoDropDirection: autoDropDirection, requestItemDOMValues: requestItemDOMValues }));
91
+ return ((0, jsx_runtime_1.jsx)(BaseSelectDropdown_1.default, { isOpen: isOpen, isLoading: isLoading, options: nonSelectedOptions, focusedItemIndex: focusedItemIndex, keyboardUsed: keyboardUsed, updateDOMValues: updateDOMValues, onSelect: onOptionChange, onClose: closeMenu, noItemMessage: noItemMessage, pullRight: pullRight, useActiveClass: true, dropup: dropup, autoDropDirection: autoDropDirection, requestItemDOMValues: requestItemDOMValues }));
92
92
  };
93
93
  const handleFilterChange = (event) => {
94
94
  event.preventDefault();
@@ -103,6 +103,11 @@ export type SelectProps<T extends SelectOption> = Omit<WithFeedbackAndAddonProps
103
103
  * @default false
104
104
  */
105
105
  useClear?: boolean;
106
+ /**
107
+ * Shows a loading spinner instead of the menu items if set to true.
108
+ * @default false
109
+ */
110
+ isLoading?: boolean;
106
111
  /**
107
112
  * Text that shall be shown when not match was found when filtering.
108
113
  */
@@ -17,7 +17,7 @@ const SelectedOption_1 = tslib_1.__importDefault(require("./SelectedOption"));
17
17
  const WithFeedbackAndAddon_1 = tslib_1.__importDefault(require("./WithFeedbackAndAddon"));
18
18
  const DEFAULT_FOCUSED_ITEM_INDEX = -1;
19
19
  const Select = (props) => {
20
- const { name, id = name, label, options = [], value, onChange = noop_1.default, placeholder, dropup = false, pullRight = false, autoDropDirection = true, bsSize = 'md', disabled = false, tabIndex = 0, hasError = false, useFilter = false, useClear = false, noItemMessage, selectedOptionText, showSelectedItemIcon = false, showUnselectedItemIcons = false, dropdownClassName, btnClassName, className, inputAddon, errorMessage, warningMessage, messageWhiteSpace = 'normal' } = props, remainingProps = tslib_1.__rest(props, ["name", "id", "label", "options", "value", "onChange", "placeholder", "dropup", "pullRight", "autoDropDirection", "bsSize", "disabled", "tabIndex", "hasError", "useFilter", "useClear", "noItemMessage", "selectedOptionText", "showSelectedItemIcon", "showUnselectedItemIcons", "dropdownClassName", "btnClassName", "className", "inputAddon", "errorMessage", "warningMessage", "messageWhiteSpace"]);
20
+ const { name, id = name, label, options = [], value, onChange = noop_1.default, placeholder, isLoading = false, dropup = false, pullRight = false, autoDropDirection = true, bsSize = 'md', disabled = false, tabIndex = 0, hasError = false, useFilter = false, useClear = false, noItemMessage, selectedOptionText, showSelectedItemIcon = false, showUnselectedItemIcons = false, dropdownClassName, btnClassName, className, inputAddon, errorMessage, warningMessage, messageWhiteSpace = 'normal' } = props, remainingProps = tslib_1.__rest(props, ["name", "id", "label", "options", "value", "onChange", "placeholder", "isLoading", "dropup", "pullRight", "autoDropDirection", "bsSize", "disabled", "tabIndex", "hasError", "useFilter", "useClear", "noItemMessage", "selectedOptionText", "showSelectedItemIcon", "showUnselectedItemIcons", "dropdownClassName", "btnClassName", "className", "inputAddon", "errorMessage", "warningMessage", "messageWhiteSpace"]);
21
21
  const [isOpen, setIsOpen] = (0, react_1.useState)(false);
22
22
  const [selectedItem, setSelectedItem] = (0, react_1.useState)(null);
23
23
  const [isFilterActive, setIsFilterActive] = (0, react_1.useState)(false);
@@ -84,7 +84,7 @@ const Select = (props) => {
84
84
  else if (keyboardUsed) {
85
85
  currentFocusedItemIndex = 0;
86
86
  }
87
- return ((0, jsx_runtime_1.jsx)(BaseSelectDropdown_1.default, { isOpen: isOpen, options: filteredOptions, focusedItemIndex: currentFocusedItemIndex, keyboardUsed: keyboardUsed, updateDOMValues: updateDOMValues, onSelect: onOptionChange, onClose: closeMenu, noItemMessage: noItemMessage, pullRight: pullRight, dropup: dropup, autoDropDirection: autoDropDirection, dropdownClassName: dropdownClassName, requestItemDOMValues: requestItemDOMValues }));
87
+ return ((0, jsx_runtime_1.jsx)(BaseSelectDropdown_1.default, { isOpen: isOpen, isLoading: isLoading, options: filteredOptions, focusedItemIndex: currentFocusedItemIndex, keyboardUsed: keyboardUsed, updateDOMValues: updateDOMValues, onSelect: onOptionChange, onClose: closeMenu, noItemMessage: noItemMessage, pullRight: pullRight, dropup: dropup, autoDropDirection: autoDropDirection, dropdownClassName: dropdownClassName, requestItemDOMValues: requestItemDOMValues }));
88
88
  };
89
89
  const handleFilterChange = (event) => {
90
90
  event.preventDefault();
@@ -1,4 +1,4 @@
1
- import { type PropsWithChildren } from 'react';
1
+ import React from 'react';
2
2
  import { type CurrentColor } from '../../utils/currentColors';
3
3
  export type SwitchProps = {
4
4
  /**
@@ -46,9 +46,10 @@ export type SwitchProps = {
46
46
  */
47
47
  labelPosition?: 'left' | 'right';
48
48
  };
49
- declare const Switch: {
50
- (props: PropsWithChildren<SwitchProps>): import("react/jsx-runtime").JSX.Element;
51
- LABEL_POSITION_LEFT: "left";
52
- LABEL_POSITION_RIGHT: "right";
49
+ declare const Switch: React.ForwardRefExoticComponent<SwitchProps & {
50
+ children?: React.ReactNode;
51
+ } & React.RefAttributes<HTMLDivElement>> & {
52
+ LABEL_POSITION_LEFT: 'left';
53
+ LABEL_POSITION_RIGHT: 'right';
53
54
  };
54
55
  export default Switch;
@@ -3,12 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  // @ts-ignore-next-line importsNotUsedAsValues
6
- require("react");
6
+ const react_1 = require("react");
7
7
  const classnames_1 = tslib_1.__importDefault(require("classnames"));
8
8
  const noop_1 = tslib_1.__importDefault(require("lodash/fp/noop"));
9
9
  const currentColors_1 = require("../../utils/currentColors");
10
- const Switch = (props) => {
11
- const { keyName, checked = false, enabledText, minWidth = 40, disabled = false, color = 'primary', disabledText, children, labelPosition = !!children ? 'right' : undefined, onChange = noop_1.default } = props, remainingProps = tslib_1.__rest(props, ["keyName", "checked", "enabledText", "minWidth", "disabled", "color", "disabledText", "children", "labelPosition", "onChange"]);
10
+ const Switch = (0, react_1.forwardRef)((props, ref) => {
11
+ const { keyName, checked = false, enabledText, minWidth = 40, disabled = false, color = 'primary', disabledText, children, labelPosition = children ? 'right' : undefined, onChange = noop_1.default } = props, remainingProps = tslib_1.__rest(props, ["keyName", "checked", "enabledText", "minWidth", "disabled", "color", "disabledText", "children", "labelPosition", "onChange"]);
12
12
  const handleChange = (event) => {
13
13
  onChange(event.target.checked);
14
14
  };
@@ -19,8 +19,8 @@ const Switch = (props) => {
19
19
  // !hasMultipleText && !hasSingleText && 'width-40'
20
20
  );
21
21
  const switchBackgroundColor = (0, currentColors_1.getCurrentBackgroundColor)(color);
22
- return ((0, jsx_runtime_1.jsx)("div", Object.assign({}, remainingProps, { className: 'uikit-switch' }, { children: (0, jsx_runtime_1.jsxs)("label", Object.assign({ className: switchLabelClasses }, { children: [(0, jsx_runtime_1.jsx)("input", { onChange: handleChange, checked: checked, type: 'checkbox', id: keyName, className: 'switch-input', disabled: disabled }, keyName), (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: switchContentClasses, style: { color: switchBackgroundColor, minWidth } }, { children: [hasMultipleText ? ((0, jsx_runtime_1.jsx)("div", { className: 'switch-text', "data-on": enabledText, "data-off": disabledText })) : (hasSingleText && (0, jsx_runtime_1.jsx)("div", { className: 'switch-text', "data-on": enabledText, "data-off": enabledText })), (0, jsx_runtime_1.jsx)("div", { className: 'switch-handle' })] })), children && children] })) })));
23
- };
22
+ return ((0, jsx_runtime_1.jsx)("div", Object.assign({ ref: ref }, remainingProps, { className: 'uikit-switch' }, { children: (0, jsx_runtime_1.jsxs)("label", Object.assign({ className: switchLabelClasses }, { children: [(0, jsx_runtime_1.jsx)("input", { onChange: handleChange, checked: checked, type: 'checkbox', id: keyName, className: 'switch-input', disabled: disabled }, keyName), (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: switchContentClasses, style: { color: switchBackgroundColor, minWidth } }, { children: [hasMultipleText ? ((0, jsx_runtime_1.jsx)("div", { className: 'switch-text', "data-on": enabledText, "data-off": disabledText })) : (hasSingleText && (0, jsx_runtime_1.jsx)("div", { className: 'switch-text', "data-on": enabledText, "data-off": enabledText })), (0, jsx_runtime_1.jsx)("div", { className: 'switch-handle' })] })), children && children] })) })));
23
+ });
24
24
  Switch.LABEL_POSITION_LEFT = 'left';
25
25
  Switch.LABEL_POSITION_RIGHT = 'right';
26
26
  exports.default = Switch;
@@ -1,4 +1,4 @@
1
- import { type PropsWithChildren } from 'react';
1
+ import React from 'react';
2
2
  export type TagProps = {
3
3
  /**
4
4
  * Defines if the tag is active.
@@ -65,5 +65,5 @@ export type TagProps = {
65
65
  */
66
66
  className?: string;
67
67
  };
68
- declare const Tag: (props: PropsWithChildren<TagProps>) => import("react/jsx-runtime").JSX.Element;
68
+ declare const Tag: React.ForwardRefExoticComponent<Omit<React.PropsWithChildren<TagProps>, "ref"> & React.RefAttributes<HTMLDivElement>>;
69
69
  export default Tag;
@@ -3,12 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  // @ts-ignore-next-line importsNotUsedAsValues
6
- require("react");
6
+ const react_1 = require("react");
7
7
  const classnames_1 = tslib_1.__importDefault(require("classnames"));
8
- const Tag = (props) => {
8
+ const Tag = (0, react_1.forwardRef)((props, ref) => {
9
9
  const { children, icon, active = false, disabled = false, clickable = false, selectable = false, deletable = false, revertable = false, multiline = false, muted = false, round = true, size, className } = props, remainingProps = tslib_1.__rest(props, ["children", "icon", "active", "disabled", "clickable", "selectable", "deletable", "revertable", "multiline", "muted", "round", "size", "className"]);
10
- const tagClasses = (0, classnames_1.default)('tag', size === 'small' && 'tag-small', icon && `rioglyph ${icon}`, active && 'active clickable rioglyph rioglyph-ok', disabled && 'disabled', clickable && 'clickable', selectable && 'selectable clickable rioglyph rioglyph-checkbox', deletable && 'deletable clickable rioglyph rioglyph-remove', revertable && 'revertable clickable rioglyph rioglyph-revert', multiline && 'multiline', muted && 'tag-muted', !round && 'rounded', // sounds wrong, but is right
11
- props.className);
12
- return ((0, jsx_runtime_1.jsx)("div", Object.assign({}, remainingProps, { className: tagClasses }, { children: (0, jsx_runtime_1.jsx)("div", Object.assign({ className: 'tag-inner' }, { children: children })) })));
13
- };
10
+ const tagClasses = (0, classnames_1.default)('tag', size === 'small' && 'tag-small', icon && `rioglyph ${icon}`, active && 'active clickable rioglyph rioglyph-ok', disabled && 'disabled', clickable && 'clickable', selectable && 'selectable clickable rioglyph rioglyph-checkbox', deletable && 'deletable clickable rioglyph rioglyph-remove', revertable && 'revertable clickable rioglyph rioglyph-revert', multiline && 'multiline', muted && 'tag-muted', !round && 'rounded', className);
11
+ return ((0, jsx_runtime_1.jsx)("div", Object.assign({ ref: ref }, remainingProps, { className: tagClasses }, { children: (0, jsx_runtime_1.jsx)("div", Object.assign({ className: 'tag-inner' }, { children: children })) })));
12
+ });
14
13
  exports.default = Tag;
@@ -0,0 +1,2 @@
1
+ declare const useDOMNodeCount: () => number;
2
+ export default useDOMNodeCount;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const react_1 = require("react");
4
+ const useDOMNodeCount = () => {
5
+ const [nodeCount, setNodeCount] = (0, react_1.useState)(0);
6
+ (0, react_1.useEffect)(() => {
7
+ const countNodes = () => {
8
+ const body = document.body;
9
+ if (body) {
10
+ setNodeCount(body.getElementsByTagName('*').length);
11
+ }
12
+ };
13
+ // Initial count
14
+ countNodes();
15
+ // Create a MutationObserver to watch for changes in the DOM
16
+ const observer = new MutationObserver(() => {
17
+ countNodes();
18
+ });
19
+ // Observe the body element for changes in the child list or subtree
20
+ observer.observe(document.body, {
21
+ childList: true,
22
+ subtree: true,
23
+ });
24
+ // Cleanup on unmount
25
+ return () => {
26
+ observer.disconnect();
27
+ };
28
+ }, []);
29
+ return nodeCount;
30
+ };
31
+ exports.default = useDOMNodeCount;
@@ -0,0 +1,5 @@
1
+ declare const useEventListenerCount: () => {
2
+ counts: Record<string, number>;
3
+ total: number;
4
+ };
5
+ export default useEventListenerCount;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const react_1 = require("react");
5
+ const throttle_1 = tslib_1.__importDefault(require("lodash/fp/throttle"));
6
+ const useEventListenerCount = () => {
7
+ const [listenerCounts, setListenerCounts] = (0, react_1.useState)({});
8
+ const [totalCount, setTotalCount] = (0, react_1.useState)(0);
9
+ (0, react_1.useEffect)(() => {
10
+ console.log('init useEventListener interceptor');
11
+ const eventListeners = new Set();
12
+ const originalAddEventListener = EventTarget.prototype.addEventListener;
13
+ const originalRemoveEventListener = EventTarget.prototype.removeEventListener;
14
+ const updateListeners = (0, throttle_1.default)(1000)(() => {
15
+ const counts = Array.from(eventListeners).reduce((acc, { type }) => {
16
+ acc[type] = (acc[type] || 0) + 1;
17
+ return acc;
18
+ }, {});
19
+ setListenerCounts(counts);
20
+ setTotalCount(eventListeners.size);
21
+ });
22
+ EventTarget.prototype.addEventListener = function (type, listener, options) {
23
+ if (listener) {
24
+ eventListeners.add({ type, listener });
25
+ updateListeners();
26
+ }
27
+ originalAddEventListener.call(this, type, listener, options);
28
+ };
29
+ EventTarget.prototype.removeEventListener = function (type, listener, options) {
30
+ eventListeners.forEach(item => {
31
+ if (item.type === type && item.listener === listener) {
32
+ eventListeners.delete(item);
33
+ }
34
+ });
35
+ updateListeners();
36
+ originalRemoveEventListener.call(this, type, listener, options);
37
+ };
38
+ return () => {
39
+ EventTarget.prototype.addEventListener = originalAddEventListener;
40
+ EventTarget.prototype.removeEventListener = originalRemoveEventListener;
41
+ };
42
+ }, []);
43
+ return { counts: listenerCounts, total: totalCount };
44
+ };
45
+ exports.default = useEventListenerCount;
@@ -2,9 +2,12 @@ type KeyboardEventType = 'keyup' | 'keydown' | 'keypress';
2
2
  /**
3
3
  * Custom hook to handle keyboard events.
4
4
  *
5
- * @param callback - The callback function to be executed when a keyboard event occurs.
6
- * @param [eventTypes=['keydown']] - The types of keyboard events to listen for.
7
- * @param [node=document] - The DOM node to attach the event listener to (defaults to document).
5
+ * @param keyOrCallback - Either a key string (e.g., 'Enter') or a callback function.
6
+ * @param callbackOrEventTypes - If the first argument is a key, this should be the callback function.
7
+ * If the first argument is a callback, this is an optional array of event types.
8
+ * @param [eventTypesOrNode=['keydown']] - If the first argument is a key, this should be an array of event types.
9
+ * If the first argument is a callback, this is the node (defaults to document).
10
+ * @param [node=document] - Optional DOM node to attach the event listener to (defaults to document).
8
11
  */
9
- declare const useKey: (callback: (event: KeyboardEvent) => void, eventTypes?: KeyboardEventType[], node?: Document) => void;
12
+ declare const useKey: (keyOrCallback: string | ((event: KeyboardEvent) => void), callbackOrEventTypes?: ((event: KeyboardEvent) => void | KeyboardEventType[]) | undefined, eventTypesOrNode?: KeyboardEventType[] | Document, node?: Document | HTMLElement) => void;
10
13
  export default useKey;
@@ -4,20 +4,48 @@ const react_1 = require("react");
4
4
  /**
5
5
  * Custom hook to handle keyboard events.
6
6
  *
7
- * @param callback - The callback function to be executed when a keyboard event occurs.
8
- * @param [eventTypes=['keydown']] - The types of keyboard events to listen for.
9
- * @param [node=document] - The DOM node to attach the event listener to (defaults to document).
7
+ * @param keyOrCallback - Either a key string (e.g., 'Enter') or a callback function.
8
+ * @param callbackOrEventTypes - If the first argument is a key, this should be the callback function.
9
+ * If the first argument is a callback, this is an optional array of event types.
10
+ * @param [eventTypesOrNode=['keydown']] - If the first argument is a key, this should be an array of event types.
11
+ * If the first argument is a callback, this is the node (defaults to document).
12
+ * @param [node=document] - Optional DOM node to attach the event listener to (defaults to document).
10
13
  */
11
- const useKey = (callback, eventTypes = ['keydown'], node = document) => {
14
+ const useKey = (keyOrCallback, callbackOrEventTypes, eventTypesOrNode = ['keydown'], node = document) => {
15
+ const callbacksRef = (0, react_1.useRef)([]);
12
16
  (0, react_1.useEffect)(() => {
17
+ const isKeyMode = typeof keyOrCallback === 'string';
18
+ const callback = isKeyMode
19
+ ? callbackOrEventTypes
20
+ : keyOrCallback;
21
+ const keyHandler = (event) => {
22
+ if (isKeyMode) {
23
+ if (event.key === keyOrCallback) {
24
+ callback(event);
25
+ }
26
+ }
27
+ else {
28
+ callback(event);
29
+ }
30
+ };
31
+ // Register the keyHandler
32
+ callbacksRef.current.push(keyHandler);
33
+ const genericHandler = (event) => {
34
+ for (const callBecky of callbacksRef.current) {
35
+ callBecky(event);
36
+ }
37
+ };
38
+ const eventTypes = Array.isArray(eventTypesOrNode) ? eventTypesOrNode : ['keydown'];
13
39
  for (const eventType of eventTypes) {
14
- node.addEventListener(eventType, callback);
40
+ node.addEventListener(eventType, genericHandler);
15
41
  }
16
42
  return () => {
17
43
  for (const eventType of eventTypes) {
18
- node.removeEventListener(eventType, callback);
44
+ node.removeEventListener(eventType, genericHandler);
19
45
  }
46
+ // Clean up callback reference
47
+ callbacksRef.current = callbacksRef.current.filter(singleCallback => singleCallback !== keyHandler);
20
48
  };
21
- }, [callback]);
49
+ }, [keyOrCallback, callbackOrEventTypes, eventTypesOrNode, node]);
22
50
  };
23
51
  exports.default = useKey;
@@ -0,0 +1,2 @@
1
+ export { default } from './hooks/useDOMNodeCount';
2
+ export * from './hooks/useDOMNodeCount';
@@ -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 useDOMNodeCount_1 = require("./hooks/useDOMNodeCount");
6
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return tslib_1.__importDefault(useDOMNodeCount_1).default; } });
7
+ tslib_1.__exportStar(require("./hooks/useDOMNodeCount"), exports);