@expofp/ui 0.0.0-experimental.cf063fc

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 (192) hide show
  1. package/README.md +30 -0
  2. package/dist/components/Alert/Alert.d.ts +20 -0
  3. package/dist/components/Alert/Alert.js +23 -0
  4. package/dist/components/Alert/index.d.ts +3 -0
  5. package/dist/components/Alert/index.js +1 -0
  6. package/dist/components/Autocomplete/Autocomplete.d.ts +28 -0
  7. package/dist/components/Autocomplete/Autocomplete.js +292 -0
  8. package/dist/components/Autocomplete/index.d.ts +3 -0
  9. package/dist/components/Autocomplete/index.js +1 -0
  10. package/dist/components/Badge/Badge.d.ts +14 -0
  11. package/dist/components/Badge/Badge.js +15 -0
  12. package/dist/components/Badge/index.d.ts +3 -0
  13. package/dist/components/Badge/index.js +1 -0
  14. package/dist/components/Button/Button.d.ts +30 -0
  15. package/dist/components/Button/Button.js +41 -0
  16. package/dist/components/Button/index.d.ts +3 -0
  17. package/dist/components/Button/index.js +1 -0
  18. package/dist/components/Checkbox/Checkbox.d.ts +19 -0
  19. package/dist/components/Checkbox/Checkbox.js +19 -0
  20. package/dist/components/Checkbox/index.d.ts +3 -0
  21. package/dist/components/Checkbox/index.js +1 -0
  22. package/dist/components/CheckboxButton/CheckboxButton.d.ts +12 -0
  23. package/dist/components/CheckboxButton/CheckboxButton.js +19 -0
  24. package/dist/components/CheckboxButton/index.d.ts +3 -0
  25. package/dist/components/CheckboxButton/index.js +1 -0
  26. package/dist/components/DownloadList/DownloadList.d.ts +15 -0
  27. package/dist/components/DownloadList/DownloadList.js +9 -0
  28. package/dist/components/DownloadList/index.d.ts +3 -0
  29. package/dist/components/DownloadList/index.js +2 -0
  30. package/dist/components/Draggable/Draggable.d.ts +9 -0
  31. package/dist/components/Draggable/Draggable.js +92 -0
  32. package/dist/components/Draggable/index.d.ts +3 -0
  33. package/dist/components/Draggable/index.js +2 -0
  34. package/dist/components/EntityItem/EntityItem.d.ts +46 -0
  35. package/dist/components/EntityItem/EntityItem.js +29 -0
  36. package/dist/components/EntityItem/index.d.ts +3 -0
  37. package/dist/components/EntityItem/index.js +1 -0
  38. package/dist/components/EventBadge/EventBadge.d.ts +13 -0
  39. package/dist/components/EventBadge/EventBadge.js +10 -0
  40. package/dist/components/EventBadge/index.d.ts +3 -0
  41. package/dist/components/EventBadge/index.js +1 -0
  42. package/dist/components/Gallery/Gallery.d.ts +24 -0
  43. package/dist/components/Gallery/Gallery.js +28 -0
  44. package/dist/components/Gallery/GalleryBadges/GalleryBadges.d.ts +8 -0
  45. package/dist/components/Gallery/GalleryBadges/GalleryBadges.js +5 -0
  46. package/dist/components/Gallery/GalleryControls/GalleryControls.d.ts +11 -0
  47. package/dist/components/Gallery/GalleryControls/GalleryControls.js +5 -0
  48. package/dist/components/Gallery/GalleryImg/GalleryImg.d.ts +13 -0
  49. package/dist/components/Gallery/GalleryImg/GalleryImg.js +37 -0
  50. package/dist/components/Gallery/GalleryItem/GalleryItem.d.ts +14 -0
  51. package/dist/components/Gallery/GalleryItem/GalleryItem.js +6 -0
  52. package/dist/components/Gallery/GalleryModal/GalleryModal.d.ts +20 -0
  53. package/dist/components/Gallery/GalleryModal/GalleryModal.js +90 -0
  54. package/dist/components/Gallery/GalleryPreLoader.d.ts +7 -0
  55. package/dist/components/Gallery/GalleryPreLoader.js +29 -0
  56. package/dist/components/Gallery/TransformImg/TransformImg.d.ts +10 -0
  57. package/dist/components/Gallery/TransformImg/TransformImg.js +15 -0
  58. package/dist/components/Gallery/index.d.ts +4 -0
  59. package/dist/components/Gallery/index.js +1 -0
  60. package/dist/components/Gallery/types.d.ts +6 -0
  61. package/dist/components/Gallery/types.js +1 -0
  62. package/dist/components/HeatmapLegend/HeatmapLegend.d.ts +15 -0
  63. package/dist/components/HeatmapLegend/HeatmapLegend.js +11 -0
  64. package/dist/components/HeatmapLegend/index.d.ts +3 -0
  65. package/dist/components/HeatmapLegend/index.js +2 -0
  66. package/dist/components/HighlightText/HighlightText.d.ts +7 -0
  67. package/dist/components/HighlightText/HighlightText.js +14 -0
  68. package/dist/components/HighlightText/index.d.ts +2 -0
  69. package/dist/components/HighlightText/index.js +1 -0
  70. package/dist/components/LevelBadge/LevelBadge.d.ts +9 -0
  71. package/dist/components/LevelBadge/LevelBadge.js +10 -0
  72. package/dist/components/LevelBadge/index.d.ts +3 -0
  73. package/dist/components/LevelBadge/index.js +2 -0
  74. package/dist/components/LevelSelector/LevelSelector.d.ts +18 -0
  75. package/dist/components/LevelSelector/LevelSelector.js +91 -0
  76. package/dist/components/LevelSelector/index.d.ts +3 -0
  77. package/dist/components/LevelSelector/index.js +2 -0
  78. package/dist/components/MapControls/MapControls.d.ts +33 -0
  79. package/dist/components/MapControls/MapControls.js +38 -0
  80. package/dist/components/MapControls/index.d.ts +3 -0
  81. package/dist/components/MapControls/index.js +2 -0
  82. package/dist/components/MobileToggleButton/MobileToggleButton.d.ts +11 -0
  83. package/dist/components/MobileToggleButton/MobileToggleButton.js +8 -0
  84. package/dist/components/MobileToggleButton/index.d.ts +3 -0
  85. package/dist/components/MobileToggleButton/index.js +1 -0
  86. package/dist/components/Modal/Modal.d.ts +34 -0
  87. package/dist/components/Modal/Modal.js +103 -0
  88. package/dist/components/Modal/index.d.ts +3 -0
  89. package/dist/components/Modal/index.js +1 -0
  90. package/dist/components/MultiSelectGroups/MultiSelectGroups.d.ts +37 -0
  91. package/dist/components/MultiSelectGroups/MultiSelectGroups.js +80 -0
  92. package/dist/components/MultiSelectGroups/index.d.ts +3 -0
  93. package/dist/components/MultiSelectGroups/index.js +1 -0
  94. package/dist/components/Overlay/Overlay.d.ts +30 -0
  95. package/dist/components/Overlay/Overlay.js +250 -0
  96. package/dist/components/Overlay/OverlayHeaderContext.d.ts +7 -0
  97. package/dist/components/Overlay/OverlayHeaderContext.js +7 -0
  98. package/dist/components/Overlay/OverlayKeyboardInsetContext.d.ts +7 -0
  99. package/dist/components/Overlay/OverlayKeyboardInsetContext.js +7 -0
  100. package/dist/components/Overlay/OverlayScrollContext.d.ts +7 -0
  101. package/dist/components/Overlay/OverlayScrollContext.js +7 -0
  102. package/dist/components/Overlay/index.d.ts +5 -0
  103. package/dist/components/Overlay/index.js +3 -0
  104. package/dist/components/OverlayGrip/OverlayGrip.d.ts +11 -0
  105. package/dist/components/OverlayGrip/OverlayGrip.js +8 -0
  106. package/dist/components/OverlayGrip/index.d.ts +3 -0
  107. package/dist/components/OverlayGrip/index.js +2 -0
  108. package/dist/components/PermissionNotice/PermissionNotice.d.ts +16 -0
  109. package/dist/components/PermissionNotice/PermissionNotice.js +11 -0
  110. package/dist/components/PermissionNotice/index.d.ts +3 -0
  111. package/dist/components/PermissionNotice/index.js +2 -0
  112. package/dist/components/PlanSelector/PlanSelector.d.ts +13 -0
  113. package/dist/components/PlanSelector/PlanSelector.js +10 -0
  114. package/dist/components/PlanSelector/index.d.ts +3 -0
  115. package/dist/components/PlanSelector/index.js +2 -0
  116. package/dist/components/Radio/Radio.d.ts +15 -0
  117. package/dist/components/Radio/Radio.js +13 -0
  118. package/dist/components/Radio/index.d.ts +3 -0
  119. package/dist/components/Radio/index.js +1 -0
  120. package/dist/components/RebookingNotes/RebookingNotes.d.ts +11 -0
  121. package/dist/components/RebookingNotes/RebookingNotes.js +18 -0
  122. package/dist/components/RebookingNotes/index.d.ts +3 -0
  123. package/dist/components/RebookingNotes/index.js +1 -0
  124. package/dist/components/RebookingRadioGroup/RebookingRadioGroup.d.ts +17 -0
  125. package/dist/components/RebookingRadioGroup/RebookingRadioGroup.js +13 -0
  126. package/dist/components/RebookingRadioGroup/index.d.ts +3 -0
  127. package/dist/components/RebookingRadioGroup/index.js +1 -0
  128. package/dist/components/ScrollableRow/ScrollableRow.d.ts +21 -0
  129. package/dist/components/ScrollableRow/ScrollableRow.js +155 -0
  130. package/dist/components/ScrollableRow/index.d.ts +3 -0
  131. package/dist/components/ScrollableRow/index.js +2 -0
  132. package/dist/components/Share/Share.d.ts +22 -0
  133. package/dist/components/Share/Share.js +24 -0
  134. package/dist/components/Share/index.d.ts +3 -0
  135. package/dist/components/Share/index.js +1 -0
  136. package/dist/components/ShowMoreButton/ShowMoreButton.d.ts +11 -0
  137. package/dist/components/ShowMoreButton/ShowMoreButton.js +7 -0
  138. package/dist/components/ShowMoreButton/index.d.ts +3 -0
  139. package/dist/components/ShowMoreButton/index.js +1 -0
  140. package/dist/components/SidebarActions/SidebarActions.d.ts +26 -0
  141. package/dist/components/SidebarActions/SidebarActions.js +32 -0
  142. package/dist/components/SidebarActions/index.d.ts +3 -0
  143. package/dist/components/SidebarActions/index.js +2 -0
  144. package/dist/components/SimpleRow/SimpleRow.d.ts +15 -0
  145. package/dist/components/SimpleRow/SimpleRow.js +11 -0
  146. package/dist/components/SimpleRow/index.d.ts +3 -0
  147. package/dist/components/SimpleRow/index.js +2 -0
  148. package/dist/components/Spinner/Spinner.d.ts +9 -0
  149. package/dist/components/Spinner/Spinner.js +8 -0
  150. package/dist/components/Spinner/index.d.ts +3 -0
  151. package/dist/components/Spinner/index.js +1 -0
  152. package/dist/components/ToggleButton/ToggleButton.d.ts +17 -0
  153. package/dist/components/ToggleButton/ToggleButton.js +8 -0
  154. package/dist/components/ToggleButton/index.d.ts +3 -0
  155. package/dist/components/ToggleButton/index.js +1 -0
  156. package/dist/components/ToggleSwitch/ToggleSwitch.d.ts +12 -0
  157. package/dist/components/ToggleSwitch/ToggleSwitch.js +10 -0
  158. package/dist/components/ToggleSwitch/index.d.ts +3 -0
  159. package/dist/components/ToggleSwitch/index.js +1 -0
  160. package/dist/components/TouchHand/TouchHand.d.ts +5 -0
  161. package/dist/components/TouchHand/TouchHand.js +7 -0
  162. package/dist/components/TouchHand/index.d.ts +2 -0
  163. package/dist/components/TouchHand/index.js +1 -0
  164. package/dist/components/VenuePicker/VenuePicker.d.ts +23 -0
  165. package/dist/components/VenuePicker/VenuePicker.js +70 -0
  166. package/dist/components/VenuePicker/index.d.ts +3 -0
  167. package/dist/components/VenuePicker/index.js +2 -0
  168. package/dist/components/WayfindingFloorSelector/WayfindingFloorSelector.d.ts +24 -0
  169. package/dist/components/WayfindingFloorSelector/WayfindingFloorSelector.js +27 -0
  170. package/dist/components/WayfindingFloorSelector/index.d.ts +3 -0
  171. package/dist/components/WayfindingFloorSelector/index.js +1 -0
  172. package/dist/index.d.ts +74 -0
  173. package/dist/index.js +77 -0
  174. package/dist/shared/activeElement.d.ts +7 -0
  175. package/dist/shared/activeElement.js +14 -0
  176. package/dist/shared/debounce.d.ts +2 -0
  177. package/dist/shared/debounce.js +9 -0
  178. package/dist/shared/hooks/useKeyboardInset.d.ts +9 -0
  179. package/dist/shared/hooks/useKeyboardInset.js +84 -0
  180. package/dist/shared/hooks/useOnClickOutside.d.ts +14 -0
  181. package/dist/shared/hooks/useOnClickOutside.js +43 -0
  182. package/dist/shared/hooks/useOnEscape.d.ts +14 -0
  183. package/dist/shared/hooks/useOnEscape.js +31 -0
  184. package/dist/shared/hooks/useSheetDrag.d.ts +28 -0
  185. package/dist/shared/hooks/useSheetDrag.js +274 -0
  186. package/dist/shared/hooks/useWindowSize.d.ts +5 -0
  187. package/dist/shared/hooks/useWindowSize.js +38 -0
  188. package/dist/shared/interactive.d.ts +2 -0
  189. package/dist/shared/interactive.js +4 -0
  190. package/dist/shared/selector-option.d.ts +7 -0
  191. package/dist/shared/selector-option.js +1 -0
  192. package/package.json +73 -0
