UNPKG

august-design-system

Version:

A comprehensive React Native design system following Apple Human Interface Guidelines

1,220 lines (1,209 loc) 26.9 kB
import { createContext, useMemo, useState, useEffect, useContext } from 'react'; import { StyleSheet, useWindowDimensions, AccessibilityInfo } from 'react-native'; // src/design-system/hooks/useThemedStyles.ts // src/design-system/tokens/colors.ts var palette = { // Gray scale - iOS system grays gray: { 50: "#F2F2F7", 100: "#E5E5EA", 200: "#D1D1D6", 300: "#C7C7CC", 400: "#AEAEB2", 500: "#8E8E93"}, // System colors - iOS standard palette // Light mode values red: { light: "#FF3B30"}, orange: { light: "#FF9500"}, yellow: { light: "#FFCC00"}, green: { light: "#34C759"}, mint: { light: "#00C7BE"}, teal: { light: "#30B0C7"}, cyan: { light: "#32ADE6"}, blue: { light: "#007AFF"}, indigo: { light: "#5856D6"}, purple: { light: "#AF52DE"}, pink: { light: "#FF2D55"}, brown: { light: "#A2845E"} }; var lightColors = { // Background colors - iOS grouped table view style layering background: { primary: "#FFFFFF", secondary: "#F2F2F7", tertiary: "#FFFFFF", grouped: "#F2F2F7", groupedSecondary: "#FFFFFF", groupedTertiary: "#F2F2F7" }, // Label colors - for text content label: { primary: "#000000", // 100% black secondary: "rgba(60, 60, 67, 0.6)", // 60% opacity tertiary: "rgba(60, 60, 67, 0.3)", // 30% opacity quaternary: "rgba(60, 60, 67, 0.18)" // 18% opacity }, // Fill colors - for thin and small shapes fill: { primary: "rgba(120, 120, 128, 0.2)", secondary: "rgba(120, 120, 128, 0.16)", tertiary: "rgba(118, 118, 128, 0.12)", quaternary: "rgba(116, 116, 128, 0.08)" }, // Separator colors separator: { opaque: "#C6C6C8", nonOpaque: "rgba(60, 60, 67, 0.36)" }, // System colors - Apple standard system: { red: palette.red.light, orange: palette.orange.light, yellow: palette.yellow.light, green: palette.green.light, mint: palette.mint.light, teal: palette.teal.light, cyan: palette.cyan.light, blue: palette.blue.light, indigo: palette.indigo.light, purple: palette.purple.light, pink: palette.pink.light, brown: palette.brown.light, gray: palette.gray[500], gray2: palette.gray[400], gray3: palette.gray[300], gray4: palette.gray[200], gray5: palette.gray[100], gray6: palette.gray[50] }, // Semantic colors - functional meaning semantic: { success: palette.green.light, warning: palette.orange.light, error: palette.red.light, info: palette.blue.light }, // Interactive colors interactive: { tint: palette.blue.light, tintPressed: "#0062CC", // Darkened blue for pressed state tintDisabled: "rgba(0, 122, 255, 0.3)", destructive: palette.red.light, destructivePressed: "#CC2F26" }, // Material/Blur backgrounds - approximated for non-blur fallback material: { thin: "rgba(255, 255, 255, 0.6)", regular: "rgba(255, 255, 255, 0.72)", thick: "rgba(255, 255, 255, 0.85)", chrome: "rgba(247, 247, 247, 0.8)" } }; // src/design-system/tokens/typography.ts var fontFamily = { regular: "System", medium: "System", semibold: "System", bold: "System", heavy: "System", monospace: "Menlo", // Falls back to platform monospace rounded: "System" // SF Pro Rounded on iOS }; var typography = { // ========================================================================== // DISPLAY STYLES // Large, prominent text for titles and headers // ========================================================================== /** * Large Title - Used for main screen titles in navigation bars. * iOS: 34pt Regular */ largeTitle: { fontFamily: fontFamily.regular, fontSize: 34, lineHeight: 41, // 1.2x letterSpacing: 0.37, fontWeight: "400" }, /** * Title 1 - Primary content titles. * iOS: 28pt Regular */ title1: { fontFamily: fontFamily.regular, fontSize: 28, lineHeight: 34, // 1.21x letterSpacing: 0.36, fontWeight: "400" }, /** * Title 2 - Secondary titles. * iOS: 22pt Regular */ title2: { fontFamily: fontFamily.regular, fontSize: 22, lineHeight: 28, // 1.27x letterSpacing: 0.35, fontWeight: "400" }, /** * Title 3 - Tertiary titles. * iOS: 20pt Regular */ title3: { fontFamily: fontFamily.regular, fontSize: 20, lineHeight: 25, // 1.25x letterSpacing: 0.38, fontWeight: "400" }, // ========================================================================== // HEADLINE STYLES // For section headers and emphasized text // ========================================================================== /** * Headline - Section headers, emphasized body text. * iOS: 17pt Semibold */ headline: { fontFamily: fontFamily.semibold, fontSize: 17, lineHeight: 22, // 1.29x letterSpacing: -0.41, fontWeight: "600" }, /** * Subheadline - Subordinate section headers. * iOS: 15pt Regular */ subheadline: { fontFamily: fontFamily.regular, fontSize: 15, lineHeight: 20, // 1.33x letterSpacing: -0.24, fontWeight: "400" }, // ========================================================================== // BODY STYLES // Primary reading text // ========================================================================== /** * Body - Primary reading text throughout the app. * iOS: 17pt Regular */ body: { fontFamily: fontFamily.regular, fontSize: 17, lineHeight: 22, // 1.29x letterSpacing: -0.41, fontWeight: "400" }, /** * Callout - Secondary text that's slightly smaller than body. * iOS: 16pt Regular */ callout: { fontFamily: fontFamily.regular, fontSize: 16, lineHeight: 21, // 1.31x letterSpacing: -0.32, fontWeight: "400" }, // ========================================================================== // SUPPORTING STYLES // Smaller text for captions, footnotes, and labels // ========================================================================== /** * Footnote - Smaller supporting text. * iOS: 13pt Regular */ footnote: { fontFamily: fontFamily.regular, fontSize: 13, lineHeight: 18, // 1.38x letterSpacing: -0.08, fontWeight: "400" }, /** * Caption 1 - Primary caption style. * iOS: 12pt Regular */ caption1: { fontFamily: fontFamily.regular, fontSize: 12, lineHeight: 16, // 1.33x letterSpacing: 0, fontWeight: "400" }, /** * Caption 2 - Secondary caption style (smallest). * iOS: 11pt Regular */ caption2: { fontFamily: fontFamily.regular, fontSize: 11, lineHeight: 13, // 1.18x letterSpacing: 0.07, fontWeight: "400" } }; function withWeight(style, weight) { return { ...style, fontWeight: weight }; } function emphasized(style) { return withWeight(style, "600"); } ({ bodyEmphasis: emphasized(typography.body), calloutEmphasis: emphasized(typography.callout), footnoteEmphasis: emphasized(typography.footnote), caption1Emphasis: emphasized(typography.caption1), subheadlineEmphasis: emphasized(typography.subheadline) }); // src/design-system/tokens/spacing.ts var spacing = { // Base scale none: 0, xxs: 2, xs: 4, sm: 8, md: 12, lg: 16, xl: 20, xxl: 24, xxxl: 32, xxxxl: 40, xxxxxl: 48, // Semantic spacing - Inset (padding) // Used for content padding inside containers inset: { none: 0, xs: 4, sm: 8, md: 12, lg: 16, // Standard content inset xl: 20 }, // Semantic spacing - Stack (vertical) // Used for vertical spacing between elements stack: { none: 0, xs: 4, sm: 8, // Tight grouping md: 12, lg: 16, // Standard section spacing xl: 24 // Large section spacing }, // Semantic spacing - Inline (horizontal) // Used for horizontal spacing between elements inline: { none: 0, xs: 4, sm: 8, // Icon to text spacing md: 12, lg: 16, // Standard element spacing xl: 24 } }; // src/design-system/tokens/radius.ts var radius = { none: 0, xs: 4, sm: 8, md: 12, lg: 16, xl: 20, xxl: 24, full: 9999 }; ({ /** * Button corner radius (matches iOS default). */ button: radius.sm, /** * Small button corner radius. */ buttonSmall: radius.xs, /** * Card corner radius. */ card: radius.md, /** * Input field corner radius. */ input: radius.sm, /** * Modal/Dialog corner radius. */ modal: radius.lg, /** * Bottom sheet corner radius. */ sheet: radius.xl, /** * Image thumbnail radius. */ thumbnail: radius.sm, /** * Avatar (circular) radius. */ avatar: radius.full, /** * Badge/Chip radius. */ badge: radius.full, /** * Pill button radius. */ pill: radius.full, /** * Tag/Label radius. */ tag: radius.xs, /** * Toast notification radius. */ toast: radius.md, /** * Tooltip radius. */ tooltip: radius.sm, /** * Popover radius. */ popover: radius.md, /** * Search bar radius. */ searchBar: radius.sm, /** * Segment control radius. */ segmentControl: radius.sm, /** * Slider track radius. */ slider: radius.full, /** * Progress bar radius. */ progressBar: radius.full }); // src/design-system/tokens/shadows.ts var shadowColors = { light: "rgba(0, 0, 0, 1)"}; var lightShadows = { /** * No shadow. */ none: { shadowColor: shadowColors.light, shadowOffset: { width: 0, height: 0 }, shadowOpacity: 0, shadowRadius: 0, elevation: 0 }, /** * Extra small shadow - subtle lift. * Use for: Subtle hover states, pressed buttons. */ xs: { shadowColor: shadowColors.light, shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.04, shadowRadius: 2, elevation: 1 }, /** * Small shadow - light elevation. * Use for: Cards, list items, buttons. */ sm: { shadowColor: shadowColors.light, shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.08, shadowRadius: 4, elevation: 2 }, /** * Medium shadow - standard elevation. * Use for: Dropdown menus, popovers, floating action buttons. */ md: { shadowColor: shadowColors.light, shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.12, shadowRadius: 8, elevation: 4 }, /** * Large shadow - prominent elevation. * Use for: Modals, dialogs, navigation overlays. */ lg: { shadowColor: shadowColors.light, shadowOffset: { width: 0, height: 8 }, shadowOpacity: 0.15, shadowRadius: 16, elevation: 8 }, /** * Extra large shadow - high elevation. * Use for: Bottom sheets, side panels. */ xl: { shadowColor: shadowColors.light, shadowOffset: { width: 0, height: 12 }, shadowOpacity: 0.18, shadowRadius: 24, elevation: 12 }, /** * XXL shadow - maximum elevation. * Use for: Full-screen overlays, critical modals. */ xxl: { shadowColor: shadowColors.light, shadowOffset: { width: 0, height: 16 }, shadowOpacity: 0.22, shadowRadius: 32, elevation: 16 } }; ({ /** * Card shadow. */ card: lightShadows.sm, /** * Button shadow (when elevated). */ button: lightShadows.xs, /** * Pressed button shadow (reduced). */ buttonPressed: lightShadows.none, /** * Floating action button shadow. */ fab: lightShadows.md, /** * Dropdown/Popover shadow. */ dropdown: lightShadows.md, /** * Modal/Dialog shadow. */ modal: lightShadows.lg, /** * Bottom sheet shadow. */ sheet: lightShadows.xl, /** * Toast notification shadow. */ toast: lightShadows.md, /** * Navigation header shadow. */ header: lightShadows.xs, /** * Tab bar shadow. */ tabBar: lightShadows.xs }); // src/design-system/tokens/animation.ts var duration = { instant: 0, fastest: 50, faster: 100, fast: 150, normal: 250, slow: 350, slower: 500, slowest: 700 }; var easing = { /** * Linear - constant speed (rarely used for UI). */ linear: [0, 0, 1, 1], /** * Ease In - slow start, fast end. * Use for: Elements leaving the screen. */ easeIn: [0.42, 0, 1, 1], /** * Ease Out - fast start, slow end. * Use for: Elements entering the screen. * This is the most common easing for iOS-style animations. */ easeOut: [0, 0, 0.58, 1], /** * Ease In Out - slow start and end. * Use for: Elements that start and end on screen. */ easeInOut: [0.42, 0, 0.58, 1], /** * Default spring - balanced, natural feel. * iOS default animation spring characteristics. * Use for: Most interactive animations. */ spring: { damping: 15, stiffness: 150, mass: 1 }, /** * Gentle spring - soft, slow settling. * Use for: Subtle movements, floating elements. */ springGentle: { damping: 20, stiffness: 100, mass: 1 }, /** * Bouncy spring - energetic, playful feel. * Use for: Emphasis, celebrations, playful interactions. * Use sparingly to avoid overwhelming users. */ springBouncy: { damping: 10, stiffness: 200, mass: 1 } }; var animation = { duration, easing }; var animationPresets = { /** * Button press feedback. */ buttonPress: { duration: duration.faster, easing: easing.easeOut }, /** * Button release feedback. */ buttonRelease: { duration: duration.fast, easing: easing.spring }, /** * Modal/Sheet appear. */ modalEnter: { duration: duration.normal, easing: easing.spring }, /** * Modal/Sheet dismiss. */ modalExit: { duration: duration.fast, easing: easing.easeIn }, /** * Page/Screen transition. */ pageTransition: { duration: duration.slow, easing: easing.easeInOut }, /** * Fade in content. */ fadeIn: { duration: duration.normal, easing: easing.easeOut }, /** * Fade out content. */ fadeOut: { duration: duration.fast, easing: easing.easeIn }, /** * Slide in from bottom. */ slideInUp: { duration: duration.normal, easing: easing.spring }, /** * Slide out to bottom. */ slideOutDown: { duration: duration.fast, easing: easing.easeIn }, /** * Scale up (appearing). */ scaleIn: { duration: duration.normal, easing: easing.springBouncy }, /** * Scale down (disappearing). */ scaleOut: { duration: duration.fast, easing: easing.easeIn }, /** * Expand/Collapse accordion. */ expand: { duration: duration.normal, easing: easing.easeInOut }, /** * Switch/Toggle animation. */ toggle: { duration: duration.fast, easing: easing.spring }, /** * Skeleton loading shimmer. */ skeleton: { duration: duration.slowest, easing: easing.linear }, /** * Toast notification appear. */ toastEnter: { duration: duration.normal, easing: easing.springBouncy }, /** * Toast notification dismiss. */ toastExit: { duration: duration.fast, easing: easing.easeIn }, /** * Haptic feedback timing. */ haptic: { duration: duration.instant, easing: easing.linear } }; var reducedMotionPresets = { /** * Replaces spring/bouncy animations with simple fade. */ default: { duration: duration.fast, easing: easing.easeOut }, /** * Replaces sliding animations with fade. */ slide: { duration: duration.faster, easing: easing.easeOut }, /** * Replaces scale animations with fade. */ scale: { duration: duration.faster, easing: easing.easeOut }, /** * Instant change (no animation). */ instant: { duration: duration.instant, easing: easing.linear } }; // src/design-system/tokens/sizes.ts var sizes = { // Touch targets - Apple HIG minimum 44pt touchTarget: { /** * Minimum touch target size (44pt). * Required by Apple HIG for all interactive elements. */ minimum: 44, /** * Comfortable touch target (48pt). * Recommended for frequently used actions. */ comfortable: 48, /** * Spacious touch target (56pt). * For primary actions and accessibility. */ spacious: 56 }, // Icon sizes icon: { /** * Extra small icon (12pt). * Use for: Inline badges, tiny indicators. */ xs: 12, /** * Small icon (16pt). * Use for: Inline text icons, compact UI. */ sm: 16, /** * Medium icon (20pt). * Use for: Standard inline icons. */ md: 20, /** * Large icon (24pt). * Use for: Navigation icons, tab bar icons. */ lg: 24, /** * Extra large icon (32pt). * Use for: Featured icons, prominent actions. */ xl: 32, /** * XXL icon (40pt). * Use for: Illustrations, large feature icons. */ xxl: 40 }, // Avatar sizes avatar: { /** * Extra small avatar (24pt). * Use for: Inline mentions, compact lists. */ xs: 24, /** * Small avatar (32pt). * Use for: Comments, messaging. */ sm: 32, /** * Medium avatar (40pt). * Use for: Standard list items. */ md: 40, /** * Large avatar (56pt). * Use for: Profile cards, detailed lists. */ lg: 56, /** * Extra large avatar (72pt). * Use for: Profile headers. */ xl: 72, /** * XXL avatar (96pt). * Use for: Profile pages, settings. */ xxl: 96 }, // Button heights button: { /** * Small button (32pt). * Use for: Compact UI, inline actions. * Note: May not meet touch target minimum. */ sm: 32, /** * Medium button (44pt) - DEFAULT. * Use for: Standard buttons. * Meets Apple HIG minimum touch target. */ md: 44, /** * Large button (50pt). * Use for: Primary actions, CTAs. */ lg: 50, /** * Extra large button (56pt). * Use for: Hero actions, onboarding. */ xl: 56 }, // Input heights input: { /** * Small input (36pt). * Use for: Compact forms, filters. */ sm: 36, /** * Medium input (44pt) - DEFAULT. * Use for: Standard form inputs. * Meets Apple HIG minimum touch target. */ md: 44, /** * Large input (52pt). * Use for: Search bars, prominent inputs. */ lg: 52 } }; var zIndex = { /** * Base level - standard content. */ base: 0, /** * Dropdown level - menus, selects. */ dropdown: 1e3, /** * Sticky level - headers, navigation. */ sticky: 1100, /** * Overlay level - background overlays. */ overlay: 1200, /** * Modal level - dialogs, sheets. */ modal: 1300, /** * Popover level - tooltips, popovers. */ popover: 1400, /** * Tooltip level - floating hints. */ tooltip: 1500, /** * Toast level - notifications (highest). */ toast: 1600 }; var breakpoints = { /** * Extra small - small phones. */ xs: 0, /** * Small - standard phones (iPhone SE+). * iPhone SE: 375pt width. */ sm: 375, /** * Medium - large phones (iPhone Pro Max). * iPhone Pro Max: 428pt width. */ md: 428, /** * Large - small tablets (iPad Mini). * iPad Mini portrait: 744pt width. */ lg: 744, /** * Extra large - large tablets (iPad Pro). * iPad Pro portrait: 1024pt width. */ xl: 1024 }; var opacity = { /** * Fully transparent. */ transparent: 0, /** * Disabled state opacity. * iOS uses 0.3-0.4 for disabled elements. */ disabled: 0.38, /** * Medium opacity - overlays, secondary elements. */ medium: 0.6, /** * High opacity - emphasized content. */ high: 0.87, /** * Fully opaque. */ opaque: 1 }; // src/design-system/theme/defaultTheme.ts var lightTheme = { name: "August Light", mode: "light", colors: lightColors, typography, fontFamily, spacing, radius, shadows: lightShadows, animation, sizes, zIndex, breakpoints, opacity }; var defaultContextValue = { theme: lightTheme, colorMode: "light", colorModePreference: "system", toggleColorMode: () => { console.warn("ThemeProvider not found in component tree"); }, setColorMode: () => { console.warn("ThemeProvider not found in component tree"); }, isDark: false, isLight: true }; var ThemeContext = createContext(defaultContextValue); function useTheme() { const context = useContext(ThemeContext); if (context === defaultContextValue) { console.warn( "useTheme must be used within a ThemeProvider. Falling back to default light theme." ); } return context; } // src/design-system/hooks/useThemedStyles.ts function useThemedStyles(styleCreator) { const { theme } = useTheme(); return useMemo(() => { const rawStyles = styleCreator(theme); return StyleSheet.create(rawStyles); }, [theme, styleCreator]); } function useThemedStyle(styleCreator) { const { theme } = useTheme(); return useMemo(() => styleCreator(theme), [theme, styleCreator]); } function createThemedStyles(styleCreator) { return function useStyles() { return useThemedStyles(styleCreator); }; } function combineStyles(...styles) { return styles.filter(Boolean); } function conditionalStyle(condition, trueStyle, falseStyle) { if (condition) return trueStyle; return falseStyle; } function useBreakpoint() { const { width } = useWindowDimensions(); const { theme } = useTheme(); const { breakpoints: breakpoints2 } = theme; return useMemo(() => { if (width >= breakpoints2.xl) return "xl"; if (width >= breakpoints2.lg) return "lg"; if (width >= breakpoints2.md) return "md"; if (width >= breakpoints2.sm) return "sm"; return "xs"; }, [width, breakpoints2]); } function useResponsiveValue(value) { const breakpoint = useBreakpoint(); return useMemo(() => { if (typeof value !== "object" || value === null || Array.isArray(value)) { return value; } const responsiveValue = value; const breakpointOrder = ["xl", "lg", "md", "sm", "xs"]; const currentIndex = breakpointOrder.indexOf(breakpoint); for (let i = currentIndex; i < breakpointOrder.length; i++) { const bp = breakpointOrder[i]; if (bp in responsiveValue && responsiveValue[bp] !== void 0) { return responsiveValue[bp]; } } for (const bp of breakpointOrder) { if (bp in responsiveValue && responsiveValue[bp] !== void 0) { return responsiveValue[bp]; } } return void 0; }, [value, breakpoint]); } function useDeviceType() { const breakpoint = useBreakpoint(); return breakpoint === "lg" || breakpoint === "xl" ? "tablet" : "phone"; } function useIsBreakpoint(targetBreakpoint) { const { width } = useWindowDimensions(); const { theme } = useTheme(); return width >= theme.breakpoints[targetBreakpoint]; } function useScreenDimensions() { const { width, height } = useWindowDimensions(); return useMemo( () => ({ width, height, isPortrait: height >= width, isLandscape: width > height, aspectRatio: width / height }), [width, height] ); } function responsiveStyle(styles) { const breakpointOrder = ["xl", "lg", "md", "sm", "xs"]; return (breakpoint) => { const currentIndex = breakpointOrder.indexOf(breakpoint); for (let i = currentIndex; i < breakpointOrder.length; i++) { const bp = breakpointOrder[i]; if (bp in styles && styles[bp] !== void 0) { return styles[bp]; } } return void 0; }; } function useReducedMotion() { const [reducedMotion, setReducedMotion] = useState(false); useEffect(() => { AccessibilityInfo.isReduceMotionEnabled().then(setReducedMotion); const subscription = AccessibilityInfo.addEventListener( "reduceMotionChanged", setReducedMotion ); return () => { subscription.remove(); }; }, []); return reducedMotion; } function useAccessibleAnimation(preset) { const prefersReducedMotion = useReducedMotion(); return useMemo(() => { if (prefersReducedMotion) { return { duration: reducedMotionPresets.default.duration, useNativeDriver: true, isReduced: true }; } return { duration: animationPresets[preset].duration, useNativeDriver: true, isReduced: false }; }, [preset, prefersReducedMotion]); } function useScreenReader() { const [screenReaderEnabled, setScreenReaderEnabled] = useState(false); useEffect(() => { AccessibilityInfo.isScreenReaderEnabled().then(setScreenReaderEnabled); const subscription = AccessibilityInfo.addEventListener( "screenReaderChanged", setScreenReaderEnabled ); return () => { subscription.remove(); }; }, []); return screenReaderEnabled; } function useBoldText() { const [boldTextEnabled, setBoldTextEnabled] = useState(false); useEffect(() => { AccessibilityInfo.isBoldTextEnabled().then(setBoldTextEnabled); const subscription = AccessibilityInfo.addEventListener( "boldTextChanged", setBoldTextEnabled ); return () => { subscription.remove(); }; }, []); return boldTextEnabled; } function useDynamicType() { const { fontScale } = useWindowDimensions(); return fontScale; } function useScaledTypography(baseStyle, options = {}) { const { maxScale = 2, minScale = 0.8 } = options; const fontScale = useDynamicType(); return useMemo(() => { const clampedScale = Math.min(Math.max(fontScale, minScale), maxScale); return { ...baseStyle, fontSize: Math.round(baseStyle.fontSize * clampedScale), lineHeight: Math.round(baseStyle.lineHeight * clampedScale) }; }, [baseStyle, fontScale, maxScale, minScale]); } function useHighContrast() { const boldTextEnabled = useBoldText(); return boldTextEnabled; } function announceForAccessibility(message) { AccessibilityInfo.announceForAccessibility(message); } function setAccessibilityFocus(reactTag) { if (reactTag) { AccessibilityInfo.setAccessibilityFocus(reactTag); } } export { announceForAccessibility, combineStyles, conditionalStyle, createThemedStyles, responsiveStyle, setAccessibilityFocus, useAccessibleAnimation, useBoldText, useBreakpoint, useDeviceType, useDynamicType, useHighContrast, useIsBreakpoint, useReducedMotion, useResponsiveValue, useScaledTypography, useScreenDimensions, useScreenReader, useThemedStyle, useThemedStyles }; //# sourceMappingURL=index.mjs.map //# sourceMappingURL=index.mjs.map