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.
- package/README.md +5 -2
- package/dist/plugin/esm/index.mjs +103 -54
- package/dist/plugin/esm/index.mjs.map +1 -1
- package/dist/plugin/index.d.ts +10 -0
- package/dist/plugin/index.js +103 -54
- package/dist/plugin/index.js.map +1 -1
- package/dist/runtime/esm/index.mjs +16 -4
- package/dist/runtime/esm/index.mjs.map +1 -1
- package/dist/runtime/esm/index.web.mjs +2 -1
- package/dist/runtime/esm/index.web.mjs.map +1 -1
- package/dist/runtime/index.d.ts +16 -3
- package/dist/runtime/index.js +15 -2
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/index.web.d.ts +2 -1
- package/dist/runtime/index.web.js +2 -0
- package/dist/runtime/index.web.js.map +1 -1
- package/package.json +5 -1
- package/src/plugin/index.ts +5 -1
- package/src/plugin/optimizers/text/index.ts +93 -31
- package/src/plugin/optimizers/view/index.ts +13 -22
- package/src/plugin/types/index.ts +17 -1
- package/src/plugin/utils/common/attributes.ts +71 -12
- package/src/plugin/utils/common/validation.ts +32 -9
- package/src/runtime/index.ts +39 -5
- package/src/runtime/index.web.ts +5 -0
|
@@ -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;
|
|
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;;;;"}
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -58,16 +58,29 @@ declare const NativeView: ComponentType<ViewProps>;
|
|
|
58
58
|
*/
|
|
59
59
|
declare function processTextStyle(style: GenericStyleProp<TextStyle>): Partial<TextProps>;
|
|
60
60
|
/**
|
|
61
|
-
*
|
|
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
|
-
* -
|
|
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 };
|
package/dist/runtime/index.js
CHANGED
|
@@ -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
|
|
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;
|
|
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.
|
|
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",
|
package/src/plugin/index.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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-
|
|
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
|
|
142
|
+
// For a "children" attribute, optimization is allowed only if it is a provable primitive
|
|
122
143
|
attribute.name.name === 'children' &&
|
|
123
|
-
!
|
|
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
|
|
130
|
-
return !parent.children.every((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
|
-
|
|
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 (
|
|
207
|
+
// 1. Prepare spread attributes (a11y / style)
|
|
178
208
|
// ============================================
|
|
179
209
|
|
|
180
210
|
const spreadAttributes: t.JSXSpreadAttribute[] = [];
|
|
181
211
|
|
|
182
|
-
// --- Accessibility ---
|
|
183
|
-
if (
|
|
184
|
-
const
|
|
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(
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
13
|
-
ViewAncestorClassification,
|
|
12
|
+
ancestorBailoutChecks,
|
|
14
13
|
} from '../../utils/common';
|
|
15
14
|
|
|
16
15
|
export const viewBlacklistedProperties = new Set([
|
|
17
|
-
//
|
|
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
|
-
'
|
|
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 = (
|
|
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: {
|