Provider
配置 HeroUI Native 的文本、动画与 Toast 等全局能力
HeroUINativeProvider 是根级 Provider,用于在 React Native 应用中初始化并配置 HeroUI Native,提供全局配置与Portal管理。
概览
Provider 作为 HeroUI Native 的主入口,为应用包裹必要的上下文与配置:
- 安全区内边距:通过
SafeAreaListener自动同步安全区变化,并写入 Uniwind,便于在 Tailwind 中使用(如pb-safe-offset-3) - 文本配置:全局 Text 相关设置,保证各 HeroUI 组件文本表现一致
- 动画配置:全局控制是否关闭应用内全部动画
- Toast 配置:全局 Toast 系统(边距、默认属性、内容包裹层等)
- Portal管理:处理叠层、模态等需要浮在应用层级之上的组件
基础用法
在应用根节点使用 Provider:
import { HeroUINativeProvider } from 'heroui-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
export default function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<HeroUINativeProvider>{/* Your app content */}</HeroUINativeProvider>
</GestureHandlerRootView>
);
}配置项
Provider 接受 config 属性,常用分组如下。
文本组件配置
面向 HeroUI Native 内所有 Text 的全局设置。仅包含适合「全局统一」调整的属性:
import { HeroUINativeProvider } from 'heroui-native';
import type { HeroUINativeConfig } from 'heroui-native';
const config: HeroUINativeConfig = {
textProps: {
// Disable font scaling for accessibility
allowFontScaling: false,
// Auto-adjust font size to fit container
adjustsFontSizeToFit: false,
// Maximum font size multiplier when scaling
maxFontSizeMultiplier: 1.5,
// Minimum font scale (iOS only, 0.01-1.0)
minimumFontScale: 0.5,
},
};
export default function App() {
return (
<HeroUINativeProvider config={config}>
{/* Your app content */}
</HeroUINativeProvider>
);
}动画配置
应用级动画开关:
const config: HeroUINativeConfig = {
// Disable all animations across the application (cascades to all children)
animation: 'disable-all',
};说明: 设为 'disable-all' 后,应用内全部动画将被关闭,可用于无障碍或性能优化场景。
开发者信息配置
控制开发环境下控制台中的提示信息:
const config: HeroUINativeConfig = {
devInfo: {
// Disable styling principles information message
stylingPrinciples: false,
},
};说明: 默认会输出信息类日志。将 stylingPrinciples: false 可关闭开发时关于样式原则的提示。
Toast 配置
配置全局 Toast(边距、默认属性、包裹层等),也可完全关闭 Toast:
方式一:关闭 Toast Provider
const config: HeroUINativeConfig = {
// Disable toast provider entirely
toast: false,
// or
toast: 'disabled',
};说明: 当 toast 为 false 或 'disabled' 时,不会渲染 ToastProvider,应用内无法使用 Toast。
方式二:配置 Toast Provider
import { KeyboardAvoidingView } from 'react-native';
const config: HeroUINativeConfig = {
toast: {
// Global toast configuration (used as defaults for all toasts)
defaultProps: {
variant: 'default',
placement: 'top',
isSwipeable: true,
animation: true,
},
// Insets for spacing from screen edges (added to safe area insets)
insets: {
top: 0, // Default: iOS = 0, Android = 12
bottom: 6, // Default: iOS = 6, Android = 12
left: 12, // Default: 12
right: 12, // Default: 12
},
// Maximum number of visible toasts before opacity starts fading
maxVisibleToasts: 3,
// Custom wrapper function to wrap the toast content
contentWrapper: (children) => (
<KeyboardAvoidingView
behavior="padding"
keyboardVerticalOffset={24}
className="flex-1"
>
{children}
</KeyboardAvoidingView>
),
},
};完整示例
综合展示各项配置:
import { HeroUINativeProvider } from 'heroui-native';
import type { HeroUINativeConfig } from 'heroui-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
const config: HeroUINativeConfig = {
// Global text configuration
textProps: {
minimumFontScale: 0.5,
maxFontSizeMultiplier: 1.5,
allowFontScaling: true,
adjustsFontSizeToFit: false,
},
// Global animation configuration
animation: 'disable-all', // Optional: disable all animations
// Developer information messages configuration
devInfo: {
stylingPrinciples: true, // Optional: disable styling principles message
},
// Global toast configuration
// Option 1: Configure toast with custom settings
toast: {
defaultProps: {
variant: 'default',
placement: 'top',
},
insets: {
top: 0,
bottom: 6,
left: 12,
right: 12,
},
maxVisibleToasts: 3,
},
// Option 2: Disable toast entirely
// toast: false,
// or
// toast: 'disabled',
};
export default function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<HeroUINativeProvider config={config}>
<YourApp />
</HeroUINativeProvider>
</GestureHandlerRootView>
);
}与 Expo Router 集成
使用 Expo Router 时,在根布局中包裹:
// app/_layout.tsx
import { HeroUINativeProvider } from 'heroui-native';
import type { HeroUINativeConfig } from 'heroui-native';
import { Stack } from 'expo-router';
const config: HeroUINativeConfig = {
textProps: {
minimumFontScale: 0.5,
maxFontSizeMultiplier: 1.5,
},
};
export default function RootLayout() {
return (
<HeroUINativeProvider config={config}>
<Stack />
</HeroUINativeProvider>
);
}架构
Provider 层级
HeroUINativeProvider 内部由多层 Provider 组合而成:
HeroUINativeProvider
├── SafeAreaListener (handles safe area insets updates)
│ └── GlobalAnimationSettingsProvider (animation configuration)
│ └── TextComponentProvider (text configuration)
│ └── ToastProvider (toast configuration, conditionally rendered)
│ └── Your App
│ └── PortalHost (for overlays)说明: ToastProvider 是否渲染取决于 toast 配置。当 toast 为 false 或 'disabled' 时,不会渲染 ToastProvider,应用内容与 PortalHost 将直接挂在 TextComponentProvider 之下。
安全区内边距处理
Provider 会自动使用 react-native-safe-area-context 的 SafeAreaListener 包裹应用。该组件监听安全区与帧的变化但不会触发重渲染,并通过 onChange 回调将最新的 insets 同步给 Uniwind。
轻量 Provider(Raw)
HeroUINativeProviderRaw 是面向包体优化的精简版,不包含 ToastProvider 与 PortalHost,仅保留最小起点,按需自行组合能力。
何时使用
当你希望精确控制打包进应用的依赖时,可使用 Raw Provider。从 heroui-native/provider-raw 导入后,下列依赖仅在用到对应组件时才需要:
- react-native-screens — 浮层类组件(Popover、Dialog)需要
- @gorhom/bottom-sheet — BottomSheet 需要
- react-native-svg — 使用图标的组件(Accordion、Alert、Checkbox 等)需要
接入
import {
HeroUINativeProviderRaw,
type HeroUINativeConfigRaw,
} from 'heroui-native/provider-raw';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
const config: HeroUINativeConfigRaw = {
textProps: {
maxFontSizeMultiplier: 1.5,
},
};
export default function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<HeroUINativeProviderRaw config={config}>
{/* Your app content */}
</HeroUINativeProviderRaw>
</GestureHandlerRootView>
);
}手动添加 Toast 与 Portal
使用 Raw Provider 且仍需要 Toast 或 Portal 时,请自行组合:
import { HeroUINativeProviderRaw } from 'heroui-native/provider-raw';
import { PortalHost } from 'heroui-native/portal';
import { ToastProvider } from 'heroui-native/toast';
export default function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<HeroUINativeProviderRaw>
<ToastProvider>
{/* Your app content */}
<PortalHost />
</ToastProvider>
</HeroUINativeProviderRaw>
</GestureHandlerRootView>
);
}Raw 的层级
HeroUINativeProviderRaw
├── SafeAreaListener (handles safe area insets updates)
│ └── GlobalAnimationSettingsProvider (animation configuration)
│ └── TextComponentProvider (text configuration)
│ └── Your App最佳实践
1. 单一 Provider 实例
始终在应用根使用一个 HeroUINativeProvider,不要嵌套多个:
// ❌ Bad
<HeroUINativeProvider>
<SomeComponent>
<HeroUINativeProvider> {/* Don't do this */}
<AnotherComponent />
</HeroUINativeProvider>
</SomeComponent>
</HeroUINativeProvider>
// ✅ Good
<HeroUINativeProvider>
<SomeComponent>
<AnotherComponent />
</SomeComponent>
</HeroUINativeProvider>2. 配置对象外置
将 config 定义在组件外,避免每次渲染重新创建:
// ❌ Bad
function App() {
return (
<HeroUINativeProvider
config={{
textProps: {
/* inline config */
},
}}
>
{/* ... */}
</HeroUINativeProvider>
);
}
// ✅ Good
const config: HeroUINativeConfig = {
textProps: {
maxFontSizeMultiplier: 1.5,
},
};
function App() {
return (
<HeroUINativeProvider config={config}>{/* ... */}</HeroUINativeProvider>
);
}3. 文本与无障碍
配置文本属性时请兼顾无障碍,例如允许系统字体缩放但限制上限:
const config: HeroUINativeConfig = {
textProps: {
// Allow font scaling for accessibility
allowFontScaling: true,
// But limit maximum scale
maxFontSizeMultiplier: 1.5,
},
};TypeScript 支持
Provider 具备完整类型,可导入类型以获得更好的 IDE 体验:
import { HeroUINativeProvider, type HeroUINativeConfig } from 'heroui-native';
const config: HeroUINativeConfig = {
// Full type safety and autocomplete
textProps: {
allowFontScaling: true,
maxFontSizeMultiplier: 1.5,
},
animation: 'disable-all', // Optional: disable all animations
devInfo: {
stylingPrinciples: true, // Optional: disable styling principles message
},
// Toast configuration options:
// - false or 'disabled': Disable toast provider
// - ToastProviderProps object: Configure toast settings
toast: {
defaultProps: {
variant: 'default',
placement: 'top',
},
insets: {
top: 0,
bottom: 6,
left: 12,
right: 12,
},
},
};