@lumx/react 3.9.1 → 3.9.2-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -6,8 +6,8 @@
6
6
  "url": "https://github.com/lumapps/design-system/issues"
7
7
  },
8
8
  "dependencies": {
9
- "@lumx/core": "^3.9.1",
10
- "@lumx/icons": "^3.9.1",
9
+ "@lumx/core": "^3.9.2-alpha.0",
10
+ "@lumx/icons": "^3.9.2-alpha.0",
11
11
  "@popperjs/core": "^2.5.4",
12
12
  "body-scroll-lock": "^3.1.5",
13
13
  "classnames": "^2.3.2",
@@ -110,5 +110,5 @@
110
110
  "build:storybook": "storybook build"
111
111
  },
112
112
  "sideEffects": false,
113
- "version": "3.9.1"
113
+ "version": "3.9.2-alpha.0"
114
114
  }
@@ -7,7 +7,7 @@ import { mdiChevronDown, mdiChevronUp } from '@lumx/icons';
7
7
 
8
8
  import { Emphasis, Icon, Size, IconButton, IconButtonProps } from '@lumx/react';
9
9
 
10
- import { Comp, GenericProps, isComponent } from '@lumx/react/utils/type';
10
+ import { Comp, GenericProps, HasCloseMode, isComponent } from '@lumx/react/utils/type';
11
11
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
12
12
  import { renderLink } from '@lumx/react/utils/renderLink';
13
13
  import { renderButtonOrLink } from '@lumx/react/utils/renderButtonOrLink';
@@ -16,7 +16,7 @@ import { useId } from '@lumx/react/hooks/useId';
16
16
  /**
17
17
  * Defines the props of the component.
18
18
  */
