@grundtone/react-native 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -0
- package/dist/index.d.mts +158 -0
- package/dist/index.d.ts +158 -0
- package/dist/index.js +928 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +912 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ThemeContext.tsx","../src/useGrundtoneTheme.ts","../src/index.ts","../src/shadows.ts","../src/components/Icon/Icon.tsx","../src/IconRegistryContext.tsx","../src/components/Button/Button.tsx","../src/components/Input/Input.tsx","../src/components/Toggle/Toggle.tsx","../src/components/Alert/Alert.tsx","../src/useField.ts","../src/useFormValidation.ts","../src/branding.ts"],"sourcesContent":["import React, {\n createContext,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport { Appearance } from 'react-native';\nimport type { Theme, ThemeMode } from '@grundtone/core';\nimport { resolveThemeMode } from '@grundtone/utils';\n\nexport type { ThemeMode } from '@grundtone/core';\n\nexport interface GrundtoneThemeContextValue {\n theme: Theme;\n mode: ThemeMode;\n isDark: boolean;\n setMode: (mode: ThemeMode) => void;\n}\n\nexport const GrundtoneThemeContext = createContext<\n GrundtoneThemeContextValue | undefined\n>(undefined);\n\nfunction getSystemIsDark(): boolean {\n return Appearance.getColorScheme() === 'dark';\n}\n\nexport interface GrundtoneThemeProviderProps {\n /** Light theme – use createTheme() from @grundtone/core */\n light: Theme;\n /** Dark theme – use createTheme() from @grundtone/core */\n dark: Theme;\n /**\n * Initial mode. Default: 'auto' (follows system).\n * Pass 'light' or 'dark' to override, or 'auto' for system preference.\n */\n defaultMode?: ThemeMode;\n /** Force a specific mode (controlled), overriding defaultMode after mount */\n mode?: ThemeMode;\n children: React.ReactNode;\n}\n\n/**\n * Provides Grundtone theme to React Native components.\n * Use useGrundtoneTheme() to consume.\n *\n * Supports 'light', 'dark', and 'auto' (system preference) modes.\n *\n * @example\n * import { GrundtoneThemeProvider, useGrundtoneTheme } from '@grundtone/react-native';\n * import { createTheme } from '@grundtone/core';\n *\n * const { light, dark } = createTheme({\n * light: { colors: { primary: '#your-brand' } },\n * dark: { colors: { primary: '#your-brand-dark' } }\n * });\n *\n * <GrundtoneThemeProvider light={light} dark={dark}>\n * <App />\n * </GrundtoneThemeProvider>\n */\nexport function GrundtoneThemeProvider({\n light,\n dark,\n defaultMode = 'auto',\n mode: controlledMode,\n children,\n}: GrundtoneThemeProviderProps): React.ReactElement {\n const [internalMode, setInternalMode] = useState<ThemeMode>(defaultMode);\n const [systemIsDark, setSystemIsDark] = useState(getSystemIsDark);\n\n // Listen for system appearance changes\n useEffect(() => {\n const sub = Appearance.addChangeListener(() => {\n setSystemIsDark(getSystemIsDark());\n });\n return () => sub.remove();\n }, []);\n\n const activeMode = controlledMode ?? internalMode;\n const resolved = resolveThemeMode(activeMode, systemIsDark);\n\n const setMode = useCallback(\n (newMode: ThemeMode) => {\n if (controlledMode === undefined) {\n setInternalMode(newMode);\n }\n },\n [controlledMode],\n );\n\n const theme = resolved === 'dark' ? dark : light;\n const isDark = resolved === 'dark';\n\n const value = useMemo<GrundtoneThemeContextValue>(\n () => ({\n theme,\n mode: activeMode,\n isDark,\n setMode,\n }),\n [theme, activeMode, isDark, setMode],\n );\n\n return (\n <GrundtoneThemeContext.Provider value={value}>\n {children}\n </GrundtoneThemeContext.Provider>\n );\n}\n","import { useContext } from 'react';\nimport { GrundtoneThemeContext } from './ThemeContext';\n\n/**\n * Returns the current Grundtone theme for use in StyleSheet and components.\n *\n * @example\n * const { theme } = useGrundtoneTheme();\n *\n * StyleSheet.create({\n * button: {\n * backgroundColor: theme.colors.primary,\n * padding: theme.spacing.md,\n * },\n * label: {\n * color: theme.colors.onPrimary,\n * fontSize: theme.typography.fontSize.base,\n * }\n * });\n *\n * @throws Error if used outside GrundtoneThemeProvider\n */\nexport function useGrundtoneTheme() {\n const context = useContext(GrundtoneThemeContext);\n\n if (context === undefined) {\n throw new Error(\n 'useGrundtoneTheme must be used within a GrundtoneThemeProvider. ' +\n 'Wrap your app with <GrundtoneThemeProvider light={...} dark={...}>.',\n );\n }\n\n return context;\n}\n","/**\n * @grundtone/react-native\n *\n * React Native theme provider and hooks for Grundtone design system.\n * Use tokens from @grundtone/core in your RN app.\n *\n * @example\n * import { GrundtoneThemeProvider, useGrundtoneTheme } from '@grundtone/react-native';\n * import { createTheme } from '@grundtone/core';\n *\n * const { light, dark } = createTheme({\n * light: { colors: { primary: '#007aff' } },\n * dark: { colors: { primary: '#0a84ff' } }\n * });\n *\n * function App() {\n * return (\n * <GrundtoneThemeProvider light={light} dark={dark}>\n * <MyScreen />\n * </GrundtoneThemeProvider>\n * );\n * }\n *\n * function MyScreen() {\n * const { theme } = useGrundtoneTheme();\n * return (\n * <View style={{ backgroundColor: theme.colors.background }}>\n * <Text style={{ color: theme.colors.text }}>Hello</Text>\n * </View>\n * );\n * }\n */\n\nexport { GrundtoneThemeProvider, GrundtoneThemeContext } from './ThemeContext';\nexport type { GrundtoneThemeContextValue, ThemeMode } from './ThemeContext';\nexport { useGrundtoneTheme } from './useGrundtoneTheme';\nexport { createTheme } from '@grundtone/core';\nexport type { Theme } from '@grundtone/core';\n\n// Shadows\nexport { shadowToRN } from './shadows';\nexport type { RNShadowStyle } from './shadows';\n\n// Components\nexport { GTIcon } from './components/Icon';\nexport type { IconProps, IconSize } from './components/Icon';\n\n// Icon registry provider\nexport { IconRegistryProvider, useIconRegistry } from './IconRegistryContext';\nexport type { IconRegistryProviderProps } from './IconRegistryContext';\nexport type { IconDefinition, IconRegistry } from '@grundtone/core';\nexport { GTButton } from './components/Button';\nexport type {\n ButtonProps,\n ButtonVariant,\n ButtonSize,\n ButtonRadius,\n} from './components/Button';\nexport { GTInput } from './components/Input';\nexport type {\n InputProps,\n InputSize,\n InputType,\n InputRadius,\n} from './components/Input';\nexport { GTToggle } from './components/Toggle';\nexport type { ToggleProps, ToggleSize } from './components/Toggle';\nexport { GTAlert } from './components/Alert';\nexport type { AlertProps, AlertVariant } from './components/Alert';\n\n// Hooks\nexport { useField } from './useField';\nexport type { UseFieldOptions, UseFieldReturn } from './useField';\nexport { useFormValidation } from './useFormValidation';\nexport type { UseFormValidationReturn } from './useFormValidation';\n\n// Validators (re-exported from @grundtone/utils)\nexport {\n required,\n email,\n phone,\n cpr,\n cvr,\n minLength,\n maxLength,\n pattern,\n url,\n composeValidators,\n} from '@grundtone/utils';\nexport type { Validator, ValidationResult } from '@grundtone/utils';\n\n// Branding\nexport {\n defaultLogoSource,\n getLogoSource,\n defaultBranding,\n createBranding,\n LOGO_VARIANT_SIZES,\n} from './branding';\nexport type { BrandingConfig, LogoVariants } from './branding';\n","import type { ShadowLayer } from '@grundtone/core';\n\nexport interface RNShadowStyle {\n shadowColor: string;\n shadowOffset: { width: number; height: number };\n shadowOpacity: number;\n shadowRadius: number;\n elevation: number;\n}\n\n/**\n * Convert structured shadow layers to React Native shadow style.\n * RN only supports a single shadow layer — uses the first layer.\n * iOS: shadowColor / shadowOffset / shadowOpacity / shadowRadius\n * Android: elevation (approximated from blur radius)\n */\nexport function shadowToRN(layers: ShadowLayer[]): RNShadowStyle {\n const layer = layers[0];\n if (!layer) {\n return {\n shadowColor: 'transparent',\n shadowOffset: { width: 0, height: 0 },\n shadowOpacity: 0,\n shadowRadius: 0,\n elevation: 0,\n };\n }\n\n return {\n shadowColor: layer.color,\n shadowOffset: { width: layer.x, height: layer.y },\n shadowOpacity: layer.opacity,\n shadowRadius: layer.blur / 2,\n elevation: Math.ceil(layer.blur / 2),\n };\n}\n","import React from 'react';\nimport { SvgXml } from 'react-native-svg';\nimport { getIconColor } from '@grundtone/core';\nimport type { IconDefinition } from '@grundtone/core';\nimport { useIconRegistry } from '../../IconRegistryContext';\nimport type { IconProps } from './types';\n\n/**\n * Icon sizes in pixels — mirrors the design-system icon-size() tokens.\n * xs: 0.75rem, sm: 1rem, md: 1.25rem, lg: 1.5rem, xl: 2rem, 2xl: 2.5rem\n */\nconst ICON_SIZES = {\n xs: 12,\n sm: 16,\n md: 20,\n lg: 24,\n xl: 32,\n '2xl': 40,\n} as const;\n\n/**\n * GTIcon — renders an SVG icon from a provided icon definition or registry.\n *\n * Requires `react-native-svg` as a peer dependency.\n *\n * @example\n * // Direct icon prop\n * <GTIcon icon={{ body: '<path d=\"M20 6L9 17l-5-5\"/>', viewBox: '0 0 24 24' }} />\n *\n * // Name lookup (requires IconRegistryProvider)\n * <GTIcon name=\"check\" />\n * <GTIcon name=\"search\" size=\"xl\" color=\"#ff0000\" />\n */\nexport function GTIcon({ icon, name, size = 'lg', label, color }: IconProps) {\n const registry = useIconRegistry();\n\n let resolved: IconDefinition | null = null;\n\n if (icon) {\n resolved = icon;\n } else if (name && registry) {\n resolved = registry[name] ?? null;\n }\n\n if (!resolved) {\n if (process.env.NODE_ENV !== 'production') {\n if (name && !registry) {\n // eslint-disable-next-line no-console\n console.warn(\n `[GTIcon] No icon registry provided. Wrap your app in <IconRegistryProvider> or pass the \"icon\" prop directly.`,\n );\n } else if (name) {\n // eslint-disable-next-line no-console\n console.warn(`[GTIcon] Icon \"${name}\" not found in registry.`);\n }\n }\n return null;\n }\n\n const px = ICON_SIZES[size];\n const resolvedColor = color ?? getIconColor();\n\n const xml = `<svg viewBox=\"${resolved.viewBox}\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"${resolvedColor}\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${resolved.body}</svg>`;\n\n return (\n <SvgXml\n xml={xml}\n width={px}\n height={px}\n accessibilityLabel={label}\n accessibilityRole={label ? 'image' : undefined}\n accessible={!!label}\n />\n );\n}\n","import React, { createContext, useContext } from 'react';\nimport type { IconRegistry } from '@grundtone/core';\n\nconst IconRegistryContext = createContext<IconRegistry | null>(null);\n\nexport interface IconRegistryProviderProps {\n registry: IconRegistry;\n children: React.ReactNode;\n}\n\n/**\n * Provides an icon registry to all GTIcon components in the tree.\n *\n * @example\n * import { iconRegistry } from '@grundtone/icons';\n *\n * <IconRegistryProvider registry={iconRegistry}>\n * <App />\n * </IconRegistryProvider>\n */\nexport function IconRegistryProvider({\n registry,\n children,\n}: IconRegistryProviderProps) {\n return (\n <IconRegistryContext.Provider value={registry}>\n {children}\n </IconRegistryContext.Provider>\n );\n}\n\n/** Returns the icon registry from the nearest IconRegistryProvider, or null. */\nexport function useIconRegistry(): IconRegistry | null {\n return useContext(IconRegistryContext);\n}\n","import React from 'react';\nimport {\n Pressable,\n Text,\n ActivityIndicator,\n StyleSheet,\n type ViewStyle,\n type TextStyle,\n} from 'react-native';\nimport { useGrundtoneTheme } from '../../useGrundtoneTheme';\nimport type {\n ButtonProps,\n ButtonVariant,\n ButtonSize,\n ButtonRadius,\n} from './types';\n\n/** Parse rem string to pixel number (base 16) */\nfunction rem(value: string): number {\n return parseFloat(value) * 16;\n}\n\n/**\n * GTButton — pressable button component driven by Grundtone theme tokens.\n *\n * @example\n * <GTButton onPress={handleSave}>Save</GTButton>\n * <GTButton variant=\"negative\" onPress={handleDelete}>Delete</GTButton>\n * <GTButton variant=\"outlined\" size=\"lg\" loading>Processing</GTButton>\n */\nexport function GTButton({\n variant = 'primary',\n size = 'md',\n rounded,\n disabled = false,\n loading = false,\n block = false,\n onPress,\n accessibilityLabel,\n children,\n}: ButtonProps) {\n const { theme } = useGrundtoneTheme();\n\n const isDisabled = disabled || loading;\n\n const variantStyles = getVariantStyles(variant, theme.colors);\n const sizeStyles = getSizeStyles(size, theme);\n const radiusStyle = getRadiusStyle(rounded, theme.radius);\n\n const containerStyle: ViewStyle = {\n ...styles.base,\n ...variantStyles.container,\n ...sizeStyles.container,\n ...radiusStyle,\n ...(block ? styles.block : undefined),\n ...(isDisabled ? styles.disabled : undefined),\n };\n\n const textStyle: TextStyle = {\n ...sizeStyles.text,\n ...variantStyles.text,\n fontFamily: theme.typography.fontFamily.base,\n fontWeight:\n `${theme.typography.fontWeight.medium}` as TextStyle['fontWeight'],\n };\n\n const spinnerColor = variantStyles.text.color as string;\n\n function handlePress() {\n if (isDisabled) return;\n onPress?.();\n }\n\n return (\n <Pressable\n onPress={handlePress}\n disabled={isDisabled}\n style={({ pressed }) => [\n containerStyle,\n pressed && !isDisabled ? variantStyles.pressed : undefined,\n ]}\n accessibilityRole=\"button\"\n accessibilityLabel={accessibilityLabel}\n accessibilityState={{ disabled: isDisabled, busy: loading }}\n >\n {loading ? (\n <ActivityIndicator size=\"small\" color={spinnerColor} />\n ) : typeof children === 'string' ? (\n <Text style={textStyle}>{children}</Text>\n ) : (\n children\n )}\n </Pressable>\n );\n}\n\nfunction getVariantStyles(\n variant: ButtonVariant,\n colors: ReturnType<typeof useGrundtoneTheme>['theme']['colors'],\n): { container: ViewStyle; text: TextStyle; pressed: ViewStyle } {\n switch (variant) {\n case 'primary':\n return {\n container: {\n backgroundColor: colors.primary,\n borderColor: colors.primary,\n },\n text: { color: colors.onPrimary },\n pressed: { backgroundColor: colors.primaryDark },\n };\n case 'secondary':\n return {\n container: {\n backgroundColor: colors.secondary,\n borderColor: colors.secondary,\n },\n text: { color: colors.text },\n pressed: { backgroundColor: colors.secondaryDark },\n };\n case 'outlined':\n return {\n container: {\n backgroundColor: 'transparent',\n borderColor: colors.borderMedium,\n },\n text: { color: colors.primary },\n pressed: {\n backgroundColor: colors.primary,\n borderColor: colors.primary,\n },\n };\n case 'negative':\n return {\n container: {\n backgroundColor: colors.error,\n borderColor: colors.error,\n },\n text: { color: colors.onPrimary },\n pressed: { backgroundColor: colors.errorDark },\n };\n case 'unstyled':\n return {\n container: {\n backgroundColor: 'transparent',\n borderColor: 'transparent',\n borderWidth: 0,\n paddingHorizontal: 0,\n paddingVertical: 0,\n },\n text: { color: colors.text },\n pressed: {},\n };\n }\n}\n\nfunction getSizeStyles(\n size: ButtonSize,\n theme: ReturnType<typeof useGrundtoneTheme>['theme'],\n): { container: ViewStyle; text: TextStyle } {\n switch (size) {\n case 'sm':\n return {\n container: {\n paddingVertical: rem(theme.spacing.xs),\n paddingHorizontal: rem(theme.spacing.sm),\n },\n text: { fontSize: rem(theme.typography.fontSize.sm) },\n };\n case 'md':\n return {\n container: {\n paddingVertical: rem(theme.spacing.sm),\n paddingHorizontal: rem(theme.spacing.md),\n },\n text: { fontSize: rem(theme.typography.fontSize.base) },\n };\n case 'lg':\n return {\n container: {\n paddingVertical: rem(theme.spacing.md),\n paddingHorizontal: rem(theme.spacing.xl),\n },\n text: { fontSize: rem(theme.typography.fontSize.lg) },\n };\n }\n}\n\nfunction getRadiusStyle(\n rounded: ButtonRadius | undefined,\n radius: ReturnType<typeof useGrundtoneTheme>['theme']['radius'],\n): ViewStyle {\n if (!rounded) return { borderRadius: rem(radius.md) };\n if (rounded === 'full') return { borderRadius: 9999 };\n if (rounded === 'none') return { borderRadius: 0 };\n return { borderRadius: rem(radius[rounded]) };\n}\n\nconst styles = StyleSheet.create({\n base: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n borderWidth: 1,\n gap: 4,\n },\n block: {\n width: '100%',\n },\n disabled: {\n opacity: 0.5,\n },\n});\n","import React, { useState } from 'react';\nimport {\n View,\n Text,\n TextInput,\n type ViewStyle,\n type TextStyle,\n type KeyboardTypeOptions,\n} from 'react-native';\nimport { useGrundtoneTheme } from '../../useGrundtoneTheme';\nimport type { InputProps, InputSize, InputRadius, InputType } from './types';\n\n/** Parse rem string to pixel number (base 16) */\nfunction rem(value: string): number {\n return parseFloat(value) * 16;\n}\n\nfunction getKeyboardType(type: InputType): KeyboardTypeOptions {\n switch (type) {\n case 'email':\n return 'email-address';\n case 'number':\n return 'numeric';\n case 'tel':\n return 'phone-pad';\n case 'url':\n return 'url';\n default:\n return 'default';\n }\n}\n\n/**\n * GTInput — text input component driven by Grundtone theme tokens.\n *\n * Help text and error messages are placed between label and input,\n * following form field best practices.\n *\n * @example\n * <GTInput value={name} onChangeText={setName} label=\"Name\" />\n * <GTInput value={email} onChangeText={setEmail} type=\"email\" errorText=\"Invalid email\" />\n * <GTInput value={amount} onChangeText={setAmount} prefix=\"kr.\" label=\"Amount\" />\n */\nexport function GTInput({\n value,\n onChangeText,\n onFocus,\n onBlur,\n type = 'text',\n size = 'md',\n rounded,\n placeholder,\n label,\n helpText,\n errorText,\n disabled = false,\n readonly = false,\n required = false,\n optionalLabel,\n block = false,\n maxLength,\n prefix,\n suffix,\n accessibilityLabel,\n}: InputProps) {\n const { theme } = useGrundtoneTheme();\n const [isFocused, setIsFocused] = useState(false);\n\n const sp = (key: keyof typeof theme.spacing) => rem(theme.spacing[key]);\n const fs = (key: keyof typeof theme.typography.fontSize) =>\n rem(theme.typography.fontSize[key]);\n const fw = (key: keyof typeof theme.typography.fontWeight) =>\n `${theme.typography.fontWeight[key]}` as TextStyle['fontWeight'];\n\n const sizeStyles = getSizeStyles(size, theme);\n const radiusStyle = getRadiusStyle(rounded, theme.radius);\n\n const borderColor = errorText\n ? theme.colors.error\n : isFocused\n ? theme.colors.primary\n : theme.colors.borderMedium;\n\n const inputStyle: ViewStyle & TextStyle = {\n borderWidth: 1,\n ...sizeStyles,\n ...radiusStyle,\n borderColor,\n backgroundColor:\n disabled || readonly ? theme.colors.surfaceAlt : theme.colors.background,\n color: theme.colors.text,\n fontFamily: theme.typography.fontFamily.base,\n opacity: disabled ? 0.5 : 1,\n ...(block ? { width: '100%' as const } : undefined),\n };\n\n const hasAffix = !!prefix || !!suffix;\n\n // When using prefix/suffix, remove border radius from adjacent sides\n const affixInputStyle: ViewStyle & TextStyle = hasAffix\n ? {\n ...inputStyle,\n ...(prefix\n ? {\n borderTopLeftRadius: 0,\n borderBottomLeftRadius: 0,\n borderLeftWidth: 0,\n }\n : {}),\n ...(suffix\n ? {\n borderTopRightRadius: 0,\n borderBottomRightRadius: 0,\n borderRightWidth: 0,\n }\n : {}),\n flex: 1,\n }\n : inputStyle;\n\n const affixStyle: ViewStyle & TextStyle = {\n justifyContent: 'center',\n paddingHorizontal: sp('md'),\n backgroundColor: theme.colors.surface,\n borderWidth: 1,\n borderColor,\n };\n\n function handleFocus() {\n setIsFocused(true);\n onFocus?.();\n }\n\n function handleBlur() {\n setIsFocused(false);\n onBlur?.();\n }\n\n const textInput = (\n <TextInput\n style={hasAffix ? affixInputStyle : inputStyle}\n value={value}\n onChangeText={onChangeText}\n onFocus={handleFocus}\n onBlur={handleBlur}\n placeholder={placeholder}\n placeholderTextColor={theme.colors.textSecondary}\n editable={!disabled && !readonly}\n secureTextEntry={type === 'password'}\n keyboardType={getKeyboardType(type)}\n maxLength={maxLength}\n accessibilityLabel={accessibilityLabel ?? label}\n accessibilityState={{ disabled }}\n />\n );\n\n return (\n <View style={block ? { width: '100%' as const } : undefined}>\n {/* Label */}\n {label ? (\n <Text\n style={{\n marginBottom: sp('xs'),\n color: theme.colors.text,\n fontFamily: theme.typography.fontFamily.base,\n fontSize: fs('sm'),\n fontWeight: fw('medium'),\n }}\n >\n {label}\n {optionalLabel && !required ? (\n <Text\n style={{\n color: theme.colors.textSecondary,\n fontWeight: fw('normal'),\n }}\n >\n {' '}\n {optionalLabel}\n </Text>\n ) : null}\n </Text>\n ) : null}\n\n {/* Help text — between label and input */}\n {helpText && !errorText ? (\n <Text\n style={{\n marginBottom: sp('xs'),\n color: theme.colors.textSecondary,\n fontFamily: theme.typography.fontFamily.base,\n fontSize: fs('sm'),\n }}\n >\n {helpText}\n </Text>\n ) : null}\n\n {/* Error text — between label and input */}\n {errorText ? (\n <Text\n style={{\n marginBottom: sp('xs'),\n color: theme.colors.error,\n fontFamily: theme.typography.fontFamily.base,\n fontSize: fs('sm'),\n fontWeight: fw('semibold'),\n }}\n accessibilityRole=\"alert\"\n >\n {errorText}\n </Text>\n ) : null}\n\n {/* Input with optional prefix/suffix */}\n {hasAffix ? (\n <View style={{ flexDirection: 'row', alignItems: 'stretch' }}>\n {prefix ? (\n <View\n style={[\n affixStyle,\n radiusStyle,\n { borderTopRightRadius: 0, borderBottomRightRadius: 0 },\n ]}\n accessibilityElementsHidden\n importantForAccessibility=\"no-hide-descendants\"\n >\n <Text\n style={{\n color: theme.colors.textSecondary,\n fontFamily: theme.typography.fontFamily.base,\n fontSize: fs('base'),\n }}\n >\n {prefix}\n </Text>\n </View>\n ) : null}\n {textInput}\n {suffix ? (\n <View\n style={[\n affixStyle,\n radiusStyle,\n { borderTopLeftRadius: 0, borderBottomLeftRadius: 0 },\n ]}\n accessibilityElementsHidden\n importantForAccessibility=\"no-hide-descendants\"\n >\n <Text\n style={{\n color: theme.colors.textSecondary,\n fontFamily: theme.typography.fontFamily.base,\n fontSize: fs('base'),\n }}\n >\n {suffix}\n </Text>\n </View>\n ) : null}\n </View>\n ) : (\n textInput\n )}\n </View>\n );\n}\n\nfunction getSizeStyles(\n size: InputSize,\n theme: ReturnType<typeof useGrundtoneTheme>['theme'],\n): TextStyle {\n switch (size) {\n case 'sm':\n return {\n fontSize: rem(theme.typography.fontSize.sm),\n paddingVertical: rem(theme.spacing.xs),\n paddingHorizontal: rem(theme.spacing.sm),\n };\n case 'md':\n return {\n fontSize: rem(theme.typography.fontSize.base),\n paddingVertical: rem(theme.spacing.sm),\n paddingHorizontal: rem(theme.spacing.md),\n };\n case 'lg':\n return {\n fontSize: rem(theme.typography.fontSize.lg),\n paddingVertical: rem(theme.spacing.md),\n paddingHorizontal: rem(theme.spacing.xl),\n };\n }\n}\n\nfunction getRadiusStyle(\n rounded: InputRadius | undefined,\n radius: ReturnType<typeof useGrundtoneTheme>['theme']['radius'],\n): ViewStyle {\n if (!rounded) return { borderRadius: rem(radius.md) };\n if (rounded === 'full') return { borderRadius: 9999 };\n if (rounded === 'none') return { borderRadius: 0 };\n return { borderRadius: rem(radius[rounded]) };\n}\n","import React, { useEffect, useRef } from 'react';\nimport {\n View,\n Text,\n Pressable,\n Animated,\n type ViewStyle,\n type TextStyle,\n} from 'react-native';\nimport { TOGGLE_SIZES } from '@grundtone/core';\nimport { useGrundtoneTheme } from '../../useGrundtoneTheme';\nimport type { ToggleProps } from './types';\n\n/** Parse rem string to pixel number (base 16) */\nfunction rem(value: string): number {\n return parseFloat(value) * 16;\n}\n\n/**\n * GTToggle — toggle switch component driven by Grundtone theme tokens.\n *\n * A digital on/off button. The choice takes effect immediately.\n *\n * @example\n * <GTToggle value={isDark} onValueChange={setIsDark} label=\"Dark mode\" />\n */\nexport function GTToggle({\n value = false,\n onValueChange,\n label,\n size = 'md',\n disabled = false,\n accessibilityLabel,\n}: ToggleProps) {\n const { theme } = useGrundtoneTheme();\n\n const dims = TOGGLE_SIZES[size];\n const thumbOffset = 2;\n const thumbTravel = dims.width - dims.thumb - thumbOffset * 2;\n\n const anim = useRef(new Animated.Value(value ? 1 : 0)).current;\n\n useEffect(() => {\n Animated.timing(anim, {\n toValue: value ? 1 : 0,\n duration: 150,\n useNativeDriver: false,\n }).start();\n }, [value, anim]);\n\n function handlePress() {\n if (disabled) return;\n onValueChange?.(!value);\n }\n\n const fieldStyle: ViewStyle = {\n flexDirection: 'row',\n alignItems: 'center',\n gap: rem(theme.spacing.sm),\n opacity: disabled ? 0.5 : 1,\n };\n\n const labelStyle: TextStyle = {\n color: theme.colors.text,\n fontFamily: theme.typography.fontFamily.base,\n fontSize: rem(theme.typography.fontSize.sm),\n fontWeight: theme.typography.fontWeight.medium as TextStyle['fontWeight'],\n };\n\n const trackBg = anim.interpolate({\n inputRange: [0, 1],\n outputRange: [theme.colors.borderMedium, theme.colors.primary],\n });\n\n const thumbTranslate = anim.interpolate({\n inputRange: [0, 1],\n outputRange: [0, thumbTravel],\n });\n\n return (\n <View style={fieldStyle}>\n {label ? <Text style={labelStyle}>{label}</Text> : null}\n <Pressable\n onPress={handlePress}\n disabled={disabled}\n accessibilityRole=\"switch\"\n accessibilityLabel={accessibilityLabel ?? label}\n accessibilityState={{ checked: value, disabled }}\n >\n <Animated.View\n style={{\n width: dims.width,\n height: dims.height,\n borderRadius: 9999,\n backgroundColor: trackBg,\n justifyContent: 'center',\n }}\n >\n <Animated.View\n style={{\n position: 'absolute',\n width: dims.thumb,\n height: dims.thumb,\n borderRadius: 9999,\n backgroundColor: theme.colors.background,\n left: thumbOffset,\n transform: [{ translateX: thumbTranslate }],\n }}\n />\n </Animated.View>\n </Pressable>\n </View>\n );\n}\n","import React from 'react';\nimport {\n View,\n Text,\n Pressable,\n type ViewStyle,\n type TextStyle,\n} from 'react-native';\nimport { useGrundtoneTheme } from '../../useGrundtoneTheme';\nimport { GTIcon } from '../Icon';\nimport type { AlertProps } from './types';\n\n/** Parse rem string to pixel number (base 16) */\nfunction rem(value: string): number {\n return parseFloat(value) * 16;\n}\n\n/** Convert hex color to rgba with alpha */\nfunction hexAlpha(hex: string, alpha: number): string {\n const r = parseInt(hex.slice(1, 3), 16);\n const g = parseInt(hex.slice(3, 5), 16);\n const b = parseInt(hex.slice(5, 7), 16);\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n}\n\n/**\n * GTAlert — status message component driven by Grundtone theme tokens.\n *\n * Static alerts for info, success, warning, and error messages.\n *\n * @example\n * <GTAlert variant=\"info\" icon=\"info-circle\">\n * <Text>This is an informational message.</Text>\n * </GTAlert>\n */\nexport function GTAlert({\n variant,\n heading,\n icon,\n dismissible = false,\n onDismiss,\n accessibilityLabel,\n children,\n footer,\n}: AlertProps) {\n const { theme } = useGrundtoneTheme();\n\n const borderColor = {\n info: theme.colors.info,\n success: theme.colors.success,\n warning: theme.colors.warning,\n error: theme.colors.error,\n }[variant];\n\n const containerStyle: ViewStyle = {\n flexDirection: 'row',\n alignItems: 'flex-start',\n gap: rem(theme.spacing.md),\n padding: rem(theme.spacing.md),\n borderRadius: rem(theme.radius.lg),\n borderWidth: 1,\n borderColor,\n backgroundColor: hexAlpha(borderColor, 0.12),\n };\n\n const iconStyle: ViewStyle = {\n alignSelf: 'center',\n };\n\n const contentStyle: ViewStyle = {\n flex: 1,\n };\n\n const headingStyle: TextStyle = {\n fontWeight: theme.typography.fontWeight.semibold as TextStyle['fontWeight'],\n fontFamily: theme.typography.fontFamily.base,\n fontSize: rem(theme.typography.fontSize.sm),\n color: theme.colors.text,\n marginBottom: rem(theme.spacing.xs),\n };\n\n const footerStyle: ViewStyle = {\n marginTop: rem(theme.spacing.lg),\n paddingTop: rem(theme.spacing.lg),\n borderTopWidth: 1,\n borderTopColor: theme.colors.text,\n opacity: 0.3,\n };\n\n const closeStyle: ViewStyle = {\n opacity: 0.7,\n };\n\n return (\n <View\n style={containerStyle}\n accessibilityRole=\"alert\"\n accessibilityLabel={accessibilityLabel}\n >\n {icon ? (\n <View style={iconStyle}>\n <GTIcon name={icon} size=\"lg\" color={theme.colors.text} />\n </View>\n ) : null}\n\n <View style={contentStyle}>\n {heading ? <Text style={headingStyle}>{heading}</Text> : null}\n <View>{children}</View>\n {footer ? <View style={footerStyle}>{footer}</View> : null}\n </View>\n\n {dismissible ? (\n <Pressable\n style={closeStyle}\n onPress={onDismiss}\n accessibilityLabel=\"Close\"\n accessibilityRole=\"button\"\n >\n <GTIcon name=\"close\" size=\"xs\" color={theme.colors.text} />\n </Pressable>\n ) : null}\n </View>\n );\n}\n","import { useState, useCallback, useRef } from 'react';\nimport type { Validator, ValidationResult } from '@grundtone/utils';\n\nexport interface UseFieldOptions {\n validators?: Validator[];\n validateOn?: 'input' | 'blur' | 'submit';\n initialValue?: string;\n}\n\nexport interface UseFieldReturn {\n value: string;\n setValue: (v: string) => void;\n errorText: string | undefined;\n touched: boolean;\n isValid: boolean;\n validate: () => ValidationResult;\n reset: () => void;\n fieldProps: {\n value: string;\n onChangeText: (v: string) => void;\n onBlur: () => void;\n };\n}\n\n/**\n * Reactive field state with validation for use with GTInput.\n *\n * @example\n * import { useField } from '@grundtone/react-native';\n * import { required, email } from '@grundtone/utils';\n *\n * const field = useField({\n * validators: [required(), email()],\n * validateOn: 'blur',\n * });\n *\n * <GTInput {...field.fieldProps} errorText={field.errorText} />\n */\nexport function useField(options: UseFieldOptions = {}): UseFieldReturn {\n const { validators = [], validateOn = 'blur', initialValue = '' } = options;\n\n const [value, setValueState] = useState(initialValue);\n const [touched, setTouched] = useState(false);\n const [validationMessage, setValidationMessage] = useState<\n string | undefined\n >(undefined);\n\n // Keep current value in ref for validate() to read synchronously\n const valueRef = useRef(value);\n\n const runValidation = useCallback(\n (val: string): ValidationResult => {\n for (const validator of validators) {\n const result = validator(val);\n if (!result.isValid) {\n setValidationMessage(result.message);\n return result;\n }\n }\n setValidationMessage(undefined);\n return { isValid: true };\n },\n [validators],\n );\n\n const validate = useCallback((): ValidationResult => {\n return runValidation(valueRef.current);\n }, [runValidation]);\n\n const setValue = useCallback(\n (v: string) => {\n setValueState(v);\n valueRef.current = v;\n if (validateOn === 'input') {\n setTouched(true);\n runValidation(v);\n }\n },\n [validateOn, runValidation],\n );\n\n const onBlur = useCallback(() => {\n if (validateOn === 'blur') {\n setTouched(true);\n runValidation(valueRef.current);\n }\n }, [validateOn, runValidation]);\n\n const reset = useCallback(() => {\n setValueState(initialValue);\n valueRef.current = initialValue;\n setTouched(false);\n setValidationMessage(undefined);\n }, [initialValue]);\n\n return {\n value,\n setValue,\n errorText: touched ? validationMessage : undefined,\n touched,\n isValid: validationMessage === undefined,\n validate,\n reset,\n fieldProps: {\n value,\n onChangeText: setValue,\n onBlur,\n },\n };\n}\n","import { useMemo, useCallback } from 'react';\nimport type { UseFieldReturn } from './useField';\n\nexport interface UseFormValidationReturn {\n isValid: boolean;\n validateAll: () => boolean;\n resetAll: () => void;\n}\n\n/**\n * Aggregates multiple useField instances for form-level validation.\n *\n * @example\n * const nameField = useField({ validators: [required()] });\n * const emailField = useField({ validators: [required(), email()] });\n *\n * const form = useFormValidation({ name: nameField, email: emailField });\n *\n * function onSubmit() {\n * if (!form.validateAll()) return;\n * // all fields valid\n * }\n */\nexport function useFormValidation(\n fields: Record<string, UseFieldReturn>,\n): UseFormValidationReturn {\n const fieldValues = Object.values(fields);\n\n const isValid = useMemo(\n () => fieldValues.every(f => f.isValid),\n [fieldValues],\n );\n\n const validateAll = useCallback((): boolean => {\n let allValid = true;\n for (const field of Object.values(fields)) {\n const result = field.validate();\n if (!result.isValid) allValid = false;\n }\n return allValid;\n }, [fields]);\n\n const resetAll = useCallback(() => {\n for (const field of Object.values(fields)) {\n field.reset();\n }\n }, [fields]);\n\n return { isValid, validateAll, resetAll };\n}\n","/**\n * React Native branding helpers.\n *\n * Re-exports core branding types and provides RN-specific image source helpers.\n *\n * @example\n * import { getLogoSource } from '@grundtone/react-native';\n * <Image source={getLogoSource()} style={{ width: 120, height: 120 }} />\n */\n\nimport type { ImageSourcePropType } from 'react-native';\nimport type { BrandingConfig } from '@grundtone/core';\nimport { defaultBranding } from '@grundtone/core';\n\nexport type { BrandingConfig, LogoVariants } from '@grundtone/core';\nexport {\n defaultBranding,\n createBranding,\n LOGO_VARIANT_SIZES,\n} from '@grundtone/core';\n\n/** Default logo as an RN ImageSourcePropType (requires bundler `require`). */\n/**\n * Static require for Metro bundler — resolves via @grundtone/core/assets/*.\n * In a real RN app, the consumer's Metro config must resolve this package path.\n * Falls back to a URI-based source if the static require is not available.\n */\nexport const defaultLogoSource: ImageSourcePropType = {\n uri: defaultBranding.logos.primary,\n};\n\n/**\n * Get an RN ImageSourcePropType for the primary logo.\n *\n * When using the default branding, returns a static `require()`.\n * When using custom branding, returns a URI-based source.\n */\nexport function getLogoSource(branding?: BrandingConfig): ImageSourcePropType {\n if (!branding || branding.logos.primary === defaultBranding.logos.primary) {\n return defaultLogoSource;\n }\n return { uri: branding.logos.primary };\n}\n"],"mappings":"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","names":["createContext","useContext","jsx","jsx","jsx","useState","Text","jsx","rem","required","maxLength","useState","getSizeStyles","getRadiusStyle","Text","useEffect","View","Text","Pressable","jsx","jsxs","rem","useEffect","View","Text","Pressable","View","Text","Pressable","jsx","jsxs","rem","View","Text","Pressable","useState","useCallback","useRef","useMemo","useCallback","defaultBranding"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@grundtone/react-native",
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "React Native theme provider and hooks for Grundtone design system",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"private": false,
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"module": "./dist/index.mjs",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.mjs",
|
|
14
|
+
"require": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/grundtone/grundtone.git",
|
|
23
|
+
"directory": "packages/react-native"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsup",
|
|
30
|
+
"dev": "tsup --watch",
|
|
31
|
+
"clean": "rm -rf .turbo node_modules dist",
|
|
32
|
+
"prepublishOnly": "test -d dist || pnpm run build"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"react": ">=18.0.0 || >=19.0.0",
|
|
36
|
+
"react-native": ">=0.72.0",
|
|
37
|
+
"expo": ">=52.0.0",
|
|
38
|
+
"react-native-svg": ">=13.0.0"
|
|
39
|
+
},
|
|
40
|
+
"peerDependenciesMeta": {
|
|
41
|
+
"react-native-svg": {
|
|
42
|
+
"optional": true
|
|
43
|
+
},
|
|
44
|
+
"expo": {
|
|
45
|
+
"optional": true
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@grundtone/core": "workspace:*",
|
|
50
|
+
"@grundtone/icons": "workspace:*",
|
|
51
|
+
"@grundtone/utils": "workspace:*"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/react": "~19.1.0",
|
|
55
|
+
"tsup": "^8.0.2",
|
|
56
|
+
"typescript": "^5.0.0"
|
|
57
|
+
}
|
|
58
|
+
}
|