Skip to content

Commit a753cb0

Browse files
committed
Iterate on viewport scaling polyfill
* Add scaling for default 'em' unit polyfill. * Move scale context provider into context file. * Expand list of length style properties.
1 parent 06dfb42 commit a753cb0

9 files changed

Lines changed: 141 additions & 103 deletions

File tree

packages/react-strict-dom/src/native/index.js

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,11 @@ import type {
1818
import typeof * as TStyleX from '@stylexjs/stylex';
1919

2020
import * as React from 'react';
21-
import { useMemo } from 'react';
2221
import * as compat from './compat';
2322
import * as html from './html';
2423
import * as stylex from './stylex';
2524
import { ProvideCustomProperties } from './modules/ContextCustomProperties';
2625
import { ProvideViewportScale } from './modules/ContextViewportScale';
27-
import * as ReactNative from './react-native';
2826

2927
type StyleTheme<V, T> = Theme<V, T>;
3028
type StyleVars<T> = VarGroup<T>;
@@ -38,11 +36,6 @@ type ProviderProps = $ReadOnly<{
3836
customProperties: ProviderValue
3937
}>;
4038

41-
type ViewportProviderProps = $ReadOnly<{
42-
children: React.Node,
43-
viewportWidth: number
44-
}>;
45-
4639
export type { StaticStyles, StyleTheme, StyleVars, Styles, StylesWithout };
4740

4841
function ThemeProvider(props: ProviderProps): React.Node {
@@ -55,29 +48,9 @@ function ThemeProvider(props: ProviderProps): React.Node {
5548
);
5649
}
5750

58-
function ViewportProvider({
59-
viewportWidth: logicalViewportWidth,
60-
children
61-
}: ViewportProviderProps): React.Node {
62-
const { width: viewportWidth } = ReactNative.useWindowDimensions();
63-
64-
const viewportScale = useMemo(
65-
() => ({
66-
scale: viewportWidth / logicalViewportWidth
67-
}),
68-
[logicalViewportWidth, viewportWidth]
69-
);
70-
71-
return (
72-
<ProvideViewportScale value={viewportScale}>
73-
{children}
74-
</ProvideViewportScale>
75-
);
76-
}
77-
7851
const contexts = {
7952
ThemeProvider: ThemeProvider as typeof ThemeProvider,
80-
ViewportProvider: ViewportProvider as typeof ViewportProvider
53+
ViewportProvider: ProvideViewportScale as typeof ProvideViewportScale
8154
};
8255

8356
// Export using StyleX types as the shim has divergent types internally.

packages/react-strict-dom/src/native/modules/ContextViewportScale.js

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,49 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @flow strict
7+
* @flow strict-local
88
*/
99

10-
import React from 'react';
10+
import * as React from 'react';
11+
import * as ReactNative from '../react-native';
1112

12-
type ViewportScale = $ReadOnly<{
13+
type Value = $ReadOnly<{
1314
scale: number
1415
}>;
1516

16-
const ContextViewportScale: React.Context<ViewportScale> = React.createContext({
17-
scale: 1
18-
});
17+
type ProviderProps = $ReadOnly<{
18+
children: React.Node,
19+
viewportWidth: number
20+
}>;
21+
22+
const defaultContext = { scale: 1 };
23+
const ContextViewportScale: React.Context<Value> =
24+
React.createContext(defaultContext);
1925

2026
if (__DEV__) {
2127
ContextViewportScale.displayName = 'ContextViewportScale';
2228
}
2329

24-
export const ProvideViewportScale = ContextViewportScale.Provider;
30+
export function ProvideViewportScale({
31+
viewportWidth: logicalViewportWidth,
32+
children
33+
}: ProviderProps): React.Node {
34+
const { width: viewportWidth } = ReactNative.useWindowDimensions();
35+
36+
const viewportScale = React.useMemo(
37+
() => ({
38+
scale: viewportWidth / logicalViewportWidth
39+
}),
40+
[logicalViewportWidth, viewportWidth]
41+
);
42+
43+
return (
44+
<ContextViewportScale.Provider value={viewportScale}>
45+
{children}
46+
</ContextViewportScale.Provider>
47+
);
48+
}
2549

26-
export function useViewportScale(): ViewportScale {
50+
export function useViewportScale(): Value {
2751
return React.useContext(ContextViewportScale);
2852
}

packages/react-strict-dom/src/native/modules/useStrictDOMElement.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @flow strict
7+
* @flow strict-local
88
*/
99

1010
import type { CallbackRef } from '../../types/react';
1111

1212
import * as React from 'react';
1313

14-
import { useElementCallback } from '../../shared/useElementCallback';
1514
import { errorMsg } from '../../shared/logUtils';
15+
import { useElementCallback } from '../../shared/useElementCallback';
1616
import { useViewportScale } from './ContextViewportScale';
1717

1818
function errorUnimplemented(name: string) {

packages/react-strict-dom/src/native/stylex/CSSLengthUnitValue.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,19 @@ export class CSSLengthUnitValue {
5454

5555
resolvePixelValue(options: ResolvePixelValueOptions): number {
5656
const {
57-
viewportWidth,
58-
viewportHeight,
5957
fontScale = 1,
6058
inheritedFontSize,
61-
viewportScale
59+
viewportHeight,
60+
viewportScale,
61+
viewportWidth
6262
} = options;
6363
const unit = this.unit;
6464
const value = this.value;
6565
const valuePercent = value / 100;
6666
switch (unit) {
6767
case 'em': {
6868
if (inheritedFontSize == null) {
69-
return fontScale * 16 * value;
69+
return fontScale * 16 * value * viewportScale;
7070
} else {
7171
return inheritedFontSize * value;
7272
}

packages/react-strict-dom/src/native/stylex/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ import type {
1919
} from '../../types/styles';
2020

2121
import { CSSLengthUnitValue } from './CSSLengthUnitValue';
22+
import { CSSTransformValue } from './CSSTransformValue';
2223
import { CSSUnparsedValue } from './typed-om/CSSUnparsedValue';
2324
import { errorMsg, warnMsg } from '../../shared/logUtils';
2425
import { fixContentBox } from './fixContentBox';
2526
import { flattenStyle } from './flattenStyleXStyles';
2627
import { isAllowedShortFormValue } from './isAllowedShortFormValue';
2728
import { isAllowedStyleKey } from './isAllowedStyleKey';
29+
import { lengthStyleKeySet } from './isLengthStyleKey';
2830
import { mediaQueryMatches } from './mediaQueryMatches';
2931
import { parseTextShadow } from './parseTextShadow';
3032
import { parseTimeValue } from './parseTimeValue';
@@ -34,8 +36,6 @@ import {
3436
stringContainsVariables
3537
} from './customProperties';
3638
import { version } from '../modules/version';
37-
import { CSSTransformValue } from './CSSTransformValue';
38-
import { LENGTH_PROPS } from './lengthProps';
3939

4040
type ResolveStyleOptions = $ReadOnly<{
4141
active?: ?boolean,
@@ -365,7 +365,7 @@ function resolveStyle(
365365
if (
366366
viewportScale !== 1 &&
367367
typeof styleValue === 'number' &&
368-
LENGTH_PROPS.has(propName)
368+
lengthStyleKeySet.has(propName)
369369
) {
370370
result[propName] = styleValue * viewportScale;
371371
continue;
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict
8+
*/
9+
10+
import { version } from '../modules/version';
11+
12+
export const lengthStyleKeySet: Set<string> = new Set([
13+
'blockSize',
14+
'borderBottomLeftRadius',
15+
'borderBottomRightRadius',
16+
'borderBottomWidth',
17+
'borderBlockWidth',
18+
'borderBlockEndWidth',
19+
'borderBlockStartWidth',
20+
'borderEndEndRadius',
21+
'borderEndStartRadius',
22+
'borderInlineWidth',
23+
'borderInlineEndWidth',
24+
'borderInlineStartWidth',
25+
'borderLeftWidth',
26+
'borderRadius',
27+
'borderRightWidth',
28+
'borderStartEndRadius',
29+
'borderStartStartRadius',
30+
'borderTopLeftRadius',
31+
'borderTopRightRadius',
32+
'borderTopWidth',
33+
'borderWidth',
34+
'bottom',
35+
'columnGap',
36+
'gap',
37+
'height',
38+
'inlineSize',
39+
'inset',
40+
'insetBlock',
41+
'insetBlockEnd',
42+
'insetBlockStart',
43+
'insetInline',
44+
'insetInlineEnd',
45+
'insetInlineStart',
46+
'left',
47+
'margin',
48+
'marginBlock',
49+
'marginBlockEnd',
50+
'marginBlockStart',
51+
'marginBottom',
52+
'marginInline',
53+
'marginInlineEnd',
54+
'marginInlineStart',
55+
'marginLeft',
56+
'marginRight',
57+
'marginTop',
58+
'maxBlockSize',
59+
'maxHeight',
60+
'maxInlineSize',
61+
'maxWidth',
62+
'minBlockSize',
63+
'minHeight',
64+
'minInlineSize',
65+
'minWidth',
66+
'padding',
67+
'paddingBlock',
68+
'paddingBlockEnd',
69+
'paddingBlockStart',
70+
'paddingBottom',
71+
'paddingInline',
72+
'paddingInlineEnd',
73+
'paddingInlineStart',
74+
'paddingLeft',
75+
'paddingRight',
76+
'paddingTop',
77+
'right',
78+
'rowGap',
79+
'top',
80+
'width'
81+
]);
82+
83+
if (version.experimental) {
84+
lengthStyleKeySet.add('outlineOffset');
85+
lengthStyleKeySet.add('outlineWidth');
86+
}

packages/react-strict-dom/src/native/stylex/lengthProps.js

Lines changed: 0 additions & 52 deletions
This file was deleted.

packages/react-strict-dom/tests/__snapshots__/html-test.native.js.snap-native

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,11 +2028,11 @@ exports[`<html.*> viewport width lengths are scaled according to viewport width:
20282028
ref={[Function]}
20292029
style={
20302030
{
2031-
"borderWidth": 3.75,
2031+
"borderWidth": 0.75,
20322032
"boxSizing": "content-box",
20332033
"height": 75,
20342034
"margin": 15,
2035-
"padding": 11.25,
2035+
"padding": 24,
20362036
"position": "static",
20372037
"transform": [
20382038
{
@@ -2051,6 +2051,8 @@ exports[`<html.*> viewport width lengths are scaled according to viewport width:
20512051
style={
20522052
{
20532053
"boxSizing": "content-box",
2054+
"fontSize": 24,
2055+
"lineHeight": 24,
20542056
"position": "static",
20552057
}
20562058
}

packages/react-strict-dom/tests/html-test.native.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1641,12 +1641,16 @@ describe('<html.*>', () => {
16411641

16421642
const styles = css.create({
16431643
container: {
1644+
borderWidth: '1px',
1645+
height: '100px',
16441646
margin: '20px',
1645-
padding: '15px',
1647+
padding: '2em',
16461648
width: '200px',
1647-
height: '100px',
1648-
borderWidth: '5px',
16491649
transform: 'translateX(10px) translateY(20px)'
1650+
},
1651+
text: {
1652+
fontSize: '2rem',
1653+
lineHeight: '1em'
16501654
}
16511655
});
16521656

@@ -1655,12 +1659,13 @@ describe('<html.*>', () => {
16551659
root = create(
16561660
<ViewportProvider viewportWidth={1280}>
16571661
<html.div style={styles.container}>
1658-
<html.span>Scaled content</html.span>
1662+
<html.span style={styles.text}>Scaled content</html.span>
16591663
</html.div>
16601664
</ViewportProvider>
16611665
);
16621666
});
16631667

1668+
// scale factor 0.75
16641669
expect(root.toJSON()).toMatchSnapshot('scaled lengths');
16651670

16661671
ReactNative.useWindowDimensions.mockRestore();

0 commit comments

Comments
 (0)