@unif/react-native-design 0.8.1 → 0.9.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 +3 -4
- package/lib/module/components/business/AvatarWithRing/AvatarWithRing.js +6 -4
- package/lib/module/components/business/AvatarWithRing/AvatarWithRing.js.map +1 -1
- package/lib/module/components/business/AvatarWithRing/styles.js +15 -3
- package/lib/module/components/business/AvatarWithRing/styles.js.map +1 -1
- package/lib/module/components/business/Decorations/GradientWash.js +50 -36
- package/lib/module/components/business/Decorations/GradientWash.js.map +1 -1
- package/lib/module/components/business/Decorations/RadialHalo.js +10 -4
- package/lib/module/components/business/Decorations/RadialHalo.js.map +1 -1
- package/lib/module/components/business/Decorations/ScreenBackdrop.js +22 -14
- package/lib/module/components/business/Decorations/ScreenBackdrop.js.map +1 -1
- package/lib/module/components/business/Decorations/index.js +3 -0
- package/lib/module/components/business/Decorations/index.js.map +1 -1
- package/lib/module/components/business/GlassStats/GlassStats.js +7 -4
- package/lib/module/components/business/GlassStats/GlassStats.js.map +1 -1
- package/lib/module/components/business/GlassStats/types.js +2 -0
- package/lib/module/components/business/VersionPill/VersionPill.js +23 -5
- package/lib/module/components/business/VersionPill/VersionPill.js.map +1 -1
- package/lib/module/components/business/VersionPill/styles.js +1 -1
- package/lib/module/components/business/index.js.map +1 -1
- package/lib/module/components/business/useSvgId.js +20 -0
- package/lib/module/components/business/useSvgId.js.map +1 -0
- package/lib/module/components/ui/Avatar/Avatar.js +13 -8
- package/lib/module/components/ui/Avatar/Avatar.js.map +1 -1
- package/lib/module/components/ui/Avatar/styles.js +7 -7
- package/lib/module/components/ui/Avatar/styles.js.map +1 -1
- package/lib/module/components/ui/BlurLayer/BlurLayer.js +5 -1
- package/lib/module/components/ui/BlurLayer/BlurLayer.js.map +1 -1
- package/lib/module/components/ui/BlurLayer/BlurLayer.web.js +7 -1
- package/lib/module/components/ui/BlurLayer/BlurLayer.web.js.map +1 -1
- package/lib/module/components/ui/Button/Button.js +2 -1
- package/lib/module/components/ui/Button/Button.js.map +1 -1
- package/lib/module/components/ui/Button/ButtonBase.js +36 -2
- package/lib/module/components/ui/Button/ButtonBase.js.map +1 -1
- package/lib/module/components/ui/Button/styles.js +27 -25
- package/lib/module/components/ui/Button/styles.js.map +1 -1
- package/lib/module/components/ui/Card/Card.js +17 -8
- package/lib/module/components/ui/Card/Card.js.map +1 -1
- package/lib/module/components/ui/Card/styles.js +6 -1
- package/lib/module/components/ui/Card/styles.js.map +1 -1
- package/lib/module/components/ui/Carousel/Carousel.js +36 -6
- package/lib/module/components/ui/Carousel/Carousel.js.map +1 -1
- package/lib/module/components/ui/Cell/Cell.js +23 -5
- package/lib/module/components/ui/Cell/Cell.js.map +1 -1
- package/lib/module/components/ui/Cell/Leading.js +2 -2
- package/lib/module/components/ui/Cell/Leading.js.map +1 -1
- package/lib/module/components/ui/Cell/List.js +10 -5
- package/lib/module/components/ui/Cell/List.js.map +1 -1
- package/lib/module/components/ui/Cell/styles.js +7 -6
- package/lib/module/components/ui/Cell/styles.js.map +1 -1
- package/lib/module/components/ui/Checkbox/Checkbox.js +10 -8
- package/lib/module/components/ui/Checkbox/Checkbox.js.map +1 -1
- package/lib/module/components/ui/Checkbox/styles.js +9 -1
- package/lib/module/components/ui/Checkbox/styles.js.map +1 -1
- package/lib/module/components/ui/Chip/Chip.js +19 -5
- package/lib/module/components/ui/Chip/Chip.js.map +1 -1
- package/lib/module/components/ui/Confirm/ConfirmHost.js +28 -11
- package/lib/module/components/ui/Confirm/ConfirmHost.js.map +1 -1
- package/lib/module/components/ui/Confirm/confirm.js +6 -0
- package/lib/module/components/ui/Confirm/confirm.js.map +1 -1
- package/lib/module/components/ui/DrawerHeader/DrawerHeader.js +14 -9
- package/lib/module/components/ui/DrawerHeader/DrawerHeader.js.map +1 -1
- package/lib/module/components/ui/DrawerHeader/styles.js +10 -6
- package/lib/module/components/ui/DrawerHeader/styles.js.map +1 -1
- package/lib/module/components/ui/Empty/Empty.js +5 -4
- package/lib/module/components/ui/Empty/Empty.js.map +1 -1
- package/lib/module/components/ui/EntryCard/EntryCard.js +5 -3
- package/lib/module/components/ui/EntryCard/EntryCard.js.map +1 -1
- package/lib/module/components/ui/EntryCard/styles.js +4 -4
- package/lib/module/components/ui/EntryCard/styles.js.map +1 -1
- package/lib/module/components/ui/Form/FormRow.js +1 -0
- package/lib/module/components/ui/Form/FormRow.js.map +1 -1
- package/lib/module/components/ui/Form/styles.js +3 -1
- package/lib/module/components/ui/Form/styles.js.map +1 -1
- package/lib/module/components/ui/Grid/Grid.js +39 -24
- package/lib/module/components/ui/Grid/Grid.js.map +1 -1
- package/lib/module/components/ui/Grid/styles.js +35 -46
- package/lib/module/components/ui/Grid/styles.js.map +1 -1
- package/lib/module/components/ui/Icon/Icon.js +46 -29
- package/lib/module/components/ui/Icon/Icon.js.map +1 -1
- package/lib/module/components/ui/IconButton/IconButton.js +2 -0
- package/lib/module/components/ui/IconButton/IconButton.js.map +1 -1
- package/lib/module/components/ui/Logo/Logo.js +2 -1
- package/lib/module/components/ui/Logo/Logo.js.map +1 -1
- package/lib/module/components/ui/NavBar/NavBar.js +15 -3
- package/lib/module/components/ui/NavBar/NavBar.js.map +1 -1
- package/lib/module/components/ui/PasswordInput/PasswordInput.js +43 -14
- package/lib/module/components/ui/PasswordInput/PasswordInput.js.map +1 -1
- package/lib/module/components/ui/PasswordInput/styles.js +1 -1
- package/lib/module/components/ui/Pulse/Pulse.js +2 -1
- package/lib/module/components/ui/Pulse/Pulse.js.map +1 -1
- package/lib/module/components/ui/Pulse/PulseDot.js +8 -10
- package/lib/module/components/ui/Pulse/PulseDot.js.map +1 -1
- package/lib/module/components/ui/Pulse/types.js +2 -0
- package/lib/module/components/ui/Pulse/usePulse.web.js +51 -30
- package/lib/module/components/ui/Pulse/usePulse.web.js.map +1 -1
- package/lib/module/components/ui/Radio/Radio.js +19 -5
- package/lib/module/components/ui/Radio/Radio.js.map +1 -1
- package/lib/module/components/ui/Radio/RadioGroup.js +10 -6
- package/lib/module/components/ui/Radio/RadioGroup.js.map +1 -1
- package/lib/module/components/ui/Radio/styles.js +10 -3
- package/lib/module/components/ui/Radio/styles.js.map +1 -1
- package/lib/module/components/ui/Reveal/Reveal.web.js +18 -3
- package/lib/module/components/ui/Reveal/Reveal.web.js.map +1 -1
- package/lib/module/components/ui/Search/Search.js +26 -10
- package/lib/module/components/ui/Search/Search.js.map +1 -1
- package/lib/module/components/ui/Segmented/Segmented.js +40 -30
- package/lib/module/components/ui/Segmented/Segmented.js.map +1 -1
- package/lib/module/components/ui/Segmented/styles.js +4 -2
- package/lib/module/components/ui/Segmented/styles.js.map +1 -1
- package/lib/module/components/ui/Skeleton/Skeleton.js +9 -8
- package/lib/module/components/ui/Skeleton/Skeleton.js.map +1 -1
- package/lib/module/components/ui/Spinner/Spinner.js +15 -16
- package/lib/module/components/ui/Spinner/Spinner.js.map +1 -1
- package/lib/module/components/ui/Spinner/Spinner.web.js +10 -14
- package/lib/module/components/ui/Spinner/Spinner.web.js.map +1 -1
- package/lib/module/components/ui/Spinner/shared.js +31 -0
- package/lib/module/components/ui/Spinner/shared.js.map +1 -0
- package/lib/module/components/ui/StatusDot/StatusDot.js +21 -4
- package/lib/module/components/ui/StatusDot/StatusDot.js.map +1 -1
- package/lib/module/components/ui/StatusDot/styles.js +1 -1
- package/lib/module/components/ui/StatusDot/types.js +2 -0
- package/lib/module/components/ui/Stepper/Stepper.js +46 -10
- package/lib/module/components/ui/Stepper/Stepper.js.map +1 -1
- package/lib/module/components/ui/Switch/Switch.js +6 -11
- package/lib/module/components/ui/Switch/Switch.js.map +1 -1
- package/lib/module/components/ui/Switch/Switch.web.js +2 -8
- package/lib/module/components/ui/Switch/Switch.web.js.map +1 -1
- package/lib/module/components/ui/Switch/styles.js +12 -3
- package/lib/module/components/ui/Switch/styles.js.map +1 -1
- package/lib/module/components/ui/TabBar/TabBar.js +10 -6
- package/lib/module/components/ui/TabBar/TabBar.js.map +1 -1
- package/lib/module/components/ui/TabBar/styles.js +28 -39
- package/lib/module/components/ui/TabBar/styles.js.map +1 -1
- package/lib/module/components/ui/Tabs/Tabs.js +19 -5
- package/lib/module/components/ui/Tabs/Tabs.js.map +1 -1
- package/lib/module/components/ui/Tabs/styles.js +6 -2
- package/lib/module/components/ui/Tabs/styles.js.map +1 -1
- package/lib/module/components/ui/Tabs/types.js +2 -0
- package/lib/module/components/ui/Tag/styles.js +15 -14
- package/lib/module/components/ui/Tag/styles.js.map +1 -1
- package/lib/module/components/ui/TextField/TextFieldBase.js +24 -6
- package/lib/module/components/ui/TextField/TextFieldBase.js.map +1 -1
- package/lib/module/components/ui/Thumbnail/Thumbnail.js +11 -3
- package/lib/module/components/ui/Thumbnail/Thumbnail.js.map +1 -1
- package/lib/module/components/ui/Thumbnail/styles.js +6 -2
- package/lib/module/components/ui/Thumbnail/styles.js.map +1 -1
- package/lib/module/components/ui/Toast/ToastHost.js +16 -5
- package/lib/module/components/ui/Toast/ToastHost.js.map +1 -1
- package/lib/module/components/ui/Toast/ToastHost.web.js +21 -4
- package/lib/module/components/ui/Toast/ToastHost.web.js.map +1 -1
- package/lib/module/components/ui/Toast/styles.js +2 -0
- package/lib/module/components/ui/Toast/styles.js.map +1 -1
- package/lib/module/components/ui/Toast/toast.js +23 -3
- package/lib/module/components/ui/Toast/toast.js.map +1 -1
- package/lib/module/components/ui/shared/badgeStyles.js +31 -0
- package/lib/module/components/ui/shared/badgeStyles.js.map +1 -0
- package/lib/module/icons/data.js +43 -18
- package/lib/module/icons/data.js.map +1 -1
- package/lib/module/theme/colors.js +28 -10
- package/lib/module/theme/colors.js.map +1 -1
- package/lib/module/theme/index.js +6 -2
- package/lib/module/theme/index.js.map +1 -1
- package/lib/module/theme/scale.js +9 -1
- package/lib/module/theme/scale.js.map +1 -1
- package/lib/module/theme/shadow.js +24 -41
- package/lib/module/theme/shadow.js.map +1 -1
- package/lib/module/theme/tokens.js +10 -5
- package/lib/module/theme/tokens.js.map +1 -1
- package/lib/module/theme/usePrefersReducedMotion.js +12 -0
- package/lib/module/theme/usePrefersReducedMotion.js.map +1 -0
- package/lib/module/theme/usePrefersReducedMotion.web.js +25 -0
- package/lib/module/theme/usePrefersReducedMotion.web.js.map +1 -0
- package/lib/module/theme/useTheme.js +13 -0
- package/lib/module/theme/useTheme.js.map +1 -1
- package/lib/module/utils/logger/logger.js +5 -1
- package/lib/module/utils/logger/logger.js.map +1 -1
- package/lib/module/utils/testID/testID.js +6 -3
- package/lib/module/utils/testID/testID.js.map +1 -1
- package/lib/typescript/src/components/business/AvatarWithRing/AvatarWithRing.d.ts +1 -1
- package/lib/typescript/src/components/business/AvatarWithRing/AvatarWithRing.d.ts.map +1 -1
- package/lib/typescript/src/components/business/AvatarWithRing/styles.d.ts +5 -5
- package/lib/typescript/src/components/business/AvatarWithRing/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/business/AvatarWithRing/types.d.ts +3 -1
- package/lib/typescript/src/components/business/AvatarWithRing/types.d.ts.map +1 -1
- package/lib/typescript/src/components/business/Decorations/GradientWash.d.ts +25 -0
- package/lib/typescript/src/components/business/Decorations/GradientWash.d.ts.map +1 -1
- package/lib/typescript/src/components/business/Decorations/RadialHalo.d.ts.map +1 -1
- package/lib/typescript/src/components/business/Decorations/ScreenBackdrop.d.ts +1 -1
- package/lib/typescript/src/components/business/Decorations/ScreenBackdrop.d.ts.map +1 -1
- package/lib/typescript/src/components/business/Decorations/index.d.ts +1 -1
- package/lib/typescript/src/components/business/Decorations/index.d.ts.map +1 -1
- package/lib/typescript/src/components/business/Decorations/types.d.ts +2 -0
- package/lib/typescript/src/components/business/Decorations/types.d.ts.map +1 -1
- package/lib/typescript/src/components/business/GlassStats/GlassStats.d.ts +1 -1
- package/lib/typescript/src/components/business/GlassStats/GlassStats.d.ts.map +1 -1
- package/lib/typescript/src/components/business/GlassStats/styles.d.ts +2 -2
- package/lib/typescript/src/components/business/GlassStats/types.d.ts +5 -0
- package/lib/typescript/src/components/business/GlassStats/types.d.ts.map +1 -1
- package/lib/typescript/src/components/business/VersionPill/VersionPill.d.ts +1 -1
- package/lib/typescript/src/components/business/VersionPill/VersionPill.d.ts.map +1 -1
- package/lib/typescript/src/components/business/VersionPill/styles.d.ts +1 -1
- package/lib/typescript/src/components/business/VersionPill/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/business/VersionPill/types.d.ts +13 -1
- package/lib/typescript/src/components/business/VersionPill/types.d.ts.map +1 -1
- package/lib/typescript/src/components/business/index.d.ts +1 -1
- package/lib/typescript/src/components/business/index.d.ts.map +1 -1
- package/lib/typescript/src/components/business/useSvgId.d.ts +12 -0
- package/lib/typescript/src/components/business/useSvgId.d.ts.map +1 -0
- package/lib/typescript/src/components/ui/Avatar/Avatar.d.ts +1 -1
- package/lib/typescript/src/components/ui/Avatar/Avatar.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Avatar/styles.d.ts +1 -1
- package/lib/typescript/src/components/ui/Avatar/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Avatar/types.d.ts +3 -1
- package/lib/typescript/src/components/ui/Avatar/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/BlurLayer/BlurLayer.d.ts +1 -1
- package/lib/typescript/src/components/ui/BlurLayer/BlurLayer.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/BlurLayer/BlurLayer.web.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Button/Button.d.ts +1 -1
- package/lib/typescript/src/components/ui/Button/Button.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Button/ButtonBase.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Button/styles.d.ts +2 -1
- package/lib/typescript/src/components/ui/Button/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Button/types.d.ts +1 -1
- package/lib/typescript/src/components/ui/Button/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Card/Card.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Card/styles.d.ts +2 -0
- package/lib/typescript/src/components/ui/Card/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Card/types.d.ts +4 -4
- package/lib/typescript/src/components/ui/Card/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Carousel/Carousel.d.ts +4 -11
- package/lib/typescript/src/components/ui/Carousel/Carousel.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Carousel/index.d.ts +1 -1
- package/lib/typescript/src/components/ui/Carousel/index.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Carousel/types.d.ts +4 -0
- package/lib/typescript/src/components/ui/Carousel/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Cell/Cell.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Cell/List.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Cell/styles.d.ts +1 -1
- package/lib/typescript/src/components/ui/Cell/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Cell/types.d.ts +5 -2
- package/lib/typescript/src/components/ui/Cell/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Checkbox/Checkbox.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Checkbox/styles.d.ts +6 -0
- package/lib/typescript/src/components/ui/Checkbox/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Chip/Chip.d.ts +4 -3
- package/lib/typescript/src/components/ui/Chip/Chip.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Chip/types.d.ts +2 -0
- package/lib/typescript/src/components/ui/Chip/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Confirm/ConfirmHost.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Confirm/confirm.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Confirm/types.d.ts +4 -2
- package/lib/typescript/src/components/ui/Confirm/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/DrawerHeader/DrawerHeader.d.ts +1 -1
- package/lib/typescript/src/components/ui/DrawerHeader/DrawerHeader.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/DrawerHeader/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/DrawerHeader/types.d.ts +3 -1
- package/lib/typescript/src/components/ui/DrawerHeader/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Empty/Empty.d.ts +2 -2
- package/lib/typescript/src/components/ui/Empty/Empty.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Empty/types.d.ts +3 -0
- package/lib/typescript/src/components/ui/Empty/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/EntryCard/EntryCard.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/EntryCard/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/EntryCard/types.d.ts +2 -2
- package/lib/typescript/src/components/ui/EntryCard/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Form/FormRow.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Form/styles.d.ts +1 -0
- package/lib/typescript/src/components/ui/Form/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Form/types.d.ts +7 -2
- package/lib/typescript/src/components/ui/Form/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Grid/Grid.d.ts +1 -1
- package/lib/typescript/src/components/ui/Grid/Grid.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Grid/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Grid/types.d.ts +4 -1
- package/lib/typescript/src/components/ui/Grid/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Icon/Icon.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/IconButton/IconButton.d.ts +1 -1
- package/lib/typescript/src/components/ui/IconButton/IconButton.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/IconButton/types.d.ts +7 -2
- package/lib/typescript/src/components/ui/IconButton/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Input/Input.d.ts +16 -16
- package/lib/typescript/src/components/ui/Input/types.d.ts +3 -2
- package/lib/typescript/src/components/ui/Input/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Logo/Logo.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/NavBar/NavBar.d.ts +8 -1
- package/lib/typescript/src/components/ui/NavBar/NavBar.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/NavBar/types.d.ts +5 -1
- package/lib/typescript/src/components/ui/NavBar/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/PasswordInput/PasswordInput.d.ts +13 -5
- package/lib/typescript/src/components/ui/PasswordInput/PasswordInput.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/PasswordInput/styles.d.ts +1 -1
- package/lib/typescript/src/components/ui/PasswordInput/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/PasswordInput/types.d.ts +7 -2
- package/lib/typescript/src/components/ui/PasswordInput/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Pulse/Pulse.d.ts +1 -1
- package/lib/typescript/src/components/ui/Pulse/Pulse.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Pulse/PulseDot.d.ts +1 -1
- package/lib/typescript/src/components/ui/Pulse/PulseDot.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Pulse/types.d.ts +5 -0
- package/lib/typescript/src/components/ui/Pulse/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Pulse/usePulse.web.d.ts +12 -8
- package/lib/typescript/src/components/ui/Pulse/usePulse.web.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Radio/Radio.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Radio/RadioGroup.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Radio/styles.d.ts +4 -2
- package/lib/typescript/src/components/ui/Radio/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Reveal/Reveal.web.d.ts +9 -0
- package/lib/typescript/src/components/ui/Reveal/Reveal.web.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Search/Search.d.ts +16 -15
- package/lib/typescript/src/components/ui/Search/Search.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Search/types.d.ts +3 -1
- package/lib/typescript/src/components/ui/Search/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Segmented/Segmented.d.ts +1 -1
- package/lib/typescript/src/components/ui/Segmented/Segmented.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Segmented/styles.d.ts +1 -1
- package/lib/typescript/src/components/ui/Segmented/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Segmented/types.d.ts +2 -0
- package/lib/typescript/src/components/ui/Segmented/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Skeleton/Skeleton.d.ts +3 -2
- package/lib/typescript/src/components/ui/Skeleton/Skeleton.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Spinner/Spinner.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Spinner/Spinner.web.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Spinner/shared.d.ts +5 -0
- package/lib/typescript/src/components/ui/Spinner/shared.d.ts.map +1 -0
- package/lib/typescript/src/components/ui/StatusDot/StatusDot.d.ts +1 -5
- package/lib/typescript/src/components/ui/StatusDot/StatusDot.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/StatusDot/styles.d.ts +1 -1
- package/lib/typescript/src/components/ui/StatusDot/types.d.ts +13 -1
- package/lib/typescript/src/components/ui/StatusDot/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Stepper/Stepper.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Switch/Switch.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Switch/Switch.web.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Switch/styles.d.ts +7 -1
- package/lib/typescript/src/components/ui/Switch/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/TabBar/TabBar.d.ts +2 -2
- package/lib/typescript/src/components/ui/TabBar/TabBar.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/TabBar/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/TabBar/types.d.ts +3 -0
- package/lib/typescript/src/components/ui/TabBar/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Tabs/Tabs.d.ts +1 -1
- package/lib/typescript/src/components/ui/Tabs/Tabs.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Tabs/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Tabs/types.d.ts +9 -1
- package/lib/typescript/src/components/ui/Tabs/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Tag/styles.d.ts +2 -1
- package/lib/typescript/src/components/ui/Tag/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Tag/types.d.ts +6 -2
- package/lib/typescript/src/components/ui/Tag/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/TextField/TextFieldBase.d.ts +16 -16
- package/lib/typescript/src/components/ui/TextField/TextFieldBase.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Textarea/Textarea.d.ts +16 -16
- package/lib/typescript/src/components/ui/Textarea/types.d.ts +2 -1
- package/lib/typescript/src/components/ui/Textarea/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Thumbnail/Thumbnail.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Thumbnail/styles.d.ts +3 -0
- package/lib/typescript/src/components/ui/Thumbnail/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Toast/ToastHost.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Toast/ToastHost.web.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Toast/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Toast/toast.d.ts +0 -5
- package/lib/typescript/src/components/ui/Toast/toast.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/Toast/types.d.ts +1 -1
- package/lib/typescript/src/components/ui/Toast/types.d.ts.map +1 -1
- package/lib/typescript/src/components/ui/shared/badgeStyles.d.ts +27 -0
- package/lib/typescript/src/components/ui/shared/badgeStyles.d.ts.map +1 -0
- package/lib/typescript/src/icons/data.d.ts.map +1 -1
- package/lib/typescript/src/icons/types.d.ts +18 -12
- package/lib/typescript/src/icons/types.d.ts.map +1 -1
- package/lib/typescript/src/theme/colors.d.ts +9 -3
- package/lib/typescript/src/theme/colors.d.ts.map +1 -1
- package/lib/typescript/src/theme/index.d.ts +3 -2
- package/lib/typescript/src/theme/index.d.ts.map +1 -1
- package/lib/typescript/src/theme/scale.d.ts.map +1 -1
- package/lib/typescript/src/theme/shadow.d.ts +8 -8
- package/lib/typescript/src/theme/shadow.d.ts.map +1 -1
- package/lib/typescript/src/theme/tokens.d.ts +7 -3
- package/lib/typescript/src/theme/tokens.d.ts.map +1 -1
- package/lib/typescript/src/theme/usePrefersReducedMotion.d.ts +8 -0
- package/lib/typescript/src/theme/usePrefersReducedMotion.d.ts.map +1 -0
- package/lib/typescript/src/theme/usePrefersReducedMotion.web.d.ts +6 -0
- package/lib/typescript/src/theme/usePrefersReducedMotion.web.d.ts.map +1 -0
- package/lib/typescript/src/theme/useTheme.d.ts.map +1 -1
- package/lib/typescript/src/utils/logger/logger.d.ts.map +1 -1
- package/lib/typescript/src/utils/testID/testID.d.ts +6 -3
- package/lib/typescript/src/utils/testID/testID.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/components/business/AvatarWithRing/AvatarWithRing.tsx +5 -4
- package/src/components/business/AvatarWithRing/styles.ts +21 -3
- package/src/components/business/AvatarWithRing/types.ts +3 -1
- package/src/components/business/Decorations/GradientWash.tsx +46 -22
- package/src/components/business/Decorations/RadialHalo.tsx +8 -4
- package/src/components/business/Decorations/ScreenBackdrop.tsx +23 -5
- package/src/components/business/Decorations/index.ts +4 -0
- package/src/components/business/Decorations/types.ts +2 -0
- package/src/components/business/GlassStats/GlassStats.tsx +8 -4
- package/src/components/business/GlassStats/types.ts +6 -0
- package/src/components/business/VersionPill/VersionPill.tsx +46 -6
- package/src/components/business/VersionPill/styles.ts +1 -1
- package/src/components/business/VersionPill/types.ts +13 -1
- package/src/components/business/index.ts +1 -0
- package/src/components/business/useSvgId.ts +17 -0
- package/src/components/ui/Avatar/Avatar.tsx +17 -10
- package/src/components/ui/Avatar/styles.ts +7 -7
- package/src/components/ui/Avatar/types.ts +3 -1
- package/src/components/ui/BlurLayer/BlurLayer.tsx +4 -1
- package/src/components/ui/BlurLayer/BlurLayer.web.tsx +7 -1
- package/src/components/ui/Button/Button.tsx +2 -1
- package/src/components/ui/Button/ButtonBase.tsx +26 -2
- package/src/components/ui/Button/styles.ts +27 -25
- package/src/components/ui/Button/types.ts +1 -1
- package/src/components/ui/Card/Card.tsx +17 -7
- package/src/components/ui/Card/styles.ts +5 -0
- package/src/components/ui/Card/types.ts +4 -4
- package/src/components/ui/Carousel/Carousel.tsx +44 -15
- package/src/components/ui/Carousel/index.ts +1 -1
- package/src/components/ui/Carousel/types.ts +5 -0
- package/src/components/ui/Cell/Cell.tsx +28 -6
- package/src/components/ui/Cell/Leading.tsx +2 -2
- package/src/components/ui/Cell/List.tsx +14 -8
- package/src/components/ui/Cell/styles.ts +8 -5
- package/src/components/ui/Cell/types.ts +5 -2
- package/src/components/ui/Checkbox/Checkbox.tsx +18 -5
- package/src/components/ui/Checkbox/styles.ts +8 -0
- package/src/components/ui/Chip/Chip.tsx +20 -5
- package/src/components/ui/Chip/types.ts +2 -0
- package/src/components/ui/Confirm/ConfirmHost.tsx +26 -10
- package/src/components/ui/Confirm/confirm.ts +8 -0
- package/src/components/ui/Confirm/types.ts +4 -2
- package/src/components/ui/DrawerHeader/DrawerHeader.tsx +18 -12
- package/src/components/ui/DrawerHeader/styles.ts +10 -6
- package/src/components/ui/DrawerHeader/types.ts +3 -1
- package/src/components/ui/Empty/Empty.tsx +5 -4
- package/src/components/ui/Empty/types.ts +3 -0
- package/src/components/ui/EntryCard/EntryCard.tsx +5 -3
- package/src/components/ui/EntryCard/styles.ts +13 -4
- package/src/components/ui/EntryCard/types.ts +2 -2
- package/src/components/ui/Form/FormRow.tsx +7 -1
- package/src/components/ui/Form/styles.ts +2 -0
- package/src/components/ui/Form/types.ts +7 -2
- package/src/components/ui/Grid/Grid.tsx +42 -25
- package/src/components/ui/Grid/styles.ts +8 -20
- package/src/components/ui/Grid/types.ts +4 -1
- package/src/components/ui/Icon/Icon.tsx +42 -27
- package/src/components/ui/IconButton/IconButton.tsx +2 -0
- package/src/components/ui/IconButton/types.ts +8 -2
- package/src/components/ui/Input/types.ts +3 -2
- package/src/components/ui/Logo/Logo.tsx +2 -1
- package/src/components/ui/NavBar/NavBar.tsx +16 -2
- package/src/components/ui/NavBar/types.ts +5 -1
- package/src/components/ui/PasswordInput/PasswordInput.tsx +77 -43
- package/src/components/ui/PasswordInput/styles.ts +1 -1
- package/src/components/ui/PasswordInput/types.ts +7 -2
- package/src/components/ui/Pulse/Pulse.tsx +2 -1
- package/src/components/ui/Pulse/PulseDot.tsx +7 -6
- package/src/components/ui/Pulse/types.ts +6 -0
- package/src/components/ui/Pulse/usePulse.web.ts +50 -33
- package/src/components/ui/Radio/Radio.tsx +29 -6
- package/src/components/ui/Radio/RadioGroup.tsx +10 -3
- package/src/components/ui/Radio/styles.ts +9 -2
- package/src/components/ui/Reveal/Reveal.web.tsx +18 -3
- package/src/components/ui/Search/Search.tsx +22 -9
- package/src/components/ui/Search/types.ts +7 -1
- package/src/components/ui/Segmented/Segmented.tsx +8 -3
- package/src/components/ui/Segmented/styles.ts +4 -2
- package/src/components/ui/Segmented/types.ts +2 -0
- package/src/components/ui/Skeleton/Skeleton.tsx +9 -8
- package/src/components/ui/Spinner/Spinner.tsx +17 -17
- package/src/components/ui/Spinner/Spinner.web.tsx +7 -15
- package/src/components/ui/Spinner/shared.ts +37 -0
- package/src/components/ui/StatusDot/StatusDot.tsx +21 -3
- package/src/components/ui/StatusDot/styles.ts +1 -1
- package/src/components/ui/StatusDot/types.ts +14 -1
- package/src/components/ui/Stepper/Stepper.tsx +45 -10
- package/src/components/ui/Switch/Switch.tsx +4 -10
- package/src/components/ui/Switch/Switch.web.tsx +2 -8
- package/src/components/ui/Switch/styles.ts +10 -1
- package/src/components/ui/TabBar/TabBar.tsx +14 -6
- package/src/components/ui/TabBar/styles.ts +9 -21
- package/src/components/ui/TabBar/types.ts +3 -0
- package/src/components/ui/Tabs/Tabs.tsx +24 -5
- package/src/components/ui/Tabs/styles.ts +6 -2
- package/src/components/ui/Tabs/types.ts +10 -1
- package/src/components/ui/Tag/styles.ts +18 -10
- package/src/components/ui/Tag/types.ts +6 -2
- package/src/components/ui/TextField/TextFieldBase.tsx +31 -6
- package/src/components/ui/Textarea/types.ts +2 -1
- package/src/components/ui/Thumbnail/Thumbnail.tsx +14 -3
- package/src/components/ui/Thumbnail/styles.ts +6 -2
- package/src/components/ui/Toast/ToastHost.tsx +16 -8
- package/src/components/ui/Toast/ToastHost.web.tsx +26 -4
- package/src/components/ui/Toast/styles.ts +2 -0
- package/src/components/ui/Toast/toast.ts +35 -2
- package/src/components/ui/Toast/types.ts +1 -1
- package/src/components/ui/shared/badgeStyles.ts +36 -0
- package/src/icons/data.ts +27 -0
- package/src/icons/types.ts +25 -10
- package/src/theme/colors.ts +29 -10
- package/src/theme/index.ts +10 -1
- package/src/theme/scale.ts +5 -1
- package/src/theme/shadow.ts +33 -24
- package/src/theme/tokens.ts +10 -5
- package/src/theme/usePrefersReducedMotion.ts +9 -0
- package/src/theme/usePrefersReducedMotion.web.ts +27 -0
- package/src/theme/useTheme.ts +15 -0
- package/src/utils/logger/logger.ts +5 -1
- package/src/utils/testID/testID.ts +6 -3
- package/lib/module/components/index.js +0 -5
- package/lib/module/components/index.js.map +0 -1
- package/lib/typescript/src/components/index.d.ts +0 -3
- package/lib/typescript/src/components/index.d.ts.map +0 -1
- package/src/components/index.ts +0 -2
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Text, View } from 'react-native';
|
|
3
3
|
import { Pressable } from 'react-native-gesture-handler';
|
|
4
|
-
import { useThemedStyles } from '../../../theme';
|
|
4
|
+
import { fixed, pressedOpacity, useThemedStyles } from '../../../theme';
|
|
5
5
|
import { createLogger } from '../../../utils/logger';
|
|
6
|
+
import { childTestID } from '../../../utils/testID';
|
|
6
7
|
import { makeStyles, sizingFor } from './styles';
|
|
7
8
|
import type { StepperProps } from './types';
|
|
8
9
|
|
|
9
10
|
const log = createLogger('Stepper');
|
|
10
11
|
|
|
12
|
+
// [L-30] 模块级 Set 去重 —— step/min/max 告警只打一次,避免渲染阶段刷屏
|
|
13
|
+
const _warned = new Set<string>();
|
|
14
|
+
|
|
11
15
|
/**
|
|
12
16
|
* 数字步进器 [−][ N ][+]。
|
|
13
17
|
* 按钮自动夹到 min/max;越界的按钮透明度变 0.4。
|
|
@@ -28,11 +32,21 @@ export function Stepper({
|
|
|
28
32
|
const styles = useThemedStyles(makeStyles);
|
|
29
33
|
const dims = sizingFor(size);
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
// [L-30] step 口径对齐:非有限数(NaN/Infinity)也告警,与 min>max 告警保持一致
|
|
36
|
+
// 模块级 Set 去重:每个异常组合只打一次告警,避免渲染阶段重复刷屏
|
|
37
|
+
if (!Number.isFinite(step) || step <= 0) {
|
|
38
|
+
const k = `step:${step}`;
|
|
39
|
+
if (!_warned.has(k)) {
|
|
40
|
+
_warned.add(k);
|
|
41
|
+
log.warn(`step 必须是有限正数,传入 ${step},已 fallback 为 1`);
|
|
42
|
+
}
|
|
33
43
|
}
|
|
34
44
|
if (Number.isFinite(min) && Number.isFinite(max) && min > max) {
|
|
35
|
-
|
|
45
|
+
const k = `minmax:${min}:${max}`;
|
|
46
|
+
if (!_warned.has(k)) {
|
|
47
|
+
_warned.add(k);
|
|
48
|
+
log.warn(`min(${min}) 不能大于 max(${max}),已按 min 渲染`);
|
|
49
|
+
}
|
|
36
50
|
}
|
|
37
51
|
const safeStep = Number.isFinite(step) && step > 0 ? step : 1;
|
|
38
52
|
const safeMin = Number.isFinite(min) ? min : 0;
|
|
@@ -44,8 +58,15 @@ export function Stepper({
|
|
|
44
58
|
const decDisabled = disabled || safeValue <= safeMin;
|
|
45
59
|
const incDisabled = disabled || safeValue >= safeMax;
|
|
46
60
|
|
|
61
|
+
// [M-7] 按钮高 sm=28 / md=32 均低于 fixed.hitTarget=44;hitSlop 不越父边界,
|
|
62
|
+
// 须让容器一并扩展:wrap 加垂直 padding 把命中区撑到 44pt。
|
|
63
|
+
const wrapPaddingV = Math.max(0, Math.round((fixed.hitTarget - dims.h) / 2));
|
|
64
|
+
|
|
47
65
|
return (
|
|
48
|
-
<View
|
|
66
|
+
<View
|
|
67
|
+
style={[styles.wrap, { paddingVertical: wrapPaddingV }]}
|
|
68
|
+
testID={testID}
|
|
69
|
+
>
|
|
49
70
|
<Pressable
|
|
50
71
|
onPress={() => onChange(Math.max(safeMin, safeValue - safeStep))}
|
|
51
72
|
disabled={decDisabled}
|
|
@@ -53,21 +74,35 @@ export function Stepper({
|
|
|
53
74
|
accessibilityLabel="减少"
|
|
54
75
|
accessibilityState={{ disabled: decDisabled }}
|
|
55
76
|
accessibilityHint={`当前值 ${safeValue},减 ${safeStep}`}
|
|
56
|
-
testID={testID
|
|
77
|
+
testID={childTestID(testID, 'decrement')}
|
|
57
78
|
style={({ pressed }) => [
|
|
58
79
|
styles.cell,
|
|
59
80
|
styles.btnLeft,
|
|
60
81
|
{ width: dims.btn, height: dims.h },
|
|
61
|
-
{ opacity: decDisabled ? 0.4 : pressed ?
|
|
82
|
+
{ opacity: decDisabled ? 0.4 : pressed ? pressedOpacity : 1 },
|
|
62
83
|
]}
|
|
63
84
|
>
|
|
64
85
|
<Text style={styles.btnText}>−</Text>
|
|
65
86
|
</Pressable>
|
|
87
|
+
{/* [L-29] adjustable 需配 accessible + accessibilityActions + onAccessibilityAction,
|
|
88
|
+
否则 iOS VoiceOver 宣读"可调节"但滑动手势无响应。*/}
|
|
66
89
|
<View
|
|
90
|
+
accessible
|
|
67
91
|
accessibilityRole="adjustable"
|
|
68
92
|
accessibilityValue={{ min: safeMin, max: safeMax, now: safeValue }}
|
|
93
|
+
accessibilityActions={[
|
|
94
|
+
{ name: 'increment', label: '增加' },
|
|
95
|
+
{ name: 'decrement', label: '减少' },
|
|
96
|
+
]}
|
|
97
|
+
onAccessibilityAction={(e) => {
|
|
98
|
+
if (e.nativeEvent.actionName === 'increment' && !incDisabled) {
|
|
99
|
+
onChange(Math.min(safeMax, safeValue + safeStep));
|
|
100
|
+
} else if (e.nativeEvent.actionName === 'decrement' && !decDisabled) {
|
|
101
|
+
onChange(Math.max(safeMin, safeValue - safeStep));
|
|
102
|
+
}
|
|
103
|
+
}}
|
|
69
104
|
style={[styles.cell, { minWidth: dims.w, height: dims.h }]}
|
|
70
|
-
testID={testID
|
|
105
|
+
testID={childTestID(testID, 'value')}
|
|
71
106
|
>
|
|
72
107
|
<Text style={[styles.valueText, { fontSize: dims.fs }]}>
|
|
73
108
|
{safeValue}
|
|
@@ -80,12 +115,12 @@ export function Stepper({
|
|
|
80
115
|
accessibilityLabel="增加"
|
|
81
116
|
accessibilityState={{ disabled: incDisabled }}
|
|
82
117
|
accessibilityHint={`当前值 ${safeValue},加 ${safeStep}`}
|
|
83
|
-
testID={testID
|
|
118
|
+
testID={childTestID(testID, 'increment')}
|
|
84
119
|
style={({ pressed }) => [
|
|
85
120
|
styles.cell,
|
|
86
121
|
styles.btnRight,
|
|
87
122
|
{ width: dims.btn, height: dims.h },
|
|
88
|
-
{ opacity: incDisabled ? 0.4 : pressed ?
|
|
123
|
+
{ opacity: incDisabled ? 0.4 : pressed ? pressedOpacity : 1 },
|
|
89
124
|
]}
|
|
90
125
|
>
|
|
91
126
|
<Text style={styles.btnText}>+</Text>
|
|
@@ -9,17 +9,10 @@ import Animated, {
|
|
|
9
9
|
useSharedValue,
|
|
10
10
|
withTiming,
|
|
11
11
|
} from 'react-native-reanimated';
|
|
12
|
-
import { motion, r, useColors, useThemedStyles } from '../../../theme';
|
|
13
|
-
import {
|
|
12
|
+
import { fixed, motion, r, useColors, useThemedStyles } from '../../../theme';
|
|
13
|
+
import { makeStyles, THUMB_OFF_X, THUMB_ON_X, TRACK_H } from './styles';
|
|
14
14
|
import type { SwitchProps } from './types';
|
|
15
15
|
|
|
16
|
-
// ─── 动画派生常量(组件私有,非 style)─────────────────────────────────────
|
|
17
|
-
// 把手 translateX 的 off / on 端点:左右各留 INSET 间距,
|
|
18
|
-
// off = INSET(2),on = trackW - INSET - thumbW(32-2-16=14)。
|
|
19
|
-
// 走 r() 保证多设备缩放跟 track / thumb 物理尺寸一致(否则非设计基准设备会错位)。
|
|
20
|
-
const THUMB_OFF_X = r(INSET);
|
|
21
|
-
const THUMB_ON_X = r(TRACK_W - INSET - THUMB);
|
|
22
|
-
|
|
23
16
|
/**
|
|
24
17
|
* 布尔切换。32×20 轨道 + 16×16 白色把手,200ms 缓动。
|
|
25
18
|
*
|
|
@@ -66,7 +59,8 @@ export function Switch({
|
|
|
66
59
|
<Pressable
|
|
67
60
|
onPress={() => !disabled && onChange(!value)}
|
|
68
61
|
disabled={disabled}
|
|
69
|
-
|
|
62
|
+
// [M-7] 轨道高 r(20)≈20pt;补 (44-20)/2=12 到 fixed.hitTarget
|
|
63
|
+
hitSlop={Math.round((fixed.hitTarget - r(TRACK_H)) / 2)}
|
|
70
64
|
style={disabled ? styles.pressableDisabled : styles.pressableEnabled}
|
|
71
65
|
accessibilityRole="switch"
|
|
72
66
|
accessibilityState={{ checked: value, disabled: !!disabled }}
|
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Pressable } from 'react-native-gesture-handler';
|
|
3
3
|
import { View } from 'react-native';
|
|
4
|
-
import { motion,
|
|
5
|
-
import {
|
|
4
|
+
import { motion, useColors, useThemedStyles } from '../../../theme';
|
|
5
|
+
import { makeStyles, THUMB_OFF_X, THUMB_ON_X } from './styles';
|
|
6
6
|
import type { SwitchProps } from './types';
|
|
7
7
|
|
|
8
|
-
// ─── 动画派生常量(组件私有,非 style)─────────────────────────────────────
|
|
9
|
-
// 把手 translateX 的 off / on 端点:左右各留 INSET 间距,
|
|
10
|
-
// off = INSET(2),on = trackW - INSET - thumbW(32-2-16=14)。
|
|
11
|
-
const THUMB_OFF_X = r(INSET);
|
|
12
|
-
const THUMB_ON_X = r(TRACK_W - INSET - THUMB);
|
|
13
|
-
|
|
14
8
|
/**
|
|
15
9
|
* Web 端 Switch —— RN-Web 上 reanimated 4 + worklets 0.9.x 的 useAnimatedStyle
|
|
16
10
|
* 链路会抛 `Object.keys(undefined)` TypeError(切换时打印,thumb 卡住),走 CSS
|
|
@@ -9,13 +9,21 @@ export const TRACK_H = 20;
|
|
|
9
9
|
export const THUMB = 16;
|
|
10
10
|
export const INSET = 2;
|
|
11
11
|
|
|
12
|
+
/** [M-25] 把手 translateX 端点 —— 与 styles 同源导出,Switch.tsx / Switch.web.tsx 两端 import。
|
|
13
|
+
* off = INSET(2),on = TRACK_W - INSET - THUMB(32-2-16=14)。走 r() 保证多设备缩放一致。 */
|
|
14
|
+
export const THUMB_OFF_X = r(INSET);
|
|
15
|
+
export const THUMB_ON_X = r(TRACK_W - INSET - THUMB);
|
|
16
|
+
|
|
12
17
|
export const makeStyles = (c: ColorTokens) =>
|
|
13
18
|
StyleSheet.create({
|
|
14
19
|
pressableEnabled: {
|
|
15
20
|
opacity: 1,
|
|
21
|
+
// [L-37] alignSelf:'flex-start' 防止父容器拉伸把手区域(与 Chip [M-8] 同口径)
|
|
22
|
+
alignSelf: 'flex-start' as const,
|
|
16
23
|
},
|
|
17
24
|
pressableDisabled: {
|
|
18
25
|
opacity: 0.5,
|
|
26
|
+
alignSelf: 'flex-start' as const,
|
|
19
27
|
},
|
|
20
28
|
track: {
|
|
21
29
|
width: r(TRACK_W),
|
|
@@ -26,7 +34,8 @@ export const makeStyles = (c: ColorTokens) =>
|
|
|
26
34
|
thumb: {
|
|
27
35
|
width: r(THUMB),
|
|
28
36
|
height: r(THUMB),
|
|
29
|
-
|
|
37
|
+
// [L-79] radius.pill —— sentinel 999 确保把手始终是真圆
|
|
38
|
+
borderRadius: radius.pill,
|
|
30
39
|
backgroundColor: c.onPrimary,
|
|
31
40
|
},
|
|
32
41
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Text, View } from 'react-native';
|
|
3
3
|
import { Pressable } from 'react-native-gesture-handler';
|
|
4
|
-
import {
|
|
4
|
+
import { pressedOpacity, r, useColors, useThemedStyles } from '../../../theme';
|
|
5
5
|
import { childTestID } from '../../../utils/testID';
|
|
6
6
|
import { Icon } from '../Icon';
|
|
7
7
|
import { makeStyles } from './styles';
|
|
@@ -9,38 +9,46 @@ import type { TabBarProps } from './types';
|
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* 固定底部 tab bar —— App 主导航。
|
|
12
|
-
* 高 50px,顶部一条细线边框。激活色:primary
|
|
12
|
+
* 高 50px,顶部一条细线边框。激活色:primary。
|
|
13
13
|
* 想留 home indicator 的安全区,请外面包一层 `<SafeAreaView edges={['bottom']}>`。
|
|
14
14
|
*/
|
|
15
15
|
export function TabBar({
|
|
16
16
|
active,
|
|
17
17
|
onChange,
|
|
18
18
|
items,
|
|
19
|
+
style,
|
|
19
20
|
testID,
|
|
20
21
|
}: TabBarProps): React.JSX.Element {
|
|
21
22
|
const c = useColors();
|
|
22
23
|
const styles = useThemedStyles(makeStyles);
|
|
23
24
|
return (
|
|
24
|
-
<View
|
|
25
|
+
<View
|
|
26
|
+
style={[styles.bar, style]}
|
|
27
|
+
testID={testID}
|
|
28
|
+
accessibilityRole="tablist"
|
|
29
|
+
>
|
|
25
30
|
{items.map((item) => {
|
|
26
31
|
const on = item.id === active;
|
|
27
32
|
const tint = on ? c.primary : c.foregroundSubtle;
|
|
28
33
|
const itemTestID = childTestID(testID, item.id, item.testID);
|
|
34
|
+
// a11y label 包含角标数量,SR 用户知晓待处理条目数(如"消息,3条未读")
|
|
35
|
+
const a11yLabel =
|
|
36
|
+
item.badge != null ? `${item.label},${item.badge}条未读` : item.label;
|
|
29
37
|
return (
|
|
30
38
|
<Pressable
|
|
31
39
|
key={item.id}
|
|
32
40
|
onPress={() => onChange(item.id)}
|
|
33
41
|
accessibilityRole="tab"
|
|
34
42
|
accessibilityState={{ selected: on }}
|
|
35
|
-
accessibilityLabel={
|
|
43
|
+
accessibilityLabel={a11yLabel}
|
|
36
44
|
testID={itemTestID}
|
|
37
45
|
style={({ pressed }) => [
|
|
38
46
|
styles.tab,
|
|
39
|
-
{ opacity: pressed ?
|
|
47
|
+
{ opacity: pressed ? pressedOpacity : 1 },
|
|
40
48
|
]}
|
|
41
49
|
>
|
|
42
50
|
<View>
|
|
43
|
-
<Icon name={item.icon} size={
|
|
51
|
+
<Icon name={item.icon} size={r(22)} color={tint} />
|
|
44
52
|
{item.badge != null ? (
|
|
45
53
|
<View style={styles.badge}>
|
|
46
54
|
<Text style={styles.badgeText}>{item.badge}</Text>
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { StyleSheet } from 'react-native';
|
|
2
2
|
import type { ColorTokens } from '../../../theme';
|
|
3
|
-
import { fixed, fw, r,
|
|
3
|
+
import { fixed, fw, r, type as t } from '../../../theme';
|
|
4
|
+
import { badgeStyles } from '../shared/badgeStyles';
|
|
4
5
|
|
|
5
|
-
export const makeStyles = (c: ColorTokens) =>
|
|
6
|
-
|
|
6
|
+
export const makeStyles = (c: ColorTokens) => {
|
|
7
|
+
// TabBar 图标 22pt,角标上边缘偏移 r(-3):使圆心落在图标右上角
|
|
8
|
+
const badge = badgeStyles(c, r(-3));
|
|
9
|
+
return StyleSheet.create({
|
|
7
10
|
bar: {
|
|
8
11
|
height: fixed.tabbarH,
|
|
9
12
|
flexDirection: 'row',
|
|
@@ -22,22 +25,7 @@ export const makeStyles = (c: ColorTokens) =>
|
|
|
22
25
|
fontWeight: fw.medium,
|
|
23
26
|
lineHeight: 12,
|
|
24
27
|
},
|
|
25
|
-
badge:
|
|
26
|
-
|
|
27
|
-
top: r(-3),
|
|
28
|
-
right: r(-10),
|
|
29
|
-
minWidth: r(16),
|
|
30
|
-
height: r(16),
|
|
31
|
-
borderRadius: radius.md,
|
|
32
|
-
backgroundColor: c.error,
|
|
33
|
-
paddingHorizontal: space[1],
|
|
34
|
-
alignItems: 'center',
|
|
35
|
-
justifyContent: 'center',
|
|
36
|
-
},
|
|
37
|
-
badgeText: {
|
|
38
|
-
color: c.onError,
|
|
39
|
-
fontSize: t.nano,
|
|
40
|
-
fontWeight: fw.bold,
|
|
41
|
-
lineHeight: 12,
|
|
42
|
-
},
|
|
28
|
+
badge: badge.badge,
|
|
29
|
+
badgeText: badge.badgeText,
|
|
43
30
|
});
|
|
31
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { StyleProp, ViewStyle } from 'react-native';
|
|
1
2
|
import type { IconName } from '../Icon';
|
|
2
3
|
|
|
3
4
|
export type TabBarItem = {
|
|
@@ -14,6 +15,8 @@ export type TabBarProps = {
|
|
|
14
15
|
active: string;
|
|
15
16
|
onChange: (id: string) => void;
|
|
16
17
|
items: TabBarItem[];
|
|
18
|
+
/** 容器附加样式(margin / position 等布局微调)。 */
|
|
19
|
+
style?: StyleProp<ViewStyle>;
|
|
17
20
|
/** 容器 testID;item testID 自动派生为 `${testID}-${id}` */
|
|
18
21
|
testID?: string;
|
|
19
22
|
};
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Text, View } from 'react-native';
|
|
3
3
|
import { Pressable } from 'react-native-gesture-handler';
|
|
4
|
-
import { useColors, useThemedStyles
|
|
4
|
+
import { fw, pressedOpacity, useColors, useThemedStyles } from '../../../theme';
|
|
5
|
+
import { createLogger } from '../../../utils/logger';
|
|
5
6
|
import { childTestID } from '../../../utils/testID';
|
|
6
7
|
import { makeStyles } from './styles';
|
|
7
8
|
import type { TabsProps } from './types';
|
|
8
9
|
|
|
10
|
+
const log = createLogger('Tabs');
|
|
11
|
+
|
|
9
12
|
/**
|
|
10
13
|
* 页面级下划线 tabs。
|
|
11
14
|
* 占满宽度,高 44px,激活项下方有 2px 主色下划线。
|
|
@@ -14,26 +17,42 @@ export function Tabs({
|
|
|
14
17
|
value,
|
|
15
18
|
onChange,
|
|
16
19
|
items,
|
|
20
|
+
disabled: allDisabled = false,
|
|
21
|
+
style,
|
|
17
22
|
testID,
|
|
18
23
|
}: TabsProps): React.JSX.Element {
|
|
19
24
|
const c = useColors();
|
|
20
25
|
const styles = useThemedStyles(makeStyles);
|
|
26
|
+
// items 长度守卫 —— types 注释承诺「≥2 项才有意义」,此处对违规使用方 dev warn。
|
|
27
|
+
// 不 return null:渲染空 tablist 比渲染单 tab 更符合 a11y 预期,且不破坏 hook 调用顺序。
|
|
28
|
+
if (items.length < 2) {
|
|
29
|
+
log.warn(`Tabs 至少需要 2 项,当前传入 ${items.length} 项`);
|
|
30
|
+
}
|
|
21
31
|
return (
|
|
22
|
-
<View
|
|
32
|
+
<View
|
|
33
|
+
style={[styles.under, style]}
|
|
34
|
+
testID={testID}
|
|
35
|
+
accessibilityRole="tablist"
|
|
36
|
+
>
|
|
23
37
|
{items.map((it) => {
|
|
24
38
|
const on = it.id === value;
|
|
39
|
+
const itemDisabled = allDisabled || (it.disabled ?? false);
|
|
25
40
|
const itemTestID = childTestID(testID, it.id, it.testID);
|
|
26
41
|
return (
|
|
27
42
|
<Pressable
|
|
28
43
|
key={it.id}
|
|
29
|
-
onPress={() => onChange(it.id)}
|
|
44
|
+
onPress={() => !itemDisabled && onChange(it.id)}
|
|
45
|
+
disabled={itemDisabled}
|
|
30
46
|
accessibilityRole="tab"
|
|
31
|
-
accessibilityState={{
|
|
47
|
+
accessibilityState={{
|
|
48
|
+
selected: on,
|
|
49
|
+
disabled: itemDisabled || undefined,
|
|
50
|
+
}}
|
|
32
51
|
accessibilityLabel={it.label}
|
|
33
52
|
testID={itemTestID}
|
|
34
53
|
style={({ pressed }) => [
|
|
35
54
|
styles.underTab,
|
|
36
|
-
{ opacity:
|
|
55
|
+
{ opacity: itemDisabled ? 0.4 : pressed ? pressedOpacity : 1 },
|
|
37
56
|
]}
|
|
38
57
|
>
|
|
39
58
|
<Text
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { StyleSheet } from 'react-native';
|
|
2
2
|
import type { ColorTokens } from '../../../theme';
|
|
3
|
-
import { fixed,
|
|
3
|
+
import { fixed, r, type as t } from '../../../theme';
|
|
4
|
+
|
|
5
|
+
// 下划线宽度固定 36pt —— 视觉上比 tab 文字稍宽、比整个 tab 格窄,
|
|
6
|
+
// 刻意不用 icon.xl(语义是图标盒),此处是装饰性下划线,用具名常量自文档化。
|
|
7
|
+
const UNDER_BAR_WIDTH = r(36);
|
|
4
8
|
|
|
5
9
|
export const makeStyles = (c: ColorTokens) =>
|
|
6
10
|
StyleSheet.create({
|
|
@@ -23,7 +27,7 @@ export const makeStyles = (c: ColorTokens) =>
|
|
|
23
27
|
position: 'absolute',
|
|
24
28
|
bottom: 0,
|
|
25
29
|
height: r(2),
|
|
26
|
-
width:
|
|
30
|
+
width: UNDER_BAR_WIDTH,
|
|
27
31
|
backgroundColor: c.primary,
|
|
28
32
|
borderRadius: r(1),
|
|
29
33
|
},
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import type { StyleProp, ViewStyle } from 'react-native';
|
|
2
|
+
|
|
1
3
|
export type TabItem = {
|
|
2
4
|
/** 唯一 id,用作 key 跟选中标识 */
|
|
3
5
|
id: string;
|
|
4
6
|
/** 显示文本 */
|
|
5
7
|
label: string;
|
|
8
|
+
/** 禁用该 tab —— disabled=true 时不可点击 + SR 报 disabled 状态 */
|
|
9
|
+
disabled?: boolean;
|
|
6
10
|
/** 单 item testID(不传则自动用 `${tabsTestID}-${id}`) */
|
|
7
11
|
testID?: string;
|
|
8
12
|
};
|
|
@@ -12,8 +16,13 @@ export type TabsProps = {
|
|
|
12
16
|
value: string;
|
|
13
17
|
/** 切换 tab 回调 */
|
|
14
18
|
onChange: (id: string) => void;
|
|
15
|
-
/** tab 列表(≥2 项才显示)
|
|
19
|
+
/** tab 列表(≥2 项才显示)
|
|
20
|
+
* @note 传入 < 2 项时组件仍渲染,但通常无意义;调用方应保证传入 ≥2 项。 */
|
|
16
21
|
items: TabItem[];
|
|
22
|
+
/** 整体禁用 —— 所有 tab 不可点击(如异步加载数据期间) */
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
/** 容器附加样式(margin / position 等布局微调)。 */
|
|
25
|
+
style?: StyleProp<ViewStyle>;
|
|
17
26
|
/** 容器 testID;item testID 自动派生为 `${testID}-${id}` */
|
|
18
27
|
testID?: string;
|
|
19
28
|
};
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { StyleSheet } from 'react-native';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
fw,
|
|
4
|
+
r,
|
|
5
|
+
radius,
|
|
6
|
+
space,
|
|
7
|
+
type as t,
|
|
8
|
+
type ColorTokens,
|
|
9
|
+
} from '../../../theme';
|
|
3
10
|
import type { TagSize, TagVariant } from './types';
|
|
4
11
|
|
|
5
12
|
/** Tag 静态 base —— alignSelf 防 flex 父容器拉伸,radius 走 token。 */
|
|
@@ -24,16 +31,23 @@ export function sizingFor(size: TagSize): {
|
|
|
24
31
|
} {
|
|
25
32
|
switch (size) {
|
|
26
33
|
case 'md':
|
|
27
|
-
return { h: 22, px:
|
|
34
|
+
return { h: r(22), px: space['3'], fs: t.xxs };
|
|
28
35
|
case 'lg':
|
|
29
|
-
return { h: 26, px:
|
|
36
|
+
return { h: r(26), px: space['4'], fs: t.xs };
|
|
30
37
|
}
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
/** Tag 颜色推导:variant → { bg, fg, border } 三色,全走 ColorTokens。
|
|
34
|
-
* 签名 `(
|
|
41
|
+
* 签名 `(variant, c)` 与 Button/Avatar 的 paletteFor 一致。
|
|
42
|
+
* 新增 variant 在 types.ts 加 union + 这里加 case。 */
|
|
35
43
|
export function paletteFor(variant: TagVariant, c: ColorTokens) {
|
|
36
44
|
switch (variant) {
|
|
45
|
+
case 'neutral':
|
|
46
|
+
return {
|
|
47
|
+
bg: c.surfaceContainerHigh,
|
|
48
|
+
fg: c.foregroundMuted,
|
|
49
|
+
border: undefined,
|
|
50
|
+
};
|
|
37
51
|
case 'brand':
|
|
38
52
|
return { bg: c.primaryContainer, fg: c.primary, border: undefined };
|
|
39
53
|
case 'success':
|
|
@@ -48,11 +62,5 @@ export function paletteFor(variant: TagVariant, c: ColorTokens) {
|
|
|
48
62
|
fg: c.foregroundMuted,
|
|
49
63
|
border: c.outline,
|
|
50
64
|
};
|
|
51
|
-
default:
|
|
52
|
-
return {
|
|
53
|
-
bg: c.surfaceContainerHigh,
|
|
54
|
-
fg: c.foregroundMuted,
|
|
55
|
-
border: undefined,
|
|
56
|
-
};
|
|
57
65
|
}
|
|
58
66
|
}
|
|
@@ -14,7 +14,7 @@ export type TagVariant =
|
|
|
14
14
|
| 'info'
|
|
15
15
|
| 'outline';
|
|
16
16
|
|
|
17
|
-
/** Tag 尺寸:md=22 (h) / lg=26 (h) */
|
|
17
|
+
/** Tag 尺寸:md=22 (h) / lg=26 (h),均随设备宽度缩放 */
|
|
18
18
|
export type TagSize = 'md' | 'lg';
|
|
19
19
|
|
|
20
20
|
export type TagProps = {
|
|
@@ -26,7 +26,11 @@ export type TagProps = {
|
|
|
26
26
|
size?: TagSize;
|
|
27
27
|
/** 额外样式覆盖 */
|
|
28
28
|
style?: StyleProp<ViewStyle>;
|
|
29
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* 文本截断行数,默认 1(超长 ellipsis)。
|
|
31
|
+
* **警告:Tag 高度钉死(md=22 / lg=26),传 >1 时多余行溢出或被裁,
|
|
32
|
+
* 仅在同时自定义高度的场景才有意义。**
|
|
33
|
+
*/
|
|
30
34
|
numberOfLines?: number;
|
|
31
35
|
/** E2E / 测试定位 */
|
|
32
36
|
testID?: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { type ComponentRef, forwardRef, useState } from 'react';
|
|
2
2
|
import { Text, TextInput, View } from 'react-native';
|
|
3
|
-
import { control, space, useColors, useThemedStyles } from '../../../theme';
|
|
3
|
+
import { control, r, space, useColors, useThemedStyles } from '../../../theme';
|
|
4
|
+
import { childTestID } from '../../../utils/testID';
|
|
4
5
|
import { makeStyles } from './styles';
|
|
5
6
|
import type { TextFieldBaseProps } from './types';
|
|
6
7
|
|
|
@@ -26,7 +27,8 @@ export const TextFieldBase = forwardRef<TextInputRef, TextFieldBaseProps>(
|
|
|
26
27
|
{
|
|
27
28
|
multiline = false,
|
|
28
29
|
height = control.lg,
|
|
29
|
-
minHeight
|
|
30
|
+
// [L-81] multiline minHeight 裸 96 → r(96),随设备缩放
|
|
31
|
+
minHeight = r(96),
|
|
30
32
|
maxHeight,
|
|
31
33
|
leading,
|
|
32
34
|
trailing,
|
|
@@ -37,6 +39,7 @@ export const TextFieldBase = forwardRef<TextInputRef, TextFieldBaseProps>(
|
|
|
37
39
|
value,
|
|
38
40
|
onFocus,
|
|
39
41
|
onBlur,
|
|
42
|
+
onChangeText,
|
|
40
43
|
testID,
|
|
41
44
|
...rest
|
|
42
45
|
},
|
|
@@ -45,8 +48,15 @@ export const TextFieldBase = forwardRef<TextInputRef, TextFieldBaseProps>(
|
|
|
45
48
|
const c = useColors();
|
|
46
49
|
const styles = useThemedStyles(makeStyles);
|
|
47
50
|
const [focused, setFocused] = useState(false);
|
|
48
|
-
|
|
51
|
+
// [M-9] 内部镜像 state:非受控场景 value 不传,用 _mirror 做 hasValue 判断
|
|
52
|
+
const [_mirror, setMirror] = useState('');
|
|
53
|
+
// [M-9] filled 在受控 value 和内部镜像 state 之间取 hasValue,
|
|
54
|
+
// 保证非受控场景 filled 视觉态能正确响应用户输入,且受控用法行为不变
|
|
55
|
+
const filled =
|
|
56
|
+
value != null ? String(value).length > 0 : _mirror.length > 0;
|
|
49
57
|
const isEditable = disabled ? false : editable;
|
|
58
|
+
// [L-31] editable=false(非 disabled)时也应进入 disabled a11y state
|
|
59
|
+
const isDisabledA11y = disabled || editable === false;
|
|
50
60
|
|
|
51
61
|
// 视觉态优先级:error > focused > filled > idle。
|
|
52
62
|
// active 三态(focus/filled/error)共享 wrapActive 白底,各自只覆 borderColor 差量。
|
|
@@ -79,6 +89,11 @@ export const TextFieldBase = forwardRef<TextInputRef, TextFieldBaseProps>(
|
|
|
79
89
|
{...rest}
|
|
80
90
|
editable={isEditable}
|
|
81
91
|
value={value}
|
|
92
|
+
onChangeText={(text) => {
|
|
93
|
+
// [M-9] 同步内部镜像,非受控场景 filled 视觉态依赖此 state
|
|
94
|
+
setMirror(text);
|
|
95
|
+
onChangeText?.(text);
|
|
96
|
+
}}
|
|
82
97
|
multiline={multiline}
|
|
83
98
|
onFocus={(e) => {
|
|
84
99
|
setFocused(true);
|
|
@@ -97,12 +112,22 @@ export const TextFieldBase = forwardRef<TextInputRef, TextFieldBaseProps>(
|
|
|
97
112
|
},
|
|
98
113
|
]}
|
|
99
114
|
placeholderTextColor={c.foregroundSubtle}
|
|
100
|
-
|
|
101
|
-
|
|
115
|
+
// [L-31] editable=false 并入 disabled a11y state,SR 能正确播报不可编辑
|
|
116
|
+
accessibilityState={isDisabledA11y ? { disabled: true } : undefined}
|
|
117
|
+
testID={childTestID(testID, 'input')}
|
|
102
118
|
/>
|
|
103
119
|
{trailing != null ? <View>{trailing}</View> : null}
|
|
104
120
|
</View>
|
|
105
|
-
{error
|
|
121
|
+
{/* [L-31] error Text 补 accessibilityLiveRegion="polite" —— 错误出现时 SR 自动播报 */}
|
|
122
|
+
{error ? (
|
|
123
|
+
<Text
|
|
124
|
+
style={styles.errorMsg}
|
|
125
|
+
accessibilityLiveRegion="polite"
|
|
126
|
+
testID={childTestID(testID, 'error')}
|
|
127
|
+
>
|
|
128
|
+
{error}
|
|
129
|
+
</Text>
|
|
130
|
+
) : null}
|
|
106
131
|
</View>
|
|
107
132
|
);
|
|
108
133
|
}
|
|
@@ -15,7 +15,8 @@ export type TextareaProps = Omit<
|
|
|
15
15
|
leading?: ReactNode;
|
|
16
16
|
/** 可选的后置插槽(如字符计数器) */
|
|
17
17
|
trailing?: ReactNode;
|
|
18
|
-
/** 错误信息 ——
|
|
18
|
+
/** 错误信息 —— 容器进入错误态并在下方显示。
|
|
19
|
+
* 空串 `""` / undefined 都不进 error 态(truthy 判定),与 TextFieldBase 保持一致。[L-96] */
|
|
19
20
|
error?: string;
|
|
20
21
|
/** 最小高度,默认 96(约 5 行) */
|
|
21
22
|
minHeight?: number;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Image, View } from 'react-native';
|
|
3
3
|
import { useThemedStyles } from '../../../theme';
|
|
4
|
-
import {
|
|
4
|
+
import { createLogger } from '../../../utils/logger';
|
|
5
|
+
import { makeStyles, RING_EXTRA_RADIUS, sizingFor } from './styles';
|
|
5
6
|
import type { ThumbnailProps } from './types';
|
|
6
7
|
|
|
8
|
+
const log = createLogger('Thumbnail');
|
|
9
|
+
|
|
7
10
|
/** 缩略图基础组件 —— 列表 / 卡片 / chat 行内通用 16:9.5 小图。
|
|
8
11
|
*
|
|
9
12
|
* 尺寸阶梯:sm / md(默认 113×67)/ lg,与 NewsList / NewsArea 历史一致。
|
|
@@ -26,7 +29,12 @@ export function Thumbnail({
|
|
|
26
29
|
testID,
|
|
27
30
|
}: ThumbnailProps): React.JSX.Element | null {
|
|
28
31
|
const styles = useThemedStyles(makeStyles);
|
|
29
|
-
if (!uri && !source)
|
|
32
|
+
if (!uri && !source) {
|
|
33
|
+
// [L-18] uri/source 均未传:一次性告警,返回 null 而非空白区域。
|
|
34
|
+
// types 注释已说明二选一语义;此 warn 用于开发期快速定位漏传。
|
|
35
|
+
log.warn('Thumbnail: uri 和 source 均未提供,组件将渲染为 null');
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
30
38
|
const dim = sizingFor(size);
|
|
31
39
|
const image = (
|
|
32
40
|
<Image
|
|
@@ -42,7 +50,10 @@ export function Thumbnail({
|
|
|
42
50
|
// ring 容器:borderRadius 比 image 大 (border + padding) 才能贴合包裹外圈
|
|
43
51
|
return (
|
|
44
52
|
<View
|
|
45
|
-
style={[
|
|
53
|
+
style={[
|
|
54
|
+
styles.ring,
|
|
55
|
+
{ borderRadius: dim.borderRadius + RING_EXTRA_RADIUS },
|
|
56
|
+
]}
|
|
46
57
|
testID={testID}
|
|
47
58
|
>
|
|
48
59
|
{image}
|
|
@@ -2,6 +2,10 @@ import { StyleSheet } from 'react-native';
|
|
|
2
2
|
import { r, type ColorTokens } from '../../../theme';
|
|
3
3
|
import type { ThumbnailSize } from './types';
|
|
4
4
|
|
|
5
|
+
/** [L-94] ring 圆角外展量:border(2) + padding(1) = 3pt,让外圈圆角贴合内圆角。
|
|
6
|
+
* Thumbnail.tsx 侧用此常量替代魔数 `+ 3`。 */
|
|
7
|
+
export const RING_EXTRA_RADIUS = r(2) + r(1); // border + padding
|
|
8
|
+
|
|
5
9
|
/** Thumbnail 静态样式 ——
|
|
6
10
|
* - `base`:Image 占位色,加载中 / 失败时不至于空白
|
|
7
11
|
* - `ring`:`selected` 态的外圈品牌色描边,padding 抵消 ring 与 image 之间留 1pt gap */
|
|
@@ -11,9 +15,9 @@ export const makeStyles = (c: ColorTokens) =>
|
|
|
11
15
|
backgroundColor: c.surfaceContainer,
|
|
12
16
|
},
|
|
13
17
|
ring: {
|
|
14
|
-
borderWidth: 2,
|
|
18
|
+
borderWidth: r(2),
|
|
15
19
|
borderColor: c.primary,
|
|
16
|
-
padding: 1,
|
|
20
|
+
padding: r(1),
|
|
17
21
|
},
|
|
18
22
|
});
|
|
19
23
|
|