diff --git a/packages/react/src/components/design-system.tsx b/packages/react/src/components/design-system.tsx index 5b3626c828..28697128d9 100644 --- a/packages/react/src/components/design-system.tsx +++ b/packages/react/src/components/design-system.tsx @@ -8,7 +8,11 @@ export type DesignSystemProps = ThemeWrapperProps & DeviceContextProviderProps & export const DesignSystem: FunctionComponent> = (props) => ( - + {props.children} diff --git a/packages/react/src/components/device-context-provider/device-context-provider.tsx b/packages/react/src/components/device-context-provider/device-context-provider.tsx index 8eb340456f..3dae4560da 100644 --- a/packages/react/src/components/device-context-provider/device-context-provider.tsx +++ b/packages/react/src/components/device-context-provider/device-context-provider.tsx @@ -1,4 +1,13 @@ -import { createContext, FunctionComponent, PropsWithChildren, useContext, useEffect, useState } from 'react'; +import { + createContext, + FunctionComponent, + PropsWithChildren, + useCallback, + useContext, + useEffect, + useRef, + useState, +} from 'react'; import { breakpoints, Breakpoints } from '../../legacy-constants/breakpoints'; export type DeviceType = 'desktop' | 'tablet' | 'mobile'; @@ -15,40 +24,20 @@ export interface DeviceContextProps { breakpoints: Breakpoints; } -const getDeviceContext = (deviceName: DeviceType | undefined = undefined): DeviceContextProps => { - let isDesktop = false; - let isTablet = false; - let isMobile = false; - const defaultContext: DeviceContextProps = { - device: 'desktop', - isDesktop: true, - isTablet: false, - isMobile: false, +function getDeviceContext(deviceName: DeviceType): DeviceContextProps { + return { + device: deviceName, + isDesktop: deviceName === 'desktop', + isTablet: deviceName === 'tablet', + isMobile: deviceName === 'mobile', breakpoints, }; +} - if (deviceName) { - if (deviceName === 'desktop') { - isDesktop = true; - } else if (deviceName === 'tablet') { - isTablet = true; - } else if (deviceName === 'mobile') { - isMobile = true; - } - - return { - device: deviceName, - isDesktop, - isTablet, - isMobile, - breakpoints, - }; - } - return defaultContext; -}; - -const getDevice = (screenWidth: number): DeviceType => { +function getDeviceType(): DeviceType { let currentDevice: DeviceType = 'desktop'; + const screenWidth = (window.innerWidth || document.documentElement.clientWidth); + if (screenWidth >= breakpoints.desktop) { currentDevice = 'desktop'; } else if (screenWidth < breakpoints.desktop && screenWidth > breakpoints.mobile) { @@ -58,39 +47,46 @@ const getDevice = (screenWidth: number): DeviceType => { } return currentDevice; -}; +} -const DeviceContext = createContext(getDeviceContext()); +const DeviceContext = createContext(getDeviceContext(getDeviceType())); -/** - * @deprecated Use {@link DesignSystem} instead - */ export const DeviceContextProvider: FunctionComponent> = ({ children, staticDevice, }) => { - const [device, setDevice] = useState(getDeviceContext(staticDevice)); + const deviceType = staticDevice || getDeviceType(); - function handleScreenResize(): void { - const screenWidth = (window.innerWidth || document.documentElement.clientWidth); - const currentDevice = getDevice(screenWidth); + const previousDeviceType = useRef(deviceType); + const previousStaticDevice = useRef(staticDevice); + const [deviceContext, setDeviceContext] = useState(getDeviceContext(deviceType)); - setDevice(getDeviceContext(currentDevice)); + if (staticDevice !== previousStaticDevice.current) { + previousStaticDevice.current = staticDevice; + setDeviceContext(getDeviceContext(deviceType)); } + const handleScreenResize = useCallback(() => { + const currentDeviceType = getDeviceType(); + + if (currentDeviceType !== previousDeviceType.current) { + previousDeviceType.current = currentDeviceType; + setDeviceContext(getDeviceContext(currentDeviceType)); + } + }, []); + useEffect(() => { if (!staticDevice) { - handleScreenResize(); window.addEventListener('resize', handleScreenResize); return () => { window.removeEventListener('resize', handleScreenResize); }; } return undefined; - }, [staticDevice]); + }, [handleScreenResize, staticDevice]); return ( - + {children} ); diff --git a/packages/react/src/components/internationalization-provider/internationalization-provider.tsx b/packages/react/src/components/internationalization-provider/internationalization-provider.tsx index ec94aedd8f..7e28a60274 100644 --- a/packages/react/src/components/internationalization-provider/internationalization-provider.tsx +++ b/packages/react/src/components/internationalization-provider/internationalization-provider.tsx @@ -15,9 +15,6 @@ interface IntlContextProps { const IntlContext = createContext({ i18n: createI18n() }); -/** - * @deprecated Use {@link DesignSystem} instead - */ export const IntlProvider: FunctionComponent> = ({ children, language }) => { const [i18n] = useState(() => createI18n(language)); diff --git a/packages/react/src/components/table/sort-button-icon.test.tsx b/packages/react/src/components/table/sort-button-icon.test.tsx index 1cf2db2e07..679768a917 100644 --- a/packages/react/src/components/table/sort-button-icon.test.tsx +++ b/packages/react/src/components/table/sort-button-icon.test.tsx @@ -1,10 +1,12 @@ import { shallow } from 'enzyme'; import { useTheme } from '../../hooks/use-theme'; -import { equisoftTheme } from '../../themes'; import { SortButtonIcon } from './sort-button-icon'; +import { buildTheme, equisoftThemeCustomization } from '../../themes'; jest.mock('../../hooks/use-theme'); +const equisoftTheme = buildTheme(equisoftThemeCustomization); + describe('SortButtonIcon', () => { beforeEach(() => { jest.mocked(useTheme).mockReturnValue(equisoftTheme); diff --git a/packages/react/src/components/theme-wrapper/theme-wrapper.test.tsx b/packages/react/src/components/theme-wrapper/theme-wrapper.test.tsx index 85b80ebb3a..bfd970025d 100644 --- a/packages/react/src/components/theme-wrapper/theme-wrapper.test.tsx +++ b/packages/react/src/components/theme-wrapper/theme-wrapper.test.tsx @@ -1,8 +1,8 @@ import { render, shallow } from 'enzyme'; -import { buildTheme, Button } from '../..'; +import { Button } from '../..'; import { ShadowWrapper } from '../shadow-wrapper/shadow-wrapper'; import { ThemeWrapper } from './theme-wrapper'; -import { ThemeCustomization } from '../../themes/theme'; +import { ThemeCustomization } from '../../themes'; describe('Theme Wrapper', () => { test('Returns component with default theme', () => { @@ -25,10 +25,8 @@ describe('Theme Wrapper', () => { }, }; - const builtTheme = buildTheme(themeCustomization); - const tree1 = render( - +