react-native-boost 1.1.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.1.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",
@@ -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
  },
@@ -13,14 +13,19 @@ import {
13
13
  isValidJSXComponent,
14
14
  isReactNativeImport,
15
15
  replaceWithNativeComponent,
16
- isStringNode,
16
+ isPrimitiveChild,
17
17
  hasExpoRouterLinkParentWithAsChild,
18
+ extractStyleAttribute,
19
+ extractSelectableAndUpdateStyle,
20
+ ancestorBailoutChecks,
18
21
  } from '../../utils/common';
19
- import { RUNTIME_MODULE_NAME } from '../../utils/constants';
20
- import { ACCESSIBILITY_PROPERTIES } from '../../utils/constants';
21
- import { extractStyleAttribute, extractSelectableAndUpdateStyle } from '../../utils/common';
22
+ import { ACCESSIBILITY_PROPERTIES, RUNTIME_MODULE_NAME } from '../../utils/constants';
22
23
 
23
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',
24
29
  'id',
25
30
  'nativeID',
26
31
  'onLongPress',
@@ -38,7 +43,20 @@ export const textBlacklistedProperties = new Set([
38
43
  'selectionColor', // TODO: we can use react-native's internal `processColor` to process this at runtime
39
44
  ]);
40
45
 
41
- 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) => {
42
60
  if (!isValidJSXComponent(path, 'Text')) return;
43
61
  if (!isReactNativeImport(path, 'Text')) return;
44
62
 
@@ -54,10 +72,13 @@ export const textOptimizer: Optimizer = (path, logger) => {
54
72
  reason: 'is a direct child of expo-router Link with asChild',
55
73
  shouldBail: () => hasExpoRouterLinkParentWithAsChild(path),
56
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.
57
77
  {
58
- reason: 'contains non-string children',
78
+ reason: 'contains non-primitive children',
59
79
  shouldBail: () => hasInvalidChildren(path, parent),
60
80
  },
81
+ ...ancestorBailoutChecks(path, options?.dangerouslyOptimizeTextWithUnknownAncestors === true),
61
82
  ];
62
83
 
63
84
  if (forced) {
@@ -97,7 +118,7 @@ export const textOptimizer: Optimizer = (path, logger) => {
97
118
  fixNegativeNumberOfLines({ path, logger });
98
119
  addDefaultProperty(path, 'allowFontScaling', t.booleanLiteral(true));
99
120
  addDefaultProperty(path, 'ellipsizeMode', t.stringLiteral('tail'));
100
- processProps(path, file);
121
+ processProps(path, file, platform);
101
122
 
102
123
  // Replace the Text component with NativeText
103
124
  replaceWithNativeComponent(path, parent, file, 'NativeText');
@@ -118,16 +139,16 @@ function hasInvalidChildren(path: NodePath<t.JSXOpeningElement>, parent: t.JSXEl
118
139
  if (
119
140
  t.isJSXIdentifier(attribute.name) &&
120
141
  attribute.value &&
121
- // 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
122
143
  attribute.name.name === 'children' &&
123
- !isStringNode(path, attribute.value)
144
+ !isPrimitiveChild(path, attribute.value)
124
145
  ) {
125
146
  return true;
126
147
  }
127
148
  }
128
149
 
129
- // Return true if any child is not a string node
130
- 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));
131
152
  }
132
153
 
133
154
  /**
@@ -166,25 +187,31 @@ function fixNegativeNumberOfLines({ path, logger }: { path: NodePath<t.JSXOpenin
166
187
  /**
167
188
  * Processes style and accessibility attributes, replacing them with optimized versions.
168
189
  */
