@lumx/react 3.9.2-alpha.0 → 3.9.2-alpha.1

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.2-alpha.0",
10
- "@lumx/icons": "^3.9.2-alpha.0",
9
+ "@lumx/core": "^3.9.2-alpha.1",
10
+ "@lumx/icons": "^3.9.2-alpha.1",
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.2-alpha.0"
113
+ "version": "3.9.2-alpha.1"
114
114
  }
@@ -3,7 +3,7 @@ import { usePopper } from 'react-popper';
3
3
  import memoize from 'lodash/memoize';
4
4
  import { detectOverflow } from '@popperjs/core';
5
5
 
6
- import { DOCUMENT, WINDOW } from '@lumx/react/constants';
6
+ import { DOCUMENT, IS_JSDOM_ENV, WINDOW } from '@lumx/react/constants';
7
7
  import { PopoverProps } from '@lumx/react/components/popover/Popover';
8
8
  import { ARROW_SIZE, FitAnchorWidth, Placement } from './constants';
9
9
 
@@ -104,7 +104,7 @@ export function usePopoverStyle({
104
104
  }: Options): Output {
105
105
  const [popperElement, setPopperElement] = useState<null | HTMLElement>(null);
106
106
 
107
- if (navigator.userAgent.includes('jsdom')) {
107
+ if (IS_JSDOM_ENV) {
108
108
  // Skip all logic; we don't need popover positioning in jsdom.
109
109
  return { styles: {}, attributes: {}, isPositioned: true, popperElement, setPopperElement };
110
110
  }
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
 
3
3
  import { Button, IconButton } from '@lumx/react';
4
- import { screen, render, waitFor } from '@testing-library/react';
4
+ import { screen, render } from '@testing-library/react';
5
5
  import { queryAllByTagName, queryByClassName } from '@lumx/react/testing/utils/queries';
6
6
  import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
7
7
  import userEvent from '@testing-library/user-event';
@@ -159,18 +159,17 @@ describe(`<${Tooltip.displayName}>`, () => {
159
159
  expect(ref.current === element).toBe(true);
160
160
  });
161
161
 
162
- it.only('should render in closeMode=hide', async () => {
163
- const { tooltip, anchorWrapper } = await setup({
162
+ it('should render in closeMode=hide', async () => {
163
+ const { tooltip } = await setup({
164
164
  label: 'Tooltip label',
165
165
  children: <Button>Anchor</Button>,
166
166
  closeMode: 'hide',
167
+ forceOpen: false,
167
168
  });
168
- screen.logTestingPlaygroundURL()
169
169
  expect(tooltip).toBeInTheDocument();
170
- expect(anchorWrapper).toBeInTheDocument();
171
- expect(anchorWrapper).toHaveAttribute('aria-describedby', tooltip?.id);
170
+ expect(tooltip).toHaveClass('lumx-tooltip--is-hidden');
172
171
  const button = screen.queryByRole('button', { name: 'Anchor' });
173
- expect(button?.parentElement).toBe(anchorWrapper);
172
+ expect(button).toHaveAttribute('aria-describedby', tooltip?.id);
174
173
  });
175
174
  });
176
175
 
@@ -194,12 +193,11 @@ describe(`<${Tooltip.displayName}>`, () => {
194
193
  expect(button).toHaveAttribute('aria-describedby', tooltip?.id);
195
194
 
196
195
  // Un-hover anchor button
197
- userEvent.unhover(button);
198
- await waitFor(() => {
199
- expect(button).not.toHaveFocus();
200
- // Tooltip closed
201
- expect(tooltip).not.toBeInTheDocument();
202
- });
196
+ await userEvent.unhover(button);
197
+
198
+ expect(button).not.toHaveFocus();
199
+ // Tooltip closed
200
+ expect(tooltip).not.toBeInTheDocument();
203
201
  });
204
202
 
205
203
  it('should activate on hover anchor and then tooltip', async () => {
@@ -226,12 +224,10 @@ describe(`<${Tooltip.displayName}>`, () => {
226
224
  expect(button).toHaveAttribute('aria-describedby', tooltip?.id);
227
225
 
228
226
  // Un-hover tooltip
229
- userEvent.unhover(tooltip);
230
- await waitFor(() => {
231
- expect(button).not.toHaveFocus();
232
- // Tooltip closed
233
- expect(tooltip).not.toBeInTheDocument();
234
- });
227
+ await userEvent.unhover(tooltip);
228
+ expect(button).not.toHaveFocus();
229
+ // Tooltip closed
230
+ expect(tooltip).not.toBeInTheDocument();
235
231
  });
236
232
 
237
233
  it('should activate on anchor focus visible and close on escape', async () => {
@@ -5,10 +5,10 @@ import { usePopper } from 'react-popper';
5
5
 
6
6
  import classNames from 'classnames';
7
7
 
8
- import { DOCUMENT } from '@lumx/react/constants';
8
+ import { DOCUMENT, IS_JSDOM_ENV } from '@lumx/react/constants';
9
9
  import { Comp, GenericProps, HasCloseMode } from '@lumx/react/utils/type';
10
10
  import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
11
- import { mergeRefs } from '@lumx/react/utils/mergeRefs';
11
+ import { useMergeRefs } from '@lumx/react/utils/mergeRefs';
12
12
  import { Placement } from '@lumx/react/components/popover';
13
13
  import { TooltipContextProvider } from '@lumx/react/components/tooltip/context';
14
14
  import { useId } from '@lumx/react/hooks/useId';
@@ -50,7 +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
+ closeMode: 'unmount',
54
54
  };
55
55
 
56
56
  /**
@@ -58,6 +58,9 @@ const DEFAULT_PROPS: Partial<TooltipProps> = {
58
58
  */
59
59
  const ARROW_SIZE = 8;
60
60
 
61
+ // Skip popper logic in jsdom env
62
+ const usePopperHook: typeof usePopper = IS_JSDOM_ENV ? () => ({}) as any : usePopper;
63
+
61
64
  /**
62
65
  * Tooltip component.
63
66
  *
@@ -76,7 +79,7 @@ export const Tooltip: Comp<TooltipProps, HTMLDivElement> = forwardRef((props, re
76
79
 
77
80
  const [popperElement, setPopperElement] = useState<null | HTMLElement>(null);
78
81
  const [anchorElement, setAnchorElement] = useState<null | HTMLElement>(null);
79
- const { styles, attributes } = usePopper(anchorElement, popperElement, {
82
+ const { styles = {}, attributes = {} } = usePopperHook(anchorElement, popperElement, {
80
83
  placement,
81
84
  modifiers: [
82
85
  {
@@ -94,13 +97,14 @@ export const Tooltip: Comp<TooltipProps, HTMLDivElement> = forwardRef((props, re
94
97
 
95
98
  const labelLines = label ? label.split('\n') : [];
96
99
 
100
+ const tooltipRef = useMergeRefs(ref, setPopperElement, onPopperMount);
97
101
  return (
98
102
  <>
99
103
  <TooltipContextProvider>{wrappedChildren}</TooltipContextProvider>
100
104
  {isMounted &&
101
105
  createPortal(
102
106
  <div
103
- ref={mergeRefs(ref, setPopperElement, onPopperMount)}
107
+ ref={tooltipRef}
104
108
  {...forwardedProps}
105
109
  id={id}
106
110
  role="tooltip"
@@ -1,6 +1,6 @@
1
1
  import { MutableRefObject, useEffect, useRef, useState } from 'react';
2
2
  import { browserDoesNotSupportHover } from '@lumx/react/utils/browserDoesNotSupportHover';
3
- import { TOOLTIP_HOVER_DELAY, TOOLTIP_LONG_PRESS_DELAY } from '@lumx/react/constants';
3
+ import { IS_JSDOM_ENV, TOOLTIP_HOVER_DELAY, TOOLTIP_LONG_PRESS_DELAY } from '@lumx/react/constants';
4
4
  import { useCallbackOnEscape } from '@lumx/react/hooks/useCallbackOnEscape';
5
5
  import { isFocusVisible } from '@lumx/react/utils/isFocusVisible';
6
6
 
@@ -31,9 +31,12 @@ export function useTooltipOpen(delay: number | undefined, anchorElement: HTMLEle
31
31
  // Run timer to defer updating the isOpen state.
32
32
  const deferUpdate = (duration: number) => {
33
33
  if (timer) clearTimeout(timer);
34
- timer = setTimeout(() => {
34
+ const update = () => {
35
35
  setIsOpen(!!shouldOpen);
36
- }, duration) as any;
36
+ };
37
+ // Skip timeout in jsdom env
38
+ if (IS_JSDOM_ENV) update();
39
+ else timer = setTimeout(update, duration) as any;
37
40
  };
38
41
 
39
42
  const hoverNotSupported = browserDoesNotSupportHover();
package/src/constants.ts CHANGED
@@ -15,3 +15,8 @@ export const WINDOW = typeof window !== 'undefined' ? window : undefined;
15
15
  * Optional global `document` instance (not defined when running SSR).
16
16
  */
17
17
  export const DOCUMENT = typeof document !== 'undefined' ? document : undefined;
18
+
19
+ /**
20
+ * Check if we are running in the simulated DOM jsdom environment
21
+ */
22
+ export const IS_JSDOM_ENV = typeof navigator !== 'undefined' && navigator.userAgent.includes('jsdom');