@rio-cloud/rio-uikit 1.5.3 → 1.6.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.
Files changed (43) hide show
  1. package/OnboardingDialog.d.ts +2 -0
  2. package/OnboardingDialog.js +2 -0
  3. package/components/assetTree/AssetTree.js +1 -3
  4. package/components/assetTree/Tree.d.ts +1 -0
  5. package/components/assetTree/Tree.js +2 -2
  6. package/components/dialog/Dialog.d.ts +4 -2
  7. package/components/dialog/Dialog.js +3 -1
  8. package/components/dialog/OnboardingDialog.d.ts +44 -0
  9. package/components/dialog/OnboardingDialog.js +12 -0
  10. package/components/dialog/SplitDialog.d.ts +7 -1
  11. package/components/onboarding/OnboardingTip.d.ts +1 -0
  12. package/components/onboarding/OnboardingTip.js +1 -0
  13. package/components/selects/Multiselect.js +20 -5
  14. package/components/selects/MultiselectToggleFilter.d.ts +0 -1
  15. package/components/selects/MultiselectToggleFilter.js +2 -2
  16. package/hooks/useOnboarding.d.ts +128 -0
  17. package/hooks/useOnboarding.js +75 -0
  18. package/lib/es/Onboarding.d.ts +2 -0
  19. package/lib/es/Onboarding.js +7 -0
  20. package/lib/es/OnboardingDialog.d.ts +2 -0
  21. package/lib/es/OnboardingDialog.js +7 -0
  22. package/lib/es/components/assetTree/AssetTree.js +1 -3
  23. package/lib/es/components/assetTree/Tree.d.ts +1 -0
  24. package/lib/es/components/assetTree/Tree.js +2 -2
  25. package/lib/es/components/dialog/Dialog.d.ts +4 -2
  26. package/lib/es/components/dialog/Dialog.js +3 -1
  27. package/lib/es/components/dialog/OnboardingDialog.d.ts +44 -0
  28. package/lib/es/components/dialog/OnboardingDialog.js +14 -0
  29. package/lib/es/components/dialog/SplitDialog.d.ts +7 -1
  30. package/lib/es/components/onboarding/OnboardingTip.d.ts +1 -0
  31. package/lib/es/components/onboarding/OnboardingTip.js +1 -0
  32. package/lib/es/components/selects/Multiselect.js +20 -5
  33. package/lib/es/components/selects/MultiselectToggleFilter.d.ts +0 -1
  34. package/lib/es/components/selects/MultiselectToggleFilter.js +2 -2
  35. package/lib/es/hooks/useOnboarding.d.ts +128 -0
  36. package/lib/es/hooks/useOnboarding.js +80 -0
  37. package/lib/es/useOnboarding.d.ts +1 -0
  38. package/lib/es/useOnboarding.js +4 -0
  39. package/lib/es/version.json +1 -1
  40. package/package.json +3 -2
  41. package/useOnboarding.d.ts +1 -0
  42. package/useOnboarding.js +1 -0
  43. package/version.json +1 -1
@@ -0,0 +1,2 @@
1
+ export { default } from './components/dialog/OnboardingDialog';
2
+ export * from './components/dialog/OnboardingDialog';
@@ -0,0 +1,2 @@
1
+ export { default } from './components/dialog/OnboardingDialog';
2
+ export * from './components/dialog/OnboardingDialog';
@@ -26,9 +26,7 @@ const getCurrentCategoryElement = (children, currentCategoryId) => {
26
26
  };
27
27
  const renderTreesOffscreen = (children, categoryId) => {
28
28
  return React.Children.map(children, child => {
29
- const offscreenClasses = classNames('TreeOffscreenWrapper', 'flex-1-1', // stretch to use 100 percent of the remaining space
30
- 'flex flex-column', // set this one to flex as well, so children can use flex grow to use remaining space
31
- child && child.props.id !== categoryId && 'position-offscreen pointer-events-none');
29
+ const offscreenClasses = classNames('TreeOffscreenWrapper', child && child.props.id !== categoryId && 'position-offscreen pointer-events-none');
32
30
  return _jsx("div", Object.assign({ className: offscreenClasses }, { children: child }));
33
31
  });
34
32
  };