19
- export interface SideNavigationItemProps extends GenericProps {
19
+ export interface SideNavigationItemProps extends GenericProps, HasCloseMode {
20
20
  /** SideNavigationItem elements. */
21
21
  children?: ReactNode;
22
22
  /** Emphasis variant. */
@@ -36,11 +36,6 @@ export interface SideNavigationItemProps extends GenericProps {
36
36
  /** Props to pass to the toggle button (minus those already set by the SideNavigationItem props). */
37
37
  toggleButtonProps: Pick<IconButtonProps, 'label'> &
38
38
  Omit<IconButtonProps, 'label' | 'onClick' | 'icon' | 'emphasis' | 'color' | 'size'>;
39
- /**
40
- * Choose how the children are hidden when closed
41
- * ('hide' keeps the children in DOM but hide them, 'unmount' remove the children from the DOM).
42
- */
43
- closeMode?: 'hide' | 'unmount';
44
39
  /** On action button click callback. */
45
40
  onActionClick?(evt: React.MouseEvent): void;
46
41
  /** On click callback. */
@@ -42,6 +42,14 @@ export const ForceOpen = {
42
42
  },
43
43
  };
44
44
 
45
+ /** Hide on close instead of unmounting */
46
+ export const CloseModeHide = {
47
+ args: {
48
+ ...OnAButton.args,
49
+ closeMode: 'hide',
50
+ },
51
+ };
52
+
45
53
  /** Display a multiline tooltip */
46
54
  export const MultilineTooltip = {
47
55
  args: {
@@ -158,6 +158,20 @@ describe(`<${Tooltip.displayName}>`, () => {
158
158
  // Children ref is stable
159
159
  expect(ref.current === element).toBe(true);
160
160
  });
161
+
162
+ it.only('should render in closeMode=hide', async () => {
163
+ const { tooltip, anchorWrapper } = await setup({
164
+ label: 'Tooltip label',
165
+ children: <Button>Anchor</Button>,
166
+ closeMode: 'hide',
167
+ });
168
+ screen.logTestingPlaygroundURL()
169
+ expect(tooltip).toBeInTheDocument();
170
+ expect(anchorWrapper).toBeInTheDocument();
171
+ expect(anchorWrapper).toHaveAttribute('aria-describedby', tooltip?.id);
172
+ const button = screen.queryByRole('button', { name: 'Anchor' });
173
+ expect(button?.parentElement).toBe(anchorWrapper);
174
+ });
161
175
  });
162
176
 
163
177
  describe('activation', () => {
@@ -6,7 +6,7 @@ import { usePopper } from 'react-popper';
6
6
  import classNames from 'classnames';
7
7
 
8
8
  import { DOCUMENT } from '@lumx/react/constants';
9
- import { Comp, GenericProps } from '@lumx/react/utils/type';
9
+ import { Comp, GenericProps, HasCloseMode } from '@lumx/react/utils/type';
10
10
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
11
11
  import { mergeRefs } from '@lumx/react/utils/mergeRefs';
12
12
  import { Placement } from '@lumx/react/components/popover';
@@ -22,7 +22,7 @@ export type TooltipPlacement = Extract<Placement, 'top' | 'right' | 'bottom' | '
22
22
  /**
23
23
  * Defines the props of the component.
24
24
  */
25
- export interface TooltipProps extends GenericProps {
25
+ export interface TooltipProps extends GenericProps, HasCloseMode {
26
26
  /** Anchor (element on which we activate the tooltip). */
27
27
  children: ReactNode;
28
28
  /** Delay (in ms) before closing the tooltip. */
@@ -50,6 +50,7 @@ const CLASSNAME = getRootClassName(COMPONENT_NAME);
50
50
  */
51
51
  const DEFAULT_PROPS: Partial<TooltipProps> = {
52
52
  placement: Placement.BOTTOM,
53
+ closeMode: 'hide',
53
54
  };
54
55
 
55
56
  /**
@@ -65,9 +66,9 @@ const ARROW_SIZE = 8;
65
66
  * @return React element.
66
67
  */
67
68
  export const Tooltip: Comp<TooltipProps, HTMLDivElement> = forwardRef((props, ref) => {
68
- const { label, children, className, delay, placement, forceOpen, ...forwardedProps } = props;
69
+ const { label, children, className, delay, placement, forceOpen, closeMode, ...forwardedProps } = props;
69
70
  // Disable in SSR.
70
- if (!DOCUMENT) {
71
+ if (!DOCUMENT && closeMode === 'unmount') {
71
72
  return <>{children}</>;
72
73
  }
73
74
 
@@ -88,28 +89,38 @@ export const Tooltip: Comp<TooltipProps, HTMLDivElement> = forwardRef((props, re
88
89
  const position = attributes?.popper?.['data-popper-placement'] ?? placement;
89
90
  const { isOpen: isActivated, onPopperMount } = useTooltipOpen(delay, anchorElement);
90
91
  const isOpen = (isActivated || forceOpen) && !!label;
91
- const wrappedChildren = useInjectTooltipRef(children, setAnchorElement, isOpen, id, label);
92
+ const isMounted = isOpen || closeMode === 'hide';
93
+ const wrappedChildren = useInjectTooltipRef(children, setAnchorElement, isMounted, id, label);
94
+
95
+ const labelLines = label ? label.split('\n') : [];
92
96
 
93
97
  return (
94
98
  <>
95
99
  <TooltipContextProvider>{wrappedChildren}</TooltipContextProvider>
96
- {isOpen &&
100
+ {isMounted &&
97
101
  createPortal(
98
102
  <div
99
103
  ref={mergeRefs(ref, setPopperElement, onPopperMount)}
100
104
  {...forwardedProps}
101
105
  id={id}
102
106
  role="tooltip"
103
- aria-label={label}
104
- className={classNames(className, handleBasicClasses({ prefix: CLASSNAME, position }))}
107
+ aria-label={label || ''}
108
+ className={classNames(
109
+ className,
110
+ handleBasicClasses({
111
+ prefix: CLASSNAME,
112
+ position,
113
+ hidden: !isOpen && closeMode === 'hide',
114
+ }),
115
+ )}
105
116
  style={styles.popper}
106
117
  {...attributes.popper}
107
118
  >
108
119
  <div className={`${CLASSNAME}__arrow`} />
109
120
  <div className={`${CLASSNAME}__inner`}>
110
- {label.indexOf('\n') !== -1
111
- ? label.split('\n').map((sentence: string) => <p key={sentence}>{sentence}</p>)
112
- : label}
121
+ {labelLines.map((line) => (
122
+ <p key={line}>{line}</p>
123
+ ))}
113
124
  </div>
114
125
  </div>,
115
126
  document.body,
package/src/utils/type.ts CHANGED
@@ -59,6 +59,15 @@ export interface HasClassName {
59
59
  className?: string;
60
60
  }
61
61
 
62
+
63
+ export interface HasCloseMode {
64
+ /**
65
+ * Choose how the children are hidden when closed
66
+ * ('hide' keeps the children in DOM but hide them, 'unmount' remove the children from the DOM).
67
+ */
68
+ closeMode?: 'hide' | 'unmount';
69
+ }
70
+
62
71
  /**
63
72
  * Define a generic props types.
64
73
  */