blend-native 0.0.1-beta.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 +404 -0
- package/lib/commonjs/a11y/announcement.js +42 -0
- package/lib/commonjs/a11y/announcement.js.map +1 -0
- package/lib/commonjs/a11y/useLiveRegion.js +37 -0
- package/lib/commonjs/a11y/useLiveRegion.js.map +1 -0
- package/lib/commonjs/adapters/cssStringAdapter.js +363 -0
- package/lib/commonjs/adapters/cssStringAdapter.js.map +1 -0
- package/lib/commonjs/adapters/optionalGradient.js +33 -0
- package/lib/commonjs/adapters/optionalGradient.js.map +1 -0
- package/lib/commonjs/adapters/surfaceStyle.js +159 -0
- package/lib/commonjs/adapters/surfaceStyle.js.map +1 -0
- package/lib/commonjs/components/Alert/Alert.js +130 -0
- package/lib/commonjs/components/Alert/Alert.js.map +1 -0
- package/lib/commonjs/components/Alert/AlertActions.js +74 -0
- package/lib/commonjs/components/Alert/AlertActions.js.map +1 -0
- package/lib/commonjs/components/Alert/AlertClose.js +48 -0
- package/lib/commonjs/components/Alert/AlertClose.js.map +1 -0
- package/lib/commonjs/components/Alert/AlertText.js +49 -0
- package/lib/commonjs/components/Alert/AlertText.js.map +1 -0
- package/lib/commonjs/components/Alert/alert.tokens.js +6 -0
- package/lib/commonjs/components/Alert/alert.tokens.js.map +1 -0
- package/lib/commonjs/components/Alert/alert.types.js +6 -0
- package/lib/commonjs/components/Alert/alert.types.js.map +1 -0
- package/lib/commonjs/components/Alert/alert.utils.js +80 -0
- package/lib/commonjs/components/Alert/alert.utils.js.map +1 -0
- package/lib/commonjs/components/Alert/index.js +51 -0
- package/lib/commonjs/components/Alert/index.js.map +1 -0
- package/lib/commonjs/components/Button/Button.js +125 -0
- package/lib/commonjs/components/Button/Button.js.map +1 -0
- package/lib/commonjs/components/Button/button.types.js +6 -0
- package/lib/commonjs/components/Button/button.types.js.map +1 -0
- package/lib/commonjs/components/Button/button.utils.js +129 -0
- package/lib/commonjs/components/Button/button.utils.js.map +1 -0
- package/lib/commonjs/components/Button/index.js +57 -0
- package/lib/commonjs/components/Button/index.js.map +1 -0
- package/lib/commonjs/components/Skeleton/Skeleton.js +154 -0
- package/lib/commonjs/components/Skeleton/Skeleton.js.map +1 -0
- package/lib/commonjs/components/Skeleton/index.js +20 -0
- package/lib/commonjs/components/Skeleton/index.js.map +1 -0
- package/lib/commonjs/components/Skeleton/skeleton.types.js +6 -0
- package/lib/commonjs/components/Skeleton/skeleton.types.js.map +1 -0
- package/lib/commonjs/components/Skeleton/skeleton.utils.js +45 -0
- package/lib/commonjs/components/Skeleton/skeleton.utils.js.map +1 -0
- package/lib/commonjs/components/Tag/Tag.js +161 -0
- package/lib/commonjs/components/Tag/Tag.js.map +1 -0
- package/lib/commonjs/components/Tag/index.js +33 -0
- package/lib/commonjs/components/Tag/index.js.map +1 -0
- package/lib/commonjs/components/Tag/tag.types.js +6 -0
- package/lib/commonjs/components/Tag/tag.types.js.map +1 -0
- package/lib/commonjs/components/Tag/tag.utils.js +69 -0
- package/lib/commonjs/components/Tag/tag.utils.js.map +1 -0
- package/lib/commonjs/components/TextInput/TextInput.js +138 -0
- package/lib/commonjs/components/TextInput/TextInput.js.map +1 -0
- package/lib/commonjs/components/TextInput/index.js +14 -0
- package/lib/commonjs/components/TextInput/index.js.map +1 -0
- package/lib/commonjs/components/TextInput/textInput.types.js +6 -0
- package/lib/commonjs/components/TextInput/textInput.types.js.map +1 -0
- package/lib/commonjs/components/TextInput/textInput.utils.js +40 -0
- package/lib/commonjs/components/TextInput/textInput.utils.js.map +1 -0
- package/lib/commonjs/components/shared/field/FieldFooter.js +51 -0
- package/lib/commonjs/components/shared/field/FieldFooter.js.map +1 -0
- package/lib/commonjs/components/shared/field/FieldLabels.js +67 -0
- package/lib/commonjs/components/shared/field/FieldLabels.js.map +1 -0
- package/lib/commonjs/components/shared/field/fieldState.js +37 -0
- package/lib/commonjs/components/shared/field/fieldState.js.map +1 -0
- package/lib/commonjs/components/shared/group.js +73 -0
- package/lib/commonjs/components/shared/group.js.map +1 -0
- package/lib/commonjs/index.js +256 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/motion/motion.js +128 -0
- package/lib/commonjs/motion/motion.js.map +1 -0
- package/lib/commonjs/motion/useReduceMotion.js +37 -0
- package/lib/commonjs/motion/useReduceMotion.js.map +1 -0
- package/lib/commonjs/overlay/portal.js +110 -0
- package/lib/commonjs/overlay/portal.js.map +1 -0
- package/lib/commonjs/overlay/positioning.js +122 -0
- package/lib/commonjs/overlay/positioning.js.map +1 -0
- package/lib/commonjs/overlay/safeAreaInsets.js +30 -0
- package/lib/commonjs/overlay/safeAreaInsets.js.map +1 -0
- package/lib/commonjs/overlay/sheet/BottomSheet.js +196 -0
- package/lib/commonjs/overlay/sheet/BottomSheet.js.map +1 -0
- package/lib/commonjs/overlay/sheet/sheetMath.js +60 -0
- package/lib/commonjs/overlay/sheet/sheetMath.js.map +1 -0
- package/lib/commonjs/overlay/toast/ToastOutlet.js +106 -0
- package/lib/commonjs/overlay/toast/ToastOutlet.js.map +1 -0
- package/lib/commonjs/overlay/toast/toastStore.js +76 -0
- package/lib/commonjs/overlay/toast/toastStore.js.map +1 -0
- package/lib/commonjs/overlay/useAnchoredPosition.js +85 -0
- package/lib/commonjs/overlay/useAnchoredPosition.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/primitives/Block.js +112 -0
- package/lib/commonjs/primitives/Block.js.map +1 -0
- package/lib/commonjs/primitives/Pressable.js +348 -0
- package/lib/commonjs/primitives/Pressable.js.map +1 -0
- package/lib/commonjs/primitives/PrimitiveInput.js +66 -0
- package/lib/commonjs/primitives/PrimitiveInput.js.map +1 -0
- package/lib/commonjs/primitives/Separator.js +55 -0
- package/lib/commonjs/primitives/Separator.js.map +1 -0
- package/lib/commonjs/primitives/Slot.js +78 -0
- package/lib/commonjs/primitives/Slot.js.map +1 -0
- package/lib/commonjs/primitives/Text.js +73 -0
- package/lib/commonjs/primitives/Text.js.map +1 -0
- package/lib/commonjs/primitives/pressFeedback.js +53 -0
- package/lib/commonjs/primitives/pressFeedback.js.map +1 -0
- package/lib/commonjs/primitives/textStyle.js +27 -0
- package/lib/commonjs/primitives/textStyle.js.map +1 -0
- package/lib/commonjs/primitives/tintSlot.js +45 -0
- package/lib/commonjs/primitives/tintSlot.js.map +1 -0
- package/lib/commonjs/primitives/touchTarget.js +64 -0
- package/lib/commonjs/primitives/touchTarget.js.map +1 -0
- package/lib/commonjs/theme/BlendNativeProvider.js +90 -0
- package/lib/commonjs/theme/BlendNativeProvider.js.map +1 -0
- package/lib/commonjs/theme/breakpoint.js +36 -0
- package/lib/commonjs/theme/breakpoint.js.map +1 -0
- package/lib/commonjs/theme/fonts.js +58 -0
- package/lib/commonjs/theme/fonts.js.map +1 -0
- package/lib/commonjs/theme/nativeTokenRegistry.js +44 -0
- package/lib/commonjs/theme/nativeTokenRegistry.js.map +1 -0
- package/lib/commonjs/theme/systemTheme.js +35 -0
- package/lib/commonjs/theme/systemTheme.js.map +1 -0
- package/lib/commonjs/theme/useNativeBreakpoint.js +33 -0
- package/lib/commonjs/theme/useNativeBreakpoint.js.map +1 -0
- package/lib/commonjs/theme/useNativeTokens.js +71 -0
- package/lib/commonjs/theme/useNativeTokens.js.map +1 -0
- package/lib/module/a11y/announcement.js +38 -0
- package/lib/module/a11y/announcement.js.map +1 -0
- package/lib/module/a11y/useLiveRegion.js +33 -0
- package/lib/module/a11y/useLiveRegion.js.map +1 -0
- package/lib/module/adapters/cssStringAdapter.js +352 -0
- package/lib/module/adapters/cssStringAdapter.js.map +1 -0
- package/lib/module/adapters/optionalGradient.js +29 -0
- package/lib/module/adapters/optionalGradient.js.map +1 -0
- package/lib/module/adapters/surfaceStyle.js +155 -0
- package/lib/module/adapters/surfaceStyle.js.map +1 -0
- package/lib/module/components/Alert/Alert.js +126 -0
- package/lib/module/components/Alert/Alert.js.map +1 -0
- package/lib/module/components/Alert/AlertActions.js +70 -0
- package/lib/module/components/Alert/AlertActions.js.map +1 -0
- package/lib/module/components/Alert/AlertClose.js +44 -0
- package/lib/module/components/Alert/AlertClose.js.map +1 -0
- package/lib/module/components/Alert/AlertText.js +45 -0
- package/lib/module/components/Alert/AlertText.js.map +1 -0
- package/lib/module/components/Alert/alert.tokens.js +4 -0
- package/lib/module/components/Alert/alert.tokens.js.map +1 -0
- package/lib/module/components/Alert/alert.types.js +4 -0
- package/lib/module/components/Alert/alert.types.js.map +1 -0
- package/lib/module/components/Alert/alert.utils.js +72 -0
- package/lib/module/components/Alert/alert.utils.js.map +1 -0
- package/lib/module/components/Alert/index.js +6 -0
- package/lib/module/components/Alert/index.js.map +1 -0
- package/lib/module/components/Button/Button.js +121 -0
- package/lib/module/components/Button/Button.js.map +1 -0
- package/lib/module/components/Button/button.types.js +4 -0
- package/lib/module/components/Button/button.types.js.map +1 -0
- package/lib/module/components/Button/button.utils.js +120 -0
- package/lib/module/components/Button/button.utils.js.map +1 -0
- package/lib/module/components/Button/index.js +5 -0
- package/lib/module/components/Button/index.js.map +1 -0
- package/lib/module/components/Skeleton/Skeleton.js +149 -0
- package/lib/module/components/Skeleton/Skeleton.js.map +1 -0
- package/lib/module/components/Skeleton/index.js +4 -0
- package/lib/module/components/Skeleton/index.js.map +1 -0
- package/lib/module/components/Skeleton/skeleton.types.js +4 -0
- package/lib/module/components/Skeleton/skeleton.types.js.map +1 -0
- package/lib/module/components/Skeleton/skeleton.utils.js +40 -0
- package/lib/module/components/Skeleton/skeleton.utils.js.map +1 -0
- package/lib/module/components/Tag/Tag.js +157 -0
- package/lib/module/components/Tag/Tag.js.map +1 -0
- package/lib/module/components/Tag/index.js +5 -0
- package/lib/module/components/Tag/index.js.map +1 -0
- package/lib/module/components/Tag/tag.types.js +4 -0
- package/lib/module/components/Tag/tag.types.js.map +1 -0
- package/lib/module/components/Tag/tag.utils.js +64 -0
- package/lib/module/components/Tag/tag.utils.js.map +1 -0
- package/lib/module/components/TextInput/TextInput.js +134 -0
- package/lib/module/components/TextInput/TextInput.js.map +1 -0
- package/lib/module/components/TextInput/index.js +4 -0
- package/lib/module/components/TextInput/index.js.map +1 -0
- package/lib/module/components/TextInput/textInput.types.js +4 -0
- package/lib/module/components/TextInput/textInput.types.js.map +1 -0
- package/lib/module/components/TextInput/textInput.utils.js +36 -0
- package/lib/module/components/TextInput/textInput.utils.js.map +1 -0
- package/lib/module/components/shared/field/FieldFooter.js +47 -0
- package/lib/module/components/shared/field/FieldFooter.js.map +1 -0
- package/lib/module/components/shared/field/FieldLabels.js +63 -0
- package/lib/module/components/shared/field/FieldLabels.js.map +1 -0
- package/lib/module/components/shared/field/fieldState.js +33 -0
- package/lib/module/components/shared/field/fieldState.js.map +1 -0
- package/lib/module/components/shared/group.js +68 -0
- package/lib/module/components/shared/group.js.map +1 -0
- package/lib/module/index.js +80 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/motion/motion.js +123 -0
- package/lib/module/motion/motion.js.map +1 -0
- package/lib/module/motion/useReduceMotion.js +33 -0
- package/lib/module/motion/useReduceMotion.js.map +1 -0
- package/lib/module/overlay/portal.js +104 -0
- package/lib/module/overlay/portal.js.map +1 -0
- package/lib/module/overlay/positioning.js +118 -0
- package/lib/module/overlay/positioning.js.map +1 -0
- package/lib/module/overlay/safeAreaInsets.js +27 -0
- package/lib/module/overlay/safeAreaInsets.js.map +1 -0
- package/lib/module/overlay/sheet/BottomSheet.js +190 -0
- package/lib/module/overlay/sheet/BottomSheet.js.map +1 -0
- package/lib/module/overlay/sheet/sheetMath.js +53 -0
- package/lib/module/overlay/sheet/sheetMath.js.map +1 -0
- package/lib/module/overlay/toast/ToastOutlet.js +101 -0
- package/lib/module/overlay/toast/ToastOutlet.js.map +1 -0
- package/lib/module/overlay/toast/toastStore.js +66 -0
- package/lib/module/overlay/toast/toastStore.js.map +1 -0
- package/lib/module/overlay/useAnchoredPosition.js +82 -0
- package/lib/module/overlay/useAnchoredPosition.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/primitives/Block.js +107 -0
- package/lib/module/primitives/Block.js.map +1 -0
- package/lib/module/primitives/Pressable.js +339 -0
- package/lib/module/primitives/Pressable.js.map +1 -0
- package/lib/module/primitives/PrimitiveInput.js +62 -0
- package/lib/module/primitives/PrimitiveInput.js.map +1 -0
- package/lib/module/primitives/Separator.js +50 -0
- package/lib/module/primitives/Separator.js.map +1 -0
- package/lib/module/primitives/Slot.js +69 -0
- package/lib/module/primitives/Slot.js.map +1 -0
- package/lib/module/primitives/Text.js +68 -0
- package/lib/module/primitives/Text.js.map +1 -0
- package/lib/module/primitives/pressFeedback.js +48 -0
- package/lib/module/primitives/pressFeedback.js.map +1 -0
- package/lib/module/primitives/textStyle.js +23 -0
- package/lib/module/primitives/textStyle.js.map +1 -0
- package/lib/module/primitives/tintSlot.js +42 -0
- package/lib/module/primitives/tintSlot.js.map +1 -0
- package/lib/module/primitives/touchTarget.js +58 -0
- package/lib/module/primitives/touchTarget.js.map +1 -0
- package/lib/module/theme/BlendNativeProvider.js +78 -0
- package/lib/module/theme/BlendNativeProvider.js.map +1 -0
- package/lib/module/theme/breakpoint.js +33 -0
- package/lib/module/theme/breakpoint.js.map +1 -0
- package/lib/module/theme/fonts.js +55 -0
- package/lib/module/theme/fonts.js.map +1 -0
- package/lib/module/theme/nativeTokenRegistry.js +40 -0
- package/lib/module/theme/nativeTokenRegistry.js.map +1 -0
- package/lib/module/theme/systemTheme.js +31 -0
- package/lib/module/theme/systemTheme.js.map +1 -0
- package/lib/module/theme/useNativeBreakpoint.js +24 -0
- package/lib/module/theme/useNativeBreakpoint.js.map +1 -0
- package/lib/module/theme/useNativeTokens.js +67 -0
- package/lib/module/theme/useNativeTokens.js.map +1 -0
- package/lib/typescript/commonjs/a11y/announcement.d.ts +26 -0
- package/lib/typescript/commonjs/a11y/announcement.d.ts.map +1 -0
- package/lib/typescript/commonjs/a11y/useLiveRegion.d.ts +17 -0
- package/lib/typescript/commonjs/a11y/useLiveRegion.d.ts.map +1 -0
- package/lib/typescript/commonjs/adapters/cssStringAdapter.d.ts +119 -0
- package/lib/typescript/commonjs/adapters/cssStringAdapter.d.ts.map +1 -0
- package/lib/typescript/commonjs/adapters/optionalGradient.d.ts +32 -0
- package/lib/typescript/commonjs/adapters/optionalGradient.d.ts.map +1 -0
- package/lib/typescript/commonjs/adapters/surfaceStyle.d.ts +75 -0
- package/lib/typescript/commonjs/adapters/surfaceStyle.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Alert/Alert.d.ts +14 -0
- package/lib/typescript/commonjs/components/Alert/Alert.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Alert/AlertActions.d.ts +13 -0
- package/lib/typescript/commonjs/components/Alert/AlertActions.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Alert/AlertClose.d.ts +22 -0
- package/lib/typescript/commonjs/components/Alert/AlertClose.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Alert/AlertText.d.ts +19 -0
- package/lib/typescript/commonjs/components/Alert/AlertText.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Alert/alert.tokens.d.ts +17 -0
- package/lib/typescript/commonjs/components/Alert/alert.tokens.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Alert/alert.types.d.ts +70 -0
- package/lib/typescript/commonjs/components/Alert/alert.types.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Alert/alert.utils.d.ts +58 -0
- package/lib/typescript/commonjs/components/Alert/alert.utils.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Alert/index.d.ts +7 -0
- package/lib/typescript/commonjs/components/Alert/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Button/Button.d.ts +22 -0
- package/lib/typescript/commonjs/components/Button/Button.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Button/button.types.d.ts +37 -0
- package/lib/typescript/commonjs/components/Button/button.types.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Button/button.utils.d.ts +98 -0
- package/lib/typescript/commonjs/components/Button/button.utils.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Button/index.d.ts +5 -0
- package/lib/typescript/commonjs/components/Button/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Skeleton/Skeleton.d.ts +7 -0
- package/lib/typescript/commonjs/components/Skeleton/Skeleton.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Skeleton/index.d.ts +3 -0
- package/lib/typescript/commonjs/components/Skeleton/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Skeleton/skeleton.types.d.ts +25 -0
- package/lib/typescript/commonjs/components/Skeleton/skeleton.types.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Skeleton/skeleton.utils.d.ts +21 -0
- package/lib/typescript/commonjs/components/Skeleton/skeleton.utils.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Tag/Tag.d.ts +21 -0
- package/lib/typescript/commonjs/components/Tag/Tag.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Tag/index.d.ts +4 -0
- package/lib/typescript/commonjs/components/Tag/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Tag/tag.types.d.ts +56 -0
- package/lib/typescript/commonjs/components/Tag/tag.types.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/Tag/tag.utils.d.ts +41 -0
- package/lib/typescript/commonjs/components/Tag/tag.utils.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/TextInput/TextInput.d.ts +33 -0
- package/lib/typescript/commonjs/components/TextInput/TextInput.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/TextInput/index.d.ts +3 -0
- package/lib/typescript/commonjs/components/TextInput/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/TextInput/textInput.types.d.ts +45 -0
- package/lib/typescript/commonjs/components/TextInput/textInput.types.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/TextInput/textInput.utils.d.ts +35 -0
- package/lib/typescript/commonjs/components/TextInput/textInput.utils.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/shared/field/FieldFooter.d.ts +22 -0
- package/lib/typescript/commonjs/components/shared/field/FieldFooter.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/shared/field/FieldLabels.d.ts +27 -0
- package/lib/typescript/commonjs/components/shared/field/FieldLabels.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/shared/field/fieldState.d.ts +23 -0
- package/lib/typescript/commonjs/components/shared/field/fieldState.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/shared/group.d.ts +50 -0
- package/lib/typescript/commonjs/components/shared/group.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +74 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/motion/motion.d.ts +121 -0
- package/lib/typescript/commonjs/motion/motion.d.ts.map +1 -0
- package/lib/typescript/commonjs/motion/useReduceMotion.d.ts +14 -0
- package/lib/typescript/commonjs/motion/useReduceMotion.d.ts.map +1 -0
- package/lib/typescript/commonjs/overlay/portal.d.ts +20 -0
- package/lib/typescript/commonjs/overlay/portal.d.ts.map +1 -0
- package/lib/typescript/commonjs/overlay/positioning.d.ts +65 -0
- package/lib/typescript/commonjs/overlay/positioning.d.ts.map +1 -0
- package/lib/typescript/commonjs/overlay/safeAreaInsets.d.ts +19 -0
- package/lib/typescript/commonjs/overlay/safeAreaInsets.d.ts.map +1 -0
- package/lib/typescript/commonjs/overlay/sheet/BottomSheet.d.ts +56 -0
- package/lib/typescript/commonjs/overlay/sheet/BottomSheet.d.ts.map +1 -0
- package/lib/typescript/commonjs/overlay/sheet/sheetMath.d.ts +32 -0
- package/lib/typescript/commonjs/overlay/sheet/sheetMath.d.ts.map +1 -0
- package/lib/typescript/commonjs/overlay/toast/ToastOutlet.d.ts +17 -0
- package/lib/typescript/commonjs/overlay/toast/ToastOutlet.d.ts.map +1 -0
- package/lib/typescript/commonjs/overlay/toast/toastStore.d.ts +45 -0
- package/lib/typescript/commonjs/overlay/toast/toastStore.d.ts.map +1 -0
- package/lib/typescript/commonjs/overlay/useAnchoredPosition.d.ts +40 -0
- package/lib/typescript/commonjs/overlay/useAnchoredPosition.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/primitives/Block.d.ts +37 -0
- package/lib/typescript/commonjs/primitives/Block.d.ts.map +1 -0
- package/lib/typescript/commonjs/primitives/Pressable.d.ts +135 -0
- package/lib/typescript/commonjs/primitives/Pressable.d.ts.map +1 -0
- package/lib/typescript/commonjs/primitives/PrimitiveInput.d.ts +42 -0
- package/lib/typescript/commonjs/primitives/PrimitiveInput.d.ts.map +1 -0
- package/lib/typescript/commonjs/primitives/Separator.d.ts +28 -0
- package/lib/typescript/commonjs/primitives/Separator.d.ts.map +1 -0
- package/lib/typescript/commonjs/primitives/Slot.d.ts +48 -0
- package/lib/typescript/commonjs/primitives/Slot.d.ts.map +1 -0
- package/lib/typescript/commonjs/primitives/Text.d.ts +50 -0
- package/lib/typescript/commonjs/primitives/Text.d.ts.map +1 -0
- package/lib/typescript/commonjs/primitives/pressFeedback.d.ts +39 -0
- package/lib/typescript/commonjs/primitives/pressFeedback.d.ts.map +1 -0
- package/lib/typescript/commonjs/primitives/textStyle.d.ts +13 -0
- package/lib/typescript/commonjs/primitives/textStyle.d.ts.map +1 -0
- package/lib/typescript/commonjs/primitives/tintSlot.d.ts +10 -0
- package/lib/typescript/commonjs/primitives/tintSlot.d.ts.map +1 -0
- package/lib/typescript/commonjs/primitives/touchTarget.d.ts +43 -0
- package/lib/typescript/commonjs/primitives/touchTarget.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/BlendNativeProvider.d.ts +69 -0
- package/lib/typescript/commonjs/theme/BlendNativeProvider.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/breakpoint.d.ts +27 -0
- package/lib/typescript/commonjs/theme/breakpoint.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/fonts.d.ts +34 -0
- package/lib/typescript/commonjs/theme/fonts.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/nativeTokenRegistry.d.ts +34 -0
- package/lib/typescript/commonjs/theme/nativeTokenRegistry.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/systemTheme.d.ts +25 -0
- package/lib/typescript/commonjs/theme/systemTheme.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/useNativeBreakpoint.d.ts +17 -0
- package/lib/typescript/commonjs/theme/useNativeBreakpoint.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/useNativeTokens.d.ts +4 -0
- package/lib/typescript/commonjs/theme/useNativeTokens.d.ts.map +1 -0
- package/lib/typescript/module/a11y/announcement.d.ts +26 -0
- package/lib/typescript/module/a11y/announcement.d.ts.map +1 -0
- package/lib/typescript/module/a11y/useLiveRegion.d.ts +17 -0
- package/lib/typescript/module/a11y/useLiveRegion.d.ts.map +1 -0
- package/lib/typescript/module/adapters/cssStringAdapter.d.ts +119 -0
- package/lib/typescript/module/adapters/cssStringAdapter.d.ts.map +1 -0
- package/lib/typescript/module/adapters/optionalGradient.d.ts +32 -0
- package/lib/typescript/module/adapters/optionalGradient.d.ts.map +1 -0
- package/lib/typescript/module/adapters/surfaceStyle.d.ts +75 -0
- package/lib/typescript/module/adapters/surfaceStyle.d.ts.map +1 -0
- package/lib/typescript/module/components/Alert/Alert.d.ts +14 -0
- package/lib/typescript/module/components/Alert/Alert.d.ts.map +1 -0
- package/lib/typescript/module/components/Alert/AlertActions.d.ts +13 -0
- package/lib/typescript/module/components/Alert/AlertActions.d.ts.map +1 -0
- package/lib/typescript/module/components/Alert/AlertClose.d.ts +22 -0
- package/lib/typescript/module/components/Alert/AlertClose.d.ts.map +1 -0
- package/lib/typescript/module/components/Alert/AlertText.d.ts +19 -0
- package/lib/typescript/module/components/Alert/AlertText.d.ts.map +1 -0
- package/lib/typescript/module/components/Alert/alert.tokens.d.ts +17 -0
- package/lib/typescript/module/components/Alert/alert.tokens.d.ts.map +1 -0
- package/lib/typescript/module/components/Alert/alert.types.d.ts +70 -0
- package/lib/typescript/module/components/Alert/alert.types.d.ts.map +1 -0
- package/lib/typescript/module/components/Alert/alert.utils.d.ts +58 -0
- package/lib/typescript/module/components/Alert/alert.utils.d.ts.map +1 -0
- package/lib/typescript/module/components/Alert/index.d.ts +7 -0
- package/lib/typescript/module/components/Alert/index.d.ts.map +1 -0
- package/lib/typescript/module/components/Button/Button.d.ts +22 -0
- package/lib/typescript/module/components/Button/Button.d.ts.map +1 -0
- package/lib/typescript/module/components/Button/button.types.d.ts +37 -0
- package/lib/typescript/module/components/Button/button.types.d.ts.map +1 -0
- package/lib/typescript/module/components/Button/button.utils.d.ts +98 -0
- package/lib/typescript/module/components/Button/button.utils.d.ts.map +1 -0
- package/lib/typescript/module/components/Button/index.d.ts +5 -0
- package/lib/typescript/module/components/Button/index.d.ts.map +1 -0
- package/lib/typescript/module/components/Skeleton/Skeleton.d.ts +7 -0
- package/lib/typescript/module/components/Skeleton/Skeleton.d.ts.map +1 -0
- package/lib/typescript/module/components/Skeleton/index.d.ts +3 -0
- package/lib/typescript/module/components/Skeleton/index.d.ts.map +1 -0
- package/lib/typescript/module/components/Skeleton/skeleton.types.d.ts +25 -0
- package/lib/typescript/module/components/Skeleton/skeleton.types.d.ts.map +1 -0
- package/lib/typescript/module/components/Skeleton/skeleton.utils.d.ts +21 -0
- package/lib/typescript/module/components/Skeleton/skeleton.utils.d.ts.map +1 -0
- package/lib/typescript/module/components/Tag/Tag.d.ts +21 -0
- package/lib/typescript/module/components/Tag/Tag.d.ts.map +1 -0
- package/lib/typescript/module/components/Tag/index.d.ts +4 -0
- package/lib/typescript/module/components/Tag/index.d.ts.map +1 -0
- package/lib/typescript/module/components/Tag/tag.types.d.ts +56 -0
- package/lib/typescript/module/components/Tag/tag.types.d.ts.map +1 -0
- package/lib/typescript/module/components/Tag/tag.utils.d.ts +41 -0
- package/lib/typescript/module/components/Tag/tag.utils.d.ts.map +1 -0
- package/lib/typescript/module/components/TextInput/TextInput.d.ts +33 -0
- package/lib/typescript/module/components/TextInput/TextInput.d.ts.map +1 -0
- package/lib/typescript/module/components/TextInput/index.d.ts +3 -0
- package/lib/typescript/module/components/TextInput/index.d.ts.map +1 -0
- package/lib/typescript/module/components/TextInput/textInput.types.d.ts +45 -0
- package/lib/typescript/module/components/TextInput/textInput.types.d.ts.map +1 -0
- package/lib/typescript/module/components/TextInput/textInput.utils.d.ts +35 -0
- package/lib/typescript/module/components/TextInput/textInput.utils.d.ts.map +1 -0
- package/lib/typescript/module/components/shared/field/FieldFooter.d.ts +22 -0
- package/lib/typescript/module/components/shared/field/FieldFooter.d.ts.map +1 -0
- package/lib/typescript/module/components/shared/field/FieldLabels.d.ts +27 -0
- package/lib/typescript/module/components/shared/field/FieldLabels.d.ts.map +1 -0
- package/lib/typescript/module/components/shared/field/fieldState.d.ts +23 -0
- package/lib/typescript/module/components/shared/field/fieldState.d.ts.map +1 -0
- package/lib/typescript/module/components/shared/group.d.ts +50 -0
- package/lib/typescript/module/components/shared/group.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +74 -0
- package/lib/typescript/module/index.d.ts.map +1 -0
- package/lib/typescript/module/motion/motion.d.ts +121 -0
- package/lib/typescript/module/motion/motion.d.ts.map +1 -0
- package/lib/typescript/module/motion/useReduceMotion.d.ts +14 -0
- package/lib/typescript/module/motion/useReduceMotion.d.ts.map +1 -0
- package/lib/typescript/module/overlay/portal.d.ts +20 -0
- package/lib/typescript/module/overlay/portal.d.ts.map +1 -0
- package/lib/typescript/module/overlay/positioning.d.ts +65 -0
- package/lib/typescript/module/overlay/positioning.d.ts.map +1 -0
- package/lib/typescript/module/overlay/safeAreaInsets.d.ts +19 -0
- package/lib/typescript/module/overlay/safeAreaInsets.d.ts.map +1 -0
- package/lib/typescript/module/overlay/sheet/BottomSheet.d.ts +56 -0
- package/lib/typescript/module/overlay/sheet/BottomSheet.d.ts.map +1 -0
- package/lib/typescript/module/overlay/sheet/sheetMath.d.ts +32 -0
- package/lib/typescript/module/overlay/sheet/sheetMath.d.ts.map +1 -0
- package/lib/typescript/module/overlay/toast/ToastOutlet.d.ts +17 -0
- package/lib/typescript/module/overlay/toast/ToastOutlet.d.ts.map +1 -0
- package/lib/typescript/module/overlay/toast/toastStore.d.ts +45 -0
- package/lib/typescript/module/overlay/toast/toastStore.d.ts.map +1 -0
- package/lib/typescript/module/overlay/useAnchoredPosition.d.ts +40 -0
- package/lib/typescript/module/overlay/useAnchoredPosition.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/primitives/Block.d.ts +37 -0
- package/lib/typescript/module/primitives/Block.d.ts.map +1 -0
- package/lib/typescript/module/primitives/Pressable.d.ts +135 -0
- package/lib/typescript/module/primitives/Pressable.d.ts.map +1 -0
- package/lib/typescript/module/primitives/PrimitiveInput.d.ts +42 -0
- package/lib/typescript/module/primitives/PrimitiveInput.d.ts.map +1 -0
- package/lib/typescript/module/primitives/Separator.d.ts +28 -0
- package/lib/typescript/module/primitives/Separator.d.ts.map +1 -0
- package/lib/typescript/module/primitives/Slot.d.ts +48 -0
- package/lib/typescript/module/primitives/Slot.d.ts.map +1 -0
- package/lib/typescript/module/primitives/Text.d.ts +50 -0
- package/lib/typescript/module/primitives/Text.d.ts.map +1 -0
- package/lib/typescript/module/primitives/pressFeedback.d.ts +39 -0
- package/lib/typescript/module/primitives/pressFeedback.d.ts.map +1 -0
- package/lib/typescript/module/primitives/textStyle.d.ts +13 -0
- package/lib/typescript/module/primitives/textStyle.d.ts.map +1 -0
- package/lib/typescript/module/primitives/tintSlot.d.ts +10 -0
- package/lib/typescript/module/primitives/tintSlot.d.ts.map +1 -0
- package/lib/typescript/module/primitives/touchTarget.d.ts +43 -0
- package/lib/typescript/module/primitives/touchTarget.d.ts.map +1 -0
- package/lib/typescript/module/theme/BlendNativeProvider.d.ts +69 -0
- package/lib/typescript/module/theme/BlendNativeProvider.d.ts.map +1 -0
- package/lib/typescript/module/theme/breakpoint.d.ts +27 -0
- package/lib/typescript/module/theme/breakpoint.d.ts.map +1 -0
- package/lib/typescript/module/theme/fonts.d.ts +34 -0
- package/lib/typescript/module/theme/fonts.d.ts.map +1 -0
- package/lib/typescript/module/theme/nativeTokenRegistry.d.ts +34 -0
- package/lib/typescript/module/theme/nativeTokenRegistry.d.ts.map +1 -0
- package/lib/typescript/module/theme/systemTheme.d.ts +25 -0
- package/lib/typescript/module/theme/systemTheme.d.ts.map +1 -0
- package/lib/typescript/module/theme/useNativeBreakpoint.d.ts +17 -0
- package/lib/typescript/module/theme/useNativeBreakpoint.d.ts.map +1 -0
- package/lib/typescript/module/theme/useNativeTokens.d.ts +4 -0
- package/lib/typescript/module/theme/useNativeTokens.d.ts.map +1 -0
- package/package.json +137 -0
- package/src/a11y/announcement.ts +41 -0
- package/src/a11y/useLiveRegion.ts +36 -0
- package/src/adapters/cssStringAdapter.ts +403 -0
- package/src/adapters/optionalGradient.ts +39 -0
- package/src/adapters/surfaceStyle.ts +209 -0
- package/src/components/Alert/Alert.tsx +167 -0
- package/src/components/Alert/AlertActions.tsx +98 -0
- package/src/components/Alert/AlertClose.tsx +53 -0
- package/src/components/Alert/AlertText.tsx +58 -0
- package/src/components/Alert/alert.tokens.ts +24 -0
- package/src/components/Alert/alert.types.ts +81 -0
- package/src/components/Alert/alert.utils.ts +94 -0
- package/src/components/Alert/index.ts +21 -0
- package/src/components/Button/Button.tsx +180 -0
- package/src/components/Button/button.types.ts +44 -0
- package/src/components/Button/button.utils.ts +213 -0
- package/src/components/Button/index.ts +12 -0
- package/src/components/Skeleton/Skeleton.tsx +196 -0
- package/src/components/Skeleton/index.ts +2 -0
- package/src/components/Skeleton/skeleton.types.ts +28 -0
- package/src/components/Skeleton/skeleton.utils.ts +56 -0
- package/src/components/Tag/Tag.tsx +204 -0
- package/src/components/Tag/index.ts +7 -0
- package/src/components/Tag/tag.types.ts +63 -0
- package/src/components/Tag/tag.utils.ts +82 -0
- package/src/components/TextInput/TextInput.tsx +165 -0
- package/src/components/TextInput/index.ts +2 -0
- package/src/components/TextInput/textInput.types.ts +54 -0
- package/src/components/TextInput/textInput.utils.ts +68 -0
- package/src/components/shared/field/FieldFooter.tsx +66 -0
- package/src/components/shared/field/FieldLabels.tsx +86 -0
- package/src/components/shared/field/fieldState.ts +39 -0
- package/src/components/shared/group.ts +72 -0
- package/src/index.ts +144 -0
- package/src/motion/motion.ts +115 -0
- package/src/motion/useReduceMotion.ts +36 -0
- package/src/overlay/portal.tsx +122 -0
- package/src/overlay/positioning.ts +196 -0
- package/src/overlay/safeAreaInsets.ts +36 -0
- package/src/overlay/sheet/BottomSheet.tsx +276 -0
- package/src/overlay/sheet/sheetMath.ts +58 -0
- package/src/overlay/toast/ToastOutlet.tsx +127 -0
- package/src/overlay/toast/toastStore.ts +96 -0
- package/src/overlay/useAnchoredPosition.ts +92 -0
- package/src/primitives/Block.tsx +129 -0
- package/src/primitives/Pressable.tsx +528 -0
- package/src/primitives/PrimitiveInput.tsx +87 -0
- package/src/primitives/Separator.tsx +65 -0
- package/src/primitives/Slot.tsx +94 -0
- package/src/primitives/Text.tsx +98 -0
- package/src/primitives/pressFeedback.ts +78 -0
- package/src/primitives/textStyle.ts +24 -0
- package/src/primitives/tintSlot.ts +44 -0
- package/src/primitives/touchTarget.ts +72 -0
- package/src/theme/BlendNativeProvider.tsx +147 -0
- package/src/theme/breakpoint.ts +38 -0
- package/src/theme/fonts.ts +63 -0
- package/src/theme/nativeTokenRegistry.ts +57 -0
- package/src/theme/systemTheme.ts +34 -0
- package/src/theme/useNativeBreakpoint.ts +27 -0
- package/src/theme/useNativeTokens.ts +99 -0
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import type { ViewStyle } from 'react-native'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CSS-string token adapter for React Native.
|
|
5
|
+
*
|
|
6
|
+
* Blend's token factories emit CSS string values (`"6px"`,
|
|
7
|
+
* `"1px solid #E1E4EA"`, `"linear-gradient(180deg, #1A56DB -5%, #2563EB 107.5%)"`).
|
|
8
|
+
* RN's stylesheet engine accepts only numbers or platform-specific style
|
|
9
|
+
* objects, so every token value that touches layout/decoration must be
|
|
10
|
+
* translated here.
|
|
11
|
+
*
|
|
12
|
+
* Every function is pure and defensive: unparseable input returns a safe
|
|
13
|
+
* fallback (usually `undefined`) rather than throwing, so a single bad token
|
|
14
|
+
* never crashes the whole button.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A decimal number, in a form the regex engine cannot backtrack over.
|
|
19
|
+
*
|
|
20
|
+
* The obvious spellings — `\d*\.?\d+` and `\d+\.?\d*` — are **ambiguous**:
|
|
21
|
+
* with no `.` present, a run of digits can be divided between the two
|
|
22
|
+
* quantifiers in as many ways as there are digits, so a long non-matching
|
|
23
|
+
* input costs O(n^2). CodeQL flags both as `js/polynomial-redos`, correctly.
|
|
24
|
+
*
|
|
25
|
+
* Here the `.` inside the optional group is mandatory, so each digit run has
|
|
26
|
+
* exactly one valid division and matching stays linear.
|
|
27
|
+
*/
|
|
28
|
+
const NUMBER = String.raw`-?(?:\d+(?:\.\d+)?|\.\d+)`
|
|
29
|
+
|
|
30
|
+
/** `"6px"`, `"1.5px"`, `"0"` — a length, with the unit optional. */
|
|
31
|
+
const DIMENSION_RE = new RegExp(`^(${NUMBER})(?:px)?$`)
|
|
32
|
+
|
|
33
|
+
/** `"50%"`, `"33.5%"`, `"-5%"` — a percentage. */
|
|
34
|
+
const PERCENT_RE = new RegExp(`^(${NUMBER})%$`)
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Result of parsing a background token.
|
|
38
|
+
*
|
|
39
|
+
* - `flat` — solid color, apply via `backgroundColor`.
|
|
40
|
+
* - `gradient` — linear gradient, requires a `<LinearGradient>` wrapper.
|
|
41
|
+
* - `null` — `none` / transparent / unparseable; no background.
|
|
42
|
+
*/
|
|
43
|
+
export type ParsedBackground =
|
|
44
|
+
| { type: 'flat'; color: string }
|
|
45
|
+
| {
|
|
46
|
+
type: 'gradient'
|
|
47
|
+
colors: string[]
|
|
48
|
+
locations: number[]
|
|
49
|
+
start: { x: number; y: number }
|
|
50
|
+
end: { x: number; y: number }
|
|
51
|
+
}
|
|
52
|
+
| null
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Parse a CSS dimension string (`"6px"`, `"1.5px"`, `"0"`) into a number.
|
|
56
|
+
* Returns `undefined` for non-numeric input.
|
|
57
|
+
*
|
|
58
|
+
* `parseDimension("6px") → 6`
|
|
59
|
+
* `parseDimension("1.5px") → 1.5`
|
|
60
|
+
* `parseDimension("0") → 0`
|
|
61
|
+
*/
|
|
62
|
+
export function parseDimension(
|
|
63
|
+
value: string | number | undefined
|
|
64
|
+
): number | undefined {
|
|
65
|
+
if (value === undefined || value === null) return undefined
|
|
66
|
+
if (typeof value === 'number')
|
|
67
|
+
return Number.isFinite(value) ? value : undefined
|
|
68
|
+
const match = value.trim().match(DIMENSION_RE)
|
|
69
|
+
if (!match) return undefined
|
|
70
|
+
const n = parseFloat(match[1])
|
|
71
|
+
return Number.isNaN(n) ? undefined : n
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* RN's type for anything that accepts a length or a percentage
|
|
76
|
+
* (`width`, `maxHeight`, `flexBasis`, ...).
|
|
77
|
+
*/
|
|
78
|
+
export type RNSize = number | `${number}%` | 'auto'
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Parse a CSS size value — `width`, `height`, `maxHeight`, `minWidth`, ... —
|
|
82
|
+
* into something RN's stylesheet actually understands.
|
|
83
|
+
*
|
|
84
|
+
* This is deliberately strict. `parseFloat` is NOT a safe fallback here: it
|
|
85
|
+
* turns `"100%"` into `100`, which RN renders as **100 pixels** rather than
|
|
86
|
+
* full width, and it silently accepts `"12abc"` (→ `12`) and `"50em"` (→ `50`).
|
|
87
|
+
* Anything not explicitly understood returns `undefined` so the caller skips
|
|
88
|
+
* the prop instead of laying out a wrong value.
|
|
89
|
+
*
|
|
90
|
+
* ```
|
|
91
|
+
* parseSize(24) → 24
|
|
92
|
+
* parseSize('24px') → 24
|
|
93
|
+
* parseSize('50%') → '50%'
|
|
94
|
+
* parseSize('100%') → '100%'
|
|
95
|
+
* parseSize('auto') → 'auto'
|
|
96
|
+
* parseSize('fit-content') → 'auto' // RN's nearest equivalent
|
|
97
|
+
* parseSize('min-content') → undefined
|
|
98
|
+
* parseSize('calc(1+2)') → undefined
|
|
99
|
+
* parseSize('50em') → undefined
|
|
100
|
+
* parseSize('12abc') → undefined
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export function parseSize(
|
|
104
|
+
value: string | number | undefined
|
|
105
|
+
): RNSize | undefined {
|
|
106
|
+
if (value === undefined || value === null) return undefined
|
|
107
|
+
if (typeof value === 'number') {
|
|
108
|
+
return Number.isFinite(value) ? value : undefined
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const trimmed = value.trim()
|
|
112
|
+
if (trimmed === '') return undefined
|
|
113
|
+
|
|
114
|
+
// `fit-content` has no RN equivalent; `auto` is the closest behaviour
|
|
115
|
+
// (shrink-to-fit within the parent's constraints).
|
|
116
|
+
if (trimmed === 'auto' || trimmed === 'fit-content') return 'auto'
|
|
117
|
+
|
|
118
|
+
// Percentages. See `NUMBER` — linear, so a long adversarial input cannot
|
|
119
|
+
// degrade this.
|
|
120
|
+
const pct = trimmed.match(PERCENT_RE)
|
|
121
|
+
if (pct) {
|
|
122
|
+
const n = parseFloat(pct[1])
|
|
123
|
+
return Number.isNaN(n) ? undefined : (`${n}%` as `${number}%`)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Bare numbers and `px` lengths.
|
|
127
|
+
return parseDimension(trimmed)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Parse a CSS time value (`"1.5s"`, `"200ms"`, `1500`) into milliseconds.
|
|
132
|
+
* Returns `undefined` for unparseable input so callers fall back to their
|
|
133
|
+
* own default duration.
|
|
134
|
+
*
|
|
135
|
+
* `parseDuration('1.5s') → 1500`
|
|
136
|
+
* `parseDuration('200ms') → 200`
|
|
137
|
+
*/
|
|
138
|
+
export function parseDuration(
|
|
139
|
+
value: string | number | undefined
|
|
140
|
+
): number | undefined {
|
|
141
|
+
if (value === undefined || value === null) return undefined
|
|
142
|
+
if (typeof value === 'number')
|
|
143
|
+
return Number.isFinite(value) ? value : undefined
|
|
144
|
+
const match = value.trim().match(new RegExp(`^(${NUMBER})(ms|s)$`))
|
|
145
|
+
if (!match) return undefined
|
|
146
|
+
const n = parseFloat(match[1])
|
|
147
|
+
if (Number.isNaN(n)) return undefined
|
|
148
|
+
return match[2] === 's' ? n * 1000 : n
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Parse a CSS `border` shorthand (`"1px solid #E1E4EA"`) into RN border props.
|
|
153
|
+
* Returns `{ borderWidth, borderColor }` — the only two border properties RN
|
|
154
|
+
* supports uniformly across iOS/Android.
|
|
155
|
+
*
|
|
156
|
+
* `parseBorder("1.5px solid #1A56DB") → { borderWidth: 1.5, borderColor: "#1A56DB" }`
|
|
157
|
+
* `parseBorder("none") → {}`
|
|
158
|
+
*/
|
|
159
|
+
export function parseBorder(
|
|
160
|
+
value: string | undefined
|
|
161
|
+
): Partial<Pick<ViewStyle, 'borderWidth' | 'borderColor'>> {
|
|
162
|
+
if (!value || value === 'none' || value === 'transparent') {
|
|
163
|
+
return {}
|
|
164
|
+
}
|
|
165
|
+
// Match: <width> <style> <color>
|
|
166
|
+
// width: "1px" / "1.5px"
|
|
167
|
+
// style: "solid" / "dashed" / "dotted" (RN only renders solid reliably)
|
|
168
|
+
// color: hex / rgb / rgba / named
|
|
169
|
+
const match = value
|
|
170
|
+
.trim()
|
|
171
|
+
.match(/^(\d*\.?\d+)px\s+(?:solid|dashed|dotted)\s+(.+)$/)
|
|
172
|
+
if (!match) return {}
|
|
173
|
+
const width = parseFloat(match[1])
|
|
174
|
+
const color = match[2].trim()
|
|
175
|
+
if (Number.isNaN(width) || !color) return {}
|
|
176
|
+
return { borderWidth: width, borderColor: color }
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Parse a CSS `border-radius` value into a number or corner-tuple for RN.
|
|
181
|
+
*
|
|
182
|
+
* Single value: `"10px" → 10`
|
|
183
|
+
* Four values (per CSS order TL TR BR BL): `"10px 0 0 10px" → { topLeft: 10, topRight: 0, bottomRight: 0, bottomLeft: 10 }`
|
|
184
|
+
*
|
|
185
|
+
* Returns `undefined` for unparseable input so callers can skip the prop.
|
|
186
|
+
*/
|
|
187
|
+
export function parseBorderRadius(
|
|
188
|
+
value: string | number | undefined
|
|
189
|
+
):
|
|
190
|
+
| number
|
|
191
|
+
| Pick<
|
|
192
|
+
ViewStyle,
|
|
193
|
+
| 'borderTopLeftRadius'
|
|
194
|
+
| 'borderTopRightRadius'
|
|
195
|
+
| 'borderBottomRightRadius'
|
|
196
|
+
| 'borderBottomLeftRadius'
|
|
197
|
+
>
|
|
198
|
+
| undefined {
|
|
199
|
+
if (value === undefined || value === null) return undefined
|
|
200
|
+
if (typeof value === 'number') return value
|
|
201
|
+
const trimmed = value.trim()
|
|
202
|
+
if (trimmed === '' || trimmed === 'none') return undefined
|
|
203
|
+
|
|
204
|
+
const parts = trimmed.split(/\s+/).map((p) => parseFloat(p))
|
|
205
|
+
if (parts.some((p) => Number.isNaN(p))) return undefined
|
|
206
|
+
|
|
207
|
+
if (parts.length === 1) return parts[0]
|
|
208
|
+
if (parts.length === 4) {
|
|
209
|
+
// CSS order: top-left, top-right, bottom-right, bottom-left
|
|
210
|
+
return {
|
|
211
|
+
borderTopLeftRadius: parts[0],
|
|
212
|
+
borderTopRightRadius: parts[1],
|
|
213
|
+
borderBottomRightRadius: parts[2],
|
|
214
|
+
borderBottomLeftRadius: parts[3],
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// 2 or 3 value shorthands are rare in tokens; fall back to single.
|
|
218
|
+
return parts[0]
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Parse one or more CSS `box-shadow` declarations into RN shadow/elevation props.
|
|
223
|
+
*
|
|
224
|
+
* RN does NOT support `inset` shadows — any `inset` declaration returns `null`
|
|
225
|
+
* (the caller should treat that as "no shadow"). Multiple comma-separated
|
|
226
|
+
* shadows are collapsed into the first non-inset shadow, because RN's shadow
|
|
227
|
+
* API models a single shadow.
|
|
228
|
+
*
|
|
229
|
+
* Focus-ring shadows (`"0 0 0 3px #EFF6FF"`) are parsed normally and become
|
|
230
|
+
* outer shadows — visually acceptable on native.
|
|
231
|
+
*
|
|
232
|
+
* Returns a `ViewStyle` subset: `shadowColor`, `shadowOffset`, `shadowOpacity`,
|
|
233
|
+
* `shadowRadius` (iOS) + `elevation` (Android).
|
|
234
|
+
*/
|
|
235
|
+
export function parseBoxShadow(
|
|
236
|
+
value: string | undefined
|
|
237
|
+
): Pick<
|
|
238
|
+
ViewStyle,
|
|
239
|
+
| 'shadowColor'
|
|
240
|
+
| 'shadowOffset'
|
|
241
|
+
| 'shadowOpacity'
|
|
242
|
+
| 'shadowRadius'
|
|
243
|
+
| 'elevation'
|
|
244
|
+
> | null {
|
|
245
|
+
if (!value || value === 'none') return null
|
|
246
|
+
|
|
247
|
+
// Split on commas that separate multiple shadow declarations — but NOT
|
|
248
|
+
// commas inside rgba()/rgb() parens, which are part of a color, not
|
|
249
|
+
// separators. `(?![^(]*\))` = skip commas inside parens.
|
|
250
|
+
const shadows = value
|
|
251
|
+
.split(/,(?![^(]*\))/)
|
|
252
|
+
.map((s) => s.trim())
|
|
253
|
+
.filter(Boolean)
|
|
254
|
+
|
|
255
|
+
// Find the first non-inset shadow — RN cannot render inset shadows at all.
|
|
256
|
+
const outer = shadows.find((s) => !/\binset\b/i.test(s))
|
|
257
|
+
if (!outer) return null
|
|
258
|
+
|
|
259
|
+
// Extract the color first, then parse numbers from the remainder.
|
|
260
|
+
// This avoids picking up digits from inside rgba(...) as offsets.
|
|
261
|
+
const colorMatch = outer.match(/#[0-9a-fA-F]{3,8}|rgba?\([^)]*\)/i)
|
|
262
|
+
const numericPart = outer
|
|
263
|
+
.replace(/#[0-9a-fA-F]{3,8}|rgba?\([^)]*\)/gi, ' ')
|
|
264
|
+
.replace(/\binset\b/gi, ' ')
|
|
265
|
+
const nums =
|
|
266
|
+
numericPart.match(/-?\d*\.?\d+/g)?.map((t) => parseFloat(t)) ?? []
|
|
267
|
+
|
|
268
|
+
const [offsetX = 0, offsetY = 0, blur = 0, spread = 0] = nums
|
|
269
|
+
|
|
270
|
+
// RN's shadowRadius is the blur radius, not the spread.
|
|
271
|
+
// Elevation approximates the combined shadow depth on Android.
|
|
272
|
+
const shadowColor = colorMatch?.[0] ?? '#000000'
|
|
273
|
+
|
|
274
|
+
// If shadowColor is rgba(), extract the rgb for shadowColor and keep the
|
|
275
|
+
// alpha separately for shadowOpacity (iOS multiplies them).
|
|
276
|
+
let resolvedColor = shadowColor
|
|
277
|
+
let resolvedOpacity = 1
|
|
278
|
+
const rgbaMatch = shadowColor.match(
|
|
279
|
+
/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/i
|
|
280
|
+
)
|
|
281
|
+
if (rgbaMatch) {
|
|
282
|
+
const [, r, g, b, a] = rgbaMatch
|
|
283
|
+
resolvedColor = `rgb(${r}, ${g}, ${b})`
|
|
284
|
+
resolvedOpacity = a ? parseFloat(a) : 1
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Elevation: a rough heuristic — use blur + |offsetY| as the depth cue.
|
|
288
|
+
// Spread on focus rings (e.g. `0 0 0 3px`) should still produce visible
|
|
289
|
+
// elevation, so include it.
|
|
290
|
+
const elevation = Math.max(blur, spread, Math.abs(offsetY))
|
|
291
|
+
|
|
292
|
+
return {
|
|
293
|
+
shadowColor: resolvedColor,
|
|
294
|
+
shadowOffset: { width: offsetX, height: offsetY },
|
|
295
|
+
shadowOpacity: resolvedOpacity,
|
|
296
|
+
shadowRadius: blur + spread,
|
|
297
|
+
elevation,
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Parse a CSS `background` value into a `ParsedBackground`.
|
|
303
|
+
*
|
|
304
|
+
* - `"linear-gradient(180deg, #1A56DB -5%, #2563EB 107.5%)"` → gradient descriptor
|
|
305
|
+
* (percentage midpoints outside [0,1] are clamped — known limitation)
|
|
306
|
+
* - `"#FFFFFF"` / `"rgb(255,255,255)"` → flat color
|
|
307
|
+
* - `"none"` / `"transparent"` → null
|
|
308
|
+
*/
|
|
309
|
+
export function parseBackground(value: string | undefined): ParsedBackground {
|
|
310
|
+
if (!value || value === 'none' || value === 'transparent') return null
|
|
311
|
+
|
|
312
|
+
// Gradient?
|
|
313
|
+
const gradientMatch = value.match(
|
|
314
|
+
/linear-gradient\(\s*(\d+)deg\s*,\s*(.+)\s*\)/i
|
|
315
|
+
)
|
|
316
|
+
if (gradientMatch) {
|
|
317
|
+
const angle = parseFloat(gradientMatch[1])
|
|
318
|
+
const stopsStr = gradientMatch[2]
|
|
319
|
+
|
|
320
|
+
// Parse color stops: "<color> <position>?" separated by commas.
|
|
321
|
+
// Blend gradient tokens use hex colors (no embedded commas), so a
|
|
322
|
+
// simple split on "," is safe. Each stop is trimmed, then split on
|
|
323
|
+
// whitespace to separate color from its optional percentage position.
|
|
324
|
+
// Positions may be outside [0,1] (e.g. "-5%", "107.5%") — clamped.
|
|
325
|
+
const stopStrs = stopsStr
|
|
326
|
+
.split(',')
|
|
327
|
+
.map((s) => s.trim())
|
|
328
|
+
.filter(Boolean)
|
|
329
|
+
const colors: string[] = []
|
|
330
|
+
const locations: number[] = []
|
|
331
|
+
for (const stop of stopStrs) {
|
|
332
|
+
// "color" or "color position%"
|
|
333
|
+
const parts = stop.split(/\s+/)
|
|
334
|
+
colors.push(parts[0])
|
|
335
|
+
if (parts[1]) {
|
|
336
|
+
const pct = parseFloat(parts[1]) / 100
|
|
337
|
+
locations.push(Math.min(1, Math.max(0, pct)))
|
|
338
|
+
} else {
|
|
339
|
+
locations.push(0)
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if (colors.length < 2) {
|
|
344
|
+
// Degenerate gradient — treat as flat color.
|
|
345
|
+
return colors[0] ? { type: 'flat', color: colors[0] } : null
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// If locations weren't specified, distribute evenly.
|
|
349
|
+
const allZero = locations.every((l) => l === 0)
|
|
350
|
+
let resolvedLocations = locations
|
|
351
|
+
if (allZero) {
|
|
352
|
+
resolvedLocations = colors.map((_, i) => i / (colors.length - 1))
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Convert CSS angle (0deg = bottom→top) to RN {start, end} coords.
|
|
356
|
+
// RN's LinearGradient uses normalized [0,1] coordinates on the bounding box.
|
|
357
|
+
// 0deg → start={x:0.5,y:1} end={x:0.5,y:0}
|
|
358
|
+
// 90deg → start={x:0,y:0.5} end={x:1,y:0.5}
|
|
359
|
+
// 180deg → start={x:0.5,y:0} end={x:0.5,y:1}
|
|
360
|
+
const rad = (angle * Math.PI) / 180
|
|
361
|
+
const start = {
|
|
362
|
+
x: 0.5 - Math.sin(rad) * 0.5,
|
|
363
|
+
y: 0.5 + Math.cos(rad) * 0.5,
|
|
364
|
+
}
|
|
365
|
+
const end = {
|
|
366
|
+
x: 0.5 + Math.sin(rad) * 0.5,
|
|
367
|
+
y: 0.5 - Math.cos(rad) * 0.5,
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
return {
|
|
371
|
+
type: 'gradient',
|
|
372
|
+
colors,
|
|
373
|
+
locations: resolvedLocations,
|
|
374
|
+
start,
|
|
375
|
+
end,
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Solid color (hex / rgb / rgba / named)
|
|
380
|
+
if (/^(#[0-9a-fA-F]{3,8}|rgba?\(|[a-z]+)/i.test(value)) {
|
|
381
|
+
return { type: 'flat', color: value }
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return null
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Merge multiple style objects into one, skipping `undefined` values.
|
|
389
|
+
* Helper for composing adapter output with caller-provided overrides.
|
|
390
|
+
*/
|
|
391
|
+
export function mergeStyles<T extends object>(...styles: (T | undefined)[]): T {
|
|
392
|
+
const result: Record<string, unknown> = {}
|
|
393
|
+
for (const s of styles) {
|
|
394
|
+
if (!s) continue
|
|
395
|
+
for (const key of Object.keys(s)) {
|
|
396
|
+
const val = (s as Record<string, unknown>)[key]
|
|
397
|
+
if (val !== undefined && val !== null) {
|
|
398
|
+
result[key] = val
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return result as T
|
|
403
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type React from 'react'
|
|
2
|
+
import type { ViewStyle } from 'react-native'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Optional `expo-linear-gradient` probe, shared by every surface that can
|
|
6
|
+
* render a gradient (Pressable's gradient buttons, Skeleton's wave sweep).
|
|
7
|
+
*
|
|
8
|
+
* The probe must survive every build target this package ships:
|
|
9
|
+
*
|
|
10
|
+
* - **Metro (`react-native` condition, raw `src/`)** and the **CJS build**
|
|
11
|
+
* (`require`/`default` conditions): `require` exists, the module loads
|
|
12
|
+
* when installed, and the `catch` absorbs its absence.
|
|
13
|
+
* - **The ESM build** (`import` condition): there is no `require` in module
|
|
14
|
+
* scope. The `typeof` guard makes the degradation explicit — gradient
|
|
15
|
+
* surfaces fall back to a flat fill — instead of relying on a caught
|
|
16
|
+
* `ReferenceError`. Bundlers that polyfill `require` in ESM (webpack)
|
|
17
|
+
* still resolve the real module.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export type GradientComponent = React.ComponentType<{
|
|
21
|
+
colors: readonly string[]
|
|
22
|
+
locations?: readonly number[]
|
|
23
|
+
start?: { x: number; y: number }
|
|
24
|
+
end?: { x: number; y: number }
|
|
25
|
+
style?: ViewStyle
|
|
26
|
+
}>
|
|
27
|
+
|
|
28
|
+
type GradientModule = { LinearGradient: GradientComponent }
|
|
29
|
+
|
|
30
|
+
export let LinearGradient: GradientComponent | null = null
|
|
31
|
+
try {
|
|
32
|
+
if (typeof require === 'function') {
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
34
|
+
const mod: GradientModule = require('expo-linear-gradient')
|
|
35
|
+
LinearGradient = mod.LinearGradient
|
|
36
|
+
}
|
|
37
|
+
} catch {
|
|
38
|
+
LinearGradient = null
|
|
39
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import type { ViewStyle } from 'react-native'
|
|
2
|
+
import {
|
|
3
|
+
parseBackground,
|
|
4
|
+
parseBorder,
|
|
5
|
+
parseBorderRadius,
|
|
6
|
+
parseBoxShadow,
|
|
7
|
+
parseDimension,
|
|
8
|
+
parseSize,
|
|
9
|
+
type ParsedBackground,
|
|
10
|
+
} from './cssStringAdapter'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Shared CSS-string → `ViewStyle` resolution for every native surface.
|
|
14
|
+
*
|
|
15
|
+
* Both `Block` (a plain `View`) and `Pressable` (an interactive surface) need
|
|
16
|
+
* to turn the same token-shaped CSS strings into RN styles. Before this
|
|
17
|
+
* existed, `Pressable` inlined the whole translation and `Block` had none at
|
|
18
|
+
* all — which meant a non-interactive container could not render a border,
|
|
19
|
+
* a radius, or a height. Components that switch between the two depending on
|
|
20
|
+
* whether they are interactive (web's `TagElement = onClick ? PrimitiveButton
|
|
21
|
+
* : Block` pattern) would have rendered differently in each branch.
|
|
22
|
+
*
|
|
23
|
+
* Pure and total: unparseable input is dropped rather than thrown, and no key
|
|
24
|
+
* is emitted for a value that could not be resolved, so `undefined`/`NaN`
|
|
25
|
+
* never reaches RN's stylesheet.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Which platform's shadow model to emit.
|
|
30
|
+
*
|
|
31
|
+
* Passed in rather than read from `Platform.OS` so this module stays free of
|
|
32
|
+
* any `react-native` value import and remains unit-testable outside a
|
|
33
|
+
* renderer — the same constraint that shapes `theme/breakpoint.ts` and
|
|
34
|
+
* `primitives/touchTarget.ts`.
|
|
35
|
+
*/
|
|
36
|
+
export type SurfacePlatform = 'ios' | 'android' | 'web' | 'windows' | 'macos'
|
|
37
|
+
|
|
38
|
+
export type SurfaceStyleProps = {
|
|
39
|
+
/** CSS-string background token — flat colour, gradient, or `none`. */
|
|
40
|
+
background?: string
|
|
41
|
+
/** CSS-string border shorthand, e.g. `"1px solid #E1E4EA"`. */
|
|
42
|
+
border?: string
|
|
43
|
+
/** CSS border-radius: `"10px"`, `"9999px"`, or a 4-value corner string. */
|
|
44
|
+
borderRadius?: string | number
|
|
45
|
+
/** CSS box-shadow. Inset shadows are dropped (RN cannot render them). */
|
|
46
|
+
boxShadow?: string
|
|
47
|
+
|
|
48
|
+
paddingTop?: string | number
|
|
49
|
+
paddingRight?: string | number
|
|
50
|
+
paddingBottom?: string | number
|
|
51
|
+
paddingLeft?: string | number
|
|
52
|
+
|
|
53
|
+
width?: string | number
|
|
54
|
+
minWidth?: string | number
|
|
55
|
+
maxWidth?: string | number
|
|
56
|
+
height?: string | number
|
|
57
|
+
minHeight?: string | number
|
|
58
|
+
maxHeight?: string | number
|
|
59
|
+
|
|
60
|
+
flexDirection?: ViewStyle['flexDirection']
|
|
61
|
+
alignItems?: ViewStyle['alignItems']
|
|
62
|
+
justifyContent?: ViewStyle['justifyContent']
|
|
63
|
+
alignSelf?: ViewStyle['alignSelf']
|
|
64
|
+
gap?: string | number
|
|
65
|
+
flexShrink?: number
|
|
66
|
+
flexGrow?: number
|
|
67
|
+
opacity?: number
|
|
68
|
+
overflow?: ViewStyle['overflow']
|
|
69
|
+
/** Solid background colour, already RN-ready. Wins over `background`. */
|
|
70
|
+
backgroundColor?: string
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Assign `value` to `target[key]` only when it is a usable style value.
|
|
75
|
+
* Keeps `undefined` and `NaN` out of the emitted `ViewStyle`.
|
|
76
|
+
*/
|
|
77
|
+
function put<K extends keyof ViewStyle>(
|
|
78
|
+
target: ViewStyle,
|
|
79
|
+
key: K,
|
|
80
|
+
value: ViewStyle[K] | undefined
|
|
81
|
+
): void {
|
|
82
|
+
if (value === undefined || value === null) return
|
|
83
|
+
if (typeof value === 'number' && Number.isNaN(value)) return
|
|
84
|
+
target[key] = value
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Resolve the parsed background into `backgroundColor`, and report whether a
|
|
89
|
+
* gradient was requested. Gradients cannot be expressed as a `ViewStyle`, so
|
|
90
|
+
* callers that support them (`Pressable`) render a `<LinearGradient>` layer
|
|
91
|
+
* and callers that do not fall back to the gradient's first colour.
|
|
92
|
+
*/
|
|
93
|
+
export function resolveBackground(
|
|
94
|
+
background: string | undefined,
|
|
95
|
+
explicitBackgroundColor: string | undefined
|
|
96
|
+
): { backgroundColor?: string; gradient?: ParsedBackground } {
|
|
97
|
+
if (explicitBackgroundColor) {
|
|
98
|
+
return { backgroundColor: explicitBackgroundColor }
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const parsed = parseBackground(background)
|
|
102
|
+
if (!parsed) return {}
|
|
103
|
+
if (parsed.type === 'flat') return { backgroundColor: parsed.color }
|
|
104
|
+
|
|
105
|
+
// Gradient — hand it back for the caller to render, and supply the first
|
|
106
|
+
// stop as a static fallback so a non-gradient-capable surface still shows
|
|
107
|
+
// something in the right colour family rather than transparent.
|
|
108
|
+
return { backgroundColor: parsed.colors[0], gradient: parsed }
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Apply the shadow model the platform actually understands.
|
|
113
|
+
*
|
|
114
|
+
* The two are mutually exclusive in practice:
|
|
115
|
+
*
|
|
116
|
+
* - **iOS** renders `shadowColor` / `shadowOffset` / `shadowOpacity` /
|
|
117
|
+
* `shadowRadius` and ignores `elevation` entirely.
|
|
118
|
+
* - **Android** renders only `elevation`, and before API 28 it ignores
|
|
119
|
+
* `shadowColor` — so emitting the iOS keys alongside it is at best dead
|
|
120
|
+
* weight and at worst misleading to anyone reading the resolved style.
|
|
121
|
+
* - **Web** (react-native-web) maps the iOS keys onto `box-shadow`, as do
|
|
122
|
+
* RN-Windows and RN-macOS — so Android is the only platform that diverges.
|
|
123
|
+
*
|
|
124
|
+
* Emitting both unconditionally, as this used to, meant every surface carried
|
|
125
|
+
* four properties the running platform would never read.
|
|
126
|
+
*/
|
|
127
|
+
function applyShadow(
|
|
128
|
+
style: ViewStyle,
|
|
129
|
+
shadow: ReturnType<typeof parseBoxShadow>,
|
|
130
|
+
platform: SurfacePlatform
|
|
131
|
+
): void {
|
|
132
|
+
if (!shadow) return
|
|
133
|
+
|
|
134
|
+
if (platform === 'android') {
|
|
135
|
+
put(style, 'elevation', shadow.elevation)
|
|
136
|
+
return
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
put(style, 'shadowColor', shadow.shadowColor)
|
|
140
|
+
put(style, 'shadowOffset', shadow.shadowOffset)
|
|
141
|
+
put(style, 'shadowOpacity', shadow.shadowOpacity)
|
|
142
|
+
put(style, 'shadowRadius', shadow.shadowRadius)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Translate token-shaped surface props into a `ViewStyle`.
|
|
147
|
+
*
|
|
148
|
+
* Gradients are reported separately via `resolveBackground` — this function
|
|
149
|
+
* emits only the flat-colour fallback, so it is safe for any `View`.
|
|
150
|
+
*/
|
|
151
|
+
export function resolveSurfaceStyle(
|
|
152
|
+
props: SurfaceStyleProps,
|
|
153
|
+
platform: SurfacePlatform = 'ios'
|
|
154
|
+
): ViewStyle {
|
|
155
|
+
const style: ViewStyle = {}
|
|
156
|
+
|
|
157
|
+
// ---- Background -----------------------------------------------------
|
|
158
|
+
const { backgroundColor } = resolveBackground(
|
|
159
|
+
props.background,
|
|
160
|
+
props.backgroundColor
|
|
161
|
+
)
|
|
162
|
+
put(style, 'backgroundColor', backgroundColor)
|
|
163
|
+
|
|
164
|
+
// ---- Border ---------------------------------------------------------
|
|
165
|
+
const borderStyle = parseBorder(props.border)
|
|
166
|
+
put(style, 'borderWidth', borderStyle.borderWidth)
|
|
167
|
+
put(style, 'borderColor', borderStyle.borderColor)
|
|
168
|
+
|
|
169
|
+
// ---- Radius ---------------------------------------------------------
|
|
170
|
+
const radius = parseBorderRadius(props.borderRadius)
|
|
171
|
+
if (typeof radius === 'number') {
|
|
172
|
+
put(style, 'borderRadius', radius)
|
|
173
|
+
} else if (radius && typeof radius === 'object') {
|
|
174
|
+
put(style, 'borderTopLeftRadius', radius.borderTopLeftRadius)
|
|
175
|
+
put(style, 'borderTopRightRadius', radius.borderTopRightRadius)
|
|
176
|
+
put(style, 'borderBottomRightRadius', radius.borderBottomRightRadius)
|
|
177
|
+
put(style, 'borderBottomLeftRadius', radius.borderBottomLeftRadius)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// ---- Shadow ---------------------------------------------------------
|
|
181
|
+
applyShadow(style, parseBoxShadow(props.boxShadow), platform)
|
|
182
|
+
|
|
183
|
+
// ---- Spacing --------------------------------------------------------
|
|
184
|
+
put(style, 'paddingTop', parseDimension(props.paddingTop))
|
|
185
|
+
put(style, 'paddingRight', parseDimension(props.paddingRight))
|
|
186
|
+
put(style, 'paddingBottom', parseDimension(props.paddingBottom))
|
|
187
|
+
put(style, 'paddingLeft', parseDimension(props.paddingLeft))
|
|
188
|
+
put(style, 'gap', parseDimension(props.gap))
|
|
189
|
+
|
|
190
|
+
// ---- Sizing ---------------------------------------------------------
|
|
191
|
+
put(style, 'width', parseSize(props.width))
|
|
192
|
+
put(style, 'minWidth', parseSize(props.minWidth))
|
|
193
|
+
put(style, 'maxWidth', parseSize(props.maxWidth))
|
|
194
|
+
put(style, 'height', parseSize(props.height))
|
|
195
|
+
put(style, 'minHeight', parseSize(props.minHeight))
|
|
196
|
+
put(style, 'maxHeight', parseSize(props.maxHeight))
|
|
197
|
+
|
|
198
|
+
// ---- Layout (already RN-shaped) -------------------------------------
|
|
199
|
+
put(style, 'flexDirection', props.flexDirection)
|
|
200
|
+
put(style, 'alignItems', props.alignItems)
|
|
201
|
+
put(style, 'justifyContent', props.justifyContent)
|
|
202
|
+
put(style, 'alignSelf', props.alignSelf)
|
|
203
|
+
put(style, 'flexShrink', props.flexShrink)
|
|
204
|
+
put(style, 'flexGrow', props.flexGrow)
|
|
205
|
+
put(style, 'opacity', props.opacity)
|
|
206
|
+
put(style, 'overflow', props.overflow)
|
|
207
|
+
|
|
208
|
+
return style
|
|
209
|
+
}
|