@lumx/react 3.10.1-alpha.3 → 3.10.1-alpha.4
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/index.js +99 -92
- package/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/chip/Chip.tsx +1 -1
- package/src/components/date-picker/DatePickerControlled.tsx +1 -1
- package/src/components/expansion-panel/ExpansionPanel.test.tsx +2 -2
- package/src/components/image-lightbox/internal/ImageSlide.tsx +2 -2
- package/src/components/image-lightbox/internal/ImageSlideshow.tsx +4 -8
- package/src/components/image-lightbox/useImageLightbox.tsx +3 -4
- package/src/components/list/ListItem.tsx +1 -1
- package/src/components/popover/usePopoverStyle.tsx +3 -1
- package/src/components/popover/useRestoreFocusOnClose.tsx +1 -1
- package/src/components/popover-dialog/PopoverDialog.test.tsx +1 -1
- package/src/components/select/Select.test.tsx +2 -2
- package/src/components/slideshow/useSlideFocusManagement.tsx +1 -1
- package/src/components/text-field/TextField.test.tsx +2 -2
- package/src/components/tooltip/Tooltip.test.tsx +2 -2
- package/src/components/tooltip/useTooltipOpen.tsx +3 -3
- package/src/hooks/useCallbackOnEscape.ts +1 -1
- package/src/hooks/useFocusTrap.ts +1 -1
- package/src/hooks/useSizeOnWindowResize.ts +14 -10
- package/src/hooks/useTransitionVisibility.ts +2 -2
- package/src/utils/{DOM → browser/DOM}/startViewTransition.ts +3 -3
- package/src/utils/{focus → browser/focus}/getFirstAndLastFocusable.test.ts +1 -1
- package/src/utils/{focus → browser/focus}/getFocusableElements.test.ts +1 -1
- package/src/utils/{browserDoesNotSupportHover.test.js → browser/isHoverNotSupported.test.js} +5 -5
- package/src/utils/browser/isHoverNotSupported.ts +2 -0
- package/src/utils/browser/{getPrefersReducedMotion.ts → isReducedMotion.ts} +1 -1
- package/src/utils/className/getFontColorClassName.ts +9 -0
- package/src/utils/{className.ts → className/getRootClassName.ts} +1 -21
- package/src/utils/className/getTypographyClassName.ts +9 -0
- package/src/utils/className/index.ts +4 -0
- package/src/utils/function/memoize.test.ts +36 -0
- package/src/utils/function/memoize.ts +13 -0
- package/src/utils/partitionMulti.test.ts +27 -0
- package/src/utils/browserDoesNotSupportHover.ts +0 -2
- package/src/utils/isInternetExplorer.ts +0 -15
- package/src/utils/userHasReducedMotion.ts +0 -7
- package/src/utils/utils.test.ts +0 -21
- /package/src/utils/{DOM → browser/DOM}/findImage.tsx +0 -0
- /package/src/utils/{event.ts → browser/event.ts} +0 -0
- /package/src/utils/{focus → browser/focus}/constants.ts +0 -0
- /package/src/utils/{focus → browser/focus}/getFirstAndLastFocusable.ts +0 -0
- /package/src/utils/{focus → browser/focus}/getFocusableElements.ts +0 -0
- /package/src/utils/{isFocusVisible.ts → browser/isFocusVisible.ts} +0 -0
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.10.1-alpha.
|
|
10
|
-
"@lumx/icons": "^3.10.1-alpha.
|
|
9
|
+
"@lumx/core": "^3.10.1-alpha.4",
|
|
10
|
+
"@lumx/icons": "^3.10.1-alpha.4",
|
|
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.10.1-alpha.
|
|
113
|
+
"version": "3.10.1-alpha.4"
|
|
114
114
|
}
|
|
@@ -7,7 +7,7 @@ import { useStopPropagation } from '@lumx/react/hooks/useStopPropagation';
|
|
|
7
7
|
|
|
8
8
|
import { GenericProps, HasTheme } from '@lumx/react/utils/type';
|
|
9
9
|
import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
|
|
10
|
-
import { onEnterPressed } from '@lumx/react/utils/event';
|
|
10
|
+
import { onEnterPressed } from '@lumx/react/utils/browser/event';
|
|
11
11
|
import { forwardRef } from '@lumx/react/utils/react/forwardRef';
|
|
12
12
|
import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
|
|
13
13
|
|
|
@@ -21,7 +21,7 @@ import { parseLocale } from '@lumx/react/utils/locale/parseLocale';
|
|
|
21
21
|
import { Locale } from '@lumx/react/utils/locale/types';
|
|
22
22
|
import { usePreviousValue } from '@lumx/react/hooks/usePreviousValue';
|
|
23
23
|
import { getYearDisplayName } from '@lumx/react/utils/date/getYearDisplayName';
|
|
24
|
-
import { onEnterPressed } from '@lumx/react/utils/event';
|
|
24
|
+
import { onEnterPressed } from '@lumx/react/utils/browser/event';
|
|
25
25
|
import { addMonthResetDay } from '@lumx/react/utils/date/addMonthResetDay';
|
|
26
26
|
import { formatDayNumber } from '@lumx/react/utils/date/formatDayNumber';
|
|
27
27
|
import { VISUALLY_HIDDEN } from '@lumx/react/constants';
|
|
@@ -4,14 +4,14 @@ import { commonTestsSuiteRTL, SetupRenderOptions } from '@lumx/react/testing/uti
|
|
|
4
4
|
import { queryByRole, render, screen } from '@testing-library/react';
|
|
5
5
|
import { getByClassName, queryByClassName } from '@lumx/react/testing/utils/queries';
|
|
6
6
|
import userEvent from '@testing-library/user-event';
|
|
7
|
-
import { isFocusVisible } from '@lumx/react/utils/isFocusVisible';
|
|
7
|
+
import { isFocusVisible } from '@lumx/react/utils/browser/isFocusVisible';
|
|
8
8
|
|
|
9
9
|
import { useBooleanState } from '@lumx/react/hooks/useBooleanState';
|
|
10
10
|
import { ExpansionPanel, ExpansionPanelProps } from '.';
|
|
11
11
|
|
|
12
12
|
const CLASSNAME = ExpansionPanel.className as string;
|
|
13
13
|
|
|
14
|
-
jest.mock('@lumx/react/utils/isFocusVisible');
|
|
14
|
+
jest.mock('@lumx/react/utils/browser/isFocusVisible');
|
|
15
15
|
|
|
16
16
|
const mockChildrenContent = 'children content';
|
|
17
17
|
|
|
@@ -4,7 +4,7 @@ import { SlideshowItem, Thumbnail } from '@lumx/react';
|
|
|
4
4
|
import { useMergeRefs } from '@lumx/react/utils/mergeRefs';
|
|
5
5
|
import { useSizeOnWindowResize } from '@lumx/react/hooks/useSizeOnWindowResize';
|
|
6
6
|
import { useImageSize } from '@lumx/react/hooks/useImageSize';
|
|
7
|
-
import {
|
|
7
|
+
import { isReducedMotion } from '@lumx/react/utils/browser/isReducedMotion';
|
|
8
8
|
import { isEqual } from '@lumx/react/utils/object/isEqual';
|
|
9
9
|
|
|
10
10
|
import { CLASSNAME } from '../constants';
|
|
@@ -97,7 +97,7 @@ export const ImageSlide = React.memo((props: ImageSlideProps) => {
|
|
|
97
97
|
maxWidth: scrollAreaSize?.width,
|
|
98
98
|
}),
|
|
99
99
|
// Only animate when scale is set, and we are not pointer zooming and the user does not prefer reduced motion
|
|
100
|
-
transition: scale && !isPointerZooming && !
|
|
100
|
+
transition: scale && !isPointerZooming && !isReducedMotion() ? 'all 250ms' : undefined,
|
|
101
101
|
},
|
|
102
102
|
}}
|
|
103
103
|
loadingPlaceholderImageRef={loadingPlaceholderImageRef}
|
|
@@ -3,8 +3,8 @@ import React from 'react';
|
|
|
3
3
|
import { mdiMagnifyMinusOutline, mdiMagnifyPlusOutline } from '@lumx/icons';
|
|
4
4
|
import { FlexBox, IconButton, Slides, SlideshowControls } from '@lumx/react';
|
|
5
5
|
import { mergeRefs } from '@lumx/react/utils/mergeRefs';
|
|
6
|
+
import { memoize } from '@lumx/react/utils/function/memoize';
|
|
6
7
|
|
|
7
|
-
import memoize from 'lodash/memoize';
|
|
8
8
|
import { ImageCaption } from '../../image-block/ImageCaption';
|
|
9
9
|
import { CLASSNAME } from '../constants';
|
|
10
10
|
import type { ImagesProps, InheritedSlideShowProps, ZoomButtonProps } from '../types';
|
|
@@ -113,13 +113,9 @@ export const ImageSlideshow: React.FC<ImageSlideshowProps> = ({
|
|
|
113
113
|
|
|
114
114
|
const getImgRef = React.useMemo(
|
|
115
115
|
() =>
|
|
116
|
-
memoize(
|
|
117
|
-
(index
|
|
118
|
-
|
|
119
|
-
},
|
|
120
|
-
// memoize based on both arguments
|
|
121
|
-
(...args) => args.join(),
|
|
122
|
-
),
|
|
116
|
+
memoize((index: number, isActive: boolean) => {
|
|
117
|
+
return mergeRefs(images?.[index].imgRef, isActive ? activeImageRef : undefined);
|
|
118
|
+
}),
|
|
123
119
|
[images, activeImageRef],
|
|
124
120
|
);
|
|
125
121
|
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
import { findImage } from '@lumx/react/utils/DOM/findImage';
|
|
3
|
+
import { startViewTransition } from '@lumx/react/utils/browser/DOM/startViewTransition';
|
|
4
|
+
import { findImage } from '@lumx/react/utils/browser/DOM/findImage';
|
|
5
|
+
import { memoize } from '@lumx/react/utils/function/memoize';
|
|
7
6
|
|
|
8
7
|
import type { ImageLightboxProps } from './types';
|
|
9
8
|
import { CLASSNAME } from './constants';
|
|
@@ -4,7 +4,7 @@ import classNames from 'classnames';
|
|
|
4
4
|
|
|
5
5
|
import { ListProps, Size } from '@lumx/react';
|
|
6
6
|
import { GenericProps } from '@lumx/react/utils/type';
|
|
7
|
-
import { onEnterPressed, onButtonPressed } from '@lumx/react/utils/event';
|
|
7
|
+
import { onEnterPressed, onButtonPressed } from '@lumx/react/utils/browser/event';
|
|
8
8
|
import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
|
|
9
9
|
import { renderLink } from '@lumx/react/utils/renderLink';
|
|
10
10
|
import { forwardRef } from '@lumx/react/utils/react/forwardRef';
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import React, { useEffect, useMemo, useState } from 'react';
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
import { detectOverflow } from '@popperjs/core';
|
|
4
4
|
|
|
5
5
|
import { DOCUMENT, WINDOW } from '@lumx/react/constants';
|
|
6
6
|
import { PopoverProps } from '@lumx/react/components/popover/Popover';
|
|
7
7
|
import { usePopper } from '@lumx/react/hooks/usePopper';
|
|
8
|
+
import { memoize } from '@lumx/react/utils/function/memoize';
|
|
9
|
+
|
|
8
10
|
import { ARROW_SIZE, FitAnchorWidth, Placement } from './constants';
|
|
9
11
|
|
|
10
12
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { getFirstAndLastFocusable } from '@lumx/react/utils/focus/getFirstAndLastFocusable';
|
|
2
|
+
import { getFirstAndLastFocusable } from '@lumx/react/utils/browser/focus/getFirstAndLastFocusable';
|
|
3
3
|
import { OnBeforeUnmount } from '@lumx/react/utils/OnBeforeUnmount';
|
|
4
4
|
import type { PopoverProps } from './Popover';
|
|
5
5
|
|
|
@@ -5,7 +5,7 @@ import userEvent from '@testing-library/user-event';
|
|
|
5
5
|
import { PopoverDialog } from './PopoverDialog';
|
|
6
6
|
import { WithButtonTrigger, WithIconButtonTrigger } from './PopoverDialog.stories';
|
|
7
7
|
|
|
8
|
-
jest.mock('@lumx/react/utils/isFocusVisible');
|
|
8
|
+
jest.mock('@lumx/react/utils/browser/isFocusVisible');
|
|
9
9
|
|
|
10
10
|
describe(`<${PopoverDialog.displayName}>`, () => {
|
|
11
11
|
it('should open and init focus', async () => {
|
|
@@ -7,13 +7,13 @@ import { getByClassName, queryAllByClassName, queryByClassName } from '@lumx/rea
|
|
|
7
7
|
import { render, within } from '@testing-library/react';
|
|
8
8
|
import { commonTestsSuiteRTL, SetupRenderOptions } from '@lumx/react/testing/utils';
|
|
9
9
|
import userEvent from '@testing-library/user-event';
|
|
10
|
-
import { isFocusVisible } from '@lumx/react/utils/isFocusVisible';
|
|
10
|
+
import { isFocusVisible } from '@lumx/react/utils/browser/isFocusVisible';
|
|
11
11
|
|
|
12
12
|
import { Select, SelectProps, SelectVariant } from './Select';
|
|
13
13
|
|
|
14
14
|
const CLASSNAME = Select.className as string;
|
|
15
15
|
|
|
16
|
-
jest.mock('@lumx/react/utils/isFocusVisible');
|
|
16
|
+
jest.mock('@lumx/react/utils/browser/isFocusVisible');
|
|
17
17
|
jest.mock('@lumx/react/hooks/useId', () => ({ useId: () => ':r1:' }));
|
|
18
18
|
|
|
19
19
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useEffect } from 'react';
|
|
2
|
-
import { getFocusableElements } from '@lumx/react/utils/focus/getFocusableElements';
|
|
2
|
+
import { getFocusableElements } from '@lumx/react/utils/browser/focus/getFocusableElements';
|
|
3
3
|
|
|
4
4
|
export interface UseSlideFocusManagementProps {
|
|
5
5
|
isSlideDisplayed?: boolean;
|
|
@@ -14,13 +14,13 @@ import {
|
|
|
14
14
|
} from '@lumx/react/testing/utils/queries';
|
|
15
15
|
import userEvent from '@testing-library/user-event';
|
|
16
16
|
|
|
17
|
-
import { isFocusVisible } from '@lumx/react/utils/isFocusVisible';
|
|
17
|
+
import { isFocusVisible } from '@lumx/react/utils/browser/isFocusVisible';
|
|
18
18
|
import { partitionMulti } from '@lumx/react/utils/collection/partitionMulti';
|
|
19
19
|
import { TextField, TextFieldProps } from './TextField';
|
|
20
20
|
|
|
21
21
|
const CLASSNAME = TextField.className as string;
|
|
22
22
|
|
|
23
|
-
jest.mock('@lumx/react/utils/isFocusVisible');
|
|
23
|
+
jest.mock('@lumx/react/utils/browser/isFocusVisible');
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Mounts the component and returns common DOM elements / data needed in multiple tests further down.
|
|
@@ -5,14 +5,14 @@ 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';
|
|
8
|
-
import { isFocusVisible } from '@lumx/react/utils/isFocusVisible';
|
|
8
|
+
import { isFocusVisible } from '@lumx/react/utils/browser/isFocusVisible';
|
|
9
9
|
import { VISUALLY_HIDDEN } from '@lumx/react/constants';
|
|
10
10
|
|
|
11
11
|
import { Tooltip, TooltipProps } from './Tooltip';
|
|
12
12
|
|
|
13
13
|
const CLASSNAME = Tooltip.className as string;
|
|
14
14
|
|
|
15
|
-
jest.mock('@lumx/react/utils/isFocusVisible');
|
|
15
|
+
jest.mock('@lumx/react/utils/browser/isFocusVisible');
|
|
16
16
|
jest.mock('@lumx/react/hooks/useId', () => ({ useId: () => ':r1:' }));
|
|
17
17
|
// Skip delays
|
|
18
18
|
jest.mock('@lumx/react/constants', () => ({
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { MutableRefObject, useEffect, useRef, useState } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { isHoverNotSupported } from '@lumx/react/utils/browser/isHoverNotSupported';
|
|
3
3
|
import { IS_BROWSER, TOOLTIP_HOVER_DELAY, TOOLTIP_LONG_PRESS_DELAY } from '@lumx/react/constants';
|
|
4
4
|
import { useCallbackOnEscape } from '@lumx/react/hooks/useCallbackOnEscape';
|
|
5
|
-
import { isFocusVisible } from '@lumx/react/utils/isFocusVisible';
|
|
5
|
+
import { isFocusVisible } from '@lumx/react/utils/browser/isFocusVisible';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Hook controlling tooltip visibility using mouse hover the anchor and delay.
|
|
@@ -39,7 +39,7 @@ export function useTooltipOpen(delay: number | undefined, anchorElement: HTMLEle
|
|
|
39
39
|
else timer = setTimeout(update, duration) as any;
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
const hoverNotSupported =
|
|
42
|
+
const hoverNotSupported = isHoverNotSupported();
|
|
43
43
|
const hasTouch = 'ontouchstart' in window;
|
|
44
44
|
|
|
45
45
|
// Adapt open/close delay
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DOCUMENT } from '@lumx/react/constants';
|
|
2
2
|
import { Callback } from '@lumx/react/utils/type';
|
|
3
|
-
import { onEscapePressed } from '@lumx/react/utils/event';
|
|
3
|
+
import { onEscapePressed } from '@lumx/react/utils/browser/event';
|
|
4
4
|
import { useEffect } from 'react';
|
|
5
5
|
import { Listener, makeListenerTowerContext } from '@lumx/react/utils/makeListenerTowerContext';
|
|
6
6
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
|
|
3
3
|
import { DOCUMENT } from '@lumx/react/constants';
|
|
4
|
-
import { getFirstAndLastFocusable } from '@lumx/react/utils/focus/getFirstAndLastFocusable';
|
|
4
|
+
import { getFirstAndLastFocusable } from '@lumx/react/utils/browser/focus/getFirstAndLastFocusable';
|
|
5
5
|
import { Falsy } from '@lumx/react/utils/type';
|
|
6
6
|
import { Listener, makeListenerTowerContext } from '@lumx/react/utils/makeListenerTowerContext';
|
|
7
7
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import { RectSize } from '@lumx/react/utils/type';
|
|
3
|
+
import type { RectSize } from '@lumx/react/utils/type';
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* Observe element size (only works if it's size depends on the window size).
|
|
@@ -13,14 +12,19 @@ import { RectSize } from '@lumx/react/utils/type';
|
|
|
13
12
|
*/
|
|
14
13
|
export function useSizeOnWindowResize(elementRef: React.RefObject<HTMLElement>): [RectSize | null, () => void] {
|
|
15
14
|
const [size, setSize] = React.useState<null | RectSize>(null);
|
|
16
|
-
const updateSize = React.useMemo(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
const updateSize = React.useMemo(() => {
|
|
16
|
+
let prevTimeout: ReturnType<typeof setTimeout> | undefined;
|
|
17
|
+
function update() {
|
|
18
|
+
const newSize = elementRef.current?.getBoundingClientRect();
|
|
19
|
+
if (newSize) setSize(newSize);
|
|
20
|
+
prevTimeout = undefined;
|
|
21
|
+
}
|
|
22
|
+
return () => {
|
|
23
|
+
if (!prevTimeout) {
|
|
24
|
+
prevTimeout = setTimeout(update, 10);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}, [elementRef]);
|
|
24
28
|
React.useEffect(() => {
|
|
25
29
|
updateSize();
|
|
26
30
|
window.addEventListener('resize', updateSize);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RefObject, useEffect, useRef, useState } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { isReducedMotion } from '@lumx/react/utils/browser/isReducedMotion';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Returns true if the component is visible tracking the opacity transition.
|
|
@@ -28,7 +28,7 @@ export const useTransitionVisibility = (
|
|
|
28
28
|
|
|
29
29
|
// Transition event is not supported or the user prefers reduced motion.
|
|
30
30
|
// => Skip and set visibility to false directly.
|
|
31
|
-
if (!element || !window.TransitionEvent ||
|
|
31
|
+
if (!element || !window.TransitionEvent || isReducedMotion()) {
|
|
32
32
|
setVisible(false);
|
|
33
33
|
return undefined;
|
|
34
34
|
}
|
|
@@ -2,8 +2,8 @@ import ReactDOM from 'react-dom';
|
|
|
2
2
|
|
|
3
3
|
import { MaybeElementOrRef } from '@lumx/react/utils/type';
|
|
4
4
|
|
|
5
|
-
import { unref } from '
|
|
6
|
-
import {
|
|
5
|
+
import { unref } from '../../react/unref';
|
|
6
|
+
import { isReducedMotion } from '../isReducedMotion';
|
|
7
7
|
|
|
8
8
|
function setupViewTransitionName(elementRef: MaybeElementOrRef<HTMLElement>, name: string) {
|
|
9
9
|
let originalName: string | null = null;
|
|
@@ -41,7 +41,7 @@ export async function startViewTransition({
|
|
|
41
41
|
};
|
|
42
42
|
}) {
|
|
43
43
|
const start = (document as any)?.startViewTransition?.bind(document);
|
|
44
|
-
const prefersReducedMotion =
|
|
44
|
+
const prefersReducedMotion = isReducedMotion();
|
|
45
45
|
const { flushSync } = ReactDOM as any;
|
|
46
46
|
if (prefersReducedMotion || !start || !flushSync || !viewTransitionName?.source || !viewTransitionName?.target) {
|
|
47
47
|
// Skip, apply changes without a transition
|
package/src/utils/{browserDoesNotSupportHover.test.js → browser/isHoverNotSupported.test.js}
RENAMED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isHoverNotSupported } from './isHoverNotSupported';
|
|
2
2
|
|
|
3
3
|
const originalMatchMedia = global.matchMedia;
|
|
4
4
|
|
|
5
|
-
describe('
|
|
5
|
+
describe('isHoverNotSupported', () => {
|
|
6
6
|
afterAll(() => {
|
|
7
7
|
global.matchMedia = originalMatchMedia;
|
|
8
8
|
});
|
|
9
9
|
|
|
10
10
|
it('should return `false` on browsers that do not support matchMedia', () => {
|
|
11
11
|
global.matchMedia = undefined;
|
|
12
|
-
expect(
|
|
12
|
+
expect(isHoverNotSupported()).toBe(false);
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
it('should return `false` on browsers that support matchMedia and does support hover', () => {
|
|
16
16
|
global.matchMedia = () => ({ matches: false });
|
|
17
|
-
expect(
|
|
17
|
+
expect(isHoverNotSupported()).toBe(false);
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
it('should return `true` on browsers that support matchMedia and does not support hover', () => {
|
|
21
21
|
global.matchMedia = () => ({ matches: true });
|
|
22
|
-
expect(
|
|
22
|
+
expect(isHoverNotSupported()).toBe(true);
|
|
23
23
|
});
|
|
24
24
|
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ColorPalette, ColorVariant } from '@lumx/react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns the classname associated to the given color and variant.
|
|
5
|
+
* For example, for 'dark' and 'L2' it returns `lumx-color-font-dark-l2`
|
|
6
|
+
*/
|
|
7
|
+
export const getFontColorClassName = (color: ColorPalette, colorVariant: ColorVariant = ColorVariant.N) => {
|
|
8
|
+
return `lumx-color-font-${color}-${colorVariant}`;
|
|
9
|
+
};
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import { CSS_PREFIX } from '@lumx/
|
|
2
|
-
|
|
1
|
+
import { CSS_PREFIX } from '@lumx/core/js/constants';
|
|
3
2
|
import kebabCase from 'lodash/kebabCase';
|
|
4
|
-
import { ColorPalette, ColorVariant, Typography } from '@lumx/react/components';
|
|
5
3
|
|
|
6
4
|
// See https://regex101.com/r/YjS1uI/3
|
|
7
5
|
const LAST_PART_CLASSNAME = /^(.*)-(.+)$/gi;
|
|
8
6
|
|
|
9
|
-
export { getBasicClass, handleBasicClasses } from '@lumx/core/js/utils';
|
|
10
|
-
|
|
11
7
|
/**
|
|
12
8
|
* Get the name of the root CSS class of a component based on its name.
|
|
13
9
|
*
|
|
@@ -26,19 +22,3 @@ export function getRootClassName(componentName: string, subComponent?: boolean):
|
|
|
26
22
|
}
|
|
27
23
|
return formattedClassName;
|
|
28
24
|
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Returns the classname associated to the given color and variant.
|
|
32
|
-
* For example, for 'dark' and 'L2' it returns `lumx-color-font-dark-l2`
|
|
33
|
-
*/
|
|
34
|
-
export const getFontColorClassName = (color: ColorPalette, colorVariant: ColorVariant = ColorVariant.N) => {
|
|
35
|
-
return `lumx-color-font-${color}-${colorVariant}`;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Returns the classname associated to the given typography.
|
|
40
|
-
* For example, for `Typography.title` it returns `lumx-typography-title`
|
|
41
|
-
*/
|
|
42
|
-
export const getTypographyClassName = (typography: Typography) => {
|
|
43
|
-
return `lumx-typography-${typography}`;
|
|
44
|
-
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Typography } from '@lumx/react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns the classname associated to the given typography.
|
|
5
|
+
* For example, for `Typography.title` it returns `lumx-typography-title`
|
|
6
|
+
*/
|
|
7
|
+
export const getTypographyClassName = (typography: Typography) => {
|
|
8
|
+
return `lumx-typography-${typography}`;
|
|
9
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { memoize } from '@lumx/react/utils/function/memoize';
|
|
2
|
+
|
|
3
|
+
describe(memoize, () => {
|
|
4
|
+
it('should memoize a function returning nothing', () => {
|
|
5
|
+
const fn = jest.fn();
|
|
6
|
+
const memoized = memoize(fn);
|
|
7
|
+
|
|
8
|
+
expect(memoized()).toEqual(undefined);
|
|
9
|
+
expect(memoized()).toEqual(undefined);
|
|
10
|
+
expect(fn).toHaveBeenCalledTimes(1);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should memoize a function with no args', () => {
|
|
14
|
+
const fn = jest.fn((i) => i);
|
|
15
|
+
const memoized = memoize(fn);
|
|
16
|
+
|
|
17
|
+
expect(memoized('value')).toEqual('value');
|
|
18
|
+
expect(memoized('value')).toEqual('value');
|
|
19
|
+
expect(fn).toHaveBeenCalledTimes(1);
|
|
20
|
+
|
|
21
|
+
expect(memoized('another value')).toEqual('another value');
|
|
22
|
+
expect(fn).toHaveBeenCalledTimes(2);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should memoize a function with multiple args', () => {
|
|
26
|
+
const fn = jest.fn((a, b) => `${a} ${b}`);
|
|
27
|
+
const memoized = memoize(fn);
|
|
28
|
+
|
|
29
|
+
expect(memoized(1, true)).toEqual('1 true');
|
|
30
|
+
expect(memoized(1, true)).toEqual('1 true');
|
|
31
|
+
expect(fn).toHaveBeenCalledTimes(1);
|
|
32
|
+
|
|
33
|
+
expect(memoized('foo', 4)).toEqual('foo 4');
|
|
34
|
+
expect(fn).toHaveBeenCalledTimes(2);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Memoize a function based on the serialization of its args */
|
|
2
|
+
export function memoize<A extends Array<unknown>, R>(fn: (...args: A) => R): (...args: A) => R {
|
|
3
|
+
const cache = new Map<string, R>();
|
|
4
|
+
|
|
5
|
+
return (...args) => {
|
|
6
|
+
const serializedArgs = JSON.stringify(args);
|
|
7
|
+
if (cache.has(serializedArgs)) return cache.get(serializedArgs) as R;
|
|
8
|
+
|
|
9
|
+
const value = fn(...args);
|
|
10
|
+
cache.set(serializedArgs, value);
|
|
11
|
+
return value;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import partition from 'lodash/partition';
|
|
2
|
+
import { partitionMulti } from './partitionMulti';
|
|
3
|
+
|
|
4
|
+
describe('partitionMulti', () => {
|
|
5
|
+
it('should act like partition for single predicate', () => {
|
|
6
|
+
const data = [0, 1, 2, 3, 4, 5];
|
|
7
|
+
const isEven = (n: number): boolean => n % 2 === 0;
|
|
8
|
+
|
|
9
|
+
const expected = partition(data, isEven);
|
|
10
|
+
const actual = partitionMulti(data, [isEven]);
|
|
11
|
+
|
|
12
|
+
expect(actual).toEqual(expected);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should partition on multiple predicates', () => {
|
|
16
|
+
type T = string | number | boolean;
|
|
17
|
+
const data: T[] = ['a', 1, 'b', false, true];
|
|
18
|
+
const isString = (s: T): boolean => typeof s === 'string';
|
|
19
|
+
const isNumber = (s: T): boolean => typeof s === 'number';
|
|
20
|
+
|
|
21
|
+
const [strings, numbers, others] = partitionMulti(data, [isString, isNumber]);
|
|
22
|
+
|
|
23
|
+
expect(strings).toEqual(['a', 'b']);
|
|
24
|
+
expect(numbers).toEqual([1]);
|
|
25
|
+
expect(others).toEqual([false, true]);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { WINDOW } from '@lumx/react/constants';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Check if browser is IE
|
|
5
|
-
* @return Browser is IE or not
|
|
6
|
-
*/
|
|
7
|
-
export const isInternetExplorer = () => {
|
|
8
|
-
const userAgent = WINDOW?.navigator?.userAgent;
|
|
9
|
-
if (!userAgent) {
|
|
10
|
-
return false;
|
|
11
|
-
}
|
|
12
|
-
const msie = userAgent.indexOf('MSIE ');
|
|
13
|
-
const isIEVersion = !!userAgent.match(/Trident.*rv:11\./);
|
|
14
|
-
return msie > 0 || isIEVersion;
|
|
15
|
-
};
|
package/src/utils/utils.test.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { isInternetExplorer } from './isInternetExplorer';
|
|
2
|
-
|
|
3
|
-
describe('isInternetExplorer', () => {
|
|
4
|
-
it('should detect IE 10', () => {
|
|
5
|
-
const userAgentIE10 = 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)';
|
|
6
|
-
Object.defineProperty(window.navigator, 'userAgent', { value: userAgentIE10, configurable: true });
|
|
7
|
-
expect(isInternetExplorer()).toEqual(true);
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
it('should detect IE 11', () => {
|
|
11
|
-
const userAgentIE11 = 'Mozilla/5.0 (Windows NT 10.0; Trident/7.0; rv:11.0) like Gecko';
|
|
12
|
-
Object.defineProperty(window.navigator, 'userAgent', { value: userAgentIE11, configurable: true });
|
|
13
|
-
expect(isInternetExplorer()).toEqual(true);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('should not detect IE', () => {
|
|
17
|
-
const userAgentFirefox = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:74.0) Gecko/20100101 Firefox/74.0';
|
|
18
|
-
Object.defineProperty(window.navigator, 'userAgent', { value: userAgentFirefox, configurable: true });
|
|
19
|
-
expect(isInternetExplorer()).toEqual(false);
|
|
20
|
-
});
|
|
21
|
-
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|