@umituz/react-native-ai-generation-content 1.17.46 → 1.17.48

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.
Files changed (25) hide show
  1. package/package.json +1 -1
  2. package/src/features/image-to-video/presentation/components/index.ts +3 -3
  3. package/src/features/text-to-image/presentation/components/index.ts +15 -29
  4. package/src/features/text-to-voice/presentation/components/index.ts +5 -5
  5. package/src/index.ts +4 -0
  6. package/src/presentation/components/PromptInput.tsx +41 -13
  7. package/src/presentation/components/buttons/GenerateButton.tsx +93 -42
  8. package/src/presentation/components/index.ts +10 -0
  9. package/src/{features/text-to-image/presentation/components → presentation/components/modals}/SettingsSheet.tsx +10 -8
  10. package/src/presentation/components/selectors/AspectRatioSelector.tsx +2 -2
  11. package/src/presentation/components/selectors/GridSelector.tsx +5 -3
  12. package/src/features/image-to-video/presentation/components/GenerateButton.tsx +0 -95
  13. package/src/features/text-to-image/presentation/components/AspectRatioSelector.tsx +0 -98
  14. package/src/features/text-to-image/presentation/components/ExamplePrompts.tsx +0 -88
  15. package/src/features/text-to-image/presentation/components/ImageSizeSelector.tsx +0 -98
  16. package/src/features/text-to-image/presentation/components/NumImagesSelector.tsx +0 -93
  17. package/src/features/text-to-image/presentation/components/OutputFormatSelector.tsx +0 -98
  18. package/src/features/text-to-image/presentation/components/StyleSelector.tsx +0 -110
  19. package/src/features/text-to-image/presentation/components/TextToImageGenerateButton.tsx +0 -84
  20. package/src/features/text-to-image/presentation/components/TextToImagePromptInput.tsx +0 -90
  21. package/src/features/text-to-voice/presentation/components/TextToVoiceErrorMessage.tsx +0 -57
  22. package/src/features/text-to-voice/presentation/components/TextToVoiceExamplePrompts.tsx +0 -77
  23. package/src/features/text-to-voice/presentation/components/TextToVoiceGenerateButton.tsx +0 -87
  24. package/src/features/text-to-voice/presentation/components/TextToVoiceOptionalInput.tsx +0 -73
  25. package/src/features/text-to-voice/presentation/components/TextToVoiceTextInput.tsx +0 -85
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-ai-generation-content",
3
- "version": "1.17.46",
3
+ "version": "1.17.48",
4
4
  "description": "Provider-agnostic AI generation orchestration for React Native",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -25,6 +25,6 @@ export type {
25
25
  // export { HeroSection as ImageToVideoHeroSection } from "./HeroSection";
26
26
  // export type { HeroSectionProps as ImageToVideoHeroSectionProps } from "./HeroSection";
27
27
 
28
- // Generate Button
29
- export { GenerateButton as ImageToVideoGenerateButton } from "./GenerateButton";
30
- export type { GenerateButtonProps as ImageToVideoGenerateButtonProps } from "./GenerateButton";
28
+ // Action Components
29
+ export { GenerateButton as ImageToVideoGenerateButton } from "../../../presentation/components/buttons/GenerateButton";
30
+ export type { GenerateButtonProps as ImageToVideoGenerateButtonProps } from "../../../presentation/components/buttons/GenerateButton";
@@ -4,41 +4,27 @@
4
4
  */
5
5
 
6
6
  // Input Components
7
- export { TextToImagePromptInput } from "./TextToImagePromptInput";
8
- export type { TextToImagePromptInputProps } from "./TextToImagePromptInput";
7
+ export { PromptInput as TextToImagePromptInput } from "../../../presentation/components/PromptInput";
8
+ export type { PromptInputProps as TextToImagePromptInputProps } from "../../../presentation/components/PromptInput";
9
9
 
10
- export { ExamplePrompts as TextToImageExamplePrompts } from "./ExamplePrompts";
11
- export type { ExamplePromptsProps as TextToImageExamplePromptsProps } from "./ExamplePrompts";
10
+ export { ExamplePrompts as TextToImageExamplePrompts } from "../../../presentation/components/prompts/ExamplePrompts";
11
+ export type { ExamplePromptsProps as TextToImageExamplePromptsProps } from "../../../presentation/components/prompts/ExamplePrompts";
12
12
 
13
13
  // Selector Components
14
- export { NumImagesSelector as TextToImageNumImagesSelector } from "./NumImagesSelector";
15
- export type { NumImagesSelectorProps as TextToImageNumImagesSelectorProps } from "./NumImagesSelector";
14
+ export { StyleSelector as TextToImageStyleSelector } from "../../../presentation/components/selectors/StyleSelector";
15
+ export type { StyleSelectorProps as TextToImageStyleSelectorProps } from "../../../presentation/components/selectors/StyleSelector";
16
16
 
17
- export { StyleSelector as TextToImageStyleSelector } from "./StyleSelector";
18
- export type { StyleSelectorProps as TextToImageStyleSelectorProps } from "./StyleSelector";
17
+ export { AspectRatioSelector as TextToImageAspectRatioSelector } from "../../../presentation/components/selectors/AspectRatioSelector";
18
+ export type { AspectRatioSelectorProps as TextToImageAspectRatioSelectorProps } from "../../../presentation/components/selectors/AspectRatioSelector";
19
19
 
20
- export { AspectRatioSelector as TextToImageAspectRatioSelector } from "./AspectRatioSelector";
21
- export type {
22
- AspectRatioSelectorProps as TextToImageAspectRatioSelectorProps,
23
- AspectRatioOption as TextToImageAspectRatioOption,
24
- } from "./AspectRatioSelector";
25
-
26
- export { ImageSizeSelector as TextToImageSizeSelector } from "./ImageSizeSelector";
27
- export type {
28
- ImageSizeSelectorProps as TextToImageSizeSelectorProps,
29
- ImageSizeOption as TextToImageSizeOption,
30
- } from "./ImageSizeSelector";
31
-
32
- export { OutputFormatSelector as TextToImageOutputFormatSelector } from "./OutputFormatSelector";
33
- export type {
34
- OutputFormatSelectorProps as TextToImageOutputFormatSelectorProps,
35
- OutputFormatOption as TextToImageOutputFormatOption,
36
- } from "./OutputFormatSelector";
20
+ export { GridSelector as TextToImageSizeSelector } from "../../../presentation/components/selectors/GridSelector";
21
+ export { GridSelector as TextToImageOutputFormatSelector } from "../../../presentation/components/selectors/GridSelector";
22
+ export { GridSelector as TextToImageNumImagesSelector } from "../../../presentation/components/selectors/GridSelector";
37
23
 
38
24
  // Action Components
39
- export { TextToImageGenerateButton } from "./TextToImageGenerateButton";
40
- export type { TextToImageGenerateButtonProps } from "./TextToImageGenerateButton";
25
+ export { GenerateButton as TextToImageGenerateButton } from "../../../presentation/components/buttons/GenerateButton";
26
+ export type { GenerateButtonProps as TextToImageGenerateButtonProps } from "../../../presentation/components/buttons/GenerateButton";
41
27
 
42
28
  // Sheet Components
43
- export { SettingsSheet as TextToImageSettingsSheet } from "./SettingsSheet";
44
- export type { SettingsSheetProps as TextToImageSettingsSheetProps } from "./SettingsSheet";
29
+ export { SettingsSheet as TextToImageSettingsSheet } from "../../../presentation/components/modals/SettingsSheet";
30
+ export type { SettingsSheetProps as TextToImageSettingsSheetProps } from "../../../presentation/components/modals/SettingsSheet";
@@ -1,7 +1,7 @@
1
- export { TextToVoiceTextInput } from "./TextToVoiceTextInput";
2
- export { TextToVoiceOptionalInput } from "./TextToVoiceOptionalInput";
3
- export { TextToVoiceExamplePrompts } from "./TextToVoiceExamplePrompts";
4
- export { TextToVoiceGenerateButton } from "./TextToVoiceGenerateButton";
1
+ export { PromptInput as TextToVoiceTextInput } from "../../../presentation/components/PromptInput";
2
+ export { PromptInput as TextToVoiceOptionalInput } from "../../../presentation/components/PromptInput";
3
+ export { ExamplePrompts as TextToVoiceExamplePrompts } from "../../../presentation/components/prompts/ExamplePrompts";
4
+ export { GenerateButton as TextToVoiceGenerateButton } from "../../../presentation/components/buttons/GenerateButton";
5
+ export { ErrorDisplay as TextToVoiceErrorMessage } from "../../../presentation/components/display/ErrorDisplay";
5
6
  export { TextToVoiceAudioPlayer } from "./TextToVoiceAudioPlayer";
6
- export { TextToVoiceErrorMessage } from "./TextToVoiceErrorMessage";
7
7
  // TextToVoiceHeader removed in favor of common AIGenerationHero
package/src/index.ts CHANGED
@@ -295,6 +295,8 @@ export {
295
295
 
296
296
  // Photo Upload
297
297
  PhotoUploadCard,
298
+ // Modals
299
+ SettingsSheet,
298
300
  // Selectors
299
301
  StyleSelector,
300
302
  AspectRatioSelector,
@@ -351,6 +353,8 @@ export type {
351
353
  // Photo Upload
352
354
  PhotoUploadCardProps,
353
355
  PhotoUploadCardConfig,
356
+ // Modals
357
+ SettingsSheetProps,
354
358
  // Selectors
355
359
  StyleSelectorProps,
356
360
  AspectRatioSelectorProps,
@@ -18,7 +18,11 @@ export interface PromptInputProps {
18
18
  readonly placeholder?: string;
19
19
  readonly minHeight?: number;
20
20
  readonly maxLines?: number;
21
+ readonly maxLength?: number;
21
22
  readonly isDisabled?: boolean;
23
+ readonly showCharacterCount?: boolean;
24
+ readonly characterCountLabel?: string;
25
+ readonly style?: any;
22
26
  }
23
27
 
24
28
  export const PromptInput: React.FC<PromptInputProps> = ({
@@ -28,20 +32,34 @@ export const PromptInput: React.FC<PromptInputProps> = ({
28
32
  placeholder,
29
33
  minHeight = 120,
30
34
  maxLines = 6,
35
+ maxLength = 500,
31
36
  isDisabled = false,
37
+ showCharacterCount = false,
38
+ characterCountLabel,
39
+ style,
32
40
  }) => {
33
41
  const tokens = useAppDesignTokens();
34
42
 
35
43
  return (
36
- <View style={styles.container}>
37
- {title && (
38
- <AtomicText
39
- type="bodyMedium"
40
- style={[styles.label, { color: tokens.colors.textPrimary }]}
41
- >
42
- {title}
43
- </AtomicText>
44
- )}
44
+ <View style={[styles.container, style]}>
45
+ <View style={styles.header}>
46
+ {title && (
47
+ <AtomicText
48
+ type="bodyMedium"
49
+ style={[styles.label, { color: tokens.colors.textPrimary }]}
50
+ >
51
+ {title}
52
+ </AtomicText>
53
+ )}
54
+ {showCharacterCount && (
55
+ <AtomicText
56
+ type="labelSmall"
57
+ style={[styles.count, { color: tokens.colors.textSecondary }]}
58
+ >
59
+ {characterCountLabel ?? `${value.length}/${maxLength}`}
60
+ </AtomicText>
61
+ )}
62
+ </View>
45
63
  <TextInput
46
64
  style={[
47
65
  styles.input,
@@ -57,8 +75,8 @@ export const PromptInput: React.FC<PromptInputProps> = ({
57
75
  value={value}
58
76
  onChangeText={onChangeText}
59
77
  multiline
60
- numberOfLines={4}
61
- maxLength={500}
78
+ numberOfLines={maxLines}
79
+ maxLength={maxLength}
62
80
  textAlignVertical="top"
63
81
  editable={!isDisabled}
64
82
  />
@@ -68,14 +86,24 @@ export const PromptInput: React.FC<PromptInputProps> = ({
68
86
 
69
87
  const styles = StyleSheet.create({
70
88
  container: {
71
- padding: 16,
89
+ paddingVertical: 16,
72
90
  width: "100%",
73
91
  },
92
+ header: {
93
+ flexDirection: "row",
94
+ justifyContent: "space-between",
95
+ alignItems: "center",
96
+ marginBottom: 8,
97
+ paddingHorizontal: 16,
98
+ },
74
99
  label: {
75
100
  fontWeight: "600",
76
- marginBottom: 8,
101
+ },
102
+ count: {
103
+ opacity: 0.8,
77
104
  },
78
105
  input: {
106
+ marginHorizontal: 16,
79
107
  borderWidth: 1,
80
108
  borderRadius: 12,
81
109
  padding: 16,
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import React from "react";
8
- import { View, StyleSheet, TouchableOpacity } from "react-native";
8
+ import { View, StyleSheet, TouchableOpacity, ActivityIndicator } from "react-native";
9
9
  import {
10
10
  AtomicText,
11
11
  useAppDesignTokens,
@@ -23,6 +23,10 @@ export interface GenerateButtonProps {
23
23
  readonly gradientColors?: readonly [string, string, ...string[]];
24
24
  readonly icon?: string;
25
25
  readonly iconSize?: number;
26
+ readonly costLabel?: string;
27
+ readonly accessoryRight?: React.ReactNode;
28
+ readonly onAccessoryRightPress?: () => void;
29
+ readonly style?: any;
26
30
  }
27
31
 
28
32
  export const GenerateButton: React.FC<GenerateButtonProps> = ({
@@ -35,60 +39,94 @@ export const GenerateButton: React.FC<GenerateButtonProps> = ({
35
39
  gradientColors = ["#FF6B9D", "#C74375", "#FF6B9D"],
36
40
  icon = "sparkles",
37
41
  iconSize = 24,
42
+ costLabel,
43
+ accessoryRight,
44
+ onAccessoryRightPress,
45
+ style,
38
46
  }) => {
39
47
  const tokens = useAppDesignTokens();
40
48
  const disabled = isDisabled || isProcessing;
41
49
  const displayText = isProcessing && processingText ? processingText : text;
50
+ const finalDisplayText = costLabel ? `${displayText} (${costLabel})` : displayText;
42
51
 
43
52
  if (variant === "solid") {
44
53
  return (
45
- <View style={[styles.solidContainer, { marginTop: tokens.spacing.xl }]}>
46
- <TouchableOpacity
47
- onPress={onPress}
48
- disabled={disabled}
49
- activeOpacity={0.8}
50
- style={[
51
- styles.solidButton,
52
- {
53
- backgroundColor: disabled
54
- ? tokens.colors.surfaceSecondary
55
- : tokens.colors.primary,
56
- },
57
- ]}
58
- >
59
- <View style={styles.buttonContent}>
60
- <AtomicIcon name={icon} customSize={20} customColor="#FFFFFF" />
61
- <AtomicText type="bodyLarge" style={styles.solidButtonText}>
62
- {displayText}
63
- </AtomicText>
64
- </View>
65
- </TouchableOpacity>
54
+ <View style={[styles.solidContainer, { marginTop: tokens.spacing.xl }, style]}>
55
+ <View style={styles.row}>
56
+ <TouchableOpacity
57
+ onPress={onPress}
58
+ disabled={disabled}
59
+ activeOpacity={0.8}
60
+ style={[
61
+ styles.solidButton,
62
+ {
63
+ backgroundColor: disabled
64
+ ? tokens.colors.surfaceSecondary
65
+ : tokens.colors.primary,
66
+ flex: 1,
67
+ },
68
+ ]}
69
+ >
70
+ <View style={styles.buttonContent}>
71
+ {isProcessing ? (
72
+ <ActivityIndicator color="#FFFFFF" size="small" />
73
+ ) : (
74
+ <AtomicIcon name={icon} customSize={20} customColor="#FFFFFF" />
75
+ )}
76
+ <AtomicText type="bodyLarge" style={styles.solidButtonText}>
77
+ {finalDisplayText}
78
+ </AtomicText>
79
+ </View>
80
+ </TouchableOpacity>
81
+ {accessoryRight && (
82
+ <TouchableOpacity
83
+ onPress={onAccessoryRightPress}
84
+ style={[styles.accessory, { backgroundColor: tokens.colors.surfaceSecondary }]}
85
+ >
86
+ {accessoryRight}
87
+ </TouchableOpacity>
88
+ )}
89
+ </View>
66
90
  </View>
67
91
  );
68
92
  }
69
93
 
70
94
  return (
71
- <View style={[styles.gradientContainer, { marginTop: tokens.spacing.xl }]}>
72
- <TouchableOpacity
73
- onPress={onPress}
74
- disabled={disabled}
75
- activeOpacity={0.85}
76
- style={styles.buttonWrapper}
77
- >
78
- <LinearGradient
79
- colors={disabled ? ["#9CA3AF", "#6B7280"] : gradientColors}
80
- start={[0, 0]}
81
- end={[1, 0]}
82
- style={[styles.gradientButton, disabled && styles.disabledButton]}
95
+ <View style={[styles.gradientContainer, { marginTop: tokens.spacing.xl }, style]}>
96
+ <View style={styles.row}>
97
+ <TouchableOpacity
98
+ onPress={onPress}
99
+ disabled={disabled}
100
+ activeOpacity={0.85}
101
+ style={[styles.buttonWrapper, accessoryRight && { flex: 1 }]}
83
102
  >
84
- <View style={styles.buttonContent}>
85
- <AtomicIcon name={icon} customSize={iconSize} customColor="#FFF" />
86
- <AtomicText type="bodyLarge" style={styles.gradientButtonText}>
87
- {displayText}
88
- </AtomicText>
89
- </View>
90
- </LinearGradient>
91
- </TouchableOpacity>
103
+ <LinearGradient
104
+ colors={disabled ? ["#9CA3AF", "#6B7280"] : gradientColors}
105
+ start={[0, 0]}
106
+ end={[1, 0]}
107
+ style={[styles.gradientButton, disabled && styles.disabledButton]}
108
+ >
109
+ <View style={styles.buttonContent}>
110
+ {isProcessing ? (
111
+ <ActivityIndicator color="#FFFFFF" size="small" />
112
+ ) : (
113
+ <AtomicIcon name={icon} customSize={iconSize} customColor="#FFF" />
114
+ )}
115
+ <AtomicText type="bodyLarge" style={styles.gradientButtonText}>
116
+ {finalDisplayText}
117
+ </AtomicText>
118
+ </View>
119
+ </LinearGradient>
120
+ </TouchableOpacity>
121
+ {accessoryRight && (
122
+ <TouchableOpacity
123
+ onPress={onAccessoryRightPress}
124
+ style={[styles.accessory, { backgroundColor: tokens.colors.surface, height: 56, width: 56 }]}
125
+ >
126
+ {accessoryRight}
127
+ </TouchableOpacity>
128
+ )}
129
+ </View>
92
130
  </View>
93
131
  );
94
132
  };
@@ -129,6 +167,19 @@ const styles = StyleSheet.create({
129
167
  justifyContent: "center",
130
168
  gap: 12,
131
169
  },
170
+ row: {
171
+ flexDirection: "row",
172
+ alignItems: "center",
173
+ gap: 12,
174
+ width: "100%",
175
+ },
176
+ accessory: {
177
+ width: 60,
178
+ height: 60,
179
+ borderRadius: 16,
180
+ alignItems: "center",
181
+ justifyContent: "center",
182
+ },
132
183
  gradientButtonText: {
133
184
  color: "#FFFFFF",
134
185
  fontWeight: "700",
@@ -30,6 +30,16 @@ export type { AIGenerationHeroProps } from "./AIGenerationHero";
30
30
 
31
31
  export * from "./result";
32
32
  export * from "./photo-step";
33
+ export * from "./modals/SettingsSheet";
34
+ export * from "./selectors/AspectRatioSelector";
35
+ export * from "./selectors/DurationSelector";
36
+ export * from "./selectors/GridSelector";
37
+ export * from "./selectors/StyleSelector";
38
+ export * from "./selectors/factories";
39
+ export * from "./selectors/types";
40
+ export * from "./PromptInput";
41
+ export * from "./ExamplePrompts";
42
+ export * from "./ModerationSummary";
33
43
  export * from "./image-picker";
34
44
  export * from "./buttons";
35
45
  export * from "./display";
@@ -1,6 +1,7 @@
1
1
  /**
2
- * Settings Sheet Component
3
- * Modal sheet for advanced image generation settings
2
+ * SettingsSheet Component
3
+ * Generic modal bottom sheet for settings or options
4
+ * Props-driven for 100+ apps compatibility
4
5
  */
5
6
 
6
7
  import React from "react";
@@ -20,11 +21,11 @@ import {
20
21
  } from "@umituz/react-native-design-system";
21
22
 
22
23
  export interface SettingsSheetProps {
23
- visible: boolean;
24
- onClose: () => void;
25
- title: string;
26
- doneLabel: string;
27
- children: React.ReactNode;
24
+ readonly visible: boolean;
25
+ readonly onClose: () => void;
26
+ readonly title: string;
27
+ readonly doneLabel: string;
28
+ readonly children: React.ReactNode;
28
29
  }
29
30
 
30
31
  export const SettingsSheet: React.FC<SettingsSheetProps> = ({
@@ -129,11 +130,12 @@ const styles = StyleSheet.create({
129
130
  },
130
131
  doneButton: {
131
132
  paddingHorizontal: 0,
133
+ backgroundColor: "transparent",
132
134
  },
133
135
  doneText: {
134
136
  fontWeight: "600",
135
137
  },
136
138
  content: {
137
- padding: 20,
139
+ paddingHorizontal: 4,
138
140
  },
139
141
  });
@@ -14,8 +14,8 @@ import type { AspectRatioOption } from "./types";
14
14
 
15
15
  export interface AspectRatioSelectorProps {
16
16
  ratios: AspectRatioOption[];
17
- selectedRatio: "16:9" | "9:16" | "1:1";
18
- onRatioSelect: (ratio: "16:9" | "9:16" | "1:1") => void;
17
+ selectedRatio: string;
18
+ onRatioSelect: (ratio: string) => void;
19
19
  title: string;
20
20
  }
21
21
 
@@ -19,6 +19,7 @@ export interface GridSelectorProps<T> {
19
19
  readonly title?: string;
20
20
  readonly columns?: number;
21
21
  readonly disabled?: boolean;
22
+ readonly style?: any;
22
23
  }
23
24
 
24
25
  export function GridSelector<T>({
@@ -26,12 +27,14 @@ export function GridSelector<T>({
26
27
  selectedValue,
27
28
  onSelect,
28
29
  title,
30
+ columns = 2,
29
31
  disabled = false,
32
+ style,
30
33
  }: GridSelectorProps<T>): JSX.Element {
31
34
  const tokens = useAppDesignTokens();
32
35
 
33
36
  return (
34
- <View style={styles.section}>
37
+ <View style={[styles.section, style]}>
35
38
  {title && (
36
39
  <AtomicText
37
40
  type="bodyMedium"
@@ -53,6 +56,7 @@ export function GridSelector<T>({
53
56
  style={[
54
57
  styles.card,
55
58
  {
59
+ width: `${100 / columns - 4}%`,
56
60
  backgroundColor: isSelected
57
61
  ? tokens.colors.primary + "15"
58
62
  : tokens.colors.surface,
@@ -111,8 +115,6 @@ const styles = StyleSheet.create({
111
115
  gap: 12,
112
116
  },
113
117
  card: {
114
- flex: 1,
115
- minWidth: "45%",
116
118
  padding: 12,
117
119
  borderRadius: 12,
118
120
  borderWidth: 2,
@@ -1,95 +0,0 @@
1
- /**
2
- * Generate Button Component
3
- * Generic generate button with loading state
4
- */
5
-
6
- import React from "react";
7
- import { View, TouchableOpacity, ActivityIndicator, StyleSheet } from "react-native";
8
- import {
9
- AtomicText,
10
- AtomicIcon,
11
- useAppDesignTokens,
12
- } from "@umituz/react-native-design-system";
13
-
14
- export interface GenerateButtonProps {
15
- onPress: () => void;
16
- isGenerating: boolean;
17
- isDisabled?: boolean;
18
- buttonText: string;
19
- generatingText: string;
20
- }
21
-
22
- export const GenerateButton: React.FC<GenerateButtonProps> = ({
23
- onPress,
24
- isGenerating,
25
- isDisabled = false,
26
- buttonText,
27
- generatingText,
28
- }) => {
29
- const tokens = useAppDesignTokens();
30
- const disabled = isGenerating || isDisabled;
31
-
32
- return (
33
- <View style={componentStyles.container}>
34
- <TouchableOpacity
35
- style={[
36
- componentStyles.button,
37
- {
38
- backgroundColor: disabled
39
- ? tokens.colors.primary + "60"
40
- : tokens.colors.primary,
41
- },
42
- ]}
43
- onPress={onPress}
44
- disabled={disabled}
45
- activeOpacity={0.8}
46
- >
47
- {isGenerating ? (
48
- <>
49
- <ActivityIndicator
50
- size="small"
51
- color={tokens.colors.textInverse}
52
- style={componentStyles.loader}
53
- />
54
- <AtomicText
55
- type="bodyMedium"
56
- style={[componentStyles.text, { color: tokens.colors.textInverse }]}
57
- >
58
- {generatingText}
59
- </AtomicText>
60
- </>
61
- ) : (
62
- <>
63
- <AtomicIcon name="videocam-outline" size="md" color="onSurface" />
64
- <AtomicText
65
- type="bodyMedium"
66
- style={[componentStyles.text, { color: tokens.colors.textInverse }]}
67
- >
68
- {buttonText}
69
- </AtomicText>
70
- </>
71
- )}
72
- </TouchableOpacity>
73
- </View>
74
- );
75
- };
76
-
77
- const componentStyles = StyleSheet.create({
78
- container: {
79
- padding: 16,
80
- },
81
- button: {
82
- flexDirection: "row",
83
- alignItems: "center",
84
- justifyContent: "center",
85
- paddingVertical: 16,
86
- borderRadius: 16,
87
- },
88
- loader: {
89
- marginRight: 8,
90
- },
91
- text: {
92
- fontWeight: "600",
93
- marginLeft: 8,
94
- },
95
- });