@umituz/react-native-ai-generation-content 1.17.42 → 1.17.43

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.17.42",
3
+ "version": "1.17.43",
4
4
  "description": "Provider-agnostic AI generation orchestration for React Native",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
package/src/index.ts CHANGED
@@ -289,13 +289,17 @@ export {
289
289
  ErrorDisplay,
290
290
  // Headers
291
291
  FeatureHeader,
292
+ AIGenScreenHeader,
293
+
292
294
  // Photo Upload
293
295
  PhotoUploadCard,
294
296
  // Selectors
295
297
  StyleSelector,
296
298
  AspectRatioSelector,
297
299
  DurationSelector,
300
+ GridSelector,
298
301
  StylePresetsGrid,
302
+
299
303
  } from "./presentation/components";
300
304
 
301
305
  export type {
@@ -337,6 +341,9 @@ export type {
337
341
  ErrorDisplayProps,
338
342
  // Headers
339
343
  FeatureHeaderProps,
344
+ AIGenScreenHeaderProps,
345
+ NavigationButtonType,
346
+
340
347
  // Photo Upload
341
348
  PhotoUploadCardProps,
342
349
  PhotoUploadCardConfig,
@@ -344,6 +351,9 @@ export type {
344
351
  StyleSelectorProps,
345
352
  AspectRatioSelectorProps,
346
353
  DurationSelectorProps,
354
+ GridSelectorProps,
355
+ GridSelectorOption,
356
+
347
357
  StyleOption,
348
358
  AspectRatioOption,
349
359
  DurationValue,
@@ -0,0 +1,127 @@
1
+ import React, { ReactNode } from "react";
2
+ import { View, TouchableOpacity, StyleSheet } from "react-native";
3
+ import {
4
+ AtomicText,
5
+ AtomicIcon,
6
+ useAppDesignTokens,
7
+ } from "@umituz/react-native-design-system";
8
+
9
+ export type NavigationButtonType = "back" | "close";
10
+
11
+ export interface AIGenScreenHeaderProps {
12
+ readonly title: string;
13
+ readonly description?: string;
14
+ readonly navigationType?: NavigationButtonType;
15
+ readonly onNavigationPress: () => void;
16
+ readonly headerContent?: ReactNode;
17
+ readonly rightContent?: ReactNode;
18
+ readonly titleType?: "headlineLarge" | "titleLarge";
19
+ readonly showDescription?: boolean;
20
+ }
21
+
22
+ export const AIGenScreenHeader: React.FC<AIGenScreenHeaderProps> = ({
23
+ title,
24
+ description,
25
+ navigationType = "back",
26
+ onNavigationPress,
27
+ headerContent,
28
+ rightContent,
29
+ titleType = "titleLarge",
30
+ showDescription = !!description,
31
+ }) => {
32
+ const tokens = useAppDesignTokens();
33
+
34
+ const isCloseButton = navigationType === "close";
35
+ const buttonStyle = isCloseButton
36
+ ? [
37
+ styles.navigationButton,
38
+ styles.closeButton,
39
+ {
40
+ backgroundColor: tokens.colors.surface,
41
+ borderColor: tokens.colors.borderLight,
42
+ },
43
+ ]
44
+ : [styles.navigationButton, styles.backButton];
45
+
46
+ const iconName = isCloseButton ? "close-circle" : "chevron-back";
47
+ const iconColor = isCloseButton ? "secondary" : "primary";
48
+
49
+ return (
50
+ <View style={styles.header}>
51
+ <View style={styles.headerTop}>
52
+ <View style={styles.leftContainer}>
53
+ <TouchableOpacity
54
+ onPress={onNavigationPress}
55
+ style={buttonStyle}
56
+ hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
57
+ >
58
+ <AtomicIcon name={iconName} size="md" color={iconColor} />
59
+ </TouchableOpacity>
60
+ <AtomicText
61
+ type={titleType}
62
+ style={{
63
+ color: tokens.colors.textPrimary,
64
+ fontWeight: "700",
65
+ marginLeft: navigationType === "back" ? 8 : 0,
66
+ }}
67
+ >
68
+ {title}
69
+ </AtomicText>
70
+ </View>
71
+ <View style={styles.headerActions}>{rightContent}</View>
72
+ </View>
73
+ {showDescription && description && (
74
+ <AtomicText
75
+ type="bodyMedium"
76
+ style={[
77
+ styles.description,
78
+ { color: tokens.colors.textSecondary, marginTop: 8 },
79
+ ]}
80
+ >
81
+ {description}
82
+ </AtomicText>
83
+ )}
84
+ {headerContent && <View style={styles.headerContent}>{headerContent}</View>}
85
+ </View>
86
+ );
87
+ };
88
+
89
+ const styles = StyleSheet.create({
90
+ header: {
91
+ padding: 16,
92
+ paddingTop: 60,
93
+ width: "100%",
94
+ },
95
+ headerTop: {
96
+ flexDirection: "row",
97
+ alignItems: "center",
98
+ justifyContent: "space-between",
99
+ },
100
+ leftContainer: {
101
+ flexDirection: "row",
102
+ alignItems: "center",
103
+ flex: 1,
104
+ },
105
+ headerActions: {
106
+ flexDirection: "row",
107
+ alignItems: "center",
108
+ gap: 12,
109
+ },
110
+ navigationButton: {
111
+ width: 40,
112
+ height: 40,
113
+ alignItems: "center",
114
+ justifyContent: "center",
115
+ },
116
+ backButton: {},
117
+ closeButton: {
118
+ borderRadius: 20,
119
+ borderWidth: 1,
120
+ },
121
+ description: {
122
+ lineHeight: 20,
123
+ },
124
+ headerContent: {
125
+ marginTop: 16,
126
+ },
127
+ });
@@ -1 +1,2 @@
1
- export { FeatureHeader, type FeatureHeaderProps } from "./FeatureHeader";
1
+ export * from "./FeatureHeader";
2
+ export * from "./AIGenScreenHeader";
@@ -0,0 +1,130 @@
1
+ import React from "react";
2
+ import { View, TouchableOpacity, StyleSheet } from "react-native";
3
+ import {
4
+ AtomicText,
5
+ useAppDesignTokens,
6
+ } from "@umituz/react-native-design-system";
7
+
8
+ export interface GridSelectorOption<T> {
9
+ readonly value: T;
10
+ readonly label: string;
11
+ readonly description?: string;
12
+ readonly emoji?: string;
13
+ }
14
+
15
+ export interface GridSelectorProps<T> {
16
+ readonly options: readonly GridSelectorOption<T>[];
17
+ readonly selectedValue: T;
18
+ readonly onSelect: (value: T) => void;
19
+ readonly title?: string;
20
+ readonly columns?: number;
21
+ readonly disabled?: boolean;
22
+ }
23
+
24
+ export function GridSelector<T>({
25
+ options,
26
+ selectedValue,
27
+ onSelect,
28
+ title,
29
+ disabled = false,
30
+ }: GridSelectorProps<T>): JSX.Element {
31
+ const tokens = useAppDesignTokens();
32
+
33
+ return (
34
+ <View style={styles.section}>
35
+ {title && (
36
+ <AtomicText
37
+ type="bodyMedium"
38
+ style={{
39
+ color: tokens.colors.textPrimary,
40
+ fontWeight: "600",
41
+ marginBottom: 12,
42
+ }}
43
+ >
44
+ {title}
45
+ </AtomicText>
46
+ )}
47
+ <View style={styles.grid}>
48
+ {options.map((option, index) => {
49
+ const isSelected = selectedValue === option.value;
50
+ return (
51
+ <TouchableOpacity
52
+ key={index}
53
+ style={[
54
+ styles.card,
55
+ {
56
+ backgroundColor: isSelected
57
+ ? tokens.colors.primary + "15"
58
+ : tokens.colors.surface,
59
+ borderColor: isSelected
60
+ ? tokens.colors.primary
61
+ : tokens.colors.borderLight,
62
+ },
63
+ ]}
64
+ onPress={() => onSelect(option.value)}
65
+ disabled={disabled}
66
+ >
67
+ <View style={styles.cardContent}>
68
+ {option.emoji && (
69
+ <AtomicText style={styles.emoji}>{option.emoji}</AtomicText>
70
+ )}
71
+ <AtomicText
72
+ type="bodySmall"
73
+ style={{
74
+ color: tokens.colors.textPrimary,
75
+ fontWeight: isSelected ? "600" : "400",
76
+ textAlign: "center",
77
+ }}
78
+ >
79
+ {option.label}
80
+ </AtomicText>
81
+ {option.description && (
82
+ <AtomicText
83
+ type="labelSmall"
84
+ style={{
85
+ color: tokens.colors.textSecondary,
86
+ marginTop: 4,
87
+ textAlign: "center",
88
+ fontSize: 10,
89
+ }}
90
+ >
91
+ {option.description}
92
+ </AtomicText>
93
+ )}
94
+ </View>
95
+ </TouchableOpacity>
96
+ );
97
+ })}
98
+ </View>
99
+ </View>
100
+ );
101
+ }
102
+
103
+ const styles = StyleSheet.create({
104
+ section: {
105
+ padding: 16,
106
+ width: "100%",
107
+ },
108
+ grid: {
109
+ flexDirection: "row",
110
+ flexWrap: "wrap",
111
+ gap: 12,
112
+ },
113
+ card: {
114
+ flex: 1,
115
+ minWidth: "45%",
116
+ padding: 12,
117
+ borderRadius: 12,
118
+ borderWidth: 2,
119
+ alignItems: "center",
120
+ justifyContent: "center",
121
+ },
122
+ cardContent: {
123
+ alignItems: "center",
124
+ justifyContent: "center",
125
+ },
126
+ emoji: {
127
+ fontSize: 24,
128
+ marginBottom: 4,
129
+ },
130
+ });
@@ -6,6 +6,7 @@
6
6
  export { StyleSelector } from "./StyleSelector";
7
7
  export { AspectRatioSelector } from "./AspectRatioSelector";
8
8
  export { DurationSelector } from "./DurationSelector";
9
+ export { GridSelector, type GridSelectorProps, type GridSelectorOption } from "./GridSelector";
9
10
 
10
11
  export type { StyleSelectorProps } from "./StyleSelector";
11
12
  export type { AspectRatioSelectorProps } from "./AspectRatioSelector";