@rio-cloud/rio-uikit 0.16.4-beta.25 → 0.16.4-beta.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/Colors.d.ts +1 -21
  2. package/Colors.js +1 -2
  3. package/Multiselect.d.ts +2 -12
  4. package/Multiselect.js +2 -2
  5. package/Select.d.ts +2 -5
  6. package/Select.js +2 -2
  7. package/components/applicationLayout/ApplicationLayoutBody.d.ts +1 -1
  8. package/components/applicationLayout/ApplicationLayoutBody.js +14 -6
  9. package/components/assetTree/AssetTree.js +2 -1
  10. package/components/assetTree/Tree.js +1 -1
  11. package/components/editableContent/EditableContent.js +1 -1
  12. package/components/map/components/features/ContextMenu.js +3 -1
  13. package/components/selects/BaseSelectDropdown.d.ts +56 -0
  14. package/components/selects/BaseSelectDropdown.js +176 -0
  15. package/components/selects/ClearButton.d.ts +8 -0
  16. package/components/selects/ClearButton.js +11 -0
  17. package/components/selects/DropdownHeader.d.ts +7 -13
  18. package/components/selects/DropdownHeader.js +4 -12
  19. package/components/selects/Multiselect.d.ts +130 -98
  20. package/components/selects/Multiselect.js +143 -287
  21. package/components/selects/MultiselectToggleCounter.d.ts +9 -0
  22. package/components/selects/MultiselectToggleCounter.js +14 -0
  23. package/components/selects/MultiselectToggleFilter.d.ts +9 -0
  24. package/components/selects/MultiselectToggleFilter.js +13 -0
  25. package/components/selects/MultiselectTogglePlaceholder.d.ts +6 -0
  26. package/components/selects/MultiselectTogglePlaceholder.js +7 -0
  27. package/components/selects/MultiselectToggleSelection.d.ts +11 -0
  28. package/components/selects/MultiselectToggleSelection.js +29 -0
  29. package/components/selects/NoItemMessage.d.ts +7 -0
  30. package/components/selects/NoItemMessage.js +11 -0
  31. package/components/selects/Select.d.ts +128 -98
  32. package/components/selects/Select.js +114 -266
  33. package/components/selects/SelectFilter.d.ts +8 -0
  34. package/components/selects/SelectFilter.js +11 -0
  35. package/components/selects/SelectedOption.d.ts +12 -0
  36. package/components/selects/SelectedOption.js +24 -0
  37. package/components/selects/WithFeedback.d.ts +27 -0
  38. package/components/selects/WithFeedback.js +12 -0
  39. package/components/sidebars/Sidebar.js +3 -2
  40. package/components/smoothScrollbars/SmoothScrollbars.d.ts +16 -0
  41. package/components/smoothScrollbars/SmoothScrollbars.js +26 -0
  42. package/index.d.ts +4 -4
  43. package/index.js +4 -4
  44. package/lib/es/Colors.d.ts +1 -21
  45. package/lib/es/Colors.js +5 -3
  46. package/lib/es/Multiselect.d.ts +2 -12
  47. package/lib/es/Multiselect.js +3 -2
  48. package/lib/es/Select.d.ts +2 -5
  49. package/lib/es/Select.js +3 -2
  50. package/lib/es/components/applicationLayout/ApplicationLayoutBody.d.ts +1 -1
  51. package/lib/es/components/applicationLayout/ApplicationLayoutBody.js +14 -6
  52. package/lib/es/components/assetTree/AssetTree.js +2 -1
  53. package/lib/es/components/assetTree/Tree.js +1 -1
  54. package/lib/es/components/editableContent/EditableContent.js +1 -1
  55. package/lib/es/components/map/components/features/ContextMenu.js +3 -1
  56. package/lib/es/components/selects/BaseSelectDropdown.d.ts +56 -0
  57. package/lib/es/components/selects/BaseSelectDropdown.js +181 -0
  58. package/lib/es/components/selects/ClearButton.d.ts +8 -0
  59. package/lib/es/components/selects/ClearButton.js +14 -0
  60. package/lib/es/components/selects/DropdownHeader.d.ts +7 -13
  61. package/lib/es/components/selects/DropdownHeader.js +4 -13
  62. package/lib/es/components/selects/Multiselect.d.ts +130 -98
  63. package/lib/es/components/selects/Multiselect.js +141 -288
  64. package/lib/es/components/selects/MultiselectToggleCounter.d.ts +9 -0
  65. package/lib/es/components/selects/MultiselectToggleCounter.js +16 -0
  66. package/lib/es/components/selects/MultiselectToggleFilter.d.ts +9 -0
  67. package/lib/es/components/selects/MultiselectToggleFilter.js +16 -0
  68. package/lib/es/components/selects/MultiselectTogglePlaceholder.d.ts +6 -0
  69. package/lib/es/components/selects/MultiselectTogglePlaceholder.js +9 -0
  70. package/lib/es/components/selects/MultiselectToggleSelection.d.ts +11 -0
  71. package/lib/es/components/selects/MultiselectToggleSelection.js +32 -0
  72. package/lib/es/components/selects/NoItemMessage.d.ts +7 -0
  73. package/lib/es/components/selects/NoItemMessage.js +13 -0
  74. package/lib/es/components/selects/Select.d.ts +128 -98
  75. package/lib/es/components/selects/Select.js +112 -267
  76. package/lib/es/components/selects/SelectFilter.d.ts +8 -0
  77. package/lib/es/components/selects/SelectFilter.js +14 -0
  78. package/lib/es/components/selects/SelectedOption.d.ts +12 -0
  79. package/lib/es/components/selects/SelectedOption.js +26 -0
  80. package/lib/es/components/selects/WithFeedback.d.ts +27 -0
  81. package/lib/es/components/selects/WithFeedback.js +15 -0
  82. package/lib/es/components/sidebars/Sidebar.js +3 -2
  83. package/lib/es/components/smoothScrollbars/SmoothScrollbars.d.ts +16 -0
  84. package/lib/es/components/smoothScrollbars/SmoothScrollbars.js +29 -0
  85. package/lib/es/index.d.ts +4 -4
  86. package/lib/es/index.js +10 -8
  87. package/lib/es/types.d.ts +0 -67
  88. package/lib/es/version.json +1 -1
  89. package/package.json +6 -5
  90. package/types.d.ts +0 -67
  91. package/version.json +1 -1
