Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NO QA] Move react-native-web types to a separate package #46358

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@
"@types/react-collapse": "^5.0.1",
"@types/react-dom": "^18.2.4",
"@types/react-is": "^18.3.0",
"@types/react-native-web": "^0.0.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@blazejkustra Is this really correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes 😅 DefinietlyTyped contributor never responded here

"@types/react-test-renderer": "^18.0.0",
"@types/semver": "^7.5.4",
"@types/setimmediate": "^1.0.2",
Expand Down
3 changes: 2 additions & 1 deletion src/components/BlockingViews/BlockingView.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type {ImageContentFit} from 'expo-image';
import React, {useMemo} from 'react';
import type {ImageSourcePropType, StyleProp, TextStyle, ViewStyle, WebStyle} from 'react-native';
import type {ImageSourcePropType, StyleProp, TextStyle, ViewStyle} from 'react-native';
import {View} from 'react-native';
import type {SvgProps} from 'react-native-svg';
import type {WebStyle} from 'react-native-web';
import type {MergeExclusive} from 'type-fest';
import AutoEmailLink from '@components/AutoEmailLink';
import Icon from '@components/Icon';
Expand Down
8 changes: 4 additions & 4 deletions src/components/Composer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {flushSync} from 'react-dom';
// eslint-disable-next-line no-restricted-imports
import type {DimensionValue, NativeSyntheticEvent, Text as RNText, TextInput, TextInputKeyPressEventData, TextInputSelectionChangeEventData, TextStyle} from 'react-native';
import type {NativeSyntheticEvent, Text as RNText, TextInput, TextInputKeyPressEventData, TextInputSelectionChangeEventData, TextStyle, ViewStyle} from 'react-native';

Check failure on line 7 in src/components/Composer/index.tsx

View workflow job for this annotation

GitHub Actions / Run ESLint

'TextStyle' is defined but never used
import {DeviceEventEmitter, StyleSheet, View} from 'react-native';
import type {AnimatedMarkdownTextInputRef} from '@components/RNMarkdownTextInput';
import RNMarkdownTextInput from '@components/RNMarkdownTextInput';
Expand Down Expand Up @@ -101,7 +101,7 @@
});
const [caretContent, setCaretContent] = useState('');
const [valueBeforeCaret, setValueBeforeCaret] = useState('');
const [textInputWidth, setTextInputWidth] = useState('');
const [textInputWidth, setTextInputWidth] = useState<ViewStyle['width']>('');
const [isRendered, setIsRendered] = useState(false);
const isScrollBarVisible = useIsScrollBarVisible(textInput, value ?? '');
const [prevScroll, setPrevScroll] = useState<number | undefined>();
Expand Down Expand Up @@ -318,7 +318,7 @@
opacity: 0,
}}
>
<Text style={[StyleSheet.flatten([style, styles.noSelect]), StyleUtils.getComposerMaxHeightStyle(maxLines, isComposerFullSize), {maxWidth: textInputWidth as DimensionValue}]}>
<Text style={[StyleSheet.flatten([style, styles.noSelect]), StyleUtils.getComposerMaxHeightStyle(maxLines, isComposerFullSize), {maxWidth: textInputWidth}]}>
{`${valueBeforeCaret} `}
<Text
numberOfLines={1}
Expand All @@ -344,7 +344,7 @@
Browser.isMobileSafari() || Browser.isSafari() ? styles.rtlTextRenderForSafari : {},
scrollStyleMemo,
StyleUtils.getComposerMaxHeightStyle(maxLines, isComposerFullSize),
isComposerFullSize ? ({height: '100%', maxHeight: 'none' as DimensionValue} as TextStyle) : undefined,
isComposerFullSize ? {height: '100%', maxHeight: 'none'} : undefined,
textContainsOnlyEmojis ? styles.onlyEmojisTextLineHeight : {},
],

Expand Down
8 changes: 4 additions & 4 deletions src/components/SafeAreaConsumer/types.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type {DimensionValue} from 'react-native';
import type {ViewStyle} from 'react-native';
import type {EdgeInsets} from 'react-native-safe-area-context';

type SafeAreaChildrenProps = {
paddingTop?: DimensionValue;
paddingBottom?: DimensionValue;
paddingTop?: ViewStyle['paddingTop'];
paddingBottom?: ViewStyle['paddingBottom'];
insets?: EdgeInsets;
safeAreaPaddingBottomStyle: {
paddingBottom?: DimensionValue;
paddingBottom?: ViewStyle['paddingBottom'];
};
};

