UNPKG

@react-native-ohos/react-native-unistyles

Version:
285 lines (248 loc) 8.56 kB
import { ScreenOrientation, UnistylesError } from '../common' import type { Color, UnistylesBridge, UnistylesPlugin } from '../types' import type { UnistylesThemes } from '../global' import type { UnistyleRegistry } from './UnistyleRegistry' import { parseColor } from '../utils/parseColor' /** * Utility to interact with the Unistyles during runtime */ export class UnistylesRuntime { constructor(private unistylesBridge: UnistylesBridge, private unistylesRegistry: UnistyleRegistry) {} /** * Get the mini runtime injected to creteStyleSheet * @returns - The mini runtime */ public get miniRuntime() { return { contentSizeCategory: this.contentSizeCategory, breakpoint: this.breakpoint, screen: this.screen, insets: this.insets, statusBar: { width: this.statusBar.width, height: this.statusBar.height }, navigationBar: { width: this.navigationBar.width, height: this.navigationBar.height }, orientation: this.orientation, pixelRatio: this.pixelRatio, fontScale: this.fontScale, hairlineWidth: this.hairlineWidth, rtl: this.rtl } } /** * Get the current color scheme * @returns - The current color scheme */ public get colorScheme() { return this.unistylesBridge.colorScheme } /** * Get the layout direction * @returns - Boolean indicating if the layout direction is RTL */ public get rtl() { return this.unistylesBridge.rtl } /** * Get info about adaptive themes * @returns - boolean indicating if the adaptive themes are enabled */ public get hasAdaptiveThemes() { return this.unistylesBridge.hasAdaptiveThemes } /** * Get the current theme name * @returns - The current theme name */ public get themeName() { return this.unistylesBridge.themeName } /** * Get the current content size category * @returns - The current content size category */ public get contentSizeCategory() { return this.unistylesBridge.contentSizeCategory } /** * Get the current breakpoint based on device size * @returns - The current breakpoint */ public get breakpoint() { return this.unistylesBridge.breakpoint } /** * Get registered breakpoints with UnitylesRegistry * @returns - The registered breakpoints */ public get breakpoints() { return this.unistylesRegistry.breakpoints } /** * Get the names of currently enabled plugins * @deprecated - Plugins will be removed in the next major release * @returns - The names of currently enabled plugins */ public get enabledPlugins() { return this.unistylesBridge.enabledPlugins } /** * Get the screen size * @returns - The screen size { width, height } */ public get screen() { return { width: this.unistylesBridge.screenWidth, height: this.unistylesBridge.screenHeight } } /** * Get the safe area insets * @returns - The safe area insets { top, bottom, left, right } */ public get insets() { return this.unistylesBridge.insets } /** * Get the status bar info * @returns - The status bar api { width, height, setColor, setHidden } */ public get statusBar() { return { width: this.unistylesBridge.statusBar.width, height: this.unistylesBridge.statusBar.height, setColor: (color?: Color, alpha?: number) => { const [parsedColor, parsedAlpha] = parseColor(color, alpha) this.unistylesBridge.statusBar.setColor(parsedColor, parsedAlpha) }, setHidden: (hidden: boolean) => this.unistylesBridge.statusBar.setHidden(hidden) } } /** * Get the navigation bar info (Android) * @returns - The navigation bar api { width, height, setColor, setHidden } */ public get navigationBar() { return { width: this.unistylesBridge.navigationBar.width, height: this.unistylesBridge.navigationBar.height, setColor: (color?: Color, alpha?: number) => { const [parsedColor, parsedAlpha] = parseColor(color, alpha) this.unistylesBridge.navigationBar.setColor(parsedColor, parsedAlpha) }, setHidden: (hidden: boolean) => this.unistylesBridge.navigationBar.setHidden(hidden) } } /** * Get the screen orientation * @returns - The screen orientation */ public get orientation() { const { width, height } = this.screen if (width > height) { return ScreenOrientation.Landscape } return ScreenOrientation.Portrait } /** * Get the pixel ratio * @returns - The pixel ratio */ public get pixelRatio() { return this.unistylesBridge.pixelRatio } /** * Get the font scale * @returns - The font scale */ public get fontScale() { return parseFloat(this.unistylesBridge.fontScale.toFixed(2)) } /** * Get the hairline width * @returns - The thinnest width of the platform */ public get hairlineWidth() { const pixelRatio = this.pixelRatio const nearestPixel = Math.trunc(pixelRatio * 0.4) || 1 return nearestPixel / pixelRatio } /** * Get theme by name * @param themeName - The name of the theme to get or current theme if not specified * @returns - The theme */ public getTheme(themeName?: keyof UnistylesThemes) { if (!themeName) { return this.unistylesRegistry.getTheme(this.themeName) } return this.unistylesRegistry.getTheme(themeName) } /** * Get the immersive mode (both status bar and navigation bar hidden (Android)) * @param isEnabled */ public setImmersiveMode(isEnabled: boolean) { return this.unistylesBridge.setImmersiveMode(isEnabled) } /** * Set the root view background color * @param color - The color to set * @param alpha - Color alpha - default is 1 */ public setRootViewBackgroundColor = (color?: Color, alpha?: number) => { const [parsedColor, parsedAlpha] = parseColor(color, alpha) this.unistylesBridge.setRootViewBackgroundColor(parsedColor, parsedAlpha) } /** * Switch to a different theme * @param name - The name of the theme to switch to * @returns - boolean indicating if the theme was switched */ public setTheme = (name: keyof UnistylesThemes) => { if (name === this.themeName) { return } if (this.unistylesRegistry.hasTheme(name)) { this.unistylesBridge.useTheme(name) return true } throw new Error(UnistylesError.ThemeNotRegistered) } /** * Update the theme at runtime * If current theme is updated, the changes will be applied immediately * @param name - The name of the theme to update * @param updater - Function that receives the current theme and expect modified theme to be returned */ public updateTheme = (name: keyof UnistylesThemes, updater: (theme: UnistylesThemes[keyof UnistylesThemes]) => UnistylesThemes[keyof UnistylesThemes]) => { this.unistylesRegistry.updateTheme(name, updater(this.unistylesRegistry.getTheme(name))) } /** * Enable or disable adaptive themes * @param enable - boolean indicating if adaptive themes should be enabled */ public setAdaptiveThemes = (enable: boolean) => { this.unistylesBridge.useAdaptiveThemes(enable) } /** * Enable a plugin * @deprecated - Plugins will be removed in the next major release * @param plugin - Plugin that conforms to UnistylesPlugin interface */ public addPlugin = (plugin: UnistylesPlugin) => { this.unistylesRegistry.addPlugin(plugin) } /** * Disable a plugin * @deprecated - Plugins will be removed in the next major release * @param plugin - Plugin that conforms to UnistylesPlugin interface */ public removePlugin = (plugin: UnistylesPlugin) => { this.unistylesRegistry.removePlugin(plugin) } }