@expofp/ui 3.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -0
- package/dist/Alert/Alert.d.ts +20 -0
- package/dist/Alert/Alert.js +23 -0
- package/dist/Alert/index.d.ts +3 -0
- package/dist/Alert/index.js +1 -0
- package/dist/Autocomplete/Autocomplete.d.ts +21 -0
- package/dist/Autocomplete/Autocomplete.js +183 -0
- package/dist/Autocomplete/index.d.ts +3 -0
- package/dist/Autocomplete/index.js +1 -0
- package/dist/Badge/Badge.d.ts +14 -0
- package/dist/Badge/Badge.js +15 -0
- package/dist/Badge/index.d.ts +3 -0
- package/dist/Badge/index.js +1 -0
- package/dist/Button/Button.d.ts +30 -0
- package/dist/Button/Button.js +41 -0
- package/dist/Button/index.d.ts +3 -0
- package/dist/Button/index.js +1 -0
- package/dist/Checkbox/Checkbox.d.ts +19 -0
- package/dist/Checkbox/Checkbox.js +19 -0
- package/dist/Checkbox/index.d.ts +3 -0
- package/dist/Checkbox/index.js +1 -0
- package/dist/CheckboxButton/CheckboxButton.d.ts +12 -0
- package/dist/CheckboxButton/CheckboxButton.js +19 -0
- package/dist/CheckboxButton/index.d.ts +3 -0
- package/dist/CheckboxButton/index.js +1 -0
- package/dist/DownloadList/DownloadList.d.ts +15 -0
- package/dist/DownloadList/DownloadList.js +9 -0
- package/dist/DownloadList/index.d.ts +3 -0
- package/dist/DownloadList/index.js +2 -0
- package/dist/Draggable/Draggable.d.ts +9 -0
- package/dist/Draggable/Draggable.js +92 -0
- package/dist/Draggable/index.d.ts +3 -0
- package/dist/Draggable/index.js +2 -0
- package/dist/EntityItem/EntityItem.d.ts +46 -0
- package/dist/EntityItem/EntityItem.js +29 -0
- package/dist/EntityItem/index.d.ts +3 -0
- package/dist/EntityItem/index.js +1 -0
- package/dist/EventBadge/EventBadge.d.ts +13 -0
- package/dist/EventBadge/EventBadge.js +10 -0
- package/dist/EventBadge/index.d.ts +3 -0
- package/dist/EventBadge/index.js +1 -0
- package/dist/HeatmapLegend/HeatmapLegend.d.ts +15 -0
- package/dist/HeatmapLegend/HeatmapLegend.js +11 -0
- package/dist/HeatmapLegend/index.d.ts +3 -0
- package/dist/HeatmapLegend/index.js +2 -0
- package/dist/HighlightText/HighlightText.d.ts +7 -0
- package/dist/HighlightText/HighlightText.js +14 -0
- package/dist/HighlightText/index.d.ts +2 -0
- package/dist/HighlightText/index.js +1 -0
- package/dist/LevelBadge/LevelBadge.d.ts +9 -0
- package/dist/LevelBadge/LevelBadge.js +10 -0
- package/dist/LevelBadge/index.d.ts +3 -0
- package/dist/LevelBadge/index.js +2 -0
- package/dist/LevelSelector/LevelSelector.d.ts +19 -0
- package/dist/LevelSelector/LevelSelector.js +91 -0
- package/dist/LevelSelector/index.d.ts +3 -0
- package/dist/LevelSelector/index.js +2 -0
- package/dist/MapControls/MapControls.d.ts +33 -0
- package/dist/MapControls/MapControls.js +38 -0
- package/dist/MapControls/index.d.ts +3 -0
- package/dist/MapControls/index.js +2 -0
- package/dist/MobileToggleButton/MobileToggleButton.d.ts +12 -0
- package/dist/MobileToggleButton/MobileToggleButton.js +8 -0
- package/dist/MobileToggleButton/index.d.ts +3 -0
- package/dist/MobileToggleButton/index.js +1 -0
- package/dist/Modal/Modal.d.ts +34 -0
- package/dist/Modal/Modal.js +98 -0
- package/dist/Modal/index.d.ts +3 -0
- package/dist/Modal/index.js +1 -0
- package/dist/MultiSelectGroups/MultiSelectGroups.d.ts +37 -0
- package/dist/MultiSelectGroups/MultiSelectGroups.js +80 -0
- package/dist/MultiSelectGroups/index.d.ts +3 -0
- package/dist/MultiSelectGroups/index.js +1 -0
- package/dist/OverlayGrip/OverlayGrip.d.ts +11 -0
- package/dist/OverlayGrip/OverlayGrip.js +8 -0
- package/dist/OverlayGrip/index.d.ts +3 -0
- package/dist/OverlayGrip/index.js +2 -0
- package/dist/PermissionNotice/PermissionNotice.d.ts +16 -0
- package/dist/PermissionNotice/PermissionNotice.js +11 -0
- package/dist/PermissionNotice/index.d.ts +3 -0
- package/dist/PermissionNotice/index.js +2 -0
- package/dist/Radio/Radio.d.ts +15 -0
- package/dist/Radio/Radio.js +13 -0
- package/dist/Radio/index.d.ts +3 -0
- package/dist/Radio/index.js +1 -0
- package/dist/RebookingNotes/RebookingNotes.d.ts +11 -0
- package/dist/RebookingNotes/RebookingNotes.js +18 -0
- package/dist/RebookingNotes/index.d.ts +3 -0
- package/dist/RebookingNotes/index.js +1 -0
- package/dist/RebookingRadioGroup/RebookingRadioGroup.d.ts +17 -0
- package/dist/RebookingRadioGroup/RebookingRadioGroup.js +13 -0
- package/dist/RebookingRadioGroup/index.d.ts +3 -0
- package/dist/RebookingRadioGroup/index.js +1 -0
- package/dist/ScrollableRow/ScrollableRow.d.ts +21 -0
- package/dist/ScrollableRow/ScrollableRow.js +155 -0
- package/dist/ScrollableRow/index.d.ts +3 -0
- package/dist/ScrollableRow/index.js +2 -0
- package/dist/Share/Share.d.ts +22 -0
- package/dist/Share/Share.js +24 -0
- package/dist/Share/index.d.ts +3 -0
- package/dist/Share/index.js +1 -0
- package/dist/ShowMoreButton/ShowMoreButton.d.ts +11 -0
- package/dist/ShowMoreButton/ShowMoreButton.js +7 -0
- package/dist/ShowMoreButton/index.d.ts +3 -0
- package/dist/ShowMoreButton/index.js +1 -0
- package/dist/SidebarActions/SidebarActions.d.ts +26 -0
- package/dist/SidebarActions/SidebarActions.js +32 -0
- package/dist/SidebarActions/index.d.ts +3 -0
- package/dist/SidebarActions/index.js +2 -0
- package/dist/SimpleRow/SimpleRow.d.ts +15 -0
- package/dist/SimpleRow/SimpleRow.js +11 -0
- package/dist/SimpleRow/index.d.ts +3 -0
- package/dist/SimpleRow/index.js +2 -0
- package/dist/Spinner/Spinner.d.ts +9 -0
- package/dist/Spinner/Spinner.js +8 -0
- package/dist/Spinner/index.d.ts +3 -0
- package/dist/Spinner/index.js +1 -0
- package/dist/ToggleButton/ToggleButton.d.ts +17 -0
- package/dist/ToggleButton/ToggleButton.js +8 -0
- package/dist/ToggleButton/index.d.ts +3 -0
- package/dist/ToggleButton/index.js +1 -0
- package/dist/ToggleSwitch/ToggleSwitch.d.ts +12 -0
- package/dist/ToggleSwitch/ToggleSwitch.js +10 -0
- package/dist/ToggleSwitch/index.d.ts +3 -0
- package/dist/ToggleSwitch/index.js +1 -0
- package/dist/TouchHand/TouchHand.d.ts +5 -0
- package/dist/TouchHand/TouchHand.js +7 -0
- package/dist/TouchHand/index.d.ts +2 -0
- package/dist/TouchHand/index.js +1 -0
- package/dist/WayfindingFloorSelector/WayfindingFloorSelector.d.ts +24 -0
- package/dist/WayfindingFloorSelector/WayfindingFloorSelector.js +27 -0
- package/dist/WayfindingFloorSelector/index.d.ts +3 -0
- package/dist/WayfindingFloorSelector/index.js +1 -0
- package/dist/components/Alert/Alert.d.ts +20 -0
- package/dist/components/Alert/Alert.js +23 -0
- package/dist/components/Alert/index.d.ts +3 -0
- package/dist/components/Alert/index.js +1 -0
- package/dist/components/Autocomplete/Autocomplete.d.ts +21 -0
- package/dist/components/Autocomplete/Autocomplete.js +183 -0
- package/dist/components/Autocomplete/index.d.ts +3 -0
- package/dist/components/Autocomplete/index.js +1 -0
- package/dist/components/Badge/Badge.d.ts +14 -0
- package/dist/components/Badge/Badge.js +15 -0
- package/dist/components/Badge/index.d.ts +3 -0
- package/dist/components/Badge/index.js +1 -0
- package/dist/components/Button/Button.d.ts +30 -0
- package/dist/components/Button/Button.js +41 -0
- package/dist/components/Button/index.d.ts +3 -0
- package/dist/components/Button/index.js +1 -0
- package/dist/components/Checkbox/Checkbox.d.ts +19 -0
- package/dist/components/Checkbox/Checkbox.js +19 -0
- package/dist/components/Checkbox/index.d.ts +3 -0
- package/dist/components/Checkbox/index.js +1 -0
- package/dist/components/CheckboxButton/CheckboxButton.d.ts +12 -0
- package/dist/components/CheckboxButton/CheckboxButton.js +19 -0
- package/dist/components/CheckboxButton/index.d.ts +3 -0
- package/dist/components/CheckboxButton/index.js +1 -0
- package/dist/components/DownloadList/DownloadList.d.ts +15 -0
- package/dist/components/DownloadList/DownloadList.js +9 -0
- package/dist/components/DownloadList/index.d.ts +3 -0
- package/dist/components/DownloadList/index.js +2 -0
- package/dist/components/Draggable/Draggable.d.ts +9 -0
- package/dist/components/Draggable/Draggable.js +92 -0
- package/dist/components/Draggable/index.d.ts +3 -0
- package/dist/components/Draggable/index.js +2 -0
- package/dist/components/EntityItem/EntityItem.d.ts +46 -0
- package/dist/components/EntityItem/EntityItem.js +29 -0
- package/dist/components/EntityItem/index.d.ts +3 -0
- package/dist/components/EntityItem/index.js +1 -0
- package/dist/components/EventBadge/EventBadge.d.ts +13 -0
- package/dist/components/EventBadge/EventBadge.js +10 -0
- package/dist/components/EventBadge/index.d.ts +3 -0
- package/dist/components/EventBadge/index.js +1 -0
- package/dist/components/Gallery/Gallery.d.ts +25 -0
- package/dist/components/Gallery/Gallery.js +25 -0
- package/dist/components/Gallery/GalleryBadges/GalleryBadges.d.ts +8 -0
- package/dist/components/Gallery/GalleryBadges/GalleryBadges.js +5 -0
- package/dist/components/Gallery/GalleryControls/GalleryControls.d.ts +11 -0
- package/dist/components/Gallery/GalleryControls/GalleryControls.js +5 -0
- package/dist/components/Gallery/GalleryImg/GalleryImg.d.ts +13 -0
- package/dist/components/Gallery/GalleryImg/GalleryImg.js +37 -0
- package/dist/components/Gallery/GalleryItem/GalleryItem.d.ts +14 -0
- package/dist/components/Gallery/GalleryItem/GalleryItem.js +6 -0
- package/dist/components/Gallery/GalleryModal/GalleryModal.d.ts +18 -0
- package/dist/components/Gallery/GalleryModal/GalleryModal.js +88 -0
- package/dist/components/Gallery/GalleryPreLoader.d.ts +7 -0
- package/dist/components/Gallery/GalleryPreLoader.js +29 -0
- package/dist/components/Gallery/TransformImg/TransformImg.d.ts +10 -0
- package/dist/components/Gallery/TransformImg/TransformImg.js +15 -0
- package/dist/components/Gallery/index.d.ts +3 -0
- package/dist/components/Gallery/index.js +1 -0
- package/dist/components/HeatmapLegend/HeatmapLegend.d.ts +15 -0
- package/dist/components/HeatmapLegend/HeatmapLegend.js +11 -0
- package/dist/components/HeatmapLegend/index.d.ts +3 -0
- package/dist/components/HeatmapLegend/index.js +2 -0
- package/dist/components/HighlightText/HighlightText.d.ts +7 -0
- package/dist/components/HighlightText/HighlightText.js +14 -0
- package/dist/components/HighlightText/index.d.ts +2 -0
- package/dist/components/HighlightText/index.js +1 -0
- package/dist/components/LevelBadge/LevelBadge.d.ts +9 -0
- package/dist/components/LevelBadge/LevelBadge.js +10 -0
- package/dist/components/LevelBadge/index.d.ts +3 -0
- package/dist/components/LevelBadge/index.js +2 -0
- package/dist/components/LevelSelector/LevelSelector.d.ts +19 -0
- package/dist/components/LevelSelector/LevelSelector.js +91 -0
- package/dist/components/LevelSelector/index.d.ts +3 -0
- package/dist/components/LevelSelector/index.js +2 -0
- package/dist/components/MapControls/MapControls.d.ts +33 -0
- package/dist/components/MapControls/MapControls.js +38 -0
- package/dist/components/MapControls/index.d.ts +3 -0
- package/dist/components/MapControls/index.js +2 -0
- package/dist/components/MobileToggleButton/MobileToggleButton.d.ts +12 -0
- package/dist/components/MobileToggleButton/MobileToggleButton.js +8 -0
- package/dist/components/MobileToggleButton/index.d.ts +3 -0
- package/dist/components/MobileToggleButton/index.js +1 -0
- package/dist/components/Modal/Modal.d.ts +34 -0
- package/dist/components/Modal/Modal.js +98 -0
- package/dist/components/Modal/index.d.ts +3 -0
- package/dist/components/Modal/index.js +1 -0
- package/dist/components/MultiSelectGroups/MultiSelectGroups.d.ts +37 -0
- package/dist/components/MultiSelectGroups/MultiSelectGroups.js +80 -0
- package/dist/components/MultiSelectGroups/index.d.ts +3 -0
- package/dist/components/MultiSelectGroups/index.js +1 -0
- package/dist/components/Overlay/Overlay.d.ts +29 -0
- package/dist/components/Overlay/Overlay.js +251 -0
- package/dist/components/Overlay/OverlayScrollContext.d.ts +7 -0
- package/dist/components/Overlay/OverlayScrollContext.js +7 -0
- package/dist/components/Overlay/index.d.ts +4 -0
- package/dist/components/Overlay/index.js +2 -0
- package/dist/components/OverlayGrip/OverlayGrip.d.ts +11 -0
- package/dist/components/OverlayGrip/OverlayGrip.js +8 -0
- package/dist/components/OverlayGrip/index.d.ts +3 -0
- package/dist/components/OverlayGrip/index.js +2 -0
- package/dist/components/PermissionNotice/PermissionNotice.d.ts +16 -0
- package/dist/components/PermissionNotice/PermissionNotice.js +11 -0
- package/dist/components/PermissionNotice/index.d.ts +3 -0
- package/dist/components/PermissionNotice/index.js +2 -0
- package/dist/components/Radio/Radio.d.ts +15 -0
- package/dist/components/Radio/Radio.js +13 -0
- package/dist/components/Radio/index.d.ts +3 -0
- package/dist/components/Radio/index.js +1 -0
- package/dist/components/RebookingNotes/RebookingNotes.d.ts +11 -0
- package/dist/components/RebookingNotes/RebookingNotes.js +18 -0
- package/dist/components/RebookingNotes/index.d.ts +3 -0
- package/dist/components/RebookingNotes/index.js +1 -0
- package/dist/components/RebookingRadioGroup/RebookingRadioGroup.d.ts +17 -0
- package/dist/components/RebookingRadioGroup/RebookingRadioGroup.js +13 -0
- package/dist/components/RebookingRadioGroup/index.d.ts +3 -0
- package/dist/components/RebookingRadioGroup/index.js +1 -0
- package/dist/components/ScrollableRow/ScrollableRow.d.ts +21 -0
- package/dist/components/ScrollableRow/ScrollableRow.js +155 -0
- package/dist/components/ScrollableRow/index.d.ts +3 -0
- package/dist/components/ScrollableRow/index.js +2 -0
- package/dist/components/Share/Share.d.ts +22 -0
- package/dist/components/Share/Share.js +24 -0
- package/dist/components/Share/index.d.ts +3 -0
- package/dist/components/Share/index.js +1 -0
- package/dist/components/ShowMoreButton/ShowMoreButton.d.ts +11 -0
- package/dist/components/ShowMoreButton/ShowMoreButton.js +7 -0
- package/dist/components/ShowMoreButton/index.d.ts +3 -0
- package/dist/components/ShowMoreButton/index.js +1 -0
- package/dist/components/SidebarActions/SidebarActions.d.ts +26 -0
- package/dist/components/SidebarActions/SidebarActions.js +32 -0
- package/dist/components/SidebarActions/index.d.ts +3 -0
- package/dist/components/SidebarActions/index.js +2 -0
- package/dist/components/SimpleRow/SimpleRow.d.ts +15 -0
- package/dist/components/SimpleRow/SimpleRow.js +11 -0
- package/dist/components/SimpleRow/index.d.ts +3 -0
- package/dist/components/SimpleRow/index.js +2 -0
- package/dist/components/Spinner/Spinner.d.ts +9 -0
- package/dist/components/Spinner/Spinner.js +8 -0
- package/dist/components/Spinner/index.d.ts +3 -0
- package/dist/components/Spinner/index.js +1 -0
- package/dist/components/ToggleButton/ToggleButton.d.ts +17 -0
- package/dist/components/ToggleButton/ToggleButton.js +8 -0
- package/dist/components/ToggleButton/index.d.ts +3 -0
- package/dist/components/ToggleButton/index.js +1 -0
- package/dist/components/ToggleSwitch/ToggleSwitch.d.ts +12 -0
- package/dist/components/ToggleSwitch/ToggleSwitch.js +10 -0
- package/dist/components/ToggleSwitch/index.d.ts +3 -0
- package/dist/components/ToggleSwitch/index.js +1 -0
- package/dist/components/TouchHand/TouchHand.d.ts +5 -0
- package/dist/components/TouchHand/TouchHand.js +7 -0
- package/dist/components/TouchHand/index.d.ts +2 -0
- package/dist/components/TouchHand/index.js +1 -0
- package/dist/components/WayfindingFloorSelector/WayfindingFloorSelector.d.ts +24 -0
- package/dist/components/WayfindingFloorSelector/WayfindingFloorSelector.js +27 -0
- package/dist/components/WayfindingFloorSelector/index.d.ts +3 -0
- package/dist/components/WayfindingFloorSelector/index.js +1 -0
- package/dist/index.d.ts +65 -0
- package/dist/index.js +69 -0
- package/dist/shared/debounce.d.ts +2 -0
- package/dist/shared/debounce.js +9 -0
- package/dist/shared/hooks/useDragGesture.d.ts +19 -0
- package/dist/shared/hooks/useDragGesture.js +45 -0
- package/dist/shared/hooks/useOnClickOutside.d.ts +14 -0
- package/dist/shared/hooks/useOnClickOutside.js +43 -0
- package/dist/shared/hooks/useOnEscape.d.ts +14 -0
- package/dist/shared/hooks/useOnEscape.js +31 -0
- package/dist/shared/hooks/useWindowSize.d.ts +5 -0
- package/dist/shared/hooks/useWindowSize.js +40 -0
- package/dist/shared/interactive.d.ts +2 -0
- package/dist/shared/interactive.js +4 -0
- package/package.json +70 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import './Autocomplete.scss';
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
import { useEffect, useId, useMemo, useRef, useState } from 'react';
|
|
5
|
+
import { createPortal } from 'react-dom';
|
|
6
|
+
import useOnClickOutside from '../../shared/hooks/useOnClickOutside';
|
|
7
|
+
const Autocomplete = ({ placeholder, options, value, showClear = false, onChange, renderTarget = document.body, noOptionsLabel, ariaLabel, clearLabel, getOptionKey = (option) => option.value, }) => {
|
|
8
|
+
const container = renderTarget;
|
|
9
|
+
const refAutocomplete = useRef(null);
|
|
10
|
+
const refSearchInput = useRef(null);
|
|
11
|
+
const refOptions = useRef(null);
|
|
12
|
+
const blurTimeoutRef = useRef(null);
|
|
13
|
+
const listboxId = useId();
|
|
14
|
+
const getOptionId = (index) => `${listboxId}-option-${index}`;
|
|
15
|
+
const getOptionLabel = (option) => option.label;
|
|
16
|
+
const isSameOption = (a, b) => getOptionKey(a) === getOptionKey(b);
|
|
17
|
+
const findOptionIndexByValue = (searchValue) => options.findIndex((option) => isSameOption(option, searchValue));
|
|
18
|
+
const findOptionByValue = (searchValue) => options.find((option) => isSameOption(option, searchValue));
|
|
19
|
+
const [searchText, setSearchText] = useState(null);
|
|
20
|
+
const [focusOptionIndex, setFocusOptionIndex] = useState(null);
|
|
21
|
+
const [showOptionsDropdown, setShowOptionsDropdown] = useState(false);
|
|
22
|
+
const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0, width: 0 });
|
|
23
|
+
const activeOption = value ? findOptionByValue(value) : undefined;
|
|
24
|
+
const activeOptionIndex = activeOption ? findOptionIndexByValue(activeOption) : null;
|
|
25
|
+
const displayValue = searchText ?? (activeOption ? getOptionLabel(activeOption) : '');
|
|
26
|
+
const filteredOptions = useMemo(() => {
|
|
27
|
+
if (!searchText)
|
|
28
|
+
return [];
|
|
29
|
+
const lower = searchText.toLowerCase();
|
|
30
|
+
return options.filter((option) => getOptionLabel(option).toLowerCase().includes(lower));
|
|
31
|
+
}, [searchText, options]);
|
|
32
|
+
const updateDropdownPosition = () => {
|
|
33
|
+
if (refAutocomplete.current && showOptionsDropdown) {
|
|
34
|
+
const rect = refAutocomplete.current.getBoundingClientRect();
|
|
35
|
+
setDropdownPosition({
|
|
36
|
+
top: rect.bottom + window.scrollY + 4,
|
|
37
|
+
left: rect.left + window.scrollX,
|
|
38
|
+
width: rect.width,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (!showOptionsDropdown)
|
|
44
|
+
return;
|
|
45
|
+
updateDropdownPosition();
|
|
46
|
+
window.addEventListener('scroll', updateDropdownPosition, true);
|
|
47
|
+
window.addEventListener('resize', updateDropdownPosition);
|
|
48
|
+
return () => {
|
|
49
|
+
window.removeEventListener('scroll', updateDropdownPosition, true);
|
|
50
|
+
window.removeEventListener('resize', updateDropdownPosition);
|
|
51
|
+
};
|
|
52
|
+
}, [showOptionsDropdown]);
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (focusOptionIndex === null || !refOptions.current)
|
|
55
|
+
return;
|
|
56
|
+
const items = refOptions.current.querySelectorAll('li');
|
|
57
|
+
items[focusOptionIndex]?.scrollIntoView({ block: 'nearest' });
|
|
58
|
+
}, [focusOptionIndex]);
|
|
59
|
+
useOnClickOutside([refAutocomplete, refOptions], () => setShowOptionsDropdown(false), showOptionsDropdown);
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
return () => {
|
|
62
|
+
if (blurTimeoutRef.current)
|
|
63
|
+
clearTimeout(blurTimeoutRef.current);
|
|
64
|
+
};
|
|
65
|
+
}, []);
|
|
66
|
+
const updateValue = (newValue) => {
|
|
67
|
+
setSearchText(null);
|
|
68
|
+
onChange?.(newValue);
|
|
69
|
+
};
|
|
70
|
+
const selectOption = (option) => {
|
|
71
|
+
updateValue(option);
|
|
72
|
+
setFocusOptionIndex(null);
|
|
73
|
+
setShowOptionsDropdown(false);
|
|
74
|
+
refSearchInput.current?.blur();
|
|
75
|
+
};
|
|
76
|
+
const clearValue = (setFocus = false) => {
|
|
77
|
+
updateValue(undefined);
|
|
78
|
+
setFocusOptionIndex(null);
|
|
79
|
+
if (setFocus)
|
|
80
|
+
refSearchInput.current?.focus();
|
|
81
|
+
};
|
|
82
|
+
const onFocus = () => {
|
|
83
|
+
setShowOptionsDropdown(true);
|
|
84
|
+
};
|
|
85
|
+
const onBlur = () => {
|
|
86
|
+
if (blurTimeoutRef.current)
|
|
87
|
+
clearTimeout(blurTimeoutRef.current);
|
|
88
|
+
blurTimeoutRef.current = setTimeout(() => {
|
|
89
|
+
setSearchText(null);
|
|
90
|
+
}, 200);
|
|
91
|
+
};
|
|
92
|
+
const handleEnterKey = () => {
|
|
93
|
+
if ((!displayValue && focusOptionIndex === null) || (searchText && focusOptionIndex === null)) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const currentOptions = filteredOptions.length > 0 ? filteredOptions : options;
|
|
97
|
+
if (focusOptionIndex !== null && currentOptions[focusOptionIndex]) {
|
|
98
|
+
const selectedOption = currentOptions[focusOptionIndex];
|
|
99
|
+
updateValue(selectedOption);
|
|
100
|
+
}
|
|
101
|
+
setFocusOptionIndex(null);
|
|
102
|
+
setShowOptionsDropdown(false);
|
|
103
|
+
refSearchInput.current?.blur();
|
|
104
|
+
};
|
|
105
|
+
const handleArrowUp = () => {
|
|
106
|
+
if (!showOptionsDropdown || focusOptionIndex === 0 || focusOptionIndex === null) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
setFocusOptionIndex(focusOptionIndex - 1);
|
|
110
|
+
};
|
|
111
|
+
const handleArrowDown = () => {
|
|
112
|
+
if (!showOptionsDropdown) {
|
|
113
|
+
setFocusOptionIndex(activeOptionIndex ?? 0);
|
|
114
|
+
setShowOptionsDropdown(true);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const currentOptions = filteredOptions.length > 0 ? filteredOptions : options;
|
|
118
|
+
const nextIndex = focusOptionIndex === null ? 0 : focusOptionIndex + 1;
|
|
119
|
+
if (nextIndex < currentOptions.length) {
|
|
120
|
+
setFocusOptionIndex(nextIndex);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
const onKeyDown = (event) => {
|
|
124
|
+
switch (event.key) {
|
|
125
|
+
case 'Enter':
|
|
126
|
+
handleEnterKey();
|
|
127
|
+
break;
|
|
128
|
+
case 'ArrowUp':
|
|
129
|
+
handleArrowUp();
|
|
130
|
+
break;
|
|
131
|
+
case 'ArrowDown':
|
|
132
|
+
handleArrowDown();
|
|
133
|
+
break;
|
|
134
|
+
case 'Delete':
|
|
135
|
+
clearValue(true);
|
|
136
|
+
break;
|
|
137
|
+
case 'Escape':
|
|
138
|
+
if (!searchText) {
|
|
139
|
+
event.preventDefault();
|
|
140
|
+
setShowOptionsDropdown(false);
|
|
141
|
+
refSearchInput.current?.blur();
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
setSearchText(null);
|
|
145
|
+
setFocusOptionIndex(activeOptionIndex);
|
|
146
|
+
}
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
const onInputChange = (event) => {
|
|
151
|
+
setSearchText(event.target.value);
|
|
152
|
+
setShowOptionsDropdown(true);
|
|
153
|
+
setFocusOptionIndex(null);
|
|
154
|
+
};
|
|
155
|
+
const renderOptions = () => {
|
|
156
|
+
const currentOptions = filteredOptions.length > 0 ? filteredOptions : options;
|
|
157
|
+
if (searchText && filteredOptions.length === 0) {
|
|
158
|
+
return _jsx("div", { className: "efp-autocomplete__empty", children: noOptionsLabel });
|
|
159
|
+
}
|
|
160
|
+
return (_jsx("ul", { role: "listbox", id: listboxId, children: currentOptions.map((option, index) => {
|
|
161
|
+
const isFocused = index === focusOptionIndex;
|
|
162
|
+
const isActive = filteredOptions.length === 0 && index === activeOptionIndex;
|
|
163
|
+
const className = isFocused ? 'is-focus' : isActive ? 'is-active' : undefined;
|
|
164
|
+
return (_jsx("li", { id: getOptionId(index), role: "option", "aria-selected": isActive, className: className, onMouseDown: (e) => e.preventDefault(), onClick: () => selectOption(option), children: getOptionLabel(option) }, getOptionKey(option)));
|
|
165
|
+
}) }));
|
|
166
|
+
};
|
|
167
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { ref: refAutocomplete, className: classNames('efp-autocomplete', {
|
|
168
|
+
'is-open': showOptionsDropdown,
|
|
169
|
+
'with-clear': showOptionsDropdown && showClear,
|
|
170
|
+
}), children: _jsxs("div", { className: "efp-autocomplete__inner", children: [_jsx("input", { type: "search", className: "efp-autocomplete__input", role: "combobox", "aria-label": ariaLabel, "aria-autocomplete": "list", "aria-expanded": showOptionsDropdown, "aria-controls": showOptionsDropdown ? listboxId : undefined, "aria-activedescendant": showOptionsDropdown && focusOptionIndex !== null
|
|
171
|
+
? getOptionId(focusOptionIndex)
|
|
172
|
+
: undefined, onChange: onInputChange, onFocus: onFocus, onBlur: onBlur, onKeyDown: onKeyDown, value: displayValue, placeholder: placeholder, ref: refSearchInput }), showClear && showOptionsDropdown && displayValue && (_jsx("button", { type: "button", className: "efp-autocomplete__clear", "aria-label": clearLabel, onMouseDown: (e) => {
|
|
173
|
+
e.preventDefault();
|
|
174
|
+
clearValue(true);
|
|
175
|
+
} }))] }) }), showOptionsDropdown &&
|
|
176
|
+
container &&
|
|
177
|
+
createPortal(_jsx("div", { ref: refOptions, className: "efp-autocomplete-options", style: {
|
|
178
|
+
top: `${dropdownPosition.top}px`,
|
|
179
|
+
left: `${dropdownPosition.left}px`,
|
|
180
|
+
width: `${dropdownPosition.width}px`,
|
|
181
|
+
}, children: _jsx("div", { className: "efp-autocomplete-options__scroll", children: renderOptions() }) }), container)] }));
|
|
182
|
+
};
|
|
183
|
+
export default Autocomplete;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './Autocomplete';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import './Badge.scss';
|
|
2
|
+
import React, { type ReactNode } from 'react';
|
|
3
|
+
export type BadgeVariant = 'primary' | 'primary-light' | 'lightgray' | 'gray' | 'ghost' | 'orange' | 'location';
|
|
4
|
+
export interface BadgeProps {
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
variant?: BadgeVariant;
|
|
7
|
+
size?: 'xs' | 'md' | 'lg';
|
|
8
|
+
noMargins?: boolean;
|
|
9
|
+
rounded?: boolean;
|
|
10
|
+
inline?: boolean;
|
|
11
|
+
}
|
|
12
|
+
declare const Badge: ({ children, variant, size, noMargins, rounded, inline, }: BadgeProps) => React.JSX.Element;
|
|
13
|
+
export default Badge;
|
|
14
|
+
//# sourceMappingURL=Badge.d.ts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import './Badge.scss';
|
|
4
|
+
import cn from 'classnames';
|
|
5
|
+
const Badge = ({ children, variant = 'ghost', size = 'lg', noMargins, rounded, inline, }) => {
|
|
6
|
+
return (_jsx("div", { className: cn({
|
|
7
|
+
'efp-badge': true,
|
|
8
|
+
[`efp-badge--${variant}`]: true,
|
|
9
|
+
[`efp-badge--${size}`]: true,
|
|
10
|
+
'is-no-margin': noMargins,
|
|
11
|
+
'is-rounded': rounded,
|
|
12
|
+
'is-inline': inline,
|
|
13
|
+
}), children: children }));
|
|
14
|
+
};
|
|
15
|
+
export default Badge;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './Badge';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import './Button.scss';
|
|
2
|
+
import React, { type ReactNode } from 'react';
|
|
3
|
+
export type ButtonVariant = 'primary' | 'secondary' | 'gray' | 'gray-border' | 'ghost' | 'danger';
|
|
4
|
+
export type ButtonSize = 'sm' | 'md' | 'lg';
|
|
5
|
+
export type ButtonTarget = '_self' | '_blank' | '_parent';
|
|
6
|
+
interface ButtonOwnProps {
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
inline?: boolean;
|
|
9
|
+
text?: string;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
variant?: ButtonVariant;
|
|
12
|
+
size?: ButtonSize;
|
|
13
|
+
target?: ButtonTarget;
|
|
14
|
+
ariaLabel?: string;
|
|
15
|
+
withBadge?: boolean;
|
|
16
|
+
/** Whether the button should have a round/circular shape */
|
|
17
|
+
round?: boolean;
|
|
18
|
+
}
|
|
19
|
+
type ButtonAsButton = ButtonOwnProps & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, keyof ButtonOwnProps> & {
|
|
20
|
+
link?: undefined;
|
|
21
|
+
ref?: React.Ref<HTMLButtonElement>;
|
|
22
|
+
};
|
|
23
|
+
type ButtonAsLink = ButtonOwnProps & Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, keyof ButtonOwnProps> & {
|
|
24
|
+
link: string;
|
|
25
|
+
ref?: React.Ref<HTMLAnchorElement>;
|
|
26
|
+
};
|
|
27
|
+
export type ButtonProps = ButtonAsButton | ButtonAsLink;
|
|
28
|
+
declare const Button: (props: ButtonProps) => React.JSX.Element;
|
|
29
|
+
export default Button;
|
|
30
|
+
//# sourceMappingURL=Button.d.ts.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import './Button.scss';
|
|
3
|
+
import cn from 'classnames';
|
|
4
|
+
// `if (props.link)` alone doesn't narrow the union for TS; this predicate does.
|
|
5
|
+
const isLinkProps = (props) => props.link != null;
|
|
6
|
+
const processLabel = (label) => {
|
|
7
|
+
const parts = label.split(/(#\d+#)/);
|
|
8
|
+
const badgeMatch = /#(\d+)#/.exec(label);
|
|
9
|
+
const badgeValue = badgeMatch ? badgeMatch[1] : null;
|
|
10
|
+
return {
|
|
11
|
+
content: parts.map((part, index) => {
|
|
12
|
+
if (/#\d+#/.exec(part)) {
|
|
13
|
+
return (_jsx("div", { className: "efp-button-badge", children: badgeValue }, index));
|
|
14
|
+
}
|
|
15
|
+
return _jsx("span", { children: part }, index);
|
|
16
|
+
}),
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
const Button = (props) => {
|
|
20
|
+
const { children, inline = false, text, disabled = false, variant = 'primary', size = 'lg', target = '_self', ariaLabel, title, withBadge = false, round, } = props;
|
|
21
|
+
const content = children ?? text;
|
|
22
|
+
const { content: processedContent } = withBadge && typeof content === 'string' ? processLabel(content) : { content };
|
|
23
|
+
const commonClassNames = cn('efp-button', `efp-button--${variant}`, `efp-button--${size}`, {
|
|
24
|
+
'efp-button--inline': inline,
|
|
25
|
+
'is-disabled': disabled,
|
|
26
|
+
'efp-button--round': round,
|
|
27
|
+
}, props.className);
|
|
28
|
+
if (isLinkProps(props)) {
|
|
29
|
+
const { link, className: _className, onClick, ...rest } = props;
|
|
30
|
+
const onKeyDown = (event) => {
|
|
31
|
+
if (disabled || event.key !== ' ')
|
|
32
|
+
return;
|
|
33
|
+
event.preventDefault();
|
|
34
|
+
event.currentTarget.click();
|
|
35
|
+
};
|
|
36
|
+
return (_jsx("a", { ...rest, href: disabled ? undefined : link, className: commonClassNames, target: target, rel: "noopener noreferrer", onClick: disabled ? undefined : onClick, onKeyDown: onKeyDown, "aria-label": ariaLabel || undefined, title: title || ariaLabel || (typeof content === 'string' ? content : undefined), role: "button", "aria-disabled": disabled, tabIndex: disabled ? -1 : 0, children: processedContent }));
|
|
37
|
+
}
|
|
38
|
+
const { className: _className, ...rest } = props;
|
|
39
|
+
return (_jsx("button", { type: "button", ...rest, className: commonClassNames, disabled: disabled, "aria-label": ariaLabel || undefined, title: title || ariaLabel || (typeof content === 'string' ? content : undefined), children: processedContent }));
|
|
40
|
+
};
|
|
41
|
+
export default Button;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './Button';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import './Checkbox.scss';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
interface CheckboxBase {
|
|
4
|
+
name?: string;
|
|
5
|
+
value: boolean;
|
|
6
|
+
indeterminate?: boolean;
|
|
7
|
+
size?: 'sm' | 'md';
|
|
8
|
+
onChange: (value: boolean) => void;
|
|
9
|
+
}
|
|
10
|
+
export type CheckboxProps = (CheckboxBase & {
|
|
11
|
+
label: string;
|
|
12
|
+
ariaLabel?: string;
|
|
13
|
+
}) | (CheckboxBase & {
|
|
14
|
+
label?: undefined;
|
|
15
|
+
ariaLabel: string;
|
|
16
|
+
});
|
|
17
|
+
declare const Checkbox: ({ name, value, label, ariaLabel, size, indeterminate, onChange, }: CheckboxProps) => React.JSX.Element;
|
|
18
|
+
export default Checkbox;
|
|
19
|
+
//# sourceMappingURL=Checkbox.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import './Checkbox.scss';
|
|
4
|
+
import classNames from 'classnames';
|
|
5
|
+
import { useEffect, useId, useRef } from 'react';
|
|
6
|
+
const Checkbox = ({ name, value, label, ariaLabel, size = 'md', indeterminate = false, onChange, }) => {
|
|
7
|
+
const id = useId();
|
|
8
|
+
const checkboxRef = useRef(null);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
if (checkboxRef.current) {
|
|
11
|
+
checkboxRef.current.indeterminate = indeterminate;
|
|
12
|
+
}
|
|
13
|
+
}, [indeterminate]);
|
|
14
|
+
return (_jsxs("div", { className: classNames({
|
|
15
|
+
'efp-checkbox': true,
|
|
16
|
+
[`efp-checkbox--${size}`]: true,
|
|
17
|
+
}), children: [_jsx("input", { ref: checkboxRef, type: "checkbox", id: id, name: name, checked: value, "aria-label": ariaLabel, onChange: () => onChange(!value) }), _jsx("label", { htmlFor: id, children: label })] }));
|
|
18
|
+
};
|
|
19
|
+
export default Checkbox;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './Checkbox';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import './CheckboxButton.scss';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
export interface CheckboxButtonProps {
|
|
4
|
+
checked: boolean;
|
|
5
|
+
label?: string;
|
|
6
|
+
ariaLabel?: string;
|
|
7
|
+
className?: string;
|
|
8
|
+
onClick: () => void;
|
|
9
|
+
}
|
|
10
|
+
declare const CheckboxButton: ({ checked, label, ariaLabel, className, onClick }: CheckboxButtonProps) => React.JSX.Element;
|
|
11
|
+
export default CheckboxButton;
|
|
12
|
+
//# sourceMappingURL=CheckboxButton.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import './CheckboxButton.scss';
|
|
4
|
+
import cn from 'classnames';
|
|
5
|
+
import { useState } from 'react';
|
|
6
|
+
const CheckboxButton = ({ checked, label, ariaLabel, className, onClick }) => {
|
|
7
|
+
const [animateIcon, setAnimateIcon] = useState(false);
|
|
8
|
+
const handleClick = () => {
|
|
9
|
+
setAnimateIcon(true);
|
|
10
|
+
onClick();
|
|
11
|
+
setTimeout(() => {
|
|
12
|
+
setAnimateIcon(false);
|
|
13
|
+
}, 320);
|
|
14
|
+
};
|
|
15
|
+
return (_jsxs("button", { type: "button", role: "checkbox", "aria-checked": checked, "aria-label": ariaLabel ?? (label ? undefined : 'Toggle'), className: cn('efp-checkbox-button', className, { 'efp-checkbox-button--checked': checked }), onClick: handleClick, children: [_jsx("div", { className: cn('efp-checkbox-button__inner', {
|
|
16
|
+
'efp-checkbox-button__inner--animate': animateIcon,
|
|
17
|
+
}) }), label && _jsx("span", { className: "efp-checkbox-button__label", children: label })] }));
|
|
18
|
+
};
|
|
19
|
+
export default CheckboxButton;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './CheckboxButton';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import './DownloadList.scss';
|
|
2
|
+
export interface DownloadItem {
|
|
3
|
+
fileName: string;
|
|
4
|
+
path: string;
|
|
5
|
+
}
|
|
6
|
+
export interface DownloadListProps {
|
|
7
|
+
list: DownloadItem[];
|
|
8
|
+
/** Section heading (e.g. a localized "Read More"). */
|
|
9
|
+
title: string;
|
|
10
|
+
/** Builds the per-item download link accessible name from its file name. */
|
|
11
|
+
downloadLabel: (fileName: string) => string;
|
|
12
|
+
}
|
|
13
|
+
declare function DownloadList({ list, title, downloadLabel }: DownloadListProps): import("react").JSX.Element;
|
|
14
|
+
export default DownloadList;
|
|
15
|
+
//# sourceMappingURL=DownloadList.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import './DownloadList.scss';
|
|
3
|
+
function DownloadListItem({ fileName, path, downloadLabel }) {
|
|
4
|
+
return (_jsxs("a", { className: "efp-download-list__item", href: path, download: true, target: "_blank", rel: "noopener noreferrer", "aria-label": downloadLabel(fileName), children: [_jsx("div", { className: "efp-download-list__item-icon", children: _jsx("i", { className: "icon-file-solid", "aria-hidden": "true" }) }), _jsx("div", { className: "efp-download-list__item-name", children: _jsx("span", { children: fileName }) }), _jsx("div", { className: "efp-download-list__item-download", children: _jsx("i", { className: "icon-download", "aria-hidden": "true" }) })] }));
|
|
5
|
+
}
|
|
6
|
+
function DownloadList({ list, title, downloadLabel }) {
|
|
7
|
+
return (_jsxs("div", { className: "efp-download-list", children: [_jsx("div", { className: "efp-download-list__title font-medium", children: title }), _jsx("ul", { className: "efp-download-list__list", children: list.map((item) => (_jsx("li", { children: _jsx(DownloadListItem, { fileName: item.fileName, path: item.path, downloadLabel: downloadLabel }) }, item.path))) })] }));
|
|
8
|
+
}
|
|
9
|
+
export default DownloadList;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface DraggableProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
className?: string;
|
|
5
|
+
style?: React.CSSProperties;
|
|
6
|
+
}
|
|
7
|
+
declare const Draggable: ({ children, className, style }: DraggableProps) => React.JSX.Element;
|
|
8
|
+
export default Draggable;
|
|
9
|
+
//# sourceMappingURL=Draggable.d.ts.map
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/* eslint-disable @eslint-react/exhaustive-deps */
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
4
|
+
import { isInteractiveTarget } from '../../shared/interactive';
|
|
5
|
+
const Draggable = ({ children, className, style }) => {
|
|
6
|
+
const [position, setPosition] = useState({ x: 0, y: 0 });
|
|
7
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
8
|
+
const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
|
|
9
|
+
const draggableRef = useRef(null);
|
|
10
|
+
const handleMouseDown = (e) => {
|
|
11
|
+
if (isInteractiveTarget(e.target)) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
setIsDragging(true);
|
|
15
|
+
setDragStart({
|
|
16
|
+
x: e.clientX - position.x,
|
|
17
|
+
y: e.clientY - position.y,
|
|
18
|
+
});
|
|
19
|
+
e.preventDefault();
|
|
20
|
+
};
|
|
21
|
+
const handleMouseMove = (e) => {
|
|
22
|
+
if (!isDragging)
|
|
23
|
+
return;
|
|
24
|
+
const newX = e.clientX - dragStart.x;
|
|
25
|
+
const newY = e.clientY - dragStart.y;
|
|
26
|
+
setPosition({ x: newX, y: newY });
|
|
27
|
+
};
|
|
28
|
+
const handleMouseUp = () => {
|
|
29
|
+
endDrag();
|
|
30
|
+
};
|
|
31
|
+
const handleTouchStart = (e) => {
|
|
32
|
+
if (isInteractiveTarget(e.target)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const touch = e.touches[0];
|
|
36
|
+
setIsDragging(true);
|
|
37
|
+
setDragStart({
|
|
38
|
+
x: touch.clientX - position.x,
|
|
39
|
+
y: touch.clientY - position.y,
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
const handleTouchMove = (e) => {
|
|
43
|
+
if (!isDragging)
|
|
44
|
+
return;
|
|
45
|
+
const touch = e.touches[0];
|
|
46
|
+
const newX = touch.clientX - dragStart.x;
|
|
47
|
+
const newY = touch.clientY - dragStart.y;
|
|
48
|
+
setPosition({ x: newX, y: newY });
|
|
49
|
+
};
|
|
50
|
+
const handleTouchEnd = () => {
|
|
51
|
+
endDrag();
|
|
52
|
+
};
|
|
53
|
+
const endDrag = () => {
|
|
54
|
+
if (!draggableRef.current)
|
|
55
|
+
return;
|
|
56
|
+
const rect = draggableRef.current.getBoundingClientRect();
|
|
57
|
+
const viewportWidth = window.innerWidth;
|
|
58
|
+
const viewportHeight = window.innerHeight;
|
|
59
|
+
const limitWidth = rect.width / 4;
|
|
60
|
+
const limitHeight = rect.height / 4;
|
|
61
|
+
const hiddenLeft = Math.max(0, 0 - rect.left);
|
|
62
|
+
const hiddenRight = Math.max(0, rect.right - viewportWidth);
|
|
63
|
+
const hiddenTop = Math.max(0, 0 - rect.top);
|
|
64
|
+
const hiddenBottom = Math.max(0, rect.bottom - viewportHeight);
|
|
65
|
+
const isPartiallyOutX = hiddenLeft > limitWidth || hiddenRight > limitWidth;
|
|
66
|
+
const isPartiallyOutY = hiddenTop > limitHeight || hiddenBottom > limitHeight;
|
|
67
|
+
if (isPartiallyOutX || isPartiallyOutY) {
|
|
68
|
+
setPosition({ x: 0, y: 0 });
|
|
69
|
+
}
|
|
70
|
+
setIsDragging(false);
|
|
71
|
+
};
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if (!isDragging)
|
|
74
|
+
return;
|
|
75
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
76
|
+
document.addEventListener('mouseup', handleMouseUp);
|
|
77
|
+
document.addEventListener('touchmove', handleTouchMove, { passive: false });
|
|
78
|
+
document.addEventListener('touchend', handleTouchEnd);
|
|
79
|
+
return () => {
|
|
80
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
81
|
+
document.removeEventListener('mouseup', handleMouseUp);
|
|
82
|
+
document.removeEventListener('touchmove', handleTouchMove);
|
|
83
|
+
document.removeEventListener('touchend', handleTouchEnd);
|
|
84
|
+
};
|
|
85
|
+
}, [isDragging, dragStart]);
|
|
86
|
+
return (_jsx("div", { ref: draggableRef, className: className, style: {
|
|
87
|
+
...style,
|
|
88
|
+
transform: `translate(${position.x}px, ${position.y}px)`,
|
|
89
|
+
cursor: isDragging ? 'grabbing' : 'grab',
|
|
90
|
+
}, onMouseDown: handleMouseDown, onTouchStart: handleTouchStart, children: children }));
|
|
91
|
+
};
|
|
92
|
+
export default Draggable;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import './EntityItem.scss';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
export type EntityItemAdditionalInfo = {
|
|
4
|
+
type: 'location';
|
|
5
|
+
locationName?: string;
|
|
6
|
+
hall?: string;
|
|
7
|
+
level?: string;
|
|
8
|
+
showLevelLabel?: boolean;
|
|
9
|
+
} | {
|
|
10
|
+
type: 'text';
|
|
11
|
+
text: string;
|
|
12
|
+
};
|
|
13
|
+
export interface EntityItemProps {
|
|
14
|
+
id: string;
|
|
15
|
+
title: string;
|
|
16
|
+
subtitle?: string;
|
|
17
|
+
image?: string;
|
|
18
|
+
icon?: string;
|
|
19
|
+
typeColor?: string;
|
|
20
|
+
iconClassName?: string;
|
|
21
|
+
variant?: 'default' | 'person';
|
|
22
|
+
titleBadge?: string | number;
|
|
23
|
+
datetime?: {
|
|
24
|
+
date?: string;
|
|
25
|
+
time?: string;
|
|
26
|
+
};
|
|
27
|
+
subtitleLabel?: string;
|
|
28
|
+
additionalInfo?: EntityItemAdditionalInfo[];
|
|
29
|
+
bookmarked?: boolean;
|
|
30
|
+
featured?: boolean;
|
|
31
|
+
visited?: boolean;
|
|
32
|
+
current?: boolean;
|
|
33
|
+
heatmapColor?: string;
|
|
34
|
+
accentBorderColor?: string;
|
|
35
|
+
hideUserState?: boolean;
|
|
36
|
+
compactDetails?: boolean;
|
|
37
|
+
secondaryText?: string;
|
|
38
|
+
highlight?: string;
|
|
39
|
+
featuredLabel: string;
|
|
40
|
+
hallLabel: string;
|
|
41
|
+
levelLabel: string;
|
|
42
|
+
onClick?: (id: string) => void;
|
|
43
|
+
}
|
|
44
|
+
declare const EntityItem: ({ id, title, subtitle, image, icon, typeColor, iconClassName, variant, titleBadge, datetime, subtitleLabel, additionalInfo, bookmarked, featured, visited, current, heatmapColor, accentBorderColor, hideUserState, compactDetails, secondaryText, highlight, featuredLabel, hallLabel, levelLabel, onClick, }: EntityItemProps) => React.JSX.Element;
|
|
45
|
+
export default EntityItem;
|
|
46
|
+
//# sourceMappingURL=EntityItem.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import './EntityItem.scss';
|
|
3
|
+
import cn from 'classnames';
|
|
4
|
+
import HighlightText from '../HighlightText';
|
|
5
|
+
const EntityItem = ({ id, title, subtitle, image, icon, typeColor, iconClassName, variant = 'default', titleBadge, datetime, subtitleLabel, additionalInfo = [], bookmarked = false, featured = false, visited, current = false, heatmapColor, accentBorderColor, hideUserState = false, compactDetails, secondaryText, highlight, featuredLabel, hallLabel, levelLabel, onClick, }) => {
|
|
6
|
+
const hasDatetime = !!(datetime?.date || datetime?.time);
|
|
7
|
+
const hasSubtitleRow = hasDatetime || !!subtitleLabel || !!subtitle;
|
|
8
|
+
return (_jsx("div", { role: "button", className: cn('efp-entity-item', {
|
|
9
|
+
'is-featured': featured,
|
|
10
|
+
'is-visited': visited,
|
|
11
|
+
'is-current': current,
|
|
12
|
+
'has-heatmap': !!heatmapColor,
|
|
13
|
+
'has-accent': !!accentBorderColor,
|
|
14
|
+
'is-person': variant === 'person',
|
|
15
|
+
}), "aria-label": title, tabIndex: 0, "aria-current": current ? 'true' : undefined, onClick: () => onClick?.(id), onKeyDown: (e) => {
|
|
16
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
17
|
+
e.preventDefault();
|
|
18
|
+
onClick?.(id);
|
|
19
|
+
}
|
|
20
|
+
}, style: {
|
|
21
|
+
...(typeColor ? { '--item-type-color': typeColor } : {}),
|
|
22
|
+
...(heatmapColor && { '--heatmap-color': heatmapColor }),
|
|
23
|
+
...(accentBorderColor &&
|
|
24
|
+
{ '--accent-border-color': accentBorderColor }),
|
|
25
|
+
}, children: _jsxs("div", { className: "efp-entity-item__body", children: [_jsxs("div", { className: "efp-entity-item__left", children: [_jsx("div", { className: "efp-entity-item__icon", children: icon ? (_jsx("img", { src: icon, alt: title })) : iconClassName ? (_jsx("i", { className: iconClassName, "aria-hidden": "true" })) : null }), !hideUserState && (_jsxs(_Fragment, { children: [visited && (_jsx("div", { className: "efp-entity-item__visited", children: _jsx("i", { className: "icon-checkmark" }) })), bookmarked && (_jsx("i", { className: cn('efp-entity-item__bookmarked', 'icon-bookmark-solid') }))] }))] }), _jsxs("div", { className: "efp-entity-item__right", children: [_jsxs("div", { className: cn('efp-entity-item__content', { 'with-image': image }), children: [_jsxs("div", { className: "efp-entity-item__header", children: [_jsxs("div", { className: "efp-entity-item__title", children: [_jsx(HighlightText, { text: title, highlight: highlight }), secondaryText && (_jsx("div", { className: "efp-entity-item__description", children: _jsx(HighlightText, { text: secondaryText, highlight: highlight }) })), titleBadge !== undefined && _jsx("span", { children: titleBadge })] }), featured && _jsx("div", { className: "efp-entity-item__featured", children: featuredLabel })] }), hasSubtitleRow && (_jsxs("div", { className: "efp-entity-item__subtitle", children: [hasDatetime && (_jsxs("div", { className: "efp-entity-item__datetime", children: [datetime?.date && _jsx("strong", { children: datetime.date }), datetime?.time && _jsx("span", { children: datetime.time })] })), subtitleLabel && _jsx("span", { children: subtitleLabel }), subtitle && _jsx("div", { children: subtitle })] })), !!additionalInfo.length && (_jsx("ul", { className: cn('efp-entity-item__details', {
|
|
26
|
+
'compact-details': compactDetails,
|
|
27
|
+
}), children: additionalInfo.map((info, idx) => (_jsxs("li", { className: "efp-entity-item__details-item", children: [info.type === 'location' && (_jsxs(_Fragment, { children: [info.locationName && (_jsx("div", { className: "efp-entity-item__details-item-booth", children: _jsx(HighlightText, { text: info.locationName, highlight: highlight }) })), info.hall && (_jsxs("div", { children: [hallLabel, "\u00A0", _jsx("span", { children: info.hall })] })), info.level && (_jsxs("div", { children: [info.showLevelLabel && _jsxs("span", { children: [levelLabel, "\u00A0"] }), _jsx("span", { children: info.level })] }))] })), info.type === 'text' && _jsx("span", { children: info.text })] }, idx))) }))] }), image && (_jsx("div", { className: "efp-entity-item__image", children: _jsx("img", { src: image, alt: title }) }))] })] }) }));
|
|
28
|
+
};
|
|
29
|
+
export default EntityItem;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './EntityItem';
|