/** * 响应式样式工具 * 提供基于断点的样式生成功能 */ import { ViewStyle } from 'react-native'; import { BREAKPOINTS } from '../presentation/hooks/responsive'; /** * 断点键名 */ export type ResponsiveBreakpoint = 'mobile' | 'tablet' | 'desktop' | 'wide'; /** * 断点值映射 */ export type ResponsiveValues = { mobile?: T; tablet?: T; desktop?: T; wide?: T; }; /** * 断点样式映射 */ export type ResponsiveStyles = { mobile?: ViewStyle; tablet?: ViewStyle; desktop?: ViewStyle; wide?: ViewStyle; }; /** * 根据当前断点返回对应的值 * * @param breakpoint - 当前断点 * @param values - 各断点对应的值 * @returns 对应断点的值,如果未找到则返回 undefined * * @example * const fontSize = responsiveValue('tablet', { * mobile: 14, * tablet: 16, * desktop: 18, * wide: 20 * }); */ export function responsiveValue( breakpoint: string, values: ResponsiveValues ): T | undefined { // 按断点优先级顺序查找 const breakpoints: ResponsiveBreakpoint[] = ['wide', 'desktop', 'tablet', 'mobile']; for (const bp of breakpoints) { if (breakpoint === bp && values[bp] !== undefined) { return values[bp]; } } return undefined; } /** * 创建响应式样式 * 根据当前断点返回对应的样式对象 * * @param breakpoint - 当前断点 * @param styles - 各断点对应的样式 * @returns 合并后的样式对象 * * @example * const containerStyle = createResponsiveStyles(breakpoint, { * mobile: { padding: 12 }, * tablet: { padding: 24 }, * desktop: { padding: 32 }, * wide: { padding: 48 } * }); */ export function createResponsiveStyles( breakpoint: string, styles: ResponsiveStyles ): ViewStyle { const result: ViewStyle = {}; // 按断点优先级从低到高合并样式 const breakpoints: ResponsiveBreakpoint[] = ['mobile', 'tablet', 'desktop', 'wide']; for (const bp of breakpoints) { const style = styles[bp]; if (style) { Object.assign(result, style); } // 到达当前断点后停止合并 if (breakpoint === bp) { break; } } return result; } /** * 获取响应式数值 * 根据屏幕宽度返回对应的数值 * * @param width - 当前屏幕宽度 * @param config - 各断点对应的数值 * @returns 对应的数值 * * @example * const padding = getResponsiveValue(screenWidth, { * mobile: 12, * tablet: 16, * desktop: 24, * wide: 32 * }); */ export function getResponsiveValue( width: number, config: ResponsiveValues ): number | undefined { if (width >= BREAKPOINTS.wide && config.wide !== undefined) { return config.wide; } if (width >= BREAKPOINTS.desktop && config.desktop !== undefined) { return config.desktop; } if (width >= BREAKPOINTS.tablet && config.tablet !== undefined) { return config.tablet; } if (config.mobile !== undefined) { return config.mobile; } return undefined; } /** * 判断当前是否为宽屏 * * @param width - 当前屏幕宽度 * @returns 是否为宽屏(tablet 及以上) */ export function isWideScreen(width: number): boolean { return width >= BREAKPOINTS.tablet; } /** * 判断当前是否为桌面端 * * @param width - 当前屏幕宽度 * @returns 是否为桌面端(desktop 及以上) */ export function isDesktop(width: number): boolean { return width >= BREAKPOINTS.desktop; } /** * 判断当前是否为超大屏 * * @param width - 当前屏幕宽度 * @returns 是否为超大屏(wide) */ export function isWide(width: number): boolean { return width >= BREAKPOINTS.wide; }