/**
* 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 strict-local
* @format
*/
'use strict';
import type {RNTesterModule} from '../../types/RNTesterTypes';
import RNTesterText from '../../components/RNTesterText';
import * as React from 'react';
import {useState} from 'react';
import {
Platform,
PlatformColor,
Pressable,
StyleSheet,
View,
} from 'react-native';
class ViewBorderStyleExample extends React.Component<
$ReadOnly<{}>,
{showBorder: boolean},
> {
state: {showBorder: boolean} = {
showBorder: true,
};
render(): React.Node {
return (
Dashed border style
Dotted border style
);
}
_handlePress = () => {
this.setState({showBorder: !this.state.showBorder});
};
}
const offscreenAlphaCompositingStyles = StyleSheet.create({
alphaCompositing: {
justifyContent: 'space-around',
width: 100,
height: 50,
borderRadius: 100,
},
});
class OffscreenAlphaCompositing extends React.Component<
$ReadOnly<{testID?: ?string}>,
{
active: boolean,
},
> {
state: {active: boolean} = {
active: false,
};
render(): React.Node {
return (
Blobs
Same blobs, but their shared container have 0.5 opacity
Tap to {this.state.active ? 'activate' : 'deactivate'}{' '}
needsOffscreenAlphaCompositing
);
}
_handlePress = () => {
this.setState({active: !this.state.active});
};
}
const ZIndexExampleStyles = StyleSheet.create({
zIndex: {
justifyContent: 'space-around',
width: 100,
height: 50,
marginTop: -10,
position: 'relative',
},
});
class ZIndexExample extends React.Component<
$ReadOnly<{}>,
{
flipped: boolean,
},
> {
state: {flipped: boolean} = {
flipped: false,
};
render(): React.Node {
const indices = this.state.flipped ? [-1, 0, 1, 2] : [2, 1, 0, -1];
return (
Tap to flip sorting order
ZIndex {indices[0]}
ZIndex {indices[1]}
ZIndex {indices[2]}
ZIndex {indices[3]}
);
}
_handlePress = () => {
this.setState({flipped: !this.state.flipped});
};
}
function PositionStaticZIndexExample(): React.Node {
return (
);
}
class DisplayNoneStyle extends React.Component<
$ReadOnly<{}>,
{
index: number,
},
> {
state: {index: number} = {
index: 0,
};
render(): React.Node {
return (
Press to toggle `display: none`
);
}
_handlePress = () => {
this.setState({index: this.state.index + 1});
};
}
class FlexGapExample extends React.Component<$ReadOnly<{testID?: ?string}>> {
render(): React.Node {
return (
);
}
}
function BoxShadowExample(): React.Node {
const defaultStyleSize = {width: 50, height: 50};
return (
{/* Invalid, should not render */}
);
}
function OutlineExample(): React.Node {
const defaultStyleSize = {width: 50, height: 50};
return (
);
}
function BoxSizingExample(): React.Node {
const styles = StyleSheet.create({
boxSizingBox: {
padding: 5,
backgroundColor: 'green',
borderWidth: 5,
margin: 10,
width: 50,
height: 25,
},
boxSizingChild: {
backgroundColor: 'red',
width: '100%',
height: '100%',
},
});
return (
Content box 50x25
Border box 50x25
);
}
function FocusableInnerRow({focusable}: {focusable: boolean}) {
const styles = StyleSheet.create({
focused: {
borderColor: 'blue',
borderWidth: 2,
},
innerBox: {
backgroundColor: 'red',
width: '100%',
height: 50,
borderColor: 'transparent',
borderWidth: 2,
},
innerBoxTextColor: {
color: 'white',
},
});
const [focused, setFocused] = useState(false);
return (
setFocused(false)}
onFocus={() => setFocused(true)}
style={[styles.innerBox, focused && styles.focused]}>
Focusable: {focusable ? 'true' : 'false'}
Focused: {focused ? 'true' : 'false'}
);
}
function FocusBlurExample(): React.Node {
const styles = StyleSheet.create({
focused: {
borderColor: 'blue',
borderWidth: 2,
},
outerBox: {
backgroundColor: 'green',
borderColor: 'transparent',
borderWidth: 2,
padding: 10,
},
outerBoxTextColor: {
color: 'white',
},
});
const [outerFocused, setOuterFocused] = useState(false);
return (
setOuterFocused(false)}
onFocus={() => setOuterFocused(true)}
style={[styles.outerBox, outerFocused && styles.focused]}>
Focused: {outerFocused ? 'true' : 'false'}
);
}
export default ({
title: 'View',
documentationURL: 'https://reactnative.dev/docs/view',
category: 'Basic',
description: ('Basic building block of all UI, examples that ' +
'demonstrate some of the many styles available.': string),
displayName: 'ViewExample',
examples: [
{
title: 'Background Color',
name: 'background-color',
render(): React.Node {
return (
Blue background
);
},
},
{
title: 'Border',
name: 'border',
render(): React.Node {
return (
5px blue border
);
},
},
{
title: 'Padding/Margin',
name: 'padding-margin',
render(): React.Node {
const styles = StyleSheet.create({
box: {
backgroundColor: '#527FE4',
borderColor: '#000033',
borderWidth: 1,
},
});
return (
5px padding
5px margin
5px margin and padding,
widthAutonomous=true
);
},
},
{
title: 'Border Radius',
name: 'border-radius',
render(): React.Node {
return (
Too much use of `borderRadius` (especially large radii) on
anything which is scrolling may result in dropped frames. Use
sparingly.
{Platform.OS === 'ios' && (
View with continuous border curve
)}
);
},
},
{
title: 'Border Style',
name: 'border-style',
render(): React.Node {
return ;
},
},
{
title: 'Rounded Borders',
name: 'rounded-borders',
render(): React.Node {
return (
);
},
},
{
title: 'Rounded Borders (Percentages)',
name: 'rounded-borders-percentages',
render(): React.Node {
return (
);
},
},
{
title: 'Overflow',
name: 'overflow',
render(): React.Node {
const styles = StyleSheet.create({
container: {
borderWidth: StyleSheet.hairlineWidth,
height: 12,
marginBottom: 8,
marginEnd: 16,
width: 95,
},
content: {
height: 20,
width: 200,
},
});
// NOTE: The that sets `overflow` should only have other layout
// styles so that we can accurately test view flattening optimizations.
return (
undefined
hidden
visible
);
},
},
{
title: 'Opacity',
name: 'opacity',
render(): React.Node {
return (
Opacity 0
Opacity 0.1
Opacity 0.3
Opacity 0.5
Opacity 0.7
Opacity 0.9
Opacity 1
);
},
},
{
title: 'Offscreen Alpha Compositing',
name: 'offscreen-alpha-compositing',
render(): React.Node {
return (
);
},
},
{
title: 'ZIndex',
name: 'z-index',
render(): React.Node {
return ;
},
},
{
title: 'ZIndex With Static',
name: 'zindex-with-static',
render: PositionStaticZIndexExample,
},
{
title: '`display: none` style',
name: 'display-none',
render(): React.Node {
return ;
},
},
{
title: 'BackfaceVisibility',
name: 'backface-visibility',
render(): React.Node {
return (
View #1, front is visible, back is hidden.
Front
Back (You should not see this)
View #2, front is hidden, back is visible.
Front (You should not see this)
Back
);
},
},
{
title: 'View with aria-label="label"',
name: 'aria-label',
render(): React.Node {
return (
Blue background
);
},
},
{
title: 'FlexGap',
name: 'flexgap',
render(): React.Node {
return ;
},
},
{
title: 'Insets',
name: 'insets',
render(): React.Node {
return (
inset 5
insetBlock 5
insetBlockEnd 5
insetBlockStart 5
insetInline 5
insetInlineEnd 5
insetInlineStart 5
);
},
},
{
title: 'Logical Border Color',
name: 'logical-border-color',
render(): React.Node {
return (
borderBlockColor orange
borderBlockStartColor purple
borderBlockEndColor green
);
},
},
{
title: 'Box Shadow',
name: 'box-shadow',
render: BoxShadowExample,
},
{
title: 'Outline',
name: 'outline',
render: OutlineExample,
},
{
title: 'Box Sizing',
name: 'box-sizing',
render: BoxSizingExample,
},
{
title: 'Focus/Blur',
name: 'focus-blur',
render: FocusBlurExample,
},
],
}: RNTesterModule);