@rio-cloud/rio-uikit 1.7.0 → 1.8.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 +4 -0
- package/SvgImage.d.ts +2 -0
- package/SvgImage.js +2 -0
- package/TableCol.d.ts +2 -0
- package/TableCol.js +2 -0
- package/TableHead.d.ts +2 -0
- package/TableHead.js +2 -0
- package/components/actionBarItem/ActionBarItemIcon.js +1 -1
- package/components/actionBarItem/ActionBarOverlay.js +1 -1
- package/components/applicationHeader/CollapsedNavItem.js +1 -0
- package/components/assetTree/Tree.d.ts +8 -0
- package/components/assetTree/Tree.js +4 -2
- package/components/assetTree/TreeLeaf.js +1 -1
- package/components/assetTree/TreeSearch.js +1 -1
- package/components/assetTree/TreeSummary.js +1 -1
- package/components/assetTree/TypeCounter.d.ts +2 -0
- package/components/assetTree/TypeCounter.js +1 -1
- package/components/autosuggest/AutoSuggest.js +2 -1
- package/components/banner/Banner.d.ts +6 -0
- package/components/banner/Banner.js +33 -8
- package/components/button/ButtonToolbar.d.ts +1 -1
- package/components/button/ButtonToolbar.js +1 -1
- package/components/button/ToggleButton.js +0 -1
- package/components/clearableInput/ClearableInput.d.ts +20 -7
- package/components/clearableInput/ClearableInput.js +68 -8
- package/components/dialog/Dialog.js +1 -1
- package/components/dialog/FrameDialog.js +1 -1
- package/components/dropdown/ButtonDropdown.d.ts +11 -3
- package/components/dropdown/ButtonDropdown.js +79 -64
- package/components/dropdown/DropdownToggleButton.d.ts +7 -4
- package/components/dropdown/DropdownToggleButton.js +11 -3
- package/components/formLabel/FormLabel.js +24 -4
- package/components/listMenu/ListMenu.js +8 -4
- package/components/map/components/Map.js +1 -1
- package/components/map/components/features/basics/InfoBubble.js +1 -1
- package/components/map/components/features/layers/overlayLayers/IncidentsLayer.js +1 -1
- package/components/mapMarker/SingleMapMarker.js +1 -1
- package/components/menuItems/MenuItem.js +1 -1
- package/components/notification/Notification.js +1 -1
- package/components/overlay/OverlayTrigger.js +1 -1
- package/components/selects/BaseSelectDropdown.js +1 -1
- package/components/selects/Multiselect.d.ts +8 -0
- package/components/selects/Multiselect.js +4 -4
- package/components/smoothScrollbars/SmoothScrollbars.js +1 -1
- package/components/svgImage/SvgElement.d.ts +8 -0
- package/components/svgImage/SvgElement.js +11 -0
- package/components/svgImage/SvgImage.d.ts +30 -0
- package/components/svgImage/SvgImage.js +20 -0
- package/components/svgImage/svgConverter.d.ts +17 -0
- package/components/svgImage/svgConverter.js +78 -0
- package/components/svgImage/useSvgLoader.d.ts +9 -0
- package/components/svgImage/useSvgLoader.js +43 -0
- package/components/switch/Switch.d.ts +4 -0
- package/components/switch/Switch.js +5 -6
- package/components/table/TableCardsSorting.d.ts +0 -1
- package/components/table/TableCol.d.ts +18 -0
- package/components/table/TableCol.js +11 -0
- package/components/table/TableHead.d.ts +33 -0
- package/components/table/TableHead.js +11 -0
- package/components/table/TableSettingsDialog.js +1 -1
- package/components/tag/Tag.js +1 -1
- package/components/timepicker/TimePicker.d.ts +1 -2
- package/components/timepicker/TimePicker.js +35 -8
- package/components/virtualList/VirtualList.js +1 -1
- package/hooks/useLocationSuggestions.d.ts +27 -0
- package/hooks/useLocationSuggestions.js +94 -0
- package/hooks/useOnboarding.d.ts +17 -5
- package/hooks/useOnboarding.js +7 -1
- package/hooks/usePostMessage.js +0 -1
- package/hooks/useSearch.d.ts +63 -0
- package/hooks/useSearch.js +73 -0
- package/hooks/useSorting.d.ts +6 -0
- package/hooks/useSorting.js +7 -4
- package/hooks/useTableSelection.d.ts +151 -0
- package/hooks/useTableSelection.js +196 -0
- package/lib/es/SvgImage.d.ts +2 -0
- package/lib/es/SvgImage.js +7 -0
- package/lib/es/TableCol.d.ts +2 -0
- package/lib/es/TableCol.js +7 -0
- package/lib/es/TableHead.d.ts +2 -0
- package/lib/es/TableHead.js +7 -0
- package/lib/es/components/actionBarItem/ActionBarItemIcon.js +1 -1
- package/lib/es/components/actionBarItem/ActionBarOverlay.js +1 -1
- package/lib/es/components/applicationHeader/CollapsedNavItem.js +1 -0
- package/lib/es/components/assetTree/Tree.d.ts +8 -0
- package/lib/es/components/assetTree/Tree.js +4 -2
- package/lib/es/components/assetTree/TreeLeaf.js +1 -1
- package/lib/es/components/assetTree/TreeSearch.js +1 -1
- package/lib/es/components/assetTree/TreeSummary.js +1 -1
- package/lib/es/components/assetTree/TypeCounter.d.ts +2 -0
- package/lib/es/components/assetTree/TypeCounter.js +1 -1
- package/lib/es/components/autosuggest/AutoSuggest.js +2 -1
- package/lib/es/components/banner/Banner.d.ts +6 -0
- package/lib/es/components/banner/Banner.js +31 -6
- package/lib/es/components/button/ButtonToolbar.d.ts +1 -1
- package/lib/es/components/button/ButtonToolbar.js +1 -1
- package/lib/es/components/button/ToggleButton.js +0 -1
- package/lib/es/components/clearableInput/ClearableInput.d.ts +20 -7
- package/lib/es/components/clearableInput/ClearableInput.js +67 -7
- package/lib/es/components/dialog/Dialog.js +1 -1
- package/lib/es/components/dialog/FrameDialog.js +1 -1
- package/lib/es/components/dropdown/ButtonDropdown.d.ts +11 -3
- package/lib/es/components/dropdown/ButtonDropdown.js +79 -64
- package/lib/es/components/dropdown/DropdownToggleButton.d.ts +7 -4
- package/lib/es/components/dropdown/DropdownToggleButton.js +11 -3
- package/lib/es/components/formLabel/FormLabel.js +24 -4
- package/lib/es/components/listMenu/ListMenu.js +7 -3
- package/lib/es/components/map/components/Map.js +1 -1
- package/lib/es/components/map/components/features/basics/InfoBubble.js +1 -1
- package/lib/es/components/map/components/features/layers/overlayLayers/IncidentsLayer.js +1 -1
- package/lib/es/components/mapMarker/SingleMapMarker.js +1 -1
- package/lib/es/components/menuItems/MenuItem.js +1 -1
- package/lib/es/components/notification/Notification.js +1 -1
- package/lib/es/components/overlay/OverlayTrigger.js +1 -1
- package/lib/es/components/selects/BaseSelectDropdown.js +1 -1
- package/lib/es/components/selects/Multiselect.d.ts +8 -0
- package/lib/es/components/selects/Multiselect.js +4 -4
- package/lib/es/components/smoothScrollbars/SmoothScrollbars.js +1 -1
- package/lib/es/components/svgImage/SvgElement.d.ts +8 -0
- package/lib/es/components/svgImage/SvgElement.js +14 -0
- package/lib/es/components/svgImage/SvgImage.d.ts +30 -0
- package/lib/es/components/svgImage/SvgImage.js +25 -0
- package/lib/es/components/svgImage/svgConverter.d.ts +17 -0
- package/lib/es/components/svgImage/svgConverter.js +84 -0
- package/lib/es/components/svgImage/useSvgLoader.d.ts +9 -0
- package/lib/es/components/svgImage/useSvgLoader.js +48 -0
- package/lib/es/components/switch/Switch.d.ts +4 -0
- package/lib/es/components/switch/Switch.js +5 -6
- package/lib/es/components/table/TableCardsSorting.d.ts +0 -1
- package/lib/es/components/table/TableCol.d.ts +18 -0
- package/lib/es/components/table/TableCol.js +13 -0
- package/lib/es/components/table/TableHead.d.ts +33 -0
- package/lib/es/components/table/TableHead.js +14 -0
- package/lib/es/components/table/TableSettingsDialog.js +1 -1
- package/lib/es/components/tag/Tag.js +1 -1
- package/lib/es/components/timepicker/TimePicker.d.ts +1 -2
- package/lib/es/components/timepicker/TimePicker.js +35 -8
- package/lib/es/components/virtualList/VirtualList.js +1 -1
- package/lib/es/hooks/useLocationSuggestions.d.ts +27 -0
- package/lib/es/hooks/useLocationSuggestions.js +97 -0
- package/lib/es/hooks/useOnboarding.d.ts +17 -5
- package/lib/es/hooks/useOnboarding.js +7 -1
- package/lib/es/hooks/usePostMessage.js +0 -1
- package/lib/es/hooks/useSearch.d.ts +63 -0
- package/lib/es/hooks/useSearch.js +75 -0
- package/lib/es/hooks/useSorting.d.ts +6 -0
- package/lib/es/hooks/useSorting.js +7 -4
- package/lib/es/hooks/useTableSelection.d.ts +151 -0
- package/lib/es/hooks/useTableSelection.js +205 -0
- package/lib/es/themes/Volkswagen/components/applicationHeader/VolkswagenApplicationHeader.js +1 -1
- package/lib/es/useLocationSuggestions.d.ts +2 -0
- package/lib/es/useLocationSuggestions.js +7 -0
- package/lib/es/useSearch.d.ts +2 -0
- package/lib/es/useSearch.js +7 -0
- package/lib/es/useTableSelection.d.ts +2 -0
- package/lib/es/useTableSelection.js +7 -0
- package/lib/es/utils/storageUtils.d.ts +2 -2
- package/lib/es/utils/storageUtils.js +2 -0
- package/lib/es/utils/urlFeatureToggles.d.ts +12 -6
- package/lib/es/utils/urlFeatureToggles.js +14 -8
- package/lib/es/utils/useDropDirection.js +1 -0
- package/lib/es/version.json +1 -1
- package/package.json +36 -39
- package/themes/Volkswagen/components/applicationHeader/VolkswagenApplicationHeader.js +1 -1
- package/useLocationSuggestions.d.ts +2 -0
- package/useLocationSuggestions.js +2 -0
- package/useSearch.d.ts +2 -0
- package/useSearch.js +2 -0
- package/useTableSelection.d.ts +2 -0
- package/useTableSelection.js +2 -0
- package/utils/storageUtils.d.ts +2 -2
- package/utils/storageUtils.js +2 -0
- package/utils/urlFeatureToggles.d.ts +12 -6
- package/utils/urlFeatureToggles.js +10 -7
- package/utils/useDropDirection.js +1 -0
- package/version.json +1 -1
|
@@ -25,71 +25,86 @@ const getPlacement = (pullRight, dropup) => {
|
|
|
25
25
|
}
|
|
26
26
|
return 'bottom-start';
|
|
27
27
|
};
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
28
|
+
const createButtonDropdown = () => {
|
|
29
|
+
return forwardRef((props, ref) => {
|
|
30
|
+
const { id = Math.random().toString(36).slice(2, 16), items = [], bsSize = 'md', bsStyle = 'default', variant, disabled = false, iconOnly = false, title, splitButton = false, customDropdown, open, dropup = false, pullRight = false, noCaret = false, onOpen = noop, onClose = noop, onLabelButtonClick = noop, usePortal = false, popperConfig, toggleButtonType = 'button', toggleClassName = '', dropdownClassName, className = '', ...remainingProps } = props;
|
|
31
|
+
const [internalOpen, setInternalOpen] = useState(open);
|
|
32
|
+
const [refDropdownToggle, setRefDropdownToggle] = useState(null);
|
|
33
|
+
const [refDropdownMenu, setRefDropdownMenu] = useState(null);
|
|
34
|
+
const [refSplitButtonToggle, setRefSplitButtonToggle] = useState(null);
|
|
35
|
+
const defaultPopperConfig = {
|
|
36
|
+
placement: getPlacement(pullRight, dropup),
|
|
37
|
+
modifiers: [],
|
|
38
|
+
};
|
|
39
|
+
const popperParentRef = splitButton && pullRight ? refSplitButtonToggle : refDropdownToggle;
|
|
40
|
+
const { styles, attributes } = usePopper(popperParentRef, refDropdownMenu, popperConfig || defaultPopperConfig);
|
|
41
|
+
const isUncontrolled = isNil(open);
|
|
42
|
+
const isOpen = isUncontrolled ? internalOpen : open;
|
|
43
|
+
const wrapperRef = useClickOutside(event => {
|
|
44
|
+
if (usePortal) {
|
|
45
|
+
// In case the dropdown is rendered via portal the clickOutside the toggle button element is
|
|
46
|
+
// triggered since the dropdown is not a child of the wrapper element.
|
|
47
|
+
// In this case we need to check if the event target is inside the dropdown-menu and prevent closing
|
|
48
|
+
// the dropdown
|
|
49
|
+
if (!refDropdownMenu?.contains(event.target)) {
|
|
50
|
+
closeMenu();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
49
54
|
closeMenu();
|
|
50
55
|
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
56
|
+
}, DEFAULT_EVENT_TYPES, Boolean(isOpen) // only listen to clicks outside when the dropdown is open
|
|
57
|
+
);
|
|
58
|
+
const dropdownRoot = getOrCreatePortalRoot();
|
|
59
|
+
const shouldShowCaret = !noCaret && !splitButton && !iconOnly;
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
if (!isUncontrolled) {
|
|
62
|
+
setInternalOpen(open);
|
|
63
|
+
}
|
|
64
|
+
}, [isUncontrolled, open]);
|
|
65
|
+
const toggleOpen = (event) => {
|
|
66
|
+
const isDropdownOpen = isUncontrolled ? internalOpen : open;
|
|
67
|
+
if (isDropdownOpen) {
|
|
68
|
+
closeMenu();
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
openMenu(event);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const openMenu = (event) => {
|
|
75
|
+
if (isUncontrolled) {
|
|
76
|
+
setInternalOpen(true);
|
|
77
|
+
}
|
|
78
|
+
if (event) {
|
|
79
|
+
onOpen(event);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const closeMenu = () => {
|
|
83
|
+
if (isUncontrolled) {
|
|
84
|
+
setInternalOpen(false);
|
|
85
|
+
}
|
|
86
|
+
onClose();
|
|
87
|
+
};
|
|
88
|
+
const handleSplitLabelButtonClick = () => {
|
|
67
89
|
closeMenu();
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
};
|
|
89
|
-
const handleDropdownButtonClick = splitButton ? handleSplitLabelButtonClick : toggleOpen;
|
|
90
|
-
const wrapperClasses = classNames('dropdown', 'btn-group', isOpen && 'open', className);
|
|
91
|
-
const dropdownClasses = classNames(usePortal && 'dropdown-portal', splitButton && pullRight && 'pull-right', dropdownClassName);
|
|
92
|
-
const dropdownMenu = (_jsx(MenuItemList, { className: dropdownClasses, ref: setRefDropdownMenu, style: styles.popper, ...attributes.popper, children: customDropdown ? customDropdown : _jsx(MenuItems, { items: items, closeMenu: toggleOpen }) }));
|
|
93
|
-
return (_jsxs("div", { ...remainingProps, className: wrapperClasses, ref: wrapperRef, children: [_jsx(DropdownToggleButton, { id: id, splitButton: splitButton, bsStyle: bsStyle, bsSize: bsSize, variant: variant, iconOnly: iconOnly, disabled: disabled, ref: setRefDropdownToggle, onClick: handleDropdownButtonClick, outerRef: ref, className: toggleClassName, children: _jsxs(_Fragment, { children: [title, shouldShowCaret && _jsx(Caret, {})] }) }), splitButton && (_jsx(SplitCaretButton, { id: id, bsStyle: bsStyle, bsSize: bsSize, disabled: disabled, className: toggleClassName, onClick: toggleOpen, ref: setRefSplitButtonToggle })), isOpen && usePortal && ReactDOM.createPortal(dropdownMenu, dropdownRoot), isOpen && !usePortal && dropdownMenu] }));
|
|
94
|
-
});
|
|
90
|
+
onLabelButtonClick();
|
|
91
|
+
};
|
|
92
|
+
const handleSplitCaretButtonClick = (event) => {
|
|
93
|
+
toggleOpen(event);
|
|
94
|
+
};
|
|
95
|
+
const handleDropdownButtonClick = (event) => {
|
|
96
|
+
if (splitButton) {
|
|
97
|
+
handleSplitLabelButtonClick();
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
toggleOpen(event);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
const wrapperClasses = classNames('dropdown', 'btn-group', isOpen && 'open', className);
|
|
104
|
+
const dropdownClasses = classNames(usePortal && 'dropdown-portal', splitButton && pullRight && 'pull-right', dropdownClassName);
|
|
105
|
+
const dropdownMenu = (_jsx(MenuItemList, { className: dropdownClasses, ref: setRefDropdownMenu, style: styles.popper, ...attributes.popper, children: customDropdown ? customDropdown : _jsx(MenuItems, { items: items, closeMenu: toggleOpen }) }));
|
|
106
|
+
return (_jsxs("div", { ...remainingProps, className: wrapperClasses, ref: wrapperRef, children: [_jsx(DropdownToggleButton, { id: id, splitButton: splitButton, bsStyle: bsStyle, bsSize: bsSize, variant: variant, iconOnly: iconOnly, disabled: disabled, ref: setRefDropdownToggle, onClick: handleDropdownButtonClick, outerRef: ref, toggleButtonType: toggleButtonType, className: toggleClassName, children: _jsxs(_Fragment, { children: [title, shouldShowCaret && _jsx(Caret, {})] }) }), splitButton && (_jsx(SplitCaretButton, { id: id, bsStyle: bsStyle, bsSize: bsSize, disabled: disabled, className: toggleClassName, onClick: handleSplitCaretButtonClick, ref: setRefSplitButtonToggle })), isOpen && usePortal && ReactDOM.createPortal(dropdownMenu, dropdownRoot), isOpen && !usePortal && dropdownMenu] }));
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
const ButtonDropdown = createButtonDropdown();
|
|
95
110
|
export default ButtonDropdown;
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { type HTMLProps, type PropsWithChildren } from 'react';
|
|
2
2
|
import { type BUTTON_VARIANT, type BUTTON_SIZE, type BUTTON_STYLE } from '../button/Button';
|
|
3
|
+
export type DropdownToggleButtonType = 'button' | 'tag' | 'label';
|
|
4
|
+
export type DropdownToggleEvent<T extends DropdownToggleButtonType = 'button'> = T extends 'button' ? React.MouseEvent<HTMLButtonElement> : React.MouseEvent<HTMLDivElement>;
|
|
3
5
|
export type DropdownToggleButtonProps = HTMLProps<HTMLButtonElement> & {
|
|
4
6
|
id?: string;
|
|
5
7
|
disabled?: boolean;
|
|
6
8
|
splitButton?: boolean;
|
|
7
9
|
iconOnly?: boolean;
|
|
8
|
-
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
10
|
+
onClick: (event: React.MouseEvent<HTMLButtonElement | HTMLDivElement>) => void;
|
|
9
11
|
bsSize: BUTTON_SIZE;
|
|
10
12
|
bsStyle: BUTTON_STYLE;
|
|
11
13
|
variant?: BUTTON_VARIANT;
|
|
12
|
-
|
|
14
|
+
toggleButtonType?: DropdownToggleButtonType;
|
|
15
|
+
outerRef?: React.Ref<HTMLButtonElement | HTMLDivElement>;
|
|
13
16
|
className?: string;
|
|
14
17
|
};
|
|
15
|
-
declare const DropdownToggleButton:
|
|
18
|
+
declare const DropdownToggleButton: import("react").ForwardRefExoticComponent<Omit<PropsWithChildren<DropdownToggleButtonProps>, "ref"> & import("react").RefAttributes<HTMLDivElement | HTMLButtonElement>>;
|
|
16
19
|
export default DropdownToggleButton;
|
|
@@ -4,9 +4,17 @@ import classNames from 'classnames';
|
|
|
4
4
|
import Button from '../button/Button';
|
|
5
5
|
import useMergeRefs from '../../hooks/useMergeRefs';
|
|
6
6
|
const DropdownToggleButton = forwardRef((props, ref) => {
|
|
7
|
-
const { id, disabled, bsSize, bsStyle, variant, splitButton = false, onClick, className = '', children, outerRef, ...remainingProps } = props;
|
|
7
|
+
const { id, disabled, bsSize, bsStyle, variant, splitButton = false, onClick, toggleButtonType = 'button', className = '', children, outerRef, iconOnly, ...remainingProps } = props;
|
|
8
8
|
const toggleRef = useMergeRefs(outerRef, ref);
|
|
9
|
-
const
|
|
10
|
-
|
|
9
|
+
const buttonClasses = classNames(!splitButton && 'dropdown-toggle', !splitButton && className);
|
|
10
|
+
const labelClasses = classNames('dropdown-toggle', 'label', `label-${bsStyle}`, 'display-flex align-items-center', 'user-select-none cursor-pointer', disabled && 'pointer-events-none', className);
|
|
11
|
+
const tagClasses = classNames('dropdown-toggle', 'tag', 'clickable height-auto', bsSize === 'sm' && 'tag-small', 'display-flex align-items-center', 'user-select-none cursor-pointer', disabled && 'pointer-events-none', className);
|
|
12
|
+
if (toggleButtonType === 'tag') {
|
|
13
|
+
return (_jsx("div", { ...remainingProps, id: id, ref: toggleRef, onClick: onClick, className: tagClasses, children: children }));
|
|
14
|
+
}
|
|
15
|
+
if (toggleButtonType === 'label') {
|
|
16
|
+
return (_jsx("div", { ...remainingProps, id: id, ref: toggleRef, onClick: onClick, className: labelClasses, children: children }));
|
|
17
|
+
}
|
|
18
|
+
return (_jsx(Button, { ...remainingProps, id: splitButton ? `button-${id}` : id, type: 'button', ref: toggleRef, disabled: disabled, bsStyle: bsStyle, bsSize: bsSize, variant: variant, onClick: onClick, iconOnly: iconOnly, className: buttonClasses, children: children }));
|
|
11
19
|
});
|
|
12
20
|
export default DropdownToggleButton;
|
|
@@ -1,17 +1,37 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// biome-ignore lint/style/useImportType: required for JSX runtime compatibility with older toolchains
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
4
|
import classNames from 'classnames';
|
|
3
5
|
const FormLabel = (props) => {
|
|
4
6
|
const { className = '', children, supportingText, ...remainingProps } = props;
|
|
7
|
+
const elementRef = useRef(null);
|
|
8
|
+
const [parentSize, setParentSize] = useState(null);
|
|
5
9
|
const isLabel = 'htmlFor' in remainingProps;
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (!elementRef.current) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const parent = elementRef.current.parentElement;
|
|
15
|
+
if (!parent) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (parent.classList.contains('form-group-lg')) {
|
|
19
|
+
setParentSize('lg');
|
|
20
|
+
}
|
|
21
|
+
else if (parent.classList.contains('form-group-sm')) {
|
|
22
|
+
setParentSize('sm');
|
|
23
|
+
}
|
|
24
|
+
}, []);
|
|
25
|
+
const supportingTextClasses = classNames('text-color-gray', 'text-italic', parentSize === 'sm' && 'text-size-10', parentSize === 'lg' && 'text-size-14', !parentSize && 'text-size-12');
|
|
6
26
|
if (isLabel) {
|
|
7
|
-
const labelClasses = classNames('display-inline-flex flex-wrap justify-content-between width-100pct', className);
|
|
27
|
+
const labelClasses = classNames(!supportingText && 'display-inline-block', supportingText && 'display-inline-flex flex-wrap justify-content-between width-100pct', className);
|
|
8
28
|
return (
|
|
9
29
|
// biome-ignore lint/a11y/noLabelWithoutControl: <explanation>
|
|
10
|
-
_jsxs("label", { ...remainingProps, className: labelClasses, children: [_jsx("span", { children: children }), supportingText && _jsx("span", { className:
|
|
30
|
+
_jsxs("label", { ref: elementRef, ...remainingProps, className: labelClasses, children: [_jsx("span", { children: children }), supportingText && _jsx("span", { className: supportingTextClasses, children: supportingText })] }));
|
|
11
31
|
}
|
|
12
|
-
const classes = classNames('text-
|
|
32
|
+
const classes = classNames('text-color-dark', 'max-width-100pct', parentSize === 'sm' && 'text-size-10', parentSize === 'lg' && 'text-size-14', !parentSize && 'text-size-12', !supportingText && 'display-inline-block', supportingText && 'display-inline-flex flex-wrap justify-content-between width-100pct', !className.includes('margin-bottom') && 'margin-bottom-5', className);
|
|
13
33
|
return (
|
|
14
34
|
// @ts-ignore
|
|
15
|
-
_jsxs("div", { ...remainingProps, className: classes, children: [children, supportingText && _jsx("span", { className:
|
|
35
|
+
_jsxs("div", { ref: elementRef, ...remainingProps, className: classes, children: [children, supportingText && _jsx("span", { className: supportingTextClasses, children: supportingText })] }));
|
|
16
36
|
};
|
|
17
37
|
export default FormLabel;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
|
|
2
|
+
// biome-ignore lint/style/useImportType: <explanation>
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
3
4
|
import isEmpty from 'lodash/fp/isEmpty';
|
|
4
5
|
import debounce from 'lodash/fp/debounce';
|
|
5
6
|
import classNames from 'classnames';
|
|
@@ -38,11 +39,13 @@ const ListMenu = (props) => {
|
|
|
38
39
|
}
|
|
39
40
|
});
|
|
40
41
|
// Convert the menu to an expandable panel for smaller screens
|
|
41
|
-
const
|
|
42
|
+
const handleMobileSize = debounce(RESIZE_THROTTLING)(() => {
|
|
42
43
|
buildMobileHeader();
|
|
43
44
|
setIsMobileMode(window.innerWidth < MOBILE_MAX_WIDTH);
|
|
44
45
|
});
|
|
45
|
-
|
|
46
|
+
// Render a dropdown menu on mobile on mount
|
|
47
|
+
useEffect(handleMobileSize, []);
|
|
48
|
+
useWindowResize(handleMobileSize);
|
|
46
49
|
const focusInput = () => {
|
|
47
50
|
inputRef.current?.focus();
|
|
48
51
|
};
|
|
@@ -56,7 +59,8 @@ const ListMenu = (props) => {
|
|
|
56
59
|
useEffectOnce(() => {
|
|
57
60
|
focusFilter && focusInput();
|
|
58
61
|
});
|
|
59
|
-
|
|
62
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
|
|
63
|
+
useEffect(() => buildMobileHeader, [menuItems]);
|
|
60
64
|
const handleClear = () => focusFilter && focusInput();
|
|
61
65
|
const handleFilterChange = (value) => {
|
|
62
66
|
setFilterValue(value);
|
|
@@ -25,7 +25,7 @@ const Map = (props) => {
|
|
|
25
25
|
const [showCluster, setShowCluster] = useState(externalShowCluster);
|
|
26
26
|
const devicePixelRatio = enableDevicePixelRatio ? window.devicePixelRatio || 1 : 1;
|
|
27
27
|
// Only short locale is supported by HERE Map
|
|
28
|
-
const language = lang.split('-')[0];
|
|
28
|
+
const language = (locale => (locale === 'nb' ? 'no' : locale))(lang.split('-')[0].toLowerCase());
|
|
29
29
|
useEffect(() => {
|
|
30
30
|
let allMapObjects = [];
|
|
31
31
|
if (api?.map) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// biome-ignore lint/style/useImportType: required for JSX runtime compatibility with older toolchains
|
|
2
2
|
import React, { useEffect } from 'react';
|
|
3
3
|
import ReactDomServer from 'react-dom/server';
|
|
4
4
|
import noop from 'lodash/fp/noop';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable max-len */
|
|
2
2
|
/* eslint-disable prefer-arrow/prefer-arrow-functions */
|
|
3
|
-
//
|
|
3
|
+
// biome-ignore lint/style/useImportType: required for JSX runtime compatibility with older toolchains
|
|
4
4
|
import { useEffect, useState } from 'react';
|
|
5
5
|
import { useMapContext } from '../../../MapContext';
|
|
6
6
|
import { MAP_LAYER_INCIDENTS } from '../../../constants';
|
|
@@ -17,7 +17,7 @@ const SingleMapMarker = (props) => {
|
|
|
17
17
|
const largeAnchor = anchorSize === 'lg';
|
|
18
18
|
const classes = classNames(active && 'active', 'rio-map-marker', 'rio-map-marker-bottom-center', !clickable && 'not-clickable', className);
|
|
19
19
|
const anchorClasses = classNames('rio-map-anchor', largeAnchor ? 'rio-map-anchor-lg' : '', cursor);
|
|
20
|
-
const singleClasses = classNames('rio-map-single', fixed && 'fixed', moving && 'moving', textColor, markerOnHover && 'visible-on-hover', active && 'active', pinging && 'pinging', cursor);
|
|
20
|
+
const singleClasses = classNames('rio-map-single', fixed && 'fixed', moving && 'moving', textColor, markerOnHover && 'visible-on-hover', active && 'active', pinging && 'pinging', typeof name === 'string' && name.length === 1 && 'single-letter', cursor);
|
|
21
21
|
const markerBackgroundColor = `var(${markerColorMapping[markerColor]})`;
|
|
22
22
|
return (_jsx("div", { className: classes, style: { ...style, color: markerBackgroundColor }, "data-marker-type": markerColor.replace('bg-', 'single-'), children: _jsxs("div", { className: 'rio-map-marker-translate', children: [!anchorOnly && (_jsxs(_Fragment, { children: [_jsxs("div", { className: singleClasses, children: [_jsx(MapStateIndicator, { moving: moving, bearing: bearing, stateIconName: stateIconName }), getIcons(iconNames), name && _jsx("div", { className: 'rio-map-name', children: name }), exceptionCount > 0 && _jsx("div", { className: 'rio-map-bubble exception', children: exceptionCount }), warningCount > 0 && _jsx("div", { className: 'rio-map-bubble warning', children: warningCount })] }), _jsx("div", { className: 'rio-map-anchor-arrow' })] })), _jsx("div", { className: anchorClasses, children: anchorIconName && largeAnchor && _jsx("span", { className: `rioglyph rioglyph-${anchorIconName}` }) })] }) }));
|
|
23
23
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
//
|
|
2
|
+
// biome-ignore lint/style/useImportType: required for JSX runtime compatibility with older toolchains
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import classNames from 'classnames';
|
|
5
5
|
import noop from 'lodash/fp/noop';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
//
|
|
2
|
+
// biome-ignore lint/style/useImportType: required for JSX runtime compatibility with older toolchains
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { toast, Slide } from 'react-toastify';
|
|
5
5
|
export const DEFAULT_NOTIFICATION_TIMEOUT_IN_MS = 5_000;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
//
|
|
2
|
+
// biome-ignore lint/style/useImportType: required for JSX runtime compatibility with older toolchains
|
|
3
3
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
4
4
|
import ReactDOM from 'react-dom';
|
|
5
5
|
import { usePopper } from 'react-popper';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
//
|
|
2
|
+
// biome-ignore lint/style/useImportType: required for JSX runtime compatibility with older toolchains
|
|
3
3
|
import { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
4
4
|
import classNames from 'classnames';
|
|
5
5
|
import isEmpty from 'lodash/fp/isEmpty';
|
|
@@ -146,6 +146,14 @@ export type MultiselectProps<T extends MultiselectOption> = Omit<WithFeedbackAnd
|
|
|
146
146
|
* @default false
|
|
147
147
|
*/
|
|
148
148
|
showUnselectedItemIcons?: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* Additional classes to be set to the dropdown.
|
|
151
|
+
*/
|
|
152
|
+
dropdownClassName?: string;
|
|
153
|
+
/**
|
|
154
|
+
* Additional classes to be set to the select/input.
|
|
155
|
+
*/
|
|
156
|
+
btnClassName?: string;
|
|
149
157
|
/**
|
|
150
158
|
* Additional classes to be set to the select wrapper
|
|
151
159
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
//
|
|
2
|
+
// biome-ignore lint/style/useImportType: required for JSX runtime compatibility with older toolchains
|
|
3
3
|
import { useRef, useState } from 'react';
|
|
4
4
|
import classNames from 'classnames';
|
|
5
5
|
import isEqual from 'lodash/fp/isEqual';
|
|
@@ -15,7 +15,7 @@ import useMergeRefs from '../../hooks/useMergeRefs';
|
|
|
15
15
|
import WithFeedbackAndAddon from './WithFeedbackAndAddon';
|
|
16
16
|
const DEFAULT_FOCUSED_ITEM_INDEX = -1;
|
|
17
17
|
const Multiselect = (props) => {
|
|
18
|
-
const { name, id = name, options = [], value, onChange = noop, placeholder, isLoading = false, dropup = false, pullRight = false, autoDropDirection = true, bsSize = 'md', disabled = false, tabIndex = 0, hasError = false, useFilter = false, multiline = false, noItemMessage, counterMessage, renderCounterMessage, showSelectedItemIcon = false, showUnselectedItemIcons = false, className, inputAddon, errorMessage, warningMessage, messageWhiteSpace = 'normal', ...remainingProps } = props;
|
|
18
|
+
const { name, id = name, options = [], value, onChange = noop, placeholder, isLoading = false, dropup = false, pullRight = false, autoDropDirection = true, bsSize = 'md', disabled = false, tabIndex = 0, hasError = false, useFilter = false, multiline = false, noItemMessage, counterMessage, renderCounterMessage, showSelectedItemIcon = false, showUnselectedItemIcons = false, className, inputAddon, errorMessage, warningMessage, messageWhiteSpace = 'normal', btnClassName, dropdownClassName, ...remainingProps } = props;
|
|
19
19
|
const [isOpen, setIsOpen] = useState(false);
|
|
20
20
|
const [selectedItemIds, setSelectedItemIds] = useState(value || []);
|
|
21
21
|
const [isFilterActive, setIsFilterActive] = useState(false);
|
|
@@ -73,7 +73,7 @@ const Multiselect = (props) => {
|
|
|
73
73
|
return (_jsx(MultiselectToggleSelection, { options: options, selectedItemIds: selectedItemIds, showSelectedItemIcon: showSelectedItemIcon, showUnselectedItemIcons: showUnselectedItemIcons, onRemoveItem: handleRemoveSelectedItem, multiline: multiline, hasInputAddon: !!inputAddon, hasFilter: useFilter, children: multiline && renderFilter() }));
|
|
74
74
|
};
|
|
75
75
|
const renderToggle = () => {
|
|
76
|
-
const wrapperClassNames = classNames('dropdown-toggle', 'form-control', 'text-left', bsSize === 'sm' && 'input-sm', bsSize === 'lg' && 'input-lg', multiline && 'height-auto', disabled && 'disabled');
|
|
76
|
+
const wrapperClassNames = classNames('dropdown-toggle', 'form-control', 'text-left', btnClassName && btnClassName, bsSize === 'sm' && 'input-sm', bsSize === 'lg' && 'input-lg', multiline && 'height-auto', disabled && 'disabled');
|
|
77
77
|
const showPlaceholder = isEmpty(selectedItemIds) && !showUnselectedItemIcons;
|
|
78
78
|
const showFilter = useFilter && isOpen && !counterMessage && !renderCounterMessage;
|
|
79
79
|
const toggleButton = (_jsxs("button", { type: 'button', id: id, name: name, className: wrapperClassNames, "data-toggle": 'dropdown', tabIndex: tabIndex, "aria-haspopup": 'true', "aria-expanded": isOpen, onClick: onToggle, onKeyDown: handleToggleKeyDown, ref: refToggle, children: [showPlaceholder ? (_jsxs(_Fragment, { children: [_jsx(MultiselectTogglePlaceholder, { placeholder: placeholder }), showFilter && renderFilter()] })) : (renderSelection()), showFilter && !multiline && renderFilter(), _jsx("span", { className: 'caret' })] }));
|
|
@@ -87,7 +87,7 @@ const Multiselect = (props) => {
|
|
|
87
87
|
option.selected = selectedItemIds.indexOf(option.id) !== -1;
|
|
88
88
|
return option;
|
|
89
89
|
});
|
|
90
|
-
return (_jsx(BaseSelectDropdown, { isOpen: isOpen, isLoading: isLoading, options: nonSelectedOptions, focusedItemIndex: focusedItemIndex, keyboardUsed: keyboardUsed, updateDOMValues: updateDOMValues, onSelect: onOptionChange, onClose: closeMenu, noItemMessage: noItemMessage, pullRight: pullRight, useActiveClass: true, dropup: dropup, autoDropDirection: autoDropDirection }));
|
|
90
|
+
return (_jsx(BaseSelectDropdown, { isOpen: isOpen, isLoading: isLoading, options: nonSelectedOptions, focusedItemIndex: focusedItemIndex, keyboardUsed: keyboardUsed, updateDOMValues: updateDOMValues, onSelect: onOptionChange, onClose: closeMenu, noItemMessage: noItemMessage, pullRight: pullRight, useActiveClass: true, dropup: dropup, autoDropDirection: autoDropDirection, dropdownClassName: dropdownClassName }));
|
|
91
91
|
};
|
|
92
92
|
const handleFilterChange = (event) => {
|
|
93
93
|
event.preventDefault();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
//
|
|
2
|
+
// biome-ignore lint/style/useImportType: required for JSX runtime compatibility with older toolchains
|
|
3
3
|
import { forwardRef, useEffect, useImperativeHandle, useRef, } from 'react';
|
|
4
4
|
import { Scrollbars } from 'react-custom-scrollbars-2';
|
|
5
5
|
import classNames from 'classnames';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type ColorOverridesMap } from './svgConverter';
|
|
3
|
+
type SvgElementProps = {
|
|
4
|
+
node: Element;
|
|
5
|
+
colorMap: ColorOverridesMap;
|
|
6
|
+
};
|
|
7
|
+
declare const SvgElement: ({ node, colorMap }: SvgElementProps) => React.DOMElement<React.DOMAttributes<Element>, Element>;
|
|
8
|
+
export default SvgElement;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { convertAttributes } from './svgConverter';
|
|
4
|
+
const SvgElement = ({ node, colorMap }) => {
|
|
5
|
+
const attributes = convertAttributes(node, colorMap);
|
|
6
|
+
return React.createElement(node.tagName.toLowerCase(), {
|
|
7
|
+
...attributes,
|
|
8
|
+
key: attributes.id || Math.random(),
|
|
9
|
+
}, Array.from(node.childNodes).map((child, idx) => child.nodeType === 1 ? _jsx(SvgElement, { node: child, colorMap: colorMap }, idx) : null));
|
|
10
|
+
};
|
|
11
|
+
export default SvgElement;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ColorOverridesMap } from './svgConverter';
|
|
3
|
+
type SvgImageProps = {
|
|
4
|
+
/**
|
|
5
|
+
* The name of the image file without extension.
|
|
6
|
+
*/
|
|
7
|
+
name: string;
|
|
8
|
+
/**
|
|
9
|
+
* The height and width of the SVG image in pixels.
|
|
10
|
+
*
|
|
11
|
+
* @default 150
|
|
12
|
+
*/
|
|
13
|
+
size?: number;
|
|
14
|
+
/**
|
|
15
|
+
* The CDN base URL where the images are located.
|
|
16
|
+
*
|
|
17
|
+
* @default 'https://cdn.rio.cloud/riosvg'
|
|
18
|
+
*/
|
|
19
|
+
baseUrl?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Customize color using the color map and define the CSS variable name that shall be used.
|
|
22
|
+
*/
|
|
23
|
+
colorMap?: ColorOverridesMap;
|
|
24
|
+
/**
|
|
25
|
+
* Additional class names added to the SVG element.
|
|
26
|
+
*/
|
|
27
|
+
className?: string;
|
|
28
|
+
};
|
|
29
|
+
export declare const SvgImage: (props: SvgImageProps) => React.ReactElement<any, string | React.JSXElementConstructor<any>> | null;
|
|
30
|
+
export default SvgImage;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useSvgLoader } from './useSvgLoader';
|
|
3
|
+
const BASE_CDN_URL = 'https://cdn.rio.cloud/riosvg';
|
|
4
|
+
export const SvgImage = (props) => {
|
|
5
|
+
const { name, className = '', size = 150, baseUrl = BASE_CDN_URL, colorMap } = props;
|
|
6
|
+
const { svgElement, error } = useSvgLoader(name, baseUrl, colorMap);
|
|
7
|
+
if (error) {
|
|
8
|
+
console.error(`Icon "${name}" not found`);
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
if (!svgElement) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
return React.cloneElement(svgElement, {
|
|
15
|
+
width: size,
|
|
16
|
+
height: size,
|
|
17
|
+
className,
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
export default SvgImage;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type CSSColorVar = 'color-white' | 'color-black' | 'always-color-white' | 'always-color-black' | 'gray-darkest' | 'gray-darker' | 'gray-dark' | 'gray' | 'gray-light' | 'gray-lighter' | 'gray-lightest' | 'gray-decent' | 'brand-primary' | 'brand-secondary' | 'brand-primary-decent' | 'brand-secondary-decent' | 'brand-info' | 'brand-success' | 'brand-warning' | 'brand-danger' | 'brand-info-decent' | 'brand-success-decent' | 'brand-warning-decent' | 'brand-danger-decent' | 'color-code' | 'color-status-available' | 'color-status-driving' | 'color-status-resting' | 'color-status-working' | 'color-map-marker-asset' | 'color-map-marker-poi' | 'color-map-marker-geofence' | 'color-map-marker-route' | 'color-map-marker-info' | 'color-map-marker-success' | 'color-map-marker-warning' | 'color-map-marker-danger' | 'color-map-marker-restrictions' | 'color-map-marker-text' | 'color-map-marker-active' | 'color-highlight-darkest' | 'color-highlight-darker' | 'color-highlight-dark' | 'color-highlight' | 'color-highlight-light' | 'color-highlight-lighter' | 'color-highlight-lightest' | 'color-highlight-decent' | 'color-rating-1' | 'color-rating-2' | 'color-rating-3' | 'color-rating-4' | 'color-rating-5' | 'color-coldplay-wine' | 'color-coldplay-aubergine' | 'color-coldplay-kashmir' | 'color-coldplay-fountain' | 'color-coldplay-turquoise' | 'color-coldplay-bermuda' | 'color-coldplay-moos' | 'color-coldplay-primrose' | 'color-coldplay-khaki' | 'color-warmup-crimson' | 'color-warmup-victoria' | 'color-warmup-cadillac' | 'color-warmup-raspberry' | 'color-warmup-cerise' | 'color-warmup-charm' | 'color-warmup-salmon' | 'color-warmup-cherokee' | 'color-warmup-corn' | 'color-spectrum-indigo' | 'color-spectrum-violet' | 'color-spectrum-purple' | 'color-spectrum-fuchsia' | 'color-spectrum-pink' | 'color-spectrum-rose';
|
|
2
|
+
export type ColorOverridesMap = {
|
|
3
|
+
mainStrokeColor?: CSSColorVar;
|
|
4
|
+
mainFillColor?: CSSColorVar;
|
|
5
|
+
secondaryStrokeColor?: CSSColorVar;
|
|
6
|
+
backgroundFillColor?: CSSColorVar;
|
|
7
|
+
};
|
|
8
|
+
export declare const defaultColorMap: ColorOverridesMap;
|
|
9
|
+
type StyleObject = Record<string, string>;
|
|
10
|
+
export declare const parseStyleString: (style: string) => StyleObject;
|
|
11
|
+
export declare const camelCase: (str: string) => string;
|
|
12
|
+
type ConvertedAttributes = {
|
|
13
|
+
style?: React.CSSProperties;
|
|
14
|
+
[key: string]: string | React.CSSProperties | undefined;
|
|
15
|
+
};
|
|
16
|
+
export declare const convertAttributes: (node: Element, colorOverrides: ColorOverridesMap) => ConvertedAttributes;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Define the color replacements - handle hex colors and fallbacks
|
|
2
|
+
// const svgColorReplacement: Record<string, string> = {
|
|
3
|
+
// 'rgb(255, 255, 255)': 'var(--color-white)',
|
|
4
|
+
// '#fff': 'var(--color-white)',
|
|
5
|
+
// '#ffffff': 'var(--color-white)',
|
|
6
|
+
export const defaultColorMap = {
|
|
7
|
+
mainStrokeColor: 'brand-info',
|
|
8
|
+
mainFillColor: 'color-highlight-lighter',
|
|
9
|
+
secondaryStrokeColor: 'gray',
|
|
10
|
+
backgroundFillColor: 'gray-lighter',
|
|
11
|
+
};
|
|
12
|
+
// Utility function to normalize RGB values (removes spaces, converts case)
|
|
13
|
+
const normalizeColor = (color) => color.replace(/\s+/g, '').toLowerCase();
|
|
14
|
+
export const parseStyleString = (style) => {
|
|
15
|
+
return style.split(';').reduce((acc, rule) => {
|
|
16
|
+
const [key, value] = rule.split(':').map(s => s.trim());
|
|
17
|
+
if (key && value) {
|
|
18
|
+
acc[camelCase(key)] = value;
|
|
19
|
+
}
|
|
20
|
+
return acc;
|
|
21
|
+
}, {});
|
|
22
|
+
};
|
|
23
|
+
export const camelCase = (str) => str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
24
|
+
const REACT_ATTRIBUTE_MAP = {
|
|
25
|
+
'xml:space': 'xmlSpace',
|
|
26
|
+
'xmlns:xlink': 'xmlnsXlink',
|
|
27
|
+
'stroke-width': 'strokeWidth',
|
|
28
|
+
'fill-opacity': 'fillOpacity',
|
|
29
|
+
'stroke-opacity': 'strokeOpacity',
|
|
30
|
+
'clip-path': 'clipPath',
|
|
31
|
+
};
|
|
32
|
+
export const convertAttributes = (node, colorOverrides) => {
|
|
33
|
+
const attributes = {};
|
|
34
|
+
const attrs = node.attributes;
|
|
35
|
+
// Create a dynamic color map based on the overrides
|
|
36
|
+
const colorMap = {
|
|
37
|
+
// Main fill color
|
|
38
|
+
'rgb(207, 240, 243)': `var(--${colorOverrides.mainFillColor || defaultColorMap.mainFillColor})`,
|
|
39
|
+
'#cff0f3': `var(--${colorOverrides.mainFillColor || defaultColorMap.mainFillColor})`,
|
|
40
|
+
// Main stroke color
|
|
41
|
+
'rgb(75, 128, 166)': `var(--${colorOverrides.mainStrokeColor || defaultColorMap.mainStrokeColor})`,
|
|
42
|
+
'#4b80a6': `var(--${colorOverrides.mainStrokeColor || defaultColorMap.mainStrokeColor})`,
|
|
43
|
+
// Secondary stroke color (gray elements)
|
|
44
|
+
'rgb(188, 192, 196)': `var(--${colorOverrides.secondaryStrokeColor || defaultColorMap.secondaryStrokeColor})`,
|
|
45
|
+
'#bcc0c4': `var(--${colorOverrides.secondaryStrokeColor || defaultColorMap.secondaryStrokeColor})`,
|
|
46
|
+
// Background fill color
|
|
47
|
+
'rgb(233, 235, 236)': `var(--${colorOverrides.backgroundFillColor || defaultColorMap.backgroundFillColor})`,
|
|
48
|
+
'#e9ebec': `var(--${colorOverrides.backgroundFillColor || defaultColorMap.backgroundFillColor})`,
|
|
49
|
+
// Static colors that don't change
|
|
50
|
+
'rgb(255, 255, 255)': 'var(--color-white)',
|
|
51
|
+
'#fff': 'var(--color-white)',
|
|
52
|
+
'#ffffff': 'var(--color-white)',
|
|
53
|
+
};
|
|
54
|
+
for (const attr of attrs) {
|
|
55
|
+
const attrName = REACT_ATTRIBUTE_MAP[attr.name] || attr.name;
|
|
56
|
+
let value = attr.value;
|
|
57
|
+
if (attrName === 'style') {
|
|
58
|
+
const parsedStyle = parseStyleString(value);
|
|
59
|
+
if (parsedStyle.fill) {
|
|
60
|
+
const normalizedFill = normalizeColor(parsedStyle.fill);
|
|
61
|
+
parsedStyle.fill = colorMap[normalizedFill] || parsedStyle.fill;
|
|
62
|
+
}
|
|
63
|
+
if (parsedStyle.stroke) {
|
|
64
|
+
const normalizedStroke = normalizeColor(parsedStyle.stroke);
|
|
65
|
+
parsedStyle.stroke = colorMap[normalizedStroke] || parsedStyle.stroke;
|
|
66
|
+
}
|
|
67
|
+
attributes.style = parsedStyle;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
if (attrName === 'fill' || attrName === 'stroke') {
|
|
71
|
+
const normalizedColor = normalizeColor(value);
|
|
72
|
+
value = colorMap[normalizedColor] || value;
|
|
73
|
+
}
|
|
74
|
+
attributes[attrName] = value;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return attributes;
|
|
78
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type ColorOverridesMap } from './svgConverter';
|
|
3
|
+
type UseSvgLoaderResult = {
|
|
4
|
+
svgElement: ReactNode | null;
|
|
5
|
+
error: boolean;
|
|
6
|
+
colorMap?: ColorOverridesMap;
|
|
7
|
+
};
|
|
8
|
+
export declare const useSvgLoader: (name: string, baseUrl: string, colorMap?: ColorOverridesMap) => UseSvgLoaderResult;
|
|
9
|
+
export {};
|