@@ -0,0 +1,15 @@
1
+ import './HeatmapLegend.scss';
2
+ import React from 'react';
3
+ export interface HeatmapLegendTick {
4
+ value: number;
5
+ color: string;
6
+ }
7
+ export interface HeatmapLegendProps {
8
+ ticks: HeatmapLegendTick[];
9
+ ariaLabel: string;
10
+ className?: string;
11
+ style?: React.CSSProperties;
12
+ }
13
+ declare const HeatmapLegend: ({ ticks, ariaLabel, className, style }: HeatmapLegendProps) => React.JSX.Element | null;
14
+ export default HeatmapLegend;
15
+ //# sourceMappingURL=HeatmapLegend.d.ts.map
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import './HeatmapLegend.scss';
3
+ import classNames from 'classnames';
4
+ const HeatmapLegend = ({ ticks, ariaLabel, className, style }) => {
5
+ if (ticks.length === 0)
6
+ return null;
7
+ const colors = ticks.map((tick) => tick.color);
8
+ const background = colors.length === 1 ? colors[0] : `linear-gradient(to right, ${colors.join(', ')})`;
9
+ return (_jsxs("div", { className: classNames('efp-heatmap-legend', className), style: style, role: "img", "aria-label": ariaLabel, children: [_jsx("div", { className: "efp-heatmap-legend__colors", style: { background }, "aria-hidden": "true" }), _jsx("div", { className: "efp-heatmap-legend__values", children: ticks.map(({ value }, index) => (_jsx("span", { "aria-hidden": "true", children: value }, index))) })] }));
10
+ };
11
+ export default HeatmapLegend;
@@ -0,0 +1,3 @@
1
+ export { default } from './HeatmapLegend';
2
+ export type { HeatmapLegendProps, HeatmapLegendTick } from './HeatmapLegend';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ /* eslint-disable simple-import-sort/exports */
2
+ export { default } from './HeatmapLegend';
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ declare const HighlightText: ({ text, highlight }: {
3
+ text: string;
4
+ highlight?: string;
5
+ }) => React.JSX.Element;
6
+ export default HighlightText;
7
+ //# sourceMappingURL=HighlightText.d.ts.map
@@ -0,0 +1,14 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ const HIGHLIGHT_COLOR = '#FFFF99';
3
+ const HighlightText = ({ text, highlight }) => {
4
+ if (!highlight || !text) {
5
+ return _jsx(_Fragment, { children: text });
6
+ }
7
+ const startIndex = text.toLowerCase().indexOf(highlight.toLowerCase());
8
+ if (startIndex === -1) {
9
+ return _jsx(_Fragment, { children: text });
10
+ }
11
+ const endIndex = startIndex + highlight.length;
12
+ return (_jsxs(_Fragment, { children: [text.slice(0, startIndex), _jsx("mark", { style: { background: `linear-gradient(to top, ${HIGHLIGHT_COLOR}, transparent)` }, children: text.slice(startIndex, endIndex) }), text.slice(endIndex)] }));
13
+ };
14
+ export default HighlightText;
@@ -0,0 +1,2 @@
1
+ export { default } from './HighlightText';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ export { default } from './HighlightText';
@@ -0,0 +1,9 @@
1
+ import './LevelBadge.scss';
2
+ import React from 'react';
3
+ export interface LevelBadgeProps {
4
+ level: string;
5
+ levelLabel: string;
6
+ }
7
+ declare const LevelBadge: ({ level, levelLabel }: LevelBadgeProps) => React.JSX.Element | null;
8
+ export default LevelBadge;
9
+ //# sourceMappingURL=LevelBadge.d.ts.map
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // @ts-nocheck
3
+ import './LevelBadge.scss';
4
+ const isNumeric = (input) => /^\d+$/.test(input);
5
+ const LevelBadge = ({ level, levelLabel }) => {
6
+ if (!level)
7
+ return null;
8
+ return (_jsx("div", { className: "efp-level-badge", children: _jsx("span", { children: isNumeric(level) ? `${levelLabel} ${level}` : level }) }));
9
+ };
10
+ export default LevelBadge;
@@ -0,0 +1,3 @@
1
+ export { default } from './LevelBadge';
2
+ export type { LevelBadgeProps } from './LevelBadge';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ /* eslint-disable simple-import-sort/exports */
2
+ export { default } from './LevelBadge';
@@ -0,0 +1,18 @@
1
+ import './LevelSelector.scss';
2
+ import type { SelectorOption } from '../../shared/selector-option.js';
3
+ /**
4
+ * A floor, as this selector sees one. The same id/label/active/disabled shape
5
+ * every plan-scope selector speaks, so kept as an alias of {@link SelectorOption}
6
+ * rather than a second declaration of it.
7
+ */
8
+ export type LevelSelectorFloor = SelectorOption;
9
+ export interface LevelSelectorProps {
10
+ floors: SelectorOption[];
11
+ layout: 'compact-list' | 'dropdown';
12
+ onSelect: (id: string) => void;
13
+ floorSelectionLabel: string;
14
+ currentFloorLabel: string;
15
+ floorLabel: string;
16
+ }
17
+ export default function LevelSelector({ floors, layout, onSelect, floorSelectionLabel, currentFloorLabel, floorLabel, }: LevelSelectorProps): import("react").JSX.Element | null;
18
+ //# sourceMappingURL=LevelSelector.d.ts.map
@@ -0,0 +1,91 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import './LevelSelector.scss';
3
+ import classNames from 'classnames';
4
+ import { useCallback, useLayoutEffect, useRef, useState } from 'react';
5
+ import useOnClickOutside from '../../shared/hooks/useOnClickOutside';
6
+ import useOnEscape from '../../shared/hooks/useOnEscape';
7
+ export default function LevelSelector({ floors, layout, onSelect, floorSelectionLabel, currentFloorLabel, floorLabel, }) {
8
+ const dropdownRef = useRef(null);
9
+ const triggerRef = useRef(null);
10
+ const itemRefs = useRef(new Map());
11
+ const [isDropdownOpen, setIsDropdownOpen] = useState(false);
12
+ const [menuPosition, setMenuPosition] = useState('down');
13
+ const closeAndRefocus = useCallback(() => {
14
+ setIsDropdownOpen(false);
15
+ triggerRef.current?.focus();
16
+ }, []);
17
+ useOnClickOutside([dropdownRef, triggerRef], () => setIsDropdownOpen(false), isDropdownOpen);
18
+ useOnEscape(closeAndRefocus, isDropdownOpen);
19
+ useLayoutEffect(() => {
20
+ if (isDropdownOpen && triggerRef.current) {
21
+ const buttonRect = triggerRef.current.getBoundingClientRect();
22
+ const windowHeight = window.innerHeight;
23
+ const spaceBelow = windowHeight - buttonRect.bottom;
24
+ const minSpaceRequired = 200;
25
+ setMenuPosition(spaceBelow < minSpaceRequired ? 'up' : 'down');
26
+ }
27
+ }, [isDropdownOpen]);
28
+ const handleFloorSelect = useCallback((floor) => {
29
+ if (floor.disabled)
30
+ return;
31
+ onSelect(floor.id);
32
+ setIsDropdownOpen(false);
33
+ triggerRef.current?.focus();
34
+ }, [onSelect]);
35
+ const focusAdjacentFloor = useCallback((e, floor) => {
36
+ if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp')
37
+ return;
38
+ e.preventDefault();
39
+ const currentIndex = floors.findIndex((f) => f.id === floor.id);
40
+ const direction = e.key === 'ArrowDown' ? 1 : -1;
41
+ let nextIndex = currentIndex + direction;
42
+ while (nextIndex >= 0 && nextIndex < floors.length) {
43
+ if (!floors[nextIndex].disabled) {
44
+ itemRefs.current.get(floors[nextIndex].id)?.focus();
45
+ return;
46
+ }
47
+ nextIndex += direction;
48
+ }
49
+ }, [floors]);
50
+ const handleDropdownItemKeyDown = useCallback((e, floor) => {
51
+ if (e.key === 'Enter' || e.key === ' ') {
52
+ if (floor.disabled)
53
+ return;
54
+ e.preventDefault();
55
+ handleFloorSelect(floor);
56
+ return;
57
+ }
58
+ focusAdjacentFloor(e, floor);
59
+ }, [focusAdjacentFloor, handleFloorSelect]);
60
+ if (floors.length === 0)
61
+ return null;
62
+ const activeFloor = floors.find((floor) => floor.active);
63
+ const tabbableFloor = activeFloor && !activeFloor.disabled ? activeFloor : floors.find((floor) => !floor.disabled);
64
+ if (layout === 'compact-list') {
65
+ // Roving tabindex: only the active floor (or the first enabled one as a
66
+ // fallback) is a tab stop; arrows move focus, Enter/Space select.
67
+ return (_jsx("div", { className: "efp-level-selector efp-level-selector--compact-list", role: "radiogroup", "aria-label": floorSelectionLabel, tabIndex: -1, children: floors.map((floor) => (_jsx("button", { ref: (el) => {
68
+ if (el)
69
+ itemRefs.current.set(floor.id, el);
70
+ else
71
+ itemRefs.current.delete(floor.id);
72
+ }, type: "button", className: classNames('efp-level-selector__item', {
73
+ 'efp-level-selector__item--active': floor.active,
74
+ 'efp-level-selector__item--disabled': floor.disabled,
75
+ }), role: "radio", title: `${floor.active ? currentFloorLabel : floorLabel} ${floor.label}`, "aria-label": `${floor.active ? currentFloorLabel : floorLabel} ${floor.label}`, "aria-checked": floor.active, "aria-disabled": floor.disabled, tabIndex: floor.id === tabbableFloor?.id ? 0 : -1, onClick: () => handleFloorSelect(floor), onKeyDown: (e) => focusAdjacentFloor(e, floor), children: _jsx("span", { dir: "auto", children: floor.label }) }, floor.id))) }));
76
+ }
77
+ return (_jsxs("div", { className: "efp-level-selector efp-level-selector--dropdown", children: [_jsxs("button", { ref: triggerRef, type: "button", className: classNames('efp-level-selector__trigger', {
78
+ 'efp-level-selector__trigger--open': isDropdownOpen,
79
+ }), onClick: () => setIsDropdownOpen(!isDropdownOpen), "aria-haspopup": "listbox", "aria-expanded": isDropdownOpen, "aria-label": `${currentFloorLabel}: ${activeFloor?.label ?? ''}`, children: [_jsxs("div", { className: "efp-level-selector__trigger-text", children: [_jsx("i", { className: "icon-layers", "aria-hidden": "true" }), _jsx("span", { dir: "auto", children: activeFloor?.label ?? '' })] }), _jsx("div", { className: "efp-level-selector__trigger-chevron", children: _jsx("i", { className: "icon-chevron-down", "aria-hidden": "true" }) })] }), isDropdownOpen && (_jsx("div", { ref: dropdownRef, className: classNames('efp-level-selector__dropdown', 'efp-level-selector__dropdown--full', {
80
+ 'efp-level-selector__dropdown--opens-up': menuPosition === 'up',
81
+ 'efp-level-selector__dropdown--opens-down': menuPosition === 'down',
82
+ }), role: "listbox", "aria-label": floorSelectionLabel, children: floors.map((floor) => (_jsxs("div", { ref: (el) => {
83
+ if (el)
84
+ itemRefs.current.set(floor.id, el);
85
+ else
86
+ itemRefs.current.delete(floor.id);
87
+ }, className: classNames('efp-level-selector__dropdown-item', {
88
+ 'efp-level-selector__dropdown-item--active': floor.active,
89
+ 'efp-level-selector__dropdown-item--disabled': floor.disabled,
90
+ }), role: "option", "aria-selected": floor.active, "aria-disabled": floor.disabled, tabIndex: floor.disabled ? -1 : 0, onClick: () => handleFloorSelect(floor), onKeyDown: (e) => handleDropdownItemKeyDown(e, floor), children: [_jsx("span", { className: "efp-level-selector__dropdown-item-icon", children: floor.active && _jsx("i", { className: "icon-checkmark-solid", "aria-hidden": "true" }) }), _jsx("span", { className: "efp-level-selector__dropdown-item-name", dir: "auto", children: floor.label })] }, floor.id))) }))] }));
91
+ }
@@ -0,0 +1,3 @@
1
+ export { default } from './LevelSelector';
2
+ export type { LevelSelectorFloor, LevelSelectorProps } from './LevelSelector';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ /* eslint-disable simple-import-sort/exports */
2
+ export { default } from './LevelSelector';
@@ -0,0 +1,33 @@
1
+ import './MapControls.scss';
2
+ import { type CSSProperties } from 'react';
3
+ export interface MapControlLayersItem {
4
+ id: string;
5
+ name: string;
6
+ }
7
+ export interface MapControlsProps {
8
+ className?: string;
9
+ style?: CSSProperties;
10
+ title: string;
11
+ findLocationLabel: string;
12
+ zoomInLabel: string;
13
+ zoomOutLabel: string;
14
+ viewModeLabel: string;
15
+ fitToScreenLabel: string;
16
+ layersLabel: string;
17
+ showModeSwitch: boolean;
18
+ showFindLocation: boolean;
19
+ isMap3d: boolean;
20
+ defaultLayersOpen?: boolean;
21
+ layersList?: MapControlLayersItem[];
22
+ layersActiveItems?: string[];
23
+ layersWidth?: number;
24
+ onViewModeSwitch: () => void;
25
+ onFindLocation: () => void;
26
+ onZoomIn: () => void;
27
+ onZoomOut: () => void;
28
+ onFitToScreen: () => void;
29
+ onChangeLayers: (value: string) => void;
30
+ }
31
+ declare const MapControls: ({ className, style, title, findLocationLabel, zoomInLabel, zoomOutLabel, viewModeLabel, fitToScreenLabel, layersLabel, isMap3d, showModeSwitch, showFindLocation, defaultLayersOpen, layersList, layersActiveItems, layersWidth, onViewModeSwitch, onFindLocation, onZoomIn, onZoomOut, onFitToScreen, onChangeLayers, }: MapControlsProps) => import("react").JSX.Element;
32
+ export default MapControls;
33
+ //# sourceMappingURL=MapControls.d.ts.map
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import './MapControls.scss';
3
+ import classNames from 'classnames';
4
+ import { useId, useLayoutEffect, useRef, useState } from 'react';
5
+ import useOnClickOutside from '../../shared/hooks/useOnClickOutside';
6
+ import useOnEscape from '../../shared/hooks/useOnEscape';
7
+ const MapControls = ({ className, style, title, findLocationLabel, zoomInLabel, zoomOutLabel, viewModeLabel, fitToScreenLabel, layersLabel, isMap3d, showModeSwitch, showFindLocation, defaultLayersOpen = false, layersList, layersActiveItems = [], layersWidth, onViewModeSwitch, onFindLocation, onZoomIn, onZoomOut, onFitToScreen, onChangeLayers, }) => {
8
+ const refLayersWrapper = useRef(null);
9
+ const refLayersButton = useRef(null);
10
+ const layerIdPrefix = useId();
11
+ const [layersIsOpen, setLayersOpen] = useState(defaultLayersOpen);
12
+ const [menuPosition, setMenuPosition] = useState('down');
13
+ useOnClickOutside(refLayersWrapper, () => setLayersOpen(false), layersIsOpen);
14
+ useOnEscape(() => {
15
+ setLayersOpen(false);
16
+ refLayersButton.current?.focus();
17
+ }, layersIsOpen);
18
+ useLayoutEffect(() => {
19
+ if (layersIsOpen && refLayersWrapper.current) {
20
+ const buttonRect = refLayersWrapper.current.getBoundingClientRect();
21
+ const windowHeight = window.innerHeight;
22
+ const spaceBelow = windowHeight - buttonRect.bottom;
23
+ const minSpaceRequired = 250;
24
+ if (spaceBelow < minSpaceRequired) {
25
+ setMenuPosition('up');
26
+ }
27
+ else {
28
+ setMenuPosition('down');
29
+ }
30
+ }
31
+ }, [layersIsOpen]);
32
+ const handleLayersCheck = (id) => onChangeLayers(id);
33
+ return (_jsxs("div", { className: classNames('efp-map-controls', className), style: style, role: "toolbar", "aria-label": title, children: [showFindLocation && (_jsx("button", { type: "button", className: "efp-map-control", "aria-label": findLocationLabel, title: findLocationLabel, onClick: onFindLocation, children: _jsx("i", { className: "icon-navigation", "aria-hidden": "true" }) })), layersList && (_jsxs("div", { className: "efp-layers-button", ref: refLayersWrapper, children: [_jsx("button", { ref: refLayersButton, type: "button", className: classNames('efp-map-control', { 'efp-map-control--active': layersIsOpen }), "aria-label": layersLabel, title: layersLabel, "aria-haspopup": "true", "aria-expanded": layersIsOpen, onClick: () => setLayersOpen(!layersIsOpen), children: _jsx("i", { className: "icon-layers", "aria-hidden": "true" }) }), layersIsOpen && (_jsx("div", { className: classNames('efp-checked-panel', {
34
+ 'efp-checked-panel--opens-up': menuPosition === 'up',
35
+ 'efp-checked-panel--opens-down': menuPosition === 'down',
36
+ }), style: { minWidth: layersWidth }, children: _jsx("ul", { className: "efp-checked-panel__list", children: layersList.map((item) => (_jsxs("li", { children: [_jsx("input", { type: "checkbox", className: "efp-checked-panel__checkbox", value: item.id, id: `${layerIdPrefix}-${item.id}`, checked: layersActiveItems.includes(item.id), onChange: () => handleLayersCheck(item.id) }), _jsx("label", { className: "efp-checked-panel__label", htmlFor: `${layerIdPrefix}-${item.id}`, children: _jsx("div", { className: "efp-checked-panel__item-name", children: item.name }) })] }, item.id))) }) }))] })), showModeSwitch && (_jsx("button", { type: "button", className: "efp-map-control", "aria-label": viewModeLabel, title: viewModeLabel, onClick: onViewModeSwitch, children: _jsx("i", { className: isMap3d ? 'icon-two-dim' : 'icon-three-dim', "aria-hidden": "true" }) })), _jsxs("div", { className: "efp-map-control-group", children: [_jsx("button", { type: "button", className: "efp-map-control", "aria-label": zoomInLabel, title: zoomInLabel, onClick: onZoomIn, children: _jsx("i", { className: "icon-plus", "aria-hidden": "true" }) }), _jsx("div", { className: "efp-map-control-divider" }), _jsx("button", { type: "button", className: "efp-map-control", "aria-label": zoomOutLabel, title: zoomOutLabel, onClick: onZoomOut, children: _jsx("i", { className: "icon-minus", "aria-hidden": "true" }) })] }), _jsx("button", { type: "button", className: "efp-map-control", "aria-label": fitToScreenLabel, title: fitToScreenLabel, onClick: onFitToScreen, children: _jsx("i", { className: "icon-maximize", "aria-hidden": "true" }) })] }));
37
+ };
38
+ export default MapControls;
@@ -0,0 +1,3 @@
1
+ export { default } from './MapControls';
2
+ export type { MapControlsProps, MapControlLayersItem } from './MapControls';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ /* eslint-disable simple-import-sort/exports */
2
+ export { default } from './MapControls';
@@ -0,0 +1,11 @@
1
+ import './MobileToggleButton.scss';
2
+ export type MobileToggleButtonMode = 'list' | 'map';
3
+ export interface MobileToggleButtonProps {
4
+ mode: MobileToggleButtonMode;
5
+ label: string;
6
+ ariaLabel: string;
7
+ onClick: () => void;
8
+ }
9
+ declare function MobileToggleButton({ mode, label, ariaLabel, onClick }: MobileToggleButtonProps): import("react").JSX.Element;
10
+ export default MobileToggleButton;
11
+ //# sourceMappingURL=MobileToggleButton.d.ts.map
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import './MobileToggleButton.scss';
3
+ import classNames from 'classnames';
4
+ function MobileToggleButton({ mode, label, ariaLabel, onClick }) {
5
+ const isListMode = mode === 'list';
6
+ return (_jsxs("button", { className: classNames('efp-mobile-toggle-button', isListMode ? 'efp-mobile-toggle-button--list' : 'efp-mobile-toggle-button--map'), onClick: onClick, type: "button", "aria-label": ariaLabel, children: [_jsx("i", { className: isListMode ? 'icon-list' : 'icon-map', "aria-hidden": "true" }), _jsx("span", { className: "efp-mobile-toggle-button__text", children: label })] }));
7
+ }
8
+ export default MobileToggleButton;
@@ -0,0 +1,3 @@
1
+ export type { MobileToggleButtonMode, MobileToggleButtonProps } from './MobileToggleButton';
2
+ export { default } from './MobileToggleButton';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ export { default } from './MobileToggleButton';
@@ -0,0 +1,34 @@
1
+ import './Modal.scss';
2
+ import React from 'react';
3
+ import { type ButtonVariant } from '../Button';
4
+ export type ModalVariant = 'default' | 'share' | 'drawer';
5
+ export interface ModalButton {
6
+ label: string;
7
+ variant?: ButtonVariant;
8
+ disabled?: boolean;
9
+ withBadge?: boolean;
10
+ onClick: () => void;
11
+ }
12
+ type ModalFooterButton = Omit<ModalButton, 'withBadge'>;
13
+ type ModalLabel = {
14
+ title: string;
15
+ ariaLabel?: string;
16
+ } | {
17
+ title?: undefined;
18
+ ariaLabel: string;
19
+ };
20
+ export type ModalProps = ModalLabel & {
21
+ open: boolean;
22
+ className?: string;
23
+ variant?: ModalVariant;
24
+ maxWidth?: number;
25
+ children?: React.ReactNode;
26
+ closeLabel: string;
27
+ renderTarget?: HTMLElement | null;
28
+ footerLeft?: ModalFooterButton[];
29
+ footerRight?: ModalButton[];
30
+ onClose: () => void;
31
+ };
32
+ declare const Modal: ({ open, className, variant, title, ariaLabel, maxWidth, children, closeLabel, renderTarget, footerLeft, footerRight, onClose, }: ModalProps) => React.ReactPortal | null;
33
+ export default Modal;
34
+ //# sourceMappingURL=Modal.d.ts.map
@@ -0,0 +1,103 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import './Modal.scss';
3
+ import classNames from 'classnames';
4
+ import { useEffect, useId, useRef, useState } from 'react';
5
+ import { createPortal } from 'react-dom';
6
+ import { getActiveElement } from '../../shared/activeElement';
7
+ import Button from '../Button';
8
+ const MODAL_EXIT_TRANSITION_MS = 200;
9
+ const isElementVisible = (el) => el.getClientRects().length > 0 && getComputedStyle(el).visibility !== 'hidden';
10
+ const Modal = ({ open, className, variant = 'default', title, ariaLabel, maxWidth, children, closeLabel, renderTarget, footerLeft = [], footerRight = [], onClose, }) => {
11
+ const modalRef = useRef(null);
12
+ const previousFocusRef = useRef(null);
13
+ const titleId = useId();
14
+ const [isOpen, setIsOpen] = useState(open);
15
+ const [isVisible, setIsVisible] = useState(open);
16
+ // Focus restore + body scroll lock + enter/exit animation. Driven by `open`
17
+ // and by the portal target, without which nothing is rendered at all.
18
+ useEffect(() => {
19
+ if (!open) {
20
+ const deactivateFrame = requestAnimationFrame(() => setIsOpen(false));
21
+ const unmountTimer = setTimeout(() => setIsVisible(false), MODAL_EXIT_TRANSITION_MS);
22
+ if (previousFocusRef.current?.isConnected)
23
+ previousFocusRef.current.focus();
24
+ previousFocusRef.current = null;
25
+ return () => {
26
+ cancelAnimationFrame(deactivateFrame);
27
+ clearTimeout(unmountTimer);
28
+ };
29
+ }
30
+ if (!renderTarget)
31
+ return;
32
+ previousFocusRef.current ??= getActiveElement(modalRef.current);
33
+ const previousBodyOverflow = document.body.style.overflow;
34
+ document.body.style.overflow = 'hidden';
35
+ let activateFrame = 0;
36
+ const mountFrame = requestAnimationFrame(() => {
37
+ setIsVisible(true);
38
+ activateFrame = requestAnimationFrame(() => setIsOpen(true));
39
+ });
40
+ return () => {
41
+ cancelAnimationFrame(mountFrame);
42
+ cancelAnimationFrame(activateFrame);
43
+ document.body.style.overflow = previousBodyOverflow;
44
+ };
45
+ }, [open, renderTarget]);
46
+ // Keydown handling (Escape + focus trap). Kept separate from the lifecycle
47
+ // effect above so a new `onClose` identity only re-subscribes this listener
48
+ // and never restarts the enter/exit animation or scroll lock.
49
+ useEffect(() => {
50
+ if (!open || !renderTarget)
51
+ return;
52
+ const handleKeyDown = (e) => {
53
+ if (e.key === 'Escape') {
54
+ e.preventDefault();
55
+ e.stopImmediatePropagation();
56
+ onClose();
57
+ return;
58
+ }
59
+ if (e.key !== 'Tab')
60
+ return;
61
+ const container = modalRef.current;
62
+ if (!container)
63
+ return;
64
+ const focusable = Array.from(container.querySelectorAll('a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])')).filter(isElementVisible);
65
+ if (focusable.length === 0) {
66
+ e.preventDefault();
67
+ return;
68
+ }
69
+ const first = focusable[0];
70
+ const last = focusable[focusable.length - 1];
71
+ const active = getActiveElement(container);
72
+ if (e.shiftKey) {
73
+ if (active === first || active === container) {
74
+ e.preventDefault();
75
+ last.focus();
76
+ }
77
+ }
78
+ else if (active === last) {
79
+ e.preventDefault();
80
+ first.focus();
81
+ }
82
+ };
83
+ document.addEventListener('keydown', handleKeyDown);
84
+ return () => document.removeEventListener('keydown', handleKeyDown);
85
+ }, [open, renderTarget, onClose]);
86
+ useEffect(() => {
87
+ if (!isOpen)
88
+ return;
89
+ let inner = 0;
90
+ const outer = requestAnimationFrame(() => {
91
+ inner = requestAnimationFrame(() => modalRef.current?.focus());
92
+ });
93
+ return () => {
94
+ cancelAnimationFrame(outer);
95
+ cancelAnimationFrame(inner);
96
+ };
97
+ }, [isOpen]);
98
+ if (!isVisible || !renderTarget)
99
+ return null;
100
+ const renderButtons = (buttons) => buttons?.map(({ label, onClick, variant = 'primary', disabled, withBadge }, idx) => (_jsx(Button, { onClick: onClick, variant: variant, size: "md", inline: true, disabled: disabled, withBadge: withBadge, children: label }, idx)));
101
+ return createPortal(_jsx("div", { className: classNames('efp-modal', `efp-modal--${variant}`, { 'efp-modal--open': isOpen }, className), role: "dialog", "aria-modal": "true", "aria-labelledby": title ? titleId : undefined, "aria-label": !title ? ariaLabel : undefined, ref: modalRef, tabIndex: -1, onClick: onClose, children: _jsxs("div", { className: "efp-modal__box", style: maxWidth ? { maxWidth: `${maxWidth}px` } : undefined, onClick: (e) => e.stopPropagation(), children: [_jsxs("div", { className: "efp-modal__header", children: [title && (_jsx("div", { className: "efp-modal__title-container", children: _jsx("h2", { className: "efp-modal__title", id: titleId, children: title }) })), _jsx("button", { type: "button", className: "efp-modal__close", onClick: onClose, "aria-label": closeLabel, title: closeLabel, children: _jsx("i", { className: "icon-close", "aria-hidden": "true" }) })] }), _jsx("div", { className: "efp-modal__body", children: children }), (footerLeft.length > 0 || footerRight.length > 0) && (_jsxs("div", { className: "efp-modal__footer", children: [_jsx("div", { className: "efp-modal__footer-left", children: footerLeft.length > 0 && renderButtons(footerLeft) }), footerRight.length > 0 && (_jsx("div", { className: "efp-modal__footer-right", children: renderButtons(footerRight) }))] }))] }) }), renderTarget);
102
+ };
103
+ export default Modal;
@@ -0,0 +1,3 @@
1
+ export type { ModalButton, ModalProps, ModalVariant } from './Modal';
2
+ export { default } from './Modal';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ export { default } from './Modal';
@@ -0,0 +1,37 @@
1
+ import './MultiSelectGroups.scss';
2
+ import React from 'react';
3
+ export interface MultiSelectGroupItem {
4
+ id: number | string;
5
+ name: string;
6
+ count?: number;
7
+ disabled?: boolean;
8
+ countProvider?: () => number;
9
+ }
10
+ export interface MultiSelectGroup {
11
+ groupName: string;
12
+ items: MultiSelectGroupItem[];
13
+ showGroupActions?: boolean;
14
+ customGroupClass?: string;
15
+ fullWidth?: boolean;
16
+ id?: string | number;
17
+ }
18
+ export type MultiSelectVariant = 'default' | 'categories';
19
+ export interface MultiSelectGroupsProps {
20
+ groups: MultiSelectGroup[];
21
+ selectedIds: (number | string)[];
22
+ showItemCounts?: boolean;
23
+ showGroupActions?: boolean;
24
+ variant?: MultiSelectVariant;
25
+ maxItemsVisible?: number;
26
+ selectAllLabel: string;
27
+ clearAllLabel: string;
28
+ selectedLabel: string;
29
+ showMoreLabel: string;
30
+ showLessLabel: string;
31
+ onChange: (selectedIds: (number | string)[]) => void;
32
+ itemCountProvider?: (item: MultiSelectGroupItem) => number;
33
+ customItemRenderer?: (item: MultiSelectGroupItem, isSelected: boolean) => React.ReactNode;
34
+ }
35
+ declare function MultiSelectGroups({ groups, selectedIds, showItemCounts, showGroupActions, variant, maxItemsVisible, selectAllLabel, clearAllLabel, selectedLabel, showMoreLabel, showLessLabel, itemCountProvider, customItemRenderer, onChange, }: MultiSelectGroupsProps): React.JSX.Element | null;
36
+ export default MultiSelectGroups;
37
+ //# sourceMappingURL=MultiSelectGroups.d.ts.map
@@ -0,0 +1,80 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import './MultiSelectGroups.scss';
3
+ import cn from 'classnames';
4
+ import React, { useCallback, useMemo, useState } from 'react';
5
+ import ShowMoreButton from '../ShowMoreButton';
6
+ const GroupItem = React.memo(({ item, isSelected, variant, showCount, count, onClick, customRenderer }) => {
7
+ if (customRenderer) {
8
+ return _jsx(_Fragment, { children: customRenderer(item, isSelected) });
9
+ }
10
+ return (_jsxs("button", { type: "button", className: cn('efp-multi-select-groups__item', {
11
+ 'efp-multi-select-groups__item--selected': isSelected,
12
+ 'efp-multi-select-groups__item--disabled': item.disabled,
13
+ [`efp-multi-select-groups__item--${variant}`]: variant,
14
+ }), onClick: () => !item.disabled && onClick(item.id), disabled: item.disabled, "aria-pressed": isSelected, children: [_jsx("div", { className: "efp-multi-select-groups__item-name", children: item.name }), showCount && count > 0 && (_jsx("span", { className: "efp-multi-select-groups__item-count", children: count }))] }));
15
+ });
16
+ function MultiSelectGroups({ groups = [], selectedIds = [], showItemCounts = true, showGroupActions = true, variant = 'default', maxItemsVisible = 20, selectAllLabel, clearAllLabel, selectedLabel, showMoreLabel, showLessLabel, itemCountProvider, customItemRenderer, onChange, }) {
17
+ const [expandedGroups, setExpandedGroups] = useState(() => new Set());
18
+ const handleItemToggle = useCallback((id) => {
19
+ const newSelected = selectedIds.includes(id)
20
+ ? selectedIds.filter((i) => i !== id)
21
+ : [...selectedIds, id];
22
+ onChange(newSelected);
23
+ }, [selectedIds, onChange]);
24
+ const selectAllInGroup = useCallback((group) => {
25
+ const groupItemIds = group.items
26
+ .filter((item) => item.id && !item.disabled)
27
+ .map((item) => item.id);
28
+ const uniqueNewIds = groupItemIds.filter((id) => !selectedIds.includes(id));
29
+ if (uniqueNewIds.length === 0)
30
+ return;
31
+ onChange([...selectedIds, ...uniqueNewIds]);
32
+ }, [selectedIds, onChange]);
33
+ const clearAllInGroup = useCallback((group) => {
34
+ const groupItemIds = new Set(group.items.map((item) => item.id));
35
+ const newSelected = selectedIds.filter((id) => !groupItemIds.has(id));
36
+ onChange(newSelected);
37
+ }, [selectedIds, onChange]);
38
+ const toggleGroupExpansion = useCallback((groupName) => {
39
+ setExpandedGroups((prev) => {
40
+ const newSet = new Set(prev);
41
+ if (newSet.has(groupName))
42
+ newSet.delete(groupName);
43
+ else
44
+ newSet.add(groupName);
45
+ return newSet;
46
+ });
47
+ }, []);
48
+ const getItemCount = (item) => {
49
+ if (item.count !== undefined)
50
+ return item.count;
51
+ if (item.countProvider)
52
+ return item.countProvider();
53
+ if (itemCountProvider)
54
+ return itemCountProvider(item);
55
+ return 0;
56
+ };
57
+ const selectedSet = useMemo(() => new Set(selectedIds), [selectedIds]);
58
+ if (!Array.isArray(groups) || !groups.length) {
59
+ return null;
60
+ }
61
+ return (_jsx("div", { className: "efp-multi-select-groups", children: _jsx("div", { className: "efp-multi-select-groups__list", children: groups.map((group) => {
62
+ if (!group?.groupName || !Array.isArray(group.items))
63
+ return null;
64
+ const validItems = group.items.filter((i) => i.id);
65
+ const selectedItemsInGroup = validItems.filter((item) => selectedSet.has(item.id));
66
+ const isFull = selectedItemsInGroup.length === validItems.length && validItems.length > 0;
67
+ const isPartial = selectedItemsInGroup.length > 0 && !isFull;
68
+ const isExpanded = expandedGroups.has(group.groupName);
69
+ const visibleItems = isExpanded || validItems.length <= maxItemsVisible
70
+ ? validItems
71
+ : validItems.slice(0, maxItemsVisible);
72
+ const hiddenCount = validItems.length - visibleItems.length;
73
+ const hiddenSelectedCount = hiddenCount > 0
74
+ ? validItems.slice(maxItemsVisible).filter((item) => selectedSet.has(item.id)).length
75
+ : 0;
76
+ return (_jsxs("div", { className: cn('efp-multi-select-groups__group', { 'efp-multi-select-groups__group--full-width': group.fullWidth }, group.customGroupClass), children: [_jsxs("div", { className: "efp-multi-select-groups__group-header", children: [_jsx("div", { className: "efp-multi-select-groups__group-title", children: group.groupName }), showGroupActions && group.showGroupActions !== false && (_jsxs("div", { className: "efp-multi-select-groups__group-actions", children: [!isFull && (_jsx("button", { type: "button", className: "efp-multi-select-groups__action-btn", onClick: () => selectAllInGroup(group), children: selectAllLabel })), (isPartial || isFull) && (_jsx("button", { type: "button", className: "efp-multi-select-groups__action-btn", onClick: () => clearAllInGroup(group), children: clearAllLabel }))] }))] }), _jsx("div", { className: "efp-multi-select-groups__group-items", children: visibleItems.map((item) => (_jsx(GroupItem, { item: item, isSelected: selectedSet.has(item.id), variant: variant, showCount: showItemCounts, count: getItemCount(item), onClick: handleItemToggle, customRenderer: customItemRenderer }, item.id))) }), validItems.length > maxItemsVisible && (_jsx(ShowMoreButton, { className: "efp-multi-select-groups__show-more", expanded: isExpanded, showMoreLabel: showMoreLabel, showLessLabel: showLessLabel, onClick: () => toggleGroupExpansion(group.groupName), suffix: !isExpanded &&
77
+ hiddenSelectedCount > 0 && (_jsxs("span", { className: "efp-multi-select-groups__show-more-badge", children: [hiddenSelectedCount, " ", selectedLabel] })) }))] }, group.groupName));
78
+ }) }) }));
79
+ }
80
+ export default MultiSelectGroups;
@@ -0,0 +1,3 @@
1
+ export type { MultiSelectGroup, MultiSelectGroupItem, MultiSelectGroupsProps, MultiSelectVariant, } from './MultiSelectGroups';
2
+ export { default } from './MultiSelectGroups';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ export { default } from './MultiSelectGroups';