diff --git a/src/internal/breakpoints.ts b/src/internal/breakpoints.ts index 62c3338b0f..574d783082 100644 --- a/src/internal/breakpoints.ts +++ b/src/internal/breakpoints.ts @@ -12,8 +12,6 @@ const BREAKPOINT_MAPPING: [Breakpoint, number][] = [ ['default', -1], ]; -export const mobileBreakpoint = BREAKPOINT_MAPPING.filter(b => b[0] === 'xs')[0][1]; - const BREAKPOINTS_DESCENDING = BREAKPOINT_MAPPING.map(([bp]) => bp); /** diff --git a/src/internal/components/dropdown/index.tsx b/src/internal/components/dropdown/index.tsx index 7dbc402aeb..12d55b0b12 100644 --- a/src/internal/components/dropdown/index.tsx +++ b/src/internal/components/dropdown/index.tsx @@ -4,12 +4,11 @@ import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import clsx from 'clsx'; -import { useMergeRefs, useResizeObserver, useUniqueId } from '@cloudscape-design/component-toolkit/internal'; +import { useMergeRefs, useMobile, useResizeObserver, useUniqueId } from '@cloudscape-design/component-toolkit/internal'; import { getLogicalBoundingClientRect } from '@cloudscape-design/component-toolkit/internal'; import { fireNonCancelableEvent } from '../../events'; import customCssProps from '../../generated/custom-css-properties'; -import { useMobile } from '../../hooks/use-mobile'; import { usePortalModeClasses } from '../../hooks/use-portal-mode-classes'; import { useVisualRefresh } from '../../hooks/use-visual-mode'; import { nodeBelongs } from '../../utils/node-belongs'; diff --git a/src/internal/hooks/use-mobile/__tests__/use-mobile.test.tsx b/src/internal/hooks/use-mobile/__tests__/use-mobile.test.tsx deleted file mode 100644 index 9a1ca0c731..0000000000 --- a/src/internal/hooks/use-mobile/__tests__/use-mobile.test.tsx +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 -import React, { useRef } from 'react'; -import { act, render } from '@testing-library/react'; - -import { useMobile } from '../index'; - -function Demo() { - const renderCount = useRef(0); - const isMobile = useMobile(); - renderCount.current++; - return ( -
- {String(isMobile)} - {renderCount.current} -
- ); -} - -function resizeWindow(width: number) { - act(() => { - Object.defineProperty(window, 'innerWidth', { value: width }); - window.dispatchEvent(new CustomEvent('resize')); - }); -} - -test('should report mobile width on the initial render', () => { - resizeWindow(400); - const { getByTestId } = render(); - expect(getByTestId('mobile')).toHaveTextContent('true'); -}); - -test('should report desktop width on the initial render', () => { - resizeWindow(1200); - const { getByTestId } = render(); - expect(getByTestId('mobile')).toHaveTextContent('false'); -}); - -test('should report the updated value after resize', () => { - resizeWindow(400); - const { getByTestId } = render(); - const countBefore = getByTestId('render-count').textContent; - resizeWindow(1200); - const countAfter = getByTestId('render-count').textContent; - expect(getByTestId('mobile')).toHaveTextContent('false'); - expect(countBefore).not.toEqual(countAfter); -}); - -test('no renders when resize does not hit the breakpoint', () => { - resizeWindow(1000); - const { getByTestId } = render(); - const countBefore = getByTestId('render-count').textContent; - resizeWindow(1200); - const countAfter = getByTestId('render-count').textContent; - expect(countBefore).toEqual(countAfter); -}); diff --git a/src/internal/hooks/use-mobile/index.ts b/src/internal/hooks/use-mobile/index.ts deleted file mode 100644 index b1a6ef7d05..0000000000 --- a/src/internal/hooks/use-mobile/index.ts +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 -import { createSingletonState } from '@cloudscape-design/component-toolkit/internal'; - -import { getMatchingBreakpoint, mobileBreakpoint } from '../../breakpoints'; - -export const forceMobileModeSymbol = Symbol.for('awsui-force-mobile-mode'); - -function getIsMobile() { - // allow overriding the mobile mode in tests - // any is needed because of this https://github.com/microsoft/TypeScript/issues/36813 - const forceMobileMode = (globalThis as any)[forceMobileModeSymbol]; - if (typeof forceMobileMode !== 'undefined') { - return forceMobileMode; - } - if (typeof window === 'undefined') { - // assume desktop in server-rendering - return false; - } - - if (window.matchMedia) { - /** - * Some browsers include the scrollbar width in their media query calculations, but - * some browsers don't. Thus we can't use `window.innerWidth` or - * `document.documentElement.clientWidth` to get a very accurate result (since we - * wouldn't know which one of them to use). - * Instead, we use the media query here in JS too. - */ - return window.matchMedia(`(max-width: ${mobileBreakpoint}px)`).matches; - } - - return getMatchingBreakpoint(window.innerWidth, ['xs']) !== 'xs'; -} - -export const useMobile = createSingletonState({ - initialState: () => getIsMobile(), - factory: handler => { - const listener = () => handler(getIsMobile()); - window.addEventListener('resize', listener); - return () => { - window.removeEventListener('resize', listener); - }; - }, -});