@umituz/react-native-ai-generation-content 1.27.23 → 1.27.25

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.23",
3
+ "version": "1.27.25",
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",
@@ -12,7 +12,8 @@ export const IMAGE_TO_VIDEO_WIZARD_CONFIG: WizardFeatureConfig = {
12
12
  {
13
13
  id: "photo_1",
14
14
  type: "photo_upload",
15
- label: "Your Photo",
15
+ titleKey: "imageToVideo.selectPhoto",
16
+ subtitleKey: "imageToVideo.selectPhotoHint",
16
17
  showFaceDetection: false,
17
18
  showPhotoTips: true,
18
19
  required: true,
@@ -20,13 +21,15 @@ export const IMAGE_TO_VIDEO_WIZARD_CONFIG: WizardFeatureConfig = {
20
21
  {
21
22
  id: "motion_prompt",
22
23
  type: "text_input",
23
- required: false,
24
+ titleKey: "imageToVideo.motionPrompt",
24
25
  placeholderKey: "imageToVideo.motionPromptPlaceholder",
26
+ required: false,
25
27
  maxLength: 200,
26
28
  },
27
29
  {
28
30
  id: "duration",
29
31
  type: "selection",
32
+ titleKey: "generation.duration.title",
30
33
  selectionType: "duration",
31
34
  options: [
32
35
  { id: "5s", label: "5 seconds", value: 5 },
@@ -9,9 +9,9 @@ const promptStep: TextInputStepConfig = {
9
9
  id: "prompt",
10
10
  type: "text_input",
11
11
  required: true,
12
- titleKey: "text2image.wizard.prompt.title",
13
- subtitleKey: "text2image.wizard.prompt.subtitle",
14
- placeholderKey: "text2image.wizard.prompt.placeholder",
12
+ titleKey: "text2image.hero.title",
13
+ subtitleKey: "text2image.hero.subtitle",
14
+ placeholderKey: "text2image.prompt.placeholder",
15
15
  minLength: 3,
16
16
  maxLength: 1000,
17
17
  multiline: true,
@@ -13,7 +13,9 @@ export const TEXT_TO_VIDEO_WIZARD_CONFIG: WizardFeatureConfig = {
13
13
  id: "prompt",
14
14
  type: "text_input",
15
15
  required: true,
16
- placeholderKey: "textToVideo.promptPlaceholder",
16
+ titleKey: "textToVideo.hero.title",
17
+ subtitleKey: "textToVideo.hero.subtitle",
18
+ placeholderKey: "textToVideo.prompt.placeholder",
17
19
  minLength: 3,
18
20
  maxLength: 500,
19
21
  multiline: true,
@@ -21,6 +23,7 @@ export const TEXT_TO_VIDEO_WIZARD_CONFIG: WizardFeatureConfig = {
21
23
  {
22
24
  id: "duration",
23
25
  type: "selection",
26
+ titleKey: "generation.duration.title",
24
27
  selectionType: "duration",
25
28
  options: [
26
29
  { id: "5s", label: "5 seconds", value: 5 },
@@ -0,0 +1,96 @@
1
+ /**
2
+ * WizardHeader Component
3
+ * Header with back button on left, action button on right
4
+ */
5
+
6
+ import React from "react";
7
+ import { View, TouchableOpacity, StyleSheet } from "react-native";
8
+ import {
9
+ AtomicText,
10
+ AtomicIcon,
11
+ useAppDesignTokens,
12
+ } from "@umituz/react-native-design-system";
13
+
14
+ export interface WizardHeaderProps {
15
+ readonly onBack: () => void;
16
+ readonly onAction?: () => void;
17
+ readonly backLabel?: string;
18
+ readonly actionLabel?: string;
19
+ readonly isActionDisabled?: boolean;
20
+ readonly showAction?: boolean;
21
+ }
22
+
23
+ export const WizardHeader: React.FC<WizardHeaderProps> = ({
24
+ onBack,
25
+ onAction,
26
+ backLabel,
27
+ actionLabel,
28
+ isActionDisabled = false,
29
+ showAction = true,
30
+ }) => {
31
+ const tokens = useAppDesignTokens();
32
+
33
+ return (
34
+ <View style={[styles.container, { paddingHorizontal: tokens.spacing.md }]}>
35
+ <TouchableOpacity onPress={onBack} style={styles.backButton}>
36
+ <AtomicIcon name="chevron-left" size="md" color="textPrimary" />
37
+ {backLabel ? (
38
+ <AtomicText type="bodyMedium" color="textPrimary">
39
+ {backLabel}
40
+ </AtomicText>
41
+ ) : null}
42
+ </TouchableOpacity>
43
+
44
+ {showAction && actionLabel ? (
45
+ <TouchableOpacity
46
+ onPress={onAction}
47
+ disabled={isActionDisabled}
48
+ style={[
49
+ styles.actionButton,
50
+ {
51
+ backgroundColor: isActionDisabled
52
+ ? tokens.colors.surfaceSecondary
53
+ : tokens.colors.primary,
54
+ borderRadius: tokens.radius.md,
55
+ },
56
+ ]}
57
+ >
58
+ <AtomicText
59
+ type="labelLarge"
60
+ style={{
61
+ color: isActionDisabled
62
+ ? tokens.colors.textSecondary
63
+ : tokens.colors.textInverse,
64
+ fontWeight: "600",
65
+ }}
66
+ >
67
+ {actionLabel}
68
+ </AtomicText>
69
+ </TouchableOpacity>
70
+ ) : (
71
+ <View style={styles.placeholder} />
72
+ )}
73
+ </View>
74
+ );
75
+ };
76
+
77
+ const styles = StyleSheet.create({
78
+ container: {
79
+ flexDirection: "row",
80
+ justifyContent: "space-between",
81
+ alignItems: "center",
82
+ paddingVertical: 12,
83
+ },
84
+ backButton: {
85
+ flexDirection: "row",
86
+ alignItems: "center",
87
+ gap: 4,
88
+ },
89
+ actionButton: {
90
+ paddingHorizontal: 16,
91
+ paddingVertical: 8,
92
+ },
93
+ placeholder: {
94
+ width: 80,
95
+ },
96
+ });
@@ -1,17 +1,17 @@
1
1
  /**
2
2
  * TextInputScreen
3
3
  * Generic text input step for wizard flows
4
+ * Header: Back on left, Continue on right
4
5
  */
5
6
 
6
7
  import React, { useState, useCallback } from "react";
7
- import { View, ScrollView, TextInput } from "react-native";
8
+ import { View, ScrollView, TextInput, TouchableOpacity, StyleSheet } from "react-native";
8
9
  import {
9
10
  AtomicText,
10
11
  AtomicButton,
11
12
  AtomicIcon,
12
13
  useAppDesignTokens,
13
14
  } from "@umituz/react-native-design-system";
14
- import { styles } from "./TextInputScreen.styles";
15
15
  import type { TextInputScreenProps } from "./TextInputScreen.types";
16
16
 
17
17
  export type {
@@ -48,17 +48,33 @@ export const TextInputScreen: React.FC<TextInputScreenProps> = ({
48
48
 
49
49
  return (
50
50
  <View style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }]}>
51
+ {/* Header with Back on left, Continue on right */}
51
52
  <View style={[styles.header, { paddingHorizontal: tokens.spacing.md }]}>
52
- <AtomicButton variant="text" size="sm" onPress={onBack}>
53
- <View style={styles.backButtonContent}>
54
- <AtomicIcon name="arrow-back" size="sm" color="textPrimary" />
55
- {translations.backButton ? (
56
- <AtomicText type="labelMedium" color="textPrimary" style={styles.backButtonText}>
57
- {translations.backButton}
58
- </AtomicText>
59
- ) : null}
60
- </View>
61
- </AtomicButton>
53
+ <TouchableOpacity onPress={onBack} style={styles.backButton}>
54
+ <AtomicIcon name="chevron-left" size="md" color="textPrimary" />
55
+ </TouchableOpacity>
56
+
57
+ <TouchableOpacity
58
+ onPress={handleContinue}
59
+ disabled={!canContinue}
60
+ style={[
61
+ styles.continueButton,
62
+ {
63
+ backgroundColor: canContinue ? tokens.colors.primary : tokens.colors.surfaceSecondary,
64
+ borderRadius: tokens.radius.md,
65
+ },
66
+ ]}
67
+ >
68
+ <AtomicText
69
+ type="labelLarge"
70
+ style={{
71
+ color: canContinue ? tokens.colors.textInverse : tokens.colors.textSecondary,
72
+ fontWeight: "600",
73
+ }}
74
+ >
75
+ {translations.continueButton}
76
+ </AtomicText>
77
+ </TouchableOpacity>
62
78
  </View>
63
79
 
64
80
  <ScrollView
@@ -120,12 +136,45 @@ export const TextInputScreen: React.FC<TextInputScreenProps> = ({
120
136
  </View>
121
137
  ) : null}
122
138
  </ScrollView>
123
-
124
- <View style={[styles.footer, { padding: tokens.spacing.md }]}>
125
- <AtomicButton variant="primary" size="lg" onPress={handleContinue} disabled={!canContinue} style={styles.continueButton}>
126
- {translations.continueButton}
127
- </AtomicButton>
128
- </View>
129
139
  </View>
130
140
  );
131
141
  };
142
+
143
+ const styles = StyleSheet.create({
144
+ container: {
145
+ flex: 1,
146
+ },
147
+ header: {
148
+ flexDirection: "row",
149
+ justifyContent: "space-between",
150
+ alignItems: "center",
151
+ paddingVertical: 12,
152
+ },
153
+ backButton: {
154
+ flexDirection: "row",
155
+ alignItems: "center",
156
+ gap: 4,
157
+ },
158
+ continueButton: {
159
+ paddingHorizontal: 16,
160
+ paddingVertical: 8,
161
+ },
162
+ scrollView: {
163
+ flex: 1,
164
+ },
165
+ title: {
166
+ marginBottom: 8,
167
+ },
168
+ inputContainer: {
169
+ borderWidth: 1,
170
+ padding: 12,
171
+ },
172
+ textInput: {
173
+ fontSize: 16,
174
+ lineHeight: 22,
175
+ },
176
+ charCount: {
177
+ textAlign: "right",
178
+ marginTop: 8,
179
+ },
180
+ });
@@ -0,0 +1,26 @@
1
+ /**
2
+ * TextToImageWizardFlow Types
3
+ */
4
+
5
+ import type { AlertMessages } from "../../../../presentation/hooks/generation/types";
6
+
7
+ export interface TextToImageWizardFlowProps {
8
+ readonly model: string;
9
+ readonly userId?: string;
10
+ readonly isAuthenticated: boolean;
11
+ readonly hasPremium: boolean;
12
+ readonly creditBalance: number;
13
+ readonly isCreditsLoaded: boolean;
14
+ readonly onShowAuthModal: (callback: () => void) => void;
15
+ readonly onShowPaywall: () => void;
16
+ readonly onGenerationComplete?: () => void;
17
+ readonly onGenerationError?: (error: string) => void;
18
+ readonly onBack: () => void;
19
+ readonly t: (key: string) => string;
20
+ readonly alertMessages?: AlertMessages;
21
+ }
22
+
23
+ export interface TextToImageFormState {
24
+ prompt: string;
25
+ selectedStyle: string;
26
+ }
package/src/index.ts CHANGED
@@ -152,3 +152,11 @@ export * from "./domains/generation";
152
152
  export * from "./features/text-to-image";
153
153
  export * from "./features/text-to-video";
154
154
  export * from "./features/image-to-video";
155
+
156
+ // Wizard Flows - Direct exports
157
+ export { TextToImageWizardFlow } from "./features/text-to-image/presentation/screens/TextToImageWizardFlow";
158
+ export type { TextToImageWizardFlowProps } from "./features/text-to-image/presentation/screens/TextToImageWizardFlow";
159
+ export { TextToVideoWizardFlow } from "./features/text-to-video/presentation/screens/TextToVideoWizardFlow";
160
+ export type { TextToVideoWizardFlowProps } from "./features/text-to-video/presentation/screens/TextToVideoWizardFlow";
161
+ export { ImageToVideoWizardFlow } from "./features/image-to-video/presentation/screens/ImageToVideoWizardFlow";
162
+ export type { ImageToVideoWizardFlowProps } from "./features/image-to-video/presentation/screens/ImageToVideoWizardFlow";
@@ -1,48 +0,0 @@
1
- /**
2
- * TextInputScreen 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
- inputContainer: {
30
- borderWidth: 1,
31
- padding: 12,
32
- },
33
- textInput: {
34
- fontSize: 16,
35
- lineHeight: 24,
36
- },
37
- charCount: {
38
- textAlign: "right",
39
- marginTop: 4,
40
- },
41
- footer: {
42
- borderTopWidth: 1,
43
- borderTopColor: "rgba(0,0,0,0.1)",
44
- },
45
- continueButton: {
46
- width: "100%",
47
- },
48
- });