Skip to content

Commit 64d6d6a

Browse files
authoredOct 5, 2020
refactor(Device): deprecate Device class and move all methods to smaller util functions (#697)
1 parent cce75e2 commit 64d6d6a

30 files changed

+1003
-822
lines changed
 

‎.eslintignore

-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,4 @@ shared
1010
rollup.config.js
1111
index.cjs.js
1212
index.esm.js
13-
packages/base/third-party/
1413
packages/cra-template

‎.reuse/dep5

+4
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ License: Apache-2.0
1111
Files: /packages/charts/src/components/PieChart/PieChart.tsx
1212
Copyright: 2016-2020 Recharts Group
1313
License: MIT
14+
15+
Files: packages/base/src/hooks/useIsomorphicLayoutEffect.ts
16+
Copyright: 2019 Tanner Linsley
17+
License: MIT

‎.storybook/main.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ module.exports = {
8181
'@ui5/webcomponents-react/dist': path.join(PATHS.root, 'packages', 'main', 'dist'),
8282
'@ui5/webcomponents-react': path.join(PATHS.root, 'packages', 'main', 'src'),
8383
'@ui5/webcomponents-react-charts': path.join(PATHS.root, 'packages', 'charts', 'src'),
84-
'@ui5/webcomponents-react-base/third-party': path.join(PATHS.root, 'packages', 'base', 'third-party'),
84+
'@ui5/webcomponents-react-base/types': path.join(PATHS.root, 'packages', 'base', 'types'),
8585
'@ui5/webcomponents-react-base': path.join(PATHS.root, 'packages', 'base', 'src')
8686
};
8787

‎LICENSES/MIT.txt

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
MIT License Copyright (c) <year> <copyright holders>
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is furnished
8+
to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice (including the next
11+
paragraph) shall be included in all copies or substantial portions of the
12+
Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
17+
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19+
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

‎config/jest.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ module.exports = {
2828
'^@shared/(.*)$': '<rootDir>/shared/$1',
2929
'^@ui5/webcomponents-react/dist/(.*)$': '<rootDir>/packages/main/dist/$1',
3030
'^@ui5/webcomponents-react/(.*)$': '<rootDir>/packages/main/src/$1',
31-
'^@ui5/webcomponents-react-base/third-party/(.*)$': '<rootDir>/packages/base/third-party/$1',
31+
'^@ui5/webcomponents-react-base/types(.*)$': '<rootDir>/packages/base/types/$1',
3232
'^@ui5/webcomponents-react-base/(.*)$': '<rootDir>/packages/base/src/$1',
3333
'^@ui5/webcomponents-react-charts/(.*)$': '<rootDir>/packages/charts/src/$1',
3434
'\\.(css|less)$': 'identity-obj-proxy'

‎config/jestsetup.ts

+13-8
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,19 @@ expect.addSnapshotSerializer(jssSerializer);
3838
expect.addSnapshotSerializer(contentLoaderSerializer);
3939

4040
export const setupMatchMedia = () => {
41-
// @ts-ignore
42-
window.matchMedia = () => {
43-
return {
44-
matches: true,
45-
addListener() {},
46-
removeListener() {}
47-
};
48-
};
41+
Object.defineProperty(window, 'matchMedia', {
42+
writable: true,
43+
value: jest.fn().mockImplementation((query) => ({
44+
matches: false,
45+
media: query,
46+
onchange: null,
47+
addListener: jest.fn(), // deprecated
48+
removeListener: jest.fn(), // deprecated
49+
addEventListener: jest.fn(),
50+
removeEventListener: jest.fn(),
51+
dispatchEvent: jest.fn()
52+
}))
53+
});
4954
};
5055

5156
export const setupResizeObserver = () => {

‎packages/base/package.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,12 @@
1414
"author": "SAP SE (https://www.sap.com)",
1515
"license": "Apache-2.0",
1616
"sideEffects": [
17-
"**/third-party/*",
1817
"./polyfill/*",
1918
"core-js/**/*",
2019
"intersection-observer"
2120
],
2221
"scripts": {
23-
"clean": "rimraf cjs Device hooks lib polyfill styling types utils index.esm.js index.d.ts",
22+
"clean": "rimraf cjs Device hooks lib polyfill styling utils index.esm.js index.d.ts",
2423
"build:rollup": "rollup -c rollup.config.js",
2524
"build:polyfills": "tsc ./src/polyfill/*.ts --outDir ./polyfill --skipLibCheck",
2625
"build": "npm-run-all -s build:rollup build:polyfills",

‎packages/base/src/Device/Media.test.ts

+10-39
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,21 @@
1-
import { setupMatchMedia } from '../../../../config/jestsetup';
21
import { EventRegistry } from './EventRegistry';
3-
import { Media, RANGESETS } from './Media';
4-
5-
const defaultSupportInstance = {
6-
matchmedialistener: false,
7-
matchmedia: false
8-
};
2+
import { getCurrentRange, MediaLegacy, RANGESETS } from './Media';
93

104
describe('Device - Media', () => {
115
test('invoke constructor', () => {
12-
const media = new Media(defaultSupportInstance);
13-
// @ts-ignore
14-
expect(media.mediaTimeout).toBe(100);
6+
const media = new MediaLegacy();
157
expect(media.hasRangeSet(RANGESETS.SAP_STANDARD)).toBe(true);
168
expect(media.hasRangeSet(RANGESETS.SAP_STANDARD_EXTENDED)).toBe(true);
17-
});
18-
19-
test('invoke constructor 2', () => {
20-
const media = new Media({ matchmedia: true, matchmedialistener: true });
21-
// @ts-ignore
22-
expect(media.mediaTimeout).toBe(0);
9+
media.initRangeSet(RANGESETS.SAP_STANDARD_EXTENDED);
2310
expect(media.hasRangeSet(RANGESETS.SAP_STANDARD)).toBe(true);
24-
expect(media.hasRangeSet(RANGESETS.SAP_STANDARD_EXTENDED)).toBe(true);
2511
});
2612

27-
test('matchLegacy', () => {
28-
const media = new Media(defaultSupportInstance);
29-
// @ts-ignore
30-
window.matchMedia = () => {
31-
return false;
32-
};
33-
expect(media.matches(19, 20, 'rem')).toBe(false);
34-
});
35-
36-
test('match', () => {
37-
const media = new Media({ matchmedia: true, matchmedialistener: true });
38-
// @ts-ignore
39-
window.matchMedia = () => {
40-
return { matches: true };
41-
};
42-
expect(media.matches(19, 20, 'rem')).toBe(true);
13+
test('getCurrentRangeSet with undefined Range Set', () => {
14+
expect(getCurrentRange('Not_Defined', 100)).toBeNull();
4315
});
4416

4517
test('Attach, fire and Detach Event', () => {
46-
const media = new Media(defaultSupportInstance);
18+
const media = new MediaLegacy();
4719
const callback = jest.fn();
4820
// @ts-ignore
4921
media.attachHandler(callback, this);
@@ -56,27 +28,26 @@ describe('Device - Media', () => {
5628
});
5729

5830
test('Init Custom Range Set and remove it again', () => {
59-
const media = new Media(defaultSupportInstance);
31+
const media = new MediaLegacy();
6032
media.initRangeSet('MyRangeSet', [200, 400], 'px', ['Small', 'Medium', 'Large']);
6133
expect(media.getCurrentRange('MyRangeSet', 300).name).toBe('Medium');
6234
media.removeRangeSet('MyRangeSet');
6335
});
6436

6537
test('Init Custom Range Set and remove it again w/ matchmedialistener', () => {
66-
setupMatchMedia();
67-
const media = new Media({ matchmedia: true, matchmedialistener: true });
38+
const media = new MediaLegacy();
6839
media.initRangeSet('MyRangeSet', [200, 400], 'px', ['Small', 'Medium', 'Large']);
6940
expect(media.getCurrentRange('MyRangeSet', 300).name).toBe('Medium');
7041
media.removeRangeSet('MyRangeSet');
7142
});
7243

7344
test('Remove unknown rangeset should not crash', () => {
74-
const media = new Media(defaultSupportInstance);
45+
const media = new MediaLegacy();
7546
expect(() => media.removeRangeSet('MyRangeSet')).not.toThrow();
7647
});
7748

7849
test("Don't remove build in rangesets", () => {
79-
const media = new Media(defaultSupportInstance);
50+
const media = new MediaLegacy();
8051
media.removeRangeSet(RANGESETS.SAP_STANDARD);
8152
expect(media.hasRangeSet(RANGESETS.SAP_STANDARD)).toBe(true);
8253
});

‎packages/base/src/Device/Media.ts

+294-200
Large diffs are not rendered by default.

‎packages/base/src/Device/Orientation.test.ts

-16
This file was deleted.

‎packages/base/src/Device/Orientation.ts

-14
This file was deleted.

‎packages/base/src/Device/Resize.test.ts

-16
This file was deleted.

‎packages/base/src/Device/Resize.ts

-24
This file was deleted.
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import {
2+
supportInputPlaceholder,
3+
supportMatchMedia,
4+
supportMatchMediaListener,
5+
supportOrientation,
6+
supportPointerEvents,
7+
supportRetina,
8+
supportWebSocket
9+
} from './Support';
10+
11+
describe('Support', () => {
12+
test('pointer events', () => {
13+
expect(supportPointerEvents()).toBe(false);
14+
});
15+
16+
test('input placeholder', () => {
17+
expect(supportInputPlaceholder()).toBe(true);
18+
});
19+
20+
test('websocket', () => {
21+
expect(supportWebSocket()).toBe(true);
22+
});
23+
24+
test('match media', () => {
25+
expect(supportMatchMedia()).toBe(true);
26+
});
27+
28+
test('match media listener', () => {
29+
expect(supportMatchMediaListener()).toBe(true);
30+
});
31+
32+
test('orientation', () => {
33+
expect(supportOrientation()).toBe(false);
34+
});
35+
test('retina', () => {
36+
expect(supportRetina()).toBe(false);
37+
});
38+
});

‎packages/base/src/Device/Support.ts

+30-20
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,33 @@
1-
import { supportTouch } from '@ui5/webcomponents-base/dist/Device';
2-
import '@ui5/webcomponents-react-base/third-party/modernizr';
1+
export const supportPointerEvents = () => {
2+
return 'onpointerdown' in window;
3+
};
4+
5+
export const supportInputPlaceholder = () => {
6+
return 'placeholder' in document.createElement('input') && 'placeholder' in document.createElement('textarea');
7+
};
8+
9+
export const supportWebSocket = () => {
10+
let isSupported = false;
11+
try {
12+
isSupported = 'WebSocket' in window && window.WebSocket.CLOSING === 2;
13+
} catch (e) {
14+
// do nothing
15+
}
16+
return isSupported;
17+
};
318

4-
declare const Modernizr: {
5-
pointerevents: boolean;
6-
matchmedia: boolean;
7-
deviceorientation: boolean;
8-
websockets: boolean;
9-
placeholder: boolean;
19+
export const supportMatchMedia = () => {
20+
return 'matchMedia' in window;
1021
};
1122

12-
export class Support {
13-
public touch: boolean = supportTouch();
14-
public pointer: boolean = Modernizr.pointerevents;
15-
public matchmedia: boolean = Modernizr.matchmedia;
16-
public matchmedialistener = !!(this.matchmedia && window.matchMedia('all and (max-width:0px)'));
17-
public orientation: boolean = Modernizr.deviceorientation;
18-
public retina: boolean = (window as any).retina || window.devicePixelRatio >= 2;
19-
public websocket: boolean = Modernizr.websockets;
20-
public input = {
21-
placeholder: Modernizr.placeholder
22-
};
23-
}
23+
export const supportMatchMediaListener = () => {
24+
return !!(supportMatchMedia() && window.matchMedia('all and (max-width:0px)'));
25+
};
26+
27+
export const supportOrientation = () => {
28+
return 'DeviceOrientationEvent' in window;
29+
};
30+
31+
export const supportRetina = () => {
32+
return (window as any).retina || window.devicePixelRatio >= 2;
33+
};

‎packages/base/src/Device/Utils.test.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { convertToPx, matchLegacyBySize } from './utils';
1+
import { changeRootCSSClass, convertToPx, matchLegacyBySize } from './utils';
22

33
describe('Device - Utils', () => {
44
test('convertToPx', () => {
@@ -19,4 +19,15 @@ describe('Device - Utils', () => {
1919
expect(matchLegacyBySize(20, -40, 'rem', [5])).toBe(false);
2020
expect(matchLegacyBySize(19, 20, 'rem', [319])).toBe(true);
2121
});
22+
23+
test('change css root classes', () => {
24+
changeRootCSSClass('sapUiMedia-Std', false);
25+
expect(document.documentElement.className).toBe('sapUiMedia-Std');
26+
changeRootCSSClass('sapUiMedia-StdExt-Phone', false);
27+
expect(document.documentElement.className).toBe('sapUiMedia-Std sapUiMedia-StdExt-Phone');
28+
changeRootCSSClass('sapUiMedia-StdExt-Desktop', false, 'sapUiMedia-StdExt-');
29+
expect(document.documentElement.className).toBe('sapUiMedia-Std sapUiMedia-StdExt-Desktop');
30+
changeRootCSSClass('sapUiMedia-StdExt-Desktop', true);
31+
expect(document.documentElement.className).toBe('sapUiMedia-Std ');
32+
});
2233
});
+58-15
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,62 @@
1-
describe('Device', () => {
2-
const FIREFOX_MAC = 'Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0';
3-
const FIREFOX_WIN = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0';
4-
5-
const CHROME =
6-
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36';
7-
8-
const SAFARI =
9-
'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1';
1+
import {
2+
attachOrientationChangeHandler,
3+
attachResizeHandler,
4+
detachOrientationChangeHandler,
5+
detachResizeHandler,
6+
getOrientation,
7+
getWindowSize
8+
} from './index';
109

11-
const IE = 'Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0)';
10+
describe('Device', () => {
11+
test('resize handler', () => {
12+
jest.useFakeTimers();
13+
const callback = jest.fn();
14+
attachResizeHandler(callback);
15+
expect(getWindowSize()).toEqual({
16+
height: 768,
17+
width: 1024
18+
});
19+
Object.defineProperty(window, 'innerWidth', { writable: true, configurable: true, value: 200 });
20+
global.dispatchEvent(new Event('resize'));
21+
jest.runAllTimers();
22+
expect(callback).toBeCalledWith({
23+
height: 768,
24+
width: 200
25+
});
26+
detachResizeHandler(callback);
27+
Object.defineProperty(window, 'innerWidth', { writable: true, configurable: true, value: 500 });
28+
global.dispatchEvent(new Event('resize'));
29+
jest.runAllTimers();
30+
expect(callback).toHaveBeenCalledTimes(1);
31+
// restore original value
32+
Object.defineProperty(window, 'innerWidth', { writable: true, configurable: true, value: 1024 });
33+
global.dispatchEvent(new Event('resize'));
34+
jest.runAllTimers();
35+
});
1236

13-
test('Firefox Mac', async (done) => {
14-
Object.defineProperty(window.navigator, 'userAgent', { value: FIREFOX_MAC });
15-
const device = (await import('./index')).Device;
16-
expect(device.browser.firefox).toBe(true);
17-
done();
37+
test('orientation change', () => {
38+
jest.useFakeTimers();
39+
const callback = jest.fn();
40+
attachOrientationChangeHandler(callback);
41+
Object.defineProperty(window, 'innerWidth', { writable: true, configurable: true, value: 1024 });
42+
Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: 768 });
43+
expect(getOrientation()).toEqual({
44+
landscape: true,
45+
portrait: false
46+
});
47+
Object.defineProperty(window, 'innerWidth', { writable: true, configurable: true, value: 300 });
48+
Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: 1000 });
49+
global.dispatchEvent(new Event('resize'));
50+
jest.runAllTimers();
51+
expect(callback).toBeCalledWith({
52+
portrait: true,
53+
landscape: false
54+
});
55+
detachOrientationChangeHandler(callback);
56+
Object.defineProperty(window, 'innerWidth', { writable: true, configurable: true, value: 1024 });
57+
Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: 768 });
58+
global.dispatchEvent(new Event('resize'));
59+
jest.runAllTimers();
60+
expect(callback).toHaveBeenCalledTimes(1);
1861
});
1962
});

‎packages/base/src/Device/index.ts

+387-149
Large diffs are not rendered by default.

‎packages/base/src/Device/utils.ts

+26-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
export const windowSize = () => {
1+
import { getOS, supportTouch } from '@ui5/webcomponents-base/dist/Device';
2+
import { supportMatchMedia, supportOrientation } from './Support';
3+
4+
export const getWindowSize = () => {
25
return [window.innerWidth, window.innerHeight];
36
};
47

@@ -24,8 +27,7 @@ export const changeRootCSSClass = (sClassName, bRemove, sPrefix?) => {
2427
}
2528
};
2629

27-
export const getQuery = (from, to, unit) => {
28-
unit = unit || 'px';
30+
export const getQuery = (from: number, to: number, unit = 'px') => {
2931
let q = 'all';
3032
if (from > 0) {
3133
q = `${q} and (min-width:${from}${unit})`;
@@ -55,3 +57,24 @@ export const matchLegacyBySize = (from, to, unit, size) => {
5557
const b = to < 0 || width <= to;
5658
return a && b;
5759
};
60+
61+
export const isLandscape = (bFromOrientationChange: boolean, orientation, bKeyboardOpen: boolean) => {
62+
if (supportTouch() && supportOrientation() && getOS().android) {
63+
// if on screen keyboard is open and the call of this method is from orientation change listener,
64+
// reverse the last value. this is because when keyboard opens on android device, the height can be less
65+
// than the width even in portrait mode.
66+
if (bKeyboardOpen && bFromOrientationChange) {
67+
return !orientation.landscape;
68+
}
69+
if (bKeyboardOpen) {
70+
// when keyboard opens, the last orientation change value will be returned.
71+
return orientation.landscape;
72+
}
73+
} else if (supportMatchMedia() && supportOrientation()) {
74+
// most desktop browsers and windows phone/tablet which not support orientationchange
75+
return !!window.matchMedia('(orientation: landscape)').matches;
76+
}
77+
// otherwise compare the width and height of window
78+
const size = getWindowSize();
79+
return size[0] > size[1];
80+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { useEffect, useLayoutEffect } from 'react';
2+
3+
export const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;

‎packages/base/src/hooks/useViewportRange.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { Device } from '@ui5/webcomponents-react-base/lib/Device';
2-
import { useEffect, useState, useRef } from 'react';
1+
import { getCurrentRange, attachHandler, detachHandler } from '@ui5/webcomponents-react-base/lib/Media';
2+
import { useEffect, useRef, useState } from 'react';
33

4-
export const useViewportRange = (rangeSet) => {
5-
const [currentRange, setCurrentRange] = useState(Device.media.getCurrentRange(rangeSet, window.innerWidth).name);
4+
export const useViewportRange = (rangeSet: string) => {
5+
const [currentRange, setCurrentRange] = useState(getCurrentRange(rangeSet, window.innerWidth).name);
66
const isMounted = useRef(true);
77

88
useEffect(() => {
@@ -11,10 +11,10 @@ export const useViewportRange = (rangeSet) => {
1111
setCurrentRange(range);
1212
}
1313
};
14-
Device.media.attachHandler(handler, null, 'StdExt');
14+
attachHandler(handler, null, rangeSet);
1515
return () => {
1616
isMounted.current = false;
17-
Device.resize.detachHandler(handler, null);
17+
detachHandler(handler, null);
1818
};
1919
}, [setCurrentRange, isMounted]);
2020

‎packages/base/src/lib/Device.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
import { Device } from '../Device';
2-
3-
export { Device };
1+
export * from '../Device';

‎packages/base/src/lib/Media.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from '../Device/Media';

‎packages/base/src/lib/hooks.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useConsolidatedRef } from '../hooks/useConsolidatedRef';
22
import { useI18nText } from '../hooks/useI18nBundle';
3+
import { useIsomorphicLayoutEffect } from '../hooks/useIsomorphicLayoutEffect';
34
import { usePassThroughHtmlProps } from '../hooks/usePassThroughHtmlProps';
45
import { useViewportRange } from '../hooks/useViewportRange';
56

6-
export { useConsolidatedRef, usePassThroughHtmlProps, useViewportRange, useI18nText };
7+
export { useConsolidatedRef, usePassThroughHtmlProps, useViewportRange, useI18nText, useIsomorphicLayoutEffect };

‎packages/base/src/utils/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { UIEvent } from 'react';
22

33
export const deprecationNotice = (component: string, message: string) => {
4-
if (process.env.NODE_ENV === 'development') {
4+
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
55
const value = `*** ui5-webcomponents-react Deprecation Notice - ${component} ***\n`;
66
// eslint-disable-next-line no-console
77
console.warn(`${value}${message}`);

‎packages/base/third-party/modernizr-config.json

-12
This file was deleted.

‎packages/base/third-party/modernizr.js

-286
This file was deleted.

‎packages/base/types/UI5Device.d.ts

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
interface OS {
2+
name?: string;
3+
versionStr?: string;
4+
version: number;
5+
windows?: boolean;
6+
macintosh?: boolean;
7+
ios?: boolean;
8+
android?: boolean;
9+
OS: {
10+
WINDOWS: 'win';
11+
MACINTOSH: 'mac';
12+
IOS: 'iOS';
13+
ANDROID: 'Android';
14+
};
15+
}
16+
17+
interface Browser {
18+
name: string;
19+
versionStr?: string;
20+
version: number;
21+
mobile?: boolean;
22+
msie?: boolean;
23+
edge?: boolean;
24+
firefox?: boolean;
25+
chrome?: boolean;
26+
safari?: boolean;
27+
webkit?: boolean;
28+
fullscreen?: boolean;
29+
webview?: boolean;
30+
phantomJS?: boolean;
31+
webkitVersion?: string;
32+
mozilla?: boolean;
33+
BROWSER: {
34+
INTERNET_EXPLORER: 'ie';
35+
EDGE: 'ed';
36+
FIREFOX: 'ff';
37+
CHROME: 'cr';
38+
SAFARI: 'sf';
39+
ANDROID: 'an';
40+
};
41+
}
42+
43+
interface System {
44+
phone: boolean;
45+
tablet: boolean;
46+
desktop: boolean;
47+
combi: boolean;
48+
SYSTEMTYPE: {
49+
TABLET: 'tablet';
50+
PHONE: 'phone';
51+
DESKTOP: 'desktop';
52+
COMBI: 'combi';
53+
};
54+
}
55+
56+
declare module '@ui5/webcomponents-base/dist/Device' {
57+
export function isIE(): boolean;
58+
59+
export function isEdge(): boolean;
60+
61+
export function isChrome(): boolean;
62+
63+
export function isFF(): boolean;
64+
65+
export function isSafari(): boolean;
66+
67+
export function isMobile(): boolean;
68+
69+
export function isDesktop(): boolean;
70+
71+
export function isTablet(): boolean;
72+
73+
export function isPhone(): boolean;
74+
75+
export function isAndroid(): boolean;
76+
77+
export function getOS(): OS;
78+
79+
export function getSystem(): System;
80+
81+
export function getBrowser(): Browser;
82+
83+
export function supportTouch(): boolean;
84+
}

‎packages/main/src/components/Form/index.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { getCurrentRange } from '@ui5/webcomponents-react-base/lib/Media';
12
import { createComponentStyles } from '@ui5/webcomponents-react-base/lib/createComponentStyles';
2-
import { Device } from '@ui5/webcomponents-react-base/lib/Device';
33
import { useConsolidatedRef, usePassThroughHtmlProps } from '@ui5/webcomponents-react-base/lib/hooks';
44
import { StyleClassHelper } from '@ui5/webcomponents-react-base/lib/StyleClassHelper';
55
import { Title } from '@ui5/webcomponents-react/lib/Title';
@@ -115,12 +115,12 @@ const Form: FC<FormPropTypes> = forwardRef((props: FormPropTypes, ref: Ref<HTMLD
115115

116116
const formRef = useConsolidatedRef<HTMLDivElement>(ref);
117117
// use the window range set as first best guess
118-
const [currentRange, setCurrentRange] = useState(Device.media.getCurrentRange('StdExt', window.innerWidth).name);
118+
const [currentRange, setCurrentRange] = useState(getCurrentRange('StdExt', window.innerWidth).name);
119119
const lastRange = useRef(currentRange);
120120

121121
useEffect(() => {
122122
const observer = new ResizeObserver(([form]) => {
123-
const newRange = Device.media.getCurrentRange('StdExt', form.contentRect.width).name;
123+
const newRange = getCurrentRange('StdExt', form.contentRect.width).name;
124124
if (lastRange.current !== newRange) {
125125
lastRange.current = newRange;
126126
setCurrentRange(newRange);

‎packages/main/src/components/ThemeProvider/index.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { getRTL } from '@ui5/webcomponents-base/dist/config/RTL';
22
import { getTheme } from '@ui5/webcomponents-base/dist/config/Theme';
33
import { createComponentStyles } from '@ui5/webcomponents-react-base/lib/createComponentStyles';
44
import { cssVariablesStyles } from '@ui5/webcomponents-react-base/lib/CssSizeVariables';
5+
import { useIsomorphicLayoutEffect } from '@ui5/webcomponents-react-base/lib/hooks';
6+
import { initRangeSet, RANGESETS } from '@ui5/webcomponents-react-base/lib/Media';
57
import { ThemingParameters } from '@ui5/webcomponents-react-base/lib/ThemingParameters';
68
import { ContentDensity } from '@ui5/webcomponents-react/lib/ContentDensity';
79
import React, { FC, ReactNode, useEffect, useMemo } from 'react';
@@ -52,6 +54,12 @@ const ThemeProvider: FC<ThemeProviderProps> = (props: ThemeProviderProps) => {
5254
}
5355
}, []);
5456

57+
// init default media range sets
58+
useIsomorphicLayoutEffect(() => {
59+
initRangeSet();
60+
initRangeSet(RANGESETS.SAP_STANDARD_EXTENDED);
61+
}, []);
62+
5563
return <ReactJssThemeProvider theme={themeContext}>{children}</ReactJssThemeProvider>;
5664
};
5765

0 commit comments

Comments
 (0)
Please sign in to comment.