@openmrs/esm-react-utils 9.0.3-pre.4235 → 9.0.3-pre.4241
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/.turbo/turbo-build.log +1 -1
- package/package.json +12 -12
- package/src/useLayoutType.test.tsx +107 -0
package/.turbo/turbo-build.log
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmrs/esm-react-utils",
|
|
3
|
-
"version": "9.0.3-pre.
|
|
3
|
+
"version": "9.0.3-pre.4241",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"description": "React utilities for OpenMRS.",
|
|
6
6
|
"type": "module",
|
|
@@ -79,17 +79,17 @@
|
|
|
79
79
|
"swr": "2.x"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
|
-
"@openmrs/esm-api": "9.0.3-pre.
|
|
83
|
-
"@openmrs/esm-config": "9.0.3-pre.
|
|
84
|
-
"@openmrs/esm-context": "9.0.3-pre.
|
|
85
|
-
"@openmrs/esm-emr-api": "9.0.3-pre.
|
|
86
|
-
"@openmrs/esm-error-handling": "9.0.3-pre.
|
|
87
|
-
"@openmrs/esm-extensions": "9.0.3-pre.
|
|
88
|
-
"@openmrs/esm-feature-flags": "9.0.3-pre.
|
|
89
|
-
"@openmrs/esm-globals": "9.0.3-pre.
|
|
90
|
-
"@openmrs/esm-navigation": "9.0.3-pre.
|
|
91
|
-
"@openmrs/esm-state": "9.0.3-pre.
|
|
92
|
-
"@openmrs/esm-utils": "9.0.3-pre.
|
|
82
|
+
"@openmrs/esm-api": "9.0.3-pre.4241",
|
|
83
|
+
"@openmrs/esm-config": "9.0.3-pre.4241",
|
|
84
|
+
"@openmrs/esm-context": "9.0.3-pre.4241",
|
|
85
|
+
"@openmrs/esm-emr-api": "9.0.3-pre.4241",
|
|
86
|
+
"@openmrs/esm-error-handling": "9.0.3-pre.4241",
|
|
87
|
+
"@openmrs/esm-extensions": "9.0.3-pre.4241",
|
|
88
|
+
"@openmrs/esm-feature-flags": "9.0.3-pre.4241",
|
|
89
|
+
"@openmrs/esm-globals": "9.0.3-pre.4241",
|
|
90
|
+
"@openmrs/esm-navigation": "9.0.3-pre.4241",
|
|
91
|
+
"@openmrs/esm-state": "9.0.3-pre.4241",
|
|
92
|
+
"@openmrs/esm-utils": "9.0.3-pre.4241",
|
|
93
93
|
"@swc/cli": "0.8.0",
|
|
94
94
|
"@swc/core": "1.15.18",
|
|
95
95
|
"@vitest/coverage-v8": "^4.0.18",
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { describe, expect, it, afterEach } from 'vitest';
|
|
2
|
+
import { renderHook, act } from '@testing-library/react';
|
|
3
|
+
import { useLayoutType, isDesktop, type LayoutType } from './useLayoutType';
|
|
4
|
+
|
|
5
|
+
// Breakpoint class → layout mapping used across tests
|
|
6
|
+
|
|
7
|
+
const LAYOUT_CASES: Array<[string, LayoutType]> = [
|
|
8
|
+
['omrs-breakpoint-lt-tablet', 'phone'],
|
|
9
|
+
['omrs-breakpoint-gt-tablet', 'small-desktop'],
|
|
10
|
+
['omrs-breakpoint-gt-small-desktop', 'large-desktop'],
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
const ALL_BREAKPOINT_CLASSES = LAYOUT_CASES.map(([className]) => className);
|
|
14
|
+
|
|
15
|
+
// Helper to apply a breakpoint class to the body
|
|
16
|
+
|
|
17
|
+
function setBreakpoint(className?: string) {
|
|
18
|
+
document.body.classList.remove(...ALL_BREAKPOINT_CLASSES);
|
|
19
|
+
if (className) {
|
|
20
|
+
document.body.classList.add(className);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function renderWithBreakpoint(className?: string) {
|
|
25
|
+
setBreakpoint(className);
|
|
26
|
+
return renderHook(() => useLayoutType());
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe('useLayoutType', () => {
|
|
30
|
+
afterEach(() => {
|
|
31
|
+
document.body.classList.remove(...ALL_BREAKPOINT_CLASSES);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('returns "tablet" by default when no breakpoint class is present', () => {
|
|
35
|
+
const { result } = renderWithBreakpoint();
|
|
36
|
+
expect(result.current).toBe('tablet');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it.each(LAYOUT_CASES)('maps class "%s" to layout "%s"', (className, expectedLayout) => {
|
|
40
|
+
const { result } = renderWithBreakpoint(className);
|
|
41
|
+
expect(result.current).toBe(expectedLayout);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('updates layout when breakpoint class changes on resize', () => {
|
|
45
|
+
const { result } = renderHook(() => useLayoutType());
|
|
46
|
+
expect(result.current).toBe('tablet');
|
|
47
|
+
|
|
48
|
+
act(() => {
|
|
49
|
+
setBreakpoint('omrs-breakpoint-lt-tablet');
|
|
50
|
+
window.dispatchEvent(new Event('resize'));
|
|
51
|
+
});
|
|
52
|
+
expect(result.current).toBe('phone');
|
|
53
|
+
|
|
54
|
+
act(() => {
|
|
55
|
+
setBreakpoint('omrs-breakpoint-gt-small-desktop');
|
|
56
|
+
window.dispatchEvent(new Event('resize'));
|
|
57
|
+
});
|
|
58
|
+
expect(result.current).toBe('large-desktop');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('falls back to "tablet" when all breakpoint classes are removed', () => {
|
|
62
|
+
const { result } = renderHook(() => useLayoutType());
|
|
63
|
+
|
|
64
|
+
act(() => {
|
|
65
|
+
setBreakpoint('omrs-breakpoint-gt-tablet');
|
|
66
|
+
window.dispatchEvent(new Event('resize'));
|
|
67
|
+
});
|
|
68
|
+
expect(result.current).toBe('small-desktop');
|
|
69
|
+
|
|
70
|
+
act(() => {
|
|
71
|
+
setBreakpoint(); // clears all classes
|
|
72
|
+
window.dispatchEvent(new Event('resize'));
|
|
73
|
+
});
|
|
74
|
+
expect(result.current).toBe('tablet');
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('ignores unrelated window events', () => {
|
|
78
|
+
const { result } = renderHook(() => useLayoutType());
|
|
79
|
+
|
|
80
|
+
act(() => {
|
|
81
|
+
setBreakpoint('omrs-breakpoint-lt-tablet');
|
|
82
|
+
window.dispatchEvent(new Event('scroll'));
|
|
83
|
+
window.dispatchEvent(new Event('click'));
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// DOM changed but no resize fired — hook should not have re-read the class
|
|
87
|
+
expect(result.current).toBe('tablet');
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
describe('isDesktop', () => {
|
|
92
|
+
it.each<[LayoutType, boolean]>([
|
|
93
|
+
['phone', false],
|
|
94
|
+
['tablet', false],
|
|
95
|
+
['small-desktop', true],
|
|
96
|
+
['large-desktop', true],
|
|
97
|
+
])('returns %s for layout "%s"', (layout, expected) => {
|
|
98
|
+
expect(isDesktop(layout)).toBe(expected);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('identifies non-desktop layouts correctly', () => {
|
|
102
|
+
const nonDesktopLayouts = LAYOUT_CASES.map(([, layout]) => layout).filter(
|
|
103
|
+
(layout) => !isDesktop(layout),
|
|
104
|
+
);
|
|
105
|
+
expect(nonDesktopLayouts).toEqual(['phone']);
|
|
106
|
+
});
|
|
107
|
+
});
|