Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
/**
* 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.
*
* @format
*/

import type * as React from 'react';

type LayoutConformanceProps = {
/**
* strict: Layout in accordance with W3C spec, even when breaking
* compatibility: Layout with the same behavior as previous versions of React Native
*/
mode: 'strict' | 'compatibility';
children: React.ReactNode;
};

export const experimental_LayoutConformance: React.ComponentType<LayoutConformanceProps>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
/**
* 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
* @oncall react_native
*/

import StyleSheet from '../../StyleSheet/StyleSheet';
import LayoutConformanceNativeComponent from './LayoutConformanceNativeComponent';
import * as React from 'react';

type Props = $ReadOnly<{
/**
* strict: Layout in accordance with W3C spec, even when breaking
* compatibility: Layout with the same behavior as previous versions of React Native
*/
mode: 'strict' | 'compatibility',

children: React.Node,
}>;

// We want a graceful fallback for apps using legacy arch, but need to know
// ahead of time whether the component is available, so we test for global.
// This does not correctly handle mixed arch apps (which is okay, since we just
// degrade the error experience).
const isFabricUIManagerInstalled = global?.nativeFabricUIManager != null;

function LayoutConformance(props: Props): React.Node {
return (
<LayoutConformanceNativeComponent {...props} style={styles.container} />
);
}

function UnimplementedLayoutConformance(props: Props): React.Node {
if (__DEV__) {
const warnOnce = require('../../Utilities/warnOnce');

warnOnce(
'layoutconformance-unsupported',
'"LayoutConformance" is only supported in the New Architecture',
);
}

return props.children;
}

export default (isFabricUIManagerInstalled
? LayoutConformance
: UnimplementedLayoutConformance) as component(...Props);

