View.js

Created Diff never expires
183 removals
Lines
Total
Removed
Words
Total
Removed
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
189 lines
170 additions
Lines
Total
Added
Words
Total
Added
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
203 lines
/**
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
*
* This source code is licensed under the MIT license found in the
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* LICENSE file in the root directory of this source tree.
*
*
* @format
* @format
* @flow strict-local
* @flow strict-local
*/
*/


import type {ViewProps} from './ViewPropTypes';
import type {ViewProps} from './ViewPropTypes';


import flattenStyle from '../../StyleSheet/flattenStyle';
import flattenStyle from '../../StyleSheet/flattenStyle';
import TextAncestor from '../../Text/TextAncestor';
import TextAncestor from '../../Text/TextAncestor';
import ViewNativeComponent from './ViewNativeComponent';
import ViewNativeComponent from './ViewNativeComponent';
import * as React from 'react';
import * as React from 'react';


export type Props = ViewProps;
export type Props = ViewProps;


let didWarnAboutGap = false;

/**
/**
* The most fundamental component for building a UI, View is a container that
* The most fundamental component for building a UI, View is a container that
* supports layout with flexbox, style, some touch handling, and accessibility
* supports layout with flexbox, style, some touch handling, and accessibility
* controls.
* controls.
*
*
* @see https://reactnative.dev/docs/view
* @see https://reactnative.dev/docs/view
*/
*/
const View: React.AbstractComponent<
const View: React.AbstractComponent<
ViewProps,
ViewProps,
React.ElementRef<typeof ViewNativeComponent>,
React.ElementRef<typeof ViewNativeComponent>
> = React.forwardRef(
> = React.forwardRef((props: ViewProps, forwardedRef) => {
(
const {
{
accessibilityElementsHidden,
accessibilityElementsHidden,
accessibilityLabel,
accessibilityLabel,
accessibilityLabelledBy,
accessibilityLabelledBy,
accessibilityLiveRegion,
accessibilityLiveRegion,
accessibilityRole,
accessibilityRole,
accessibilityState,
accessibilityState,
accessibilityValue,
accessibilityValue,
'aria-busy': ariaBusy,
'aria-busy': ariaBusy,
'aria-checked': ariaChecked,
'aria-checked': ariaChecked,
'aria-disabled': ariaDisabled,
'aria-disabled': ariaDisabled,
'aria-expanded': ariaExpanded,
'aria-expanded': ariaExpanded,
'aria-hidden': ariaHidden,
'aria-hidden': ariaHidden,
'aria-label': ariaLabel,
'aria-label': ariaLabel,
'aria-labelledby': ariaLabelledBy,
'aria-labelledby': ariaLabelledBy,
'aria-live': ariaLive,
'aria-live': ariaLive,
'aria-selected': ariaSelected,
'aria-selected': ariaSelected,
'aria-valuemax': ariaValueMax,
'aria-valuemax': ariaValueMax,
'aria-valuemin': ariaValueMin,
'aria-valuemin': ariaValueMin,
'aria-valuenow': ariaValueNow,
'aria-valuenow': ariaValueNow,
'aria-valuetext': ariaValueText,
'aria-valuetext': ariaValueText,
focusable,
focusable,
id,
id,
importantForAccessibility,
importantForAccessibility,
nativeID,
nativeID,
pointerEvents,
pointerEvents,
role,
role,
style,
style,
tabIndex,
tabIndex,
gap,
...otherProps
rowGap,
}: ViewProps,
columnGap,
forwardedRef,
...otherProps
) => {
} = props;
const _accessibilityLabelledBy =
ariaLabelledBy?.split(/\s*,\s*/g) ?? accessibilityLabelledBy;


const _accessibilityState = {
if (__DEV__) {
busy: ariaBusy ?? accessibilityState?.busy,
if (
checked: ariaChecked ?? accessibilityState?.checked,
('gap' in props || 'columnGap' in props || 'rowGap' in props) &&
disabled: ariaDisabled ?? accessibilityState?.disabled,
!didWarnAboutGap
expanded: ariaExpanded ?? accessibilityState?.expanded,
) {
selected: ariaSelected ?? accessibilityState?.selected,
console.warn(
};
'<View> was passed prop either `gap`, `columnGap`, `rowGap`. ' +
'Currently this is a no-op, but in future versions, this will ' +
'apply these props as styles.'
);
didWarnAboutGap = true;
}
}


const _accessibilityValue = {
const _accessibilityLabelledBy =
max: ariaValueMax ?? accessibilityValue?.max,
ariaLabelledBy?.split(/\s*,\s*/g) ?? accessibilityLabelledBy;
min: ariaValueMin ?? accessibilityValue?.min,
now: ariaValueNow ?? accessibilityValue?.now,
text: ariaValueText ?? accessibilityValue?.text,
};


// Map role values to AccessibilityRole values
const _accessibilityState = {
const roleToAccessibilityRoleMapping = {
busy: ariaBusy ?? accessibilityState?.busy,
alert: 'alert',
checked: ariaChecked ?? accessibilityState?.checked,
alertdialog: undefined,
disabled: ariaDisabled ?? accessibilityState?.disabled,
application: undefined,
expanded: ariaExpanded ?? accessibilityState?.expanded,
article: undefined,
selected: ariaSelected ?? accessibilityState?.selected,
banner: undefined,
};
button: 'button',
cell: undefined,
checkbox: 'checkbox',
columnheader: undefined,
combobox: 'combobox',
complementary: undefined,
contentinfo: undefined,
definition: undefined,
dialog: undefined,
directory: undefined,
document: undefined,
feed: undefined,
figure: undefined,
form: undefined,
grid: 'grid',
group: undefined,
heading: 'header',
img: 'image',
link: 'link',
list: 'list',
listitem: undefined,
log: undefined,
main: undefined,
marquee: undefined,
math: undefined,
menu: 'menu',
menubar: 'menubar',
menuitem: 'menuitem',
meter: undefined,
navigation: undefined,
none: 'none',
note: undefined,
presentation: 'none',
progressbar: 'progressbar',
radio: 'radio',
radiogroup: 'radiogroup',
region: undefined,
row: undefined,
rowgroup: undefined,
rowheader: undefined,
scrollbar: 'scrollbar',
searchbox: 'search',
separator: undefined,
slider: 'adjustable',
spinbutton: 'spinbutton',
status: undefined,
summary: 'summary',
switch: 'switch',
tab: 'tab',
table: undefined,
tablist: 'tablist',
tabpanel: undefined,
term: undefined,
timer: 'timer',
toolbar: 'toolbar',
tooltip: undefined,
tree: undefined,
treegrid: undefined,
treeitem: undefined,
};


const flattenedStyle = flattenStyle(style);
const _accessibilityValue = {
const newPointerEvents = flattenedStyle?.pointerEvents || pointerEvents;
max: ariaValueMax ?? accessibilityValue?.max,
min: ariaValueMin ?? accessibilityValue?.min,
now: ariaValueNow ?? accessibilityValue?.now,
text: ariaValueText ?? accessibilityValue?.text,
};


return (
// Map role values to AccessibilityRole values
<TextAncestor.Provider value={false}>
const roleToAccessibilityRoleMapping = {
<ViewNativeComponent
alert: 'alert',
{...otherProps}
alertdialog: undefined,
accessibilityLiveRegion={
application: undefined,
ariaLive === 'off' ? 'none' : ariaLive ?? accessibilityLiveRegion
article: undefined,
}
banner: undefined,
accessibilityLabel={ariaLabel ?? accessibilityLabel}
button: 'button',
focusable={tabIndex !== undefined ? !tabIndex : focusable}
cell: undefined,
accessibilityState={_accessibilityState}
checkbox: 'checkbox',
accessibilityRole={
columnheader: undefined,
role ? roleToAccessibilityRoleMapping[role] : accessibilityRole
combobox: 'combobox',
}
complementary: undefined,
accessibilityElementsHidden={
contentinfo: undefined,
ariaHidden ?? accessibilityElementsHidden
definition: undefined,
}
dialog: undefined,
accessibilityLabelledBy={_accessibilityLabelledBy}
directory: undefined,
accessibilityValue={_accessibilityValue}
document: undefined,
importantForAccessibility={
feed: undefined,
ariaHidden === true
figure: undefined,
? 'no-hide-descendants'
form: undefined,
: importantForAccessibility
grid: 'grid',
}
group: undefined,
nativeID={id ?? nativeID}
heading: 'header',
style={style}
img: 'image',
pointerEvents={newPointerEvents}
link: 'link',
ref={forwardedRef}
list: 'list',
/>
listitem: undefined,
</TextAncestor.Provider>
log: undefined,
);
main: undefined,
},
marquee: undefined,
);
math: undefined,
menu: 'menu',
menubar: 'menubar',
menuitem: 'menuitem',
meter: undefined,
navigation: undefined,
none: 'none',
note: undefined,
presentation: 'none',
progressbar: 'progressbar',
radio: 'radio',
radiogroup: 'radiogroup',
region: undefined,
row: undefined,
rowgroup: undefined,
rowheader: undefined,
scrollbar: 'scrollbar',
searchbox: 'search',
separator: undefined,
slider: 'adjustable',
spinbutton: 'spinbutton',
status: undefined,
summary: 'summary',
switch: 'switch',
tab: 'tab',
table: undefined,
tablist: 'tablist',
tabpanel: undefined,
term: undefined,
timer: 'timer',
toolbar: 'toolbar',
tooltip: undefined,
tree: undefined,
treegrid: undefined,
treeitem: undefined,
};

const flattenedStyle = flattenStyle(style);
const newPointerEvents = flattenedStyle?.pointerEvents || pointerEvents;

return (
<TextAncestor.Provider value={false}>
<ViewNativeComponent
{...otherProps}
accessibilityLiveRegion={
ariaLive === 'off' ? 'none' : ariaLive ?? accessibilityLiveRegion
}
accessibilityLabel={ariaLabel ?? accessibilityLabel}
focusable={tabIndex !== undefined ? !tabIndex : focusable}
accessibilityState={_accessibilityState}
accessibilityRole={
role ? roleToAccessibilityRoleMapping[role] : accessibilityRole
}
accessibilityElementsHidden={ariaHidden ?? accessibilityElementsHidden}
accessibilityLabelledBy={_accessibilityLabelledBy}
accessibilityValue={_accessibilityValue}
importantForAccessibility={
ariaHidden === true
? 'no-hide-descendants'
: importantForAccessibility
}
nativeID={id ?? nativeID}
style={style}
pointerEvents={newPointerEvents}
ref={forwardedRef}
/>
</TextAncestor.Provider>
);
});


View.displayName = 'View';
View.displayName = 'View';


module.exports = View;
module.exports = View;