View.js

Created Diff never expires
183 removals
Words removed267
Total words431
Words removed (%)61.95
189 lines
170 additions
Words added327
Total words491
Words added (%)66.60
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;