@umituz/react-native-ai-generation-content 1.27.26 → 1.27.27
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.27.
|
|
3
|
+
"version": "1.27.27",
|
|
4
4
|
"description": "Provider-agnostic AI generation orchestration for React Native with result preview components",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SelectionScreen
|
|
3
3
|
* Generic selection step for wizard flows (duration, style, etc.)
|
|
4
|
+
* Uses design system: NavigationHeader + ScreenLayout
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
|
-
import React, { useState, useCallback } from "react";
|
|
7
|
-
import { View,
|
|
7
|
+
import React, { useState, useCallback, useMemo } from "react";
|
|
8
|
+
import { View, TouchableOpacity, StyleSheet } from "react-native";
|
|
8
9
|
import {
|
|
9
10
|
AtomicText,
|
|
10
|
-
AtomicButton,
|
|
11
11
|
AtomicIcon,
|
|
12
12
|
useAppDesignTokens,
|
|
13
|
+
ScreenLayout,
|
|
14
|
+
NavigationHeader,
|
|
15
|
+
type DesignTokens,
|
|
13
16
|
} from "@umituz/react-native-design-system";
|
|
14
|
-
import { styles } from "./SelectionScreen.styles";
|
|
15
17
|
import type { SelectionScreenProps } from "./SelectionScreen.types";
|
|
16
18
|
|
|
17
19
|
export type {
|
|
@@ -78,28 +80,55 @@ export const SelectionScreen: React.FC<SelectionScreenProps> = ({
|
|
|
78
80
|
[isMultiSelect, selected],
|
|
79
81
|
);
|
|
80
82
|
|
|
81
|
-
|
|
82
|
-
<View style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }]}>
|
|
83
|
-
<View style={[styles.header, { paddingHorizontal: tokens.spacing.md }]}>
|
|
84
|
-
<AtomicButton variant="text" size="sm" onPress={onBack}>
|
|
85
|
-
<View style={styles.backButtonContent}>
|
|
86
|
-
<AtomicIcon name="arrow-back" size="sm" color="textPrimary" />
|
|
87
|
-
{translations.backButton ? (
|
|
88
|
-
<AtomicText type="labelMedium" color="textPrimary" style={styles.backButtonText}>
|
|
89
|
-
{translations.backButton}
|
|
90
|
-
</AtomicText>
|
|
91
|
-
) : null}
|
|
92
|
-
</View>
|
|
93
|
-
</AtomicButton>
|
|
94
|
-
</View>
|
|
83
|
+
const styles = useMemo(() => createStyles(tokens), [tokens]);
|
|
95
84
|
|
|
96
|
-
|
|
85
|
+
return (
|
|
86
|
+
<View style={{ flex: 1, backgroundColor: tokens.colors.backgroundPrimary }}>
|
|
87
|
+
<NavigationHeader
|
|
88
|
+
title=""
|
|
89
|
+
onBackPress={onBack}
|
|
90
|
+
rightElement={
|
|
91
|
+
<TouchableOpacity
|
|
92
|
+
onPress={handleContinue}
|
|
93
|
+
activeOpacity={0.7}
|
|
94
|
+
disabled={!canContinue}
|
|
95
|
+
style={[
|
|
96
|
+
styles.continueButton,
|
|
97
|
+
{
|
|
98
|
+
backgroundColor: canContinue ? tokens.colors.primary : tokens.colors.surfaceVariant,
|
|
99
|
+
opacity: canContinue ? 1 : 0.5,
|
|
100
|
+
},
|
|
101
|
+
]}
|
|
102
|
+
>
|
|
103
|
+
<AtomicText
|
|
104
|
+
type="bodyMedium"
|
|
105
|
+
style={[
|
|
106
|
+
styles.continueText,
|
|
107
|
+
{ color: canContinue ? tokens.colors.onPrimary : tokens.colors.textSecondary },
|
|
108
|
+
]}
|
|
109
|
+
>
|
|
110
|
+
{translations.continueButton}
|
|
111
|
+
</AtomicText>
|
|
112
|
+
<AtomicIcon
|
|
113
|
+
name="arrow-forward"
|
|
114
|
+
size="sm"
|
|
115
|
+
color={canContinue ? "onPrimary" : "textSecondary"}
|
|
116
|
+
/>
|
|
117
|
+
</TouchableOpacity>
|
|
118
|
+
}
|
|
119
|
+
/>
|
|
120
|
+
<ScreenLayout
|
|
121
|
+
scrollable={true}
|
|
122
|
+
edges={["left", "right"]}
|
|
123
|
+
hideScrollIndicator={true}
|
|
124
|
+
contentContainerStyle={styles.scrollContent}
|
|
125
|
+
>
|
|
97
126
|
<AtomicText type="headlineMedium" color="textPrimary" style={styles.title}>
|
|
98
127
|
{translations.title}
|
|
99
128
|
</AtomicText>
|
|
100
129
|
|
|
101
130
|
{translations.subtitle ? (
|
|
102
|
-
<AtomicText type="bodyMedium" color="textSecondary" style={
|
|
131
|
+
<AtomicText type="bodyMedium" color="textSecondary" style={styles.subtitle}>
|
|
103
132
|
{translations.subtitle}
|
|
104
133
|
</AtomicText>
|
|
105
134
|
) : null}
|
|
@@ -115,7 +144,6 @@ export const SelectionScreen: React.FC<SelectionScreenProps> = ({
|
|
|
115
144
|
{
|
|
116
145
|
backgroundColor: isSelected ? tokens.colors.primaryContainer : tokens.colors.backgroundSecondary,
|
|
117
146
|
borderColor: isSelected ? tokens.colors.primary : tokens.colors.border,
|
|
118
|
-
borderRadius: tokens.borders.radius.md,
|
|
119
147
|
},
|
|
120
148
|
]}
|
|
121
149
|
onPress={() => handleSelect(option.id)}
|
|
@@ -136,13 +164,61 @@ export const SelectionScreen: React.FC<SelectionScreenProps> = ({
|
|
|
136
164
|
);
|
|
137
165
|
})}
|
|
138
166
|
</View>
|
|
139
|
-
</
|
|
140
|
-
|
|
141
|
-
<View style={[styles.footer, { padding: tokens.spacing.md }]}>
|
|
142
|
-
<AtomicButton variant="primary" size="lg" onPress={handleContinue} disabled={!canContinue} style={styles.continueButton}>
|
|
143
|
-
{translations.continueButton}
|
|
144
|
-
</AtomicButton>
|
|
145
|
-
</View>
|
|
167
|
+
</ScreenLayout>
|
|
146
168
|
</View>
|
|
147
169
|
);
|
|
148
170
|
};
|
|
171
|
+
|
|
172
|
+
const createStyles = (tokens: DesignTokens) =>
|
|
173
|
+
StyleSheet.create({
|
|
174
|
+
scrollContent: {
|
|
175
|
+
paddingHorizontal: tokens.spacing.lg,
|
|
176
|
+
paddingBottom: 40,
|
|
177
|
+
},
|
|
178
|
+
title: {
|
|
179
|
+
marginBottom: tokens.spacing.sm,
|
|
180
|
+
},
|
|
181
|
+
subtitle: {
|
|
182
|
+
marginBottom: tokens.spacing.lg,
|
|
183
|
+
},
|
|
184
|
+
optionsGrid: {
|
|
185
|
+
flexDirection: "row",
|
|
186
|
+
flexWrap: "wrap",
|
|
187
|
+
gap: tokens.spacing.sm,
|
|
188
|
+
},
|
|
189
|
+
optionCard: {
|
|
190
|
+
flex: 1,
|
|
191
|
+
minWidth: "45%",
|
|
192
|
+
padding: tokens.spacing.md,
|
|
193
|
+
borderWidth: 2,
|
|
194
|
+
borderRadius: tokens.borders.radius.md,
|
|
195
|
+
alignItems: "center",
|
|
196
|
+
justifyContent: "center",
|
|
197
|
+
gap: tokens.spacing.xs,
|
|
198
|
+
position: "relative",
|
|
199
|
+
},
|
|
200
|
+
optionLabel: {
|
|
201
|
+
textAlign: "center",
|
|
202
|
+
},
|
|
203
|
+
checkmark: {
|
|
204
|
+
position: "absolute",
|
|
205
|
+
top: tokens.spacing.xs,
|
|
206
|
+
right: tokens.spacing.xs,
|
|
207
|
+
width: 20,
|
|
208
|
+
height: 20,
|
|
209
|
+
borderRadius: 10,
|
|
210
|
+
alignItems: "center",
|
|
211
|
+
justifyContent: "center",
|
|
212
|
+
},
|
|
213
|
+
continueButton: {
|
|
214
|
+
flexDirection: "row",
|
|
215
|
+
alignItems: "center",
|
|
216
|
+
paddingHorizontal: tokens.spacing.md,
|
|
217
|
+
paddingVertical: tokens.spacing.xs,
|
|
218
|
+
borderRadius: tokens.borders.radius.full,
|
|
219
|
+
},
|
|
220
|
+
continueText: {
|
|
221
|
+
fontWeight: "800",
|
|
222
|
+
marginRight: 4,
|
|
223
|
+
},
|
|
224
|
+
});
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* TextInputScreen
|
|
3
3
|
* Generic text input step for wizard flows
|
|
4
|
-
*
|
|
4
|
+
* Uses design system: NavigationHeader + ScreenLayout
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import React, { useState, useCallback } from "react";
|
|
8
|
-
import { View,
|
|
7
|
+
import React, { useState, useCallback, useMemo } from "react";
|
|
8
|
+
import { View, TextInput, TouchableOpacity, StyleSheet } from "react-native";
|
|
9
9
|
import {
|
|
10
10
|
AtomicText,
|
|
11
11
|
AtomicButton,
|
|
12
12
|
AtomicIcon,
|
|
13
13
|
useAppDesignTokens,
|
|
14
|
+
ScreenLayout,
|
|
15
|
+
NavigationHeader,
|
|
16
|
+
type DesignTokens,
|
|
14
17
|
} from "@umituz/react-native-design-system";
|
|
15
18
|
import type { TextInputScreenProps } from "./TextInputScreen.types";
|
|
16
19
|
|
|
@@ -46,64 +49,63 @@ export const TextInputScreen: React.FC<TextInputScreenProps> = ({
|
|
|
46
49
|
setText(example);
|
|
47
50
|
}, []);
|
|
48
51
|
|
|
49
|
-
|
|
50
|
-
<View style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }]}>
|
|
51
|
-
{/* Header with Back on left, Continue on right */}
|
|
52
|
-
<View style={[styles.header, { paddingHorizontal: tokens.spacing.md }]}>
|
|
53
|
-
<TouchableOpacity onPress={onBack} style={styles.backButton}>
|
|
54
|
-
<AtomicIcon name="chevron-left" size="md" color="textPrimary" />
|
|
55
|
-
</TouchableOpacity>
|
|
52
|
+
const styles = useMemo(() => createStyles(tokens), [tokens]);
|
|
56
53
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
54
|
+
return (
|
|
55
|
+
<View style={{ flex: 1, backgroundColor: tokens.colors.backgroundPrimary }}>
|
|
56
|
+
<NavigationHeader
|
|
57
|
+
title=""
|
|
58
|
+
onBackPress={onBack}
|
|
59
|
+
rightElement={
|
|
60
|
+
<TouchableOpacity
|
|
61
|
+
onPress={handleContinue}
|
|
62
|
+
activeOpacity={0.7}
|
|
63
|
+
disabled={!canContinue}
|
|
64
|
+
style={[
|
|
65
|
+
styles.continueButton,
|
|
66
|
+
{
|
|
67
|
+
backgroundColor: canContinue ? tokens.colors.primary : tokens.colors.surfaceVariant,
|
|
68
|
+
opacity: canContinue ? 1 : 0.5,
|
|
69
|
+
},
|
|
70
|
+
]}
|
|
74
71
|
>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
72
|
+
<AtomicText
|
|
73
|
+
type="bodyMedium"
|
|
74
|
+
style={[
|
|
75
|
+
styles.continueText,
|
|
76
|
+
{ color: canContinue ? tokens.colors.onPrimary : tokens.colors.textSecondary },
|
|
77
|
+
]}
|
|
78
|
+
>
|
|
79
|
+
{translations.continueButton}
|
|
80
|
+
</AtomicText>
|
|
81
|
+
<AtomicIcon
|
|
82
|
+
name="arrow-forward"
|
|
83
|
+
size="sm"
|
|
84
|
+
color={canContinue ? "onPrimary" : "textSecondary"}
|
|
85
|
+
/>
|
|
86
|
+
</TouchableOpacity>
|
|
87
|
+
}
|
|
88
|
+
/>
|
|
89
|
+
<ScreenLayout
|
|
90
|
+
scrollable={true}
|
|
91
|
+
edges={["left", "right"]}
|
|
92
|
+
hideScrollIndicator={true}
|
|
93
|
+
keyboardAvoiding={true}
|
|
94
|
+
contentContainerStyle={styles.scrollContent}
|
|
84
95
|
>
|
|
85
96
|
<AtomicText type="headlineMedium" color="textPrimary" style={styles.title}>
|
|
86
97
|
{translations.title}
|
|
87
98
|
</AtomicText>
|
|
88
99
|
|
|
89
100
|
{translations.subtitle ? (
|
|
90
|
-
<AtomicText type="bodyMedium" color="textSecondary" style={
|
|
101
|
+
<AtomicText type="bodyMedium" color="textSecondary" style={styles.subtitle}>
|
|
91
102
|
{translations.subtitle}
|
|
92
103
|
</AtomicText>
|
|
93
104
|
) : null}
|
|
94
105
|
|
|
95
|
-
<View
|
|
96
|
-
style={[
|
|
97
|
-
styles.inputContainer,
|
|
98
|
-
{
|
|
99
|
-
backgroundColor: tokens.colors.backgroundSecondary,
|
|
100
|
-
borderRadius: tokens.borders.radius.md,
|
|
101
|
-
borderColor: tokens.colors.border,
|
|
102
|
-
},
|
|
103
|
-
]}
|
|
104
|
-
>
|
|
106
|
+
<View style={styles.inputContainer}>
|
|
105
107
|
<TextInput
|
|
106
|
-
style={[styles.textInput, {
|
|
108
|
+
style={[styles.textInput, { minHeight: config?.multiline ? 120 : 48 }]}
|
|
107
109
|
placeholder={translations.placeholder}
|
|
108
110
|
placeholderTextColor={tokens.colors.textTertiary}
|
|
109
111
|
value={text}
|
|
@@ -118,8 +120,8 @@ export const TextInputScreen: React.FC<TextInputScreenProps> = ({
|
|
|
118
120
|
</View>
|
|
119
121
|
|
|
120
122
|
{examplePrompts.length > 0 && translations.examplesTitle ? (
|
|
121
|
-
<View style={
|
|
122
|
-
<AtomicText type="labelLarge" color="textSecondary" style={
|
|
123
|
+
<View style={styles.examplesSection}>
|
|
124
|
+
<AtomicText type="labelLarge" color="textSecondary" style={styles.examplesTitle}>
|
|
123
125
|
{translations.examplesTitle}
|
|
124
126
|
</AtomicText>
|
|
125
127
|
{examplePrompts.slice(0, 4).map((example, index) => (
|
|
@@ -128,53 +130,64 @@ export const TextInputScreen: React.FC<TextInputScreenProps> = ({
|
|
|
128
130
|
variant="outline"
|
|
129
131
|
size="sm"
|
|
130
132
|
onPress={() => handleExampleSelect(example)}
|
|
131
|
-
style={
|
|
133
|
+
style={styles.exampleButton}
|
|
132
134
|
>
|
|
133
135
|
{example.length > 50 ? `${example.slice(0, 50)}...` : example}
|
|
134
136
|
</AtomicButton>
|
|
135
137
|
))}
|
|
136
138
|
</View>
|
|
137
139
|
) : null}
|
|
138
|
-
</
|
|
140
|
+
</ScreenLayout>
|
|
139
141
|
</View>
|
|
140
142
|
);
|
|
141
143
|
};
|
|
142
144
|
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
145
|
+
const createStyles = (tokens: DesignTokens) =>
|
|
146
|
+
StyleSheet.create({
|
|
147
|
+
scrollContent: {
|
|
148
|
+
paddingHorizontal: tokens.spacing.lg,
|
|
149
|
+
paddingBottom: 40,
|
|
150
|
+
},
|
|
151
|
+
title: {
|
|
152
|
+
marginBottom: tokens.spacing.sm,
|
|
153
|
+
},
|
|
154
|
+
subtitle: {
|
|
155
|
+
marginBottom: tokens.spacing.lg,
|
|
156
|
+
},
|
|
157
|
+
inputContainer: {
|
|
158
|
+
backgroundColor: tokens.colors.backgroundSecondary,
|
|
159
|
+
borderRadius: tokens.borders.radius.md,
|
|
160
|
+
borderWidth: 1,
|
|
161
|
+
borderColor: tokens.colors.border,
|
|
162
|
+
padding: tokens.spacing.md,
|
|
163
|
+
},
|
|
164
|
+
textInput: {
|
|
165
|
+
fontSize: 16,
|
|
166
|
+
lineHeight: 22,
|
|
167
|
+
color: tokens.colors.textPrimary,
|
|
168
|
+
},
|
|
169
|
+
charCount: {
|
|
170
|
+
textAlign: "right",
|
|
171
|
+
marginTop: tokens.spacing.sm,
|
|
172
|
+
},
|
|
173
|
+
examplesSection: {
|
|
174
|
+
marginTop: tokens.spacing.lg,
|
|
175
|
+
},
|
|
176
|
+
examplesTitle: {
|
|
177
|
+
marginBottom: tokens.spacing.sm,
|
|
178
|
+
},
|
|
179
|
+
exampleButton: {
|
|
180
|
+
marginBottom: tokens.spacing.xs,
|
|
181
|
+
},
|
|
182
|
+
continueButton: {
|
|
183
|
+
flexDirection: "row",
|
|
184
|
+
alignItems: "center",
|
|
185
|
+
paddingHorizontal: tokens.spacing.md,
|
|
186
|
+
paddingVertical: tokens.spacing.xs,
|
|
187
|
+
borderRadius: tokens.borders.radius.full,
|
|
188
|
+
},
|
|
189
|
+
continueText: {
|
|
190
|
+
fontWeight: "800",
|
|
191
|
+
marginRight: 4,
|
|
192
|
+
},
|
|
193
|
+
});
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SelectionScreen Styles
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { StyleSheet } from "react-native";
|
|
6
|
-
|
|
7
|
-
export const styles = StyleSheet.create({
|
|
8
|
-
container: {
|
|
9
|
-
flex: 1,
|
|
10
|
-
},
|
|
11
|
-
header: {
|
|
12
|
-
flexDirection: "row",
|
|
13
|
-
alignItems: "center",
|
|
14
|
-
paddingVertical: 8,
|
|
15
|
-
},
|
|
16
|
-
backButtonContent: {
|
|
17
|
-
flexDirection: "row",
|
|
18
|
-
alignItems: "center",
|
|
19
|
-
},
|
|
20
|
-
backButtonText: {
|
|
21
|
-
marginLeft: 4,
|
|
22
|
-
},
|
|
23
|
-
scrollView: {
|
|
24
|
-
flex: 1,
|
|
25
|
-
},
|
|
26
|
-
title: {
|
|
27
|
-
marginBottom: 8,
|
|
28
|
-
},
|
|
29
|
-
optionsGrid: {
|
|
30
|
-
flexDirection: "row",
|
|
31
|
-
flexWrap: "wrap",
|
|
32
|
-
gap: 12,
|
|
33
|
-
},
|
|
34
|
-
optionCard: {
|
|
35
|
-
flex: 1,
|
|
36
|
-
minWidth: "45%",
|
|
37
|
-
padding: 16,
|
|
38
|
-
borderWidth: 2,
|
|
39
|
-
alignItems: "center",
|
|
40
|
-
position: "relative",
|
|
41
|
-
},
|
|
42
|
-
optionLabel: {
|
|
43
|
-
marginTop: 8,
|
|
44
|
-
textAlign: "center",
|
|
45
|
-
},
|
|
46
|
-
checkmark: {
|
|
47
|
-
position: "absolute",
|
|
48
|
-
top: 8,
|
|
49
|
-
right: 8,
|
|
50
|
-
width: 20,
|
|
51
|
-
height: 20,
|
|
52
|
-
borderRadius: 10,
|
|
53
|
-
alignItems: "center",
|
|
54
|
-
justifyContent: "center",
|
|
55
|
-
},
|
|
56
|
-
footer: {
|
|
57
|
-
borderTopWidth: 1,
|
|
58
|
-
borderTopColor: "rgba(0,0,0,0.1)",
|
|
59
|
-
},
|
|
60
|
-
continueButton: {
|
|
61
|
-
width: "100%",
|
|
62
|
-
},
|
|
63
|
-
});
|