@hyphen/hyphen-components 2.21.0 → 2.22.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/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/useIsMobile/useIsMobile.d.ts +1 -0
- package/dist/hooks/useIsMobile/useIsMobile.stories.d.ts +6 -0
- package/dist/hyphen-components.cjs.development.js +42 -0
- package/dist/hyphen-components.cjs.development.js.map +1 -1
- package/dist/hyphen-components.cjs.production.min.js +1 -1
- package/dist/hyphen-components.cjs.production.min.js.map +1 -1
- package/dist/hyphen-components.esm.js +239 -216
- package/dist/hyphen-components.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useIsMobile/useIsMobile.mdx +12 -0
- package/src/hooks/useIsMobile/useIsMobile.stories.tsx +27 -0
- package/src/hooks/useIsMobile/useIsMobile.test.tsx +46 -0
- package/src/hooks/useIsMobile/useIsMobile.tsx +23 -0
package/package.json
CHANGED
package/src/hooks/index.ts
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Meta, Canvas } from '@storybook/addon-docs';
|
|
2
|
+
import * as Stories from './useIsMobile.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# useIsMobile
|
|
7
|
+
|
|
8
|
+
The `useIsMobile` returns a boolean of whether `window.innerWidth` is greater than the minimum width of the `desktop` breakpoint.
|
|
9
|
+
|
|
10
|
+
## Basic Usage
|
|
11
|
+
|
|
12
|
+
<Canvas isExpanded of={Stories.BasicUsage} />
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Meta } from '@storybook/react';
|
|
3
|
+
import { ResponsiveProvider } from '../../components/ResponsiveProvider/ResponsiveProvider';
|
|
4
|
+
import { useIsMobile } from '../useIsMobile/useIsMobile';
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof useIsMobile> = {
|
|
7
|
+
title: 'Hooks/useIsMobile',
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default meta;
|
|
11
|
+
|
|
12
|
+
export const BasicUsage = () =>
|
|
13
|
+
(() => {
|
|
14
|
+
const App = () => {
|
|
15
|
+
const isMobile = useIsMobile();
|
|
16
|
+
return (
|
|
17
|
+
<div>
|
|
18
|
+
<p>isMobile: {isMobile ? '✅ TRUE' : '❌ FALSE'}</p>
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
return (
|
|
23
|
+
<ResponsiveProvider>
|
|
24
|
+
<App />
|
|
25
|
+
</ResponsiveProvider>
|
|
26
|
+
);
|
|
27
|
+
})();
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render } from '@testing-library/react';
|
|
3
|
+
import { useIsMobile } from './useIsMobile';
|
|
4
|
+
import { BREAKPOINTS } from '../../lib/tokens';
|
|
5
|
+
|
|
6
|
+
const UseIsMobileExample = () => {
|
|
7
|
+
const isMobile = useIsMobile();
|
|
8
|
+
|
|
9
|
+
return <div>{isMobile ? 'is mobile' : 'not mobile'}</div>;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
describe('useIsMobile hook', () => {
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
// Mock window.matchMedia
|
|
15
|
+
Object.defineProperty(window, 'matchMedia', {
|
|
16
|
+
writable: true,
|
|
17
|
+
value: jest.fn().mockImplementation((query) => ({
|
|
18
|
+
matches: query.includes('max-width'),
|
|
19
|
+
media: query,
|
|
20
|
+
onchange: null,
|
|
21
|
+
addEventListener: jest.fn(),
|
|
22
|
+
removeEventListener: jest.fn(),
|
|
23
|
+
})),
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('renders with initial state', () => {
|
|
28
|
+
const { getByText } = render(<UseIsMobileExample />);
|
|
29
|
+
expect(getByText('not mobile')).toBeInTheDocument();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('renders as mobile when window width is less than MOBILE_BREAKPOINT', () => {
|
|
33
|
+
const desktopBreakpoint = BREAKPOINTS.find((b) => b.name === 'desktop');
|
|
34
|
+
window.innerWidth =
|
|
35
|
+
(desktopBreakpoint ? desktopBreakpoint.minWidth : 992) - 1;
|
|
36
|
+
const { getByText } = render(<UseIsMobileExample />);
|
|
37
|
+
expect(getByText('is mobile')).toBeInTheDocument();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('renders as not mobile when window width is greater than MOBILE_BREAKPOINT', () => {
|
|
41
|
+
const desktopBreakpoint = BREAKPOINTS.find((b) => b.name === 'desktop');
|
|
42
|
+
window.innerWidth = desktopBreakpoint ? desktopBreakpoint.minWidth : 992;
|
|
43
|
+
const { getByText } = render(<UseIsMobileExample />);
|
|
44
|
+
expect(getByText('not mobile')).toBeInTheDocument();
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { BREAKPOINTS } from '../../lib/tokens';
|
|
3
|
+
|
|
4
|
+
const desktopBreakpoint = BREAKPOINTS.find((b) => b.name === 'desktop');
|
|
5
|
+
const MOBILE_BREAKPOINT = desktopBreakpoint ? desktopBreakpoint.minWidth : 0; // min width in pixels
|
|
6
|
+
|
|
7
|
+
export function useIsMobile(): boolean {
|
|
8
|
+
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
|
|
9
|
+
undefined
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
React.useEffect(() => {
|
|
13
|
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
14
|
+
const onChange = () => {
|
|
15
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
16
|
+
};
|
|
17
|
+
mql.addEventListener('change', onChange);
|
|
18
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
19
|
+
return () => mql.removeEventListener('change', onChange);
|
|
20
|
+
}, []);
|
|
21
|
+
|
|
22
|
+
return !!isMobile;
|
|
23
|
+
}
|