const styles = StyleSheet.create({
container: {
display: 'contents',
},
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
/**
* 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
*/

import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
import type {ViewProps} from '../View/ViewPropTypes';

import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentRegistry';

type Props = $ReadOnly<{
mode: 'strict' | 'compatibility',
...ViewProps,
}>;

const LayoutConformanceNativeComponent: HostComponent<Props> =
NativeComponentRegistry.get<Props>('LayoutConformance', () => ({
uiViewClassName: 'LayoutConformance',
validAttributes: {
mode: true,
},
}));

export default LayoutConformanceNativeComponent;
Original file line numberDiff line numberDiff line change
Expand Up@@ -211,11 +211,4 @@ export interface ViewProps
* Used to reference react managed views from native code.
*/
nativeID?: string | undefined;

/**
* Contols whether this view, and its transitive children, are laid in a way
* consistent with web browsers ('strict'), or consistent with existing
* React Native code which may rely on incorrect behavior ('classic').
*/
experimental_layoutConformance?: 'strict' | 'classic' | undefined;
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -578,15 +578,6 @@ export type ViewProps = $ReadOnly<{|
*/
collapsableChildren?: ?boolean,

/**
* Contols whether this view, and its transitive children, are laid in a way
* consistent with web browsers ('strict'), or consistent with existing
* React Native code which may rely on incorrect behavior ('classic').
*
* This prop only works when using Fabric.
*/
experimental_layoutConformance?: ?('strict' | 'classic'),

/**
* Used to locate this view from native classes. Has precedence over `nativeID` prop.
*
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -293,8 +293,6 @@ const validAttributesForNonEventProps = {

style: ReactNativeStyleAttributes,

experimental_layoutConformance: true,

// ReactClippingViewManager @ReactProps
removeClippedSubviews: true,

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -357,8 +357,6 @@ const validAttributesForNonEventProps = {
direction: true,

style: ReactNativeStyleAttributes,

experimental_layoutConformance: true,
};

// Props for bubbling and direct events
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -1887,6 +1887,25 @@ declare export default typeof NativeKeyboardObserver;
"
`;

exports[`public API should not change unintentionally Libraries/Components/LayoutConformance/LayoutConformance.js 1`] = `
"type Props = $ReadOnly<{
mode: \\"strict\\" | \\"compatibility\\",
children: React.Node,
}>;
declare export default component(...Props);
"
`;

exports[`public API should not change unintentionally Libraries/Components/LayoutConformance/LayoutConformanceNativeComponent.js 1`] = `
"type Props = $ReadOnly<{
mode: \\"strict\\" | \\"compatibility\\",
...ViewProps,
}>;
declare const LayoutConformanceNativeComponent: HostComponent<Props>;
declare export default typeof LayoutConformanceNativeComponent;
"
`;

exports[`public API should not change unintentionally Libraries/Components/Pressable/Pressable.js 1`] = `
"type ViewStyleProp = $ElementType<React.ElementConfig<typeof View>, \\"style\\">;
export type StateCallbackType = $ReadOnly<{|
Expand DownExpand Up@@ -4268,7 +4287,6 @@ export type ViewProps = $ReadOnly<{|
\\"aria-hidden\\"?: ?boolean,
collapsable?: ?boolean,
collapsableChildren?: ?boolean,
experimental_layoutConformance?: ?(\\"strict\\" | \\"classic\\"),
id?: string,
testID?: ?string,
nativeID?: ?string,
Expand DownExpand Up@@ -9627,6 +9645,7 @@ declare module.exports: {
get Image(): Image,
get ImageBackground(): ImageBackground,
get InputAccessoryView(): InputAccessoryView,
get experimental_LayoutConformance(): LayoutConformance,
get KeyboardAvoidingView(): KeyboardAvoidingView,
get Modal(): Modal,
get Pressable(): Pressable,
Expand Down
7 changes: 0 additions & 7 deletions packages/react-native/React/Views/RCTViewManager.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -424,13 +424,6 @@ - (void)updateAccessibilityTraitsForRole:(RCTView *)view withDefaultView:(RCTVie
// filtered by view configs.
}

RCT_CUSTOM_VIEW_PROPERTY(experimental_layoutConformance, NSString *, RCTView)
{
// Property is only to be used in the new renderer.
// It is necessary to add it here, otherwise it gets
// filtered by view configs.
}

typedef NSArray *FilterArray; // Custom type to make the StaticViewConfigValidator Happy
RCT_CUSTOM_VIEW_PROPERTY(filter, FilterArray, RCTView)
{
Expand Down
1 change: 0 additions & 1 deletion packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line numberDiff line numberDiff line change
Expand Up@@ -4155,7 +4155,6 @@ public class com/facebook/react/uimanager/LayoutShadowNode : com/facebook/react/
public fun setInsetBlock (ILcom/facebook/react/bridge/Dynamic;)V
public fun setInsetInline (ILcom/facebook/react/bridge/Dynamic;)V
public fun setJustifyContent (Ljava/lang/String;)V
public fun setLayoutConformance (Ljava/lang/String;)V
public fun setMarginBlock (ILcom/facebook/react/bridge/Dynamic;)V
public fun setMarginInline (ILcom/facebook/react/bridge/Dynamic;)V
public fun setMargins (ILcom/facebook/react/bridge/Dynamic;)V
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -972,9 +972,4 @@ public void setShouldNotifyPointerLeave(boolean value) {
public void setShouldNotifyPointerMove(boolean value) {
// Do Nothing: Align with static ViewConfigs
}

@ReactProp(name = "experimental_layoutConformance")
public void setLayoutConformance(String value) {
// Do Nothing: Align with static ViewConfigs
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@
#include <react/renderer/components/text/ParagraphComponentDescriptor.h>
#include <react/renderer/components/text/RawTextComponentDescriptor.h>
#include <react/renderer/components/text/TextComponentDescriptor.h>
#include <react/renderer/components/view/LayoutConformanceComponentDescriptor.h>
#include <react/renderer/components/view/ViewComponentDescriptor.h>

namespace facebook::react::CoreComponentsRegistry {
Expand DownExpand Up@@ -66,6 +67,8 @@ sharedProviderRegistry() {
AndroidDrawerLayoutComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
DebuggingOverlayComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
LayoutConformanceComponentDescriptor>());

return providerRegistry;
}();
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -342,16 +342,7 @@ BaseViewProps::BaseViewProps(
rawProps,
"removeClippedSubviews",
sourceProps.removeClippedSubviews,
false)),
experimental_layoutConformance(
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.experimental_layoutConformance
: convertRawProp(
context,
rawProps,
"experimental_layoutConformance",
sourceProps.experimental_layoutConformance,
{})) {}
false)) {}

#define VIEW_EVENT_CASE(eventType) \
case CONSTEXPR_RAW_PROPS_KEY_HASH("on" #eventType): { \
Expand DownExpand Up@@ -397,7 +388,6 @@ void BaseViewProps::setProp(
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsable);
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsableChildren);
RAW_SET_PROP_SWITCH_CASE_BASIC(removeClippedSubviews);
RAW_SET_PROP_SWITCH_CASE_BASIC(experimental_layoutConformance);
RAW_SET_PROP_SWITCH_CASE_BASIC(cursor);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineColor);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineOffset);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,8 +106,6 @@ class BaseViewProps : public YogaStylableProps, public AccessibilityProps {

bool removeClippedSubviews{false};

LayoutConformance experimental_layoutConformance{};

#pragma mark - Convenience Methods

CascadedBorderWidths getBorderWidths() const;
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/LayoutConformanceShadowNode.h>
#include <react/renderer/core/ConcreteComponentDescriptor.h>

namespace facebook::react {

using LayoutConformanceComponentDescriptor =
ConcreteComponentDescriptor<LayoutConformanceShadowNode>;

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/YogaStylableProps.h>
#include <react/renderer/components/view/propsConversions.h>

namespace facebook::react {

struct LayoutConformanceProps final : public YogaStylableProps {
/**
* Whether to layout the subtree with strict conformance to W3C standard
* (YGErrataNone) or for compatibility with legacy RN bugs (YGErrataAll)
*/
LayoutConformance mode{LayoutConformance::Strict};

LayoutConformanceProps() = default;
LayoutConformanceProps(
const PropsParserContext& context,
const LayoutConformanceProps& sourceProps,
const RawProps& rawProps)
: YogaStylableProps(context, sourceProps, rawProps),
mode{convertRawProp(
context,
rawProps,
"mode",
mode,
LayoutConformance::Strict)} {}
};

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/ConcreteViewShadowNode.h>
#include <react/renderer/components/view/LayoutConformanceProps.h>
#include <react/renderer/components/view/YogaLayoutableShadowNode.h>

namespace facebook::react {

constexpr const char LayoutConformanceShadowNodeComponentName[] =
"LayoutConformance";

using LayoutConformanceShadowNode = ConcreteShadowNode<
LayoutConformanceShadowNodeComponentName,
YogaLayoutableShadowNode,
LayoutConformanceProps>;

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,6 +11,7 @@
#include <react/debug/flags.h>
#include <react/debug/react_native_assert.h>
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <react/renderer/components/view/LayoutConformanceShadowNode.h>
#include <react/renderer/components/view/ViewProps.h>
#include <react/renderer/components/view/ViewShadowNode.h>
#include <react/renderer/components/view/conversions.h>
Expand DownExpand Up@@ -501,15 +502,13 @@ void YogaLayoutableShadowNode::configureYogaTree(
}

YGErrata YogaLayoutableShadowNode::resolveErrata(YGErrata defaultErrata) const {
if (auto viewShadowNode = dynamic_cast<const ViewShadowNode*>(this)) {
const auto& props = viewShadowNode->getConcreteProps();
switch (props.experimental_layoutConformance) {
case LayoutConformance::Classic:
return YGErrataAll;
if (auto layoutConformanceNode =
dynamic_cast<const LayoutConformanceShadowNode*>(this)) {
switch (layoutConformanceNode->getConcreteProps().mode) {
case LayoutConformance::Strict:
return YGErrataNone;
case LayoutConformance::Undefined:
return defaultErrata;
case LayoutConformance::Compatibility:
return YGErrataAll;
}
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
/**
* 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.
*
* @format
*/

import type * as React from 'react';

type LayoutConformanceProps = {
/**
* strict: Layout in accordance with W3C spec, even when breaking
* compatibility: Layout with the same behavior as previous versions of React Native
*/
mode: 'strict' | 'compatibility';
children: React.ReactNode;
};

export const experimental_LayoutConformance: React.ComponentType<LayoutConformanceProps>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
/**
* 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
* @oncall react_native
*/

import StyleSheet from '../../StyleSheet/StyleSheet';
import LayoutConformanceNativeComponent from './LayoutConformanceNativeComponent';
import * as React from 'react';

type Props = $ReadOnly<{
/**
* strict: Layout in accordance with W3C spec, even when breaking
* compatibility: Layout with the same behavior as previous versions of React Native
*/
mode: 'strict' | 'compatibility',

children: React.Node,
}>;

// We want a graceful fallback for apps using legacy arch, but need to know
// ahead of time whether the component is available, so we test for global.
// This does not correctly handle mixed arch apps (which is okay, since we just
// degrade the error experience).
const isFabricUIManagerInstalled = global?.nativeFabricUIManager != null;

function LayoutConformance(props: Props): React.Node {
return (
<LayoutConformanceNativeComponent {...props} style={styles.container} />
);
}

function UnimplementedLayoutConformance(props: Props): React.Node {
if (__DEV__) {
const warnOnce = require('../../Utilities/warnOnce');

warnOnce(
'layoutconformance-unsupported',
'"LayoutConformance" is only supported in the New Architecture',
);
}

return props.children;
}

export default (isFabricUIManagerInstalled
? LayoutConformance
: UnimplementedLayoutConformance) as component(...Props);

const styles = StyleSheet.create({
container: {
display: 'contents',
},
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
/**
* 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
*/

import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
import type {ViewProps} from '../View/ViewPropTypes';

import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentRegistry';

type Props = $ReadOnly<{
mode: 'strict' | 'compatibility',
...ViewProps,
}>;

const LayoutConformanceNativeComponent: HostComponent<Props> =
NativeComponentRegistry.get<Props>('LayoutConformance', () => ({
uiViewClassName: 'LayoutConformance',
validAttributes: {
mode: true,
},
}));

export default LayoutConformanceNativeComponent;
Original file line numberDiff line numberDiff line change
Expand Up@@ -211,11 +211,4 @@ export interface ViewProps
* Used to reference react managed views from native code.
*/
nativeID?: string | undefined;

/**
* Contols whether this view, and its transitive children, are laid in a way
* consistent with web browsers ('strict'), or consistent with existing
* React Native code which may rely on incorrect behavior ('classic').
*/
experimental_layoutConformance?: 'strict' | 'classic' | undefined;
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -578,15 +578,6 @@ export type ViewProps = $ReadOnly<{|
*/
collapsableChildren?: ?boolean,

/**
* Contols whether this view, and its transitive children, are laid in a way
* consistent with web browsers ('strict'), or consistent with existing
* React Native code which may rely on incorrect behavior ('classic').
*
* This prop only works when using Fabric.
*/
experimental_layoutConformance?: ?('strict' | 'classic'),

/**
* Used to locate this view from native classes. Has precedence over `nativeID` prop.
*
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -293,8 +293,6 @@ const validAttributesForNonEventProps = {

style: ReactNativeStyleAttributes,

experimental_layoutConformance: true,

// ReactClippingViewManager @ReactProps
removeClippedSubviews: true,

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -357,8 +357,6 @@ const validAttributesForNonEventProps = {
direction: true,

style: ReactNativeStyleAttributes,

experimental_layoutConformance: true,
};

// Props for bubbling and direct events
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -1887,6 +1887,25 @@ declare export default typeof NativeKeyboardObserver;
"
`;

exports[`public API should not change unintentionally Libraries/Components/LayoutConformance/LayoutConformance.js 1`] = `
"type Props = $ReadOnly<{
mode: \\"strict\\" | \\"compatibility\\",
children: React.Node,
}>;
declare export default component(...Props);
"
`;

exports[`public API should not change unintentionally Libraries/Components/LayoutConformance/LayoutConformanceNativeComponent.js 1`] = `
"type Props = $ReadOnly<{
mode: \\"strict\\" | \\"compatibility\\",
...ViewProps,
}>;
declare const LayoutConformanceNativeComponent: HostComponent<Props>;
declare export default typeof LayoutConformanceNativeComponent;
"
`;

exports[`public API should not change unintentionally Libraries/Components/Pressable/Pressable.js 1`] = `
"type ViewStyleProp = $ElementType<React.ElementConfig<typeof View>, \\"style\\">;
export type StateCallbackType = $ReadOnly<{|
Expand DownExpand Up@@ -4268,7 +4287,6 @@ export type ViewProps = $ReadOnly<{|
\\"aria-hidden\\"?: ?boolean,
collapsable?: ?boolean,
collapsableChildren?: ?boolean,
experimental_layoutConformance?: ?(\\"strict\\" | \\"classic\\"),
id?: string,
testID?: ?string,
nativeID?: ?string,
Expand DownExpand Up@@ -9627,6 +9645,7 @@ declare module.exports: {
get Image(): Image,
get ImageBackground(): ImageBackground,
get InputAccessoryView(): InputAccessoryView,
get experimental_LayoutConformance(): LayoutConformance,
get KeyboardAvoidingView(): KeyboardAvoidingView,
get Modal(): Modal,
get Pressable(): Pressable,
Expand Down
7 changes: 0 additions & 7 deletions packages/react-native/React/Views/RCTViewManager.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -424,13 +424,6 @@ - (void)updateAccessibilityTraitsForRole:(RCTView *)view withDefaultView:(RCTVie
// filtered by view configs.
}

RCT_CUSTOM_VIEW_PROPERTY(experimental_layoutConformance, NSString *, RCTView)
{
// Property is only to be used in the new renderer.
// It is necessary to add it here, otherwise it gets
// filtered by view configs.
}

typedef NSArray *FilterArray; // Custom type to make the StaticViewConfigValidator Happy
RCT_CUSTOM_VIEW_PROPERTY(filter, FilterArray, RCTView)
{
Expand Down
1 change: 0 additions & 1 deletion packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line numberDiff line numberDiff line change
Expand Up@@ -4155,7 +4155,6 @@ public class com/facebook/react/uimanager/LayoutShadowNode : com/facebook/react/
public fun setInsetBlock (ILcom/facebook/react/bridge/Dynamic;)V
public fun setInsetInline (ILcom/facebook/react/bridge/Dynamic;)V
public fun setJustifyContent (Ljava/lang/String;)V
public fun setLayoutConformance (Ljava/lang/String;)V
public fun setMarginBlock (ILcom/facebook/react/bridge/Dynamic;)V
public fun setMarginInline (ILcom/facebook/react/bridge/Dynamic;)V
public fun setMargins (ILcom/facebook/react/bridge/Dynamic;)V
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -972,9 +972,4 @@ public void setShouldNotifyPointerLeave(boolean value) {
public void setShouldNotifyPointerMove(boolean value) {
// Do Nothing: Align with static ViewConfigs
}

@ReactProp(name = "experimental_layoutConformance")
public void setLayoutConformance(String value) {
// Do Nothing: Align with static ViewConfigs
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@
#include <react/renderer/components/text/ParagraphComponentDescriptor.h>
#include <react/renderer/components/text/RawTextComponentDescriptor.h>
#include <react/renderer/components/text/TextComponentDescriptor.h>
#include <react/renderer/components/view/LayoutConformanceComponentDescriptor.h>
#include <react/renderer/components/view/ViewComponentDescriptor.h>

namespace facebook::react::CoreComponentsRegistry {
Expand DownExpand Up@@ -66,6 +67,8 @@ sharedProviderRegistry() {
AndroidDrawerLayoutComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
DebuggingOverlayComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
LayoutConformanceComponentDescriptor>());

return providerRegistry;
}();
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -342,16 +342,7 @@ BaseViewProps::BaseViewProps(
rawProps,
"removeClippedSubviews",
sourceProps.removeClippedSubviews,
false)),
experimental_layoutConformance(
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.experimental_layoutConformance
: convertRawProp(
context,
rawProps,
"experimental_layoutConformance",
sourceProps.experimental_layoutConformance,
{})) {}
false)) {}

#define VIEW_EVENT_CASE(eventType) \
case CONSTEXPR_RAW_PROPS_KEY_HASH("on" #eventType): { \
Expand DownExpand Up@@ -397,7 +388,6 @@ void BaseViewProps::setProp(
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsable);
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsableChildren);
RAW_SET_PROP_SWITCH_CASE_BASIC(removeClippedSubviews);
RAW_SET_PROP_SWITCH_CASE_BASIC(experimental_layoutConformance);
RAW_SET_PROP_SWITCH_CASE_BASIC(cursor);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineColor);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineOffset);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,8 +106,6 @@ class BaseViewProps : public YogaStylableProps, public AccessibilityProps {

bool removeClippedSubviews{false};

LayoutConformance experimental_layoutConformance{};

#pragma mark - Convenience Methods

CascadedBorderWidths getBorderWidths() const;
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/LayoutConformanceShadowNode.h>
#include <react/renderer/core/ConcreteComponentDescriptor.h>

namespace facebook::react {

using LayoutConformanceComponentDescriptor =
ConcreteComponentDescriptor<LayoutConformanceShadowNode>;

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/YogaStylableProps.h>
#include <react/renderer/components/view/propsConversions.h>

namespace facebook::react {

struct LayoutConformanceProps final : public YogaStylableProps {
/**
* Whether to layout the subtree with strict conformance to W3C standard
* (YGErrataNone) or for compatibility with legacy RN bugs (YGErrataAll)
*/
LayoutConformance mode{LayoutConformance::Strict};

LayoutConformanceProps() = default;
LayoutConformanceProps(
const PropsParserContext& context,
const LayoutConformanceProps& sourceProps,
const RawProps& rawProps)
: YogaStylableProps(context, sourceProps, rawProps),
mode{convertRawProp(
context,
rawProps,
"mode",
mode,
LayoutConformance::Strict)} {}
};

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/ConcreteViewShadowNode.h>
#include <react/renderer/components/view/LayoutConformanceProps.h>
#include <react/renderer/components/view/YogaLayoutableShadowNode.h>

namespace facebook::react {

constexpr const char LayoutConformanceShadowNodeComponentName[] =
"LayoutConformance";

using LayoutConformanceShadowNode = ConcreteShadowNode<
LayoutConformanceShadowNodeComponentName,
YogaLayoutableShadowNode,
LayoutConformanceProps>;

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,6 +11,7 @@
#include <react/debug/flags.h>
#include <react/debug/react_native_assert.h>
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <react/renderer/components/view/LayoutConformanceShadowNode.h>
#include <react/renderer/components/view/ViewProps.h>
#include <react/renderer/components/view/ViewShadowNode.h>
#include <react/renderer/components/view/conversions.h>
Expand DownExpand Up@@ -501,15 +502,13 @@ void YogaLayoutableShadowNode::configureYogaTree(
}

YGErrata YogaLayoutableShadowNode::resolveErrata(YGErrata defaultErrata) const {
if (auto viewShadowNode = dynamic_cast<const ViewShadowNode*>(this)) {
const auto& props = viewShadowNode->getConcreteProps();
switch (props.experimental_layoutConformance) {
case LayoutConformance::Classic:
return YGErrataAll;
if (auto layoutConformanceNode =
dynamic_cast<const LayoutConformanceShadowNode*>(this)) {
switch (layoutConformanceNode->getConcreteProps().mode) {
case LayoutConformance::Strict:
return YGErrataNone;
case LayoutConformance::Undefined:
return defaultErrata;
case LayoutConformance::Compatibility:
return YGErrataAll;
}
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
/**
* 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.
*
* @format
*/

import type * as React from 'react';

type LayoutConformanceProps = {
/**
* strict: Layout in accordance with W3C spec, even when breaking
* compatibility: Layout with the same behavior as previous versions of React Native
*/
mode: 'strict' | 'compatibility';
children: React.ReactNode;
};

export const experimental_LayoutConformance: React.ComponentType<LayoutConformanceProps>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
/**
* 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
* @oncall react_native
*/

import StyleSheet from '../../StyleSheet/StyleSheet';
import LayoutConformanceNativeComponent from './LayoutConformanceNativeComponent';
import * as React from 'react';

type Props = $ReadOnly<{
/**
* strict: Layout in accordance with W3C spec, even when breaking
* compatibility: Layout with the same behavior as previous versions of React Native
*/
mode: 'strict' | 'compatibility',

children: React.Node,
}>;

// We want a graceful fallback for apps using legacy arch, but need to know
// ahead of time whether the component is available, so we test for global.
// This does not correctly handle mixed arch apps (which is okay, since we just
// degrade the error experience).
const isFabricUIManagerInstalled = global?.nativeFabricUIManager != null;

function LayoutConformance(props: Props): React.Node {
return (
<LayoutConformanceNativeComponent {...props} style={styles.container} />
);
}

function UnimplementedLayoutConformance(props: Props): React.Node {
if (__DEV__) {
const warnOnce = require('../../Utilities/warnOnce');

warnOnce(
'layoutconformance-unsupported',
'"LayoutConformance" is only supported in the New Architecture',
);
}

return props.children;
}

export default (isFabricUIManagerInstalled
? LayoutConformance
: UnimplementedLayoutConformance) as component(...Props);

const styles = StyleSheet.create({
container: {
display: 'contents',
},
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
/**
* 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
*/

import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
import type {ViewProps} from '../View/ViewPropTypes';

import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentRegistry';

type Props = $ReadOnly<{
mode: 'strict' | 'compatibility',
...ViewProps,
}>;

const LayoutConformanceNativeComponent: HostComponent<Props> =
NativeComponentRegistry.get<Props>('LayoutConformance', () => ({
uiViewClassName: 'LayoutConformance',
validAttributes: {
mode: true,
},
}));

export default LayoutConformanceNativeComponent;
Original file line numberDiff line numberDiff line change
Expand Up@@ -211,11 +211,4 @@ export interface ViewProps
* Used to reference react managed views from native code.
*/
nativeID?: string | undefined;

/**
* Contols whether this view, and its transitive children, are laid in a way
* consistent with web browsers ('strict'), or consistent with existing
* React Native code which may rely on incorrect behavior ('classic').
*/
experimental_layoutConformance?: 'strict' | 'classic' | undefined;
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -578,15 +578,6 @@ export type ViewProps = $ReadOnly<{|
*/
collapsableChildren?: ?boolean,

/**
* Contols whether this view, and its transitive children, are laid in a way
* consistent with web browsers ('strict'), or consistent with existing
* React Native code which may rely on incorrect behavior ('classic').
*
* This prop only works when using Fabric.
*/
experimental_layoutConformance?: ?('strict' | 'classic'),

/**
* Used to locate this view from native classes. Has precedence over `nativeID` prop.
*
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -293,8 +293,6 @@ const validAttributesForNonEventProps = {

style: ReactNativeStyleAttributes,

experimental_layoutConformance: true,

// ReactClippingViewManager @ReactProps
removeClippedSubviews: true,

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -357,8 +357,6 @@ const validAttributesForNonEventProps = {
direction: true,

style: ReactNativeStyleAttributes,

experimental_layoutConformance: true,
};

// Props for bubbling and direct events
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -1887,6 +1887,25 @@ declare export default typeof NativeKeyboardObserver;
"
`;

exports[`public API should not change unintentionally Libraries/Components/LayoutConformance/LayoutConformance.js 1`] = `
"type Props = $ReadOnly<{
mode: \\"strict\\" | \\"compatibility\\",
children: React.Node,
}>;
declare export default component(...Props);
"
`;

exports[`public API should not change unintentionally Libraries/Components/LayoutConformance/LayoutConformanceNativeComponent.js 1`] = `
"type Props = $ReadOnly<{
mode: \\"strict\\" | \\"compatibility\\",
...ViewProps,
}>;
declare const LayoutConformanceNativeComponent: HostComponent<Props>;
declare export default typeof LayoutConformanceNativeComponent;
"
`;

exports[`public API should not change unintentionally Libraries/Components/Pressable/Pressable.js 1`] = `
"type ViewStyleProp = $ElementType<React.ElementConfig<typeof View>, \\"style\\">;
export type StateCallbackType = $ReadOnly<{|
Expand DownExpand Up@@ -4268,7 +4287,6 @@ export type ViewProps = $ReadOnly<{|
\\"aria-hidden\\"?: ?boolean,
collapsable?: ?boolean,
collapsableChildren?: ?boolean,
experimental_layoutConformance?: ?(\\"strict\\" | \\"classic\\"),
id?: string,
testID?: ?string,
nativeID?: ?string,
Expand DownExpand Up@@ -9627,6 +9645,7 @@ declare module.exports: {
get Image(): Image,
get ImageBackground(): ImageBackground,
get InputAccessoryView(): InputAccessoryView,
get experimental_LayoutConformance(): LayoutConformance,
get KeyboardAvoidingView(): KeyboardAvoidingView,
get Modal(): Modal,
get Pressable(): Pressable,
Expand Down
7 changes: 0 additions & 7 deletions packages/react-native/React/Views/RCTViewManager.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -424,13 +424,6 @@ - (void)updateAccessibilityTraitsForRole:(RCTView *)view withDefaultView:(RCTVie
// filtered by view configs.
}

RCT_CUSTOM_VIEW_PROPERTY(experimental_layoutConformance, NSString *, RCTView)
{
// Property is only to be used in the new renderer.
// It is necessary to add it here, otherwise it gets
// filtered by view configs.
}

typedef NSArray *FilterArray; // Custom type to make the StaticViewConfigValidator Happy
RCT_CUSTOM_VIEW_PROPERTY(filter, FilterArray, RCTView)
{
Expand Down
1 change: 0 additions & 1 deletion packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line numberDiff line numberDiff line change
Expand Up@@ -4155,7 +4155,6 @@ public class com/facebook/react/uimanager/LayoutShadowNode : com/facebook/react/
public fun setInsetBlock (ILcom/facebook/react/bridge/Dynamic;)V
public fun setInsetInline (ILcom/facebook/react/bridge/Dynamic;)V
public fun setJustifyContent (Ljava/lang/String;)V
public fun setLayoutConformance (Ljava/lang/String;)V
public fun setMarginBlock (ILcom/facebook/react/bridge/Dynamic;)V
public fun setMarginInline (ILcom/facebook/react/bridge/Dynamic;)V
public fun setMargins (ILcom/facebook/react/bridge/Dynamic;)V
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -972,9 +972,4 @@ public void setShouldNotifyPointerLeave(boolean value) {
public void setShouldNotifyPointerMove(boolean value) {
// Do Nothing: Align with static ViewConfigs
}

@ReactProp(name = "experimental_layoutConformance")
public void setLayoutConformance(String value) {
// Do Nothing: Align with static ViewConfigs
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@
#include <react/renderer/components/text/ParagraphComponentDescriptor.h>
#include <react/renderer/components/text/RawTextComponentDescriptor.h>
#include <react/renderer/components/text/TextComponentDescriptor.h>
#include <react/renderer/components/view/LayoutConformanceComponentDescriptor.h>
#include <react/renderer/components/view/ViewComponentDescriptor.h>

namespace facebook::react::CoreComponentsRegistry {
Expand DownExpand Up@@ -66,6 +67,8 @@ sharedProviderRegistry() {
AndroidDrawerLayoutComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
DebuggingOverlayComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
LayoutConformanceComponentDescriptor>());

return providerRegistry;
}();
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -342,16 +342,7 @@ BaseViewProps::BaseViewProps(
rawProps,
"removeClippedSubviews",
sourceProps.removeClippedSubviews,
false)),
experimental_layoutConformance(
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.experimental_layoutConformance
: convertRawProp(
context,
rawProps,
"experimental_layoutConformance",
sourceProps.experimental_layoutConformance,
{})) {}
false)) {}

#define VIEW_EVENT_CASE(eventType) \
case CONSTEXPR_RAW_PROPS_KEY_HASH("on" #eventType): { \
Expand DownExpand Up@@ -397,7 +388,6 @@ void BaseViewProps::setProp(
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsable);
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsableChildren);
RAW_SET_PROP_SWITCH_CASE_BASIC(removeClippedSubviews);
RAW_SET_PROP_SWITCH_CASE_BASIC(experimental_layoutConformance);
RAW_SET_PROP_SWITCH_CASE_BASIC(cursor);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineColor);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineOffset);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,8 +106,6 @@ class BaseViewProps : public YogaStylableProps, public AccessibilityProps {

bool removeClippedSubviews{false};

LayoutConformance experimental_layoutConformance{};

#pragma mark - Convenience Methods

CascadedBorderWidths getBorderWidths() const;
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/LayoutConformanceShadowNode.h>
#include <react/renderer/core/ConcreteComponentDescriptor.h>

namespace facebook::react {

using LayoutConformanceComponentDescriptor =
ConcreteComponentDescriptor<LayoutConformanceShadowNode>;

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/YogaStylableProps.h>
#include <react/renderer/components/view/propsConversions.h>

namespace facebook::react {

struct LayoutConformanceProps final : public YogaStylableProps {
/**
* Whether to layout the subtree with strict conformance to W3C standard
* (YGErrataNone) or for compatibility with legacy RN bugs (YGErrataAll)
*/
LayoutConformance mode{LayoutConformance::Strict};

LayoutConformanceProps() = default;
LayoutConformanceProps(
const PropsParserContext& context,
const LayoutConformanceProps& sourceProps,
const RawProps& rawProps)
: YogaStylableProps(context, sourceProps, rawProps),
mode{convertRawProp(
context,
rawProps,
"mode",
mode,
LayoutConformance::Strict)} {}
};

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/ConcreteViewShadowNode.h>
#include <react/renderer/components/view/LayoutConformanceProps.h>
#include <react/renderer/components/view/YogaLayoutableShadowNode.h>

namespace facebook::react {

constexpr const char LayoutConformanceShadowNodeComponentName[] =
"LayoutConformance";

using LayoutConformanceShadowNode = ConcreteShadowNode<
LayoutConformanceShadowNodeComponentName,
YogaLayoutableShadowNode,
LayoutConformanceProps>;

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,6 +11,7 @@
#include <react/debug/flags.h>
#include <react/debug/react_native_assert.h>
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <react/renderer/components/view/LayoutConformanceShadowNode.h>
#include <react/renderer/components/view/ViewProps.h>
#include <react/renderer/components/view/ViewShadowNode.h>
#include <react/renderer/components/view/conversions.h>
Expand DownExpand Up@@ -501,15 +502,13 @@ void YogaLayoutableShadowNode::configureYogaTree(
}

YGErrata YogaLayoutableShadowNode::resolveErrata(YGErrata defaultErrata) const {
if (auto viewShadowNode = dynamic_cast<const ViewShadowNode*>(this)) {
const auto& props = viewShadowNode->getConcreteProps();
switch (props.experimental_layoutConformance) {
case LayoutConformance::Classic:
return YGErrataAll;
if (auto layoutConformanceNode =
dynamic_cast<const LayoutConformanceShadowNode*>(this)) {
switch (layoutConformanceNode->getConcreteProps().mode) {
case LayoutConformance::Strict:
return YGErrataNone;
case LayoutConformance::Undefined:
return defaultErrata;
case LayoutConformance::Compatibility:
return YGErrataAll;
}
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
/**
* 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.
*
* @format
*/

import type * as React from 'react';

type LayoutConformanceProps = {
/**
* strict: Layout in accordance with W3C spec, even when breaking
* compatibility: Layout with the same behavior as previous versions of React Native
*/
mode: 'strict' | 'compatibility';
children: React.ReactNode;
};

export const experimental_LayoutConformance: React.ComponentType<LayoutConformanceProps>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
/**
* 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
* @oncall react_native
*/

import StyleSheet from '../../StyleSheet/StyleSheet';
import LayoutConformanceNativeComponent from './LayoutConformanceNativeComponent';
import * as React from 'react';

type Props = $ReadOnly<{
/**
* strict: Layout in accordance with W3C spec, even when breaking
* compatibility: Layout with the same behavior as previous versions of React Native
*/
mode: 'strict' | 'compatibility',

children: React.Node,
}>;

// We want a graceful fallback for apps using legacy arch, but need to know
// ahead of time whether the component is available, so we test for global.
// This does not correctly handle mixed arch apps (which is okay, since we just
// degrade the error experience).
const isFabricUIManagerInstalled = global?.nativeFabricUIManager != null;

function LayoutConformance(props: Props): React.Node {
return (
<LayoutConformanceNativeComponent {...props} style={styles.container} />
);
}

function UnimplementedLayoutConformance(props: Props): React.Node {
if (__DEV__) {
const warnOnce = require('../../Utilities/warnOnce');

warnOnce(
'layoutconformance-unsupported',
'"LayoutConformance" is only supported in the New Architecture',
);
}

return props.children;
}

export default (isFabricUIManagerInstalled
? LayoutConformance
: UnimplementedLayoutConformance) as component(...Props);

const styles = StyleSheet.create({
container: {
display: 'contents',
},
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
/**
* 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
*/

import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
import type {ViewProps} from '../View/ViewPropTypes';

import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentRegistry';

type Props = $ReadOnly<{
mode: 'strict' | 'compatibility',
...ViewProps,
}>;

const LayoutConformanceNativeComponent: HostComponent<Props> =
NativeComponentRegistry.get<Props>('LayoutConformance', () => ({
uiViewClassName: 'LayoutConformance',
validAttributes: {
mode: true,
},
}));

export default LayoutConformanceNativeComponent;
Original file line numberDiff line numberDiff line change
Expand Up@@ -211,11 +211,4 @@ export interface ViewProps
* Used to reference react managed views from native code.
*/
nativeID?: string | undefined;

/**
* Contols whether this view, and its transitive children, are laid in a way
* consistent with web browsers ('strict'), or consistent with existing
* React Native code which may rely on incorrect behavior ('classic').
*/
experimental_layoutConformance?: 'strict' | 'classic' | undefined;
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -578,15 +578,6 @@ export type ViewProps = $ReadOnly<{|
*/
collapsableChildren?: ?boolean,

/**
* Contols whether this view, and its transitive children, are laid in a way
* consistent with web browsers ('strict'), or consistent with existing
* React Native code which may rely on incorrect behavior ('classic').
*
* This prop only works when using Fabric.
*/
experimental_layoutConformance?: ?('strict' | 'classic'),

/**
* Used to locate this view from native classes. Has precedence over `nativeID` prop.
*
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -293,8 +293,6 @@ const validAttributesForNonEventProps = {

style: ReactNativeStyleAttributes,

experimental_layoutConformance: true,

// ReactClippingViewManager @ReactProps
removeClippedSubviews: true,

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -357,8 +357,6 @@ const validAttributesForNonEventProps = {
direction: true,

style: ReactNativeStyleAttributes,

experimental_layoutConformance: true,
};

// Props for bubbling and direct events
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -1887,6 +1887,25 @@ declare export default typeof NativeKeyboardObserver;
"
`;

exports[`public API should not change unintentionally Libraries/Components/LayoutConformance/LayoutConformance.js 1`] = `
"type Props = $ReadOnly<{
mode: \\"strict\\" | \\"compatibility\\",
children: React.Node,
}>;
declare export default component(...Props);
"
`;

exports[`public API should not change unintentionally Libraries/Components/LayoutConformance/LayoutConformanceNativeComponent.js 1`] = `
"type Props = $ReadOnly<{
mode: \\"strict\\" | \\"compatibility\\",
...ViewProps,
}>;
declare const LayoutConformanceNativeComponent: HostComponent<Props>;
declare export default typeof LayoutConformanceNativeComponent;
"
`;

exports[`public API should not change unintentionally Libraries/Components/Pressable/Pressable.js 1`] = `
"type ViewStyleProp = $ElementType<React.ElementConfig<typeof View>, \\"style\\">;
export type StateCallbackType = $ReadOnly<{|
Expand DownExpand Up@@ -4268,7 +4287,6 @@ export type ViewProps = $ReadOnly<{|
\\"aria-hidden\\"?: ?boolean,
collapsable?: ?boolean,
collapsableChildren?: ?boolean,
experimental_layoutConformance?: ?(\\"strict\\" | \\"classic\\"),
id?: string,
testID?: ?string,
nativeID?: ?string,
Expand DownExpand Up@@ -9627,6 +9645,7 @@ declare module.exports: {
get Image(): Image,
get ImageBackground(): ImageBackground,
get InputAccessoryView(): InputAccessoryView,
get experimental_LayoutConformance(): LayoutConformance,
get KeyboardAvoidingView(): KeyboardAvoidingView,
get Modal(): Modal,
get Pressable(): Pressable,
Expand Down
7 changes: 0 additions & 7 deletions packages/react-native/React/Views/RCTViewManager.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -424,13 +424,6 @@ - (void)updateAccessibilityTraitsForRole:(RCTView *)view withDefaultView:(RCTVie
// filtered by view configs.
}

RCT_CUSTOM_VIEW_PROPERTY(experimental_layoutConformance, NSString *, RCTView)
{
// Property is only to be used in the new renderer.
// It is necessary to add it here, otherwise it gets
// filtered by view configs.
}

typedef NSArray *FilterArray; // Custom type to make the StaticViewConfigValidator Happy
RCT_CUSTOM_VIEW_PROPERTY(filter, FilterArray, RCTView)
{
Expand Down
1 change: 0 additions & 1 deletion packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line numberDiff line numberDiff line change
Expand Up@@ -4155,7 +4155,6 @@ public class com/facebook/react/uimanager/LayoutShadowNode : com/facebook/react/
public fun setInsetBlock (ILcom/facebook/react/bridge/Dynamic;)V
public fun setInsetInline (ILcom/facebook/react/bridge/Dynamic;)V
public fun setJustifyContent (Ljava/lang/String;)V
public fun setLayoutConformance (Ljava/lang/String;)V
public fun setMarginBlock (ILcom/facebook/react/bridge/Dynamic;)V
public fun setMarginInline (ILcom/facebook/react/bridge/Dynamic;)V
public fun setMargins (ILcom/facebook/react/bridge/Dynamic;)V
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -972,9 +972,4 @@ public void setShouldNotifyPointerLeave(boolean value) {
public void setShouldNotifyPointerMove(boolean value) {
// Do Nothing: Align with static ViewConfigs
}

@ReactProp(name = "experimental_layoutConformance")
public void setLayoutConformance(String value) {
// Do Nothing: Align with static ViewConfigs
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@
#include <react/renderer/components/text/ParagraphComponentDescriptor.h>
#include <react/renderer/components/text/RawTextComponentDescriptor.h>
#include <react/renderer/components/text/TextComponentDescriptor.h>
#include <react/renderer/components/view/LayoutConformanceComponentDescriptor.h>
#include <react/renderer/components/view/ViewComponentDescriptor.h>

namespace facebook::react::CoreComponentsRegistry {
Expand DownExpand Up@@ -66,6 +67,8 @@ sharedProviderRegistry() {
AndroidDrawerLayoutComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
DebuggingOverlayComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
LayoutConformanceComponentDescriptor>());

return providerRegistry;
}();
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -342,16 +342,7 @@ BaseViewProps::BaseViewProps(
rawProps,
"removeClippedSubviews",
sourceProps.removeClippedSubviews,
false)),
experimental_layoutConformance(
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.experimental_layoutConformance
: convertRawProp(
context,
rawProps,
"experimental_layoutConformance",
sourceProps.experimental_layoutConformance,
{})) {}
false)) {}

#define VIEW_EVENT_CASE(eventType) \
case CONSTEXPR_RAW_PROPS_KEY_HASH("on" #eventType): { \
Expand DownExpand Up@@ -397,7 +388,6 @@ void BaseViewProps::setProp(
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsable);
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsableChildren);
RAW_SET_PROP_SWITCH_CASE_BASIC(removeClippedSubviews);
RAW_SET_PROP_SWITCH_CASE_BASIC(experimental_layoutConformance);
RAW_SET_PROP_SWITCH_CASE_BASIC(cursor);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineColor);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineOffset);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,8 +106,6 @@ class BaseViewProps : public YogaStylableProps, public AccessibilityProps {

bool removeClippedSubviews{false};

LayoutConformance experimental_layoutConformance{};

#pragma mark - Convenience Methods

CascadedBorderWidths getBorderWidths() const;
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/LayoutConformanceShadowNode.h>
#include <react/renderer/core/ConcreteComponentDescriptor.h>

namespace facebook::react {

using LayoutConformanceComponentDescriptor =
ConcreteComponentDescriptor<LayoutConformanceShadowNode>;

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/YogaStylableProps.h>
#include <react/renderer/components/view/propsConversions.h>

namespace facebook::react {

struct LayoutConformanceProps final : public YogaStylableProps {
/**
* Whether to layout the subtree with strict conformance to W3C standard
* (YGErrataNone) or for compatibility with legacy RN bugs (YGErrataAll)
*/
LayoutConformance mode{LayoutConformance::Strict};

LayoutConformanceProps() = default;
LayoutConformanceProps(
const PropsParserContext& context,
const LayoutConformanceProps& sourceProps,
const RawProps& rawProps)
: YogaStylableProps(context, sourceProps, rawProps),
mode{convertRawProp(
context,
rawProps,
"mode",
mode,
LayoutConformance::Strict)} {}
};

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/ConcreteViewShadowNode.h>
#include <react/renderer/components/view/LayoutConformanceProps.h>
#include <react/renderer/components/view/YogaLayoutableShadowNode.h>

namespace facebook::react {

constexpr const char LayoutConformanceShadowNodeComponentName[] =
"LayoutConformance";

using LayoutConformanceShadowNode = ConcreteShadowNode<
LayoutConformanceShadowNodeComponentName,
YogaLayoutableShadowNode,
LayoutConformanceProps>;

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,6 +11,7 @@
#include <react/debug/flags.h>
#include <react/debug/react_native_assert.h>
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <react/renderer/components/view/LayoutConformanceShadowNode.h>
#include <react/renderer/components/view/ViewProps.h>
#include <react/renderer/components/view/ViewShadowNode.h>
#include <react/renderer/components/view/conversions.h>
Expand DownExpand Up@@ -501,15 +502,13 @@ void YogaLayoutableShadowNode::configureYogaTree(
}

YGErrata YogaLayoutableShadowNode::resolveErrata(YGErrata defaultErrata) const {
if (auto viewShadowNode = dynamic_cast<const ViewShadowNode*>(this)) {
const auto& props = viewShadowNode->getConcreteProps();
switch (props.experimental_layoutConformance) {
case LayoutConformance::Classic:
return YGErrataAll;
if (auto layoutConformanceNode =
dynamic_cast<const LayoutConformanceShadowNode*>(this)) {
switch (layoutConformanceNode->getConcreteProps().mode) {
case LayoutConformance::Strict:
return YGErrataNone;
case LayoutConformance::Undefined:
return defaultErrata;
case LayoutConformance::Compatibility:
return YGErrataAll;
}
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
/**
* 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.
*
* @format
*/

import type * as React from 'react';

type LayoutConformanceProps = {
/**
* strict: Layout in accordance with W3C spec, even when breaking
* compatibility: Layout with the same behavior as previous versions of React Native
*/
mode: 'strict' | 'compatibility';
children: React.ReactNode;
};

export const experimental_LayoutConformance: React.ComponentType<LayoutConformanceProps>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
/**
* 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
* @oncall react_native
*/

import StyleSheet from '../../StyleSheet/StyleSheet';
import LayoutConformanceNativeComponent from './LayoutConformanceNativeComponent';
import * as React from 'react';

type Props = $ReadOnly<{
/**
* strict: Layout in accordance with W3C spec, even when breaking
* compatibility: Layout with the same behavior as previous versions of React Native
*/
mode: 'strict' | 'compatibility',

children: React.Node,
}>;

// We want a graceful fallback for apps using legacy arch, but need to know
// ahead of time whether the component is available, so we test for global.
// This does not correctly handle mixed arch apps (which is okay, since we just
// degrade the error experience).
const isFabricUIManagerInstalled = global?.nativeFabricUIManager != null;

function LayoutConformance(props: Props): React.Node {
return (
<LayoutConformanceNativeComponent {...props} style={styles.container} />
);
}

function UnimplementedLayoutConformance(props: Props): React.Node {
if (__DEV__) {
const warnOnce = require('../../Utilities/warnOnce');

warnOnce(
'layoutconformance-unsupported',
'"LayoutConformance" is only supported in the New Architecture',
);
}

return props.children;
}

export default (isFabricUIManagerInstalled
? LayoutConformance
: UnimplementedLayoutConformance) as component(...Props);

const styles = StyleSheet.create({
container: {
display: 'contents',
},
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
/**
* 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
*/

import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
import type {ViewProps} from '../View/ViewPropTypes';

import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentRegistry';

type Props = $ReadOnly<{
mode: 'strict' | 'compatibility',
...ViewProps,
}>;

const LayoutConformanceNativeComponent: HostComponent<Props> =
NativeComponentRegistry.get<Props>('LayoutConformance', () => ({
uiViewClassName: 'LayoutConformance',
validAttributes: {
mode: true,
},
}));

export default LayoutConformanceNativeComponent;
Original file line numberDiff line numberDiff line change
Expand Up@@ -211,11 +211,4 @@ export interface ViewProps
* Used to reference react managed views from native code.
*/
nativeID?: string | undefined;

/**
* Contols whether this view, and its transitive children, are laid in a way
* consistent with web browsers ('strict'), or consistent with existing
* React Native code which may rely on incorrect behavior ('classic').
*/
experimental_layoutConformance?: 'strict' | 'classic' | undefined;
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -578,15 +578,6 @@ export type ViewProps = $ReadOnly<{|
*/
collapsableChildren?: ?boolean,

/**
* Contols whether this view, and its transitive children, are laid in a way
* consistent with web browsers ('strict'), or consistent with existing
* React Native code which may rely on incorrect behavior ('classic').
*
* This prop only works when using Fabric.
*/
experimental_layoutConformance?: ?('strict' | 'classic'),

/**
* Used to locate this view from native classes. Has precedence over `nativeID` prop.
*
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -293,8 +293,6 @@ const validAttributesForNonEventProps = {

style: ReactNativeStyleAttributes,

experimental_layoutConformance: true,

// ReactClippingViewManager @ReactProps
removeClippedSubviews: true,

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -357,8 +357,6 @@ const validAttributesForNonEventProps = {
direction: true,

style: ReactNativeStyleAttributes,

experimental_layoutConformance: true,
};

// Props for bubbling and direct events
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -1887,6 +1887,25 @@ declare export default typeof NativeKeyboardObserver;
"
`;

exports[`public API should not change unintentionally Libraries/Components/LayoutConformance/LayoutConformance.js 1`] = `
"type Props = $ReadOnly<{
mode: \\"strict\\" | \\"compatibility\\",
children: React.Node,
}>;
declare export default component(...Props);
"
`;

exports[`public API should not change unintentionally Libraries/Components/LayoutConformance/LayoutConformanceNativeComponent.js 1`] = `
"type Props = $ReadOnly<{
mode: \\"strict\\" | \\"compatibility\\",
...ViewProps,
}>;
declare const LayoutConformanceNativeComponent: HostComponent<Props>;
declare export default typeof LayoutConformanceNativeComponent;
"
`;

exports[`public API should not change unintentionally Libraries/Components/Pressable/Pressable.js 1`] = `
"type ViewStyleProp = $ElementType<React.ElementConfig<typeof View>, \\"style\\">;
export type StateCallbackType = $ReadOnly<{|
Expand DownExpand Up@@ -4268,7 +4287,6 @@ export type ViewProps = $ReadOnly<{|
\\"aria-hidden\\"?: ?boolean,
collapsable?: ?boolean,
collapsableChildren?: ?boolean,
experimental_layoutConformance?: ?(\\"strict\\" | \\"classic\\"),
id?: string,
testID?: ?string,
nativeID?: ?string,
Expand DownExpand Up@@ -9627,6 +9645,7 @@ declare module.exports: {
get Image(): Image,
get ImageBackground(): ImageBackground,
get InputAccessoryView(): InputAccessoryView,
get experimental_LayoutConformance(): LayoutConformance,
get KeyboardAvoidingView(): KeyboardAvoidingView,
get Modal(): Modal,
get Pressable(): Pressable,
Expand Down
7 changes: 0 additions & 7 deletions packages/react-native/React/Views/RCTViewManager.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -424,13 +424,6 @@ - (void)updateAccessibilityTraitsForRole:(RCTView *)view withDefaultView:(RCTVie
// filtered by view configs.
}

RCT_CUSTOM_VIEW_PROPERTY(experimental_layoutConformance, NSString *, RCTView)
{
// Property is only to be used in the new renderer.
// It is necessary to add it here, otherwise it gets
// filtered by view configs.
}

typedef NSArray *FilterArray; // Custom type to make the StaticViewConfigValidator Happy
RCT_CUSTOM_VIEW_PROPERTY(filter, FilterArray, RCTView)
{
Expand Down
1 change: 0 additions & 1 deletion packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line numberDiff line numberDiff line change
Expand Up@@ -4155,7 +4155,6 @@ public class com/facebook/react/uimanager/LayoutShadowNode : com/facebook/react/
public fun setInsetBlock (ILcom/facebook/react/bridge/Dynamic;)V
public fun setInsetInline (ILcom/facebook/react/bridge/Dynamic;)V
public fun setJustifyContent (Ljava/lang/String;)V
public fun setLayoutConformance (Ljava/lang/String;)V
public fun setMarginBlock (ILcom/facebook/react/bridge/Dynamic;)V
public fun setMarginInline (ILcom/facebook/react/bridge/Dynamic;)V
public fun setMargins (ILcom/facebook/react/bridge/Dynamic;)V
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -972,9 +972,4 @@ public void setShouldNotifyPointerLeave(boolean value) {
public void setShouldNotifyPointerMove(boolean value) {
// Do Nothing: Align with static ViewConfigs
}

@ReactProp(name = "experimental_layoutConformance")
public void setLayoutConformance(String value) {
// Do Nothing: Align with static ViewConfigs
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@
#include <react/renderer/components/text/ParagraphComponentDescriptor.h>
#include <react/renderer/components/text/RawTextComponentDescriptor.h>
#include <react/renderer/components/text/TextComponentDescriptor.h>
#include <react/renderer/components/view/LayoutConformanceComponentDescriptor.h>
#include <react/renderer/components/view/ViewComponentDescriptor.h>

namespace facebook::react::CoreComponentsRegistry {
Expand DownExpand Up@@ -66,6 +67,8 @@ sharedProviderRegistry() {
AndroidDrawerLayoutComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
DebuggingOverlayComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
LayoutConformanceComponentDescriptor>());

return providerRegistry;
}();
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -342,16 +342,7 @@ BaseViewProps::BaseViewProps(
rawProps,
"removeClippedSubviews",
sourceProps.removeClippedSubviews,
false)),
experimental_layoutConformance(
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.experimental_layoutConformance
: convertRawProp(
context,
rawProps,
"experimental_layoutConformance",
sourceProps.experimental_layoutConformance,
{})) {}
false)) {}

#define VIEW_EVENT_CASE(eventType) \
case CONSTEXPR_RAW_PROPS_KEY_HASH("on" #eventType): { \
Expand DownExpand Up@@ -397,7 +388,6 @@ void BaseViewProps::setProp(
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsable);
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsableChildren);
RAW_SET_PROP_SWITCH_CASE_BASIC(removeClippedSubviews);
RAW_SET_PROP_SWITCH_CASE_BASIC(experimental_layoutConformance);
RAW_SET_PROP_SWITCH_CASE_BASIC(cursor);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineColor);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineOffset);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,8 +106,6 @@ class BaseViewProps : public YogaStylableProps, public AccessibilityProps {

bool removeClippedSubviews{false};

LayoutConformance experimental_layoutConformance{};

#pragma mark - Convenience Methods

CascadedBorderWidths getBorderWidths() const;
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/LayoutConformanceShadowNode.h>
#include <react/renderer/core/ConcreteComponentDescriptor.h>

namespace facebook::react {

using LayoutConformanceComponentDescriptor =
ConcreteComponentDescriptor<LayoutConformanceShadowNode>;

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/YogaStylableProps.h>
#include <react/renderer/components/view/propsConversions.h>

namespace facebook::react {

struct LayoutConformanceProps final : public YogaStylableProps {
/**
* Whether to layout the subtree with strict conformance to W3C standard
* (YGErrataNone) or for compatibility with legacy RN bugs (YGErrataAll)
*/
LayoutConformance mode{LayoutConformance::Strict};

LayoutConformanceProps() = default;
LayoutConformanceProps(
const PropsParserContext& context,
const LayoutConformanceProps& sourceProps,
const RawProps& rawProps)
: YogaStylableProps(context, sourceProps, rawProps),
mode{convertRawProp(
context,
rawProps,
"mode",
mode,
LayoutConformance::Strict)} {}
};

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/ConcreteViewShadowNode.h>
#include <react/renderer/components/view/LayoutConformanceProps.h>
#include <react/renderer/components/view/YogaLayoutableShadowNode.h>

namespace facebook::react {

constexpr const char LayoutConformanceShadowNodeComponentName[] =
"LayoutConformance";

using LayoutConformanceShadowNode = ConcreteShadowNode<
LayoutConformanceShadowNodeComponentName,
YogaLayoutableShadowNode,
LayoutConformanceProps>;

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,6 +11,7 @@
#include <react/debug/flags.h>
#include <react/debug/react_native_assert.h>
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <react/renderer/components/view/LayoutConformanceShadowNode.h>
#include <react/renderer/components/view/ViewProps.h>
#include <react/renderer/components/view/ViewShadowNode.h>
#include <react/renderer/components/view/conversions.h>
Expand DownExpand Up@@ -501,15 +502,13 @@ void YogaLayoutableShadowNode::configureYogaTree(
}

YGErrata YogaLayoutableShadowNode::resolveErrata(YGErrata defaultErrata) const {
if (auto viewShadowNode = dynamic_cast<const ViewShadowNode*>(this)) {
const auto& props = viewShadowNode->getConcreteProps();
switch (props.experimental_layoutConformance) {
case LayoutConformance::Classic:
return YGErrataAll;
if (auto layoutConformanceNode =
dynamic_cast<const LayoutConformanceShadowNode*>(this)) {
switch (layoutConformanceNode->getConcreteProps().mode) {
case LayoutConformance::Strict:
return YGErrataNone;
case LayoutConformance::Undefined:
return defaultErrata;
case LayoutConformance::Compatibility:
return YGErrataAll;
}
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
/**
* 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.
*
* @format
*/

import type * as React from 'react';

type LayoutConformanceProps = {
/**
* strict: Layout in accordance with W3C spec, even when breaking
* compatibility: Layout with the same behavior as previous versions of React Native
*/
mode: 'strict' | 'compatibility';
children: React.ReactNode;
};

export const experimental_LayoutConformance: React.ComponentType<LayoutConformanceProps>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
/**
* 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
* @oncall react_native
*/

import StyleSheet from '../../StyleSheet/StyleSheet';
import LayoutConformanceNativeComponent from './LayoutConformanceNativeComponent';
import * as React from 'react';

type Props = $ReadOnly<{
/**
* strict: Layout in accordance with W3C spec, even when breaking
* compatibility: Layout with the same behavior as previous versions of React Native
*/
mode: 'strict' | 'compatibility',

children: React.Node,
}>;

// We want a graceful fallback for apps using legacy arch, but need to know
// ahead of time whether the component is available, so we test for global.
// This does not correctly handle mixed arch apps (which is okay, since we just
// degrade the error experience).
const isFabricUIManagerInstalled = global?.nativeFabricUIManager != null;

function LayoutConformance(props: Props): React.Node {
return (
<LayoutConformanceNativeComponent {...props} style={styles.container} />
);
}

function UnimplementedLayoutConformance(props: Props): React.Node {
if (__DEV__) {
const warnOnce = require('../../Utilities/warnOnce');

warnOnce(
'layoutconformance-unsupported',
'"LayoutConformance" is only supported in the New Architecture',
);
}

return props.children;
}

export default (isFabricUIManagerInstalled
? LayoutConformance
: UnimplementedLayoutConformance) as component(...Props);

const styles = StyleSheet.create({
container: {
display: 'contents',
},
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
/**
* 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
*/

import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
import type {ViewProps} from '../View/ViewPropTypes';

import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentRegistry';

type Props = $ReadOnly<{
mode: 'strict' | 'compatibility',
...ViewProps,
}>;

const LayoutConformanceNativeComponent: HostComponent<Props> =
NativeComponentRegistry.get<Props>('LayoutConformance', () => ({
uiViewClassName: 'LayoutConformance',
validAttributes: {
mode: true,
},
}));

export default LayoutConformanceNativeComponent;
Original file line numberDiff line numberDiff line change
Expand Up@@ -211,11 +211,4 @@ export interface ViewProps
* Used to reference react managed views from native code.
*/
nativeID?: string | undefined;

/**
* Contols whether this view, and its transitive children, are laid in a way
* consistent with web browsers ('strict'), or consistent with existing
* React Native code which may rely on incorrect behavior ('classic').
*/
experimental_layoutConformance?: 'strict' | 'classic' | undefined;
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -578,15 +578,6 @@ export type ViewProps = $ReadOnly<{|
*/
collapsableChildren?: ?boolean,

/**
* Contols whether this view, and its transitive children, are laid in a way
* consistent with web browsers ('strict'), or consistent with existing
* React Native code which may rely on incorrect behavior ('classic').
*
* This prop only works when using Fabric.
*/
experimental_layoutConformance?: ?('strict' | 'classic'),

/**
* Used to locate this view from native classes. Has precedence over `nativeID` prop.
*
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -293,8 +293,6 @@ const validAttributesForNonEventProps = {

style: ReactNativeStyleAttributes,

experimental_layoutConformance: true,

// ReactClippingViewManager @ReactProps
removeClippedSubviews: true,

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -357,8 +357,6 @@ const validAttributesForNonEventProps = {
direction: true,

style: ReactNativeStyleAttributes,

experimental_layoutConformance: true,
};

// Props for bubbling and direct events
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -1887,6 +1887,25 @@ declare export default typeof NativeKeyboardObserver;
"
`;

exports[`public API should not change unintentionally Libraries/Components/LayoutConformance/LayoutConformance.js 1`] = `
"type Props = $ReadOnly<{
mode: \\"strict\\" | \\"compatibility\\",
children: React.Node,
}>;
declare export default component(...Props);
"
`;

exports[`public API should not change unintentionally Libraries/Components/LayoutConformance/LayoutConformanceNativeComponent.js 1`] = `
"type Props = $ReadOnly<{
mode: \\"strict\\" | \\"compatibility\\",
...ViewProps,
}>;
declare const LayoutConformanceNativeComponent: HostComponent<Props>;
declare export default typeof LayoutConformanceNativeComponent;
"
`;

exports[`public API should not change unintentionally Libraries/Components/Pressable/Pressable.js 1`] = `
"type ViewStyleProp = $ElementType<React.ElementConfig<typeof View>, \\"style\\">;
export type StateCallbackType = $ReadOnly<{|
Expand DownExpand Up@@ -4268,7 +4287,6 @@ export type ViewProps = $ReadOnly<{|
\\"aria-hidden\\"?: ?boolean,
collapsable?: ?boolean,
collapsableChildren?: ?boolean,
experimental_layoutConformance?: ?(\\"strict\\" | \\"classic\\"),
id?: string,
testID?: ?string,
nativeID?: ?string,
Expand DownExpand Up@@ -9627,6 +9645,7 @@ declare module.exports: {
get Image(): Image,
get ImageBackground(): ImageBackground,
get InputAccessoryView(): InputAccessoryView,
get experimental_LayoutConformance(): LayoutConformance,
get KeyboardAvoidingView(): KeyboardAvoidingView,
get Modal(): Modal,
get Pressable(): Pressable,
Expand Down
7 changes: 0 additions & 7 deletions packages/react-native/React/Views/RCTViewManager.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -424,13 +424,6 @@ - (void)updateAccessibilityTraitsForRole:(RCTView *)view withDefaultView:(RCTVie
// filtered by view configs.
}

RCT_CUSTOM_VIEW_PROPERTY(experimental_layoutConformance, NSString *, RCTView)
{
// Property is only to be used in the new renderer.
// It is necessary to add it here, otherwise it gets
// filtered by view configs.
}

typedef NSArray *FilterArray; // Custom type to make the StaticViewConfigValidator Happy
RCT_CUSTOM_VIEW_PROPERTY(filter, FilterArray, RCTView)
{
Expand Down
1 change: 0 additions & 1 deletion packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line numberDiff line numberDiff line change
Expand Up@@ -4155,7 +4155,6 @@ public class com/facebook/react/uimanager/LayoutShadowNode : com/facebook/react/
public fun setInsetBlock (ILcom/facebook/react/bridge/Dynamic;)V
public fun setInsetInline (ILcom/facebook/react/bridge/Dynamic;)V
public fun setJustifyContent (Ljava/lang/String;)V
public fun setLayoutConformance (Ljava/lang/String;)V
public fun setMarginBlock (ILcom/facebook/react/bridge/Dynamic;)V
public fun setMarginInline (ILcom/facebook/react/bridge/Dynamic;)V
public fun setMargins (ILcom/facebook/react/bridge/Dynamic;)V
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -972,9 +972,4 @@ public void setShouldNotifyPointerLeave(boolean value) {
public void setShouldNotifyPointerMove(boolean value) {
// Do Nothing: Align with static ViewConfigs
}

@ReactProp(name = "experimental_layoutConformance")
public void setLayoutConformance(String value) {
// Do Nothing: Align with static ViewConfigs
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@
#include <react/renderer/components/text/ParagraphComponentDescriptor.h>
#include <react/renderer/components/text/RawTextComponentDescriptor.h>
#include <react/renderer/components/text/TextComponentDescriptor.h>
#include <react/renderer/components/view/LayoutConformanceComponentDescriptor.h>
#include <react/renderer/components/view/ViewComponentDescriptor.h>

namespace facebook::react::CoreComponentsRegistry {
Expand DownExpand Up@@ -66,6 +67,8 @@ sharedProviderRegistry() {
AndroidDrawerLayoutComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
DebuggingOverlayComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
LayoutConformanceComponentDescriptor>());

return providerRegistry;
}();
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -342,16 +342,7 @@ BaseViewProps::BaseViewProps(
rawProps,
"removeClippedSubviews",
sourceProps.removeClippedSubviews,
false)),
experimental_layoutConformance(
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.experimental_layoutConformance
: convertRawProp(
context,
rawProps,
"experimental_layoutConformance",
sourceProps.experimental_layoutConformance,
{})) {}
false)) {}

#define VIEW_EVENT_CASE(eventType) \
case CONSTEXPR_RAW_PROPS_KEY_HASH("on" #eventType): { \
Expand DownExpand Up@@ -397,7 +388,6 @@ void BaseViewProps::setProp(
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsable);
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsableChildren);
RAW_SET_PROP_SWITCH_CASE_BASIC(removeClippedSubviews);
RAW_SET_PROP_SWITCH_CASE_BASIC(experimental_layoutConformance);
RAW_SET_PROP_SWITCH_CASE_BASIC(cursor);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineColor);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineOffset);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,8 +106,6 @@ class BaseViewProps : public YogaStylableProps, public AccessibilityProps {

bool removeClippedSubviews{false};

LayoutConformance experimental_layoutConformance{};

#pragma mark - Convenience Methods

CascadedBorderWidths getBorderWidths() const;
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/LayoutConformanceShadowNode.h>
#include <react/renderer/core/ConcreteComponentDescriptor.h>

namespace facebook::react {

using LayoutConformanceComponentDescriptor =
ConcreteComponentDescriptor<LayoutConformanceShadowNode>;

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/YogaStylableProps.h>
#include <react/renderer/components/view/propsConversions.h>

namespace facebook::react {

struct LayoutConformanceProps final : public YogaStylableProps {
/**
* Whether to layout the subtree with strict conformance to W3C standard
* (YGErrataNone) or for compatibility with legacy RN bugs (YGErrataAll)
*/
LayoutConformance mode{LayoutConformance::Strict};

LayoutConformanceProps() = default;
LayoutConformanceProps(
const PropsParserContext& context,
const LayoutConformanceProps& sourceProps,
const RawProps& rawProps)
: YogaStylableProps(context, sourceProps, rawProps),
mode{convertRawProp(
context,
rawProps,
"mode",
mode,
LayoutConformance::Strict)} {}
};

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/ConcreteViewShadowNode.h>
#include <react/renderer/components/view/LayoutConformanceProps.h>
#include <react/renderer/components/view/YogaLayoutableShadowNode.h>

namespace facebook::react {

constexpr const char LayoutConformanceShadowNodeComponentName[] =
"LayoutConformance";

using LayoutConformanceShadowNode = ConcreteShadowNode<
LayoutConformanceShadowNodeComponentName,
YogaLayoutableShadowNode,
LayoutConformanceProps>;

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,6 +11,7 @@
#include <react/debug/flags.h>
#include <react/debug/react_native_assert.h>
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <react/renderer/components/view/LayoutConformanceShadowNode.h>
#include <react/renderer/components/view/ViewProps.h>
#include <react/renderer/components/view/ViewShadowNode.h>
#include <react/renderer/components/view/conversions.h>
Expand DownExpand Up@@ -501,15 +502,13 @@ void YogaLayoutableShadowNode::configureYogaTree(
}

YGErrata YogaLayoutableShadowNode::resolveErrata(YGErrata defaultErrata) const {
if (auto viewShadowNode = dynamic_cast<const ViewShadowNode*>(this)) {
const auto& props = viewShadowNode->getConcreteProps();
switch (props.experimental_layoutConformance) {
case LayoutConformance::Classic:
return YGErrataAll;
if (auto layoutConformanceNode =
dynamic_cast<const LayoutConformanceShadowNode*>(this)) {
switch (layoutConformanceNode->getConcreteProps().mode) {
case LayoutConformance::Strict:
return YGErrataNone;
case LayoutConformance::Undefined:
return defaultErrata;
case LayoutConformance::Compatibility:
return YGErrataAll;
}
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
/**
* 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.
*
* @format
*/

import type * as React from 'react';

type LayoutConformanceProps = {
/**
* strict: Layout in accordance with W3C spec, even when breaking
* compatibility: Layout with the same behavior as previous versions of React Native
*/
mode: 'strict' | 'compatibility';
children: React.ReactNode;
};

export const experimental_LayoutConformance: React.ComponentType<LayoutConformanceProps>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
/**
* 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
* @oncall react_native
*/

import StyleSheet from '../../StyleSheet/StyleSheet';
import LayoutConformanceNativeComponent from './LayoutConformanceNativeComponent';
import * as React from 'react';

type Props = $ReadOnly<{
/**
* strict: Layout in accordance with W3C spec, even when breaking
* compatibility: Layout with the same behavior as previous versions of React Native
*/
mode: 'strict' | 'compatibility',

children: React.Node,
}>;

// We want a graceful fallback for apps using legacy arch, but need to know
// ahead of time whether the component is available, so we test for global.
// This does not correctly handle mixed arch apps (which is okay, since we just
// degrade the error experience).
const isFabricUIManagerInstalled = global?.nativeFabricUIManager != null;

function LayoutConformance(props: Props): React.Node {
return (
<LayoutConformanceNativeComponent {...props} style={styles.container} />
);
}

function UnimplementedLayoutConformance(props: Props): React.Node {
if (__DEV__) {
const warnOnce = require('../../Utilities/warnOnce');

warnOnce(
'layoutconformance-unsupported',
'"LayoutConformance" is only supported in the New Architecture',
);
}

return props.children;
}

export default (isFabricUIManagerInstalled
? LayoutConformance
: UnimplementedLayoutConformance) as component(...Props);

const styles = StyleSheet.create({
container: {
display: 'contents',
},
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
/**
* 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
*/

import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
import type {ViewProps} from '../View/ViewPropTypes';

import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentRegistry';

type Props = $ReadOnly<{
mode: 'strict' | 'compatibility',
...ViewProps,
}>;

const LayoutConformanceNativeComponent: HostComponent<Props> =
NativeComponentRegistry.get<Props>('LayoutConformance', () => ({
uiViewClassName: 'LayoutConformance',
validAttributes: {
mode: true,
},
}));

export default LayoutConformanceNativeComponent;
Original file line numberDiff line numberDiff line change
Expand Up@@ -211,11 +211,4 @@ export interface ViewProps
* Used to reference react managed views from native code.
*/
nativeID?: string | undefined;

/**
* Contols whether this view, and its transitive children, are laid in a way
* consistent with web browsers ('strict'), or consistent with existing
* React Native code which may rely on incorrect behavior ('classic').
*/
experimental_layoutConformance?: 'strict' | 'classic' | undefined;
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -578,15 +578,6 @@ export type ViewProps = $ReadOnly<{|
*/
collapsableChildren?: ?boolean,

/**
* Contols whether this view, and its transitive children, are laid in a way
* consistent with web browsers ('strict'), or consistent with existing
* React Native code which may rely on incorrect behavior ('classic').
*
* This prop only works when using Fabric.
*/
experimental_layoutConformance?: ?('strict' | 'classic'),

/**
* Used to locate this view from native classes. Has precedence over `nativeID` prop.
*
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -293,8 +293,6 @@ const validAttributesForNonEventProps = {

style: ReactNativeStyleAttributes,

experimental_layoutConformance: true,

// ReactClippingViewManager @ReactProps
removeClippedSubviews: true,

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -357,8 +357,6 @@ const validAttributesForNonEventProps = {
direction: true,

style: ReactNativeStyleAttributes,

experimental_layoutConformance: true,
};

// Props for bubbling and direct events
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -1887,6 +1887,25 @@ declare export default typeof NativeKeyboardObserver;
"
`;

exports[`public API should not change unintentionally Libraries/Components/LayoutConformance/LayoutConformance.js 1`] = `
"type Props = $ReadOnly<{
mode: \\"strict\\" | \\"compatibility\\",
children: React.Node,
}>;
declare export default component(...Props);
"
`;

exports[`public API should not change unintentionally Libraries/Components/LayoutConformance/LayoutConformanceNativeComponent.js 1`] = `
"type Props = $ReadOnly<{
mode: \\"strict\\" | \\"compatibility\\",
...ViewProps,
}>;
declare const LayoutConformanceNativeComponent: HostComponent<Props>;
declare export default typeof LayoutConformanceNativeComponent;
"
`;

exports[`public API should not change unintentionally Libraries/Components/Pressable/Pressable.js 1`] = `
"type ViewStyleProp = $ElementType<React.ElementConfig<typeof View>, \\"style\\">;
export type StateCallbackType = $ReadOnly<{|
Expand DownExpand Up@@ -4268,7 +4287,6 @@ export type ViewProps = $ReadOnly<{|
\\"aria-hidden\\"?: ?boolean,
collapsable?: ?boolean,
collapsableChildren?: ?boolean,
experimental_layoutConformance?: ?(\\"strict\\" | \\"classic\\"),
id?: string,
testID?: ?string,
nativeID?: ?string,
Expand DownExpand Up@@ -9627,6 +9645,7 @@ declare module.exports: {
get Image(): Image,
get ImageBackground(): ImageBackground,
get InputAccessoryView(): InputAccessoryView,
get experimental_LayoutConformance(): LayoutConformance,
get KeyboardAvoidingView(): KeyboardAvoidingView,
get Modal(): Modal,
get Pressable(): Pressable,
Expand Down
7 changes: 0 additions & 7 deletions packages/react-native/React/Views/RCTViewManager.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -424,13 +424,6 @@ - (void)updateAccessibilityTraitsForRole:(RCTView *)view withDefaultView:(RCTVie
// filtered by view configs.
}

RCT_CUSTOM_VIEW_PROPERTY(experimental_layoutConformance, NSString *, RCTView)
{
// Property is only to be used in the new renderer.
// It is necessary to add it here, otherwise it gets
// filtered by view configs.
}

typedef NSArray *FilterArray; // Custom type to make the StaticViewConfigValidator Happy
RCT_CUSTOM_VIEW_PROPERTY(filter, FilterArray, RCTView)
{
Expand Down
1 change: 0 additions & 1 deletion packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line numberDiff line numberDiff line change
Expand Up@@ -4155,7 +4155,6 @@ public class com/facebook/react/uimanager/LayoutShadowNode : com/facebook/react/
public fun setInsetBlock (ILcom/facebook/react/bridge/Dynamic;)V
public fun setInsetInline (ILcom/facebook/react/bridge/Dynamic;)V
public fun setJustifyContent (Ljava/lang/String;)V
public fun setLayoutConformance (Ljava/lang/String;)V
public fun setMarginBlock (ILcom/facebook/react/bridge/Dynamic;)V
public fun setMarginInline (ILcom/facebook/react/bridge/Dynamic;)V
public fun setMargins (ILcom/facebook/react/bridge/Dynamic;)V
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -972,9 +972,4 @@ public void setShouldNotifyPointerLeave(boolean value) {
public void setShouldNotifyPointerMove(boolean value) {
// Do Nothing: Align with static ViewConfigs
}

@ReactProp(name = "experimental_layoutConformance")
public void setLayoutConformance(String value) {
// Do Nothing: Align with static ViewConfigs
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@
#include <react/renderer/components/text/ParagraphComponentDescriptor.h>
#include <react/renderer/components/text/RawTextComponentDescriptor.h>
#include <react/renderer/components/text/TextComponentDescriptor.h>
#include <react/renderer/components/view/LayoutConformanceComponentDescriptor.h>
#include <react/renderer/components/view/ViewComponentDescriptor.h>

namespace facebook::react::CoreComponentsRegistry {
Expand DownExpand Up@@ -66,6 +67,8 @@ sharedProviderRegistry() {
AndroidDrawerLayoutComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
DebuggingOverlayComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
LayoutConformanceComponentDescriptor>());

return providerRegistry;
}();
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -342,16 +342,7 @@ BaseViewProps::BaseViewProps(
rawProps,
"removeClippedSubviews",
sourceProps.removeClippedSubviews,
false)),
experimental_layoutConformance(
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.experimental_layoutConformance
: convertRawProp(
context,
rawProps,
"experimental_layoutConformance",
sourceProps.experimental_layoutConformance,
{})) {}
false)) {}

#define VIEW_EVENT_CASE(eventType) \
case CONSTEXPR_RAW_PROPS_KEY_HASH("on" #eventType): { \
Expand DownExpand Up@@ -397,7 +388,6 @@ void BaseViewProps::setProp(
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsable);
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsableChildren);
RAW_SET_PROP_SWITCH_CASE_BASIC(removeClippedSubviews);
RAW_SET_PROP_SWITCH_CASE_BASIC(experimental_layoutConformance);
RAW_SET_PROP_SWITCH_CASE_BASIC(cursor);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineColor);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineOffset);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,8 +106,6 @@ class BaseViewProps : public YogaStylableProps, public AccessibilityProps {

bool removeClippedSubviews{false};

LayoutConformance experimental_layoutConformance{};

#pragma mark - Convenience Methods

CascadedBorderWidths getBorderWidths() const;
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/LayoutConformanceShadowNode.h>
#include <react/renderer/core/ConcreteComponentDescriptor.h>

namespace facebook::react {

using LayoutConformanceComponentDescriptor =
ConcreteComponentDescriptor<LayoutConformanceShadowNode>;

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/YogaStylableProps.h>
#include <react/renderer/components/view/propsConversions.h>

namespace facebook::react {

struct LayoutConformanceProps final : public YogaStylableProps {
/**
* Whether to layout the subtree with strict conformance to W3C standard
* (YGErrataNone) or for compatibility with legacy RN bugs (YGErrataAll)
*/
LayoutConformance mode{LayoutConformance::Strict};

LayoutConformanceProps() = default;
LayoutConformanceProps(
const PropsParserContext& context,
const LayoutConformanceProps& sourceProps,
const RawProps& rawProps)
: YogaStylableProps(context, sourceProps, rawProps),
mode{convertRawProp(
context,
rawProps,
"mode",
mode,
LayoutConformance::Strict)} {}
};

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/ConcreteViewShadowNode.h>
#include <react/renderer/components/view/LayoutConformanceProps.h>
#include <react/renderer/components/view/YogaLayoutableShadowNode.h>

namespace facebook::react {

constexpr const char LayoutConformanceShadowNodeComponentName[] =
"LayoutConformance";

using LayoutConformanceShadowNode = ConcreteShadowNode<
LayoutConformanceShadowNodeComponentName,
YogaLayoutableShadowNode,
LayoutConformanceProps>;

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,6 +11,7 @@
#include <react/debug/flags.h>
#include <react/debug/react_native_assert.h>
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <react/renderer/components/view/LayoutConformanceShadowNode.h>
#include <react/renderer/components/view/ViewProps.h>
#include <react/renderer/components/view/ViewShadowNode.h>
#include <react/renderer/components/view/conversions.h>
Expand DownExpand Up@@ -501,15 +502,13 @@ void YogaLayoutableShadowNode::configureYogaTree(
}

YGErrata YogaLayoutableShadowNode::resolveErrata(YGErrata defaultErrata) const {
if (auto viewShadowNode = dynamic_cast<const ViewShadowNode*>(this)) {
const auto& props = viewShadowNode->getConcreteProps();
switch (props.experimental_layoutConformance) {
case LayoutConformance::Classic:
return YGErrataAll;
if (auto layoutConformanceNode =
dynamic_cast<const LayoutConformanceShadowNode*>(this)) {
switch (layoutConformanceNode->getConcreteProps().mode) {
case LayoutConformance::Strict:
return YGErrataNone;
case LayoutConformance::Undefined:
return defaultErrata;
case LayoutConformance::Compatibility:
return YGErrataAll;
}
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
/**
* 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.
*
* @format
*/

import type * as React from 'react';

type LayoutConformanceProps = {
/**
* strict: Layout in accordance with W3C spec, even when breaking
* compatibility: Layout with the same behavior as previous versions of React Native
*/
mode: 'strict' | 'compatibility';
children: React.ReactNode;
};

export const experimental_LayoutConformance: React.ComponentType<LayoutConformanceProps>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
/**
* 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
* @oncall react_native
*/

import StyleSheet from '../../StyleSheet/StyleSheet';
import LayoutConformanceNativeComponent from './LayoutConformanceNativeComponent';
import * as React from 'react';

type Props = $ReadOnly<{
/**
* strict: Layout in accordance with W3C spec, even when breaking
* compatibility: Layout with the same behavior as previous versions of React Native
*/
mode: 'strict' | 'compatibility',

children: React.Node,
}>;

// We want a graceful fallback for apps using legacy arch, but need to know
// ahead of time whether the component is available, so we test for global.
// This does not correctly handle mixed arch apps (which is okay, since we just
// degrade the error experience).
const isFabricUIManagerInstalled = global?.nativeFabricUIManager != null;

function LayoutConformance(props: Props): React.Node {
return (
<LayoutConformanceNativeComponent {...props} style={styles.container} />
);
}

function UnimplementedLayoutConformance(props: Props): React.Node {
if (__DEV__) {
const warnOnce = require('../../Utilities/warnOnce');

warnOnce(
'layoutconformance-unsupported',
'"LayoutConformance" is only supported in the New Architecture',
);
}

return props.children;
}

export default (isFabricUIManagerInstalled
? LayoutConformance
: UnimplementedLayoutConformance) as component(...Props);

const styles = StyleSheet.create({
container: {
display: 'contents',
},
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
/**
* 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
*/

import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
import type {ViewProps} from '../View/ViewPropTypes';

import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentRegistry';

type Props = $ReadOnly<{
mode: 'strict' | 'compatibility',
...ViewProps,
}>;

const LayoutConformanceNativeComponent: HostComponent<Props> =
NativeComponentRegistry.get<Props>('LayoutConformance', () => ({
uiViewClassName: 'LayoutConformance',
validAttributes: {
mode: true,
},
}));

export default LayoutConformanceNativeComponent;
Original file line numberDiff line numberDiff line change
Expand Up@@ -211,11 +211,4 @@ export interface ViewProps
* Used to reference react managed views from native code.
*/
nativeID?: string | undefined;

/**
* Contols whether this view, and its transitive children, are laid in a way
* consistent with web browsers ('strict'), or consistent with existing
* React Native code which may rely on incorrect behavior ('classic').
*/
experimental_layoutConformance?: 'strict' | 'classic' | undefined;
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -578,15 +578,6 @@ export type ViewProps = $ReadOnly<{|
*/
collapsableChildren?: ?boolean,

/**
* Contols whether this view, and its transitive children, are laid in a way
* consistent with web browsers ('strict'), or consistent with existing
* React Native code which may rely on incorrect behavior ('classic').
*
* This prop only works when using Fabric.
*/
experimental_layoutConformance?: ?('strict' | 'classic'),

/**
* Used to locate this view from native classes. Has precedence over `nativeID` prop.
*
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -293,8 +293,6 @@ const validAttributesForNonEventProps = {

style: ReactNativeStyleAttributes,

experimental_layoutConformance: true,

// ReactClippingViewManager @ReactProps
removeClippedSubviews: true,

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -357,8 +357,6 @@ const validAttributesForNonEventProps = {
direction: true,

style: ReactNativeStyleAttributes,

experimental_layoutConformance: true,
};

// Props for bubbling and direct events
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -1887,6 +1887,25 @@ declare export default typeof NativeKeyboardObserver;
"
`;

exports[`public API should not change unintentionally Libraries/Components/LayoutConformance/LayoutConformance.js 1`] = `
"type Props = $ReadOnly<{
mode: \\"strict\\" | \\"compatibility\\",
children: React.Node,
}>;
declare export default component(...Props);
"
`;

exports[`public API should not change unintentionally Libraries/Components/LayoutConformance/LayoutConformanceNativeComponent.js 1`] = `
"type Props = $ReadOnly<{
mode: \\"strict\\" | \\"compatibility\\",
...ViewProps,
}>;
declare const LayoutConformanceNativeComponent: HostComponent<Props>;
declare export default typeof LayoutConformanceNativeComponent;
"
`;

exports[`public API should not change unintentionally Libraries/Components/Pressable/Pressable.js 1`] = `
"type ViewStyleProp = $ElementType<React.ElementConfig<typeof View>, \\"style\\">;
export type StateCallbackType = $ReadOnly<{|
Expand DownExpand Up@@ -4268,7 +4287,6 @@ export type ViewProps = $ReadOnly<{|
\\"aria-hidden\\"?: ?boolean,
collapsable?: ?boolean,
collapsableChildren?: ?boolean,
experimental_layoutConformance?: ?(\\"strict\\" | \\"classic\\"),
id?: string,
testID?: ?string,
nativeID?: ?string,
Expand DownExpand Up@@ -9627,6 +9645,7 @@ declare module.exports: {
get Image(): Image,
get ImageBackground(): ImageBackground,
get InputAccessoryView(): InputAccessoryView,
get experimental_LayoutConformance(): LayoutConformance,
get KeyboardAvoidingView(): KeyboardAvoidingView,
get Modal(): Modal,
get Pressable(): Pressable,
Expand Down
7 changes: 0 additions & 7 deletions packages/react-native/React/Views/RCTViewManager.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -424,13 +424,6 @@ - (void)updateAccessibilityTraitsForRole:(RCTView *)view withDefaultView:(RCTVie
// filtered by view configs.
}

RCT_CUSTOM_VIEW_PROPERTY(experimental_layoutConformance, NSString *, RCTView)
{
// Property is only to be used in the new renderer.
// It is necessary to add it here, otherwise it gets
// filtered by view configs.
}

typedef NSArray *FilterArray; // Custom type to make the StaticViewConfigValidator Happy
RCT_CUSTOM_VIEW_PROPERTY(filter, FilterArray, RCTView)
{
Expand Down
1 change: 0 additions & 1 deletion packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line numberDiff line numberDiff line change
Expand Up@@ -4155,7 +4155,6 @@ public class com/facebook/react/uimanager/LayoutShadowNode : com/facebook/react/
public fun setInsetBlock (ILcom/facebook/react/bridge/Dynamic;)V
public fun setInsetInline (ILcom/facebook/react/bridge/Dynamic;)V
public fun setJustifyContent (Ljava/lang/String;)V
public fun setLayoutConformance (Ljava/lang/String;)V
public fun setMarginBlock (ILcom/facebook/react/bridge/Dynamic;)V
public fun setMarginInline (ILcom/facebook/react/bridge/Dynamic;)V
public fun setMargins (ILcom/facebook/react/bridge/Dynamic;)V
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -972,9 +972,4 @@ public void setShouldNotifyPointerLeave(boolean value) {
public void setShouldNotifyPointerMove(boolean value) {
// Do Nothing: Align with static ViewConfigs
}

@ReactProp(name = "experimental_layoutConformance")
public void setLayoutConformance(String value) {
// Do Nothing: Align with static ViewConfigs
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@
#include <react/renderer/components/text/ParagraphComponentDescriptor.h>
#include <react/renderer/components/text/RawTextComponentDescriptor.h>
#include <react/renderer/components/text/TextComponentDescriptor.h>
#include <react/renderer/components/view/LayoutConformanceComponentDescriptor.h>
#include <react/renderer/components/view/ViewComponentDescriptor.h>

namespace facebook::react::CoreComponentsRegistry {
Expand DownExpand Up@@ -66,6 +67,8 @@ sharedProviderRegistry() {
AndroidDrawerLayoutComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
DebuggingOverlayComponentDescriptor>());
providerRegistry->add(concreteComponentDescriptorProvider<
LayoutConformanceComponentDescriptor>());

return providerRegistry;
}();
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -342,16 +342,7 @@ BaseViewProps::BaseViewProps(
rawProps,
"removeClippedSubviews",
sourceProps.removeClippedSubviews,
false)),
experimental_layoutConformance(
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.experimental_layoutConformance
: convertRawProp(
context,
rawProps,
"experimental_layoutConformance",
sourceProps.experimental_layoutConformance,
{})) {}
false)) {}

#define VIEW_EVENT_CASE(eventType) \
case CONSTEXPR_RAW_PROPS_KEY_HASH("on" #eventType): { \
Expand DownExpand Up@@ -397,7 +388,6 @@ void BaseViewProps::setProp(
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsable);
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsableChildren);
RAW_SET_PROP_SWITCH_CASE_BASIC(removeClippedSubviews);
RAW_SET_PROP_SWITCH_CASE_BASIC(experimental_layoutConformance);
RAW_SET_PROP_SWITCH_CASE_BASIC(cursor);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineColor);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineOffset);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,8 +106,6 @@ class BaseViewProps : public YogaStylableProps, public AccessibilityProps {

bool removeClippedSubviews{false};

LayoutConformance experimental_layoutConformance{};

#pragma mark - Convenience Methods

CascadedBorderWidths getBorderWidths() const;
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/LayoutConformanceShadowNode.h>
#include <react/renderer/core/ConcreteComponentDescriptor.h>

namespace facebook::react {

using LayoutConformanceComponentDescriptor =
ConcreteComponentDescriptor<LayoutConformanceShadowNode>;

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/YogaStylableProps.h>
#include <react/renderer/components/view/propsConversions.h>

namespace facebook::react {

struct LayoutConformanceProps final : public YogaStylableProps {
/**
* Whether to layout the subtree with strict conformance to W3C standard
* (YGErrataNone) or for compatibility with legacy RN bugs (YGErrataAll)
*/
LayoutConformance mode{LayoutConformance::Strict};

LayoutConformanceProps() = default;
LayoutConformanceProps(
const PropsParserContext& context,
const LayoutConformanceProps& sourceProps,
const RawProps& rawProps)
: YogaStylableProps(context, sourceProps, rawProps),
mode{convertRawProp(
context,
rawProps,
"mode",
mode,
LayoutConformance::Strict)} {}
};

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
/*
* 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.
*/

#pragma once

#include <react/renderer/components/view/ConcreteViewShadowNode.h>
#include <react/renderer/components/view/LayoutConformanceProps.h>
#include <react/renderer/components/view/YogaLayoutableShadowNode.h>

namespace facebook::react {

constexpr const char LayoutConformanceShadowNodeComponentName[] =
"LayoutConformance";

using LayoutConformanceShadowNode = ConcreteShadowNode<
LayoutConformanceShadowNodeComponentName,
YogaLayoutableShadowNode,
LayoutConformanceProps>;

} // namespace facebook::react
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,6 +11,7 @@
#include <react/debug/flags.h>
#include <react/debug/react_native_assert.h>
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <react/renderer/components/view/LayoutConformanceShadowNode.h>
#include <react/renderer/components/view/ViewProps.h>
#include <react/renderer/components/view/ViewShadowNode.h>
#include <react/renderer/components/view/conversions.h>
Expand DownExpand Up@@ -501,15 +502,13 @@ void YogaLayoutableShadowNode::configureYogaTree(
}

YGErrata YogaLayoutableShadowNode::resolveErrata(YGErrata defaultErrata) const {
if (auto viewShadowNode = dynamic_cast<const ViewShadowNode*>(this)) {
const auto& props = viewShadowNode->getConcreteProps();
switch (props.experimental_layoutConformance) {
case LayoutConformance::Classic:
return YGErrataAll;
if (auto layoutConformanceNode =
dynamic_cast<const LayoutConformanceShadowNode*>(this)) {
switch (layoutConformanceNode->getConcreteProps().mode) {
case LayoutConformance::Strict:
return YGErrataNone;
case LayoutConformance::Undefined:
return defaultErrata;
case LayoutConformance::Compatibility:
return YGErrataAll;
}
}

Expand Down
Loading