package/Colors.d.ts CHANGED
@@ -1,21 +1 @@
1
- declare module '@rio-cloud/rio-uikit/Colors' {
2
- type Colors = {
3
- 'gray-darkest': string;
4
- 'gray-darker': string;
5
- 'gray-dark': string;
6
- gray: string;
7
- 'gray-light': string;
8
- 'gray-lighter': string;
9
- 'gray-lightest': string;
10
- 'color-highlight-darkest': string;
11
- 'color-highlight-darker': string;
12
- 'color-highlight-dark': string;
13
- 'color-highlight': string;
14
- 'color-highlight-light': string;
15
- 'color-highlight-lighter': string;
16
- 'color-highlight-lightest': string;
17
- };
18
-
19
- const colors: Colors;
20
- export default colors;
21
- }
1
+ export { default } from './styles/variables/colors/colors.json';
package/Colors.js CHANGED
@@ -1,2 +1 @@
1
- import _colors from './styles/variables/colors/colors.json';
2
- export { _colors as default };
1
+ export { default } from './styles/variables/colors/colors.json';
package/Multiselect.d.ts CHANGED
@@ -1,12 +1,2 @@
1
- import React from 'react';
2
- import { MultiselectProps, MultiselectOption } from './types';
3
-
4
- export { MultiselectOption } from './types';
5
- export { MultiselectCounterMessage } from './types';
6
-
7
- export default class Multiselect<T extends MultiselectOption> extends React.Component<MultiselectProps<T>> {
8
- static SIZE_SM = 'sm';
9
- static SIZE_LG = 'lg';
10
- static SIZE_SMALL = 'small';
11
- static SIZE_LARGE = 'large';
12
- }
1
+ export { default } from './components/selects/Multiselect';
2
+ export * from './components/selects/Multiselect';
package/Multiselect.js CHANGED
@@ -1,2 +1,2 @@
1
- import { default as _Multiselect } from './components/selects/Multiselect';
2
- export { _Multiselect as default };
1
+ export { default } from './components/selects/Multiselect';
2
+ export * from './components/selects/Multiselect';
package/Select.d.ts CHANGED
@@ -1,5 +1,2 @@
1
- import React from 'react';
2
- import { SelectProps } from './types';
3
-
4
- export { SelectOption } from './types';
5
- export default class Select<T extends SelectOption> extends React.Component<SelectProps<T>> {}
1
+ export { default } from './components/selects/Select';
2
+ export * from './components/selects/Select';
package/Select.js CHANGED
@@ -1,2 +1,2 @@
1
- import { default as _Select } from './components/selects/Select';
2
- export { _Select as default };
1
+ export { default } from './components/selects/Select';
2
+ export * from './components/selects/Select';
@@ -7,7 +7,7 @@ export type ApplicationLayoutBodyProps = {
7
7
  enableScrollToTop?: boolean;
8
8
  /**
9
9
  * Always show vertical scrollbar to prevent the content from jumping.
10
- * @default false
10
+ * @default true
11
11
  */
12
12
  forceScrollbar?: boolean;
13
13
  /**
@@ -3,10 +3,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React, { useState, useRef, useEffect, forwardRef, useImperativeHandle, } from 'react';
4
4
  import debounce from 'lodash/fp/debounce';
5
5
  import classNames from 'classnames';
6
+ import SmoothScrollbars from '../smoothScrollbars/SmoothScrollbars';
6
7
  const RESIZE_THROTTLING = 200;
7
8
  const DEFAULT_BOTTOM_BAR_HEIGHT = 54;
8
9
  const ApplicationLayoutBody = forwardRef((props, ref) => {
9
- const { className, innerClassName, forceScrollbar = false, enableScrollToTop = true, banner, navigation, bottomBar, bottomBarHeight = DEFAULT_BOTTOM_BAR_HEIGHT, children } = props, remainingProps = __rest(props, ["className", "innerClassName", "forceScrollbar", "enableScrollToTop", "banner", "navigation", "bottomBar", "bottomBarHeight", "children"]);
10
+ const { className, innerClassName, forceScrollbar = true, enableScrollToTop = true, banner, navigation, bottomBar, bottomBarHeight = DEFAULT_BOTTOM_BAR_HEIGHT, children } = props, remainingProps = __rest(props, ["className", "innerClassName", "forceScrollbar", "enableScrollToTop", "banner", "navigation", "bottomBar", "bottomBarHeight", "children"]);
10
11
  const [offset, setOffset] = useState(0);
11
12
  const moduleContentRef = useRef(null);
12
13
  const layoutBodyRef = useRef(null);
@@ -19,24 +20,31 @@ const ApplicationLayoutBody = forwardRef((props, ref) => {
19
20
  }, [bottomBarHeight]);
20
21
  const handleScroll = debounce(RESIZE_THROTTLING)(() => {
21
22
  if (moduleContentRef.current) {
22
- setOffset(moduleContentRef.current.scrollTop);
23
+ setOffset(moduleContentRef.current.getScrollTop());
23
24
  }
24
25
  });
25
26
  const handleToTop = () => {
27
+ var _a;
26
28
  if (!moduleContentRef.current) {
27
29
  return;
28
30
  }
29
- const currentScroll = moduleContentRef.current.scrollTop;
31
+ const scrollWrapper = moduleContentRef.current.container;
32
+ const scrollingElement = scrollWrapper.firstElementChild;
33
+ const currentScroll = (_a = scrollingElement === null || scrollingElement === void 0 ? void 0 : scrollingElement.scrollTop) !== null && _a !== void 0 ? _a : 0;
30
34
  if (currentScroll > 0) {
31
35
  window.requestAnimationFrame(handleToTop);
32
- moduleContentRef.current.scrollTo(0, currentScroll - currentScroll / 5);
36
+ scrollingElement === null || scrollingElement === void 0 ? void 0 : scrollingElement.scrollTo(0, currentScroll - currentScroll / 5);
37
+ scrollWrapper.classList.add('is-scrolling-to-top');
33
38
  setOffset(currentScroll);
34
39
  }
40
+ else {
41
+ scrollWrapper.classList.remove('is-scrolling-to-top');
42
+ }
35
43
  };
36
44
  const classes = classNames('ApplicationLayoutBody', bottomBar && 'has-footer', className);
37
- const innerClasses = classNames('module-content', forceScrollbar && 'overflow-y-scroll', innerClassName && innerClassName);
45
+ const innerClasses = classNames('module-content', innerClassName && innerClassName);
38
46
  const offsetThreshold = window.innerHeight * 0.1;
39
47
  const scrollToTopClasses = classNames('scroll-to-top', offset > offsetThreshold && 'in');
40
- return (_jsxs(React.Fragment, { children: [_jsxs("div", Object.assign({}, remainingProps, { ref: layoutBodyRef, className: classes }, { children: [_jsxs("div", Object.assign({ className: 'module-content-wrapper' }, { children: [navigation && navigation, banner && banner, _jsx("div", Object.assign({ className: innerClasses, onScroll: handleScroll, ref: moduleContentRef }, { children: children }))] })), enableScrollToTop && (_jsx("span", Object.assign({ className: scrollToTopClasses }, { children: _jsx("button", Object.assign({ type: 'button', className: 'btn btn-primary btn-icon-only', onClick: handleToTop }, { children: _jsx("span", { className: 'rioglyph rioglyph-arrow-up' }) })) })))] })), bottomBar && bottomBar] }));
48
+ return (_jsxs(React.Fragment, { children: [_jsxs("div", Object.assign({}, remainingProps, { ref: layoutBodyRef, className: classes }, { children: [_jsxs("div", Object.assign({ className: 'module-content-wrapper' }, { children: [navigation && navigation, banner && banner, _jsx(SmoothScrollbars, Object.assign({ ref: moduleContentRef, slideIn: !forceScrollbar, largeTrack: true, trackOffset: true, className: innerClasses, onScroll: handleScroll }, { children: children }))] })), enableScrollToTop && (_jsx("span", Object.assign({ className: scrollToTopClasses }, { children: _jsx("button", Object.assign({ type: 'button', className: 'btn btn-primary btn-icon-only', onClick: handleToTop }, { children: _jsx("span", { className: 'rioglyph rioglyph-arrow-up' }) })) })))] })), bottomBar && bottomBar] }));
41
49
  });
42
50
  export default ApplicationLayoutBody;
@@ -12,6 +12,7 @@ import TreeSidebar from './TreeSidebar';
12
12
  import getWidthInBoundaries from '../../utils/getWidthInBoundaries';
13
13
  import mergeRefs from '../../utils/mergeRefs';
14
14
  import usePrevious from '../../usePrevious';
15
+ import SmoothScrollbars from '../smoothScrollbars/SmoothScrollbars';
15
16
  const DEFAULT_WIDTH = 350;
16
17
  const DEFAULT_MIN_WIDTH = 100;
17
18
  const DEFAULT_MAX_WIDTH = 0;
@@ -99,7 +100,7 @@ const AssetTree = memo(forwardRef((props, ref) => {
99
100
  setIsResize(false);
100
101
  onResizeEnd();
101
102
  };
102
- return (_jsxs("div", Object.assign({}, remainingProps, { className: classes, style: style, ref: mergedRefs }, { children: [_jsx("div", { className: resizeLimitClasses, style: resizeLimitStyle }), _jsxs("div", Object.assign({ className: 'AssetTreeContent' }, { children: [_jsx(TreeSidebar, Object.assign({ onSelectCategory: handleSelectCategory, currentCategoryId: currentCategoryId, onClick: handleToggleTreeContent }, { children: isArray(children) ? children : [children] })), _jsx("div", Object.assign({ className: 'AssetTreeBody' }, { children: useOffscreen ? renderTreesOffscreen(childrenArray, currentCategoryId) : category }))] })), resizable && isOpen && (_jsx(Resizer, { onResizeStart: handleResizeStart, onResize: handleResize, onResizeEnd: handleResizeEnd, direction: Resizer.HORIZONTAL, position: Resizer.RIGHT }))] })));
103
+ return (_jsxs("div", Object.assign({}, remainingProps, { className: classes, style: style, ref: mergedRefs }, { children: [_jsx("div", { className: resizeLimitClasses, style: resizeLimitStyle }), _jsxs("div", Object.assign({ className: 'AssetTreeContent' }, { children: [_jsx(TreeSidebar, Object.assign({ onSelectCategory: handleSelectCategory, currentCategoryId: currentCategoryId, onClick: handleToggleTreeContent }, { children: isArray(children) ? children : [children] })), _jsx(SmoothScrollbars, Object.assign({ slideIn: true, className: 'AssetTreeBody' }, { children: useOffscreen ? renderTreesOffscreen(childrenArray, currentCategoryId) : category }))] })), resizable && isOpen && (_jsx(Resizer, { onResizeStart: handleResizeStart, onResize: handleResize, onResizeEnd: handleResizeEnd, direction: Resizer.HORIZONTAL, position: Resizer.RIGHT }))] })));
103
104
  }));
104
105
  AssetTree.displayName = 'AssetTree';
105
106
  Object.assign(AssetTree, TreeMode);
@@ -256,7 +256,7 @@ const Tree = React.memo((props) => {
256
256
  const hasSearchAndNoGroups = hasInternalSearchValue() && isEmpty(state.groupedItems) && hasExternalGroups;
257
257
  const hideSelectAll = hasSearchAndNoItems || hasSearchAndNoGroups;
258
258
  const isIndeterminate = hasPartiallySelectedGroups() || hasPartiallySelectedItems();
259
- const treeClassNames = classNames('Tree', 'overflow-x-hidden', className);
259
+ const treeClassNames = classNames('Tree', className);
260
260
  const treeHeadClasses = classNames('TreeHead', 'display-flex gap-5', 'padding-15');
261
261
  const shouldRenderTree = () => hasGroups() && !hasInternalSearchValue();
262
262
  const content = cond([
@@ -99,7 +99,7 @@ const EditableContent = (props) => {
99
99
  }
100
100
  const textWrapperClasses = classNames(className, isEditMode && 'opacity-0');
101
101
  const overlayWrapperClasses = classNames('EditableContentEditor', 'display-flex gap-5', 'padding-5', 'rounded', 'shadow-accent', 'z-index-max', 'bg-white', editorClassName);
102
- const inputWrapperClasses = classNames('display-flex flex-column gap-5', 'margin-0', !hasCustomControl && 'form-group has-feedback', hasError && 'has-error');
102
+ const inputWrapperClasses = classNames('display-flex flex-column gap-5', 'margin-0', 'form-group has-feedback', hasError && 'has-error');
103
103
  const inputClasses = classNames('form-control', size === 'lg' && 'input-lg', inputClassName);
104
104
  const inputStyle = {
105
105
  minWidth: '100px',
@@ -3,7 +3,9 @@ import { useContext, useRef, useLayoutEffect } from 'react';
3
3
  import isEmpty from 'lodash/fp/isEmpty';
4
4
  import { MapContext } from '../context';
5
5
  const HERE_ITEM_CLASS = 'H_context_menu_item';
6
- const centeredSpinner = '<div class="flex-1-1 display-flex justify-content-center align-items-center"><div class="spinner"></div></div>';
6
+ const centeredSpinner =
7
+ // eslint-disable-next-line max-len
8
+ '<svg aria-labelledby="ggtrwic-aria" role="img" height="14" width="135px" class="ContentLoader use-mix-blend-mode"><title id="ggtrwic-aria">Loading...</title><rect role="presentation" x="0" y="0" width="100%" height="100%" clip-path="url(#ggtrwic-diff)" style="fill: url(&quot;#ggtrwic-animated-diff&quot;);"></rect><defs><clipPath id="ggtrwic-diff"><rect width="100%" height="100%" rx="3" ry="3"></rect></clipPath><linearGradient id="ggtrwic-animated-diff"><stop offset="0%" stop-color="#f5f6f7" stop-opacity="1"><animate attributeName="offset" values="-2; -2; 1" keyTimes="0; 0.25; 1" dur="2s" repeatCount="indefinite"></animate></stop><stop offset="50%" stop-color="#aaaaaa" stop-opacity="1"><animate attributeName="offset" values="-1; -1; 2" keyTimes="0; 0.25; 1" dur="2s" repeatCount="indefinite"></animate></stop><stop offset="100%" stop-color="#f5f6f7" stop-opacity="1"><animate attributeName="offset" values="0; 0; 3" keyTimes="0; 0.25; 1" dur="2s" repeatCount="indefinite"></animate></stop></linearGradient></defs></svg>';
7
9
  const getDOMMenuItems = () => document.getElementsByClassName(HERE_ITEM_CLASS);
8
10
  // Query DOM nodes for "H_context_menu_item" and update label when children label has changed.
9
11
  // This function allows to use HTML markup for the menu items in the second render
@@ -0,0 +1,56 @@
1
+ import React from 'react';
2
+ export type OptionDOMValue = {
3
+ id: string;
4
+ text: string;
5
+ };
6
+ export type SelectOption = {
7
+ /**
8
+ * Used to identify an option
9
+ */
10
+ id: string;
11
+ /**
12
+ * The option item text
13
+ */
14
+ label: string | React.ReactNode;
15
+ /**
16
+ * Icon to be displayed in front of the label
17
+ */
18
+ icon?: React.ReactNode;
19
+ /**
20
+ * Defines whether the menu item is selected or not
21
+ *
22
+ * @default false
23
+ */
24
+ selected?: boolean;
25
+ /**
26
+ * Setting "disabled" to true will disable the respective item
27
+ *
28
+ * @default false
29
+ */
30
+ disabled?: boolean;
31
+ /**
32
+ * Will treat the given value as a menu header
33
+ */
34
+ header?: boolean;
35
+ };
36
+ export type BaseSelectDropdownProps = {
37
+ options?: SelectOption[];
38
+ isOpen?: boolean;
39
+ updateDOMValues?: (values: OptionDOMValue[] | undefined) => void;
40
+ onOpen?: (hasDropup: boolean) => void;
41
+ onSelect?: (selectedItem: SelectOption | undefined) => void;
42
+ onClose?: () => void;
43
+ placeholder?: string | React.ReactNode;
44
+ dropup?: boolean;
45
+ pullRight?: boolean;
46
+ autoDropDirection?: boolean;
47
+ noItemMessage?: string | React.ReactNode;
48
+ focusedItemIndex?: number;
49
+ dropdownClassName?: string;
50
+ requestItemDOMValues?: boolean;
51
+ keyboardUsed?: boolean;
52
+ useActiveClass?: boolean;
53
+ };
54
+ declare const BaseSelectDropdown: (props: BaseSelectDropdownProps) => import("react/jsx-runtime").JSX.Element;
55
+ export declare const filterOptions: (itemDOMValues: OptionDOMValue[], filterValue: string, options: SelectOption[]) => SelectOption[];
56
+ export default BaseSelectDropdown;
@@ -0,0 +1,176 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // @ts-ignore-next-line importsNotUsedAsValues
3
+ import { useState, useRef, useLayoutEffect } from 'react';
4
+ import classNames from 'classnames';
5
+ import isEmpty from 'lodash/fp/isEmpty';
6
+ import noop from 'lodash/fp/noop';
7
+ import { useDropDirection } from '../../utils/useDropDirection';
8
+ import { scrollItemIntoView, UP, DOWN } from '../../utils/scrollItemIntoView';
9
+ import useEffectOnce from '../../hooks/useEffectOnce';
10
+ import useKey from '../../useKey';
11
+ import DropdownHeader from './DropdownHeader';
12
+ import NoItemMessage from './NoItemMessage';
13
+ const DATA_ATTRIBUTE_ID = 'data-item-id';
14
+ const DEFAULT_FOCUSED_ITEM_INDEX = 0;
15
+ const HIGHLIGHT_CLASS = 'focus';
16
+ const BaseSelectDropdown = (props) => {
17
+ const { isOpen = false, updateDOMValues = noop, onOpen = noop, onSelect = noop, onClose = noop, options = [], autoDropDirection = true, dropup = false, pullRight = false, useActiveClass = false, focusedItemIndex: externalFocusedItemIndex, keyboardUsed: externalKeyboardUsed, noItemMessage, dropdownClassName, } = props;
18
+ const [focusedItemIndex, setFocusedItemIndex] = useState(externalFocusedItemIndex || DEFAULT_FOCUSED_ITEM_INDEX);
19
+ const [keyboardUsed, setKeyboardUsed] = useState(externalKeyboardUsed);
20
+ const dropdownMenuRef = useRef(null);
21
+ useEffectOnce(() => {
22
+ // all available items need to be rendered in order to know their DOM value
23
+ // which will be used for filtering in the parent component
24
+ const currentItemDOMValues = updateItemDOMValues();
25
+ updateDOMValues(currentItemDOMValues);
26
+ });
27
+ // Overwrite position of dropdown menu in case auto drop is enabled
28
+ const dropDirection = useDropDirection({ pullRight, dropup, autoDropDirection, dropdownMenuRef }, [isOpen]);
29
+ // Add or remove the "dropup" class from the parent Select/Multiselect component to position
30
+ // the dropdown element accordingly via CSS
31
+ useLayoutEffect(() => {
32
+ if (dropdownMenuRef.current) {
33
+ const parent = dropdownMenuRef.current.parentElement;
34
+ if (dropDirection.dropup) {
35
+ parent === null || parent === void 0 ? void 0 : parent.classList.add('dropup');
36
+ }
37
+ else {
38
+ parent === null || parent === void 0 ? void 0 : parent.classList.remove('dropup');
39
+ }
40
+ }
41
+ }, [dropDirection, dropdownMenuRef]);
42
+ // update internal state for isOpen
43
+ const [previousIsOpen, setPreviousIsOpen] = useState(isOpen);
44
+ if (isOpen && !previousIsOpen) {
45
+ onOpen(dropDirection.dropup);
46
+ setPreviousIsOpen(isOpen);
47
+ }
48
+ else if (!isOpen && previousIsOpen) {
49
+ onClose();
50
+ setPreviousIsOpen(isOpen);
51
+ }
52
+ useKey(event => {
53
+ if (isOpen) {
54
+ switch (event.key) {
55
+ case 'Escape': {
56
+ // close dropdown on esc
57
+ onClose();
58
+ break;
59
+ }
60
+ case 'Tab': {
61
+ // close dropdown on tab
62
+ onClose();
63
+ break;
64
+ }
65
+ case 'Enter': {
66
+ // select item on enter
67
+ selectOptionOnEnter(event);
68
+ break;
69
+ }
70
+ case 'ArrowUp': {
71
+ // prevent scrolling the page when dropdown menu is open
72
+ event.preventDefault();
73
+ // select item above on arrow up key
74
+ focusOption(UP);
75
+ scrollItemIntoView(UP, dropdownMenuRef.current, getFocusedOptionNode());
76
+ break;
77
+ }
78
+ case 'ArrowDown': {
79
+ // prevent scrolling the page when dropdown menu is open
80
+ event.preventDefault();
81
+ // select item below on arrow down key
82
+ focusOption(DOWN);
83
+ scrollItemIntoView(DOWN, dropdownMenuRef.current, getFocusedOptionNode());
84
+ break;
85
+ }
86
+ default:
87
+ break;
88
+ }
89
+ }
90
+ });
91
+ const focusOption = (direction) => {
92
+ let nextFocusedItem = 0;
93
+ switch (direction) {
94
+ case UP: {
95
+ nextFocusedItem = focusedItemIndex <= 0 ? focusedItemIndex : focusedItemIndex - 1;
96
+ break;
97
+ }
98
+ case DOWN: {
99
+ nextFocusedItem = focusedItemIndex === options.length - 1 ? focusedItemIndex : focusedItemIndex + 1;
100
+ break;
101
+ }
102
+ default:
103
+ break;
104
+ }
105
+ // In case the next item index is negative, means outside the bounds of the items,
106
+ // reset it depending on the current direction
107
+ const indexLimit = direction === UP ? options.length - 1 : 0;
108
+ setFocusedItemIndex(nextFocusedItem < 0 ? indexLimit : nextFocusedItem);
109
+ setKeyboardUsed(true);
110
+ };
111
+ const getOptionNodes = () => {
112
+ const node = dropdownMenuRef.current;
113
+ return (node === null || node === void 0 ? void 0 : node.getElementsByTagName('a')) || [];
114
+ };
115
+ const updateItemDOMValues = () => {
116
+ if (dropdownMenuRef.current) {
117
+ const optionNodes = getOptionNodes();
118
+ const itemDOMValuesMapped = [...optionNodes].map(item => {
119
+ return {
120
+ id: item.getAttribute(DATA_ATTRIBUTE_ID),
121
+ text: item.textContent,
122
+ };
123
+ });
124
+ return itemDOMValuesMapped;
125
+ }
126
+ };
127
+ const getFocusedOptionNode = () => {
128
+ const optionNodes = getOptionNodes();
129
+ return [...optionNodes].find(item => item.className.includes(HIGHLIGHT_CLASS));
130
+ };
131
+ const selectOptionOnEnter = (event) => {
132
+ event.preventDefault();
133
+ // When no filter result was found, avoid selecting anything
134
+ if (isEmpty(options)) {
135
+ return;
136
+ }
137
+ const match = getFocusedOptionNode();
138
+ if (match) {
139
+ const selectedItem = options.find(option => option.id === match.getAttribute(DATA_ATTRIBUTE_ID));
140
+ onSelect(selectedItem);
141
+ }
142
+ };
143
+ const handleOptionChange = (event) => {
144
+ event.preventDefault();
145
+ const optionId = event.currentTarget.getElementsByTagName('input')[0].value;
146
+ const selectedItem = options.find(option => option.id === optionId);
147
+ onSelect(selectedItem);
148
+ };
149
+ const dropdownMenuClasses = classNames('dropdown-menu', dropDirection.pullRight && 'pull-right', dropdownClassName);
150
+ // Don't show the dropdown, when no match are found when filtering unless there is a not found message
151
+ if (isEmpty(options)) {
152
+ return _jsx(NoItemMessage, { noItemMessage: noItemMessage, className: dropdownMenuClasses });
153
+ }
154
+ return (_jsx("ul", Object.assign({ className: dropdownMenuClasses, ref: dropdownMenuRef, role: 'menu' }, { children: options.map((option, index) => {
155
+ if (option.header) {
156
+ return _jsx(DropdownHeader, { icon: option.icon, label: option.label }, option.id);
157
+ }
158
+ // Show focused style only when keyboard is in use
159
+ const anchorClassNames = classNames('display-flex align-items-center', keyboardUsed && focusedItemIndex === index ? HIGHLIGHT_CLASS : '', option.disabled && 'pointer-events-none');
160
+ const wrapperClassNames = classNames(option.disabled && 'disabled', useActiveClass && option.selected && 'active');
161
+ return (_jsx("li", Object.assign({ className: wrapperClassNames, role: 'listitem' }, { children: _jsxs("a", Object.assign({ role: 'menuitem', className: anchorClassNames, "data-item-id": option.id, "data-item-index": index,
162
+ // Note, we need to assign the click callback only when it's not disabled
163
+ // otherwise the functions is still triggered
164
+ // biome-ignore lint/a11y/useValidAnchor: due to old structure and backwards compatibility
165
+ onClick: option.disabled ? undefined : handleOptionChange }, { children: [_jsxs("span", { children: [option.icon && _jsx("span", Object.assign({ className: 'margin-right-5' }, { children: option.icon })), option.label] }), _jsx("input", { type: 'hidden', value: option.id })] })) }), option.id));
166
+ }) })));
167
+ };
168
+ export const filterOptions = (itemDOMValues, filterValue, options) => {
169
+ const filteredDOMValues = itemDOMValues.filter(item => item.text.toLowerCase().includes(filterValue.toLowerCase()));
170
+ // Filter the options according to the filtered DOM values and map the IDs since the filter cannot be done
171
+ // on the options itself as they might contain arbitrary components
172
+ return options.filter(option => {
173
+ return filteredDOMValues.find(domValue => domValue.id === option.id);
174
+ });
175
+ };
176
+ export default BaseSelectDropdown;
@@ -0,0 +1,8 @@
1
+ import type { SelectOption } from './Select';
2
+ export type ClearButtonProps = {
3
+ showClear: boolean;
4
+ selectedItem: SelectOption | null;
5
+ onClear: () => void;
6
+ };
7
+ declare const ClearButton: (props: ClearButtonProps) => import("react/jsx-runtime").JSX.Element;
8
+ export default ClearButton;
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // @ts-ignore-next-line importsNotUsedAsValues
3
+ import 'react';
4
+ import classNames from 'classnames';
5
+ import isNil from 'lodash/fp/isNil';
6
+ const ClearButton = (props) => {
7
+ const { showClear, selectedItem, onClear } = props;
8
+ const clearButtonClassNames = classNames('clearButton', (!showClear || isNil(selectedItem)) && 'hide pointer-events-none');
9
+ return (_jsx("span", Object.assign({ className: clearButtonClassNames, onClick: onClear }, { children: _jsx("span", { className: 'clearButtonIcon rioglyph rioglyph-remove-sign' }) })));
10
+ };
11
+ export default ClearButton;
@@ -1,14 +1,8 @@
1
+ import React from 'react';
2
+ export type DropdownHeaderProps = {
3
+ icon?: React.ReactNode;
4
+ center?: boolean;
5
+ label: string | React.ReactNode;
6
+ };
7
+ declare const DropdownHeader: (props: DropdownHeaderProps) => import("react/jsx-runtime").JSX.Element;
1
8
  export default DropdownHeader;