169
- function processProps(path: NodePath<t.JSXOpeningElement>, file: HubFile) {
190
+ function processProps(path: NodePath<t.JSXOpeningElement>, file: HubFile, platform?: string) {
170
191
  // Grab the up-to-date list of attributes
171
192
  const currentAttributes = [...path.node.attributes];
172
193
 
173
194
  const { styleExpr, styleAttribute } = extractStyleAttribute(currentAttributes);
174
- 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
+ );
175
205
 
176
206
  // ============================================
177
- // 1. Prepare spread attributes (style / a11y)
207
+ // 1. Prepare spread attributes (a11y / style)
178
208
  // ============================================
179
209
 
180
210
  const spreadAttributes: t.JSXSpreadAttribute[] = [];
181
211
 
182
- // --- Accessibility ---
183
- if (hasA11y) {
184
- const accessibilityAttributes = currentAttributes.filter((attribute) => {
185
- if (!t.isJSXAttribute(attribute)) return false;
186
- return t.isJSXIdentifier(attribute.name) && ACCESSIBILITY_PROPERTIES.has(attribute.name.name as string);
187
- });
212
+ // --- Accessibility & `disabled` ---
213
+ if (shouldNormalize) {
214
+ const normalizedAttributes = currentAttributes.filter((attribute) => isNormalizedProperty(attribute));
188
215
 
189
216
  const normalizeIdentifier = addFileImportHint({
190
217
  file,
@@ -194,7 +221,7 @@ function processProps(path: NodePath<t.JSXOpeningElement>, file: HubFile) {
194
221
  moduleName: RUNTIME_MODULE_NAME,
195
222
  });
196
223
 
197
- const accessibilityObject = buildPropertiesFromAttributes(accessibilityAttributes);
224
+ const accessibilityObject = buildPropertiesFromAttributes(normalizedAttributes);
198
225
  const accessibilityExpr = t.callExpression(t.identifier(normalizeIdentifier.name), [accessibilityObject]);
199
226
  spreadAttributes.push(t.jsxSpreadAttribute(accessibilityExpr));
200
227
  }
@@ -232,20 +259,55 @@ function processProps(path: NodePath<t.JSXOpeningElement>, file: HubFile) {
232
259
  // Skip the style attribute (we have replaced it with a spread)
233
260
  if (styleAttribute && attribute === styleAttribute) continue;
234
261
 
235
- // Skip accessibility attributes if we processed them
236
- if (
237
- hasA11y &&
238
- t.isJSXAttribute(attribute) &&
239
- t.isJSXIdentifier(attribute.name) &&
240
- ACCESSIBILITY_PROPERTIES.has(attribute.name.name as string)
241
- ) {
242
- continue;
243
- }
262
+ // Skip the props we routed through `processAccessibilityProps`
263
+ if (shouldNormalize && isNormalizedProperty(attribute)) continue;
244
264
 
245
265
  remainingAttributes.push(attribute);
246
266
  }
247
267
 
248
- 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(
249
280
  (attribute): attribute is t.JSXAttribute | t.JSXSpreadAttribute => attribute !== undefined
250
281
  );
251
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
+ }
@@ -9,12 +9,13 @@ import {
9
9
  isValidJSXComponent,
10
10
  isReactNativeImport,
11
11
  replaceWithNativeComponent,
12
- getViewAncestorClassification,
13
- ViewAncestorClassification,
12
+ ancestorBailoutChecks,
14
13
  } from '../../utils/common';
15
14
 
16
15
  export const viewBlacklistedProperties = new Set([
17
- // TODO: process a11y props at runtime
16
+ // The `View` wrapper translates these into native props (e.g. `aria-*` → `accessibility*`,
17
+ // `tabIndex` → `focusable`). The native host does not understand them, so passing them through
18
+ // would silently drop them. TODO: process these at runtime instead of bailing.
18
19
  'accessible',
19
20
  'accessibilityLabel',
20
21
  'accessibilityState',
@@ -22,26 +23,24 @@ export const viewBlacklistedProperties = new Set([
22
23
  'aria-checked',
23
24
  'aria-disabled',
24
25
  'aria-expanded',
26
+ 'aria-hidden',
25
27
  'aria-label',
28
+ 'aria-labelledby',
29
+ 'aria-live',
26
30
  'aria-selected',
31
+ 'aria-valuemax',
32
+ 'aria-valuemin',
33
+ 'aria-valuenow',
34
+ 'aria-valuetext',
27
35
  'id',
28
36
  'nativeID',
29
- 'style', // TODO: process style at runtime
37
+ 'tabIndex',
30
38
  ]);
31
39
 
32
40
  export const viewOptimizer: Optimizer = (path, logger, options) => {
33
41
  if (!isValidJSXComponent(path, 'View')) return;
34
42
  if (!isReactNativeImport(path, 'View')) return;
35
43
 
36
- let ancestorClassification: ViewAncestorClassification | undefined;
37
- const getAncestorClassification = () => {
38
- if (!ancestorClassification) {
39
- ancestorClassification = getViewAncestorClassification(path);
40
- }
41
-
42
- return ancestorClassification;
43
- };
44
-
45
44
  const forced = isForcedLine(path);
46
45
 
47
46
  const overridableChecks: BailoutCheck[] = [
@@ -49,15 +48,7 @@ export const viewOptimizer: Optimizer = (path, logger, options) => {
49
48
  reason: 'contains blacklisted props',
50
49
  shouldBail: () => hasBlacklistedProperty(path, viewBlacklistedProperties),
51
50
  },
52
- {
53
- reason: 'has Text ancestor',
54
- shouldBail: () => getAncestorClassification() === 'text',
55
- },
56
- {
57
- reason: 'has unresolved ancestor and dangerous optimization is disabled',
58
- shouldBail: () =>
59
- getAncestorClassification() === 'unknown' && options?.dangerouslyOptimizeViewWithUnknownAncestors !== true,
60
- },
51
+ ...ancestorBailoutChecks(path, options?.dangerouslyOptimizeViewWithUnknownAncestors === true),
61
52
  ];
62
53
 
63
54
  if (forced) {
@@ -52,6 +52,16 @@ export interface PluginOptions {
52
52
  * @default false
53
53
  */
54
54
  dangerouslyOptimizeViewWithUnknownAncestors?: boolean;
55
+ /**
56
+ * Opt-in flag that allows Text optimization when ancestor components cannot be statically resolved.
57
+ *
58
+ * This increases optimization coverage, but may introduce behavioral differences when an unresolved
59
+ * ancestor renders a React Native `Text` wrapper: a nested `Text` must render as the inline
60
+ * `NativeVirtualText` host rather than `NativeText`, and optimizing it would emit the wrong host.
61
+ * Prefer targeted `@boost-force` first, and enable this only after verifying affected screens.
62
+ * @default false
63
+ */
64
+ dangerouslyOptimizeTextWithUnknownAncestors?: boolean;
55
65
  }
56
66
 
57
67
  export type OptimizableComponent = 'Text' | 'View';
@@ -78,7 +88,13 @@ export interface PluginLogger {
78
88
  warning: (payload: WarningLogPayload) => void;
79
89
  }
80
90
 
81
- export type Optimizer = (path: NodePath<t.JSXOpeningElement>, logger: PluginLogger, options?: PluginOptions) => void;
91
+ export type Optimizer = (
92
+ path: NodePath<t.JSXOpeningElement>,
93
+ logger: PluginLogger,
94
+ options?: PluginOptions,
95
+ /** Target platform from Babel's caller (e.g. Metro sets `'ios'`/`'android'`). Lets optimizers resolve platform-specific defaults at build time. */
96
+ platform?: string
97
+ ) => void;
82
98
 
83
99
  export type HubFile = t.File & {
84
100
  opts: {