跳到主要内容

Decorations 装饰图元

3 个用于沉浸式屏 / hero 区的视觉装饰原子,全部基于 react-native-svg 渲染,可与任何容器组合用。它们是 absolute 定位的纯装饰,不接管 hit area / 布局,放在屏底部图层即可。

组件用途
GradientWash线性渐变带 —— 屏顶 / 屏底 的颜色淡入淡出
RadialHalo圆 / 椭圆径向光晕 —— hero 区点缀光斑
ScreenBackdrop整屏沉浸式预设 —— 渐变底 + 多个 halo 组合(如 warmOrange)

实时预览

下方渲染的就是 src/components/business/Decorations/*.tsx 本体。

GradientWash · 单色顶部 wash
RadialHalo · 单光晕
ScreenBackdrop warmOrange · 整屏预设(在 ScreenBackdrop 内层叠加 wash + 3 个 halo)

用法

import { GradientWash, RadialHalo, ScreenBackdrop } from '@unif/react-native-design';

{/* 名片屏整屏沉浸式背景(预设) */}
<View style={{ flex: 1 }}>
<ScreenBackdrop preset="warmOrange" />
{/* 真实内容 */}
</View>

{/* 自定义 hero 区:屏顶橙色 wash + 右上 halo 点缀 */}
<View style={{ height: 220, position: 'relative' }}>
<GradientWash height={220} color={c.primary} fromOpacity={0.18} toOpacity={0} />
<RadialHalo
size={180}
color={c.primary}
maxOpacity={0.20}
style={{ position: 'absolute', top: -30, right: -30 }}
/>
<View>{/* hero 内容 */}</View>
</View>

GradientWash API

PropType默认说明
heightnumber渐变带高度
colorstring单色模式必填(顶 fromOpacity → 底 toOpacity)
fromOpacitynumber?0.1顶部透明度(单色模式)
toOpacitynumber?0底部透明度(单色模式)
stopsReadonlyArray<GradientStop>?完全自定义 stops(与 color/fromOpacity 互斥)
gradientIdstring?自动同屏多 GradientWash 需要不同 id
styleStyleProp<ViewStyle>容器附加样式

RadialHalo API

PropType默认说明
sizenumber宽(圆模式即直径)
heightnumber?size椭圆高度,不传 = 圆
colorstring中心颜色
maxOpacitynumber?0.16简化用法的中心最大透明度,自动生成 3 stop
stopsReadonlyArray<{offset, opacity}>?完全自定义透明度分布(覆盖 maxOpacity)
gradientIdstring?自动同屏多 halo 需要不同 id
styleStyleProp<ViewStyle>absolute 定位用

ScreenBackdrop API

PropType默认说明
presetScreenBackdropPreset预设名,目前只有 'warmOrange'(暖橙渐变 + 3 halo)。不传且无 stops/halos 时仅渲染 c.background 实色外壳
stops{ light: GradientStop[]; dark: GradientStop[] }preset 推算自定义全屏渐变 stops(scheme-aware),覆盖 preset
halosReadonlyArray<ScreenBackdropHalo>preset 推算自定义 halo 列表,覆盖 preset
childrenReactNode内容层(渲染在装饰层之上)
styleStyleProp<ViewStyle>外层附加样式

ScreenBackdropHalo:{ size, height?, color?(默认 c.primary), maxOpacity?(默认 0.16), top?, bottom?, left?, right?, centerX? }

useSvgId(生成 gradientId)

useSvgId(prefix, override?) —— 公共 hook,生成唯一且 SVG 合法的渐变 id,用来喂 GradientWash / RadialHalogradientId(或你自建 SVG 渐变的 <LinearGradient id> / <RadialGradient id>)。

React 19 的 useId() 返回含冒号的串(:r0:),不是合法的 SVG id(XML NCName);useSvgId 消毒冒号后拼上 prefix,保证同屏多渐变 id 互不覆盖 —— 正是上文「不要忘传 gradientId」的标准解法。

import { GradientWash, useSvgId } from '@unif/react-native-design';

function Hero() {
const gid = useSvgId('hero-wash');
return (
<GradientWash gradientId={gid} height={220} color="#EB6E00" fromOpacity={0.18} toOpacity={0} />
);
}
参数Type说明
prefixstring短前缀,区分同屏多 gradient(如 "gw" / "rh" / "av")
overridestring?有值时直接返回(跳过 useId 分配),用于外部受控 id

主题键(Tokens)

Token来源作用
c.backgrounduseColors()ScreenBackdrop 外壳实色底
c.primaryuseColors()ScreenBackdrop halo 默认色(color 缺省时)
warmOrangePalette@unif/react-native-designwarmOrange preset 的 4 stop 渐变(light / dark)

GradientWash / RadialHalo 本身不读主题色 —— 颜色全由 color / stops 入参决定(ScreenBackdrop 内部才注入 c.background / c.primary)。

无障碍(a11y)

来源:src/components/business/Decorations/{GradientWash,RadialHalo,ScreenBackdrop}.tsxtypes.ts

3 个组件都是纯视觉装饰图层,均accessibilityRole / accessibilityLabel,也无可传的 a11y prop。

  • GradientWash / RadialHalo:根 <View> 显式设 pointerEvents="none",不拦截触摸、不暴露给 SR,只渲染 SVG 渐变。
  • ScreenBackdrop:外壳 <View> 本身不设 a11y(它在装饰层之上承载 children);其内部叠加的 GradientWash / RadialHalo 子层各自 pointerEvents="none"

语义应由这些装饰所承载 / 覆盖的内容(children 或上层业务屏)自行提供,不要给装饰图元挂交互或 a11y。

不要

  • 不要在装饰组件上挂 onPress —— 它们是纯视觉图层,加交互会拦截真内容的 hit
  • 不要在屏内放超过 3 个 RadialHalo —— SVG 太多影响渲染性能,真要多就考虑 Image 静态导出
  • 不要把 ScreenBackdrop 用在普通业务屏 —— 用于品牌 hero(名片 / Splash / 扫码屏);普通 ScreenLayout 自带白底就够了
  • 不要忘传 gradientId —— 同屏多 GradientWash / RadialHalo 共享一个默认 id,SVG defs 互覆盖导致后一个生效