@umituz/react-native-ai-creations 1.2.3 → 1.2.5

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-creations",
3
- "version": "1.2.3",
3
+ "version": "1.2.5",
4
4
  "description": "AI-generated creations gallery with filtering, sharing, and management for React Native apps",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -62,4 +62,4 @@
62
62
  "README.md",
63
63
  "LICENSE"
64
64
  ]
65
- }
65
+ }
@@ -16,11 +16,10 @@ import { useCreations } from "../hooks/useCreations";
16
16
  import { useDeleteCreation } from "../hooks/useDeleteCreation";
17
17
  import { useCreationsFilter } from "../hooks/useCreationsFilter";
18
18
  import { CreationCard } from "../components/CreationCard";
19
- import { FilterChips } from "../components/FilterChips";
20
19
  import { EmptyState } from "../components/EmptyState";
21
20
  import { FilterBottomSheet, type FilterCategory } from "@umituz/react-native-filter";
22
21
  import { BottomSheetModalRef } from "@umituz/react-native-bottom-sheet";
23
- import { AtomicIcon, AtomicText } from "@umituz/react-native-design-system-atoms";
22
+ import { AtomicIcon, AtomicText, AtomicButton } from "@umituz/react-native-design-system-atoms";
24
23
 
25
24
  interface CreationsGalleryScreenProps {
26
25
  readonly userId: string | null;
@@ -55,11 +54,29 @@ export function CreationsGalleryScreen({
55
54
  const { filtered, selectedIds, toggleFilter, clearFilters, isFiltered } =
56
55
  useCreationsFilter({ creations });
57
56
 
58
- const availableTypes = useMemo(() => {
59
- if (!creations) return [];
60
- const types = new Set(creations.map((c) => c.type));
61
- return Array.from(types);
62
- }, [creations]);
57
+ const allCategories = useMemo(() => {
58
+ const categories: FilterCategory[] = [];
59
+
60
+ // Add dynamic types category if types exist
61
+ if (config.types.length > 0) {
62
+ categories.push({
63
+ id: 'type', // This ID matches logic in useFilter? No, filter logic is flat ID based. 'type' is category ID.
64
+ title: t('creations.category') || 'Category',
65
+ multiSelect: false,
66
+ options: config.types.map(t => ({
67
+ id: t.id,
68
+ label: t.labelKey, // In a real app we'd translate this, but for now passing key or mocked
69
+ icon: 'Image', // Default icon since types have emojis which might not work with AtomicIcon
70
+ }))
71
+ });
72
+ }
73
+
74
+ if (config.filterCategories) {
75
+ categories.push(...config.filterCategories);
76
+ }
77
+
78
+ return categories;
79
+ }, [config.types, config.filterCategories, t]);
63
80
 
64
81
  const handleView = useCallback(
65
82
  (creation: Creation) => {
@@ -124,19 +141,37 @@ export function CreationsGalleryScreen({
124
141
  headerArea: {
125
142
  flexDirection: "row",
126
143
  alignItems: "center",
127
- paddingRight: tokens.spacing.md,
144
+ justifyContent: 'space-between',
145
+ paddingHorizontal: tokens.spacing.md,
146
+ paddingVertical: tokens.spacing.sm,
147
+ marginBottom: tokens.spacing.sm,
128
148
  },
129
149
  filterButton: {
130
- padding: tokens.spacing.sm,
150
+ flexDirection: 'row',
151
+ alignItems: 'center',
152
+ gap: tokens.spacing.xs,
153
+ paddingVertical: tokens.spacing.xs,
154
+ paddingHorizontal: tokens.spacing.md,
131
155
  borderRadius: (tokens as any).borders?.radius?.full || 999,
132
156
  backgroundColor: tokens.colors.surfaceVariant,
133
- marginLeft: tokens.spacing.sm,
157
+ borderWidth: 1,
158
+ borderColor: 'transparent',
134
159
  },
135
160
  filterButtonActive: {
136
161
  backgroundColor: tokens.colors.primary + "15",
162
+ borderColor: tokens.colors.primary + "30",
163
+ },
164
+ badge: {
165
+ width: 8,
166
+ height: 8,
167
+ borderRadius: 4,
168
+ backgroundColor: tokens.colors.primary,
169
+ position: 'absolute',
170
+ top: 6,
171
+ right: 6,
137
172
  },
138
173
  list: {
139
- padding: tokens.spacing.md,
174
+ paddingHorizontal: tokens.spacing.md,
140
175
  paddingBottom: insets.bottom + tokens.spacing.xl,
141
176
  gap: tokens.spacing.md,
142
177
  },
@@ -176,24 +211,20 @@ export function CreationsGalleryScreen({
176
211
  return (
177
212
  <View style={styles.container}>
178
213
  <View style={styles.headerArea}>
179
- {config.types.length > 0 && availableTypes.length > 1 && (
180
- <FilterChips
181
- style={{ flex: 1 }}
182
- types={config.types}
183
- availableTypes={availableTypes}
184
- selectedType={selectedIds[0] || "all"}
185
- allLabel={t(config.translations.filterAll)}
186
- onSelect={(type) => toggleFilter(type, false)}
187
- />
188
- )}
189
- {(config.filterCategories?.length || 0) > 0 && (
190
- <TouchableOpacity
191
- onPress={() => filterSheetRef.current?.present()}
192
- style={[styles.filterButton, isFiltered && styles.filterButtonActive]}
193
- >
194
- <AtomicIcon name="ListFilter" size="md" color={isFiltered ? "primary" : "secondary"} />
195
- </TouchableOpacity>
196
- )}
214
+ <View>
215
+ <AtomicText type="headlineSmall">{t(config.translations.title) || 'My Creations'}</AtomicText>
216
+ <AtomicText type="bodySmall" style={{ opacity: 0.6 }}>{filtered.length} {t(config.translations.photoCount) || 'photos'}</AtomicText>
217
+ </View>
218
+ <TouchableOpacity
219
+ onPress={() => filterSheetRef.current?.present()}
220
+ style={[styles.filterButton, isFiltered && styles.filterButtonActive]}
221
+ >
222
+ <AtomicIcon name="ListFilter" size="sm" color={isFiltered ? "primary" : "secondary"} />
223
+ <AtomicText type="labelMedium" color={isFiltered ? "primary" : "secondary"}>Filter</AtomicText>
224
+ {isFiltered && (
225
+ <View style={styles.badge} />
226
+ )}
227
+ </TouchableOpacity>
197
228
  </View>
198
229
  <FlatList
199
230
  data={filtered}
@@ -218,19 +249,17 @@ export function CreationsGalleryScreen({
218
249
  onImageChange={handleImageChange}
219
250
  />
220
251
 
221
- {config.filterCategories && (
222
- <FilterBottomSheet
223
- ref={filterSheetRef}
224
- categories={config.filterCategories as FilterCategory[]}
225
- selectedIds={selectedIds}
226
- onFilterPress={(id, catId) => {
227
- const category = config.filterCategories?.find(c => c.id === catId);
228
- toggleFilter(id, category?.multiSelect);
229
- }}
230
- onClearFilters={clearFilters}
231
- title={t("common.filter")}
232
- />
233
- )}
252
+ <FilterBottomSheet
253
+ ref={filterSheetRef}
254
+ categories={allCategories as FilterCategory[]}
255
+ selectedIds={selectedIds}
256
+ onFilterPress={(id, catId) => {
257
+ const category = allCategories.find(c => c.id === catId);
258
+ toggleFilter(id, category?.multiSelect);
259
+ }}
260
+ onClearFilters={clearFilters}
261
+ title={t("common.filter")}
262
+ />
234
263
  </View>
235
264
  );
236
265
  }