react-native-boost 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../src/runtime/utils/constants.ts","../../../src/runtime/components/native-text.tsx","../../../src/runtime/components/native-view.tsx","../../../src/runtime/index.ts"],"sourcesContent":["/**\n * Maps CSS-like `userSelect` values to React Native's `selectable` prop.\n */\nexport const userSelectToSelectableMap = {\n auto: true,\n text: true,\n none: false,\n contain: true,\n all: true,\n};\n\n/**\n * Maps CSS-like `verticalAlign` values to React Native's `textAlignVertical`.\n */\nexport const verticalAlignToTextAlignVerticalMap = {\n auto: 'auto',\n top: 'top',\n bottom: 'bottom',\n middle: 'center',\n};\n","/* eslint-disable @typescript-eslint/no-require-imports,unicorn/prefer-module */\n\nimport type { ComponentType } from 'react';\nimport type { TextProps } from 'react-native';\n\nconst reactNative = require('react-native');\nconst isWeb = reactNative.Platform.OS === 'web';\n\nlet nativeText = reactNative.unstable_NativeText;\n\nif (isWeb || nativeText == null) {\n // Fallback to regular Text component if unstable_NativeText is not available or we're on Web\n nativeText = reactNative.Text;\n}\n\n/**\n * Native Text component with graceful fallback.\n *\n * @remarks\n * Uses `unstable_NativeText` on supported native runtimes and falls back to `Text`\n * on web or when the unstable export is unavailable.\n */\nexport const NativeText: ComponentType<TextProps> = nativeText;\n","/* eslint-disable @typescript-eslint/no-require-imports,unicorn/prefer-module */\n\nimport type { ComponentType } from 'react';\nimport type { ViewProps } from 'react-native';\n\nconst reactNative = require('react-native');\nconst isWeb = reactNative.Platform.OS === 'web';\n\nlet nativeView = reactNative.unstable_NativeView;\n\nif (isWeb || nativeView == null) {\n // Fallback to regular View component if unstable_NativeView is not available or we're on Web\n nativeView = reactNative.View;\n}\n\n/**\n * Native View component with graceful fallback.\n *\n * @remarks\n * Uses `unstable_NativeView` on supported native runtimes and falls back to `View`\n * on web or when the unstable export is unavailable.\n */\nexport const NativeView: ComponentType<ViewProps> = nativeView;\n","import { TextProps, TextStyle, StyleSheet } from 'react-native';\nimport { GenericStyleProp } from './types';\nimport { userSelectToSelectableMap, verticalAlignToTextAlignVerticalMap } from './utils/constants';\n\nconst propsCache = new WeakMap();\n\n/**\n * Normalizes `Text` style values for `NativeText`.\n *\n * @param style - Style prop passed to a text-like component.\n * @returns Native-friendly text props. Returns an empty object when `style` is falsy or cannot be normalized.\n * @remarks\n * - Flattens style arrays via `StyleSheet.flatten`\n * - Converts numeric `fontWeight` values to string values\n * - Maps `userSelect` and `verticalAlign` to native-compatible props\n */\nexport function processTextStyle(style: GenericStyleProp<TextStyle>): Partial<TextProps> {\n if (!style) return {};\n\n // Cache the computed props\n let props = propsCache.get(style);\n if (props) return props;\n\n props = {};\n propsCache.set(style, props);\n\n style = StyleSheet.flatten(style) as TextStyle;\n\n if (!style) return {};\n\n if (typeof style?.fontWeight === 'number') {\n style.fontWeight = style.fontWeight.toString() as TextStyle['fontWeight'];\n }\n\n if (style?.userSelect != null) {\n props.selectable = userSelectToSelectableMap[style.userSelect];\n delete style.userSelect;\n }\n\n if (style?.verticalAlign != null) {\n style.textAlignVertical = verticalAlignToTextAlignVerticalMap[\n style.verticalAlign\n ] as TextStyle['textAlignVertical'];\n delete style.verticalAlign;\n }\n\n props.style = style;\n return props;\n}\n\n/**\n * Normalizes accessibility and ARIA props for runtime native components.\n *\n * @param props - Accessibility and ARIA props.\n * @returns Props with normalized accessibility fields.\n * @remarks\n * - Merges `aria-label` with `accessibilityLabel`\n * - Merges ARIA state fields into `accessibilityState`\n * - Defaults `accessible` to `true` when omitted\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function processAccessibilityProps(props: Record<string, any>): Record<string, any> {\n const {\n accessibilityLabel,\n ['aria-label']: ariaLabel,\n accessibilityState,\n ['aria-busy']: ariaBusy,\n ['aria-checked']: ariaChecked,\n ['aria-disabled']: ariaDisabled,\n ['aria-expanded']: ariaExpanded,\n ['aria-selected']: ariaSelected,\n accessible,\n ...restProperties\n } = props;\n\n // Merge label props: prefer the aria-label if defined.\n const normalizedLabel = ariaLabel ?? accessibilityLabel;\n\n // Merge the accessibilityState with any provided ARIA properties.\n let normalizedState = accessibilityState;\n if (ariaBusy != null || ariaChecked != null || ariaDisabled != null || ariaExpanded != null || ariaSelected != null) {\n normalizedState =\n normalizedState == null\n ? {\n busy: ariaBusy,\n checked: ariaChecked,\n disabled: ariaDisabled,\n expanded: ariaExpanded,\n selected: ariaSelected,\n }\n : {\n busy: ariaBusy ?? normalizedState.busy,\n checked: ariaChecked ?? normalizedState.checked,\n disabled: ariaDisabled ?? normalizedState.disabled,\n expanded: ariaExpanded ?? normalizedState.expanded,\n selected: ariaSelected ?? normalizedState.selected,\n };\n }\n\n // For the accessible prop, if not provided, default to `true`\n const normalizedAccessible = accessible == null ? true : accessible;\n\n return {\n ...restProperties,\n accessibilityLabel: normalizedLabel,\n accessibilityState: normalizedState,\n accessible: normalizedAccessible,\n };\n}\n\nexport * from './types';\nexport * from './utils/constants';\nexport * from './components/native-text';\nexport * from './components/native-view';\n"],"names":["reactNative","isWeb"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../src/runtime/utils/constants.ts","../../../src/runtime/components/native-text.tsx","../../../src/runtime/components/native-view.tsx","../../../src/runtime/index.ts"],"sourcesContent":["/**\n * Maps CSS-like `userSelect` values to React Native's `selectable` prop.\n */\nexport const userSelectToSelectableMap = {\n auto: true,\n text: true,\n none: false,\n contain: true,\n all: true,\n};\n\n/**\n * Maps CSS-like `verticalAlign` values to React Native's `textAlignVertical`.\n */\nexport const verticalAlignToTextAlignVerticalMap = {\n auto: 'auto',\n top: 'top',\n bottom: 'bottom',\n middle: 'center',\n};\n","/* eslint-disable @typescript-eslint/no-require-imports,unicorn/prefer-module */\n\nimport type { ComponentType } from 'react';\nimport type { TextProps } from 'react-native';\n\nconst reactNative = require('react-native');\nconst isWeb = reactNative.Platform.OS === 'web';\n\nlet nativeText = reactNative.unstable_NativeText;\n\nif (isWeb || nativeText == null) {\n // Fallback to regular Text component if unstable_NativeText is not available or we're on Web\n nativeText = reactNative.Text;\n}\n\n/**\n * Native Text component with graceful fallback.\n *\n * @remarks\n * Uses `unstable_NativeText` on supported native runtimes and falls back to `Text`\n * on web or when the unstable export is unavailable.\n */\nexport const NativeText: ComponentType<TextProps> = nativeText;\n","/* eslint-disable @typescript-eslint/no-require-imports,unicorn/prefer-module */\n\nimport type { ComponentType } from 'react';\nimport type { ViewProps } from 'react-native';\n\nconst reactNative = require('react-native');\nconst isWeb = reactNative.Platform.OS === 'web';\n\nlet nativeView = reactNative.unstable_NativeView;\n\nif (isWeb || nativeView == null) {\n // Fallback to regular View component if unstable_NativeView is not available or we're on Web\n nativeView = reactNative.View;\n}\n\n/**\n * Native View component with graceful fallback.\n *\n * @remarks\n * Uses `unstable_NativeView` on supported native runtimes and falls back to `View`\n * on web or when the unstable export is unavailable.\n */\nexport const NativeView: ComponentType<ViewProps> = nativeView;\n","import { TextProps, TextStyle, StyleSheet, Platform } from 'react-native';\nimport { GenericStyleProp } from './types';\nimport { userSelectToSelectableMap, verticalAlignToTextAlignVerticalMap } from './utils/constants';\n\nconst propsCache = new WeakMap();\n\n/**\n * Normalizes `Text` style values for `NativeText`.\n *\n * @param style - Style prop passed to a text-like component.\n * @returns Native-friendly text props. Returns an empty object when `style` is falsy or cannot be normalized.\n * @remarks\n * - Flattens style arrays via `StyleSheet.flatten`\n * - Converts numeric `fontWeight` values to string values\n * - Maps `userSelect` and `verticalAlign` to native-compatible props\n */\nexport function processTextStyle(style: GenericStyleProp<TextStyle>): Partial<TextProps> {\n if (!style) return {};\n\n // Cache the computed props\n let props = propsCache.get(style);\n if (props) return props;\n\n props = {};\n propsCache.set(style, props);\n\n style = StyleSheet.flatten(style) as TextStyle;\n\n if (!style) return {};\n\n if (typeof style?.fontWeight === 'number') {\n style.fontWeight = style.fontWeight.toString() as TextStyle['fontWeight'];\n }\n\n if (style?.userSelect != null) {\n props.selectable = userSelectToSelectableMap[style.userSelect];\n delete style.userSelect;\n }\n\n if (style?.verticalAlign != null) {\n style.textAlignVertical = verticalAlignToTextAlignVerticalMap[\n style.verticalAlign\n ] as TextStyle['textAlignVertical'];\n delete style.verticalAlign;\n }\n\n props.style = style;\n return props;\n}\n\n/**\n * The default value `Text` resolves for `accessible` when the prop is omitted: `true` on iOS (text is\n * an accessibility element unless opted out), `false` on Android, and `undefined` elsewhere.\n *\n * @remarks\n * Runtime fallback for the common optimized `<Text>` path (no accessibility props) when the target\n * platform is unknown at build time. When it is known (Metro reports it on the Babel caller), the\n * plugin inlines the literal instead and this is not emitted. Evaluated per render — like `Text`'s own\n * `Platform.select` — rather than hoisted to a constant, so it always reflects the current platform.\n */\nexport const getDefaultTextAccessible = (): boolean | undefined => Platform.select({ ios: true, android: false });\n\n/**\n * Normalizes accessibility and ARIA props for runtime native components, mirroring the reconciliation\n * `Text` performs before handing off to its native host.\n *\n * @param props - Accessibility and ARIA props.\n * @returns Props with normalized accessibility fields.\n * @remarks\n * - Merges `aria-label` with `accessibilityLabel`\n * - Merges ARIA state fields into `accessibilityState`\n * - Reconciles `disabled` with `accessibilityState.disabled` (the explicit `disabled` prop wins)\n * - Resolves the platform-specific `accessible` default (see {@link getDefaultTextAccessible})\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function processAccessibilityProps(props: Record<string, any>): Record<string, any> {\n const {\n accessibilityLabel,\n ['aria-label']: ariaLabel,\n accessibilityState,\n ['aria-busy']: ariaBusy,\n ['aria-checked']: ariaChecked,\n ['aria-disabled']: ariaDisabled,\n ['aria-expanded']: ariaExpanded,\n ['aria-selected']: ariaSelected,\n accessible,\n disabled,\n ...restProperties\n } = props;\n\n // Merge label props: prefer the aria-label if defined.\n const normalizedLabel = ariaLabel ?? accessibilityLabel;\n\n // Merge the accessibilityState with any provided ARIA properties.\n let normalizedState = accessibilityState;\n if (ariaBusy != null || ariaChecked != null || ariaDisabled != null || ariaExpanded != null || ariaSelected != null) {\n normalizedState =\n normalizedState == null\n ? {\n busy: ariaBusy,\n checked: ariaChecked,\n disabled: ariaDisabled,\n expanded: ariaExpanded,\n selected: ariaSelected,\n }\n : {\n busy: ariaBusy ?? normalizedState.busy,\n checked: ariaChecked ?? normalizedState.checked,\n disabled: ariaDisabled ?? normalizedState.disabled,\n expanded: ariaExpanded ?? normalizedState.expanded,\n selected: ariaSelected ?? normalizedState.selected,\n };\n }\n\n // Reconcile `disabled` with `accessibilityState.disabled`. When the two are out of sync (and not\n // both falsy) the explicit `disabled` prop wins and is mirrored back into the state object, so the\n // native host receives a consistent value on both fields.\n const stateDisabled = normalizedState?.disabled;\n const normalizedDisabled = disabled ?? stateDisabled;\n if (\n normalizedDisabled !== stateDisabled &&\n ((normalizedDisabled != null && normalizedDisabled !== false) || (stateDisabled != null && stateDisabled !== false))\n ) {\n normalizedState = { ...normalizedState, disabled: normalizedDisabled };\n }\n\n // Resolve `accessible` exactly as `Text` does: opt-out on iOS, off by default on Android. The\n // Android pressable case (`onPress`/`onLongPress`) never applies — press handlers bail out of\n // optimization — so an omitted prop falls back to the platform default.\n const normalizedAccessible = Platform.select({\n ios: accessible !== false,\n android: accessible ?? false,\n default: accessible,\n });\n\n return {\n ...restProperties,\n accessibilityLabel: normalizedLabel,\n accessibilityState: normalizedState,\n accessible: normalizedAccessible,\n disabled: normalizedDisabled,\n };\n}\n\nexport * from './types';\nexport * from './utils/constants';\nexport * from './components/native-text';\nexport * from './components/native-view';\n"],"names":["reactNative","isWeb"],"mappings":"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"}
@@ -13,11 +13,12 @@ const verticalAlignToTextAlignVerticalMap = {
13
13
  };
14
14
 
15
15
  const processTextStyle = (style) => ({ style });
16
+ const getDefaultTextAccessible = () => void 0;
16
17
  function processAccessibilityProps(props) {
17
18
  return props;
18
19
  }
19
20
  const NativeText = require("react-native").Text;
20
21
  const NativeView = require("react-native").View;
21
22
 
22
- export { NativeText, NativeView, processAccessibilityProps, processTextStyle, userSelectToSelectableMap, verticalAlignToTextAlignVerticalMap };
23
+ export { NativeText, NativeView, getDefaultTextAccessible, processAccessibilityProps, processTextStyle, userSelectToSelectableMap, verticalAlignToTextAlignVerticalMap };
23
24
  //# sourceMappingURL=index.web.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.web.mjs","sources":["../../../src/runtime/utils/constants.ts","../../../src/runtime/index.web.ts"],"sourcesContent":["/**\n * Maps CSS-like `userSelect` values to React Native's `selectable` prop.\n */\nexport const userSelectToSelectableMap = {\n auto: true,\n text: true,\n none: false,\n contain: true,\n all: true,\n};\n\n/**\n * Maps CSS-like `verticalAlign` values to React Native's `textAlignVertical`.\n */\nexport const verticalAlignToTextAlignVerticalMap = {\n auto: 'auto',\n top: 'top',\n bottom: 'bottom',\n middle: 'center',\n};\n","// This is a dummy file to ensure that nothing breaks when using the runtime in a web environment.\n\nimport { TextProps, TextStyle } from 'react-native';\nimport { GenericStyleProp } from './types';\n\nexport const processTextStyle = (style: GenericStyleProp<TextStyle>) => ({ style }) as Partial<TextProps>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function processAccessibilityProps(props: Record<string, any>): Record<string, any> {\n return props;\n}\n\nexport * from './types';\nexport * from './utils/constants';\n\n// On Web, the native components are not available, so we use the standard components that'll be replaced by their DOM\n// equivalents by react-native-web.\n/* eslint-disable @typescript-eslint/no-require-imports,unicorn/prefer-module */\nexport const NativeText = require('react-native').Text;\nexport const NativeView = require('react-native').View;\n/* eslint-enable @typescript-eslint/no-require-imports,unicorn/prefer-module */\n"],"names":[],"mappings":"AAGO,MAAM,yBAAA,GAA4B;AAAA,EACvC,IAAA,EAAM,IAAA;AAAA,EACN,IAAA,EAAM,IAAA;AAAA,EACN,IAAA,EAAM,KAAA;AAAA,EACN,OAAA,EAAS,IAAA;AAAA,EACT,GAAA,EAAK;AACP;AAKO,MAAM,mCAAA,GAAsC;AAAA,EACjD,IAAA,EAAM,MAAA;AAAA,EACN,GAAA,EAAK,KAAA;AAAA,EACL,MAAA,EAAQ,QAAA;AAAA,EACR,MAAA,EAAQ;AACV;;ACdO,MAAM,gBAAA,GAAmB,CAAC,KAAA,MAAwC,EAAE,KAAA,EAAM;AAG1E,SAAS,0BAA0B,KAAA,EAAiD;AACzF,EAAA,OAAO,KAAA;AACT;AAQO,MAAM,UAAA,GAAa,OAAA,CAAQ,cAAc,CAAA,CAAE;AAC3C,MAAM,UAAA,GAAa,OAAA,CAAQ,cAAc,CAAA,CAAE;;;;"}
1
+ {"version":3,"file":"index.web.mjs","sources":["../../../src/runtime/utils/constants.ts","../../../src/runtime/index.web.ts"],"sourcesContent":["/**\n * Maps CSS-like `userSelect` values to React Native's `selectable` prop.\n */\nexport const userSelectToSelectableMap = {\n auto: true,\n text: true,\n none: false,\n contain: true,\n all: true,\n};\n\n/**\n * Maps CSS-like `verticalAlign` values to React Native's `textAlignVertical`.\n */\nexport const verticalAlignToTextAlignVerticalMap = {\n auto: 'auto',\n top: 'top',\n bottom: 'bottom',\n middle: 'center',\n};\n","// This is a dummy file to ensure that nothing breaks when using the runtime in a web environment.\n\nimport { TextProps, TextStyle } from 'react-native';\nimport { GenericStyleProp } from './types';\n\nexport const processTextStyle = (style: GenericStyleProp<TextStyle>) => ({ style }) as Partial<TextProps>;\n\n// On Web there is no platform-specific `accessible` default to apply; react-native-web's `Text`\n// derives accessibility from the rendered DOM. Returning `undefined` makes the injected\n// `accessible={getDefaultTextAccessible()}` a no-op.\nexport const getDefaultTextAccessible = (): boolean | undefined => undefined;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function processAccessibilityProps(props: Record<string, any>): Record<string, any> {\n return props;\n}\n\nexport * from './types';\nexport * from './utils/constants';\n\n// On Web, the native components are not available, so we use the standard components that'll be replaced by their DOM\n// equivalents by react-native-web.\n/* eslint-disable @typescript-eslint/no-require-imports,unicorn/prefer-module */\nexport const NativeText = require('react-native').Text;\nexport const NativeView = require('react-native').View;\n/* eslint-enable @typescript-eslint/no-require-imports,unicorn/prefer-module */\n"],"names":[],"mappings":"AAGO,MAAM,yBAAA,GAA4B;AAAA,EACvC,IAAA,EAAM,IAAA;AAAA,EACN,IAAA,EAAM,IAAA;AAAA,EACN,IAAA,EAAM,KAAA;AAAA,EACN,OAAA,EAAS,IAAA;AAAA,EACT,GAAA,EAAK;AACP;AAKO,MAAM,mCAAA,GAAsC;AAAA,EACjD,IAAA,EAAM,MAAA;AAAA,EACN,GAAA,EAAK,KAAA;AAAA,EACL,MAAA,EAAQ,QAAA;AAAA,EACR,MAAA,EAAQ;AACV;;ACdO,MAAM,gBAAA,GAAmB,CAAC,KAAA,MAAwC,EAAE,KAAA,EAAM;AAK1E,MAAM,2BAA2B,MAA2B;AAG5D,SAAS,0BAA0B,KAAA,EAAiD;AACzF,EAAA,OAAO,KAAA;AACT;AAQO,MAAM,UAAA,GAAa,OAAA,CAAQ,cAAc,CAAA,CAAE;AAC3C,MAAM,UAAA,GAAa,OAAA,CAAQ,cAAc,CAAA,CAAE;;;;"}
@@ -58,16 +58,29 @@ declare const NativeView: ComponentType<ViewProps>;
58
58
  */
59
59
  declare function processTextStyle(style: GenericStyleProp<TextStyle>): Partial<TextProps>;
60
60
  /**
61
- * Normalizes accessibility and ARIA props for runtime native components.
61
+ * The default value `Text` resolves for `accessible` when the prop is omitted: `true` on iOS (text is
62
+ * an accessibility element unless opted out), `false` on Android, and `undefined` elsewhere.
63
+ *
64
+ * @remarks
65
+ * Runtime fallback for the common optimized `<Text>` path (no accessibility props) when the target
66
+ * platform is unknown at build time. When it is known (Metro reports it on the Babel caller), the
67
+ * plugin inlines the literal instead and this is not emitted. Evaluated per render — like `Text`'s own
68
+ * `Platform.select` — rather than hoisted to a constant, so it always reflects the current platform.
69
+ */
70
+ declare const getDefaultTextAccessible: () => boolean | undefined;
71
+ /**
72
+ * Normalizes accessibility and ARIA props for runtime native components, mirroring the reconciliation
73
+ * `Text` performs before handing off to its native host.
62
74
  *
63
75
  * @param props - Accessibility and ARIA props.
64
76
  * @returns Props with normalized accessibility fields.
65
77
  * @remarks
66
78
  * - Merges `aria-label` with `accessibilityLabel`
67
79
  * - Merges ARIA state fields into `accessibilityState`
68
- * - Defaults `accessible` to `true` when omitted
80
+ * - Reconciles `disabled` with `accessibilityState.disabled` (the explicit `disabled` prop wins)
81
+ * - Resolves the platform-specific `accessible` default (see {@link getDefaultTextAccessible})
69
82
  */
70
83
  declare function processAccessibilityProps(props: Record<string, any>): Record<string, any>;
71
84
 
72
- export { NativeText, NativeView, processAccessibilityProps, processTextStyle, userSelectToSelectableMap, verticalAlignToTextAlignVerticalMap };
85
+ export { NativeText, NativeView, getDefaultTextAccessible, processAccessibilityProps, processTextStyle, userSelectToSelectableMap, verticalAlignToTextAlignVerticalMap };
73
86
  export type { GenericStyleProp };
@@ -55,6 +55,7 @@ function processTextStyle(style) {
55
55
  props.style = style;
56
56
  return props;
57
57
  }
58
+ const getDefaultTextAccessible = () => reactNative$2.Platform.select({ ios: true, android: false });
58
59
  function processAccessibilityProps(props) {
59
60
  const {
60
61
  accessibilityLabel,
@@ -66,6 +67,7 @@ function processAccessibilityProps(props) {
66
67
  ["aria-expanded"]: ariaExpanded,
67
68
  ["aria-selected"]: ariaSelected,
68
69
  accessible,
70
+ disabled,
69
71
  ...restProperties
70
72
  } = props;
71
73
  const normalizedLabel = ariaLabel != null ? ariaLabel : accessibilityLabel;
@@ -85,17 +87,28 @@ function processAccessibilityProps(props) {
85
87
  selected: ariaSelected != null ? ariaSelected : normalizedState.selected
86
88
  };
87
89
  }
88
- const normalizedAccessible = accessible == null ? true : accessible;
90
+ const stateDisabled = normalizedState == null ? void 0 : normalizedState.disabled;
91
+ const normalizedDisabled = disabled != null ? disabled : stateDisabled;
92
+ if (normalizedDisabled !== stateDisabled && (normalizedDisabled != null && normalizedDisabled !== false || stateDisabled != null && stateDisabled !== false)) {
93
+ normalizedState = { ...normalizedState, disabled: normalizedDisabled };
94
+ }
95
+ const normalizedAccessible = reactNative$2.Platform.select({
96
+ ios: accessible !== false,
97
+ android: accessible != null ? accessible : false,
98
+ default: accessible
99
+ });
89
100
  return {
90
101
  ...restProperties,
91
102
  accessibilityLabel: normalizedLabel,
92
103
  accessibilityState: normalizedState,
93
- accessible: normalizedAccessible
104
+ accessible: normalizedAccessible,
105
+ disabled: normalizedDisabled
94
106
  };
95
107
  }
96
108
 
97
109
  exports.NativeText = NativeText;
98
110
  exports.NativeView = NativeView;
111
+ exports.getDefaultTextAccessible = getDefaultTextAccessible;
99
112
  exports.processAccessibilityProps = processAccessibilityProps;
100
113
  exports.processTextStyle = processTextStyle;
101
114
  exports.userSelectToSelectableMap = userSelectToSelectableMap;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/runtime/utils/constants.ts","../../src/runtime/components/native-text.tsx","../../src/runtime/components/native-view.tsx","../../src/runtime/index.ts"],"sourcesContent":["/**\n * Maps CSS-like `userSelect` values to React Native's `selectable` prop.\n */\nexport const userSelectToSelectableMap = {\n auto: true,\n text: true,\n none: false,\n contain: true,\n all: true,\n};\n\n/**\n * Maps CSS-like `verticalAlign` values to React Native's `textAlignVertical`.\n */\nexport const verticalAlignToTextAlignVerticalMap = {\n auto: 'auto',\n top: 'top',\n bottom: 'bottom',\n middle: 'center',\n};\n","/* eslint-disable @typescript-eslint/no-require-imports,unicorn/prefer-module */\n\nimport type { ComponentType } from 'react';\nimport type { TextProps } from 'react-native';\n\nconst reactNative = require('react-native');\nconst isWeb = reactNative.Platform.OS === 'web';\n\nlet nativeText = reactNative.unstable_NativeText;\n\nif (isWeb || nativeText == null) {\n // Fallback to regular Text component if unstable_NativeText is not available or we're on Web\n nativeText = reactNative.Text;\n}\n\n/**\n * Native Text component with graceful fallback.\n *\n * @remarks\n * Uses `unstable_NativeText` on supported native runtimes and falls back to `Text`\n * on web or when the unstable export is unavailable.\n */\nexport const NativeText: ComponentType<TextProps> = nativeText;\n","/* eslint-disable @typescript-eslint/no-require-imports,unicorn/prefer-module */\n\nimport type { ComponentType } from 'react';\nimport type { ViewProps } from 'react-native';\n\nconst reactNative = require('react-native');\nconst isWeb = reactNative.Platform.OS === 'web';\n\nlet nativeView = reactNative.unstable_NativeView;\n\nif (isWeb || nativeView == null) {\n // Fallback to regular View component if unstable_NativeView is not available or we're on Web\n nativeView = reactNative.View;\n}\n\n/**\n * Native View component with graceful fallback.\n *\n * @remarks\n * Uses `unstable_NativeView` on supported native runtimes and falls back to `View`\n * on web or when the unstable export is unavailable.\n */\nexport const NativeView: ComponentType<ViewProps> = nativeView;\n","import { TextProps, TextStyle, StyleSheet } from 'react-native';\nimport { GenericStyleProp } from './types';\nimport { userSelectToSelectableMap, verticalAlignToTextAlignVerticalMap } from './utils/constants';\n\nconst propsCache = new WeakMap();\n\n/**\n * Normalizes `Text` style values for `NativeText`.\n *\n * @param style - Style prop passed to a text-like component.\n * @returns Native-friendly text props. Returns an empty object when `style` is falsy or cannot be normalized.\n * @remarks\n * - Flattens style arrays via `StyleSheet.flatten`\n * - Converts numeric `fontWeight` values to string values\n * - Maps `userSelect` and `verticalAlign` to native-compatible props\n */\nexport function processTextStyle(style: GenericStyleProp<TextStyle>): Partial<TextProps> {\n if (!style) return {};\n\n // Cache the computed props\n let props = propsCache.get(style);\n if (props) return props;\n\n props = {};\n propsCache.set(style, props);\n\n style = StyleSheet.flatten(style) as TextStyle;\n\n if (!style) return {};\n\n if (typeof style?.fontWeight === 'number') {\n style.fontWeight = style.fontWeight.toString() as TextStyle['fontWeight'];\n }\n\n if (style?.userSelect != null) {\n props.selectable = userSelectToSelectableMap[style.userSelect];\n delete style.userSelect;\n }\n\n if (style?.verticalAlign != null) {\n style.textAlignVertical = verticalAlignToTextAlignVerticalMap[\n style.verticalAlign\n ] as TextStyle['textAlignVertical'];\n delete style.verticalAlign;\n }\n\n props.style = style;\n return props;\n}\n\n/**\n * Normalizes accessibility and ARIA props for runtime native components.\n *\n * @param props - Accessibility and ARIA props.\n * @returns Props with normalized accessibility fields.\n * @remarks\n * - Merges `aria-label` with `accessibilityLabel`\n * - Merges ARIA state fields into `accessibilityState`\n * - Defaults `accessible` to `true` when omitted\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function processAccessibilityProps(props: Record<string, any>): Record<string, any> {\n const {\n accessibilityLabel,\n ['aria-label']: ariaLabel,\n accessibilityState,\n ['aria-busy']: ariaBusy,\n ['aria-checked']: ariaChecked,\n ['aria-disabled']: ariaDisabled,\n ['aria-expanded']: ariaExpanded,\n ['aria-selected']: ariaSelected,\n accessible,\n ...restProperties\n } = props;\n\n // Merge label props: prefer the aria-label if defined.\n const normalizedLabel = ariaLabel ?? accessibilityLabel;\n\n // Merge the accessibilityState with any provided ARIA properties.\n let normalizedState = accessibilityState;\n if (ariaBusy != null || ariaChecked != null || ariaDisabled != null || ariaExpanded != null || ariaSelected != null) {\n normalizedState =\n normalizedState == null\n ? {\n busy: ariaBusy,\n checked: ariaChecked,\n disabled: ariaDisabled,\n expanded: ariaExpanded,\n selected: ariaSelected,\n }\n : {\n busy: ariaBusy ?? normalizedState.busy,\n checked: ariaChecked ?? normalizedState.checked,\n disabled: ariaDisabled ?? normalizedState.disabled,\n expanded: ariaExpanded ?? normalizedState.expanded,\n selected: ariaSelected ?? normalizedState.selected,\n };\n }\n\n // For the accessible prop, if not provided, default to `true`\n const normalizedAccessible = accessible == null ? true : accessible;\n\n return {\n ...restProperties,\n accessibilityLabel: normalizedLabel,\n accessibilityState: normalizedState,\n accessible: normalizedAccessible,\n };\n}\n\nexport * from './types';\nexport * from './utils/constants';\nexport * from './components/native-text';\nexport * from './components/native-view';\n"],"names":["reactNative","isWeb","StyleSheet"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/runtime/utils/constants.ts","../../src/runtime/components/native-text.tsx","../../src/runtime/components/native-view.tsx","../../src/runtime/index.ts"],"sourcesContent":["/**\n * Maps CSS-like `userSelect` values to React Native's `selectable` prop.\n */\nexport const userSelectToSelectableMap = {\n auto: true,\n text: true,\n none: false,\n contain: true,\n all: true,\n};\n\n/**\n * Maps CSS-like `verticalAlign` values to React Native's `textAlignVertical`.\n */\nexport const verticalAlignToTextAlignVerticalMap = {\n auto: 'auto',\n top: 'top',\n bottom: 'bottom',\n middle: 'center',\n};\n","/* eslint-disable @typescript-eslint/no-require-imports,unicorn/prefer-module */\n\nimport type { ComponentType } from 'react';\nimport type { TextProps } from 'react-native';\n\nconst reactNative = require('react-native');\nconst isWeb = reactNative.Platform.OS === 'web';\n\nlet nativeText = reactNative.unstable_NativeText;\n\nif (isWeb || nativeText == null) {\n // Fallback to regular Text component if unstable_NativeText is not available or we're on Web\n nativeText = reactNative.Text;\n}\n\n/**\n * Native Text component with graceful fallback.\n *\n * @remarks\n * Uses `unstable_NativeText` on supported native runtimes and falls back to `Text`\n * on web or when the unstable export is unavailable.\n */\nexport const NativeText: ComponentType<TextProps> = nativeText;\n","/* eslint-disable @typescript-eslint/no-require-imports,unicorn/prefer-module */\n\nimport type { ComponentType } from 'react';\nimport type { ViewProps } from 'react-native';\n\nconst reactNative = require('react-native');\nconst isWeb = reactNative.Platform.OS === 'web';\n\nlet nativeView = reactNative.unstable_NativeView;\n\nif (isWeb || nativeView == null) {\n // Fallback to regular View component if unstable_NativeView is not available or we're on Web\n nativeView = reactNative.View;\n}\n\n/**\n * Native View component with graceful fallback.\n *\n * @remarks\n * Uses `unstable_NativeView` on supported native runtimes and falls back to `View`\n * on web or when the unstable export is unavailable.\n */\nexport const NativeView: ComponentType<ViewProps> = nativeView;\n","import { TextProps, TextStyle, StyleSheet, Platform } from 'react-native';\nimport { GenericStyleProp } from './types';\nimport { userSelectToSelectableMap, verticalAlignToTextAlignVerticalMap } from './utils/constants';\n\nconst propsCache = new WeakMap();\n\n/**\n * Normalizes `Text` style values for `NativeText`.\n *\n * @param style - Style prop passed to a text-like component.\n * @returns Native-friendly text props. Returns an empty object when `style` is falsy or cannot be normalized.\n * @remarks\n * - Flattens style arrays via `StyleSheet.flatten`\n * - Converts numeric `fontWeight` values to string values\n * - Maps `userSelect` and `verticalAlign` to native-compatible props\n */\nexport function processTextStyle(style: GenericStyleProp<TextStyle>): Partial<TextProps> {\n if (!style) return {};\n\n // Cache the computed props\n let props = propsCache.get(style);\n if (props) return props;\n\n props = {};\n propsCache.set(style, props);\n\n style = StyleSheet.flatten(style) as TextStyle;\n\n if (!style) return {};\n\n if (typeof style?.fontWeight === 'number') {\n style.fontWeight = style.fontWeight.toString() as TextStyle['fontWeight'];\n }\n\n if (style?.userSelect != null) {\n props.selectable = userSelectToSelectableMap[style.userSelect];\n delete style.userSelect;\n }\n\n if (style?.verticalAlign != null) {\n style.textAlignVertical = verticalAlignToTextAlignVerticalMap[\n style.verticalAlign\n ] as TextStyle['textAlignVertical'];\n delete style.verticalAlign;\n }\n\n props.style = style;\n return props;\n}\n\n/**\n * The default value `Text` resolves for `accessible` when the prop is omitted: `true` on iOS (text is\n * an accessibility element unless opted out), `false` on Android, and `undefined` elsewhere.\n *\n * @remarks\n * Runtime fallback for the common optimized `<Text>` path (no accessibility props) when the target\n * platform is unknown at build time. When it is known (Metro reports it on the Babel caller), the\n * plugin inlines the literal instead and this is not emitted. Evaluated per render — like `Text`'s own\n * `Platform.select` — rather than hoisted to a constant, so it always reflects the current platform.\n */\nexport const getDefaultTextAccessible = (): boolean | undefined => Platform.select({ ios: true, android: false });\n\n/**\n * Normalizes accessibility and ARIA props for runtime native components, mirroring the reconciliation\n * `Text` performs before handing off to its native host.\n *\n * @param props - Accessibility and ARIA props.\n * @returns Props with normalized accessibility fields.\n * @remarks\n * - Merges `aria-label` with `accessibilityLabel`\n * - Merges ARIA state fields into `accessibilityState`\n * - Reconciles `disabled` with `accessibilityState.disabled` (the explicit `disabled` prop wins)\n * - Resolves the platform-specific `accessible` default (see {@link getDefaultTextAccessible})\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function processAccessibilityProps(props: Record<string, any>): Record<string, any> {\n const {\n accessibilityLabel,\n ['aria-label']: ariaLabel,\n accessibilityState,\n ['aria-busy']: ariaBusy,\n ['aria-checked']: ariaChecked,\n ['aria-disabled']: ariaDisabled,\n ['aria-expanded']: ariaExpanded,\n ['aria-selected']: ariaSelected,\n accessible,\n disabled,\n ...restProperties\n } = props;\n\n // Merge label props: prefer the aria-label if defined.\n const normalizedLabel = ariaLabel ?? accessibilityLabel;\n\n // Merge the accessibilityState with any provided ARIA properties.\n let normalizedState = accessibilityState;\n if (ariaBusy != null || ariaChecked != null || ariaDisabled != null || ariaExpanded != null || ariaSelected != null) {\n normalizedState =\n normalizedState == null\n ? {\n busy: ariaBusy,\n checked: ariaChecked,\n disabled: ariaDisabled,\n expanded: ariaExpanded,\n selected: ariaSelected,\n }\n : {\n busy: ariaBusy ?? normalizedState.busy,\n checked: ariaChecked ?? normalizedState.checked,\n disabled: ariaDisabled ?? normalizedState.disabled,\n expanded: ariaExpanded ?? normalizedState.expanded,\n selected: ariaSelected ?? normalizedState.selected,\n };\n }\n\n // Reconcile `disabled` with `accessibilityState.disabled`. When the two are out of sync (and not\n // both falsy) the explicit `disabled` prop wins and is mirrored back into the state object, so the\n // native host receives a consistent value on both fields.\n const stateDisabled = normalizedState?.disabled;\n const normalizedDisabled = disabled ?? stateDisabled;\n if (\n normalizedDisabled !== stateDisabled &&\n ((normalizedDisabled != null && normalizedDisabled !== false) || (stateDisabled != null && stateDisabled !== false))\n ) {\n normalizedState = { ...normalizedState, disabled: normalizedDisabled };\n }\n\n // Resolve `accessible` exactly as `Text` does: opt-out on iOS, off by default on Android. The\n // Android pressable case (`onPress`/`onLongPress`) never applies — press handlers bail out of\n // optimization — so an omitted prop falls back to the platform default.\n const normalizedAccessible = Platform.select({\n ios: accessible !== false,\n android: accessible ?? false,\n default: accessible,\n });\n\n return {\n ...restProperties,\n accessibilityLabel: normalizedLabel,\n accessibilityState: normalizedState,\n accessible: normalizedAccessible,\n disabled: normalizedDisabled,\n };\n}\n\nexport * from './types';\nexport * from './utils/constants';\nexport * from './components/native-text';\nexport * from './components/native-view';\n"],"names":["reactNative","isWeb","StyleSheet","Platform"],"mappings":"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"}
@@ -28,10 +28,11 @@ declare const verticalAlignToTextAlignVerticalMap: {
28
28
  };
29
29
 
30
30
  declare const processTextStyle: (style: GenericStyleProp<TextStyle>) => Partial<TextProps>;
31
+ declare const getDefaultTextAccessible: () => boolean | undefined;
31
32
  declare function processAccessibilityProps(props: Record<string, any>): Record<string, any>;
32
33
 
33
34
  declare const NativeText: any;
34
35
  declare const NativeView: any;
35
36
 
36
- export { NativeText, NativeView, processAccessibilityProps, processTextStyle, userSelectToSelectableMap, verticalAlignToTextAlignVerticalMap };
37
+ export { NativeText, NativeView, getDefaultTextAccessible, processAccessibilityProps, processTextStyle, userSelectToSelectableMap, verticalAlignToTextAlignVerticalMap };
37
38
  export type { GenericStyleProp };
@@ -15,6 +15,7 @@ const verticalAlignToTextAlignVerticalMap = {
15
15
  };
16
16
 
17
17
  const processTextStyle = (style) => ({ style });
18
+ const getDefaultTextAccessible = () => void 0;
18
19
  function processAccessibilityProps(props) {
19
20
  return props;
20
21
  }
@@ -23,6 +24,7 @@ const NativeView = require("react-native").View;
23
24
 
24
25
  exports.NativeText = NativeText;
25
26
  exports.NativeView = NativeView;
27
+ exports.getDefaultTextAccessible = getDefaultTextAccessible;
26
28
  exports.processAccessibilityProps = processAccessibilityProps;
27
29
  exports.processTextStyle = processTextStyle;
28
30
  exports.userSelectToSelectableMap = userSelectToSelectableMap;
@@ -1 +1 @@
1
- {"version":3,"file":"index.web.js","sources":["../../src/runtime/utils/constants.ts","../../src/runtime/index.web.ts"],"sourcesContent":["/**\n * Maps CSS-like `userSelect` values to React Native's `selectable` prop.\n */\nexport const userSelectToSelectableMap = {\n auto: true,\n text: true,\n none: false,\n contain: true,\n all: true,\n};\n\n/**\n * Maps CSS-like `verticalAlign` values to React Native's `textAlignVertical`.\n */\nexport const verticalAlignToTextAlignVerticalMap = {\n auto: 'auto',\n top: 'top',\n bottom: 'bottom',\n middle: 'center',\n};\n","// This is a dummy file to ensure that nothing breaks when using the runtime in a web environment.\n\nimport { TextProps, TextStyle } from 'react-native';\nimport { GenericStyleProp } from './types';\n\nexport const processTextStyle = (style: GenericStyleProp<TextStyle>) => ({ style }) as Partial<TextProps>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function processAccessibilityProps(props: Record<string, any>): Record<string, any> {\n return props;\n}\n\nexport * from './types';\nexport * from './utils/constants';\n\n// On Web, the native components are not available, so we use the standard components that'll be replaced by their DOM\n// equivalents by react-native-web.\n/* eslint-disable @typescript-eslint/no-require-imports,unicorn/prefer-module */\nexport const NativeText = require('react-native').Text;\nexport const NativeView = require('react-native').View;\n/* eslint-enable @typescript-eslint/no-require-imports,unicorn/prefer-module */\n"],"names":[],"mappings":";;AAGO,MAAM,yBAAA,GAA4B;AAAA,EACvC,IAAA,EAAM,IAAA;AAAA,EACN,IAAA,EAAM,IAAA;AAAA,EACN,IAAA,EAAM,KAAA;AAAA,EACN,OAAA,EAAS,IAAA;AAAA,EACT,GAAA,EAAK;AACP;AAKO,MAAM,mCAAA,GAAsC;AAAA,EACjD,IAAA,EAAM,MAAA;AAAA,EACN,GAAA,EAAK,KAAA;AAAA,EACL,MAAA,EAAQ,QAAA;AAAA,EACR,MAAA,EAAQ;AACV;;ACdO,MAAM,gBAAA,GAAmB,CAAC,KAAA,MAAwC,EAAE,KAAA,EAAM;AAG1E,SAAS,0BAA0B,KAAA,EAAiD;AACzF,EAAA,OAAO,KAAA;AACT;AAQO,MAAM,UAAA,GAAa,OAAA,CAAQ,cAAc,CAAA,CAAE;AAC3C,MAAM,UAAA,GAAa,OAAA,CAAQ,cAAc,CAAA,CAAE;;;;;;;;;"}
1
+ {"version":3,"file":"index.web.js","sources":["../../src/runtime/utils/constants.ts","../../src/runtime/index.web.ts"],"sourcesContent":["/**\n * Maps CSS-like `userSelect` values to React Native's `selectable` prop.\n */\nexport const userSelectToSelectableMap = {\n auto: true,\n text: true,\n none: false,\n contain: true,\n all: true,\n};\n\n/**\n * Maps CSS-like `verticalAlign` values to React Native's `textAlignVertical`.\n */\nexport const verticalAlignToTextAlignVerticalMap = {\n auto: 'auto',\n top: 'top',\n bottom: 'bottom',\n middle: 'center',\n};\n","// This is a dummy file to ensure that nothing breaks when using the runtime in a web environment.\n\nimport { TextProps, TextStyle } from 'react-native';\nimport { GenericStyleProp } from './types';\n\nexport const processTextStyle = (style: GenericStyleProp<TextStyle>) => ({ style }) as Partial<TextProps>;\n\n// On Web there is no platform-specific `accessible` default to apply; react-native-web's `Text`\n// derives accessibility from the rendered DOM. Returning `undefined` makes the injected\n// `accessible={getDefaultTextAccessible()}` a no-op.\nexport const getDefaultTextAccessible = (): boolean | undefined => undefined;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function processAccessibilityProps(props: Record<string, any>): Record<string, any> {\n return props;\n}\n\nexport * from './types';\nexport * from './utils/constants';\n\n// On Web, the native components are not available, so we use the standard components that'll be replaced by their DOM\n// equivalents by react-native-web.\n/* eslint-disable @typescript-eslint/no-require-imports,unicorn/prefer-module */\nexport const NativeText = require('react-native').Text;\nexport const NativeView = require('react-native').View;\n/* eslint-enable @typescript-eslint/no-require-imports,unicorn/prefer-module */\n"],"names":[],"mappings":";;AAGO,MAAM,yBAAA,GAA4B;AAAA,EACvC,IAAA,EAAM,IAAA;AAAA,EACN,IAAA,EAAM,IAAA;AAAA,EACN,IAAA,EAAM,KAAA;AAAA,EACN,OAAA,EAAS,IAAA;AAAA,EACT,GAAA,EAAK;AACP;AAKO,MAAM,mCAAA,GAAsC;AAAA,EACjD,IAAA,EAAM,MAAA;AAAA,EACN,GAAA,EAAK,KAAA;AAAA,EACL,MAAA,EAAQ,QAAA;AAAA,EACR,MAAA,EAAQ;AACV;;ACdO,MAAM,gBAAA,GAAmB,CAAC,KAAA,MAAwC,EAAE,KAAA,EAAM;AAK1E,MAAM,2BAA2B,MAA2B;AAG5D,SAAS,0BAA0B,KAAA,EAAiD;AACzF,EAAA,OAAO,KAAA;AACT;AAQO,MAAM,UAAA,GAAa,OAAA,CAAQ,cAAc,CAAA,CAAE;AAC3C,MAAM,UAAA,GAAa,OAAA,CAAQ,cAAc,CAAA,CAAE;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-native-boost",
3
3
  "description": "🚀 Boost your React Native app's performance with a single line of code",
4
- "version": "1.0.0",
4
+ "version": "1.2.0",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/esm/index.mjs",
7
7
  "types": "dist/index.d.ts",
@@ -88,7 +88,9 @@
88
88
  },
89
89
  "devDependencies": {
90
90
  "@babel/plugin-syntax-jsx": "^7.25.0",
91
+ "@babel/preset-react": "^7.25.0",
91
92
  "@babel/preset-typescript": "^7.25.0",
93
+ "@react-native/babel-preset": "0.83.2",
92
94
  "@release-it/conventional-changelog": "^10.0.0",
93
95
  "@rollup/plugin-alias": "^6.0.0",
94
96
  "@rollup/plugin-node-resolve": "^16.0.0",
@@ -99,6 +101,8 @@
99
101
  "@types/node": "^24",
100
102
  "babel-plugin-tester": "^12.0.0",
101
103
  "esbuild-node-externals": "^1.18.0",
104
+ "react": "19.2.0",
105
+ "react-dom": "19.2.0",
102
106
  "react-native": "0.83.2",
103
107
  "release-it": "^19.2.4",
104
108
  "rollup": "^4.34.8",
@@ -118,6 +122,7 @@
118
122
  },
119
123
  "npm": {
120
124
  "publish": true,
125
+ "skipChecks": true,
121
126
  "versionArgs": [
122
127
  "--workspaces-update=false"
123
128
  ]
@@ -15,6 +15,10 @@ type PluginState = {
15
15
  export default declare((api) => {
16
16
  api.assertVersion(7);
17
17
 
18
+ // Target platform, resolved at build time. Metro sets this on the Babel caller per platform bundle,
19
+ // letting optimizers inline platform-specific defaults instead of deferring them to the runtime.
20
+ const platform = api.caller((caller) => (caller as { platform?: string } | undefined)?.platform);
21
+
18
22
  return {
19
23
  name: 'react-native-boost',
20
24
  visitor: {
@@ -24,7 +28,7 @@ export default declare((api) => {
24
28
  const logger = getOrCreateLogger(pluginState, options);
25
29
 
26
30
  if (isIgnoredFile(path, options.ignores ?? [])) return;
27
- if (options.optimizations?.text !== false) textOptimizer(path, logger);
31
+ if (options.optimizations?.text !== false) textOptimizer(path, logger, options, platform);
28
32
  if (options.optimizations?.view !== false) viewOptimizer(path, logger, options);
29
33
  },
30
34
  },
@@ -1,25 +1,31 @@
1
1
  import { NodePath, types as t } from '@babel/core';
2
2
  import { HubFile, Optimizer, PluginLogger } from '../../types';
3
3
  import PluginError from '../../utils/plugin-error';
4
- import { getFirstBailoutReason } from '../../utils/helpers';
4
+ import { BailoutCheck, getFirstBailoutReason } from '../../utils/helpers';
5
5
  import {
6
6
  addDefaultProperty,
7
7
  addFileImportHint,
8
8
  buildPropertiesFromAttributes,
9
9
  hasAccessibilityProperty,
10
10
  hasBlacklistedProperty,
11
+ isForcedLine,
11
12
  isIgnoredLine,
12
13
  isValidJSXComponent,
13
14
  isReactNativeImport,
14
15
  replaceWithNativeComponent,
15
- isStringNode,
16
+ isPrimitiveChild,
16
17
  hasExpoRouterLinkParentWithAsChild,
18
+ extractStyleAttribute,
19
+ extractSelectableAndUpdateStyle,
20
+ ancestorBailoutChecks,
17
21
  } from '../../utils/common';
18
- import { RUNTIME_MODULE_NAME } from '../../utils/constants';
19
- import { ACCESSIBILITY_PROPERTIES } from '../../utils/constants';
20
- import { extractStyleAttribute, extractSelectableAndUpdateStyle } from '../../utils/common';
22
+ import { ACCESSIBILITY_PROPERTIES, RUNTIME_MODULE_NAME } from '../../utils/constants';
21
23
 
22
24
  export const textBlacklistedProperties = new Set([
25
+ // The `Text` wrapper translates `aria-hidden` into `accessibilityElementsHidden` /
26
+ // `importantForAccessibility`, which `processAccessibilityProps` does not yet handle. Passing it
27
+ // through would drop it, so bail. TODO: handle this in the runtime helper instead.
28
+ 'aria-hidden',
23
29
  'id',
24
30
  'nativeID',
25
31
  'onLongPress',
@@ -37,21 +43,27 @@ export const textBlacklistedProperties = new Set([
37
43
  'selectionColor', // TODO: we can use react-native's internal `processColor` to process this at runtime
38
44
  ]);
39
45
 
40
- export const textOptimizer: Optimizer = (path, logger) => {
46
+ /**
47
+ * Props handed off to `processAccessibilityProps` at runtime: the accessibility props plus `disabled`,
48
+ * which `Text` reconciles against `accessibilityState.disabled`. They are collected into a single
49
+ * helper call and stripped from the element so they are not also emitted verbatim.
50
+ */
51
+ const NORMALIZED_PROPERTIES = new Set([...ACCESSIBILITY_PROPERTIES, 'disabled']);
52
+
53
+ /**
54
+ * Type guard for a direct JSX attribute whose name is in {@link NORMALIZED_PROPERTIES}.
55
+ */
56
+ const isNormalizedProperty = (attribute: t.JSXAttribute | t.JSXSpreadAttribute): attribute is t.JSXAttribute =>
57
+ t.isJSXAttribute(attribute) && t.isJSXIdentifier(attribute.name) && NORMALIZED_PROPERTIES.has(attribute.name.name);
58
+
59
+ export const textOptimizer: Optimizer = (path, logger, options, platform) => {
41
60
  if (!isValidJSXComponent(path, 'Text')) return;
61
+ if (!isReactNativeImport(path, 'Text')) return;
42
62
 
43
- // Verify that the Text only has string children
44
63
  const parent = path.parent as t.JSXElement;
64
+ const forced = isForcedLine(path);
45
65
 
46
- const skipReason = getFirstBailoutReason([
47
- {
48
- reason: 'line is marked with @boost-ignore',
49
- shouldBail: () => isIgnoredLine(path),
50
- },
51
- {
52
- reason: 'Text is not imported from react-native',
53
- shouldBail: () => !isReactNativeImport(path, 'Text'),
54
- },
66
+ const overridableChecks: BailoutCheck[] = [
55
67
  {
56
68
  reason: 'contains blacklisted props',
57
69
  shouldBail: () => hasBlacklistedProperty(path, textBlacklistedProperties),
@@ -60,19 +72,34 @@ export const textOptimizer: Optimizer = (path, logger) => {
60
72
  reason: 'is a direct child of expo-router Link with asChild',
61
73
  shouldBail: () => hasExpoRouterLinkParentWithAsChild(path),
62
74
  },
75
+ // The local children check runs before the ancestor checks because it is cheap and prunes the
76
+ // common nested-element `Text` before the unbounded ancestor walk those checks trigger.
63
77
  {
64
- reason: 'contains non-string children',
78
+ reason: 'contains non-primitive children',
65
79
  shouldBail: () => hasInvalidChildren(path, parent),
66
80
  },
67
- ]);
81
+ ...ancestorBailoutChecks(path, options?.dangerouslyOptimizeTextWithUnknownAncestors === true),
82
+ ];
68
83
 
69
- if (skipReason) {
70
- logger.skipped({
71
- component: 'Text',
72
- path,
73
- reason: skipReason,
74
- });
75
- return;
84
+ if (forced) {
85
+ const overriddenReason = getFirstBailoutReason(overridableChecks);
86
+
87
+ if (overriddenReason) {
88
+ logger.forced({ component: 'Text', path, reason: overriddenReason });
89
+ }
90
+ } else {
91
+ const skipReason = getFirstBailoutReason([
92
+ {
93
+ reason: 'line is marked with @boost-ignore',
94
+ shouldBail: () => isIgnoredLine(path),
95
+ },
96
+ ...overridableChecks,
97
+ ]);
98
+
99
+ if (skipReason) {
100
+ logger.skipped({ component: 'Text', path, reason: skipReason });
101
+ return;
102
+ }
76
103
  }
77
104
 
78
105
  const hub = path.hub as unknown;
@@ -91,7 +118,7 @@ export const textOptimizer: Optimizer = (path, logger) => {
91
118
  fixNegativeNumberOfLines({ path, logger });
92
119
  addDefaultProperty(path, 'allowFontScaling', t.booleanLiteral(true));
93
120
  addDefaultProperty(path, 'ellipsizeMode', t.stringLiteral('tail'));
94
- processProps(path, file);
121
+ processProps(path, file, platform);
95
122
 
96
123
  // Replace the Text component with NativeText
97
124
  replaceWithNativeComponent(path, parent, file, 'NativeText');
@@ -112,16 +139,16 @@ function hasInvalidChildren(path: NodePath<t.JSXOpeningElement>, parent: t.JSXEl
112
139
  if (
113
140
  t.isJSXIdentifier(attribute.name) &&
114
141
  attribute.value &&
115
- // For a "children" attribute, optimization is allowed only if it is a string
142
+ // For a "children" attribute, optimization is allowed only if it is a provable primitive
116
143
  attribute.name.name === 'children' &&
117
- !isStringNode(path, attribute.value)
144
+ !isPrimitiveChild(path, attribute.value)
118
145
  ) {
119
146
  return true;
120
147
  }
121
148
  }
122
149
 
123
- // Return true if any child is not a string node
124
- return !parent.children.every((child) => isStringNode(path, child));
150
+ // Return true if any child is not a provably-primitive node
151
+ return !parent.children.every((child) => isPrimitiveChild(path, child));
125
152
  }
126
153
 
127
154
  /**
@@ -160,25 +187,31 @@ function fixNegativeNumberOfLines({ path, logger }: { path: NodePath<t.JSXOpenin
160
187
  /**
161
188
  * Processes style and accessibility attributes, replacing them with optimized versions.
162
189
  */
163
- function processProps(path: NodePath<t.JSXOpeningElement>, file: HubFile) {
190
+ function processProps(path: NodePath<t.JSXOpeningElement>, file: HubFile, platform?: string) {
164
191
  // Grab the up-to-date list of attributes
165
192
  const currentAttributes = [...path.node.attributes];
166
193
 
167
194
  const { styleExpr, styleAttribute } = extractStyleAttribute(currentAttributes);
168
- const hasA11y = hasAccessibilityProperty(path, currentAttributes);
195
+
196
+ // `Text` always resolves a platform-specific `accessible` default and reconciles `disabled` with
197
+ // `accessibilityState.disabled`. When any accessibility prop or `disabled` is present we hand the
198
+ // element off to `processAccessibilityProps` (which also performs the aria/label merges); otherwise
199
+ // only the `accessible` default is needed, so we inject it directly to keep the common path cheap.
200
+ const shouldNormalize =
201
+ hasAccessibilityProperty(path, currentAttributes) ||
202
+ currentAttributes.some(
203
+ (attribute) => t.isJSXAttribute(attribute) && t.isJSXIdentifier(attribute.name, { name: 'disabled' })
204
+ );
169
205
 
170
206
  // ============================================
171
- // 1. Prepare spread attributes (style / a11y)
207
+ // 1. Prepare spread attributes (a11y / style)
172
208
  // ============================================
173
209
 
174
210
  const spreadAttributes: t.JSXSpreadAttribute[] = [];
175
211
 
176
- // --- Accessibility ---
177
- if (hasA11y) {
178
- const accessibilityAttributes = currentAttributes.filter((attribute) => {
179
- if (!t.isJSXAttribute(attribute)) return false;
180
- return t.isJSXIdentifier(attribute.name) && ACCESSIBILITY_PROPERTIES.has(attribute.name.name as string);
181
- });
212
+ // --- Accessibility & `disabled` ---
213
+ if (shouldNormalize) {
214
+ const normalizedAttributes = currentAttributes.filter((attribute) => isNormalizedProperty(attribute));
182
215
 
183
216
  const normalizeIdentifier = addFileImportHint({
184
217
  file,
@@ -188,7 +221,7 @@ function processProps(path: NodePath<t.JSXOpeningElement>, file: HubFile) {
188
221
  moduleName: RUNTIME_MODULE_NAME,
189
222
  });
190
223
 
191
- const accessibilityObject = buildPropertiesFromAttributes(accessibilityAttributes);
224
+ const accessibilityObject = buildPropertiesFromAttributes(normalizedAttributes);
192
225
  const accessibilityExpr = t.callExpression(t.identifier(normalizeIdentifier.name), [accessibilityObject]);
193
226
  spreadAttributes.push(t.jsxSpreadAttribute(accessibilityExpr));
194
227
  }
@@ -226,20 +259,55 @@ function processProps(path: NodePath<t.JSXOpeningElement>, file: HubFile) {
226
259
  // Skip the style attribute (we have replaced it with a spread)
227
260
  if (styleAttribute && attribute === styleAttribute) continue;
228
261
 
229
- // Skip accessibility attributes if we processed them
230
- if (
231
- hasA11y &&
232
- t.isJSXAttribute(attribute) &&
233
- t.isJSXIdentifier(attribute.name) &&
234
- ACCESSIBILITY_PROPERTIES.has(attribute.name.name as string)
235
- ) {
236
- continue;
237
- }
262
+ // Skip the props we routed through `processAccessibilityProps`
263
+ if (shouldNormalize && isNormalizedProperty(attribute)) continue;
238
264
 
239
265
  remainingAttributes.push(attribute);
240
266
  }
241
267
 
242
- path.node.attributes = [...spreadAttributes, selectableAttribute, ...remainingAttributes].filter(
268
+ // ============================================
269
+ // 3. `accessible` default for the common path
270
+ // ============================================
271
+ // With no accessibility/`disabled` prop the helper is skipped, but `Text` still applies a
272
+ // platform-specific `accessible` default. We build it explicitly (rather than via `addDefaultProperty`,
273
+ // which gives up when it hits the unresolvable `{...processTextStyle(...)}` spread and would silently
274
+ // drop the default on styled text). The cheap path guarantees no `accessible` is already set — any
275
+ // such prop would have set `shouldNormalize`, and unresolvable spreads bail before this point — so
276
+ // appending it unconditionally is safe.
277
+ const accessibleAttribute = shouldNormalize ? undefined : buildAccessibleDefault(path, file, platform);
278
+
279
+ path.node.attributes = [...spreadAttributes, selectableAttribute, ...remainingAttributes, accessibleAttribute].filter(
243
280
  (attribute): attribute is t.JSXAttribute | t.JSXSpreadAttribute => attribute !== undefined
244
281
  );
245
282
  }
283
+
284
+ /**
285
+ * Builds the `accessible` default attribute `Text` applies when the prop is omitted: `true` on iOS,
286
+ * `false` on Android, omitted on web. Metro bundles per platform and reports the target on the Babel
287
+ * caller, so a known platform is inlined as a literal; an unknown platform (non-Metro bundlers,
288
+ * fixture tests) defers to the lightweight runtime resolver. Returns `undefined` when nothing should
289
+ * be emitted.
290
+ */
291
+ function buildAccessibleDefault(
292
+ path: NodePath<t.JSXOpeningElement>,
293
+ file: HubFile,
294
+ platform?: string
295
+ ): t.JSXAttribute | undefined {
296
+ if (platform === 'web') return undefined;
297
+
298
+ let value: t.Expression;
299
+ if (platform === 'ios' || platform === 'android') {
300
+ value = t.booleanLiteral(platform === 'ios');
301
+ } else {
302
+ const accessibleIdentifier = addFileImportHint({
303
+ file,
304
+ nameHint: 'getDefaultTextAccessible',
305
+ path,
306
+ importName: 'getDefaultTextAccessible',
307
+ moduleName: RUNTIME_MODULE_NAME,
308
+ });
309
+ value = t.callExpression(t.identifier(accessibleIdentifier.name), []);
310
+ }
311
+
312
+ return t.jsxAttribute(t.jsxIdentifier('accessible'), t.jsxExpressionContainer(value));
313
+ }