@@ -157,6 +157,7 @@ export type TreeProps = {
157
157
  * @default false
158
158
  */
159
159
  hideTreeHead?: boolean;
160
+ treeHeaderContent?: React.ReactElement;
160
161
  /**
161
162
  * Defines the max-height of the scrollable list.
162
163
  */
@@ -38,7 +38,7 @@ const filterProps = omit([
38
38
  ]);
39
39
  const customCompare = (prevProps, nextProps) => isEqual(filterProps(prevProps), filterProps(nextProps));
40
40
  const Tree = React.memo((props) => {
41
- const { groups = [], items = [], selectedGroups = [], selectedItems = [], onSelectionChange = noop, hasMultiselect = true, showRadioButtons = false, hideSearch = false, hideTreeHead, summary, hideSummary = false, search, searchPlaceholder = 'Type here to filter by name', onSearchChange = noop, className, scrollHeight, expandedGroups, onExpandGroupsChange = noop, showEmptyGroups = true, treeOptions = [], treeOptionsTooltip, disableAnimation = false } = props, remainingProps = __rest(props, ["groups", "items", "selectedGroups", "selectedItems", "onSelectionChange", "hasMultiselect", "showRadioButtons", "hideSearch", "hideTreeHead", "summary", "hideSummary", "search", "searchPlaceholder", "onSearchChange", "className", "scrollHeight", "expandedGroups", "onExpandGroupsChange", "showEmptyGroups", "treeOptions", "treeOptionsTooltip", "disableAnimation"]);
41
+ const { groups = [], items = [], selectedGroups = [], selectedItems = [], onSelectionChange = noop, hasMultiselect = true, showRadioButtons = false, hideSearch = false, hideTreeHead, treeHeaderContent, summary, hideSummary = false, search, searchPlaceholder = 'Type here to filter by name', onSearchChange = noop, className, scrollHeight, expandedGroups, onExpandGroupsChange = noop, showEmptyGroups = true, treeOptions = [], treeOptionsTooltip, disableAnimation = false } = props, remainingProps = __rest(props, ["groups", "items", "selectedGroups", "selectedItems", "onSelectionChange", "hasMultiselect", "showRadioButtons", "hideSearch", "hideTreeHead", "treeHeaderContent", "summary", "hideSummary", "search", "searchPlaceholder", "onSearchChange", "className", "scrollHeight", "expandedGroups", "onExpandGroupsChange", "showEmptyGroups", "treeOptions", "treeOptionsTooltip", "disableAnimation"]);
42
42
  const [state, dispatch] = useReducer(treeReducer, {
43
43
  groupedItems: [],
44
44
  flatItems: [],
@@ -273,7 +273,7 @@ const Tree = React.memo((props) => {
273
273
  const showSearch = !hideSearch;
274
274
  const showSummary = !hideSummary;
275
275
  const hasCustomSearch = !isNil(search);
276
- return (_jsxs("div", Object.assign({}, remainingProps, { className: treeClassNames, ref: treeRef }, { children: [_jsxs("div", Object.assign({ className: 'TreeHeader' }, { children: [showSearch && !hasCustomSearch && (_jsx(TreeSearch, { value: state.searchValue, onChange: handleSearchChange, placeholder: searchPlaceholder })), hasCustomSearch && search, showTreeHead && (_jsxs("div", Object.assign({ className: treeHeadClasses }, { children: [showSelectAll && (_jsx("div", Object.assign({ className: 'border border-right-only hidden-empty padding-right-10 margin-right-2' }, { children: _jsx(TreeSelectAll, { isChecked: state.allChecked, isEnabled: hasMultiselect, isIndeterminate: isIndeterminate, onSelect: handleSelectAll }) }))), _jsx("div", Object.assign({ className: 'display-flex justify-content-between align-items-start width-100pct' }, { children: showSummary
276
+ return (_jsxs("div", Object.assign({}, remainingProps, { className: treeClassNames, ref: treeRef }, { children: [_jsxs("div", Object.assign({ className: 'TreeHeader' }, { children: [treeHeaderContent, showSearch && !hasCustomSearch && (_jsx(TreeSearch, { value: state.searchValue, onChange: handleSearchChange, placeholder: searchPlaceholder })), hasCustomSearch && search, showTreeHead && (_jsxs("div", Object.assign({ className: treeHeadClasses }, { children: [showSelectAll && (_jsx("div", Object.assign({ className: 'border border-right-only hidden-empty padding-right-10 margin-right-2' }, { children: _jsx(TreeSelectAll, { isChecked: state.allChecked, isEnabled: hasMultiselect, isIndeterminate: isIndeterminate, onSelect: handleSelectAll }) }))), _jsx("div", Object.assign({ className: 'display-flex justify-content-between align-items-start width-100pct' }, { children: showSummary
277
277
  ? summary || (_jsx(TreeSummary, { children: map((typeCounter) => (_jsx(TypeCounter, { type: typeCounter, icon: `${typeCounter}`, value: state.assetCounts[typeCounter], onClick: handleFilterByType, isActive: state.typeFilter.includes(typeCounter), hasFilter: isFilterActive, enableActivity: enableActivity }, typeCounter)))(state.visibleTypeCounters) }))
278
278
  : null })), _jsx(TreeOptions, { treeOptions: treeOptions, treeOptionsTooltip: treeOptionsTooltip })] })))] })), _jsx(TreeRoot, Object.assign({ maxHeight: scrollHeight, disableAnimation: disableAnimation }, { children: content }))] })));
279
279
  }, customCompare);
@@ -1,5 +1,5 @@
1
1
  import React, { type PropsWithChildren } from 'react';
2
- export type DialogSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full' | 'fullwidth' | 'fullheight' | 'fullscreen';
2
+ export type DialogSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full' | 'fullwidth' | 'fullheight' | 'fullheight-lg' | 'fullheight-xl' | 'fullscreen';
3
3
  export type BaseDialogProps = {
4
4
  /**
5
5
  * Opens the dialog when set to `true`.
@@ -30,7 +30,7 @@ export type BaseDialogProps = {
30
30
  *
31
31
  * By default, the dialog has a medium size, and thus it can be omitted.
32
32
  *
33
- * Possible values are: `xs`, `sm`, `lg` `xl` `fullwidth` `fullheight` `fullscreen`
33
+ * Possible values are: `xs`, `sm`, `lg` `xl` `fullwidth` `fullheight` 'fullheight-lg' 'fullheight-xl' `fullscreen`
34
34
  *
35
35
  * @default 'md'
36
36
  */
@@ -109,6 +109,8 @@ declare const Dialog: {
109
109
  SIZE_FULL: "full";
110
110
  SIZE_FULL_WIDTH: "fullwidth";
111
111
  SIZE_FULL_HEIGHT: "fullheight";
112
+ SIZE_FULL_HEIGHT_LG: "fullheight-lg";
113
+ SIZE_FULL_HEIGHT_XL: "fullheight-xl";
112
114
  SIZE_FULL_SCREEN: "fullscreen";
113
115
  };
114
116
  export default Dialog;
@@ -85,7 +85,7 @@ const Dialog = (props) => {
85
85
  const modalClasses = classNames('modal', 'show', className);
86
86
  const isSmallestDialog = bsSize === 'xs';
87
87
  const hasChildren = !!children;
88
- const modalDialogClasses = classNames(MODAL_DIALOG_CLASS, useOverflow && 'modal-overflow', bsSize === 'xs' && 'modal-xs', bsSize === 'sm' && 'modal-sm', bsSize === 'lg' && 'modal-lg', bsSize === 'xl' && 'modal-xl', bsSize === 'full' && 'modal-full-width', bsSize === 'fullwidth' && 'modal-full-width', bsSize === 'fullheight' && 'modal-full-height', bsSize === 'fullscreen' && 'modal-fullscreen');
88
+ const modalDialogClasses = classNames(MODAL_DIALOG_CLASS, useOverflow && 'modal-overflow', bsSize === 'xs' && 'modal-xs', bsSize === 'sm' && 'modal-sm', bsSize === 'lg' && 'modal-lg', bsSize === 'xl' && 'modal-xl', bsSize === 'full' && 'modal-full-width', bsSize === 'fullwidth' && 'modal-full-width', bsSize === 'fullheight' && 'modal-full-height', bsSize === 'fullheight-lg' && 'modal-full-height modal-lg', bsSize === 'fullheight-xl' && 'modal-full-height modal-xl', bsSize === 'fullscreen' && 'modal-fullscreen');
89
89
  const spring = {
90
90
  type: 'spring',
91
91
  damping: 33,
@@ -124,5 +124,7 @@ Dialog.SIZE_XL = 'xl';
124
124
  Dialog.SIZE_FULL = 'full';
125
125
  Dialog.SIZE_FULL_WIDTH = 'fullwidth';
126
126
  Dialog.SIZE_FULL_HEIGHT = 'fullheight';
127
+ Dialog.SIZE_FULL_HEIGHT_LG = 'fullheight-lg';
128
+ Dialog.SIZE_FULL_HEIGHT_XL = 'fullheight-xl';
127
129
  Dialog.SIZE_FULL_SCREEN = 'fullscreen';
128
130
  export default Dialog;
@@ -0,0 +1,44 @@
1
+ import React from 'react';
2
+ import { type BaseDialogProps } from './Dialog';
3
+ export type OnboardingDialogProps = Pick<BaseDialogProps, 'show' | 'onClose' | 'className'> & {
4
+ /**
5
+ * The source URL of the image to be displayed in the dialog.
6
+ */
7
+ imageSrc: string;
8
+ /**
9
+ * Alternative text for the image, used for accessibility.
10
+ */
11
+ imageAlt?: string;
12
+ /**
13
+ * The title of the dialog. A welcome message.
14
+ */
15
+ title?: string | React.ReactNode;
16
+ /**
17
+ * A short description of the service and it's onboarding.
18
+ */
19
+ description?: string | React.ReactNode;
20
+ /**
21
+ * Hint text for restarting the onboarding process.
22
+ */
23
+ onboardingRestartHint?: string | React.ReactNode;
24
+ /**
25
+ * Detailed description for restarting the onboarding process.
26
+ */
27
+ onboardingRestartDescription?: string | React.ReactNode;
28
+ /**
29
+ * Text for the skip button
30
+ */
31
+ skipButtonText?: string | React.ReactNode;
32
+ /**
33
+ * Text for the button to start the tour
34
+ */
35
+ tourButtonText?: string | React.ReactNode;
36
+ /**
37
+ * Callback function to be called when the tour starts.
38
+ *
39
+ * @returns
40
+ */
41
+ onStartTour: () => void;
42
+ };
43
+ declare const OnboardingDialog: (props: OnboardingDialogProps) => import("react/jsx-runtime").JSX.Element;
44
+ export default OnboardingDialog;
@@ -0,0 +1,12 @@
1
+ import { __rest } from "tslib";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ // @ts-ignore-next-line importsNotUsedAsValues
4
+ import 'react';
5
+ import Dialog from './Dialog';
6
+ import Button from '../button/Button';
7
+ const OnboardingDialog = (props) => {
8
+ const { className, show, onClose, onStartTour, imageSrc, imageAlt, title = 'Welcome to the RIO UIKIT!', description = (_jsxs("span", { children: [_jsx("span", Object.assign({ className: 'text-medium' }, { children: "Get started with a quick tour to explore UIKIT and discover its key features." })), ' ', _jsx("span", { children: "It's the easiest way to get familiar with the service and make the most of your experience." })] })), onboardingRestartHint = 'Not ready to start now?', onboardingRestartDescription = 'You can always start the onboarding tour later from the service info option in the application header.', skipButtonText = 'Skip', tourButtonText = 'Start the tour' } = props, remainingProps = __rest(props, ["className", "show", "onClose", "onStartTour", "imageSrc", "imageAlt", "title", "description", "onboardingRestartHint", "onboardingRestartDescription", "skipButtonText", "tourButtonText"]);
9
+ const dialogClassName = `${className ? className : ''} onboarding-dialog`;
10
+ return (_jsx(Dialog, Object.assign({}, remainingProps, { show: show, bsSize: 'sm', onClose: onClose, onEsc: onClose, bodyClassName: 'padding-0', className: dialogClassName, showCloseButton: false, body: _jsxs("div", { children: [_jsx("div", { children: _jsx("img", { className: 'img-responsive rounded-top-right-extra-large rounded-top-left-extra-large', src: imageSrc, alt: imageAlt }) }), _jsxs("div", Object.assign({ className: 'position-relative padding-20 margin-top-10 margin-x-20' }, { children: [_jsx("div", Object.assign({ className: 'margin-bottom-15 margin-right-20 text-color-darkest' }, { children: _jsx("div", Object.assign({ className: 'text-size-h3 text-medium' }, { children: title })) })), _jsx("div", Object.assign({ className: 'text-color-darker' }, { children: _jsx("p", Object.assign({ className: 'text-size-16' }, { children: description })) })), _jsxs("div", Object.assign({ className: 'text-color-darker' }, { children: [_jsx("div", Object.assign({ className: 'margin-top-25 text-medium' }, { children: onboardingRestartHint })), _jsx("p", Object.assign({ className: 'text-color-darker padding-bottom-15 margin-top-5' }, { children: onboardingRestartDescription }))] })), _jsxs("div", Object.assign({ className: 'btn-toolbar justify-content-end margin-y-20' }, { children: [_jsx(Button, Object.assign({ bsStyle: Button.MUTED, onClick: onClose }, { children: skipButtonText })), _jsx(Button, Object.assign({ bsStyle: Button.PRIMARY, onClick: onStartTour }, { children: tourButtonText }))] }))] }))] }) })));
11
+ };
12
+ export default OnboardingDialog;
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { type BaseDialogProps } from './Dialog';
3
- export type SplitDialogProps = BaseDialogProps & {
3
+ export type SplitDialogProps = Omit<BaseDialogProps, 'useOverflow'> & {
4
4
  /**
5
5
  * The content to be shown on the left side.
6
6
  */
@@ -31,6 +31,12 @@ export type SplitDialogProps = BaseDialogProps & {
31
31
  * If the function returns `false`, the dialog will not be closed
32
32
  */
33
33
  onCloseValidation?: () => boolean;
34
+ /**
35
+ * Enables the modal body to overflow and use inline scrolling if needed.
36
+ *
37
+ * @default true
38
+ */
39
+ useOverflow?: boolean;
34
40
  };
35
41
  declare const SplitDialog: (props: SplitDialogProps) => import("react/jsx-runtime").JSX.Element;
36
42
  export default SplitDialog;
@@ -60,6 +60,7 @@ export type OnboardingTipProps = {
60
60
  * Defines whether to have a clickflow journey.
61
61
  *
62
62
  * @default false
63
+ * @deprecated Please use the "useOnboardingTour" hook instead.
63
64
  */
64
65
  clickflow?: boolean;
65
66
  /**
@@ -10,6 +10,7 @@ import { TEXT_ALIGNMENT } from '../../values/TextAlignment';
10
10
  import { PLACEMENT } from '../../values/Placement';
11
11
  const OnboardingTip = (props) => {
12
12
  const { id, show = false, placement = PLACEMENT.BOTTOM, title, content, onHide = noop, children, textAlignment = TEXT_ALIGNMENT.LEFT, useInDialog = false, showCloseIcon = true, clickflow = false, previousButton, nextButton, className = '', width, preventOverflow = true, popperConfig, } = props;
13
+ // DEPRECATED in favor of driver.js - see useOnboardingTour hook
13
14
  const clickFlowWithButtons = (_jsxs("div", Object.assign({ className: 'display-flex flex-column gap-25' }, { children: [_jsx("div", { children: content }), _jsxs("div", Object.assign({ className: `btn-toolbar justify-content-between ${showCloseIcon ? 'margin-right--25' : ''}` }, { children: [previousButton ? (_jsxs("div", Object.assign({ className: 'position-relative' }, { children: [_jsx("div", { className: 'bg-black opacity-10 rounded display-absolute inset-0' }), _jsxs(Button, Object.assign({ bsStyle: Button.SECONDARY, variant: Button.VARIANT_OUTLINE, className: 'border-none text-color-white', onClick: previousButton.onClick }, { children: [previousButton.iconName && (_jsx("span", { className: `rioglyph ${previousButton.iconName} text-color-white` })), _jsx("span", { children: previousButton.text })] }))] }))) : (_jsx("div", {})), nextButton ? (_jsxs(Button, Object.assign({ bsStyle: Button.SECONDARY, variant: Button.VARIANT_OUTLINE, className: 'border-color-white text-color-white', onClick: nextButton.onClick, iconRight: true }, { children: [_jsx("span", { children: nextButton.text }), nextButton.iconName && _jsx("span", { className: `rioglyph ${nextButton.iconName} text-color-white` })] }))) : (_jsx("div", {}))] }))] })));
14
15
  const tooltipWrapperClasses = classNames(useInDialog && 'z-index-max', className && className, clickflow && 'onboarding-clickflow');
15
16
  const overlay = (_jsx(Tooltip, Object.assign({ className: tooltipWrapperClasses, tooltipStyle: Tooltip.STYLE_ONBOARDING, id: id, onClick: onHide, width: width, textAlignment: textAlignment, allowOnTouch: true }, { children: _jsxs("div", Object.assign({ className: 'display-flex' }, { children: [_jsxs("div", Object.assign({ className: 'display-flex flex-column flex-1-1' }, { children: [title && _jsx("div", Object.assign({ className: 'tooltip-title' }, { children: title })), content && _jsx("div", Object.assign({ className: 'tooltip-content' }, { children: clickflow ? clickFlowWithButtons : content }))] })), showCloseIcon && _jsx("span", { className: 'tooltip-close rioglyph rioglyph-remove' })] })) })));
@@ -27,7 +27,12 @@ const Multiselect = (props) => {
27
27
  const [keyboardUsed, setKeyboardUsed] = useState(false);
28
28
  const refToggle = useRef(null);
29
29
  const refMultiSelectWrapper = useRef(null);
30
- const ref = useClickOutside(() => closeMenu());
30
+ const ref = useClickOutside(event => {
31
+ // Check if the click is truly outside the multiselect wrapper
32
+ if (refMultiSelectWrapper.current && !refMultiSelectWrapper.current.contains(event.target)) {
33
+ closeMenu();
34
+ }
35
+ });
31
36
  const mergedSelectRefs = useMergeRefs(refMultiSelectWrapper, ref);
32
37
  const updateSelectedItems = (optionsToCheck, selectedItem) => {
33
38
  if (selectedItem) {
@@ -61,7 +66,7 @@ const Multiselect = (props) => {
61
66
  const updateDOMValues = (updatedItemDOMValues = []) => {
62
67
  setItemDOMValues(updatedItemDOMValues);
63
68
  };
64
- const renderFilter = () => (_jsx(MultiselectToggleFilter, { isActive: isFilterActive || !!filterValue, selectedItemIds: selectedItemIds, filterValue: filterValue, onFilterChange: handleFilterChange, multiline: multiline }));
69
+ const renderFilter = () => (_jsx(MultiselectToggleFilter, { isActive: isFilterActive || !!filterValue, selectedItemIds: selectedItemIds, filterValue: filterValue, onFilterChange: handleFilterChange }));
65
70
  const renderSelection = () => {
66
71
  if (counterMessage || renderCounterMessage) {
67
72
  return (_jsx(MultiselectToggleCounter, { selectedAmount: selectedItemIds.length, counterMessage: counterMessage, customRenderer: renderCounterMessage }));
@@ -89,12 +94,18 @@ const Multiselect = (props) => {
89
94
  event.preventDefault();
90
95
  const targetFilterValue = event.currentTarget.value;
91
96
  const optionsFiltered = filterOptions(itemDOMValues, targetFilterValue, options);
92
- // highlight the first item of the search result if at least one item was found
97
+ if (!isOpen) {
98
+ // Ensure dropdown stays open when filtering
99
+ setIsOpen(true);
100
+ }
93
101
  const newFocusedItemIndex = optionsFiltered.length > 0 ? 0 : -1;
94
102
  setIsFilterActive(true);
95
103
  setFilterValue(targetFilterValue);
96
104
  setFilteredOptions(optionsFiltered);
97
- setKeyboardUsed(true);
105
+ if (optionsFiltered.length > 0) {
106
+ // Only set keyboard used if there are filtered options
107
+ setKeyboardUsed(true);
108
+ }
98
109
  setFocusedItemIndex(newFocusedItemIndex);
99
110
  };
100
111
  const onOptionChange = (currentSelectedItem) => {
@@ -103,6 +114,7 @@ const Multiselect = (props) => {
103
114
  return;
104
115
  }
105
116
  const updatedSelectedItems = currentSelectedItem ? updateSelection(currentSelectedItem.id) : selectedItemIds;
117
+ // Reset everything after an option was selected. Remove the filter again.
106
118
  setSelectedItemIds(updatedSelectedItems);
107
119
  setIsFilterActive(false);
108
120
  setFilterValue('');
@@ -157,7 +169,7 @@ const Multiselect = (props) => {
157
169
  // type submit by default in HTML. In order to differentiate between real click and a synthetic event
158
170
  // caused by they keyboard, use the event details. A synthetic event is always 0.
159
171
  const isKeyboardUsed = event.detail === 0;
160
- setIsOpen(!isOpen);
172
+ setIsOpen(prevValue => !prevValue);
161
173
  setKeyboardUsed(isKeyboardUsed);
162
174
  };
163
175
  const closeMenu = () => {
@@ -165,6 +177,9 @@ const Multiselect = (props) => {
165
177
  if (isOpen) {
166
178
  setIsOpen(false);
167
179
  setIsFilterActive(false);
180
+ setFilterValue('');
181
+ setFilteredOptions(options);
182
+ setFocusedItemIndex(DEFAULT_FOCUSED_ITEM_INDEX);
168
183
  setKeyboardUsed(false);
169
184
  (_a = refToggle === null || refToggle === void 0 ? void 0 : refToggle.current) === null || _a === void 0 ? void 0 : _a.focus();
170
185
  }
@@ -3,7 +3,6 @@ export type MultiselectToggleFilterProps = {
3
3
  isActive: boolean;
4
4
  selectedItemIds?: string[];
5
5
  filterValue: string;
6
- multiline: boolean;
7
6
  onFilterChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
8
7
  };
9
8
  declare const MultiselectToggleFilter: (props: MultiselectToggleFilterProps) => import("react/jsx-runtime").JSX.Element;
@@ -4,10 +4,10 @@ import 'react';
4
4
  import classNames from 'classnames';
5
5
  import isEmpty from 'lodash/fp/isEmpty';
6
6
  const MultiselectToggleFilter = (props) => {
7
- const { isActive, selectedItemIds, filterValue, multiline, onFilterChange } = props;
7
+ const { isActive, selectedItemIds, filterValue, onFilterChange } = props;
8
8
  const inputClasses = classNames('multiselect-filter-input', isEmpty(selectedItemIds) && 'multiselect-filter-input-placeholder', isActive && 'multiselect-filter-input-active');
9
9
  return (_jsx("input", { type: 'text', role: 'searchbox', className: inputClasses,
10
10
  // biome-ignore lint/a11y/noAutofocus: autofocus is intentionally set to allow instant typing to filter
11
- autoFocus: true, onChange: onFilterChange, defaultValue: filterValue }));
11
+ autoFocus: true, onChange: onFilterChange, value: filterValue }));
12
12
  };
13
13
  export default MultiselectToggleFilter;
@@ -0,0 +1,128 @@
1
+ import { type PopoverDOM as DriverPopoverDOM, type State as DriverState, type AllowedButtons } from 'driver.js';
2
+ import 'driver.js/dist/driver.css';
3
+ export type PopoverDOM = DriverPopoverDOM;
4
+ export type OnboardingState = DriverState;
5
+ export type OnboardingStep = {
6
+ element?: string | Element;
7
+ onHighlightStarted?: (element: Element | undefined, step: OnboardingStep, opts: any) => void;
8
+ onHighlighted?: (element: Element | undefined, step: OnboardingStep, opts: any) => void;
9
+ onDeselected?: (element: Element | undefined, step: OnboardingStep, opts: any) => void;
10
+ popover?: {
11
+ title?: string;
12
+ description?: string;
13
+ side?: 'top' | 'right' | 'bottom' | 'left' | 'over';
14
+ align?: 'start' | 'center' | 'end';
15
+ showButtons?: ('next' | 'previous' | 'close')[];
16
+ disableButtons?: ('next' | 'previous' | 'close')[];
17
+ popoverClass?: string;
18
+ doneBtnText?: string;
19
+ nextBtnText?: string;
20
+ prevBtnText?: string;
21
+ };
22
+ };
23
+ type OnboardingOptions = {
24
+ /**
25
+ * Array of steps to highlight. You should pass this when you want to setup a product tour.
26
+ */
27
+ steps?: OnboardingStep[];
28
+ /**
29
+ * Text for the previous button in the onboarding popover.
30
+ */
31
+ prevBtnText?: string;
32
+ /**
33
+ * Text for the next button in the onboarding popover.
34
+ */
35
+ nextBtnText?: string;
36
+ /**
37
+ * Text for the done button in the onboarding popover.
38
+ */
39
+ doneBtnText?: string;
40
+ /**
41
+ * Indicates whether to show progress in the onboarding popover.
42
+ *
43
+ * @default true
44
+ */
45
+ showProgress?: boolean;
46
+ /**
47
+ * Whether to allow closing the popover by clicking on the backdrop.
48
+ * This should be disabled during the tour to ensure th user completes the tour.
49
+ * But can be enabled on the last step.
50
+ *
51
+ * @default false
52
+ */
53
+ allowClose?: boolean;
54
+ /**
55
+ * Distance between the highlighted element and the cutout.
56
+ *
57
+ * @default 10
58
+ */
59
+ stagePadding?: number;
60
+ /**
61
+ * Radius of the cutout around the highlighted element.
62
+ *
63
+ * @default 5
64
+ */
65
+ stageRadius?: number;
66
+ /**
67
+ * Whether to allow keyboard navigation.
68
+ *
69
+ * @default true
70
+ */
71
+ allowKeyboardControl?: boolean;
72
+ /**
73
+ * Array of buttons to show in the popover. Defaults to ["next", "previous", "close"]
74
+ * for product tours and [] for single element highlighting.
75
+ */
76
+ showButtons?: AllowedButtons[];
77
+ /**
78
+ * Array of buttons to disable. This is useful when you want to show some of the buttons, but disable some of them.
79
+ */
80
+ disableButtons?: AllowedButtons[];
81
+ /**
82
+ * Option to disable the backdrop. Note, the backdrop element is still there but with 100% opacity
83
+ * and the close on the backdrop is disabled.
84
+ *
85
+ * @default false
86
+ */
87
+ noBackdrop?: boolean;
88
+ /**
89
+ * Additional classes set on the popover itself.
90
+ */
91
+ popoverClass?: string;
92
+ /**
93
+ * Callback triggered when the onboarding popover renders.
94
+ *
95
+ * @param popover
96
+ * @param state
97
+ * @returns
98
+ */
99
+ onPopoverRender?: (popover: PopoverDOM, state: OnboardingState) => void;
100
+ };
101
+ export declare const useOnboardingTour: (params: OnboardingOptions) => {
102
+ run: () => void;
103
+ destroy: () => void;
104
+ onboardingState: () => DriverState;
105
+ refresh: () => void;
106
+ isActive: () => boolean;
107
+ moveNext: () => void;
108
+ movePrevious: () => void;
109
+ moveTo: (stepNumber: number) => void;
110
+ hasNextStep: () => false | import("driver.js").DriveStep;
111
+ hasPreviousStep: () => false | import("driver.js").DriveStep;
112
+ isFirstStep: () => boolean;
113
+ isLastStep: () => boolean;
114
+ getActiveIndex: () => number | undefined;
115
+ };
116
+ type OnboardingTipOptions = {
117
+ allowClose?: boolean;
118
+ stagePadding?: number;
119
+ stageRadius?: number;
120
+ noBackdrop?: boolean;
121
+ };
122
+ export declare const useOnboardingTip: (options?: OnboardingTipOptions) => {
123
+ highlight: (step: OnboardingStep) => void;
124
+ destroy: () => void;
125
+ refresh: () => void;
126
+ isActive: () => boolean;
127
+ };
128
+ export {};
@@ -0,0 +1,75 @@
1
+ import { driver, } from 'driver.js';
2
+ import 'driver.js/dist/driver.css';
3
+ export const useOnboardingTour = (params) => {
4
+ const { steps, prevBtnText = 'Previous', nextBtnText = 'Next', doneBtnText = 'Done', showProgress = true, allowClose = false, stagePadding = 10, stageRadius = 5, allowKeyboardControl = true, showButtons, disableButtons, popoverClass, noBackdrop = false, onPopoverRender = () => { }, } = params;
5
+ const handlePopoverRender = (popover, options) => {
6
+ onPopoverRender(popover, options.state);
7
+ };
8
+ const isSingleStep = !steps || steps.length === 1;
9
+ // This configuration is applied to all steps.
10
+ // Driver.js allows also for individual customization for single steps too.
11
+ const driverInstance = driver({
12
+ steps,
13
+ prevBtnText,
14
+ nextBtnText,
15
+ doneBtnText,
16
+ showProgress: isSingleStep ? false : showProgress,
17
+ showButtons: isSingleStep ? ['close'] : showButtons,
18
+ allowClose,
19
+ overlayOpacity: noBackdrop ? 0 : 0.5,
20
+ disableButtons,
21
+ progressText: '{{current}} / {{total}}',
22
+ overlayColor: 'var(--color-black)',
23
+ stagePadding,
24
+ stageRadius,
25
+ allowKeyboardControl,
26
+ popoverClass,
27
+ onPopoverRender: handlePopoverRender,
28
+ });
29
+ return {
30
+ // Use for onboarding tours. Pass in all steps as "steps" parameter for initial configuration.
31
+ run: () => driverInstance.drive(),
32
+ // Use for single element highlights -> see useOnboardingTip
33
+ // highlight: (step: OnboardingStep) => driverInstance.highlight(step),
34
+ // Cleanup the onboarding
35
+ destroy: () => driverInstance.destroy(),
36
+ // Gets the current state of the onboarding with the current step
37
+ onboardingState: () => driverInstance.getState(),
38
+ // Recalculate and redraw the highlight
39
+ refresh: () => driverInstance.refresh(),
40
+ // Is the tour or highlight currently active
41
+ isActive: () => driverInstance.isActive(),
42
+ // Move to the next step
43
+ moveNext: () => driverInstance.moveNext(),
44
+ // Move to the previous step
45
+ movePrevious: () => driverInstance.movePrevious(),
46
+ // Move to the step 4
47
+ moveTo: (stepNumber) => driverInstance.moveTo(stepNumber),
48
+ // Is there a next step
49
+ hasNextStep: () => driverInstance.hasNextStep(),
50
+ // Is there a previous step
51
+ hasPreviousStep: () => driverInstance.hasPreviousStep(),
52
+ // Is the current step the first step
53
+ isFirstStep: () => driverInstance.isFirstStep(),
54
+ // Is the current step the last step
55
+ isLastStep: () => driverInstance.isLastStep(),
56
+ // Gets the active step index
57
+ getActiveIndex: () => driverInstance.getActiveIndex(),
58
+ };
59
+ };
60
+ export const useOnboardingTip = (options) => {
61
+ const { allowClose = true, stagePadding = 0, stageRadius = 5, noBackdrop = true } = options || {};
62
+ const driverInstance = driver({
63
+ allowClose,
64
+ stagePadding,
65
+ stageRadius,
66
+ overlayOpacity: noBackdrop ? 0 : 0.5,
67
+ overlayColor: undefined,
68
+ });
69
+ return {
70
+ highlight: (step) => driverInstance.highlight(step),
71
+ destroy: () => driverInstance.destroy(),
72
+ refresh: () => driverInstance.refresh(),
73
+ isActive: () => driverInstance.isActive(),
74
+ };
75
+ };
@@ -0,0 +1,2 @@
1
+ export { default } from './components/onboarding/Onboarding';
2
+ export * from './components/onboarding/Onboarding';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = void 0;
4
+ const tslib_1 = require("tslib");
5
+ var Onboarding_1 = require("./components/onboarding/Onboarding");
6
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return tslib_1.__importDefault(Onboarding_1).default; } });
7
+ tslib_1.__exportStar(require("./components/onboarding/Onboarding"), exports);
@@ -0,0 +1,2 @@
1
+ export { default } from './components/dialog/OnboardingDialog';
2
+ export * from './components/dialog/OnboardingDialog';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = void 0;
4
+ const tslib_1 = require("tslib");
5
+ var OnboardingDialog_1 = require("./components/dialog/OnboardingDialog");
6
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return tslib_1.__importDefault(OnboardingDialog_1).default; } });
7
+ tslib_1.__exportStar(require("./components/dialog/OnboardingDialog"), exports);
@@ -28,9 +28,7 @@ const getCurrentCategoryElement = (children, currentCategoryId) => {
28
28
  };
29
29
  const renderTreesOffscreen = (children, categoryId) => {
30
30
  return react_1.default.Children.map(children, child => {
31
- const offscreenClasses = (0, classnames_1.default)('TreeOffscreenWrapper', 'flex-1-1', // stretch to use 100 percent of the remaining space
32
- 'flex flex-column', // set this one to flex as well, so children can use flex grow to use remaining space
33
- child && child.props.id !== categoryId && 'position-offscreen pointer-events-none');
31
+ const offscreenClasses = (0, classnames_1.default)('TreeOffscreenWrapper', child && child.props.id !== categoryId && 'position-offscreen pointer-events-none');
34
32
  return (0, jsx_runtime_1.jsx)("div", Object.assign({ className: offscreenClasses }, { children: child }));
35
33
  });
36
34
  };
@@ -157,6 +157,7 @@ export type TreeProps = {
157
157
  * @default false
158
158
  */
159
159
  hideTreeHead?: boolean;
160
+ treeHeaderContent?: React.ReactElement;
160
161
  /**
161
162
  * Defines the max-height of the scrollable list.
162
163
  */
@@ -43,7 +43,7 @@ const filterProps = (0, omit_1.default)([
43
43
  ]);
44
44
  const customCompare = (prevProps, nextProps) => (0, isEqual_1.default)(filterProps(prevProps), filterProps(nextProps));
45
45
  const Tree = react_1.default.memo((props) => {
46
- const { groups = [], items = [], selectedGroups = [], selectedItems = [], onSelectionChange = noop_1.default, hasMultiselect = true, showRadioButtons = false, hideSearch = false, hideTreeHead, summary, hideSummary = false, search, searchPlaceholder = 'Type here to filter by name', onSearchChange = noop_1.default, className, scrollHeight, expandedGroups, onExpandGroupsChange = noop_1.default, showEmptyGroups = true, treeOptions = [], treeOptionsTooltip, disableAnimation = false } = props, remainingProps = tslib_1.__rest(props, ["groups", "items", "selectedGroups", "selectedItems", "onSelectionChange", "hasMultiselect", "showRadioButtons", "hideSearch", "hideTreeHead", "summary", "hideSummary", "search", "searchPlaceholder", "onSearchChange", "className", "scrollHeight", "expandedGroups", "onExpandGroupsChange", "showEmptyGroups", "treeOptions", "treeOptionsTooltip", "disableAnimation"]);
46
+ const { groups = [], items = [], selectedGroups = [], selectedItems = [], onSelectionChange = noop_1.default, hasMultiselect = true, showRadioButtons = false, hideSearch = false, hideTreeHead, treeHeaderContent, summary, hideSummary = false, search, searchPlaceholder = 'Type here to filter by name', onSearchChange = noop_1.default, className, scrollHeight, expandedGroups, onExpandGroupsChange = noop_1.default, showEmptyGroups = true, treeOptions = [], treeOptionsTooltip, disableAnimation = false } = props, remainingProps = tslib_1.__rest(props, ["groups", "items", "selectedGroups", "selectedItems", "onSelectionChange", "hasMultiselect", "showRadioButtons", "hideSearch", "hideTreeHead", "treeHeaderContent", "summary", "hideSummary", "search", "searchPlaceholder", "onSearchChange", "className", "scrollHeight", "expandedGroups", "onExpandGroupsChange", "showEmptyGroups", "treeOptions", "treeOptionsTooltip", "disableAnimation"]);
47
47
  const [state, dispatch] = (0, react_1.useReducer)(treeReducer_1.treeReducer, {
48
48
  groupedItems: [],
49
49
  flatItems: [],
@@ -278,7 +278,7 @@ const Tree = react_1.default.memo((props) => {
278
278
  const showSearch = !hideSearch;
279
279
  const showSummary = !hideSummary;
280
280
  const hasCustomSearch = !(0, isNil_1.default)(search);
281
- return ((0, jsx_runtime_1.jsxs)("div", Object.assign({}, remainingProps, { className: treeClassNames, ref: treeRef }, { children: [(0, jsx_runtime_1.jsxs)("div", Object.assign({ className: 'TreeHeader' }, { children: [showSearch && !hasCustomSearch && ((0, jsx_runtime_1.jsx)(TreeSearch_1.default, { value: state.searchValue, onChange: handleSearchChange, placeholder: searchPlaceholder })), hasCustomSearch && search, showTreeHead && ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: treeHeadClasses }, { children: [showSelectAll && ((0, jsx_runtime_1.jsx)("div", Object.assign({ className: 'border border-right-only hidden-empty padding-right-10 margin-right-2' }, { children: (0, jsx_runtime_1.jsx)(TreeSelectAll_1.default, { isChecked: state.allChecked, isEnabled: hasMultiselect, isIndeterminate: isIndeterminate, onSelect: handleSelectAll }) }))), (0, jsx_runtime_1.jsx)("div", Object.assign({ className: 'display-flex justify-content-between align-items-start width-100pct' }, { children: showSummary
281
+ return ((0, jsx_runtime_1.jsxs)("div", Object.assign({}, remainingProps, { className: treeClassNames, ref: treeRef }, { children: [(0, jsx_runtime_1.jsxs)("div", Object.assign({ className: 'TreeHeader' }, { children: [treeHeaderContent, showSearch && !hasCustomSearch && ((0, jsx_runtime_1.jsx)(TreeSearch_1.default, { value: state.searchValue, onChange: handleSearchChange, placeholder: searchPlaceholder })), hasCustomSearch && search, showTreeHead && ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: treeHeadClasses }, { children: [showSelectAll && ((0, jsx_runtime_1.jsx)("div", Object.assign({ className: 'border border-right-only hidden-empty padding-right-10 margin-right-2' }, { children: (0, jsx_runtime_1.jsx)(TreeSelectAll_1.default, { isChecked: state.allChecked, isEnabled: hasMultiselect, isIndeterminate: isIndeterminate, onSelect: handleSelectAll }) }))), (0, jsx_runtime_1.jsx)("div", Object.assign({ className: 'display-flex justify-content-between align-items-start width-100pct' }, { children: showSummary
282
282
  ? summary || ((0, jsx_runtime_1.jsx)(TreeSummary_1.default, { children: (0, map_1.default)((typeCounter) => ((0, jsx_runtime_1.jsx)(TypeCounter_1.default, { type: typeCounter, icon: `${typeCounter}`, value: state.assetCounts[typeCounter], onClick: handleFilterByType, isActive: state.typeFilter.includes(typeCounter), hasFilter: isFilterActive, enableActivity: enableActivity }, typeCounter)))(state.visibleTypeCounters) }))
283
283
  : null })), (0, jsx_runtime_1.jsx)(TreeOptions_1.default, { treeOptions: treeOptions, treeOptionsTooltip: treeOptionsTooltip })] })))] })), (0, jsx_runtime_1.jsx)(TreeRoot_1.default, Object.assign({ maxHeight: scrollHeight, disableAnimation: disableAnimation }, { children: content }))] })));
284
284
  }, customCompare);
@@ -1,5 +1,5 @@
1
1
  import React, { type PropsWithChildren } from 'react';
2
- export type DialogSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full' | 'fullwidth' | 'fullheight' | 'fullscreen';
2
+ export type DialogSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full' | 'fullwidth' | 'fullheight' | 'fullheight-lg' | 'fullheight-xl' | 'fullscreen';
3
3
  export type BaseDialogProps = {
4
4
  /**
5
5
  * Opens the dialog when set to `true`.
@@ -30,7 +30,7 @@ export type BaseDialogProps = {
30
30
  *
31
31
  * By default, the dialog has a medium size, and thus it can be omitted.
32
32
  *
33
- * Possible values are: `xs`, `sm`, `lg` `xl` `fullwidth` `fullheight` `fullscreen`
33
+ * Possible values are: `xs`, `sm`, `lg` `xl` `fullwidth` `fullheight` 'fullheight-lg' 'fullheight-xl' `fullscreen`
34
34
  *
35
35
  * @default 'md'
36
36
  */
@@ -109,6 +109,8 @@ declare const Dialog: {
109
109
  SIZE_FULL: "full";
110
110
  SIZE_FULL_WIDTH: "fullwidth";
111
111
  SIZE_FULL_HEIGHT: "fullheight";
112
+ SIZE_FULL_HEIGHT_LG: "fullheight-lg";
113
+ SIZE_FULL_HEIGHT_XL: "fullheight-xl";
112
114
  SIZE_FULL_SCREEN: "fullscreen";
113
115
  };
114
116
  export default Dialog;
@@ -87,7 +87,7 @@ const Dialog = (props) => {
87
87
  const modalClasses = (0, classnames_1.default)('modal', 'show', className);
88
88
  const isSmallestDialog = bsSize === 'xs';
89
89
  const hasChildren = !!children;
90
- const modalDialogClasses = (0, classnames_1.default)(MODAL_DIALOG_CLASS, useOverflow && 'modal-overflow', bsSize === 'xs' && 'modal-xs', bsSize === 'sm' && 'modal-sm', bsSize === 'lg' && 'modal-lg', bsSize === 'xl' && 'modal-xl', bsSize === 'full' && 'modal-full-width', bsSize === 'fullwidth' && 'modal-full-width', bsSize === 'fullheight' && 'modal-full-height', bsSize === 'fullscreen' && 'modal-fullscreen');
90
+ const modalDialogClasses = (0, classnames_1.default)(MODAL_DIALOG_CLASS, useOverflow && 'modal-overflow', bsSize === 'xs' && 'modal-xs', bsSize === 'sm' && 'modal-sm', bsSize === 'lg' && 'modal-lg', bsSize === 'xl' && 'modal-xl', bsSize === 'full' && 'modal-full-width', bsSize === 'fullwidth' && 'modal-full-width', bsSize === 'fullheight' && 'modal-full-height', bsSize === 'fullheight-lg' && 'modal-full-height modal-lg', bsSize === 'fullheight-xl' && 'modal-full-height modal-xl', bsSize === 'fullscreen' && 'modal-fullscreen');
91
91
  const spring = {
92
92
  type: 'spring',
93
93
  damping: 33,
@@ -126,5 +126,7 @@ Dialog.SIZE_XL = 'xl';
126
126
  Dialog.SIZE_FULL = 'full';
127
127
  Dialog.SIZE_FULL_WIDTH = 'fullwidth';
128
128
  Dialog.SIZE_FULL_HEIGHT = 'fullheight';
129
+ Dialog.SIZE_FULL_HEIGHT_LG = 'fullheight-lg';
130
+ Dialog.SIZE_FULL_HEIGHT_XL = 'fullheight-xl';
129
131
  Dialog.SIZE_FULL_SCREEN = 'fullscreen';
130
132
  exports.default = Dialog;
@@ -0,0 +1,44 @@
1
+ import React from 'react';
2
+ import { type BaseDialogProps } from './Dialog';
3
+ export type OnboardingDialogProps = Pick<BaseDialogProps, 'show' | 'onClose' | 'className'> & {
4
+ /**
5
+ * The source URL of the image to be displayed in the dialog.
6
+ */
7
+ imageSrc: string;
8
+ /**
9
+ * Alternative text for the image, used for accessibility.
10
+ */
11
+ imageAlt?: string;
12
+ /**
13
+ * The title of the dialog. A welcome message.
14
+ */
15
+ title?: string | React.ReactNode;
16
+ /**
17
+ * A short description of the service and it's onboarding.
18
+ */
19
+ description?: string | React.ReactNode;
20
+ /**
21
+ * Hint text for restarting the onboarding process.
22
+ */
23
+ onboardingRestartHint?: string | React.ReactNode;
24
+ /**
25
+ * Detailed description for restarting the onboarding process.
26
+ */
27
+ onboardingRestartDescription?: string | React.ReactNode;
28
+ /**
29
+ * Text for the skip button
30
+ */
31
+ skipButtonText?: string | React.ReactNode;
32
+ /**
33
+ * Text for the button to start the tour
34
+ */
35
+ tourButtonText?: string | React.ReactNode;
36
+ /**
37
+ * Callback function to be called when the tour starts.
38
+ *
39
+ * @returns
40
+ */
41
+ onStartTour: () => void;
42
+ };
43
+ declare const OnboardingDialog: (props: OnboardingDialogProps) => import("react/jsx-runtime").JSX.Element;
44
+ export default OnboardingDialog;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ // @ts-ignore-next-line importsNotUsedAsValues
6
+ require("react");
7
+ const Dialog_1 = tslib_1.__importDefault(require("./Dialog"));
8
+ const Button_1 = tslib_1.__importDefault(require("../button/Button"));
9
+ const OnboardingDialog = (props) => {
10
+ const { className, show, onClose, onStartTour, imageSrc, imageAlt, title = 'Welcome to the RIO UIKIT!', description = ((0, jsx_runtime_1.jsxs)("span", { children: [(0, jsx_runtime_1.jsx)("span", Object.assign({ className: 'text-medium' }, { children: "Get started with a quick tour to explore UIKIT and discover its key features." })), ' ', (0, jsx_runtime_1.jsx)("span", { children: "It's the easiest way to get familiar with the service and make the most of your experience." })] })), onboardingRestartHint = 'Not ready to start now?', onboardingRestartDescription = 'You can always start the onboarding tour later from the service info option in the application header.', skipButtonText = 'Skip', tourButtonText = 'Start the tour' } = props, remainingProps = tslib_1.__rest(props, ["className", "show", "onClose", "onStartTour", "imageSrc", "imageAlt", "title", "description", "onboardingRestartHint", "onboardingRestartDescription", "skipButtonText", "tourButtonText"]);
11
+ const dialogClassName = `${className ? className : ''} onboarding-dialog`;
12
+ return ((0, jsx_runtime_1.jsx)(Dialog_1.default, Object.assign({}, remainingProps, { show: show, bsSize: 'sm', onClose: onClose, onEsc: onClose, bodyClassName: 'padding-0', className: dialogClassName, showCloseButton: false, body: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)("img", { className: 'img-responsive rounded-top-right-extra-large rounded-top-left-extra-large', src: imageSrc, alt: imageAlt }) }), (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: 'position-relative padding-20 margin-top-10 margin-x-20' }, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ className: 'margin-bottom-15 margin-right-20 text-color-darkest' }, { children: (0, jsx_runtime_1.jsx)("div", Object.assign({ className: 'text-size-h3 text-medium' }, { children: title })) })), (0, jsx_runtime_1.jsx)("div", Object.assign({ className: 'text-color-darker' }, { children: (0, jsx_runtime_1.jsx)("p", Object.assign({ className: 'text-size-16' }, { children: description })) })), (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: 'text-color-darker' }, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ className: 'margin-top-25 text-medium' }, { children: onboardingRestartHint })), (0, jsx_runtime_1.jsx)("p", Object.assign({ className: 'text-color-darker padding-bottom-15 margin-top-5' }, { children: onboardingRestartDescription }))] })), (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: 'btn-toolbar justify-content-end margin-y-20' }, { children: [(0, jsx_runtime_1.jsx)(Button_1.default, Object.assign({ bsStyle: Button_1.default.MUTED, onClick: onClose }, { children: skipButtonText })), (0, jsx_runtime_1.jsx)(Button_1.default, Object.assign({ bsStyle: Button_1.default.PRIMARY, onClick: onStartTour }, { children: tourButtonText }))] }))] }))] }) })));
13
+ };
14
+ exports.default = OnboardingDialog;
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { type BaseDialogProps } from './Dialog';
3
- export type SplitDialogProps = BaseDialogProps & {
3
+ export type SplitDialogProps = Omit<BaseDialogProps, 'useOverflow'> & {
4
4
  /**
5
5
  * The content to be shown on the left side.
6
6
  */
@@ -31,6 +31,12 @@ export type SplitDialogProps = BaseDialogProps & {
31
31
  * If the function returns `false`, the dialog will not be closed
32
32
  */
33
33
  onCloseValidation?: () => boolean;
34
+ /**
35
+ * Enables the modal body to overflow and use inline scrolling if needed.
36
+ *
37
+ * @default true
38
+ */
39
+ useOverflow?: boolean;
34
40
  };
35
41
  declare const SplitDialog: (props: SplitDialogProps) => import("react/jsx-runtime").JSX.Element;
36
42
  export default SplitDialog;
@@ -60,6 +60,7 @@ export type OnboardingTipProps = {
60
60
  * Defines whether to have a clickflow journey.
61
61
  *
62
62
  * @default false
63
+ * @deprecated Please use the "useOnboardingTour" hook instead.
63
64
  */
64
65
  clickflow?: boolean;
65
66
  /**
@@ -13,6 +13,7 @@ const TextAlignment_1 = require("../../values/TextAlignment");
13
13
  const Placement_1 = require("../../values/Placement");
14
14
  const OnboardingTip = (props) => {
15
15
  const { id, show = false, placement = Placement_1.PLACEMENT.BOTTOM, title, content, onHide = noop_1.default, children, textAlignment = TextAlignment_1.TEXT_ALIGNMENT.LEFT, useInDialog = false, showCloseIcon = true, clickflow = false, previousButton, nextButton, className = '', width, preventOverflow = true, popperConfig, } = props;
16
+ // DEPRECATED in favor of driver.js - see useOnboardingTour hook
16
17
  const clickFlowWithButtons = ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: 'display-flex flex-column gap-25' }, { children: [(0, jsx_runtime_1.jsx)("div", { children: content }), (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: `btn-toolbar justify-content-between ${showCloseIcon ? 'margin-right--25' : ''}` }, { children: [previousButton ? ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: 'position-relative' }, { children: [(0, jsx_runtime_1.jsx)("div", { className: 'bg-black opacity-10 rounded display-absolute inset-0' }), (0, jsx_runtime_1.jsxs)(Button_1.default, Object.assign({ bsStyle: Button_1.default.SECONDARY, variant: Button_1.default.VARIANT_OUTLINE, className: 'border-none text-color-white', onClick: previousButton.onClick }, { children: [previousButton.iconName && ((0, jsx_runtime_1.jsx)("span", { className: `rioglyph ${previousButton.iconName} text-color-white` })), (0, jsx_runtime_1.jsx)("span", { children: previousButton.text })] }))] }))) : ((0, jsx_runtime_1.jsx)("div", {})), nextButton ? ((0, jsx_runtime_1.jsxs)(Button_1.default, Object.assign({ bsStyle: Button_1.default.SECONDARY, variant: Button_1.default.VARIANT_OUTLINE, className: 'border-color-white text-color-white', onClick: nextButton.onClick, iconRight: true }, { children: [(0, jsx_runtime_1.jsx)("span", { children: nextButton.text }), nextButton.iconName && (0, jsx_runtime_1.jsx)("span", { className: `rioglyph ${nextButton.iconName} text-color-white` })] }))) : ((0, jsx_runtime_1.jsx)("div", {}))] }))] })));
17
18
  const tooltipWrapperClasses = (0, classnames_1.default)(useInDialog && 'z-index-max', className && className, clickflow && 'onboarding-clickflow');
18
19
  const overlay = ((0, jsx_runtime_1.jsx)(Tooltip_1.default, Object.assign({ className: tooltipWrapperClasses, tooltipStyle: Tooltip_1.default.STYLE_ONBOARDING, id: id, onClick: onHide, width: width, textAlignment: textAlignment, allowOnTouch: true }, { children: (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: 'display-flex' }, { children: [(0, jsx_runtime_1.jsxs)("div", Object.assign({ className: 'display-flex flex-column flex-1-1' }, { children: [title && (0, jsx_runtime_1.jsx)("div", Object.assign({ className: 'tooltip-title' }, { children: title })), content && (0, jsx_runtime_1.jsx)("div", Object.assign({ className: 'tooltip-content' }, { children: clickflow ? clickFlowWithButtons : content }))] })), showCloseIcon && (0, jsx_runtime_1.jsx)("span", { className: 'tooltip-close rioglyph rioglyph-remove' })] })) })));
@@ -29,7 +29,12 @@ const Multiselect = (props) => {
29
29
  const [keyboardUsed, setKeyboardUsed] = (0, react_1.useState)(false);
30
30
  const refToggle = (0, react_1.useRef)(null);
31
31
  const refMultiSelectWrapper = (0, react_1.useRef)(null);
32
- const ref = (0, useClickOutside_1.default)(() => closeMenu());
32
+ const ref = (0, useClickOutside_1.default)(event => {
33
+ // Check if the click is truly outside the multiselect wrapper
34
+ if (refMultiSelectWrapper.current && !refMultiSelectWrapper.current.contains(event.target)) {
35
+ closeMenu();
36
+ }
37
+ });
33
38
  const mergedSelectRefs = (0, useMergeRefs_1.default)(refMultiSelectWrapper, ref);
34
39
  const updateSelectedItems = (optionsToCheck, selectedItem) => {
35
40
  if (selectedItem) {
@@ -63,7 +68,7 @@ const Multiselect = (props) => {
63
68
  const updateDOMValues = (updatedItemDOMValues = []) => {
64
69
  setItemDOMValues(updatedItemDOMValues);
65
70
  };
66
- const renderFilter = () => ((0, jsx_runtime_1.jsx)(MultiselectToggleFilter_1.default, { isActive: isFilterActive || !!filterValue, selectedItemIds: selectedItemIds, filterValue: filterValue, onFilterChange: handleFilterChange, multiline: multiline }));
71
+ const renderFilter = () => ((0, jsx_runtime_1.jsx)(MultiselectToggleFilter_1.default, { isActive: isFilterActive || !!filterValue, selectedItemIds: selectedItemIds, filterValue: filterValue, onFilterChange: handleFilterChange }));
67
72
  const renderSelection = () => {
68
73
  if (counterMessage || renderCounterMessage) {
69
74
  return ((0, jsx_runtime_1.jsx)(MultiselectToggleCounter_1.default, { selectedAmount: selectedItemIds.length, counterMessage: counterMessage, customRenderer: renderCounterMessage }));
@@ -91,12 +96,18 @@ const Multiselect = (props) => {
91
96
  event.preventDefault();
92
97
  const targetFilterValue = event.currentTarget.value;
93
98
  const optionsFiltered = (0, BaseSelectDropdown_1.filterOptions)(itemDOMValues, targetFilterValue, options);
94
- // highlight the first item of the search result if at least one item was found
99
+ if (!isOpen) {
100
+ // Ensure dropdown stays open when filtering
101
+ setIsOpen(true);
102
+ }
95
103
  const newFocusedItemIndex = optionsFiltered.length > 0 ? 0 : -1;
96
104
  setIsFilterActive(true);
97
105
  setFilterValue(targetFilterValue);
98
106
  setFilteredOptions(optionsFiltered);
99
- setKeyboardUsed(true);
107
+ if (optionsFiltered.length > 0) {
108
+ // Only set keyboard used if there are filtered options
109
+ setKeyboardUsed(true);
110
+ }
100
111
  setFocusedItemIndex(newFocusedItemIndex);
101
112
  };
102
113
  const onOptionChange = (currentSelectedItem) => {
@@ -105,6 +116,7 @@ const Multiselect = (props) => {
105
116
  return;
106
117
  }
107
118
  const updatedSelectedItems = currentSelectedItem ? updateSelection(currentSelectedItem.id) : selectedItemIds;
119
+ // Reset everything after an option was selected. Remove the filter again.
108
120
  setSelectedItemIds(updatedSelectedItems);
109
121
  setIsFilterActive(false);
110
122
  setFilterValue('');
@@ -159,7 +171,7 @@ const Multiselect = (props) => {
159
171
  // type submit by default in HTML. In order to differentiate between real click and a synthetic event
160
172
  // caused by they keyboard, use the event details. A synthetic event is always 0.
161
173
  const isKeyboardUsed = event.detail === 0;
162
- setIsOpen(!isOpen);
174
+ setIsOpen(prevValue => !prevValue);
163
175
  setKeyboardUsed(isKeyboardUsed);
164
176
  };
165
177
  const closeMenu = () => {
@@ -167,6 +179,9 @@ const Multiselect = (props) => {
167
179
  if (isOpen) {
168
180
  setIsOpen(false);
169
181
  setIsFilterActive(false);
182
+ setFilterValue('');
183
+ setFilteredOptions(options);
184
+ setFocusedItemIndex(DEFAULT_FOCUSED_ITEM_INDEX);
170
185
  setKeyboardUsed(false);
171
186
  (_a = refToggle === null || refToggle === void 0 ? void 0 : refToggle.current) === null || _a === void 0 ? void 0 : _a.focus();
172
187
  }
@@ -3,7 +3,6 @@ export type MultiselectToggleFilterProps = {
3
3
  isActive: boolean;
4
4
  selectedItemIds?: string[];
5
5
  filterValue: string;
6
- multiline: boolean;
7
6
  onFilterChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
8
7
  };
9
8
  declare const MultiselectToggleFilter: (props: MultiselectToggleFilterProps) => import("react/jsx-runtime").JSX.Element;
@@ -7,10 +7,10 @@ require("react");
7
7
  const classnames_1 = tslib_1.__importDefault(require("classnames"));
8
8
  const isEmpty_1 = tslib_1.__importDefault(require("lodash/fp/isEmpty"));
9
9
  const MultiselectToggleFilter = (props) => {
10
- const { isActive, selectedItemIds, filterValue, multiline, onFilterChange } = props;
10
+ const { isActive, selectedItemIds, filterValue, onFilterChange } = props;
11
11
  const inputClasses = (0, classnames_1.default)('multiselect-filter-input', (0, isEmpty_1.default)(selectedItemIds) && 'multiselect-filter-input-placeholder', isActive && 'multiselect-filter-input-active');
12
12
  return ((0, jsx_runtime_1.jsx)("input", { type: 'text', role: 'searchbox', className: inputClasses,
13
13
  // biome-ignore lint/a11y/noAutofocus: autofocus is intentionally set to allow instant typing to filter
14
- autoFocus: true, onChange: onFilterChange, defaultValue: filterValue }));
14
+ autoFocus: true, onChange: onFilterChange, value: filterValue }));
15
15
  };
16
16
  exports.default = MultiselectToggleFilter;
@@ -0,0 +1,128 @@
1
+ import { type PopoverDOM as DriverPopoverDOM, type State as DriverState, type AllowedButtons } from 'driver.js';
2
+ import 'driver.js/dist/driver.css';
3
+ export type PopoverDOM = DriverPopoverDOM;
4
+ export type OnboardingState = DriverState;
5
+ export type OnboardingStep = {
6
+ element?: string | Element;
7
+ onHighlightStarted?: (element: Element | undefined, step: OnboardingStep, opts: any) => void;
8
+ onHighlighted?: (element: Element | undefined, step: OnboardingStep, opts: any) => void;
9
+ onDeselected?: (element: Element | undefined, step: OnboardingStep, opts: any) => void;
10
+ popover?: {
11
+ title?: string;
12
+ description?: string;
13
+ side?: 'top' | 'right' | 'bottom' | 'left' | 'over';
14
+ align?: 'start' | 'center' | 'end';
15
+ showButtons?: ('next' | 'previous' | 'close')[];
16
+ disableButtons?: ('next' | 'previous' | 'close')[];
17
+ popoverClass?: string;
18
+ doneBtnText?: string;
19
+ nextBtnText?: string;
20
+ prevBtnText?: string;
21
+ };
22
+ };
23
+ type OnboardingOptions = {
24
+ /**
25
+ * Array of steps to highlight. You should pass this when you want to setup a product tour.
26
+ */
27
+ steps?: OnboardingStep[];
28
+ /**
29
+ * Text for the previous button in the onboarding popover.
30
+ */
31
+ prevBtnText?: string;
32
+ /**
33
+ * Text for the next button in the onboarding popover.
34
+ */
35
+ nextBtnText?: string;
36
+ /**
37
+ * Text for the done button in the onboarding popover.
38
+ */
39
+ doneBtnText?: string;
40
+ /**
41
+ * Indicates whether to show progress in the onboarding popover.
42
+ *
43
+ * @default true
44
+ */
45
+ showProgress?: boolean;
46
+ /**
47
+ * Whether to allow closing the popover by clicking on the backdrop.
48
+ * This should be disabled during the tour to ensure th user completes the tour.
49
+ * But can be enabled on the last step.
50
+ *
51
+ * @default false
52
+ */
53
+ allowClose?: boolean;
54
+ /**
55
+ * Distance between the highlighted element and the cutout.
56
+ *
57
+ * @default 10
58
+ */
59
+ stagePadding?: number;
60
+ /**
61
+ * Radius of the cutout around the highlighted element.
62
+ *
63
+ * @default 5
64
+ */
65
+ stageRadius?: number;
66
+ /**
67
+ * Whether to allow keyboard navigation.
68
+ *
69
+ * @default true
70
+ */
71
+ allowKeyboardControl?: boolean;
72
+ /**
73
+ * Array of buttons to show in the popover. Defaults to ["next", "previous", "close"]
74
+ * for product tours and [] for single element highlighting.
75
+ */
76
+ showButtons?: AllowedButtons[];
77
+ /**
78
+ * Array of buttons to disable. This is useful when you want to show some of the buttons, but disable some of them.
79
+ */
80
+ disableButtons?: AllowedButtons[];
81
+ /**
82
+ * Option to disable the backdrop. Note, the backdrop element is still there but with 100% opacity
83
+ * and the close on the backdrop is disabled.
84
+ *
85
+ * @default false
86
+ */
87
+ noBackdrop?: boolean;
88
+ /**
89
+ * Additional classes set on the popover itself.
90
+ */
91
+ popoverClass?: string;
92
+ /**
93
+ * Callback triggered when the onboarding popover renders.
94
+ *
95
+ * @param popover
96
+ * @param state
97
+ * @returns
98
+ */
99
+ onPopoverRender?: (popover: PopoverDOM, state: OnboardingState) => void;
100
+ };
101
+ export declare const useOnboardingTour: (params: OnboardingOptions) => {
102
+ run: () => void;
103
+ destroy: () => void;
104
+ onboardingState: () => DriverState;
105
+ refresh: () => void;
106
+ isActive: () => boolean;
107
+ moveNext: () => void;
108
+ movePrevious: () => void;
109
+ moveTo: (stepNumber: number) => void;
110
+ hasNextStep: () => false | import("driver.js").DriveStep;
111
+ hasPreviousStep: () => false | import("driver.js").DriveStep;
112
+ isFirstStep: () => boolean;
113
+ isLastStep: () => boolean;
114
+ getActiveIndex: () => number | undefined;
115
+ };
116
+ type OnboardingTipOptions = {
117
+ allowClose?: boolean;
118
+ stagePadding?: number;
119
+ stageRadius?: number;
120
+ noBackdrop?: boolean;
121
+ };
122
+ export declare const useOnboardingTip: (options?: OnboardingTipOptions) => {
123
+ highlight: (step: OnboardingStep) => void;
124
+ destroy: () => void;
125
+ refresh: () => void;
126
+ isActive: () => boolean;
127
+ };
128
+ export {};
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useOnboardingTip = exports.useOnboardingTour = void 0;
4
+ const driver_js_1 = require("driver.js");
5
+ require("driver.js/dist/driver.css");
6
+ const useOnboardingTour = (params) => {
7
+ const { steps, prevBtnText = 'Previous', nextBtnText = 'Next', doneBtnText = 'Done', showProgress = true, allowClose = false, stagePadding = 10, stageRadius = 5, allowKeyboardControl = true, showButtons, disableButtons, popoverClass, noBackdrop = false, onPopoverRender = () => { }, } = params;
8
+ const handlePopoverRender = (popover, options) => {
9
+ onPopoverRender(popover, options.state);
10
+ };
11
+ const isSingleStep = !steps || steps.length === 1;
12
+ // This configuration is applied to all steps.
13
+ // Driver.js allows also for individual customization for single steps too.
14
+ const driverInstance = (0, driver_js_1.driver)({
15
+ steps,
16
+ prevBtnText,
17
+ nextBtnText,
18
+ doneBtnText,
19
+ showProgress: isSingleStep ? false : showProgress,
20
+ showButtons: isSingleStep ? ['close'] : showButtons,
21
+ allowClose,
22
+ overlayOpacity: noBackdrop ? 0 : 0.5,
23
+ disableButtons,
24
+ progressText: '{{current}} / {{total}}',
25
+ overlayColor: 'var(--color-black)',
26
+ stagePadding,
27
+ stageRadius,
28
+ allowKeyboardControl,
29
+ popoverClass,
30
+ onPopoverRender: handlePopoverRender,
31
+ });
32
+ return {
33
+ // Use for onboarding tours. Pass in all steps as "steps" parameter for initial configuration.
34
+ run: () => driverInstance.drive(),
35
+ // Use for single element highlights -> see useOnboardingTip
36
+ // highlight: (step: OnboardingStep) => driverInstance.highlight(step),
37
+ // Cleanup the onboarding
38
+ destroy: () => driverInstance.destroy(),
39
+ // Gets the current state of the onboarding with the current step
40
+ onboardingState: () => driverInstance.getState(),
41
+ // Recalculate and redraw the highlight
42
+ refresh: () => driverInstance.refresh(),
43
+ // Is the tour or highlight currently active
44
+ isActive: () => driverInstance.isActive(),
45
+ // Move to the next step
46
+ moveNext: () => driverInstance.moveNext(),
47
+ // Move to the previous step
48
+ movePrevious: () => driverInstance.movePrevious(),
49
+ // Move to the step 4
50
+ moveTo: (stepNumber) => driverInstance.moveTo(stepNumber),
51
+ // Is there a next step
52
+ hasNextStep: () => driverInstance.hasNextStep(),
53
+ // Is there a previous step
54
+ hasPreviousStep: () => driverInstance.hasPreviousStep(),
55
+ // Is the current step the first step
56
+ isFirstStep: () => driverInstance.isFirstStep(),
57
+ // Is the current step the last step
58
+ isLastStep: () => driverInstance.isLastStep(),
59
+ // Gets the active step index
60
+ getActiveIndex: () => driverInstance.getActiveIndex(),
61
+ };
62
+ };
63
+ exports.useOnboardingTour = useOnboardingTour;
64
+ const useOnboardingTip = (options) => {
65
+ const { allowClose = true, stagePadding = 0, stageRadius = 5, noBackdrop = true } = options || {};
66
+ const driverInstance = (0, driver_js_1.driver)({
67
+ allowClose,
68
+ stagePadding,
69
+ stageRadius,
70
+ overlayOpacity: noBackdrop ? 0 : 0.5,
71
+ overlayColor: undefined,
72
+ });
73
+ return {
74
+ highlight: (step) => driverInstance.highlight(step),
75
+ destroy: () => driverInstance.destroy(),
76
+ refresh: () => driverInstance.refresh(),
77
+ isActive: () => driverInstance.isActive(),
78
+ };
79
+ };
80
+ exports.useOnboardingTip = useOnboardingTip;
@@ -0,0 +1 @@
1
+ export * from './hooks/useOnboarding';
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./hooks/useOnboarding"), exports);
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "1.5.3"
2
+ "version": "1.6.0"
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rio-cloud/rio-uikit",
3
- "version": "1.5.3",
3
+ "version": "1.6.0",
4
4
  "description": "The RIO UIKIT component library",
5
5
  "repository": {
6
6
  "type": "git",
@@ -66,7 +66,7 @@
66
66
  "@vitejs/plugin-react": "4.3.1",
67
67
  "@vitest/coverage-c8": "0.33.0",
68
68
  "autoprefixer": "10.4.20",
69
- "backstopjs": "6.3.23",
69
+ "backstopjs": "6.3.25",
70
70
  "copyfiles": "2.4.1",
71
71
  "dotenv": "16.4.5",
72
72
  "eslint": "8.55.0",
@@ -111,6 +111,7 @@
111
111
  "@formkit/auto-animate": "0.8.2",
112
112
  "@popperjs/core": "2.11.8",
113
113
  "classnames": "2.5.1",
114
+ "driver.js": "^1.3.1",
114
115
  "events": "3.3.0",
115
116
  "framer-motion": "4.1.17",
116
117
  "iframe-resizer-react": "1.1.0",
@@ -0,0 +1 @@
1
+ export * from './hooks/useOnboarding';
@@ -0,0 +1 @@
1
+ export * from './hooks/useOnboarding';
package/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "1.5.3"
2
+ "version": "1.6.0"
3
3
  }