@ggui-ai/mcp-apps-react-native 0.0.1-placeholder → 0.9.0
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/LICENSE +201 -0
- package/README.md +58 -4
- package/package.json +84 -4
- package/src/McpAppIframe/McpAppIframe.tsx +368 -0
- package/src/McpAppIframe/dispatch.ts +418 -0
- package/src/McpAppIframe/index.ts +15 -0
- package/src/McpAppIframe/types.ts +227 -0
- package/src/chat-helpers/index.ts +12 -0
- package/src/chat-helpers/message-groups.ts +124 -0
- package/src/chat-helpers/render.ts +65 -0
- package/src/chat-helpers/useRafThrottled.ts +34 -0
- package/src/components/ErrorBoundary.tsx +96 -0
- package/src/components/GguiProvider.tsx +188 -0
- package/src/components/UiFeedback.tsx +233 -0
- package/src/components/mcp-apps-bridge.ts +388 -0
- package/src/context/GguiContext.ts +121 -0
- package/src/hooks/useAppState.ts +24 -0
- package/src/index.ts +150 -0
- package/src/invoke/index.ts +8 -0
- package/src/invoke/sse-parse.ts +79 -0
- package/src/invoke/useInvoke.ts +502 -0
- package/src/test-setup.ts +85 -0
- package/src/theme/ThemeProvider.tsx +129 -0
- package/src/theme/index.ts +29 -0
- package/src/theme/tokens.ts +201 -0
- package/src/theme/types.ts +94 -0
- package/src/types/react-test-renderer.d.ts +50 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native Theme Provider
|
|
3
|
+
*
|
|
4
|
+
* Provides design tokens via React Context with light/dark mode support.
|
|
5
|
+
* Uses the system color scheme by default but supports explicit override.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createContext, useContext, useEffect, useMemo, useState, type ReactNode } from 'react';
|
|
9
|
+
import { AccessibilityInfo, useColorScheme } from 'react-native';
|
|
10
|
+
import type { RNTheme } from './types';
|
|
11
|
+
import {
|
|
12
|
+
rnColors,
|
|
13
|
+
rnSemantic,
|
|
14
|
+
rnSpacing,
|
|
15
|
+
rnSpacingNamed,
|
|
16
|
+
rnFontSize,
|
|
17
|
+
rnFontWeight,
|
|
18
|
+
rnLineHeight,
|
|
19
|
+
rnFontFamily,
|
|
20
|
+
rnRadius,
|
|
21
|
+
rnShadow,
|
|
22
|
+
rnDuration,
|
|
23
|
+
rnEasing,
|
|
24
|
+
rnTransition,
|
|
25
|
+
rnAccessibility,
|
|
26
|
+
} from './tokens';
|
|
27
|
+
|
|
28
|
+
// Dark mode semantic overrides
|
|
29
|
+
const darkSemantic = {
|
|
30
|
+
textPrimary: rnColors.gray[50],
|
|
31
|
+
textSecondary: rnColors.gray[400],
|
|
32
|
+
textMuted: rnColors.gray[500],
|
|
33
|
+
textInverse: rnColors.gray[900],
|
|
34
|
+
bgPrimary: '#0f172a',
|
|
35
|
+
bgSecondary: '#1e293b',
|
|
36
|
+
bgTertiary: rnColors.gray[800],
|
|
37
|
+
bgInverse: rnColors.gray[50],
|
|
38
|
+
borderLight: rnColors.gray[700],
|
|
39
|
+
borderDefault: rnColors.gray[600],
|
|
40
|
+
borderDark: rnColors.gray[500],
|
|
41
|
+
focus: rnColors.primary[400],
|
|
42
|
+
hover: rnColors.primary[900],
|
|
43
|
+
active: rnColors.primary[800],
|
|
44
|
+
disabled: rnColors.gray[600],
|
|
45
|
+
success: rnColors.success[400],
|
|
46
|
+
warning: rnColors.warning[400],
|
|
47
|
+
error: rnColors.error[400],
|
|
48
|
+
info: rnColors.info[400],
|
|
49
|
+
} as const;
|
|
50
|
+
|
|
51
|
+
// Dark shadow overrides (higher opacity for visibility on dark backgrounds)
|
|
52
|
+
const darkShadow = {
|
|
53
|
+
none: rnShadow.none,
|
|
54
|
+
sm: { ...rnShadow.sm, shadowOpacity: 0.3 },
|
|
55
|
+
md: { ...rnShadow.md, shadowOpacity: 0.4 },
|
|
56
|
+
lg: { ...rnShadow.lg, shadowOpacity: 0.4 },
|
|
57
|
+
xl: { ...rnShadow.xl, shadowOpacity: 0.5 },
|
|
58
|
+
'2xl': { ...rnShadow['2xl'], shadowOpacity: 0.6 },
|
|
59
|
+
} as const;
|
|
60
|
+
|
|
61
|
+
function buildTheme(colorScheme: 'light' | 'dark', reduceMotionEnabled = false): RNTheme {
|
|
62
|
+
const isDark = colorScheme === 'dark';
|
|
63
|
+
return {
|
|
64
|
+
colorScheme,
|
|
65
|
+
colors: rnColors,
|
|
66
|
+
semantic: isDark ? darkSemantic : rnSemantic,
|
|
67
|
+
spacing: rnSpacing,
|
|
68
|
+
spacingNamed: rnSpacingNamed,
|
|
69
|
+
fontSize: rnFontSize,
|
|
70
|
+
fontWeight: rnFontWeight,
|
|
71
|
+
lineHeight: rnLineHeight,
|
|
72
|
+
fontFamily: rnFontFamily,
|
|
73
|
+
radius: rnRadius,
|
|
74
|
+
shadow: isDark ? darkShadow : rnShadow,
|
|
75
|
+
duration: reduceMotionEnabled
|
|
76
|
+
? Object.fromEntries(Object.keys(rnDuration).map((k) => [k, 0]))
|
|
77
|
+
: rnDuration,
|
|
78
|
+
easing: rnEasing,
|
|
79
|
+
transition: reduceMotionEnabled
|
|
80
|
+
? Object.fromEntries(
|
|
81
|
+
Object.entries(rnTransition).map(([k, v]) => [k, { ...v, duration: 0 }])
|
|
82
|
+
)
|
|
83
|
+
: rnTransition,
|
|
84
|
+
accessibility: rnAccessibility,
|
|
85
|
+
reduceMotionEnabled,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const ThemeContext = createContext<RNTheme | null>(null);
|
|
90
|
+
|
|
91
|
+
export interface ThemeProviderProps {
|
|
92
|
+
colorScheme?: 'light' | 'dark';
|
|
93
|
+
children: ReactNode;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function ThemeProvider({ colorScheme: colorSchemeProp, children }: ThemeProviderProps) {
|
|
97
|
+
const systemScheme = useColorScheme();
|
|
98
|
+
const effectiveScheme = colorSchemeProp ?? systemScheme ?? 'light';
|
|
99
|
+
const [reduceMotionEnabled, setReduceMotionEnabled] = useState(false);
|
|
100
|
+
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
AccessibilityInfo.isReduceMotionEnabled()
|
|
103
|
+
.then(setReduceMotionEnabled)
|
|
104
|
+
.catch(() => {});
|
|
105
|
+
|
|
106
|
+
const subscription = AccessibilityInfo.addEventListener(
|
|
107
|
+
'reduceMotionChanged',
|
|
108
|
+
setReduceMotionEnabled,
|
|
109
|
+
);
|
|
110
|
+
return () => subscription.remove();
|
|
111
|
+
}, []);
|
|
112
|
+
|
|
113
|
+
const theme = useMemo(
|
|
114
|
+
() => buildTheme(effectiveScheme, reduceMotionEnabled),
|
|
115
|
+
[effectiveScheme, reduceMotionEnabled],
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
return <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function useTheme(): RNTheme {
|
|
122
|
+
const theme = useContext(ThemeContext);
|
|
123
|
+
if (!theme) {
|
|
124
|
+
throw new Error('useTheme must be used within a ThemeProvider');
|
|
125
|
+
}
|
|
126
|
+
return theme;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export { buildTheme };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Module Exports
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Theme Provider & Hook
|
|
6
|
+
export { ThemeProvider, useTheme, buildTheme } from './ThemeProvider';
|
|
7
|
+
export type { ThemeProviderProps } from './ThemeProvider';
|
|
8
|
+
|
|
9
|
+
// Types
|
|
10
|
+
export type { RNTheme, RNThemeColors, RNThemeSemantic, RNTransitionPreset, RNAccessibility } from './types';
|
|
11
|
+
|
|
12
|
+
// Raw Tokens (for direct use without provider)
|
|
13
|
+
export {
|
|
14
|
+
rnColors,
|
|
15
|
+
rnSemantic,
|
|
16
|
+
rnSpacing,
|
|
17
|
+
rnSpacingNamed,
|
|
18
|
+
rnFontSize,
|
|
19
|
+
rnFontWeight,
|
|
20
|
+
rnLineHeight,
|
|
21
|
+
rnFontFamily,
|
|
22
|
+
rnRadius,
|
|
23
|
+
rnShadow,
|
|
24
|
+
rnDuration,
|
|
25
|
+
rnEasing,
|
|
26
|
+
rnTransition,
|
|
27
|
+
rnAccessibility,
|
|
28
|
+
} from './tokens';
|
|
29
|
+
export type { RNShadow } from './tokens';
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native Design Tokens
|
|
3
|
+
*
|
|
4
|
+
* Converts DTCG/CSS-based design tokens from @ggui-ai/design
|
|
5
|
+
* into React Native-compatible values (numbers, RN shadow format, etc.)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
colors,
|
|
10
|
+
semantic,
|
|
11
|
+
focusRing,
|
|
12
|
+
reducedMotion,
|
|
13
|
+
highContrast,
|
|
14
|
+
spacingValues,
|
|
15
|
+
nativeTokens,
|
|
16
|
+
} from '@ggui-ai/design/tokens';
|
|
17
|
+
import { Easing } from 'react-native';
|
|
18
|
+
|
|
19
|
+
// --- Colors (already plain hex strings, pass through) ---
|
|
20
|
+
|
|
21
|
+
export const rnColors = {
|
|
22
|
+
primary: colors.primary,
|
|
23
|
+
gray: colors.gray,
|
|
24
|
+
success: colors.success,
|
|
25
|
+
warning: colors.warning,
|
|
26
|
+
error: colors.error,
|
|
27
|
+
info: colors.info,
|
|
28
|
+
white: colors.white,
|
|
29
|
+
black: colors.black,
|
|
30
|
+
transparent: colors.transparent,
|
|
31
|
+
} as const;
|
|
32
|
+
|
|
33
|
+
export const rnSemantic = semantic;
|
|
34
|
+
|
|
35
|
+
// --- Spacing (numeric values for RN) ---
|
|
36
|
+
|
|
37
|
+
// Two-Layer Theming: spacing tokens are platform constants owned by
|
|
38
|
+
// `@ggui-ai/design` — re-exported here (NOT copied) so a scale change
|
|
39
|
+
// in the design package propagates to RN automatically.
|
|
40
|
+
export const rnSpacing = spacingValues;
|
|
41
|
+
|
|
42
|
+
// Named spacing aliases for ergonomic use — design's RN-numeric
|
|
43
|
+
// native token set is the single source.
|
|
44
|
+
export const rnSpacingNamed = nativeTokens.light.spacing;
|
|
45
|
+
|
|
46
|
+
// --- Typography (numeric values for RN) ---
|
|
47
|
+
|
|
48
|
+
export const rnFontSize = {
|
|
49
|
+
xs: 12,
|
|
50
|
+
sm: 14,
|
|
51
|
+
base: 16,
|
|
52
|
+
lg: 18,
|
|
53
|
+
xl: 20,
|
|
54
|
+
'2xl': 24,
|
|
55
|
+
'3xl': 30,
|
|
56
|
+
'4xl': 36,
|
|
57
|
+
'5xl': 48,
|
|
58
|
+
'6xl': 60,
|
|
59
|
+
} as const;
|
|
60
|
+
|
|
61
|
+
export const rnFontWeight = {
|
|
62
|
+
thin: '100' as const,
|
|
63
|
+
extralight: '200' as const,
|
|
64
|
+
light: '300' as const,
|
|
65
|
+
normal: '400' as const,
|
|
66
|
+
medium: '500' as const,
|
|
67
|
+
semibold: '600' as const,
|
|
68
|
+
bold: '700' as const,
|
|
69
|
+
extrabold: '800' as const,
|
|
70
|
+
black: '900' as const,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const rnLineHeight = {
|
|
74
|
+
none: 1,
|
|
75
|
+
tight: 1.25,
|
|
76
|
+
snug: 1.375,
|
|
77
|
+
normal: 1.5,
|
|
78
|
+
relaxed: 1.625,
|
|
79
|
+
loose: 2,
|
|
80
|
+
} as const;
|
|
81
|
+
|
|
82
|
+
// Platform font families (RN uses system fonts, not CSS font stacks)
|
|
83
|
+
export const rnFontFamily = {
|
|
84
|
+
sans: undefined, // Uses system default (San Francisco on iOS, Roboto on Android)
|
|
85
|
+
mono: 'monospace' as const, // Platform monospace
|
|
86
|
+
} as const;
|
|
87
|
+
|
|
88
|
+
// --- Border Radius (numeric values for RN) ---
|
|
89
|
+
|
|
90
|
+
export const rnRadius = {
|
|
91
|
+
none: 0,
|
|
92
|
+
sm: 4,
|
|
93
|
+
md: 6,
|
|
94
|
+
lg: 8,
|
|
95
|
+
xl: 12,
|
|
96
|
+
'2xl': 16,
|
|
97
|
+
'3xl': 24,
|
|
98
|
+
full: 9999,
|
|
99
|
+
} as const;
|
|
100
|
+
|
|
101
|
+
// --- Shadows (RN shadow format) ---
|
|
102
|
+
|
|
103
|
+
export interface RNShadow {
|
|
104
|
+
shadowColor: string;
|
|
105
|
+
shadowOffset: { width: number; height: number };
|
|
106
|
+
shadowOpacity: number;
|
|
107
|
+
shadowRadius: number;
|
|
108
|
+
elevation: number; // Android
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export const rnShadow: Record<string, RNShadow> = {
|
|
112
|
+
none: {
|
|
113
|
+
shadowColor: 'transparent',
|
|
114
|
+
shadowOffset: { width: 0, height: 0 },
|
|
115
|
+
shadowOpacity: 0,
|
|
116
|
+
shadowRadius: 0,
|
|
117
|
+
elevation: 0,
|
|
118
|
+
},
|
|
119
|
+
sm: {
|
|
120
|
+
shadowColor: '#000',
|
|
121
|
+
shadowOffset: { width: 0, height: 1 },
|
|
122
|
+
shadowOpacity: 0.05,
|
|
123
|
+
shadowRadius: 2,
|
|
124
|
+
elevation: 1,
|
|
125
|
+
},
|
|
126
|
+
md: {
|
|
127
|
+
shadowColor: '#000',
|
|
128
|
+
shadowOffset: { width: 0, height: 4 },
|
|
129
|
+
shadowOpacity: 0.1,
|
|
130
|
+
shadowRadius: 6,
|
|
131
|
+
elevation: 3,
|
|
132
|
+
},
|
|
133
|
+
lg: {
|
|
134
|
+
shadowColor: '#000',
|
|
135
|
+
shadowOffset: { width: 0, height: 10 },
|
|
136
|
+
shadowOpacity: 0.1,
|
|
137
|
+
shadowRadius: 15,
|
|
138
|
+
elevation: 6,
|
|
139
|
+
},
|
|
140
|
+
xl: {
|
|
141
|
+
shadowColor: '#000',
|
|
142
|
+
shadowOffset: { width: 0, height: 20 },
|
|
143
|
+
shadowOpacity: 0.1,
|
|
144
|
+
shadowRadius: 25,
|
|
145
|
+
elevation: 10,
|
|
146
|
+
},
|
|
147
|
+
'2xl': {
|
|
148
|
+
shadowColor: '#000',
|
|
149
|
+
shadowOffset: { width: 0, height: 25 },
|
|
150
|
+
shadowOpacity: 0.25,
|
|
151
|
+
shadowRadius: 50,
|
|
152
|
+
elevation: 15,
|
|
153
|
+
},
|
|
154
|
+
} as const;
|
|
155
|
+
|
|
156
|
+
// --- Duration (milliseconds for Animated.timing) ---
|
|
157
|
+
|
|
158
|
+
export const rnDuration = {
|
|
159
|
+
instant: 0,
|
|
160
|
+
fast: 100,
|
|
161
|
+
normal: 200,
|
|
162
|
+
slow: 300,
|
|
163
|
+
slower: 500,
|
|
164
|
+
} as const;
|
|
165
|
+
|
|
166
|
+
// --- Easing (RN Easing functions mapped to Material Design curves) ---
|
|
167
|
+
|
|
168
|
+
export const rnEasing = {
|
|
169
|
+
standard: Easing.bezier(0.4, 0, 0.2, 1),
|
|
170
|
+
decelerate: Easing.bezier(0, 0, 0.2, 1),
|
|
171
|
+
accelerate: Easing.bezier(0.4, 0, 1, 1),
|
|
172
|
+
linear: Easing.linear,
|
|
173
|
+
} as const;
|
|
174
|
+
|
|
175
|
+
// --- Transition presets (duration + easing combos for Animated.timing) ---
|
|
176
|
+
|
|
177
|
+
export const rnTransition = {
|
|
178
|
+
fast: { duration: 100, easing: rnEasing.standard },
|
|
179
|
+
normal: { duration: 200, easing: rnEasing.standard },
|
|
180
|
+
slow: { duration: 300, easing: rnEasing.standard },
|
|
181
|
+
transform: { duration: 200, easing: rnEasing.decelerate },
|
|
182
|
+
} as const;
|
|
183
|
+
|
|
184
|
+
// --- Accessibility (RN-compatible values from design package) ---
|
|
185
|
+
|
|
186
|
+
export const rnAccessibility = {
|
|
187
|
+
focusRing: {
|
|
188
|
+
color: focusRing.color,
|
|
189
|
+
width: parseFloat(focusRing.width),
|
|
190
|
+
offset: parseFloat(focusRing.offset),
|
|
191
|
+
},
|
|
192
|
+
reducedMotion: {
|
|
193
|
+
duration: parseInt(reducedMotion.duration, 10),
|
|
194
|
+
},
|
|
195
|
+
highContrast: {
|
|
196
|
+
borderWidth: parseFloat(highContrast.borderWidth),
|
|
197
|
+
textColor: highContrast.textColor,
|
|
198
|
+
backgroundColor: highContrast.backgroundColor,
|
|
199
|
+
linkColor: highContrast.linkColor,
|
|
200
|
+
},
|
|
201
|
+
} as const;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native Theme Types
|
|
3
|
+
*
|
|
4
|
+
* Typed theme interface for the RN design system.
|
|
5
|
+
* Mirrors the web DTCG theme structure but with RN-compatible values.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { RNShadow } from './tokens';
|
|
9
|
+
|
|
10
|
+
export interface RNThemeColors {
|
|
11
|
+
primary: Record<string, string>;
|
|
12
|
+
gray: Record<string, string>;
|
|
13
|
+
success: Record<string, string>;
|
|
14
|
+
warning: Record<string, string>;
|
|
15
|
+
error: Record<string, string>;
|
|
16
|
+
info: Record<string, string>;
|
|
17
|
+
white: string;
|
|
18
|
+
black: string;
|
|
19
|
+
transparent: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface RNThemeSemantic {
|
|
23
|
+
textPrimary: string;
|
|
24
|
+
textSecondary: string;
|
|
25
|
+
textMuted: string;
|
|
26
|
+
textInverse: string;
|
|
27
|
+
bgPrimary: string;
|
|
28
|
+
bgSecondary: string;
|
|
29
|
+
bgTertiary: string;
|
|
30
|
+
bgInverse: string;
|
|
31
|
+
borderLight: string;
|
|
32
|
+
borderDefault: string;
|
|
33
|
+
borderDark: string;
|
|
34
|
+
focus: string;
|
|
35
|
+
hover: string;
|
|
36
|
+
active: string;
|
|
37
|
+
disabled: string;
|
|
38
|
+
success: string;
|
|
39
|
+
warning: string;
|
|
40
|
+
error: string;
|
|
41
|
+
info: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface RNTransitionPreset {
|
|
45
|
+
duration: number;
|
|
46
|
+
easing: (t: number) => number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface RNAccessibility {
|
|
50
|
+
focusRing: {
|
|
51
|
+
color: string;
|
|
52
|
+
width: number;
|
|
53
|
+
offset: number;
|
|
54
|
+
};
|
|
55
|
+
reducedMotion: {
|
|
56
|
+
duration: number;
|
|
57
|
+
};
|
|
58
|
+
highContrast: {
|
|
59
|
+
borderWidth: number;
|
|
60
|
+
textColor: string;
|
|
61
|
+
backgroundColor: string;
|
|
62
|
+
linkColor: string;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface RNTheme {
|
|
67
|
+
colorScheme: 'light' | 'dark';
|
|
68
|
+
colors: RNThemeColors;
|
|
69
|
+
semantic: RNThemeSemantic;
|
|
70
|
+
spacing: Record<number, number>;
|
|
71
|
+
spacingNamed: {
|
|
72
|
+
xs: number;
|
|
73
|
+
sm: number;
|
|
74
|
+
md: number;
|
|
75
|
+
lg: number;
|
|
76
|
+
xl: number;
|
|
77
|
+
'2xl': number;
|
|
78
|
+
'3xl': number;
|
|
79
|
+
};
|
|
80
|
+
fontSize: Record<string, number>;
|
|
81
|
+
fontWeight: Record<string, string>;
|
|
82
|
+
lineHeight: Record<string, number>;
|
|
83
|
+
fontFamily: {
|
|
84
|
+
sans: string | undefined;
|
|
85
|
+
mono: string;
|
|
86
|
+
};
|
|
87
|
+
radius: Record<string, number>;
|
|
88
|
+
shadow: Record<string, RNShadow>;
|
|
89
|
+
duration: Record<string, number>;
|
|
90
|
+
easing: Record<string, (t: number) => number>;
|
|
91
|
+
transition: Record<string, RNTransitionPreset>;
|
|
92
|
+
accessibility: RNAccessibility;
|
|
93
|
+
reduceMotionEnabled: boolean;
|
|
94
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local ambient declarations for `react-test-renderer`.
|
|
3
|
+
*
|
|
4
|
+
* `react-test-renderer@19` does not ship its own types, and there is no
|
|
5
|
+
* matching `@types/react-test-renderer@19` on npm. We only need a tiny
|
|
6
|
+
* surface (`create`, `act`, `ReactTestRenderer.toJSON()`) for the SDK's
|
|
7
|
+
* test files — full fidelity is not required.
|
|
8
|
+
*/
|
|
9
|
+
declare module 'react-test-renderer' {
|
|
10
|
+
import type { ReactElement } from 'react';
|
|
11
|
+
|
|
12
|
+
export interface ReactTestRendererJSON {
|
|
13
|
+
type: string;
|
|
14
|
+
props: Record<string, unknown>;
|
|
15
|
+
children: null | Array<ReactTestRendererJSON | string>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ReactTestInstance {
|
|
19
|
+
instance: unknown;
|
|
20
|
+
type: string | { displayName?: string; name?: string };
|
|
21
|
+
props: Record<string, unknown>;
|
|
22
|
+
parent: ReactTestInstance | null;
|
|
23
|
+
children: Array<ReactTestInstance | string>;
|
|
24
|
+
find(predicate: (node: ReactTestInstance) => boolean): ReactTestInstance;
|
|
25
|
+
findAll(predicate: (node: ReactTestInstance) => boolean): ReactTestInstance[];
|
|
26
|
+
findByType(type: unknown): ReactTestInstance;
|
|
27
|
+
findAllByType(type: unknown): ReactTestInstance[];
|
|
28
|
+
findByProps(props: Record<string, unknown>): ReactTestInstance;
|
|
29
|
+
findAllByProps(props: Record<string, unknown>): ReactTestInstance[];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface ReactTestRenderer {
|
|
33
|
+
root: ReactTestInstance;
|
|
34
|
+
toJSON(): ReactTestRendererJSON | ReactTestRendererJSON[] | null;
|
|
35
|
+
toTree(): unknown;
|
|
36
|
+
update(element: ReactElement): void;
|
|
37
|
+
unmount(): void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface TestRendererOptions {
|
|
41
|
+
createNodeMock?: (element: ReactElement) => unknown;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function create(
|
|
45
|
+
element: ReactElement,
|
|
46
|
+
options?: TestRendererOptions,
|
|
47
|
+
): ReactTestRenderer;
|
|
48
|
+
|
|
49
|
+
export function act(callback: () => void | Promise<void>): Promise<void>;
|
|
50
|
+
}
|