@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 ADDED
@@ -0,0 +1,78 @@
1
+ # @grundtone/react-native
2
+
3
+ React Native theme provider and hooks for the [Grundtone](https://grundtone.com) design system. Uses
4
+ the same semantic tokens as the web packages.
5
+
6
+ ## Installation
7
+
8
+ ```bash
9
+ npm install @grundtone/react-native @grundtone/core
10
+ ```
11
+
12
+ You do **not** need `@grundtone/design-system` - that package is web-only (SCSS/CSS). For React
13
+ Native, tokens are delivered via the theme object.
14
+
15
+ ## Usage
16
+
17
+ ### 1. Wrap your app
18
+
19
+ ```tsx
20
+ import { GrundtoneThemeProvider } from '@grundtone/react-native';
21
+ import { createTheme } from '@grundtone/core';
22
+
23
+ const { light, dark } = createTheme({
24
+ light: {
25
+ colors: { primary: '#007aff', background: '#ffffff', text: '#1c1c1e' },
26
+ },
27
+ dark: {
28
+ colors: { primary: '#0a84ff', background: '#000000', text: '#ffffff' },
29
+ },
30
+ });
31
+
32
+ export default function App() {
33
+ return (
34
+ <GrundtoneThemeProvider light={light} dark={dark}>
35
+ <RootNavigator />
36
+ </GrundtoneThemeProvider>
37
+ );
38
+ }
39
+ ```
40
+
41
+ ### 2. Use the theme
42
+
43
+ ```tsx
44
+ import { useGrundtoneTheme } from '@grundtone/react-native';
45
+
46
+ function MyScreen() {
47
+ const { theme, mode, setMode, isDark } = useGrundtoneTheme();
48
+
49
+ return (
50
+ <View style={{ backgroundColor: theme.colors.background, flex: 1 }}>
51
+ <Text style={{ color: theme.colors.text }}>Hello</Text>
52
+ </View>
53
+ );
54
+ }
55
+ ```
56
+
57
+ ### Toggle theme
58
+
59
+ ```tsx
60
+ const { setMode } = useGrundtoneTheme();
61
+ setMode('dark');
62
+ ```
63
+
64
+ By default, the provider follows the system color scheme.
65
+
66
+ ## Utilities
67
+
68
+ - `shadowToRN(shadow)` - Convert web shadow values to React Native shadow styles
69
+ - `createBranding()` - Create branding configuration
70
+ - `getLogoSource()` - Get logo asset for current theme
71
+
72
+ ## Documentation
73
+
74
+ See [grundtone.com](https://grundtone.com) for full API reference.
75
+
76
+ ## License
77
+
78
+ MIT
@@ -0,0 +1,158 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { Theme, ThemeMode, ShadowLayer, IconDefinition, IconRegistry, ToggleSize, BrandingConfig } from '@grundtone/core';
3
+ export { BrandingConfig, IconDefinition, IconRegistry, LOGO_VARIANT_SIZES, LogoVariants, Theme, ThemeMode, ToggleSize, createBranding, createTheme, defaultBranding } from '@grundtone/core';
4
+ import * as react_jsx_runtime from 'react/jsx-runtime';
5
+ import { Validator, ValidationResult } from '@grundtone/utils';
6
+ export { ValidationResult, Validator, composeValidators, cpr, cvr, email, maxLength, minLength, pattern, phone, required, url } from '@grundtone/utils';
7
+ import { ImageSourcePropType } from 'react-native';
8
+
9
+ interface GrundtoneThemeContextValue {
10
+ theme: Theme;
11
+ mode: ThemeMode;
12
+ isDark: boolean;
13
+ setMode: (mode: ThemeMode) => void;
14
+ }
15
+ declare const GrundtoneThemeContext: React.Context<GrundtoneThemeContextValue | undefined>;
16
+ interface GrundtoneThemeProviderProps {
17
+ light: Theme;
18
+ dark: Theme;
19
+ defaultMode?: ThemeMode;
20
+ mode?: ThemeMode;
21
+ children: React.ReactNode;
22
+ }
23
+ declare function GrundtoneThemeProvider({ light, dark, defaultMode, mode: controlledMode, children, }: GrundtoneThemeProviderProps): React.ReactElement;
24
+
25
+ declare function useGrundtoneTheme(): GrundtoneThemeContextValue;
26
+
27
+ interface RNShadowStyle {
28
+ shadowColor: string;
29
+ shadowOffset: {
30
+ width: number;
31
+ height: number;
32
+ };
33
+ shadowOpacity: number;
34
+ shadowRadius: number;
35
+ elevation: number;
36
+ }
37
+ declare function shadowToRN(layers: ShadowLayer[]): RNShadowStyle;
38
+
39
+ type IconSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
40
+ interface IconProps {
41
+ icon?: IconDefinition;
42
+ name?: string;
43
+ size?: IconSize;
44
+ label?: string;
45
+ color?: string;
46
+ }
47
+
48
+ declare function GTIcon({ icon, name, size, label, color }: IconProps): react_jsx_runtime.JSX.Element | null;
49
+
50
+ interface IconRegistryProviderProps {
51
+ registry: IconRegistry;
52
+ children: React.ReactNode;
53
+ }
54
+ declare function IconRegistryProvider({ registry, children, }: IconRegistryProviderProps): react_jsx_runtime.JSX.Element;
55
+ declare function useIconRegistry(): IconRegistry | null;
56
+
57
+ type ButtonVariant = 'primary' | 'secondary' | 'outlined' | 'negative' | 'unstyled';
58
+ type ButtonSize = 'sm' | 'md' | 'lg';
59
+ type ButtonRadius = 'none' | 'sm' | 'md' | 'lg' | 'full';
60
+ interface ButtonProps {
61
+ variant?: ButtonVariant;
62
+ size?: ButtonSize;
63
+ rounded?: ButtonRadius;
64
+ disabled?: boolean;
65
+ loading?: boolean;
66
+ block?: boolean;
67
+ onPress?: () => void;
68
+ accessibilityLabel?: string;
69
+ children: ReactNode;
70
+ }
71
+
72
+ declare function GTButton({ variant, size, rounded, disabled, loading, block, onPress, accessibilityLabel, children, }: ButtonProps): react_jsx_runtime.JSX.Element;
73
+
74
+ type InputSize = 'sm' | 'md' | 'lg';
75
+ type InputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search';
76
+ type InputRadius = 'none' | 'sm' | 'md' | 'lg' | 'full';
77
+ interface InputProps {
78
+ value?: string;
79
+ onChangeText?: (text: string) => void;
80
+ onFocus?: () => void;
81
+ onBlur?: () => void;
82
+ type?: InputType;
83
+ size?: InputSize;
84
+ rounded?: InputRadius;
85
+ placeholder?: string;
86
+ label?: string;
87
+ helpText?: string;
88
+ errorText?: string;
89
+ disabled?: boolean;
90
+ readonly?: boolean;
91
+ required?: boolean;
92
+ optionalLabel?: string;
93
+ block?: boolean;
94
+ maxLength?: number;
95
+ prefix?: string;
96
+ suffix?: string;
97
+ accessibilityLabel?: string;
98
+ }
99
+
100
+ declare function GTInput({ value, onChangeText, onFocus, onBlur, type, size, rounded, placeholder, label, helpText, errorText, disabled, readonly, required, optionalLabel, block, maxLength, prefix, suffix, accessibilityLabel, }: InputProps): react_jsx_runtime.JSX.Element;
101
+
102
+ interface ToggleProps {
103
+ value?: boolean;
104
+ onValueChange?: (value: boolean) => void;
105
+ label?: string;
106
+ size?: ToggleSize;
107
+ disabled?: boolean;
108
+ accessibilityLabel?: string;
109
+ }
110
+
111
+ declare function GTToggle({ value, onValueChange, label, size, disabled, accessibilityLabel, }: ToggleProps): react_jsx_runtime.JSX.Element;
112
+
113
+ type AlertVariant = 'info' | 'success' | 'warning' | 'error';
114
+ interface AlertProps {
115
+ variant: AlertVariant;
116
+ heading?: string;
117
+ icon?: string;
118
+ dismissible?: boolean;
119
+ onDismiss?: () => void;
120
+ accessibilityLabel?: string;
121
+ children: ReactNode;
122
+ footer?: ReactNode;
123
+ }
124
+
125
+ declare function GTAlert({ variant, heading, icon, dismissible, onDismiss, accessibilityLabel, children, footer, }: AlertProps): react_jsx_runtime.JSX.Element;
126
+
127
+ interface UseFieldOptions {
128
+ validators?: Validator[];
129
+ validateOn?: 'input' | 'blur' | 'submit';
130
+ initialValue?: string;
131
+ }
132
+ interface UseFieldReturn {
133
+ value: string;
134
+ setValue: (v: string) => void;
135
+ errorText: string | undefined;
136
+ touched: boolean;
137
+ isValid: boolean;
138
+ validate: () => ValidationResult;
139
+ reset: () => void;
140
+ fieldProps: {
141
+ value: string;
142
+ onChangeText: (v: string) => void;
143
+ onBlur: () => void;
144
+ };
145
+ }
146
+ declare function useField(options?: UseFieldOptions): UseFieldReturn;
147
+
148
+ interface UseFormValidationReturn {
149
+ isValid: boolean;
150
+ validateAll: () => boolean;
151
+ resetAll: () => void;
152
+ }
153
+ declare function useFormValidation(fields: Record<string, UseFieldReturn>): UseFormValidationReturn;
154
+
155
+ declare const defaultLogoSource: ImageSourcePropType;
156
+ declare function getLogoSource(branding?: BrandingConfig): ImageSourcePropType;
157
+
158
+ export { type AlertProps, type AlertVariant, type ButtonProps, type ButtonRadius, type ButtonSize, type ButtonVariant, GTAlert, GTButton, GTIcon, GTInput, GTToggle, GrundtoneThemeContext, type GrundtoneThemeContextValue, GrundtoneThemeProvider, type IconProps, IconRegistryProvider, type IconRegistryProviderProps, type IconSize, type InputProps, type InputRadius, type InputSize, type InputType, type RNShadowStyle, type ToggleProps, type UseFieldOptions, type UseFieldReturn, type UseFormValidationReturn, defaultLogoSource, getLogoSource, shadowToRN, useField, useFormValidation, useGrundtoneTheme, useIconRegistry };
@@ -0,0 +1,158 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { Theme, ThemeMode, ShadowLayer, IconDefinition, IconRegistry, ToggleSize, BrandingConfig } from '@grundtone/core';
3
+ export { BrandingConfig, IconDefinition, IconRegistry, LOGO_VARIANT_SIZES, LogoVariants, Theme, ThemeMode, ToggleSize, createBranding, createTheme, defaultBranding } from '@grundtone/core';
4
+ import * as react_jsx_runtime from 'react/jsx-runtime';
5
+ import { Validator, ValidationResult } from '@grundtone/utils';
6
+ export { ValidationResult, Validator, composeValidators, cpr, cvr, email, maxLength, minLength, pattern, phone, required, url } from '@grundtone/utils';
7
+ import { ImageSourcePropType } from 'react-native';
8
+
9
+ interface GrundtoneThemeContextValue {
10
+ theme: Theme;
11
+ mode: ThemeMode;
12
+ isDark: boolean;
13
+ setMode: (mode: ThemeMode) => void;
14
+ }
15
+ declare const GrundtoneThemeContext: React.Context<GrundtoneThemeContextValue | undefined>;
16
+ interface GrundtoneThemeProviderProps {
17
+ light: Theme;
18
+ dark: Theme;
19
+ defaultMode?: ThemeMode;
20
+ mode?: ThemeMode;
21
+ children: React.ReactNode;
22
+ }
23
+ declare function GrundtoneThemeProvider({ light, dark, defaultMode, mode: controlledMode, children, }: GrundtoneThemeProviderProps): React.ReactElement;
24
+
25
+ declare function useGrundtoneTheme(): GrundtoneThemeContextValue;
26
+
27
+ interface RNShadowStyle {
28
+ shadowColor: string;
29
+ shadowOffset: {
30
+ width: number;
31
+ height: number;
32
+ };
33
+ shadowOpacity: number;
34
+ shadowRadius: number;
35
+ elevation: number;
36
+ }
37
+ declare function shadowToRN(layers: ShadowLayer[]): RNShadowStyle;
38
+
39
+ type IconSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
40
+ interface IconProps {
41
+ icon?: IconDefinition;
42
+ name?: string;
43
+ size?: IconSize;
44
+ label?: string;
45
+ color?: string;
46
+ }
47
+
48
+ declare function GTIcon({ icon, name, size, label, color }: IconProps): react_jsx_runtime.JSX.Element | null;
49
+
50
+ interface IconRegistryProviderProps {
51
+ registry: IconRegistry;
52
+ children: React.ReactNode;
53
+ }
54
+ declare function IconRegistryProvider({ registry, children, }: IconRegistryProviderProps): react_jsx_runtime.JSX.Element;
55
+ declare function useIconRegistry(): IconRegistry | null;
56
+
57
+ type ButtonVariant = 'primary' | 'secondary' | 'outlined' | 'negative' | 'unstyled';
58
+ type ButtonSize = 'sm' | 'md' | 'lg';
59
+ type ButtonRadius = 'none' | 'sm' | 'md' | 'lg' | 'full';
60
+ interface ButtonProps {
61
+ variant?: ButtonVariant;
62
+ size?: ButtonSize;
63
+ rounded?: ButtonRadius;
64
+ disabled?: boolean;
65
+ loading?: boolean;
66
+ block?: boolean;
67
+ onPress?: () => void;
68
+ accessibilityLabel?: string;
69
+ children: ReactNode;
70
+ }
71
+
72
+ declare function GTButton({ variant, size, rounded, disabled, loading, block, onPress, accessibilityLabel, children, }: ButtonProps): react_jsx_runtime.JSX.Element;
73
+
74
+ type InputSize = 'sm' | 'md' | 'lg';
75
+ type InputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search';
76
+ type InputRadius = 'none' | 'sm' | 'md' | 'lg' | 'full';
77
+ interface InputProps {
78
+ value?: string;
79
+ onChangeText?: (text: string) => void;
80
+ onFocus?: () => void;
81
+ onBlur?: () => void;
82
+ type?: InputType;
83
+ size?: InputSize;
84
+ rounded?: InputRadius;
85
+ placeholder?: string;
86
+ label?: string;
87
+ helpText?: string;
88
+ errorText?: string;
89
+ disabled?: boolean;
90
+ readonly?: boolean;
91
+ required?: boolean;
92
+ optionalLabel?: string;
93
+ block?: boolean;
94
+ maxLength?: number;
95
+ prefix?: string;
96
+ suffix?: string;
97
+ accessibilityLabel?: string;
98
+ }
99
+
100
+ declare function GTInput({ value, onChangeText, onFocus, onBlur, type, size, rounded, placeholder, label, helpText, errorText, disabled, readonly, required, optionalLabel, block, maxLength, prefix, suffix, accessibilityLabel, }: InputProps): react_jsx_runtime.JSX.Element;
101
+
102
+ interface ToggleProps {
103
+ value?: boolean;
104
+ onValueChange?: (value: boolean) => void;
105
+ label?: string;
106
+ size?: ToggleSize;
107
+ disabled?: boolean;
108
+ accessibilityLabel?: string;
109
+ }
110
+
111
+ declare function GTToggle({ value, onValueChange, label, size, disabled, accessibilityLabel, }: ToggleProps): react_jsx_runtime.JSX.Element;
112
+
113
+ type AlertVariant = 'info' | 'success' | 'warning' | 'error';
114
+ interface AlertProps {
115
+ variant: AlertVariant;
116
+ heading?: string;
117
+ icon?: string;
118
+ dismissible?: boolean;
119
+ onDismiss?: () => void;
120
+ accessibilityLabel?: string;
121
+ children: ReactNode;
122
+ footer?: ReactNode;
123
+ }
124
+
125
+ declare function GTAlert({ variant, heading, icon, dismissible, onDismiss, accessibilityLabel, children, footer, }: AlertProps): react_jsx_runtime.JSX.Element;
126
+
127
+ interface UseFieldOptions {
128
+ validators?: Validator[];
129
+ validateOn?: 'input' | 'blur' | 'submit';
130
+ initialValue?: string;
131
+ }
132
+ interface UseFieldReturn {
133
+ value: string;
134
+ setValue: (v: string) => void;
135
+ errorText: string | undefined;
136
+ touched: boolean;
137
+ isValid: boolean;
138
+ validate: () => ValidationResult;
139
+ reset: () => void;
140
+ fieldProps: {
141
+ value: string;
142
+ onChangeText: (v: string) => void;
143
+ onBlur: () => void;
144
+ };
145
+ }
146
+ declare function useField(options?: UseFieldOptions): UseFieldReturn;
147
+
148
+ interface UseFormValidationReturn {
149
+ isValid: boolean;
150
+ validateAll: () => boolean;
151
+ resetAll: () => void;
152
+ }
153
+ declare function useFormValidation(fields: Record<string, UseFieldReturn>): UseFormValidationReturn;
154
+
155
+ declare const defaultLogoSource: ImageSourcePropType;
156
+ declare function getLogoSource(branding?: BrandingConfig): ImageSourcePropType;
157
+
158
+ export { type AlertProps, type AlertVariant, type ButtonProps, type ButtonRadius, type ButtonSize, type ButtonVariant, GTAlert, GTButton, GTIcon, GTInput, GTToggle, GrundtoneThemeContext, type GrundtoneThemeContextValue, GrundtoneThemeProvider, type IconProps, IconRegistryProvider, type IconRegistryProviderProps, type IconSize, type InputProps, type InputRadius, type InputSize, type InputType, type RNShadowStyle, type ToggleProps, type UseFieldOptions, type UseFieldReturn, type UseFormValidationReturn, defaultLogoSource, getLogoSource, shadowToRN, useField, useFormValidation, useGrundtoneTheme, useIconRegistry };