@umituz/react-native-ai-generation-content 1.17.42 → 1.17.44
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 +1 -1
- package/src/index.ts +10 -0
- package/src/presentation/components/headers/AIGenScreenHeader.tsx +131 -0
- package/src/presentation/components/headers/index.ts +2 -1
- package/src/presentation/components/selectors/GridSelector.tsx +130 -0
- package/src/presentation/components/selectors/index.ts +1 -0
package/package.json
CHANGED
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,131 @@
|
|
|
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 = "headlineLarge",
|
|
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.titleContainer}>
|
|
53
|
+
<AtomicText
|
|
54
|
+
type={titleType}
|
|
55
|
+
style={{
|
|
56
|
+
color: tokens.colors.textPrimary,
|
|
57
|
+
fontWeight: "700",
|
|
58
|
+
}}
|
|
59
|
+
>
|
|
60
|
+
{title}
|
|
61
|
+
</AtomicText>
|
|
62
|
+
</View>
|
|
63
|
+
<View style={styles.headerActions}>
|
|
64
|
+
{rightContent}
|
|
65
|
+
<TouchableOpacity
|
|
66
|
+
onPress={onNavigationPress}
|
|
67
|
+
style={buttonStyle}
|
|
68
|
+
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
|
|
69
|
+
>
|
|
70
|
+
<AtomicIcon name={iconName} size="md" color={iconColor} />
|
|
71
|
+
</TouchableOpacity>
|
|
72
|
+
</View>
|
|
73
|
+
</View>
|
|
74
|
+
{showDescription && description && (
|
|
75
|
+
<AtomicText
|
|
76
|
+
type="bodyMedium"
|
|
77
|
+
style={[
|
|
78
|
+
styles.description,
|
|
79
|
+
{ color: tokens.colors.textSecondary, marginTop: 4 },
|
|
80
|
+
]}
|
|
81
|
+
>
|
|
82
|
+
{description}
|
|
83
|
+
</AtomicText>
|
|
84
|
+
)}
|
|
85
|
+
{headerContent && <View style={styles.headerContent}>{headerContent}</View>}
|
|
86
|
+
</View>
|
|
87
|
+
);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const styles = StyleSheet.create({
|
|
91
|
+
header: {
|
|
92
|
+
paddingHorizontal: 16,
|
|
93
|
+
paddingTop: 60,
|
|
94
|
+
width: "100%",
|
|
95
|
+
marginBottom: 24,
|
|
96
|
+
},
|
|
97
|
+
headerTop: {
|
|
98
|
+
flexDirection: "row",
|
|
99
|
+
alignItems: "flex-start",
|
|
100
|
+
justifyContent: "space-between",
|
|
101
|
+
},
|
|
102
|
+
titleContainer: {
|
|
103
|
+
flex: 1,
|
|
104
|
+
marginRight: 12,
|
|
105
|
+
},
|
|
106
|
+
headerActions: {
|
|
107
|
+
flexDirection: "row",
|
|
108
|
+
alignItems: "center",
|
|
109
|
+
gap: 8,
|
|
110
|
+
},
|
|
111
|
+
navigationButton: {
|
|
112
|
+
width: 36,
|
|
113
|
+
height: 36,
|
|
114
|
+
borderRadius: 18,
|
|
115
|
+
alignItems: "center",
|
|
116
|
+
justifyContent: "center",
|
|
117
|
+
},
|
|
118
|
+
backButton: {
|
|
119
|
+
width: 40,
|
|
120
|
+
height: 40,
|
|
121
|
+
},
|
|
122
|
+
closeButton: {
|
|
123
|
+
borderWidth: 1,
|
|
124
|
+
},
|
|
125
|
+
description: {
|
|
126
|
+
lineHeight: 20,
|
|
127
|
+
},
|
|
128
|
+
headerContent: {
|
|
129
|
+
marginTop: 16,
|
|
130
|
+
},
|
|
131
|
+
});
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export
|
|
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";
|