Expand Down
4 changes: 2 additions & 2 deletions src/components/ScreenWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {useNavigation} from '@react-navigation/native';
import type {StackNavigationProp} from '@react-navigation/stack';
import type {ForwardedRef, ReactNode} from 'react';
import React, {createContext, forwardRef, useEffect, useMemo, useRef, useState} from 'react';
import type {DimensionValue, StyleProp, ViewStyle} from 'react-native';
import type {StyleProp, ViewStyle} from 'react-native';
import {Keyboard, PanResponder, View} from 'react-native';
import {PickerAvoidingView} from 'react-native-picker-select';
import type {EdgeInsets} from 'react-native-safe-area-context';
Expand Down Expand Up @@ -30,7 +30,7 @@ import withNavigationFallback from './withNavigationFallback';
type ScreenWrapperChildrenProps = {
insets: EdgeInsets;
safeAreaPaddingBottomStyle?: {
paddingBottom?: DimensionValue;
paddingBottom?: ViewStyle['paddingBottom'];
};
didScreenTransitionEnd: boolean;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, {memo, useEffect, useRef} from 'react';
import type {LayoutChangeEvent} from 'react-native';
import GenericTooltip from '@components/Tooltip/GenericTooltip';
import type TooltipProps from '@components/Tooltip/types';
import getBounds from './getBounds';
import type {LayoutChangeEventWithTarget} from './getBounds/types';

/**
* A component used to wrap an element intended for displaying a tooltip.
Expand Down Expand Up @@ -44,7 +44,7 @@ function BaseEducationalTooltip({children, ...props}: TooltipProps) {
// eslint-disable-next-line react-compiler/react-compiler
hideTooltipRef.current = hideTooltip;
return React.cloneElement(children as React.ReactElement, {
onLayout: (e: LayoutChangeEvent) => {
onLayout: (e: LayoutChangeEventWithTarget) => {
updateTargetBounds(getBounds(e));
showTooltip();
},
Expand Down
4 changes: 2 additions & 2 deletions src/components/Tooltip/EducationalTooltip/getBounds/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type {LayoutChangeEvent} from 'react-native';
import type GetBounds from './types';
import type {LayoutChangeEventWithTarget} from './types';

const getBounds: GetBounds = (event: LayoutChangeEvent) => (event.nativeEvent.target as HTMLElement).getBoundingClientRect();
const getBounds: GetBounds = (event: LayoutChangeEventWithTarget) => event.nativeEvent.target?.getBoundingClientRect();

export default getBounds;
7 changes: 5 additions & 2 deletions src/components/Tooltip/EducationalTooltip/getBounds/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import type {LayoutChangeEvent, LayoutRectangle} from 'react-native';
import type {LayoutRectangle, NativeSyntheticEvent} from 'react-native';

type GetBounds = (event: LayoutChangeEvent) => LayoutRectangle;
type LayoutChangeEventWithTarget = NativeSyntheticEvent<{layout: LayoutRectangle; target: HTMLElement}>;

type GetBounds = (event: LayoutChangeEventWithTarget) => LayoutRectangle;

export default GetBounds;
export type {LayoutChangeEventWithTarget};
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type {StackCardInterpolationProps, StackNavigationOptions} from '@react-navigation/stack';
import type {ViewStyle} from 'react-native';
import type {ThemeStyles} from '@styles/index';
import type {StyleUtilsType} from '@styles/utils';
import variables from '@styles/variables';
Expand Down Expand Up @@ -61,8 +60,7 @@ const getRootNavigatorScreenOptions: GetRootNavigatorScreenOptions = (isSmallScr
width: '100%',
top: 0,
left: 0,
// We need to guarantee that it covers BottomTabBar on web, but fixed position is not supported in react native.
position: 'fixed' as ViewStyle['position'],
position: 'fixed',
},
}),
leftModalNavigator: {
Expand Down
12 changes: 4 additions & 8 deletions src/styles/utils/display.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,27 @@ export default {
* Web-only style.
*/
dInline: {
// NOTE: asserting "display" to a valid type, because it isn't possible to augment "display".
display: 'inline' as ViewStyle['display'],
display: 'inline',
},

/**
* Web-only style.
*/
dInlineFlex: {
// NOTE: asserting "display" to a valid type, because it isn't possible to augment "display".
display: 'inline-flex' as ViewStyle['display'],
display: 'inline-flex',
},

/**
* Web-only style.
*/
dBlock: {
// NOTE: asserting "display" to a valid type, because it isn't possible to augment "display".
display: 'block' as ViewStyle['display'],
display: 'block',
},

/**
* Web-only style.
*/
dGrid: {
// NOTE: asserting "display" to a valid type, because it isn't possible to augment "display".
display: 'grid' as ViewStyle['display'],
display: 'grid',
},
} satisfies Record<string, ViewStyle>;
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ const getMiniWrapperStyle = (theme: ThemeColors, styles: ThemeStyles): ViewStyle
borderWidth: 1,
borderColor: theme.border,
// In Safari, when welcome messages use a code block (triple backticks), they would overlap the context menu below when there is no scrollbar without the transform style.
// NOTE: asserting "transform" to a valid type, because it isn't possible to augment "transform".
transform: 'translateZ(0)' as unknown as ViewStyle['transform'],
transform: 'translateZ(0)',
},
];

