@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
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
|
package/dist/index.d.mts
ADDED
|
@@ -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 };
|
package/dist/index.d.ts
ADDED
|
@@ -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 };
|