@umituz/react-native-design-system 2.6.110 → 2.6.112

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 (81) hide show
  1. package/package.json +7 -3
  2. package/src/atoms/image/AtomicImage.tsx +29 -0
  3. package/src/atoms/index.ts +3 -0
  4. package/src/exports/image.ts +7 -0
  5. package/src/exports/infinite-scroll.ts +7 -0
  6. package/src/exports/uuid.ts +7 -0
  7. package/src/image/domain/entities/EditorTypes.ts +23 -0
  8. package/src/image/domain/entities/ImageConstants.ts +38 -0
  9. package/src/image/domain/entities/ImageFilterTypes.ts +70 -0
  10. package/src/image/domain/entities/ImageTemplateTypes.ts +18 -0
  11. package/src/image/domain/entities/ImageTypes.ts +86 -0
  12. package/src/image/domain/entities/ValidationResult.ts +15 -0
  13. package/src/image/domain/entities/editor/EditorConfigTypes.ts +35 -0
  14. package/src/image/domain/entities/editor/EditorElementTypes.ts +60 -0
  15. package/src/image/domain/entities/editor/EditorFilterTypes.ts +9 -0
  16. package/src/image/domain/entities/editor/EditorLayerTypes.ts +34 -0
  17. package/src/image/domain/entities/editor/EditorStateTypes.ts +35 -0
  18. package/src/image/domain/entities/editor/EditorToolTypes.ts +33 -0
  19. package/src/image/domain/utils/ImageUtils.ts +103 -0
  20. package/src/image/index.ts +123 -0
  21. package/src/image/infrastructure/services/ImageBatchService.ts +110 -0
  22. package/src/image/infrastructure/services/ImageConversionService.ts +74 -0
  23. package/src/image/infrastructure/services/ImageEditorService.ts +136 -0
  24. package/src/image/infrastructure/services/ImageEnhanceService.ts +123 -0
  25. package/src/image/infrastructure/services/ImageMetadataService.ts +116 -0
  26. package/src/image/infrastructure/services/ImageStorageService.ts +37 -0
  27. package/src/image/infrastructure/services/ImageTemplateService.ts +66 -0
  28. package/src/image/infrastructure/services/ImageTransformService.ts +89 -0
  29. package/src/image/infrastructure/services/ImageViewerService.ts +64 -0
  30. package/src/image/infrastructure/utils/BatchProcessor.ts +95 -0
  31. package/src/image/infrastructure/utils/FilterProcessor.ts +124 -0
  32. package/src/image/infrastructure/utils/ImageAnalysisUtils.ts +122 -0
  33. package/src/image/infrastructure/utils/ImageEditorHistoryUtils.ts +63 -0
  34. package/src/image/infrastructure/utils/ImageErrorHandler.ts +40 -0
  35. package/src/image/infrastructure/utils/ImageFilterUtils.ts +21 -0
  36. package/src/image/infrastructure/utils/ImageQualityPresets.ts +110 -0
  37. package/src/image/infrastructure/utils/ImageTransformUtils.ts +25 -0
  38. package/src/image/infrastructure/utils/ImageValidator.ts +59 -0
  39. package/src/image/infrastructure/utils/LayerManager.ts +77 -0
  40. package/src/image/infrastructure/utils/MetadataExtractor.ts +83 -0
  41. package/src/image/infrastructure/utils/filters/BasicFilters.ts +61 -0
  42. package/src/image/infrastructure/utils/filters/FilterHelpers.ts +21 -0
  43. package/src/image/infrastructure/utils/filters/SpecialFilters.ts +84 -0
  44. package/src/image/infrastructure/utils/validation/image-validator.ts +77 -0
  45. package/src/image/infrastructure/utils/validation/mime-type-validator.ts +101 -0
  46. package/src/image/infrastructure/utils/validation/mime-types.constants.ts +41 -0
  47. package/src/image/presentation/components/GalleryHeader.tsx +126 -0
  48. package/src/image/presentation/components/ImageGallery.tsx +138 -0
  49. package/src/image/presentation/components/editor/FilterPickerSheet.tsx +75 -0
  50. package/src/image/presentation/components/editor/StickerPickerSheet.tsx +62 -0
  51. package/src/image/presentation/components/editor/TextEditorSheet.tsx +98 -0
  52. package/src/image/presentation/components/editor/TextEditorTabs.tsx +111 -0
  53. package/src/image/presentation/components/image/AtomicImage.tsx +29 -0
  54. package/src/image/presentation/hooks/useImage.ts +39 -0
  55. package/src/image/presentation/hooks/useImageBatch.ts +28 -0
  56. package/src/image/presentation/hooks/useImageConversion.ts +29 -0
  57. package/src/image/presentation/hooks/useImageEnhance.ts +32 -0
  58. package/src/image/presentation/hooks/useImageGallery.ts +90 -0
  59. package/src/image/presentation/hooks/useImageMetadata.ts +28 -0
  60. package/src/image/presentation/hooks/useImageOperation.ts +37 -0
  61. package/src/image/presentation/hooks/useImageTransform.ts +42 -0
  62. package/src/index.ts +15 -0
  63. package/src/infinite-scroll/domain/interfaces/infinite-scroll-list-props.ts +67 -0
  64. package/src/infinite-scroll/domain/types/infinite-scroll-config.ts +108 -0
  65. package/src/infinite-scroll/domain/types/infinite-scroll-return.ts +40 -0
  66. package/src/infinite-scroll/domain/types/infinite-scroll-state.ts +58 -0
  67. package/src/infinite-scroll/domain/utils/pagination-utils.ts +63 -0
  68. package/src/infinite-scroll/domain/utils/type-guards.ts +53 -0
  69. package/src/infinite-scroll/index.ts +62 -0
  70. package/src/infinite-scroll/presentation/components/empty.tsx +44 -0
  71. package/src/infinite-scroll/presentation/components/error.tsx +66 -0
  72. package/src/infinite-scroll/presentation/components/infinite-scroll-list.tsx +120 -0
  73. package/src/infinite-scroll/presentation/components/loading-more.tsx +38 -0
  74. package/src/infinite-scroll/presentation/components/loading.tsx +40 -0
  75. package/src/infinite-scroll/presentation/components/types.ts +124 -0
  76. package/src/infinite-scroll/presentation/hooks/pagination.helper.ts +83 -0
  77. package/src/infinite-scroll/presentation/hooks/useInfiniteScroll.ts +327 -0
  78. package/src/uuid/index.ts +15 -0
  79. package/src/uuid/infrastructure/utils/UUIDUtils.ts +75 -0
  80. package/src/uuid/package-lock.json +14255 -0
  81. package/src/uuid/types/UUID.ts +36 -0
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Infinite Scroll Return Types
3
+ *
4
+ * Domain types for hook return values
5
+ * Follows SOLID, DRY, KISS principles
6
+ */
7
+
8
+ import type { InfiniteScrollState } from "./infinite-scroll-state";
9
+
10
+ export interface UseInfiniteScrollReturn<T> {
11
+ /**
12
+ * All loaded items (flattened)
13
+ */
14
+ items: T[];
15
+
16
+ /**
17
+ * Current state
18
+ */
19
+ state: InfiniteScrollState<T>;
20
+
21
+ /**
22
+ * Load next page of items
23
+ */
24
+ loadMore: () => Promise<void>;
25
+
26
+ /**
27
+ * Refresh all data (resets to page 0)
28
+ */
29
+ refresh: () => Promise<void>;
30
+
31
+ /**
32
+ * Reset to initial state
33
+ */
34
+ reset: () => void;
35
+
36
+ /**
37
+ * Check if can load more
38
+ */
39
+ canLoadMore: boolean;
40
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Infinite Scroll State Types
3
+ *
4
+ * Domain types for infinite scroll state management
5
+ * Follows SOLID, DRY, KISS principles
6
+ */
7
+
8
+ export interface InfiniteScrollState<T> {
9
+ /**
10
+ * All loaded items (flattened from pages)
11
+ */
12
+ items: T[];
13
+
14
+ /**
15
+ * All pages of items (used in page-based mode)
16
+ */
17
+ pages: T[][];
18
+
19
+ /**
20
+ * Current page number (0-indexed, page-based mode)
21
+ */
22
+ currentPage: number;
23
+
24
+ /**
25
+ * Current cursor (cursor-based mode)
26
+ */
27
+ cursor: string | null;
28
+
29
+ /**
30
+ * Whether more items are available
31
+ */
32
+ hasMore: boolean;
33
+
34
+ /**
35
+ * Whether currently loading initial data
36
+ */
37
+ isLoading: boolean;
38
+
39
+ /**
40
+ * Whether currently loading more items
41
+ */
42
+ isLoadingMore: boolean;
43
+
44
+ /**
45
+ * Whether currently refreshing
46
+ */
47
+ isRefreshing: boolean;
48
+
49
+ /**
50
+ * Error message if any
51
+ */
52
+ error: string | null;
53
+
54
+ /**
55
+ * Total number of items (if known)
56
+ */
57
+ totalItems?: number;
58
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Pagination Utilities
3
+ *
4
+ * Pure functions for pagination calculations
5
+ * Follows SOLID, DRY, KISS principles
6
+ */
7
+
8
+ /**
9
+ * Calculate onEndReachedThreshold from threshold value
10
+ * Converts threshold (number of items) to percentage (0-1)
11
+ *
12
+ * @param threshold - Number of items from bottom to trigger load
13
+ * @param defaultThreshold - Default threshold if not provided (default: 0.1 = 10%)
14
+ * @returns Threshold value between 0.01 and 1.0
15
+ */
16
+ export function calculateEndReachedThreshold(
17
+ threshold?: number,
18
+ defaultThreshold = 0.1,
19
+ ): number {
20
+ if (!threshold) {
21
+ return defaultThreshold;
22
+ }
23
+
24
+ // Convert threshold to percentage (0-1 range)
25
+ // Ensure minimum 0.01 (1%) and maximum 1.0 (100%)
26
+ const calculated = threshold / 100;
27
+ return Math.max(0.01, Math.min(1.0, calculated));
28
+ }
29
+
30
+ /**
31
+ * Calculate pagination slice for client-side pagination
32
+ *
33
+ * @param items - All items to paginate
34
+ * @param page - Page number (0-indexed)
35
+ * @param pageSize - Number of items per page
36
+ * @returns Slice of items for the requested page
37
+ */
38
+ export function getPageSlice<T>(
39
+ items: T[],
40
+ page: number,
41
+ pageSize: number,
42
+ ): T[] {
43
+ const start = page * pageSize;
44
+ const end = start + pageSize;
45
+ return items.slice(start, end);
46
+ }
47
+
48
+ /**
49
+ * Check if there are more items to load
50
+ *
51
+ * @param lastPage - Last fetched page
52
+ * @param allPages - All fetched pages
53
+ * @param pageSize - Page size
54
+ * @returns True if there are more items to load
55
+ */
56
+ export function hasMoreItems<T>(
57
+ lastPage: T[],
58
+ allPages: T[][],
59
+ pageSize: number,
60
+ ): boolean {
61
+ // If last page has fewer items than pageSize, we've reached the end
62
+ return lastPage.length >= pageSize;
63
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Type Guard Utilities
3
+ *
4
+ * Runtime type checking for better type safety
5
+ */
6
+
7
+ import type { InfiniteScrollConfig, PageBasedConfig, CursorBasedConfig } from "../types/infinite-scroll-config";
8
+
9
+ /**
10
+ * Check if config is page-based pagination
11
+ */
12
+ export function isPageBasedConfig<T>(
13
+ config: InfiniteScrollConfig<T>,
14
+ ): config is PageBasedConfig<T> {
15
+ return "fetchData" in config && typeof config.fetchData === "function";
16
+ }
17
+
18
+ /**
19
+ * Check if config is cursor-based pagination
20
+ */
21
+ export function isCursorBasedConfig<T>(
22
+ config: InfiniteScrollConfig<T>,
23
+ ): config is CursorBasedConfig<T> {
24
+ return "paginationMode" in config && config.paginationMode === "cursor";
25
+ }
26
+
27
+ /**
28
+ * Check if value is a valid error
29
+ */
30
+ export function isError(value: unknown): value is Error {
31
+ return value instanceof Error;
32
+ }
33
+
34
+ /**
35
+ * Check if value is a non-null object
36
+ */
37
+ export function isNonNullObject<T>(value: T | null | undefined): value is T {
38
+ return value !== null && value !== undefined;
39
+ }
40
+
41
+ /**
42
+ * Check if array has items
43
+ */
44
+ export function hasItems<T>(items: T[] | null | undefined): items is T[] {
45
+ return Array.isArray(items) && items.length > 0;
46
+ }
47
+
48
+ /**
49
+ * Check if string is not empty
50
+ */
51
+ export function isNonEmptyString(value: string | null | undefined): value is string {
52
+ return typeof value === "string" && value.length > 0;
53
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * React Native Infinite Scroll
3
+ *
4
+ * Modern infinite scroll system for React Native
5
+ * Follows SOLID, DRY, KISS principles
6
+ *
7
+ * Features:
8
+ * - Page-based and cursor-based pagination
9
+ * - Automatic retry with exponential backoff
10
+ * - Request cancellation with AbortController
11
+ * - Performance monitoring in __DEV__ mode
12
+ * - Full accessibility support
13
+ * - Type-safe utilities
14
+ */
15
+
16
+ // Domain Layer
17
+ export type {
18
+ InfiniteScrollConfig,
19
+ PaginatedResult,
20
+ PageBasedConfig,
21
+ CursorBasedConfig,
22
+ } from "./domain/types/infinite-scroll-config";
23
+ export type { InfiniteScrollState } from "./domain/types/infinite-scroll-state";
24
+ export type { UseInfiniteScrollReturn } from "./domain/types/infinite-scroll-return";
25
+ export type { InfiniteScrollListProps } from "./domain/interfaces/infinite-scroll-list-props";
26
+
27
+ // Domain Utils
28
+ export {
29
+ calculateEndReachedThreshold,
30
+ getPageSlice,
31
+ hasMoreItems,
32
+ } from "./domain/utils/pagination-utils";
33
+
34
+ // Type Guards
35
+ export {
36
+ isPageBasedConfig,
37
+ isCursorBasedConfig,
38
+ isError,
39
+ isNonNullObject,
40
+ hasItems,
41
+ isNonEmptyString,
42
+ } from "./domain/utils/type-guards";
43
+
44
+ // Presentation Layer - Hooks
45
+ export { useInfiniteScroll } from "./presentation/hooks/useInfiniteScroll";
46
+
47
+ // Presentation Layer - Components
48
+ export { InfiniteScrollList } from "./presentation/components/infinite-scroll-list";
49
+
50
+ // Component Types
51
+ export type {
52
+ EmptyProps,
53
+ ErrorProps,
54
+ LoadingProps,
55
+ LoadingMoreProps,
56
+ } from "./presentation/components/types";
57
+
58
+ // State Components
59
+ export { Loading } from "./presentation/components/loading";
60
+ export { LoadingMore } from "./presentation/components/loading-more";
61
+ export { Empty } from "./presentation/components/empty";
62
+ export { Error } from "./presentation/components/error";
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Empty Component
3
+ *
4
+ * Presentation component for empty state
5
+ * Fully customizable via props
6
+ * Accessibility support included
7
+ */
8
+
9
+ import React from "react";
10
+ import { View, Text, StyleSheet } from "react-native";
11
+ import type { EmptyProps } from "./types";
12
+
13
+ export const Empty = React.memo<EmptyProps>(({
14
+ text = "No items found",
15
+ containerStyle,
16
+ textStyle,
17
+ accessibilityLabel = "Empty list",
18
+ ...accessibilityProps
19
+ }) => (
20
+ <View
21
+ style={[styles.container, containerStyle]}
22
+ accessibilityLabel={accessibilityLabel}
23
+ accessibilityRole="text"
24
+ accessibilityValue={{ text }}
25
+ {...accessibilityProps}
26
+ >
27
+ <Text style={[styles.text, textStyle]}>{text}</Text>
28
+ </View>
29
+ ));
30
+
31
+ Empty.displayName = "Empty";
32
+
33
+ const styles = StyleSheet.create({
34
+ container: {
35
+ flex: 1,
36
+ justifyContent: "center",
37
+ alignItems: "center",
38
+ padding: 20,
39
+ },
40
+ text: {
41
+ fontSize: 16,
42
+ textAlign: "center",
43
+ },
44
+ });
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Error Component
3
+ *
4
+ * Presentation component for error state
5
+ * Fully customizable via props
6
+ * Accessibility support included
7
+ */
8
+
9
+ import React from "react";
10
+ import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
11
+ import type { ErrorProps } from "./types";
12
+
13
+ export const Error = React.memo<ErrorProps>(({
14
+ error,
15
+ onRetry,
16
+ retryText = "Tap to retry",
17
+ containerStyle,
18
+ errorTextStyle,
19
+ retryTextStyle,
20
+ accessibilityLabel,
21
+ retryAccessibilityHint = "Double tap to retry",
22
+ ...accessibilityProps
23
+ }) => (
24
+ <View
25
+ style={[styles.container, containerStyle]}
26
+ accessibilityLabel={accessibilityLabel || `Error: ${error}`}
27
+ accessibilityRole="alert"
28
+ {...accessibilityProps}
29
+ >
30
+ <Text
31
+ style={[styles.errorText, errorTextStyle]}
32
+ accessibilityRole="text"
33
+ >
34
+ {error}
35
+ </Text>
36
+ <TouchableOpacity
37
+ onPress={onRetry}
38
+ accessibilityRole="button"
39
+ accessibilityLabel={retryText}
40
+ accessibilityHint={retryAccessibilityHint}
41
+ >
42
+ <Text style={[styles.retryText, retryTextStyle]}>{retryText}</Text>
43
+ </TouchableOpacity>
44
+ </View>
45
+ ));
46
+
47
+ Error.displayName = "Error";
48
+
49
+ const styles = StyleSheet.create({
50
+ container: {
51
+ flex: 1,
52
+ justifyContent: "center",
53
+ alignItems: "center",
54
+ padding: 20,
55
+ },
56
+ errorText: {
57
+ fontSize: 16,
58
+ textAlign: "center",
59
+ marginBottom: 8,
60
+ },
61
+ retryText: {
62
+ fontSize: 14,
63
+ textAlign: "center",
64
+ marginTop: 8,
65
+ },
66
+ });
@@ -0,0 +1,120 @@
1
+ /**
2
+ * InfiniteScrollList Component
3
+ *
4
+ * Presentation component for infinite scroll list
5
+ * Optimized with React.memo for performance
6
+ */
7
+
8
+ import React from "react";
9
+ import { FlatList } from "react-native";
10
+ import { useInfiniteScroll } from "../hooks/useInfiniteScroll";
11
+ import { calculateEndReachedThreshold } from "../../domain/utils/pagination-utils";
12
+ import type { InfiniteScrollListProps } from "../../domain/interfaces/infinite-scroll-list-props";
13
+ import { Loading } from "./loading";
14
+ import { LoadingMore } from "./loading-more";
15
+ import { Empty } from "./empty";
16
+ import { Error } from "./error";
17
+
18
+ /**
19
+ * Render error component
20
+ */
21
+ function renderErrorComponent(
22
+ error: string,
23
+ retry: () => void,
24
+ errorComponent?: (error: string, retry: () => void) => React.ReactElement,
25
+ ): React.ReactElement {
26
+ if (errorComponent) {
27
+ return errorComponent(error, retry);
28
+ }
29
+ return <Error error={error} onRetry={retry} />;
30
+ }
31
+
32
+ /**
33
+ * InfiniteScrollList Component
34
+ *
35
+ * FlatList wrapper with automatic infinite scroll and pagination
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * <InfiniteScrollList
40
+ * config={{
41
+ * pageSize: 20,
42
+ * threshold: 5,
43
+ * fetchData: async (page, pageSize) => {
44
+ * const response = await api.getItems({ page, limit: pageSize });
45
+ * return response.data;
46
+ * },
47
+ * }}
48
+ * renderItem={(item) => <ItemCard item={item} />}
49
+ * />
50
+ * ```
51
+ */
52
+ function InfiniteScrollListComponent<T>({
53
+ config,
54
+ renderItem,
55
+ loadingComponent,
56
+ loadingMoreComponent,
57
+ emptyComponent,
58
+ errorComponent,
59
+ ListHeaderComponent,
60
+ ListFooterComponent,
61
+ flatListProps,
62
+ }: InfiniteScrollListProps<T>): React.ReactElement {
63
+ const { items, state, loadMore, refresh, canLoadMore } = useInfiniteScroll(config);
64
+
65
+ const handleEndReached = React.useCallback(() => {
66
+ if (canLoadMore && config.autoLoad !== false) {
67
+ loadMore();
68
+ }
69
+ }, [canLoadMore, loadMore, config.autoLoad]);
70
+
71
+ const getItemKey = React.useCallback(
72
+ (item: T, index: number): string => {
73
+ if (config.getItemKey) {
74
+ return config.getItemKey(item, index);
75
+ }
76
+ return `item-${index}`;
77
+ },
78
+ [config],
79
+ );
80
+
81
+ // Loading state
82
+ if (state.isLoading) {
83
+ return loadingComponent || <Loading />;
84
+ }
85
+
86
+ // Error state
87
+ if (state.error) {
88
+ return renderErrorComponent(state.error, refresh, errorComponent);
89
+ }
90
+
91
+ // Empty state
92
+ if (items.length === 0 && !state.isLoading) {
93
+ return emptyComponent || <Empty />;
94
+ }
95
+
96
+ // Render list
97
+ return (
98
+ <FlatList
99
+ data={items}
100
+ renderItem={({ item, index }) => renderItem(item, index)}
101
+ keyExtractor={(item, index) => getItemKey(item, index)}
102
+ onEndReached={handleEndReached}
103
+ onEndReachedThreshold={calculateEndReachedThreshold(config.threshold)}
104
+ onRefresh={refresh}
105
+ refreshing={state.isRefreshing}
106
+ ListHeaderComponent={ListHeaderComponent}
107
+ ListFooterComponent={
108
+ <>
109
+ {ListFooterComponent}
110
+ {state.isLoadingMore && (loadingMoreComponent || <LoadingMore />)}
111
+ </>
112
+ }
113
+ {...flatListProps}
114
+ />
115
+ );
116
+ }
117
+
118
+ export const InfiniteScrollList = React.memo(InfiniteScrollListComponent) as <T>(
119
+ props: InfiniteScrollListProps<T>,
120
+ ) => React.ReactElement;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Loading More Component
3
+ *
4
+ * Presentation component for loading more state
5
+ * Fully customizable via props
6
+ * Accessibility support included
7
+ */
8
+
9
+ import React from "react";
10
+ import { View, ActivityIndicator, StyleSheet } from "react-native";
11
+ import type { LoadingMoreProps } from "./types";
12
+
13
+ export const LoadingMore = React.memo<LoadingMoreProps>(({
14
+ containerStyle,
15
+ size = "small",
16
+ color,
17
+ accessibilityLabel = "Loading more",
18
+ ...accessibilityProps
19
+ }) => (
20
+ <View
21
+ style={[styles.container, containerStyle]}
22
+ accessibilityLabel={accessibilityLabel}
23
+ accessibilityRole="progressbar"
24
+ accessibilityState={{ busy: true }}
25
+ {...accessibilityProps}
26
+ >
27
+ <ActivityIndicator size={size} color={color} />
28
+ </View>
29
+ ));
30
+
31
+ LoadingMore.displayName = "LoadingMore";
32
+
33
+ const styles = StyleSheet.create({
34
+ container: {
35
+ padding: 16,
36
+ alignItems: "center",
37
+ },
38
+ });
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Loading Component
3
+ *
4
+ * Presentation component for loading state
5
+ * Fully customizable via props
6
+ * Accessibility support included
7
+ */
8
+
9
+ import React from "react";
10
+ import { View, ActivityIndicator, StyleSheet } from "react-native";
11
+ import type { LoadingProps } from "./types";
12
+
13
+ export const Loading = React.memo<LoadingProps>(({
14
+ containerStyle,
15
+ size = "large",
16
+ color,
17
+ accessibilityLabel = "Loading",
18
+ ...accessibilityProps
19
+ }) => (
20
+ <View
21
+ style={[styles.container, containerStyle]}
22
+ accessibilityLabel={accessibilityLabel}
23
+ accessibilityRole="progressbar"
24
+ accessibilityState={{ busy: true }}
25
+ {...accessibilityProps}
26
+ >
27
+ <ActivityIndicator size={size} color={color} />
28
+ </View>
29
+ ));
30
+
31
+ Loading.displayName = "Loading";
32
+
33
+ const styles = StyleSheet.create({
34
+ container: {
35
+ flex: 1,
36
+ justifyContent: "center",
37
+ alignItems: "center",
38
+ padding: 20,
39
+ },
40
+ });