Expand Down
59 changes: 31 additions & 28 deletions src/styles/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {StyleSheet} from 'react-native';
import type {AnimatableNumericValue, Animated, ColorValue, DimensionValue, ImageStyle, PressableStateCallbackType, StyleProp, TextStyle, ViewStyle} from 'react-native';
import type {AnimatableNumericValue, Animated, ColorValue, ImageStyle, PressableStateCallbackType, StyleProp, TextStyle, ViewStyle} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import type {EdgeInsets} from 'react-native-safe-area-context';
import type {ValueOf} from 'type-fest';
Expand Down Expand Up @@ -342,7 +342,6 @@ function getSafeAreaMargins(insets?: EdgeInsets): ViewStyle {
return {marginBottom: (insets?.bottom ?? 0) * variables.safeInsertPercentage};
}

// NOTE: asserting some web style properties to a valid type, because it isn't possible to augment them.
function getZoomSizingStyle(
isZoomed: boolean,
imgWidth: number,
Expand All @@ -356,23 +355,23 @@ function getZoomSizingStyle(
if (isLoading || imgWidth === 0 || imgHeight === 0) {
return undefined;
}
const top = `${Math.max((containerHeight - imgHeight) / 2, 0)}px` as DimensionValue;
const left = `${Math.max((containerWidth - imgWidth) / 2, 0)}px` as DimensionValue;
const top = `${Math.max((containerHeight - imgHeight) / 2, 0)}px`;
const left = `${Math.max((containerWidth - imgWidth) / 2, 0)}px`;

// Return different size and offset style based on zoomScale and isZoom.
if (isZoomed) {
// When both width and height are smaller than container(modal) size, set the height by multiplying zoomScale if it is zoomed in.
if (zoomScale >= 1) {
return {
height: `${imgHeight * zoomScale}px` as DimensionValue,
width: `${imgWidth * zoomScale}px` as DimensionValue,
height: `${imgHeight * zoomScale}px`,
width: `${imgWidth * zoomScale}px`,
};
}

// If image height and width are bigger than container size, display image with original size because original size is bigger and position absolute.
return {
height: `${imgHeight}px` as DimensionValue,
width: `${imgWidth}px` as DimensionValue,
height: `${imgHeight}px`,
width: `${imgWidth}px`,
top,
left,
};
Expand All @@ -381,20 +380,20 @@ function getZoomSizingStyle(
// If image is not zoomed in and image size is smaller than container size, display with original size based on offset and position absolute.
if (zoomScale > 1) {
return {
height: `${imgHeight}px` as DimensionValue,
width: `${imgWidth}px` as DimensionValue,
height: `${imgHeight}px`,
width: `${imgWidth}px`,
top,
left,
};
}

// If image is bigger than container size, display full image in the screen with scaled size (fit by container size) and position absolute.
// top, left offset should be different when displaying long or wide image.
const scaledTop = `${Math.max((containerHeight - imgHeight * zoomScale) / 2, 0)}px` as DimensionValue;
const scaledLeft = `${Math.max((containerWidth - imgWidth * zoomScale) / 2, 0)}px` as DimensionValue;
const scaledTop = `${Math.max((containerHeight - imgHeight * zoomScale) / 2, 0)}px`;
const scaledLeft = `${Math.max((containerWidth - imgWidth * zoomScale) / 2, 0)}px`;
return {
height: `${imgHeight * zoomScale}px` as DimensionValue,
width: `${imgWidth * zoomScale}px` as DimensionValue,
height: `${imgHeight * zoomScale}px`,
width: `${imgWidth * zoomScale}px`,
top: scaledTop,
left: scaledLeft,
};
Expand Down Expand Up @@ -538,17 +537,23 @@ function getButtonStyleWithIcon(
}
}

type MarginPaddingValue = ViewStyle['marginTop' | 'marginBottom' | 'paddingTop' | 'paddingBottom'];

/**
* Combine margin/padding with safe area inset
*
* @param modalContainerValue - margin or padding value
* @param safeAreaValue - safe area inset
* @param shouldAddSafeAreaValue - indicator whether safe area inset should be applied
*/
function getCombinedSpacing(modalContainerValue: DimensionValue | undefined, safeAreaValue: number, shouldAddSafeAreaValue: boolean): number | DimensionValue | undefined {
function getCombinedSpacing(modalContainerValue: MarginPaddingValue, safeAreaValue: number, shouldAddSafeAreaValue: boolean): MarginPaddingValue {
// modalContainerValue can only be added to safe area inset if it's a number, otherwise it's returned as is
if (typeof modalContainerValue === 'number' || !modalContainerValue) {
return (modalContainerValue ?? 0) + (shouldAddSafeAreaValue ? safeAreaValue : 0);
if (typeof modalContainerValue === 'number') {
return modalContainerValue + (shouldAddSafeAreaValue ? safeAreaValue : 0);
}

if (!modalContainerValue) {
return shouldAddSafeAreaValue ? safeAreaValue : 0;
}

return modalContainerValue;
Expand All @@ -563,10 +568,10 @@ type ModalPaddingStylesParams = {
safeAreaPaddingBottom: number;
safeAreaPaddingLeft: number;
safeAreaPaddingRight: number;
modalContainerStyleMarginTop: DimensionValue | undefined;
modalContainerStyleMarginBottom: DimensionValue | undefined;
modalContainerStylePaddingTop: DimensionValue | undefined;
modalContainerStylePaddingBottom: DimensionValue | undefined;
modalContainerStyleMarginTop: MarginPaddingValue;
modalContainerStyleMarginBottom: MarginPaddingValue;
modalContainerStylePaddingTop: MarginPaddingValue;
modalContainerStylePaddingBottom: MarginPaddingValue;
insets: EdgeInsets;
};

Expand Down Expand Up @@ -964,8 +969,7 @@ function getCheckboxPressableStyle(borderRadius = 6): ViewStyle {
return {
justifyContent: 'center',
alignItems: 'center',
// eslint-disable-next-line object-shorthand
borderRadius: borderRadius,
borderRadius,
};
}

Expand Down Expand Up @@ -1311,8 +1315,7 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({
borderWidth: 2,
justifyContent: 'center',
alignItems: 'center',
// eslint-disable-next-line object-shorthand
borderRadius: borderRadius,
borderRadius,
}),

/**
Expand All @@ -1338,13 +1341,13 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({
/**
* Get the style for the AM and PM buttons in the TimePicker
*/
getStatusAMandPMButtonStyle: (amPmValue: string): {styleForAM: ViewStyle; styleForPM: ViewStyle} => {
getStatusAMandPMButtonStyle: (amPmValue: string): {styleForAM: StyleProp<ViewStyle>; styleForPM: StyleProp<ViewStyle>} => {
const computedStyleForAM: ViewStyle = amPmValue !== CONST.TIME_PERIOD.AM ? {backgroundColor: theme.componentBG} : {};
const computedStyleForPM: ViewStyle = amPmValue !== CONST.TIME_PERIOD.PM ? {backgroundColor: theme.componentBG} : {};

return {
styleForAM: [styles.timePickerWidth100, computedStyleForAM] as unknown as ViewStyle,
styleForPM: [styles.timePickerWidth100, computedStyleForPM] as unknown as ViewStyle,
styleForAM: [styles.timePickerWidth100, computedStyleForAM],
styleForPM: [styles.timePickerWidth100, computedStyleForPM],
};
},

Expand Down
4 changes: 1 addition & 3 deletions src/styles/utils/overflowAuto/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import type {ViewStyle} from 'react-native';
import type OverflowAutoStyles from './types';

/**
* Web-only style.
*/
const overflowAuto: OverflowAutoStyles = {
// NOTE: asserting "overflow" to a valid type, because it isn't possible to augment "overflow".
overflow: 'auto' as ViewStyle['overflow'],
overflow: 'auto',
};

export default overflowAuto;
3 changes: 1 addition & 2 deletions src/styles/utils/positioning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ export default {
* Web-only style.
*/
pFixed: {
// NOTE: asserting "position" to a valid type, because it isn't possible to augment "position".
position: 'fixed' as ViewStyle['position'],
position: 'fixed',
},

t0: {
Expand Down
Loading
Loading