diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheet.js b/packages/react-native/Libraries/StyleSheet/StyleSheet.js index ae220e2929ac..b6cb186c5db3 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheet.js +++ b/packages/react-native/Libraries/StyleSheet/StyleSheet.js @@ -10,25 +10,21 @@ 'use strict'; +import typeof * as StyleSheetExports from './StyleSheetExports'; import type { ____ColorValue_Internal, ____DangerouslyImpreciseStyle_Internal, ____DangerouslyImpreciseStyleProp_Internal, ____ImageStyle_Internal, ____ImageStyleProp_Internal, - ____Styles_Internal, ____TextStyle_Internal, ____TextStyleProp_Internal, ____ViewStyle_Internal, ____ViewStyleProp_Internal, } from './StyleSheetTypes'; - -import composeStyles from '../../src/private/styles/composeStyles'; -import flatten from './flattenStyle'; - -const ReactNativeStyleAttributes = - require('../Components/View/ReactNativeStyleAttributes').default; -const PixelRatio = require('../Utilities/PixelRatio').default; +const StyleSheet: StyleSheetExports = ( + require('./StyleSheetExports') as $FlowFixMe +).default; export type {NativeColorValue} from './StyleSheetTypes'; @@ -166,192 +162,4 @@ export type ImageStyle = ____ImageStyle_Internal; */ export type DangerouslyImpreciseStyle = ____DangerouslyImpreciseStyle_Internal; -let hairlineWidth: number = PixelRatio.roundToNearestPixel(0.4); -if (hairlineWidth === 0) { - hairlineWidth = 1 / PixelRatio.get(); -} - -const absoluteFill: { - +bottom: 0, - +left: 0, - +position: 'absolute', - +right: 0, - +top: 0, -} = { - position: 'absolute', - left: 0, - right: 0, - top: 0, - bottom: 0, -}; -if (__DEV__) { - Object.freeze(absoluteFill); -} - -/** - * A StyleSheet is an abstraction similar to CSS StyleSheets - * - * Create a new StyleSheet: - * - * ``` - * const styles = StyleSheet.create({ - * container: { - * borderRadius: 4, - * borderWidth: 0.5, - * borderColor: '#d6d7da', - * }, - * title: { - * fontSize: 19, - * fontWeight: 'bold', - * }, - * activeTitle: { - * color: 'red', - * }, - * }); - * ``` - * - * Use a StyleSheet: - * - * ``` - * - * - * - * ``` - * - * Code quality: - * - * - By moving styles away from the render function, you're making the code - * easier to understand. - * - Naming the styles is a good way to add meaning to the low level components - * in the render function, and encourage reuse. - * - In most IDEs, using `StyleSheet.create()` will offer static type checking - * and suggestions to help you write valid styles. - * - */ -export default { - /** - * This is defined as the width of a thin line on the platform. It can be - * used as the thickness of a border or division between two elements. - * Example: - * ``` - * { - * borderBottomColor: '#bbb', - * borderBottomWidth: StyleSheet.hairlineWidth - * } - * ``` - * - * This constant will always be a round number of pixels (so a line defined - * by it look crisp) and will try to match the standard width of a thin line - * on the underlying platform. However, you should not rely on it being a - * constant size, because on different platforms and screen densities its - * value may be calculated differently. - * - * A line with hairline width may not be visible if your simulator is downscaled. - */ - hairlineWidth, - - /** - * A very common pattern is to create overlays with position absolute and zero positioning, - * so `absoluteFill` can be used for convenience and to reduce duplication of these repeated - * styles. - */ - absoluteFill: (absoluteFill: any), // TODO: This should be updated after we fix downstream Flow sites. - - /** - * Sometimes you may want `absoluteFill` but with a couple tweaks - `absoluteFillObject` can be - * used to create a customized entry in a `StyleSheet`, e.g.: - * - * const styles = StyleSheet.create({ - * wrapper: { - * ...StyleSheet.absoluteFillObject, - * top: 10, - * backgroundColor: 'transparent', - * }, - * }); - */ - absoluteFillObject: absoluteFill, - - /** - * Combines two styles such that `style2` will override any styles in `style1`. - * If either style is falsy, the other one is returned without allocating an - * array, saving allocations and maintaining reference equality for - * PureComponent checks. - */ - compose: composeStyles, - - /** - * Flattens an array of style objects, into one aggregated style object. - * - * Example: - * ``` - * const styles = StyleSheet.create({ - * listItem: { - * flex: 1, - * fontSize: 16, - * color: 'white' - * }, - * selectedListItem: { - * color: 'green' - * } - * }); - * - * StyleSheet.flatten([styles.listItem, styles.selectedListItem]) - * // returns { flex: 1, fontSize: 16, color: 'green' } - * ``` - */ - flatten, - - /** - * WARNING: EXPERIMENTAL. Breaking changes will probably happen a lot and will - * not be reliably announced. The whole thing might be deleted, who knows? Use - * at your own risk. - * - * Sets a function to use to pre-process a style property value. This is used - * internally to process color and transform values. You should not use this - * unless you really know what you are doing and have exhausted other options. - */ - setStyleAttributePreprocessor( - property: string, - process: (nextProp: mixed) => mixed, - ) { - let value; - - if (ReactNativeStyleAttributes[property] === true) { - value = {process}; - } else if (typeof ReactNativeStyleAttributes[property] === 'object') { - value = {...ReactNativeStyleAttributes[property], process}; - } else { - console.error(`${property} is not a valid style attribute`); - return; - } - - if ( - __DEV__ && - typeof value.process === 'function' && - typeof ReactNativeStyleAttributes[property]?.process === 'function' && - value.process !== ReactNativeStyleAttributes[property]?.process - ) { - console.warn(`Overwriting ${property} style attribute preprocessor`); - } - - ReactNativeStyleAttributes[property] = value; - }, - - /** - * An identity function for creating style sheets. - */ - // $FlowFixMe[unsupported-variance-annotation] - create<+S: ____Styles_Internal>(obj: S): $ReadOnly { - // TODO: This should return S as the return type. But first, - // we need to codemod all the callsites that are typing this - // return value as a number (even though it was opaque). - if (__DEV__) { - for (const key in obj) { - if (obj[key]) { - Object.freeze(obj[key]); - } - } - } - return obj; - }, -}; +export default StyleSheet; diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheet.js.flow b/packages/react-native/Libraries/StyleSheet/StyleSheet.js.flow new file mode 100644 index 000000000000..07170ee7e4a3 --- /dev/null +++ b/packages/react-native/Libraries/StyleSheet/StyleSheet.js.flow @@ -0,0 +1,166 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + * @format + */ + +export * as default from './StyleSheetExports'; + +import type { + ____ColorValue_Internal, + ____DangerouslyImpreciseStyle_Internal, + ____DangerouslyImpreciseStyleProp_Internal, + ____ImageStyle_Internal, + ____ImageStyleProp_Internal, + ____TextStyle_Internal, + ____TextStyleProp_Internal, + ____ViewStyle_Internal, + ____ViewStyleProp_Internal, +} from './StyleSheetTypes'; + +export type {StyleProp} from './StyleSheetTypes'; + +export type StyleSheetProperties = { + hairlineWidth: number, + flatten(style: T): T, +}; + +export type {NativeColorValue} from './StyleSheetTypes'; + +/** + * This type should be used as the type for anything that is a color. It is + * most useful when using DynamicColorIOS which can be a string or a dynamic + * color object. + * + * type props = {backgroundColor: ColorValue}; + */ +export type ColorValue = ____ColorValue_Internal; + +/** + * This type should be used as the type for a prop that is passed through + * to a 's `style` prop. This ensures call sites of the component + * can't pass styles that View doesn't support such as `fontSize`.` + * + * type Props = {style: ViewStyleProp} + * const MyComponent = (props: Props) => + */ +export type ViewStyleProp = ____ViewStyleProp_Internal; + +/** + * This type should be used as the type for a prop that is passed through + * to a 's `style` prop. This ensures call sites of the component + * can't pass styles that Text doesn't support such as `resizeMode`.` + * + * type Props = {style: TextStyleProp} + * const MyComponent = (props: Props) => + */ +export type TextStyleProp = ____TextStyleProp_Internal; + +/** + * This type should be used as the type for a prop that is passed through + * to an 's `style` prop. This ensures call sites of the component + * can't pass styles that Image doesn't support such as `fontSize`.` + * + * type Props = {style: ImageStyleProp} + * const MyComponent = (props: Props) => + */ +export type ImageStyleProp = ____ImageStyleProp_Internal; + +/** + * WARNING: You probably shouldn't be using this type. This type + * is similar to the ones above except it allows styles that are accepted + * by all of View, Text, or Image. It is therefore very unsafe to pass this + * through to an underlying component. Using this is almost always a mistake + * and using one of the other more restrictive types is likely the right choice. + */ +export type DangerouslyImpreciseStyleProp = + ____DangerouslyImpreciseStyleProp_Internal; + +/** + * Utility type for getting the values for specific style keys. + * + * The following is bad because position is more restrictive than 'string': + * ``` + * type Props = {position: string}; + * ``` + * + * You should use the following instead: + * + * ``` + * type Props = {position: TypeForStyleKey<'position'>}; + * ``` + * + * This will correctly give you the type 'absolute' | 'relative' + */ +export type TypeForStyleKey< + +key: $Keys<____DangerouslyImpreciseStyle_Internal>, +> = $ElementType<____DangerouslyImpreciseStyle_Internal, key>; + +/** + * This type is an object of the different possible style + * properties that can be specified for View. + * + * Note that this isn't a safe way to type a style prop for a component as + * results from StyleSheet.create return an internal identifier, not + * an object of styles. + * + * If you want to type the style prop of a function, + * consider using ViewStyleProp. + * + * A reasonable usage of this type is for helper functions that return an + * object of styles to pass to a View that can't be precomputed with + * StyleSheet.create. + */ +export type ViewStyle = ____ViewStyle_Internal; + +/** + * This type is an object of the different possible style + * properties that can be specified for Text. + * + * Note that this isn't a safe way to type a style prop for a component as + * results from StyleSheet.create return an internal identifier, not + * an object of styles. + * + * If you want to type the style prop of a function, + * consider using TextStyleProp. + * + * A reasonable usage of this type is for helper functions that return an + * object of styles to pass to a Text that can't be precomputed with + * StyleSheet.create. + */ +export type TextStyle = ____TextStyle_Internal; + +/** + * This type is an object of the different possible style + * properties that can be specified for Image. + * + * Note that this isn't a safe way to type a style prop for a component as + * results from StyleSheet.create return an internal identifier, not + * an object of styles. + * + * If you want to type the style prop of a function, + * consider using ImageStyleProp. + * + * A reasonable usage of this type is for helper functions that return an + * object of styles to pass to an Image that can't be precomputed with + * StyleSheet.create. + */ +export type ImageStyle = ____ImageStyle_Internal; + +/** + * WARNING: You probably shouldn't be using this type. This type is an object + * with all possible style keys and their values. Note that this isn't + * a safe way to type a style prop for a component as results from + * StyleSheet.create return an internal identifier, not an object of styles. + * + * If you want to type the style prop of a function, consider using + * ViewStyleProp, TextStyleProp, or ImageStyleProp. + * + * This should only be used by very core utilities that operate on an object + * containing any possible style value. + */ +export type DangerouslyImpreciseStyle = ____DangerouslyImpreciseStyle_Internal; diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheetExports.js b/packages/react-native/Libraries/StyleSheet/StyleSheetExports.js new file mode 100644 index 000000000000..e80111bd1f5b --- /dev/null +++ b/packages/react-native/Libraries/StyleSheet/StyleSheetExports.js @@ -0,0 +1,210 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + * @format + */ + +'use strict'; + +import type {____Styles_Internal} from './StyleSheetTypes'; + +import composeStyles from '../../src/private/styles/composeStyles'; +import flatten from './flattenStyle'; + +const ReactNativeStyleAttributes = + require('../Components/View/ReactNativeStyleAttributes').default; +const PixelRatio = require('../Utilities/PixelRatio').default; + +let hairlineWidth: number = PixelRatio.roundToNearestPixel(0.4); +if (hairlineWidth === 0) { + hairlineWidth = 1 / PixelRatio.get(); +} + +const absoluteFill: { + +bottom: 0, + +left: 0, + +position: 'absolute', + +right: 0, + +top: 0, +} = { + position: 'absolute', + left: 0, + right: 0, + top: 0, + bottom: 0, +}; +if (__DEV__) { + Object.freeze(absoluteFill); +} + +/** + * A StyleSheet is an abstraction similar to CSS StyleSheets + * + * Create a new StyleSheet: + * + * ``` + * const styles = StyleSheet.create({ + * container: { + * borderRadius: 4, + * borderWidth: 0.5, + * borderColor: '#d6d7da', + * }, + * title: { + * fontSize: 19, + * fontWeight: 'bold', + * }, + * activeTitle: { + * color: 'red', + * }, + * }); + * ``` + * + * Use a StyleSheet: + * + * ``` + * + * + * + * ``` + * + * Code quality: + * + * - By moving styles away from the render function, you're making the code + * easier to understand. + * - Naming the styles is a good way to add meaning to the low level components + * in the render function, and encourage reuse. + * - In most IDEs, using `StyleSheet.create()` will offer static type checking + * and suggestions to help you write valid styles. + * + */ +export default { + /** + * This is defined as the width of a thin line on the platform. It can be + * used as the thickness of a border or division between two elements. + * Example: + * ``` + * { + * borderBottomColor: '#bbb', + * borderBottomWidth: StyleSheet.hairlineWidth + * } + * ``` + * + * This constant will always be a round number of pixels (so a line defined + * by it look crisp) and will try to match the standard width of a thin line + * on the underlying platform. However, you should not rely on it being a + * constant size, because on different platforms and screen densities its + * value may be calculated differently. + * + * A line with hairline width may not be visible if your simulator is downscaled. + */ + hairlineWidth, + + /** + * A very common pattern is to create overlays with position absolute and zero positioning, + * so `absoluteFill` can be used for convenience and to reduce duplication of these repeated + * styles. + */ + absoluteFill: (absoluteFill: any), // TODO: This should be updated after we fix downstream Flow sites. + + /** + * Sometimes you may want `absoluteFill` but with a couple tweaks - `absoluteFillObject` can be + * used to create a customized entry in a `StyleSheet`, e.g.: + * + * const styles = StyleSheet.create({ + * wrapper: { + * ...StyleSheet.absoluteFillObject, + * top: 10, + * backgroundColor: 'transparent', + * }, + * }); + */ + absoluteFillObject: absoluteFill, + + /** + * Combines two styles such that `style2` will override any styles in `style1`. + * If either style is falsy, the other one is returned without allocating an + * array, saving allocations and maintaining reference equality for + * PureComponent checks. + */ + compose: composeStyles, + + /** + * Flattens an array of style objects, into one aggregated style object. + * + * Example: + * ``` + * const styles = StyleSheet.create({ + * listItem: { + * flex: 1, + * fontSize: 16, + * color: 'white' + * }, + * selectedListItem: { + * color: 'green' + * } + * }); + * + * StyleSheet.flatten([styles.listItem, styles.selectedListItem]) + * // returns { flex: 1, fontSize: 16, color: 'green' } + * ``` + */ + flatten, + + /** + * WARNING: EXPERIMENTAL. Breaking changes will probably happen a lot and will + * not be reliably announced. The whole thing might be deleted, who knows? Use + * at your own risk. + * + * Sets a function to use to pre-process a style property value. This is used + * internally to process color and transform values. You should not use this + * unless you really know what you are doing and have exhausted other options. + */ + setStyleAttributePreprocessor( + property: string, + process: (nextProp: mixed) => mixed, + ) { + let value; + + if (ReactNativeStyleAttributes[property] === true) { + value = {process}; + } else if (typeof ReactNativeStyleAttributes[property] === 'object') { + value = {...ReactNativeStyleAttributes[property], process}; + } else { + console.error(`${property} is not a valid style attribute`); + return; + } + + if ( + __DEV__ && + typeof value.process === 'function' && + typeof ReactNativeStyleAttributes[property]?.process === 'function' && + value.process !== ReactNativeStyleAttributes[property]?.process + ) { + console.warn(`Overwriting ${property} style attribute preprocessor`); + } + + ReactNativeStyleAttributes[property] = value; + }, + + /** + * An identity function for creating style sheets. + */ + // $FlowFixMe[unsupported-variance-annotation] + create<+S: ____Styles_Internal>(obj: S): $ReadOnly { + // TODO: This should return S as the return type. But first, + // we need to codemod all the callsites that are typing this + // return value as a number (even though it was opaque). + if (__DEV__) { + for (const key in obj) { + if (obj[key]) { + Object.freeze(obj[key]); + } + } + } + return obj; + }, +}; diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheetExports.js.flow b/packages/react-native/Libraries/StyleSheet/StyleSheetExports.js.flow new file mode 100644 index 000000000000..13debbe910fe --- /dev/null +++ b/packages/react-native/Libraries/StyleSheet/StyleSheetExports.js.flow @@ -0,0 +1,110 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + * @format + */ + +import type {____Styles_Internal} from './StyleSheetTypes'; + +import composeStyles from '../../src/private/styles/composeStyles'; +import flattenStyle from './flattenStyle'; + +/** + * This is defined as the width of a thin line on the platform. It can be + * used as the thickness of a border or division between two elements. + * Example: + * ``` + * { + * borderBottomColor: '#bbb', + * borderBottomWidth: StyleSheet.hairlineWidth + * } + * ``` + * + * This constant will always be a round number of pixels (so a line defined + * by it look crisp) and will try to match the standard width of a thin line + * on the underlying platform. However, you should not rely on it being a + * constant size, because on different platforms and screen densities its + * value may be calculated differently. + */ +declare export const hairlineWidth: number; + +/** + * A very common pattern is to create overlays with position absolute and zero positioning, + * so `absoluteFill` can be used for convenience and to reduce duplication of these repeated + * styles. + */ +declare export const absoluteFill: any; + +/** + * Sometimes you may want `absoluteFill` but with a couple tweaks - `absoluteFillObject` can be + * used to create a customized entry in a `StyleSheet`, e.g.: + * + * const styles = StyleSheet.create({ + * wrapper: { + * ...StyleSheet.absoluteFillObject, + * top: 10, + * backgroundColor: 'transparent', + * }, + * }); + */ +declare export const absoluteFillObject: { + +bottom: 0, + +left: 0, + +position: 'absolute', + +right: 0, + +top: 0, +}; + +/** + * Combines two styles such that style2 will override any styles in style1. + * If either style is falsy, the other one is returned without allocating + * an array, saving allocations and maintaining reference equality for + * PureComponent checks. + */ +declare export const compose: typeof composeStyles; + +/** + * Flattens an array of style objects, into one aggregated style object. + * + * Example: + * ``` + * const styles = StyleSheet.create({ + * listItem: { + * flex: 1, + * fontSize: 16, + * color: 'white' + * }, + * selectedListItem: { + * color: 'green' + * } + * }); + * + * StyleSheet.flatten([styles.listItem, styles.selectedListItem]) + * // returns { flex: 1, fontSize: 16, color: 'green' } + * ``` + */ +declare export const flatten: typeof flattenStyle; + +/** + * WARNING: EXPERIMENTAL. Breaking changes will probably happen a lot and will + * not be reliably announced. The whole thing might be deleted, who knows? Use + * at your own risk. + * + * Sets a function to use to pre-process a style property value. This is used + * internally to process color and transform values. You should not use this + * unless you really know what you are doing and have exhausted other options. + */ +declare export const setStyleAttributePreprocessor: ( + property: string, + process: (nextProp: any) => any, +) => void; + +/** + * An identity function for creating style sheets. + */ +// $FlowFixMe[unsupported-variance-annotation] +declare export const create: <+S: ____Styles_Internal>(obj: S) => $ReadOnly; diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js index 0d75a9420404..b70482248c1e 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js +++ b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js @@ -760,10 +760,7 @@ type ____BlendMode_Internal = | 'color' | 'luminosity'; -export type ____ViewStyle_InternalCore = $ReadOnly<{ - ...$Exact<____LayoutStyle_Internal>, - ...$Exact<____ShadowStyle_Internal>, - ...$Exact<____TransformStyle_Internal>, +export type ____ViewStyle_InternalBase = $ReadOnly<{ backfaceVisibility?: 'visible' | 'hidden', backgroundColor?: ____ColorValue_Internal, borderColor?: ____ColorValue_Internal, @@ -813,6 +810,13 @@ export type ____ViewStyle_InternalCore = $ReadOnly<{ isolation?: 'auto' | 'isolate', }>; +export type ____ViewStyle_InternalCore = $ReadOnly<{ + ...$Exact<____LayoutStyle_Internal>, + ...$Exact<____ShadowStyle_Internal>, + ...$Exact<____TransformStyle_Internal>, + ...____ViewStyle_InternalBase, +}>; + export type ____ViewStyle_Internal = $ReadOnly<{ ...____ViewStyle_InternalCore, ...____ViewStyle_InternalOverrides, @@ -903,8 +907,7 @@ export type ____FontVariantArray_Internal = $ReadOnlyArray< | 'stylistic-twenty', >; -export type ____TextStyle_InternalCore = $ReadOnly<{ - ...$Exact<____ViewStyle_Internal>, +type ____TextStyle_InternalBase = $ReadOnly<{ color?: ____ColorValue_Internal, fontFamily?: string, fontSize?: number, @@ -935,6 +938,11 @@ export type ____TextStyle_InternalCore = $ReadOnly<{ writingDirection?: 'auto' | 'ltr' | 'rtl', }>; +export type ____TextStyle_InternalCore = $ReadOnly<{ + ...$Exact<____ViewStyle_Internal>, + ...____TextStyle_InternalBase, +}>; + export type ____TextStyle_Internal = $ReadOnly<{ ...____TextStyle_InternalCore, ...____TextStyle_InternalOverrides, @@ -967,24 +975,24 @@ export type ____DangerouslyImpreciseStyle_Internal = $ReadOnly<{ ... }>; -type GenericStyleProp<+T> = +export type StyleProp<+T> = | null | void | T | false | '' - | $ReadOnlyArray>; + | $ReadOnlyArray>; -export type ____DangerouslyImpreciseStyleProp_Internal = GenericStyleProp< +export type ____DangerouslyImpreciseStyleProp_Internal = StyleProp< Partial<____DangerouslyImpreciseStyle_Internal>, >; -export type ____ViewStyleProp_Internal = GenericStyleProp< +export type ____ViewStyleProp_Internal = StyleProp< $ReadOnly>, >; -export type ____TextStyleProp_Internal = GenericStyleProp< +export type ____TextStyleProp_Internal = StyleProp< $ReadOnly>, >; -export type ____ImageStyleProp_Internal = GenericStyleProp< +export type ____ImageStyleProp_Internal = StyleProp< $ReadOnly>, >; @@ -995,10 +1003,9 @@ export type ____Styles_Internal = { ... }; -export type ____FlattenStyleProp_Internal< - +TStyleProp: GenericStyleProp, -> = TStyleProp extends null | void | false | '' - ? empty - : TStyleProp extends $ReadOnlyArray - ? ____FlattenStyleProp_Internal - : TStyleProp; +export type ____FlattenStyleProp_Internal<+TStyleProp: StyleProp> = + TStyleProp extends null | void | false | '' + ? empty + : TStyleProp extends $ReadOnlyArray + ? ____FlattenStyleProp_Internal + : TStyleProp; diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index d0bdeba7c8ba..475b7feb832e 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -7303,7 +7303,8 @@ declare export function normalizeRect(rectOrSize: ?RectOrSize): ?Rect; `; exports[`public API should not change unintentionally Libraries/StyleSheet/StyleSheet.js 1`] = ` -"export type { NativeColorValue } from \\"./StyleSheetTypes\\"; +"declare const StyleSheet: StyleSheetExports; +export type { NativeColorValue } from \\"./StyleSheetTypes\\"; export type ColorValue = ____ColorValue_Internal; export type ViewStyleProp = ____ViewStyleProp_Internal; export type TextStyleProp = ____TextStyleProp_Internal; @@ -7317,7 +7318,36 @@ export type ViewStyle = ____ViewStyle_Internal; export type TextStyle = ____TextStyle_Internal; export type ImageStyle = ____ImageStyle_Internal; export type DangerouslyImpreciseStyle = ____DangerouslyImpreciseStyle_Internal; -declare let hairlineWidth: number; +declare export default typeof StyleSheet; +" +`; + +exports[`public API should not change unintentionally Libraries/StyleSheet/StyleSheet.js.flow 1`] = ` +"export * as default from \\"./StyleSheetExports\\"; +export type { StyleProp } from \\"./StyleSheetTypes\\"; +export type StyleSheetProperties = { + hairlineWidth: number, + flatten(style: T): T, +}; +export type { NativeColorValue } from \\"./StyleSheetTypes\\"; +export type ColorValue = ____ColorValue_Internal; +export type ViewStyleProp = ____ViewStyleProp_Internal; +export type TextStyleProp = ____TextStyleProp_Internal; +export type ImageStyleProp = ____ImageStyleProp_Internal; +export type DangerouslyImpreciseStyleProp = + ____DangerouslyImpreciseStyleProp_Internal; +export type TypeForStyleKey< + +key: $Keys<____DangerouslyImpreciseStyle_Internal>, +> = $ElementType<____DangerouslyImpreciseStyle_Internal, key>; +export type ViewStyle = ____ViewStyle_Internal; +export type TextStyle = ____TextStyle_Internal; +export type ImageStyle = ____ImageStyle_Internal; +export type DangerouslyImpreciseStyle = ____DangerouslyImpreciseStyle_Internal; +" +`; + +exports[`public API should not change unintentionally Libraries/StyleSheet/StyleSheetExports.js 1`] = ` +"declare let hairlineWidth: number; declare const absoluteFill: { +bottom: 0, +left: 0, @@ -7340,6 +7370,26 @@ declare export default { " `; +exports[`public API should not change unintentionally Libraries/StyleSheet/StyleSheetExports.js.flow 1`] = ` +"declare export const hairlineWidth: number; +declare export const absoluteFill: any; +declare export const absoluteFillObject: { + +bottom: 0, + +left: 0, + +position: \\"absolute\\", + +right: 0, + +top: 0, +}; +declare export const compose: typeof composeStyles; +declare export const flatten: typeof flattenStyle; +declare export const setStyleAttributePreprocessor: ( + property: string, + process: (nextProp: any) => any +) => void; +declare export const create: <+S: ____Styles_Internal>(obj: S) => $ReadOnly; +" +`; + exports[`public API should not change unintentionally Libraries/StyleSheet/StyleSheetTypes.js 1`] = ` "declare export opaque type NativeColorValue; export type ____ColorValue_Internal = null | string | number | NativeColorValue; @@ -7517,10 +7567,7 @@ type ____BlendMode_Internal = | \\"saturation\\" | \\"color\\" | \\"luminosity\\"; -export type ____ViewStyle_InternalCore = $ReadOnly<{ - ...$Exact<____LayoutStyle_Internal>, - ...$Exact<____ShadowStyle_Internal>, - ...$Exact<____TransformStyle_Internal>, +export type ____ViewStyle_InternalBase = $ReadOnly<{ backfaceVisibility?: \\"visible\\" | \\"hidden\\", backgroundColor?: ____ColorValue_Internal, borderColor?: ____ColorValue_Internal, @@ -7569,6 +7616,12 @@ export type ____ViewStyle_InternalCore = $ReadOnly<{ experimental_backgroundImage?: $ReadOnlyArray | string, isolation?: \\"auto\\" | \\"isolate\\", }>; +export type ____ViewStyle_InternalCore = $ReadOnly<{ + ...$Exact<____LayoutStyle_Internal>, + ...$Exact<____ShadowStyle_Internal>, + ...$Exact<____TransformStyle_Internal>, + ...____ViewStyle_InternalBase, +}>; export type ____ViewStyle_Internal = $ReadOnly<{ ...____ViewStyle_InternalCore, ...____ViewStyle_InternalOverrides, @@ -7654,8 +7707,7 @@ export type ____FontVariantArray_Internal = $ReadOnlyArray< | \\"stylistic-nineteen\\" | \\"stylistic-twenty\\", >; -export type ____TextStyle_InternalCore = $ReadOnly<{ - ...$Exact<____ViewStyle_Internal>, +type ____TextStyle_InternalBase = $ReadOnly<{ color?: ____ColorValue_Internal, fontFamily?: string, fontSize?: number, @@ -7685,6 +7737,10 @@ export type ____TextStyle_InternalCore = $ReadOnly<{ verticalAlign?: \\"auto\\" | \\"top\\" | \\"bottom\\" | \\"middle\\", writingDirection?: \\"auto\\" | \\"ltr\\" | \\"rtl\\", }>; +export type ____TextStyle_InternalCore = $ReadOnly<{ + ...$Exact<____ViewStyle_Internal>, + ...____TextStyle_InternalBase, +}>; export type ____TextStyle_Internal = $ReadOnly<{ ...____TextStyle_InternalCore, ...____TextStyle_InternalOverrides, @@ -7712,36 +7768,35 @@ export type ____DangerouslyImpreciseStyle_Internal = $ReadOnly<{ ...____DangerouslyImpreciseStyle_InternalOverrides, ... }>; -type GenericStyleProp<+T> = +export type StyleProp<+T> = | null | void | T | false | \\"\\" - | $ReadOnlyArray>; -export type ____DangerouslyImpreciseStyleProp_Internal = GenericStyleProp< + | $ReadOnlyArray>; +export type ____DangerouslyImpreciseStyleProp_Internal = StyleProp< Partial<____DangerouslyImpreciseStyle_Internal>, >; -export type ____ViewStyleProp_Internal = GenericStyleProp< +export type ____ViewStyleProp_Internal = StyleProp< $ReadOnly>, >; -export type ____TextStyleProp_Internal = GenericStyleProp< +export type ____TextStyleProp_Internal = StyleProp< $ReadOnly>, >; -export type ____ImageStyleProp_Internal = GenericStyleProp< +export type ____ImageStyleProp_Internal = StyleProp< $ReadOnly>, >; export type ____Styles_Internal = { +[key: string]: Partial<____DangerouslyImpreciseStyle_Internal>, ... }; -export type ____FlattenStyleProp_Internal< - +TStyleProp: GenericStyleProp, -> = TStyleProp extends null | void | false | \\"\\" - ? empty - : TStyleProp extends $ReadOnlyArray - ? ____FlattenStyleProp_Internal - : TStyleProp; +export type ____FlattenStyleProp_Internal<+TStyleProp: StyleProp> = + TStyleProp extends null | void | false | \\"\\" + ? empty + : TStyleProp extends $ReadOnlyArray + ? ____FlattenStyleProp_Internal + : TStyleProp; " `; diff --git a/packages/react-native/types/__typetests__/index.tsx b/packages/react-native/types/__typetests__/index.tsx index 2073740bdebc..3ec2b0e69f51 100644 --- a/packages/react-native/types/__typetests__/index.tsx +++ b/packages/react-native/types/__typetests__/index.tsx @@ -167,11 +167,11 @@ BackHandler.addEventListener('hardwareBackPress', () => false).remove(); BackHandler.addEventListener('hardwareBackPress', () => undefined).remove(); BackHandler.addEventListener('hardwareBackPress', () => null).remove(); -interface LocalStyles { +type LocalStyles = { container: ViewStyle; welcome: TextStyle; instructions: TextStyle; -} +}; const styles = StyleSheet.create({ container: { @@ -217,7 +217,7 @@ StyleSheet.setStyleAttributePreprocessor( (family: string) => family, ); -const welcomeFontSize = StyleSheet.flatten(styles.welcome).fontSize; +const welcomeFontSize = StyleSheet.flatten(styles.welcome)?.fontSize; const viewStyle: StyleProp = { backgroundColor: '#F5FCFF',