2
- declare function DropdownHeader(props: any): import("react/jsx-runtime").JSX.Element;
3
- declare namespace DropdownHeader {
4
- namespace defaultProps {
5
- const center: boolean;
6
- }
7
- namespace propTypes {
8
- export const icon: PropTypes.Requireable<string>;
9
- const center_1: PropTypes.Requireable<boolean>;
10
- export { center_1 as center };
11
- export const label: PropTypes.Requireable<NonNullable<PropTypes.ReactNodeLike>>;
12
- }
13
- }
14
- import PropTypes from "prop-types";
@@ -1,16 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React from 'react';
3
- import PropTypes from 'prop-types';
4
- const DropdownHeader = props => {
5
- const { icon, label, center } = props;
2
+ // @ts-ignore-next-line importsNotUsedAsValues
3
+ import 'react';
4
+ const DropdownHeader = (props) => {
5
+ const { icon, label, center = true } = props;
6
6
  return (_jsx("li", Object.assign({ className: `dropdown-header ${center ? 'center' : ''}` }, { children: _jsxs("span", Object.assign({ className: 'dropdown-header-text' }, { children: [icon && _jsx("span", Object.assign({ className: 'margin-right-5' }, { children: icon })), label] })) })));
7
7
  };
8
- DropdownHeader.defaultProps = {
9
- center: true,
10
- };
11
- DropdownHeader.propTypes = {
12
- icon: PropTypes.string,
13
- center: PropTypes.bool,
14
- label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
15
- };
16
8
  export default DropdownHeader;