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 | * @format
|
8 | */
|
9 |
|
10 | import {ImageStyle, TextStyle, ViewStyle} from './StyleSheetTypes';
|
11 |
|
12 | export interface StyleSheetProperties {
|
13 | hairlineWidth: number;
|
14 | flatten<T extends string>(style: T): T;
|
15 | }
|
16 |
|
17 | type Falsy = undefined | null | false | '';
|
18 | interface RecursiveArray<T>
|
19 | extends Array<T | ReadonlyArray<T> | RecursiveArray<T>> {}
|
20 | /** Keep a brand of 'T' so that calls to `StyleSheet.flatten` can take `RegisteredStyle<T>` and return `T`. */
|
21 | type RegisteredStyle<T> = number & {__registeredStyleBrand: T};
|
22 | export type StyleProp<T> =
|
23 | | T
|
24 | | RegisteredStyle<T>
|
25 | | RecursiveArray<T | RegisteredStyle<T> | Falsy>
|
26 | | Falsy;
|
27 |
|
28 | type OpaqueColorValue = symbol & {__TYPE__: 'Color'};
|
29 | export type ColorValue = string | OpaqueColorValue;
|
30 |
|
31 | export namespace StyleSheet {
|
32 | type NamedStyles<T> = {[P in keyof T]: ViewStyle | TextStyle | ImageStyle};
|
33 |
|
34 | /**
|
35 | * An identity function for creating style sheets.
|
36 | */
|
37 | export function create<T extends NamedStyles<T> | NamedStyles<any>>(
|
38 | // The extra & NamedStyles<any> here helps Typescript catch typos: e.g.,
|
39 | // the following code would not error with `styles: T | NamedStyles<T>`,
|
40 | // but would error with `styles: T & NamedStyles<any>`
|
41 | //
|
42 | // ```ts
|
43 | // StyleSheet.create({
|
44 | // someComponent: { marginLeft: 1, magrinRight: 1 },
|
45 | // });
|
46 | // ```
|
47 | styles: T & NamedStyles<any>,
|
48 | ): T;
|
49 |
|
50 | /**
|
51 | * Flattens an array of style objects, into one aggregated style object.
|
52 | *
|
53 | * Example:
|
54 | * ```
|
55 | * const styles = StyleSheet.create({
|
56 | * listItem: {
|
57 | * flex: 1,
|
58 | * fontSize: 16,
|
59 | * color: 'white'
|
60 | * },
|
61 | * selectedListItem: {
|
62 | * color: 'green'
|
63 | * }
|
64 | * });
|
65 | *
|
66 | * StyleSheet.flatten([styles.listItem, styles.selectedListItem])
|
67 | * // returns { flex: 1, fontSize: 16, color: 'green' }
|
68 | * ```
|
69 | */
|
70 | export function flatten<T>(
|
71 | style?: StyleProp<T>,
|
72 | ): T extends (infer U)[] ? U : T;
|
73 |
|
74 | /**
|
75 | * Combines two styles such that style2 will override any styles in style1.
|
76 | * If either style is falsy, the other one is returned without allocating
|
77 | * an array, saving allocations and maintaining reference equality for
|
78 | * PureComponent checks.
|
79 | */
|
80 | export function compose<
|
81 | T extends ViewStyle | TextStyle | ImageStyle,
|
82 | U extends T,
|
83 | V extends T,
|
84 | >(
|
85 | style1: StyleProp<U> | Array<StyleProp<U>>,
|
86 | style2: StyleProp<V> | Array<StyleProp<V>>,
|
87 | ): StyleProp<T>;
|
88 |
|
89 | /**
|
90 | * WARNING: EXPERIMENTAL. Breaking changes will probably happen a lot and will
|
91 | * not be reliably announced. The whole thing might be deleted, who knows? Use
|
92 | * at your own risk.
|
93 | *
|
94 | * Sets a function to use to pre-process a style property value. This is used
|
95 | * internally to process color and transform values. You should not use this
|
96 | * unless you really know what you are doing and have exhausted other options.
|
97 | */
|
98 | export function setStyleAttributePreprocessor(
|
99 | property: string,
|
100 | process: (nextProp: any) => any,
|
101 | ): void;
|
102 |
|
103 | /**
|
104 | * This is defined as the width of a thin line on the platform. It can be
|
105 | * used as the thickness of a border or division between two elements.
|
106 | * Example:
|
107 | * ```
|
108 | * {
|
109 | * borderBottomColor: '#bbb',
|
110 | * borderBottomWidth: StyleSheet.hairlineWidth
|
111 | * }
|
112 | * ```
|
113 | *
|
114 | * This constant will always be a round number of pixels (so a line defined
|
115 | * by it look crisp) and will try to match the standard width of a thin line
|
116 | * on the underlying platform. However, you should not rely on it being a
|
117 | * constant size, because on different platforms and screen densities its
|
118 | * value may be calculated differently.
|
119 | */
|
120 | export const hairlineWidth: number;
|
121 |
|
122 | interface AbsoluteFillStyle {
|
123 | position: 'absolute';
|
124 | left: 0;
|
125 | right: 0;
|
126 | top: 0;
|
127 | bottom: 0;
|
128 | }
|
129 |
|
130 | /**
|
131 | * Sometimes you may want `absoluteFill` but with a couple tweaks - `absoluteFillObject` can be
|
132 | * used to create a customized entry in a `StyleSheet`, e.g.:
|
133 | *
|
134 | * const styles = StyleSheet.create({
|
135 | * wrapper: {
|
136 | * ...StyleSheet.absoluteFillObject,
|
137 | * top: 10,
|
138 | * backgroundColor: 'transparent',
|
139 | * },
|
140 | * });
|
141 | */
|
142 | export const absoluteFillObject: AbsoluteFillStyle;
|
143 |
|
144 | /**
|
145 | * A very common pattern is to create overlays with position absolute and zero positioning,
|
146 | * so `absoluteFill` can be used for convenience and to reduce duplication of these repeated
|
147 | * styles.
|
148 | */
|
149 | export const absoluteFill: RegisteredStyle<AbsoluteFillStyle>;
|
150 | }
|