@umituz/react-native-design-system 4.23.41 → 4.23.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 +1 -1
- package/src/exports/molecules/alerts.ts +22 -0
- package/src/exports/molecules/bottom-sheet.ts +20 -0
- package/src/exports/molecules/calendar.ts +23 -0
- package/src/exports/molecules/core.ts +29 -0
- package/src/exports/molecules/countdown.ts +23 -0
- package/src/exports/molecules/emoji.ts +17 -0
- package/src/exports/molecules/index.ts +13 -0
- package/src/exports/molecules/misc.ts +42 -0
- package/src/exports/molecules/navigation.ts +46 -0
- package/src/exports/molecules/swipe-actions.ts +15 -0
- package/src/image/presentation/components/editor/TextEditorSheet.tsx +1 -1
- package/src/image/presentation/components/editor/text-editor/TextContentTab.tsx +42 -0
- package/src/image/presentation/components/editor/text-editor/TextEditorTabs.styles.ts +36 -0
- package/src/image/presentation/components/editor/text-editor/TextStyleTab.tsx +167 -0
- package/src/image/presentation/components/editor/text-editor/TextTransformTab.tsx +192 -0
- package/src/image/presentation/components/editor/text-editor/index.ts +14 -0
- package/src/exports/molecules.ts +0 -201
- package/src/image/presentation/components/editor/TextEditorTabs.tsx +0 -424
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-design-system",
|
|
3
|
-
"version": "4.23.
|
|
3
|
+
"version": "4.23.43",
|
|
4
4
|
"description": "Universal design system for React Native apps - Consolidated package with atoms, molecules, organisms, theme, typography, responsive, safe area, exception, infinite scroll, UUID, image, timezone, offline, onboarding, and loading utilities",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Alert Molecules Exports
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
AlertBanner,
|
|
7
|
+
AlertToast,
|
|
8
|
+
AlertInline,
|
|
9
|
+
AlertModal,
|
|
10
|
+
AlertContainer,
|
|
11
|
+
AlertProvider,
|
|
12
|
+
AlertService,
|
|
13
|
+
useAlert,
|
|
14
|
+
useAlertStore,
|
|
15
|
+
alertService,
|
|
16
|
+
AlertType,
|
|
17
|
+
AlertMode,
|
|
18
|
+
AlertPosition,
|
|
19
|
+
type Alert,
|
|
20
|
+
type AlertAction,
|
|
21
|
+
type AlertOptions,
|
|
22
|
+
} from "../../molecules";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bottom Sheet Molecules Exports
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
BottomSheet,
|
|
7
|
+
BottomSheetModal,
|
|
8
|
+
FilterBottomSheet,
|
|
9
|
+
FilterSheet,
|
|
10
|
+
useBottomSheet,
|
|
11
|
+
useBottomSheetModal,
|
|
12
|
+
useListFilters,
|
|
13
|
+
SafeBottomSheetModalProvider,
|
|
14
|
+
type BottomSheetProps,
|
|
15
|
+
type BottomSheetModalProps,
|
|
16
|
+
type BottomSheetRef,
|
|
17
|
+
type BottomSheetModalRef,
|
|
18
|
+
type FilterOption,
|
|
19
|
+
type FilterCategory,
|
|
20
|
+
} from "../../molecules";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calendar Molecules Exports
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
AtomicCalendar,
|
|
7
|
+
useCalendar,
|
|
8
|
+
useCalendarEvents,
|
|
9
|
+
useCalendarNavigation,
|
|
10
|
+
useCalendarView,
|
|
11
|
+
CalendarService,
|
|
12
|
+
CalendarGeneration,
|
|
13
|
+
DateUtilities,
|
|
14
|
+
type AtomicCalendarProps,
|
|
15
|
+
type CalendarEvent,
|
|
16
|
+
type CalendarViewMode,
|
|
17
|
+
type CreateCalendarEventRequest,
|
|
18
|
+
type UpdateCalendarEventRequest,
|
|
19
|
+
type CalendarDay,
|
|
20
|
+
type CalendarMonth,
|
|
21
|
+
type CalendarWeek,
|
|
22
|
+
type ICalendarRepository,
|
|
23
|
+
} from "../../molecules";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Molecules Exports
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
FormField,
|
|
7
|
+
ListItem,
|
|
8
|
+
SearchBar,
|
|
9
|
+
IconContainer,
|
|
10
|
+
BaseModal,
|
|
11
|
+
ConfirmationModal,
|
|
12
|
+
useConfirmationModal,
|
|
13
|
+
Divider,
|
|
14
|
+
type DividerProps,
|
|
15
|
+
StepProgress,
|
|
16
|
+
List,
|
|
17
|
+
Avatar,
|
|
18
|
+
AvatarGroup,
|
|
19
|
+
AvatarUtils,
|
|
20
|
+
type AvatarProps,
|
|
21
|
+
type AvatarGroupProps,
|
|
22
|
+
type AvatarGroupItem,
|
|
23
|
+
type AvatarSize,
|
|
24
|
+
type AvatarShape,
|
|
25
|
+
type AvatarConfig,
|
|
26
|
+
type AvatarType,
|
|
27
|
+
type BaseModalProps,
|
|
28
|
+
type ListProps,
|
|
29
|
+
} from "../../molecules";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Countdown Molecules Exports
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
Countdown,
|
|
7
|
+
TimeUnit,
|
|
8
|
+
CountdownHeader,
|
|
9
|
+
useCountdown,
|
|
10
|
+
calculateTimeRemaining,
|
|
11
|
+
padNumber,
|
|
12
|
+
getNextDayStart,
|
|
13
|
+
getNextYearStart,
|
|
14
|
+
type CountdownProps,
|
|
15
|
+
type TimeUnitProps,
|
|
16
|
+
type CountdownHeaderProps,
|
|
17
|
+
type UseCountdownOptions,
|
|
18
|
+
type UseCountdownReturn,
|
|
19
|
+
type TimeRemaining,
|
|
20
|
+
type CountdownTarget,
|
|
21
|
+
type CountdownFormatOptions,
|
|
22
|
+
type CountdownDisplayConfig,
|
|
23
|
+
} from "../../molecules";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Emoji Molecules Exports
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
EmojiPicker,
|
|
7
|
+
useEmojiPicker,
|
|
8
|
+
EmojiCategory,
|
|
9
|
+
EmojiUtils,
|
|
10
|
+
type EmojiObject,
|
|
11
|
+
type EmojiPickerConfig,
|
|
12
|
+
type EmojiSelectCallback,
|
|
13
|
+
type EmojiPickerState,
|
|
14
|
+
type EmojiPickerProps,
|
|
15
|
+
type UseEmojiPickerOptions,
|
|
16
|
+
type UseEmojiPickerReturn,
|
|
17
|
+
} from "../../molecules";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Molecules Exports - Barrel
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export * from "./core";
|
|
6
|
+
export * from "./alerts";
|
|
7
|
+
export * from "./bottom-sheet";
|
|
8
|
+
export * from "./calendar";
|
|
9
|
+
export * from "./swipe-actions";
|
|
10
|
+
export * from "./navigation";
|
|
11
|
+
export * from "./emoji";
|
|
12
|
+
export * from "./countdown";
|
|
13
|
+
export * from "./misc";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Miscellaneous Molecules Exports
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
// Long Press Menu
|
|
7
|
+
MenuActionType,
|
|
8
|
+
type MenuAction,
|
|
9
|
+
type MenuActionTypeValue,
|
|
10
|
+
// Step Header
|
|
11
|
+
StepHeader,
|
|
12
|
+
type StepHeaderProps,
|
|
13
|
+
type StepHeaderConfig,
|
|
14
|
+
// Splash
|
|
15
|
+
SplashScreen,
|
|
16
|
+
useSplashFlow,
|
|
17
|
+
type SplashScreenProps,
|
|
18
|
+
type SplashColors,
|
|
19
|
+
type UseSplashFlowOptions,
|
|
20
|
+
type UseSplashFlowResult,
|
|
21
|
+
// Filter Group
|
|
22
|
+
FilterGroup,
|
|
23
|
+
type FilterGroupProps,
|
|
24
|
+
type FilterGroupItem,
|
|
25
|
+
// Action Footer
|
|
26
|
+
ActionFooter,
|
|
27
|
+
type ActionFooterProps,
|
|
28
|
+
// Hero Section
|
|
29
|
+
HeroSection,
|
|
30
|
+
type HeroSectionProps,
|
|
31
|
+
// Info Grid
|
|
32
|
+
InfoGrid,
|
|
33
|
+
type InfoGridProps,
|
|
34
|
+
type InfoGridItem,
|
|
35
|
+
// Circular Menu
|
|
36
|
+
CircularMenu,
|
|
37
|
+
CircularMenuItem,
|
|
38
|
+
CircularMenuBackground,
|
|
39
|
+
CircularMenuCloseButton,
|
|
40
|
+
type CircularMenuProps,
|
|
41
|
+
type CircularMenuAction,
|
|
42
|
+
} from "../../molecules";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Navigation Molecules Exports
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
TabsNavigator,
|
|
7
|
+
StackNavigator,
|
|
8
|
+
createTabNavigator,
|
|
9
|
+
createStackNavigator,
|
|
10
|
+
FabButton,
|
|
11
|
+
NavigationCleanupManager,
|
|
12
|
+
AppNavigation,
|
|
13
|
+
NavigationContainer,
|
|
14
|
+
TabLabel,
|
|
15
|
+
NavigationHeader,
|
|
16
|
+
createScreenOptions,
|
|
17
|
+
createNavigationTheme,
|
|
18
|
+
useTabBarStyles,
|
|
19
|
+
useTabConfig,
|
|
20
|
+
useAppNavigation,
|
|
21
|
+
useAppRoute,
|
|
22
|
+
useAppFocusEffect,
|
|
23
|
+
useAppIsFocused,
|
|
24
|
+
type NavigationHeaderProps,
|
|
25
|
+
type ScreenOptionsParams,
|
|
26
|
+
type TabsNavigatorProps,
|
|
27
|
+
type StackNavigatorProps,
|
|
28
|
+
type StackNavigatorConfig,
|
|
29
|
+
type StackScreen,
|
|
30
|
+
type FabButtonProps,
|
|
31
|
+
type TabScreen,
|
|
32
|
+
type TabNavigatorConfig,
|
|
33
|
+
type BaseScreen,
|
|
34
|
+
type BaseNavigatorConfig,
|
|
35
|
+
type IconRendererProps,
|
|
36
|
+
type LabelProcessorProps,
|
|
37
|
+
type FabConfig,
|
|
38
|
+
type NavigationCleanup,
|
|
39
|
+
type BottomTabNavigationOptions,
|
|
40
|
+
type BottomTabScreenProps,
|
|
41
|
+
type StackNavigationOptions,
|
|
42
|
+
type StackScreenProps,
|
|
43
|
+
type RouteProp,
|
|
44
|
+
type TabLabelProps,
|
|
45
|
+
type TabBarConfig,
|
|
46
|
+
} from "../../molecules";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Swipe Actions Molecules Exports
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
SwipeActionButton,
|
|
7
|
+
SwipeActionUtils,
|
|
8
|
+
ACTION_PRESETS,
|
|
9
|
+
DEFAULT_SWIPE_CONFIG,
|
|
10
|
+
type SwipeActionButtonProps,
|
|
11
|
+
type SwipeActionType,
|
|
12
|
+
type SwipeActionConfig,
|
|
13
|
+
type SwipeDirection,
|
|
14
|
+
type SwipeableConfig,
|
|
15
|
+
} from "../../molecules";
|
|
@@ -9,7 +9,7 @@ import type { BottomSheetModalRef } from '../../../../molecules/bottom-sheet/typ
|
|
|
9
9
|
import { AtomicText } from '../../../../atoms/AtomicText';
|
|
10
10
|
import { AtomicIcon } from '../../../../atoms';
|
|
11
11
|
import { useAppDesignTokens } from '../../../../theme/hooks/useAppDesignTokens';
|
|
12
|
-
import { TextContentTab, TextStyleTab, TextTransformTab } from './
|
|
12
|
+
import { TextContentTab, TextStyleTab, TextTransformTab } from './text-editor';
|
|
13
13
|
|
|
14
14
|
export interface TextEditorSheetProps {
|
|
15
15
|
text: string;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text Content Tab - Text input for editor
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import React from "react";
|
|
6
|
+
import { View, TextInput } from "react-native";
|
|
7
|
+
import { useAppDesignTokens } from "../../../../../theme/hooks/useAppDesignTokens";
|
|
8
|
+
import { textEditorStyles, type TabProps } from "./TextEditorTabs.styles";
|
|
9
|
+
|
|
10
|
+
export interface TextContentTabProps extends TabProps {
|
|
11
|
+
text: string;
|
|
12
|
+
onTextChange: (t: string) => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const TextContentTab: React.FC<TextContentTabProps> = ({
|
|
16
|
+
text,
|
|
17
|
+
onTextChange,
|
|
18
|
+
t,
|
|
19
|
+
}) => {
|
|
20
|
+
const tokens = useAppDesignTokens();
|
|
21
|
+
return (
|
|
22
|
+
<View style={{ gap: tokens.spacing.lg }}>
|
|
23
|
+
<TextInput
|
|
24
|
+
value={text}
|
|
25
|
+
onChangeText={onTextChange}
|
|
26
|
+
placeholder={t("editor.text_placeholder")}
|
|
27
|
+
style={[
|
|
28
|
+
textEditorStyles.textInput,
|
|
29
|
+
{
|
|
30
|
+
...tokens.typography.bodyLarge,
|
|
31
|
+
borderColor: tokens.colors.border,
|
|
32
|
+
borderRadius: tokens.borders.radius.md,
|
|
33
|
+
padding: tokens.spacing.md,
|
|
34
|
+
minHeight: 120,
|
|
35
|
+
color: tokens.colors.textPrimary,
|
|
36
|
+
},
|
|
37
|
+
]}
|
|
38
|
+
multiline
|
|
39
|
+
/>
|
|
40
|
+
</View>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Styles for Text Editor Tabs
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { StyleSheet } from "react-native";
|
|
6
|
+
|
|
7
|
+
export const textEditorStyles = StyleSheet.create({
|
|
8
|
+
textInput: {
|
|
9
|
+
borderWidth: 1,
|
|
10
|
+
textAlignVertical: "top",
|
|
11
|
+
},
|
|
12
|
+
fontButton: {
|
|
13
|
+
paddingVertical: 8,
|
|
14
|
+
minWidth: 80,
|
|
15
|
+
alignItems: "center",
|
|
16
|
+
},
|
|
17
|
+
colorButton: {
|
|
18
|
+
width: 40,
|
|
19
|
+
height: 40,
|
|
20
|
+
},
|
|
21
|
+
sizeButton: {
|
|
22
|
+
minWidth: 50,
|
|
23
|
+
alignItems: "center",
|
|
24
|
+
},
|
|
25
|
+
transformButton: {
|
|
26
|
+
minWidth: 60,
|
|
27
|
+
alignItems: "center",
|
|
28
|
+
},
|
|
29
|
+
deleteButton: {
|
|
30
|
+
alignSelf: "flex-start",
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export interface TabProps {
|
|
35
|
+
t: (key: string) => string;
|
|
36
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text Style Tab - Font, color, size selection
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import React from "react";
|
|
6
|
+
import { View, ScrollView, TouchableOpacity } from "react-native";
|
|
7
|
+
import { AtomicText } from "../../../../../atoms";
|
|
8
|
+
import { useAppDesignTokens } from "../../../../../theme/hooks/useAppDesignTokens";
|
|
9
|
+
import { textEditorStyles, type TabProps } from "./TextEditorTabs.styles";
|
|
10
|
+
|
|
11
|
+
const DEFAULT_COLORS = [
|
|
12
|
+
"#FFFFFF",
|
|
13
|
+
"#000000",
|
|
14
|
+
"#FF0000",
|
|
15
|
+
"#FFFF00",
|
|
16
|
+
"#0000FF",
|
|
17
|
+
"#00FF00",
|
|
18
|
+
"#FF00FF",
|
|
19
|
+
"#FFA500",
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
const DEFAULT_FONTS = ["System", "serif", "sans-serif", "monospace"];
|
|
23
|
+
const DEFAULT_FONT_SIZES = [12, 14, 16, 18, 20, 24, 28, 32];
|
|
24
|
+
|
|
25
|
+
export interface TextStyleTabProps extends TabProps {
|
|
26
|
+
fontSize: number;
|
|
27
|
+
setFontSize: (s: number) => void;
|
|
28
|
+
color: string;
|
|
29
|
+
setColor: (c: string) => void;
|
|
30
|
+
fontFamily: string;
|
|
31
|
+
setFontFamily: (f: string) => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const TextStyleTab: React.FC<TextStyleTabProps> = ({
|
|
35
|
+
fontSize,
|
|
36
|
+
setFontSize,
|
|
37
|
+
color,
|
|
38
|
+
setColor,
|
|
39
|
+
fontFamily,
|
|
40
|
+
setFontFamily,
|
|
41
|
+
}) => {
|
|
42
|
+
const tokens = useAppDesignTokens();
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<View style={{ gap: tokens.spacing.xl }}>
|
|
46
|
+
{/* Font Family Selection */}
|
|
47
|
+
<View>
|
|
48
|
+
<AtomicText
|
|
49
|
+
style={{
|
|
50
|
+
...tokens.typography.labelMedium,
|
|
51
|
+
marginBottom: tokens.spacing.sm,
|
|
52
|
+
}}
|
|
53
|
+
>
|
|
54
|
+
Font
|
|
55
|
+
</AtomicText>
|
|
56
|
+
<ScrollView
|
|
57
|
+
horizontal
|
|
58
|
+
showsHorizontalScrollIndicator={false}
|
|
59
|
+
contentContainerStyle={{ gap: tokens.spacing.sm }}
|
|
60
|
+
>
|
|
61
|
+
{DEFAULT_FONTS.map((f) => (
|
|
62
|
+
<TouchableOpacity
|
|
63
|
+
key={f}
|
|
64
|
+
onPress={() => setFontFamily(f)}
|
|
65
|
+
style={[
|
|
66
|
+
textEditorStyles.fontButton,
|
|
67
|
+
{
|
|
68
|
+
paddingHorizontal: tokens.spacing.md,
|
|
69
|
+
paddingVertical: tokens.spacing.xs,
|
|
70
|
+
borderRadius: tokens.borders.radius.full,
|
|
71
|
+
borderWidth: 1,
|
|
72
|
+
borderColor:
|
|
73
|
+
fontFamily === f ? tokens.colors.primary : tokens.colors.border,
|
|
74
|
+
backgroundColor:
|
|
75
|
+
fontFamily === f ? tokens.colors.primary : tokens.colors.surface,
|
|
76
|
+
},
|
|
77
|
+
]}
|
|
78
|
+
>
|
|
79
|
+
<AtomicText style={{ fontFamily: f }}>{f}</AtomicText>
|
|
80
|
+
</TouchableOpacity>
|
|
81
|
+
))}
|
|
82
|
+
</ScrollView>
|
|
83
|
+
</View>
|
|
84
|
+
|
|
85
|
+
{/* Color Selection */}
|
|
86
|
+
<View>
|
|
87
|
+
<AtomicText
|
|
88
|
+
style={{
|
|
89
|
+
...tokens.typography.labelMedium,
|
|
90
|
+
marginBottom: tokens.spacing.sm,
|
|
91
|
+
}}
|
|
92
|
+
>
|
|
93
|
+
Color
|
|
94
|
+
</AtomicText>
|
|
95
|
+
<ScrollView
|
|
96
|
+
horizontal
|
|
97
|
+
showsHorizontalScrollIndicator={false}
|
|
98
|
+
contentContainerStyle={{ gap: tokens.spacing.sm }}
|
|
99
|
+
>
|
|
100
|
+
{DEFAULT_COLORS.map((c) => (
|
|
101
|
+
<TouchableOpacity
|
|
102
|
+
key={c}
|
|
103
|
+
onPress={() => setColor(c)}
|
|
104
|
+
style={[
|
|
105
|
+
textEditorStyles.colorButton,
|
|
106
|
+
{
|
|
107
|
+
width: 40,
|
|
108
|
+
height: 40,
|
|
109
|
+
borderRadius: 20,
|
|
110
|
+
backgroundColor: c,
|
|
111
|
+
borderWidth: color === c ? 3 : 1,
|
|
112
|
+
borderColor: tokens.colors.primary,
|
|
113
|
+
},
|
|
114
|
+
]}
|
|
115
|
+
/>
|
|
116
|
+
))}
|
|
117
|
+
</ScrollView>
|
|
118
|
+
</View>
|
|
119
|
+
|
|
120
|
+
{/* Font Size Selection */}
|
|
121
|
+
<View>
|
|
122
|
+
<AtomicText
|
|
123
|
+
style={{
|
|
124
|
+
...tokens.typography.labelMedium,
|
|
125
|
+
marginBottom: tokens.spacing.xs,
|
|
126
|
+
}}
|
|
127
|
+
>
|
|
128
|
+
Size: {fontSize}px
|
|
129
|
+
</AtomicText>
|
|
130
|
+
<ScrollView
|
|
131
|
+
horizontal
|
|
132
|
+
showsHorizontalScrollIndicator={false}
|
|
133
|
+
contentContainerStyle={{ gap: tokens.spacing.sm }}
|
|
134
|
+
>
|
|
135
|
+
{DEFAULT_FONT_SIZES.map((s) => (
|
|
136
|
+
<TouchableOpacity
|
|
137
|
+
key={s}
|
|
138
|
+
onPress={() => setFontSize(s)}
|
|
139
|
+
style={[
|
|
140
|
+
textEditorStyles.sizeButton,
|
|
141
|
+
{
|
|
142
|
+
paddingHorizontal: tokens.spacing.md,
|
|
143
|
+
paddingVertical: tokens.spacing.sm,
|
|
144
|
+
borderRadius: tokens.borders.radius.md,
|
|
145
|
+
borderWidth: 1,
|
|
146
|
+
borderColor:
|
|
147
|
+
fontSize === s ? tokens.colors.primary : tokens.colors.border,
|
|
148
|
+
backgroundColor:
|
|
149
|
+
fontSize === s ? tokens.colors.primary : tokens.colors.surface,
|
|
150
|
+
},
|
|
151
|
+
]}
|
|
152
|
+
>
|
|
153
|
+
<AtomicText
|
|
154
|
+
style={{
|
|
155
|
+
color: fontSize === s ? "white" : tokens.colors.textPrimary,
|
|
156
|
+
fontWeight: "600",
|
|
157
|
+
}}
|
|
158
|
+
>
|
|
159
|
+
{s}
|
|
160
|
+
</AtomicText>
|
|
161
|
+
</TouchableOpacity>
|
|
162
|
+
))}
|
|
163
|
+
</ScrollView>
|
|
164
|
+
</View>
|
|
165
|
+
</View>
|
|
166
|
+
);
|
|
167
|
+
};
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text Transform Tab - Scale, rotation, opacity, delete
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import React from "react";
|
|
6
|
+
import { View, ScrollView, TouchableOpacity } from "react-native";
|
|
7
|
+
import { AtomicText, AtomicIcon } from "../../../../../atoms";
|
|
8
|
+
import { useAppDesignTokens } from "../../../../../theme/hooks/useAppDesignTokens";
|
|
9
|
+
import { textEditorStyles, type TabProps } from "./TextEditorTabs.styles";
|
|
10
|
+
|
|
11
|
+
const DEFAULT_SCALES = [0.5, 0.75, 1, 1.25, 1.5, 2];
|
|
12
|
+
const DEFAULT_ROTATIONS = [0, 45, 90, 135, 180, 225, 270, 315];
|
|
13
|
+
const DEFAULT_OPACITIES = [0.2, 0.4, 0.6, 0.8, 1];
|
|
14
|
+
|
|
15
|
+
export interface TextTransformTabProps extends TabProps {
|
|
16
|
+
scale: number;
|
|
17
|
+
setScale: (s: number) => void;
|
|
18
|
+
rotation: number;
|
|
19
|
+
setRotation: (r: number) => void;
|
|
20
|
+
opacity: number;
|
|
21
|
+
setOpacity: (o: number) => void;
|
|
22
|
+
onDelete?: () => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const TextTransformTab: React.FC<TextTransformTabProps> = ({
|
|
26
|
+
scale,
|
|
27
|
+
setScale,
|
|
28
|
+
rotation,
|
|
29
|
+
setRotation,
|
|
30
|
+
opacity,
|
|
31
|
+
setOpacity,
|
|
32
|
+
onDelete,
|
|
33
|
+
}) => {
|
|
34
|
+
const tokens = useAppDesignTokens();
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<View style={{ gap: tokens.spacing.xl }}>
|
|
38
|
+
{/* Scale Selection */}
|
|
39
|
+
<View>
|
|
40
|
+
<AtomicText
|
|
41
|
+
style={{
|
|
42
|
+
...tokens.typography.labelMedium,
|
|
43
|
+
marginBottom: tokens.spacing.xs,
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
Scale: {scale.toFixed(2)}x
|
|
47
|
+
</AtomicText>
|
|
48
|
+
<ScrollView
|
|
49
|
+
horizontal
|
|
50
|
+
showsHorizontalScrollIndicator={false}
|
|
51
|
+
contentContainerStyle={{ gap: tokens.spacing.sm }}
|
|
52
|
+
>
|
|
53
|
+
{DEFAULT_SCALES.map((s) => (
|
|
54
|
+
<TouchableOpacity
|
|
55
|
+
key={s}
|
|
56
|
+
onPress={() => setScale(s)}
|
|
57
|
+
style={[
|
|
58
|
+
textEditorStyles.transformButton,
|
|
59
|
+
{
|
|
60
|
+
paddingHorizontal: tokens.spacing.md,
|
|
61
|
+
paddingVertical: tokens.spacing.sm,
|
|
62
|
+
borderRadius: tokens.borders.radius.md,
|
|
63
|
+
borderWidth: 1,
|
|
64
|
+
borderColor: scale === s ? tokens.colors.primary : tokens.colors.border,
|
|
65
|
+
backgroundColor: scale === s ? tokens.colors.primary : tokens.colors.surface,
|
|
66
|
+
},
|
|
67
|
+
]}
|
|
68
|
+
>
|
|
69
|
+
<AtomicText
|
|
70
|
+
style={{ color: scale === s ? "white" : tokens.colors.textPrimary }}
|
|
71
|
+
>
|
|
72
|
+
{s.toFixed(1)}x
|
|
73
|
+
</AtomicText>
|
|
74
|
+
</TouchableOpacity>
|
|
75
|
+
))}
|
|
76
|
+
</ScrollView>
|
|
77
|
+
</View>
|
|
78
|
+
|
|
79
|
+
{/* Rotation Selection */}
|
|
80
|
+
<View>
|
|
81
|
+
<AtomicText
|
|
82
|
+
style={{
|
|
83
|
+
...tokens.typography.labelMedium,
|
|
84
|
+
marginBottom: tokens.spacing.xs,
|
|
85
|
+
}}
|
|
86
|
+
>
|
|
87
|
+
Rotation: {Math.round(rotation)}°
|
|
88
|
+
</AtomicText>
|
|
89
|
+
<ScrollView
|
|
90
|
+
horizontal
|
|
91
|
+
showsHorizontalScrollIndicator={false}
|
|
92
|
+
contentContainerStyle={{ gap: tokens.spacing.sm }}
|
|
93
|
+
>
|
|
94
|
+
{DEFAULT_ROTATIONS.map((r) => (
|
|
95
|
+
<TouchableOpacity
|
|
96
|
+
key={r}
|
|
97
|
+
onPress={() => setRotation(r)}
|
|
98
|
+
style={[
|
|
99
|
+
textEditorStyles.transformButton,
|
|
100
|
+
{
|
|
101
|
+
paddingHorizontal: tokens.spacing.md,
|
|
102
|
+
paddingVertical: tokens.spacing.sm,
|
|
103
|
+
borderRadius: tokens.borders.radius.md,
|
|
104
|
+
borderWidth: 1,
|
|
105
|
+
borderColor: rotation === r ? tokens.colors.primary : tokens.colors.border,
|
|
106
|
+
backgroundColor: rotation === r ? tokens.colors.primary : tokens.colors.surface,
|
|
107
|
+
},
|
|
108
|
+
]}
|
|
109
|
+
>
|
|
110
|
+
<AtomicText
|
|
111
|
+
style={{ color: rotation === r ? "white" : tokens.colors.textPrimary }}
|
|
112
|
+
>
|
|
113
|
+
{r}°
|
|
114
|
+
</AtomicText>
|
|
115
|
+
</TouchableOpacity>
|
|
116
|
+
))}
|
|
117
|
+
</ScrollView>
|
|
118
|
+
</View>
|
|
119
|
+
|
|
120
|
+
{/* Opacity Selection */}
|
|
121
|
+
<View>
|
|
122
|
+
<AtomicText
|
|
123
|
+
style={{
|
|
124
|
+
...tokens.typography.labelMedium,
|
|
125
|
+
marginBottom: tokens.spacing.xs,
|
|
126
|
+
}}
|
|
127
|
+
>
|
|
128
|
+
Opacity: {(opacity * 100).toFixed(0)}%
|
|
129
|
+
</AtomicText>
|
|
130
|
+
<ScrollView
|
|
131
|
+
horizontal
|
|
132
|
+
showsHorizontalScrollIndicator={false}
|
|
133
|
+
contentContainerStyle={{ gap: tokens.spacing.sm }}
|
|
134
|
+
>
|
|
135
|
+
{DEFAULT_OPACITIES.map((o) => (
|
|
136
|
+
<TouchableOpacity
|
|
137
|
+
key={o}
|
|
138
|
+
onPress={() => setOpacity(o)}
|
|
139
|
+
style={[
|
|
140
|
+
textEditorStyles.transformButton,
|
|
141
|
+
{
|
|
142
|
+
paddingHorizontal: tokens.spacing.md,
|
|
143
|
+
paddingVertical: tokens.spacing.sm,
|
|
144
|
+
borderRadius: tokens.borders.radius.md,
|
|
145
|
+
borderWidth: 1,
|
|
146
|
+
borderColor: opacity === o ? tokens.colors.primary : tokens.colors.border,
|
|
147
|
+
backgroundColor: opacity === o ? tokens.colors.primary : tokens.colors.surface,
|
|
148
|
+
},
|
|
149
|
+
]}
|
|
150
|
+
>
|
|
151
|
+
<AtomicText
|
|
152
|
+
style={{ color: opacity === o ? "white" : tokens.colors.textPrimary }}
|
|
153
|
+
>
|
|
154
|
+
{Math.round(o * 100)}%
|
|
155
|
+
</AtomicText>
|
|
156
|
+
</TouchableOpacity>
|
|
157
|
+
))}
|
|
158
|
+
</ScrollView>
|
|
159
|
+
</View>
|
|
160
|
+
|
|
161
|
+
{/* Delete Button */}
|
|
162
|
+
{onDelete && (
|
|
163
|
+
<TouchableOpacity
|
|
164
|
+
onPress={onDelete}
|
|
165
|
+
style={[
|
|
166
|
+
textEditorStyles.deleteButton,
|
|
167
|
+
{
|
|
168
|
+
flexDirection: "row",
|
|
169
|
+
alignItems: "center",
|
|
170
|
+
justifyContent: "center",
|
|
171
|
+
gap: tokens.spacing.sm,
|
|
172
|
+
padding: tokens.spacing.md,
|
|
173
|
+
borderRadius: tokens.borders.radius.md,
|
|
174
|
+
borderWidth: 1,
|
|
175
|
+
borderColor: tokens.colors.error,
|
|
176
|
+
},
|
|
177
|
+
]}
|
|
178
|
+
>
|
|
179
|
+
<AtomicIcon name="trash" size={20} color="error" />
|
|
180
|
+
<AtomicText
|
|
181
|
+
style={{
|
|
182
|
+
...tokens.typography.labelMedium,
|
|
183
|
+
color: tokens.colors.error,
|
|
184
|
+
}}
|
|
185
|
+
>
|
|
186
|
+
Delete Layer
|
|
187
|
+
</AtomicText>
|
|
188
|
+
</TouchableOpacity>
|
|
189
|
+
)}
|
|
190
|
+
</View>
|
|
191
|
+
);
|
|
192
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text Editor Tabs - Barrel export
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export { TextContentTab } from "./TextContentTab";
|
|
6
|
+
export type { TextContentTabProps } from "./TextContentTab";
|
|
7
|
+
|
|
8
|
+
export { TextStyleTab } from "./TextStyleTab";
|
|
9
|
+
export type { TextStyleTabProps } from "./TextStyleTab";
|
|
10
|
+
|
|
11
|
+
export { TextTransformTab } from "./TextTransformTab";
|
|
12
|
+
export type { TextTransformTabProps } from "./TextTransformTab";
|
|
13
|
+
|
|
14
|
+
export { textEditorStyles, type TabProps } from "./TextEditorTabs.styles";
|
package/src/exports/molecules.ts
DELETED
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Molecules Exports
|
|
3
|
-
* Composite components
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export {
|
|
7
|
-
FormField,
|
|
8
|
-
ListItem,
|
|
9
|
-
SearchBar,
|
|
10
|
-
IconContainer,
|
|
11
|
-
BaseModal,
|
|
12
|
-
ConfirmationModal,
|
|
13
|
-
useConfirmationModal,
|
|
14
|
-
Divider,
|
|
15
|
-
type DividerProps,
|
|
16
|
-
StepProgress,
|
|
17
|
-
List,
|
|
18
|
-
Avatar,
|
|
19
|
-
AvatarGroup,
|
|
20
|
-
AvatarUtils,
|
|
21
|
-
type AvatarProps,
|
|
22
|
-
type AvatarGroupProps,
|
|
23
|
-
type AvatarGroupItem,
|
|
24
|
-
type AvatarSize,
|
|
25
|
-
type AvatarShape,
|
|
26
|
-
type AvatarConfig,
|
|
27
|
-
type AvatarType,
|
|
28
|
-
|
|
29
|
-
// Bottom Sheet
|
|
30
|
-
BottomSheet,
|
|
31
|
-
BottomSheetModal,
|
|
32
|
-
FilterBottomSheet,
|
|
33
|
-
FilterSheet,
|
|
34
|
-
useBottomSheet,
|
|
35
|
-
useBottomSheetModal,
|
|
36
|
-
useListFilters,
|
|
37
|
-
type BottomSheetProps,
|
|
38
|
-
type BottomSheetModalProps,
|
|
39
|
-
type BottomSheetRef,
|
|
40
|
-
type BottomSheetModalRef,
|
|
41
|
-
SafeBottomSheetModalProvider,
|
|
42
|
-
type FilterOption,
|
|
43
|
-
type FilterCategory,
|
|
44
|
-
// Alerts
|
|
45
|
-
AlertBanner,
|
|
46
|
-
AlertToast,
|
|
47
|
-
AlertInline,
|
|
48
|
-
AlertModal,
|
|
49
|
-
AlertContainer,
|
|
50
|
-
AlertProvider,
|
|
51
|
-
AlertService,
|
|
52
|
-
useAlert,
|
|
53
|
-
useAlertStore,
|
|
54
|
-
alertService,
|
|
55
|
-
AlertType,
|
|
56
|
-
AlertMode,
|
|
57
|
-
AlertPosition,
|
|
58
|
-
type BaseModalProps,
|
|
59
|
-
type ListProps,
|
|
60
|
-
type Alert,
|
|
61
|
-
type AlertAction,
|
|
62
|
-
type AlertOptions,
|
|
63
|
-
// Calendar
|
|
64
|
-
AtomicCalendar,
|
|
65
|
-
useCalendar,
|
|
66
|
-
useCalendarEvents,
|
|
67
|
-
useCalendarNavigation,
|
|
68
|
-
useCalendarView,
|
|
69
|
-
CalendarService,
|
|
70
|
-
CalendarGeneration,
|
|
71
|
-
DateUtilities,
|
|
72
|
-
type AtomicCalendarProps,
|
|
73
|
-
type CalendarEvent,
|
|
74
|
-
type CalendarViewMode,
|
|
75
|
-
type CreateCalendarEventRequest,
|
|
76
|
-
type UpdateCalendarEventRequest,
|
|
77
|
-
type CalendarDay,
|
|
78
|
-
type CalendarMonth,
|
|
79
|
-
type CalendarWeek,
|
|
80
|
-
type ICalendarRepository,
|
|
81
|
-
// Swipe Actions
|
|
82
|
-
SwipeActionButton,
|
|
83
|
-
SwipeActionUtils,
|
|
84
|
-
ACTION_PRESETS,
|
|
85
|
-
DEFAULT_SWIPE_CONFIG,
|
|
86
|
-
type SwipeActionButtonProps,
|
|
87
|
-
type SwipeActionType,
|
|
88
|
-
type SwipeActionConfig,
|
|
89
|
-
type SwipeDirection,
|
|
90
|
-
type SwipeableConfig,
|
|
91
|
-
// Navigation
|
|
92
|
-
TabsNavigator,
|
|
93
|
-
StackNavigator,
|
|
94
|
-
createTabNavigator,
|
|
95
|
-
createStackNavigator,
|
|
96
|
-
FabButton,
|
|
97
|
-
NavigationCleanupManager,
|
|
98
|
-
AppNavigation,
|
|
99
|
-
NavigationContainer,
|
|
100
|
-
TabLabel,
|
|
101
|
-
NavigationHeader,
|
|
102
|
-
createScreenOptions,
|
|
103
|
-
createNavigationTheme,
|
|
104
|
-
useTabBarStyles,
|
|
105
|
-
useTabConfig,
|
|
106
|
-
useAppNavigation,
|
|
107
|
-
useAppRoute,
|
|
108
|
-
useAppFocusEffect,
|
|
109
|
-
useAppIsFocused,
|
|
110
|
-
type NavigationHeaderProps,
|
|
111
|
-
type ScreenOptionsParams,
|
|
112
|
-
type TabsNavigatorProps,
|
|
113
|
-
type StackNavigatorProps,
|
|
114
|
-
type StackNavigatorConfig,
|
|
115
|
-
type StackScreen,
|
|
116
|
-
type FabButtonProps,
|
|
117
|
-
type TabScreen,
|
|
118
|
-
type TabNavigatorConfig,
|
|
119
|
-
type BaseScreen,
|
|
120
|
-
type BaseNavigatorConfig,
|
|
121
|
-
type IconRendererProps,
|
|
122
|
-
type LabelProcessorProps,
|
|
123
|
-
type FabConfig,
|
|
124
|
-
type NavigationCleanup,
|
|
125
|
-
type BottomTabNavigationOptions,
|
|
126
|
-
type BottomTabScreenProps,
|
|
127
|
-
type StackNavigationOptions,
|
|
128
|
-
type StackScreenProps,
|
|
129
|
-
type RouteProp,
|
|
130
|
-
type TabLabelProps,
|
|
131
|
-
type TabBarConfig,
|
|
132
|
-
// Long Press Menu
|
|
133
|
-
type MenuAction,
|
|
134
|
-
type MenuActionTypeValue,
|
|
135
|
-
MenuActionType,
|
|
136
|
-
// Emoji
|
|
137
|
-
EmojiPicker,
|
|
138
|
-
useEmojiPicker,
|
|
139
|
-
EmojiCategory,
|
|
140
|
-
EmojiUtils,
|
|
141
|
-
type EmojiObject,
|
|
142
|
-
type EmojiPickerConfig,
|
|
143
|
-
type EmojiSelectCallback,
|
|
144
|
-
type EmojiPickerState,
|
|
145
|
-
type EmojiPickerProps,
|
|
146
|
-
type UseEmojiPickerOptions,
|
|
147
|
-
type UseEmojiPickerReturn,
|
|
148
|
-
// Countdown
|
|
149
|
-
Countdown,
|
|
150
|
-
TimeUnit,
|
|
151
|
-
CountdownHeader,
|
|
152
|
-
useCountdown,
|
|
153
|
-
calculateTimeRemaining,
|
|
154
|
-
padNumber,
|
|
155
|
-
getNextDayStart,
|
|
156
|
-
getNextYearStart,
|
|
157
|
-
type CountdownProps,
|
|
158
|
-
type TimeUnitProps,
|
|
159
|
-
type CountdownHeaderProps,
|
|
160
|
-
type UseCountdownOptions,
|
|
161
|
-
type UseCountdownReturn,
|
|
162
|
-
type TimeRemaining,
|
|
163
|
-
type CountdownTarget,
|
|
164
|
-
type CountdownFormatOptions,
|
|
165
|
-
type CountdownDisplayConfig,
|
|
166
|
-
// Step Header
|
|
167
|
-
StepHeader,
|
|
168
|
-
type StepHeaderProps,
|
|
169
|
-
type StepHeaderConfig,
|
|
170
|
-
// Splash
|
|
171
|
-
SplashScreen,
|
|
172
|
-
useSplashFlow,
|
|
173
|
-
type SplashScreenProps,
|
|
174
|
-
type SplashColors,
|
|
175
|
-
type UseSplashFlowOptions,
|
|
176
|
-
type UseSplashFlowResult,
|
|
177
|
-
|
|
178
|
-
// Filter Group
|
|
179
|
-
FilterGroup,
|
|
180
|
-
type FilterGroupProps,
|
|
181
|
-
type FilterGroupItem,
|
|
182
|
-
// Action Footer
|
|
183
|
-
ActionFooter,
|
|
184
|
-
type ActionFooterProps,
|
|
185
|
-
|
|
186
|
-
// Hero Section
|
|
187
|
-
HeroSection,
|
|
188
|
-
type HeroSectionProps,
|
|
189
|
-
// Info Grid
|
|
190
|
-
InfoGrid,
|
|
191
|
-
type InfoGridProps,
|
|
192
|
-
type InfoGridItem,
|
|
193
|
-
|
|
194
|
-
// Circular Menu
|
|
195
|
-
CircularMenu,
|
|
196
|
-
CircularMenuItem,
|
|
197
|
-
CircularMenuBackground,
|
|
198
|
-
CircularMenuCloseButton,
|
|
199
|
-
type CircularMenuProps,
|
|
200
|
-
type CircularMenuAction,
|
|
201
|
-
} from "../molecules";
|
|
@@ -1,424 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Presentation - Text Editor Tabs
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import React from "react";
|
|
6
|
-
import {
|
|
7
|
-
View,
|
|
8
|
-
TextInput,
|
|
9
|
-
ScrollView,
|
|
10
|
-
TouchableOpacity,
|
|
11
|
-
StyleSheet,
|
|
12
|
-
} from "react-native";
|
|
13
|
-
import { AtomicText, AtomicIcon } from "../../../../atoms";
|
|
14
|
-
import { useAppDesignTokens } from "../../../../theme/hooks/useAppDesignTokens";
|
|
15
|
-
|
|
16
|
-
interface TabProps {
|
|
17
|
-
t: (key: string) => string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const TextContentTab: React.FC<
|
|
21
|
-
TabProps & { text: string; onTextChange: (t: string) => void }
|
|
22
|
-
> = ({ text, onTextChange, t }) => {
|
|
23
|
-
const tokens = useAppDesignTokens();
|
|
24
|
-
return (
|
|
25
|
-
<View style={{ gap: tokens.spacing.lg }}>
|
|
26
|
-
<TextInput
|
|
27
|
-
value={text}
|
|
28
|
-
onChangeText={onTextChange}
|
|
29
|
-
placeholder={t("editor.text_placeholder")}
|
|
30
|
-
style={[
|
|
31
|
-
styles.textInput,
|
|
32
|
-
{
|
|
33
|
-
...tokens.typography.bodyLarge,
|
|
34
|
-
borderColor: tokens.colors.border,
|
|
35
|
-
borderRadius: tokens.borders.radius.md,
|
|
36
|
-
padding: tokens.spacing.md,
|
|
37
|
-
minHeight: 120,
|
|
38
|
-
color: tokens.colors.textPrimary,
|
|
39
|
-
},
|
|
40
|
-
]}
|
|
41
|
-
multiline
|
|
42
|
-
/>
|
|
43
|
-
</View>
|
|
44
|
-
);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export const TextStyleTab: React.FC<
|
|
48
|
-
TabProps & {
|
|
49
|
-
fontSize: number;
|
|
50
|
-
setFontSize: (s: number) => void;
|
|
51
|
-
color: string;
|
|
52
|
-
setColor: (c: string) => void;
|
|
53
|
-
fontFamily: string;
|
|
54
|
-
setFontFamily: (f: string) => void;
|
|
55
|
-
}
|
|
56
|
-
> = ({ fontSize, setFontSize, color, setColor, fontFamily, setFontFamily }) => {
|
|
57
|
-
const tokens = useAppDesignTokens();
|
|
58
|
-
const colors = [
|
|
59
|
-
"#FFFFFF",
|
|
60
|
-
"#000000",
|
|
61
|
-
"#FF0000",
|
|
62
|
-
"#FFFF00",
|
|
63
|
-
"#0000FF",
|
|
64
|
-
"#00FF00",
|
|
65
|
-
"#FF00FF",
|
|
66
|
-
"#FFA500",
|
|
67
|
-
];
|
|
68
|
-
const fonts = ["System", "serif", "sans-serif", "monospace"];
|
|
69
|
-
const fontSizes = [12, 14, 16, 18, 20, 24, 28, 32];
|
|
70
|
-
|
|
71
|
-
return (
|
|
72
|
-
<View style={{ gap: tokens.spacing.xl }}>
|
|
73
|
-
<View>
|
|
74
|
-
<AtomicText
|
|
75
|
-
style={{
|
|
76
|
-
...tokens.typography.labelMedium,
|
|
77
|
-
marginBottom: tokens.spacing.sm,
|
|
78
|
-
}}
|
|
79
|
-
>
|
|
80
|
-
Font
|
|
81
|
-
</AtomicText>
|
|
82
|
-
<ScrollView
|
|
83
|
-
horizontal
|
|
84
|
-
showsHorizontalScrollIndicator={false}
|
|
85
|
-
contentContainerStyle={{ gap: tokens.spacing.sm }}
|
|
86
|
-
>
|
|
87
|
-
{fonts.map((f) => (
|
|
88
|
-
<TouchableOpacity
|
|
89
|
-
key={f}
|
|
90
|
-
onPress={() => setFontFamily(f)}
|
|
91
|
-
style={[
|
|
92
|
-
styles.fontButton,
|
|
93
|
-
{
|
|
94
|
-
paddingHorizontal: tokens.spacing.md,
|
|
95
|
-
paddingVertical: tokens.spacing.xs,
|
|
96
|
-
borderRadius: tokens.borders.radius.full,
|
|
97
|
-
borderWidth: 1,
|
|
98
|
-
borderColor:
|
|
99
|
-
fontFamily === f
|
|
100
|
-
? tokens.colors.primary
|
|
101
|
-
: tokens.colors.border,
|
|
102
|
-
backgroundColor:
|
|
103
|
-
fontFamily === f
|
|
104
|
-
? tokens.colors.primary
|
|
105
|
-
: tokens.colors.surface,
|
|
106
|
-
},
|
|
107
|
-
]}
|
|
108
|
-
>
|
|
109
|
-
<AtomicText style={{ fontFamily: f }}>{f}</AtomicText>
|
|
110
|
-
</TouchableOpacity>
|
|
111
|
-
))}
|
|
112
|
-
</ScrollView>
|
|
113
|
-
</View>
|
|
114
|
-
|
|
115
|
-
<View>
|
|
116
|
-
<AtomicText
|
|
117
|
-
style={{
|
|
118
|
-
...tokens.typography.labelMedium,
|
|
119
|
-
marginBottom: tokens.spacing.sm,
|
|
120
|
-
}}
|
|
121
|
-
>
|
|
122
|
-
Color
|
|
123
|
-
</AtomicText>
|
|
124
|
-
<ScrollView
|
|
125
|
-
horizontal
|
|
126
|
-
showsHorizontalScrollIndicator={false}
|
|
127
|
-
contentContainerStyle={{ gap: tokens.spacing.sm }}
|
|
128
|
-
>
|
|
129
|
-
{colors.map((c) => (
|
|
130
|
-
<TouchableOpacity
|
|
131
|
-
key={c}
|
|
132
|
-
onPress={() => setColor(c)}
|
|
133
|
-
style={[
|
|
134
|
-
styles.colorButton,
|
|
135
|
-
{
|
|
136
|
-
width: 40,
|
|
137
|
-
height: 40,
|
|
138
|
-
borderRadius: 20,
|
|
139
|
-
backgroundColor: c,
|
|
140
|
-
borderWidth: color === c ? 3 : 1,
|
|
141
|
-
borderColor: tokens.colors.primary,
|
|
142
|
-
},
|
|
143
|
-
]}
|
|
144
|
-
/>
|
|
145
|
-
))}
|
|
146
|
-
</ScrollView>
|
|
147
|
-
</View>
|
|
148
|
-
|
|
149
|
-
<View>
|
|
150
|
-
<AtomicText
|
|
151
|
-
style={{
|
|
152
|
-
...tokens.typography.labelMedium,
|
|
153
|
-
marginBottom: tokens.spacing.xs,
|
|
154
|
-
}}
|
|
155
|
-
>
|
|
156
|
-
Size: {fontSize}px
|
|
157
|
-
</AtomicText>
|
|
158
|
-
<ScrollView
|
|
159
|
-
horizontal
|
|
160
|
-
showsHorizontalScrollIndicator={false}
|
|
161
|
-
contentContainerStyle={{ gap: tokens.spacing.sm }}
|
|
162
|
-
>
|
|
163
|
-
{fontSizes.map((s) => (
|
|
164
|
-
<TouchableOpacity
|
|
165
|
-
key={s}
|
|
166
|
-
onPress={() => setFontSize(s)}
|
|
167
|
-
style={[
|
|
168
|
-
styles.sizeButton,
|
|
169
|
-
{
|
|
170
|
-
paddingHorizontal: tokens.spacing.md,
|
|
171
|
-
paddingVertical: tokens.spacing.sm,
|
|
172
|
-
borderRadius: tokens.borders.radius.md,
|
|
173
|
-
borderWidth: 1,
|
|
174
|
-
borderColor:
|
|
175
|
-
fontSize === s
|
|
176
|
-
? tokens.colors.primary
|
|
177
|
-
: tokens.colors.border,
|
|
178
|
-
backgroundColor:
|
|
179
|
-
fontSize === s
|
|
180
|
-
? tokens.colors.primary
|
|
181
|
-
: tokens.colors.surface,
|
|
182
|
-
},
|
|
183
|
-
]}
|
|
184
|
-
>
|
|
185
|
-
<AtomicText
|
|
186
|
-
style={{
|
|
187
|
-
color: fontSize === s ? "white" : tokens.colors.textPrimary,
|
|
188
|
-
fontWeight: "600",
|
|
189
|
-
}}
|
|
190
|
-
>
|
|
191
|
-
{s}
|
|
192
|
-
</AtomicText>
|
|
193
|
-
</TouchableOpacity>
|
|
194
|
-
))}
|
|
195
|
-
</ScrollView>
|
|
196
|
-
</View>
|
|
197
|
-
</View>
|
|
198
|
-
);
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
export const TextTransformTab: React.FC<
|
|
202
|
-
TabProps & {
|
|
203
|
-
scale: number;
|
|
204
|
-
setScale: (s: number) => void;
|
|
205
|
-
rotation: number;
|
|
206
|
-
setRotation: (r: number) => void;
|
|
207
|
-
opacity: number;
|
|
208
|
-
setOpacity: (o: number) => void;
|
|
209
|
-
onDelete?: () => void;
|
|
210
|
-
}
|
|
211
|
-
> = ({
|
|
212
|
-
scale,
|
|
213
|
-
setScale,
|
|
214
|
-
rotation,
|
|
215
|
-
setRotation,
|
|
216
|
-
opacity,
|
|
217
|
-
setOpacity,
|
|
218
|
-
onDelete,
|
|
219
|
-
}) => {
|
|
220
|
-
const tokens = useAppDesignTokens();
|
|
221
|
-
const scales = [0.5, 0.75, 1, 1.25, 1.5, 2];
|
|
222
|
-
const rotations = [0, 45, 90, 135, 180, 225, 270, 315];
|
|
223
|
-
const opacities = [0.2, 0.4, 0.6, 0.8, 1];
|
|
224
|
-
|
|
225
|
-
return (
|
|
226
|
-
<View style={{ gap: tokens.spacing.xl }}>
|
|
227
|
-
<View>
|
|
228
|
-
<AtomicText
|
|
229
|
-
style={{
|
|
230
|
-
...tokens.typography.labelMedium,
|
|
231
|
-
marginBottom: tokens.spacing.xs,
|
|
232
|
-
}}
|
|
233
|
-
>
|
|
234
|
-
Scale: {scale.toFixed(2)}x
|
|
235
|
-
</AtomicText>
|
|
236
|
-
<ScrollView
|
|
237
|
-
horizontal
|
|
238
|
-
showsHorizontalScrollIndicator={false}
|
|
239
|
-
contentContainerStyle={{ gap: tokens.spacing.sm }}
|
|
240
|
-
>
|
|
241
|
-
{scales.map((s) => (
|
|
242
|
-
<TouchableOpacity
|
|
243
|
-
key={s}
|
|
244
|
-
onPress={() => setScale(s)}
|
|
245
|
-
style={[
|
|
246
|
-
styles.transformButton,
|
|
247
|
-
{
|
|
248
|
-
paddingHorizontal: tokens.spacing.md,
|
|
249
|
-
paddingVertical: tokens.spacing.sm,
|
|
250
|
-
borderRadius: tokens.borders.radius.md,
|
|
251
|
-
borderWidth: 1,
|
|
252
|
-
borderColor:
|
|
253
|
-
scale === s ? tokens.colors.primary : tokens.colors.border,
|
|
254
|
-
backgroundColor:
|
|
255
|
-
scale === s ? tokens.colors.primary : tokens.colors.surface,
|
|
256
|
-
},
|
|
257
|
-
]}
|
|
258
|
-
>
|
|
259
|
-
<AtomicText
|
|
260
|
-
style={{
|
|
261
|
-
color: scale === s ? "white" : tokens.colors.textPrimary,
|
|
262
|
-
}}
|
|
263
|
-
>
|
|
264
|
-
{s.toFixed(1)}x
|
|
265
|
-
</AtomicText>
|
|
266
|
-
</TouchableOpacity>
|
|
267
|
-
))}
|
|
268
|
-
</ScrollView>
|
|
269
|
-
</View>
|
|
270
|
-
|
|
271
|
-
<View>
|
|
272
|
-
<AtomicText
|
|
273
|
-
style={{
|
|
274
|
-
...tokens.typography.labelMedium,
|
|
275
|
-
marginBottom: tokens.spacing.xs,
|
|
276
|
-
}}
|
|
277
|
-
>
|
|
278
|
-
Rotation: {Math.round(rotation)}°
|
|
279
|
-
</AtomicText>
|
|
280
|
-
<ScrollView
|
|
281
|
-
horizontal
|
|
282
|
-
showsHorizontalScrollIndicator={false}
|
|
283
|
-
contentContainerStyle={{ gap: tokens.spacing.sm }}
|
|
284
|
-
>
|
|
285
|
-
{rotations.map((r) => (
|
|
286
|
-
<TouchableOpacity
|
|
287
|
-
key={r}
|
|
288
|
-
onPress={() => setRotation(r)}
|
|
289
|
-
style={[
|
|
290
|
-
styles.transformButton,
|
|
291
|
-
{
|
|
292
|
-
paddingHorizontal: tokens.spacing.md,
|
|
293
|
-
paddingVertical: tokens.spacing.sm,
|
|
294
|
-
borderRadius: tokens.borders.radius.md,
|
|
295
|
-
borderWidth: 1,
|
|
296
|
-
borderColor:
|
|
297
|
-
rotation === r
|
|
298
|
-
? tokens.colors.primary
|
|
299
|
-
: tokens.colors.border,
|
|
300
|
-
backgroundColor:
|
|
301
|
-
rotation === r
|
|
302
|
-
? tokens.colors.primary
|
|
303
|
-
: tokens.colors.surface,
|
|
304
|
-
},
|
|
305
|
-
]}
|
|
306
|
-
>
|
|
307
|
-
<AtomicText
|
|
308
|
-
style={{
|
|
309
|
-
color: rotation === r ? "white" : tokens.colors.textPrimary,
|
|
310
|
-
}}
|
|
311
|
-
>
|
|
312
|
-
{r}°
|
|
313
|
-
</AtomicText>
|
|
314
|
-
</TouchableOpacity>
|
|
315
|
-
))}
|
|
316
|
-
</ScrollView>
|
|
317
|
-
</View>
|
|
318
|
-
|
|
319
|
-
<View>
|
|
320
|
-
<AtomicText
|
|
321
|
-
style={{
|
|
322
|
-
...tokens.typography.labelMedium,
|
|
323
|
-
marginBottom: tokens.spacing.xs,
|
|
324
|
-
}}
|
|
325
|
-
>
|
|
326
|
-
Opacity: {(opacity * 100).toFixed(0)}%
|
|
327
|
-
</AtomicText>
|
|
328
|
-
<ScrollView
|
|
329
|
-
horizontal
|
|
330
|
-
showsHorizontalScrollIndicator={false}
|
|
331
|
-
contentContainerStyle={{ gap: tokens.spacing.sm }}
|
|
332
|
-
>
|
|
333
|
-
{opacities.map((o) => (
|
|
334
|
-
<TouchableOpacity
|
|
335
|
-
key={o}
|
|
336
|
-
onPress={() => setOpacity(o)}
|
|
337
|
-
style={[
|
|
338
|
-
styles.transformButton,
|
|
339
|
-
{
|
|
340
|
-
paddingHorizontal: tokens.spacing.md,
|
|
341
|
-
paddingVertical: tokens.spacing.sm,
|
|
342
|
-
borderRadius: tokens.borders.radius.md,
|
|
343
|
-
borderWidth: 1,
|
|
344
|
-
borderColor:
|
|
345
|
-
opacity === o
|
|
346
|
-
? tokens.colors.primary
|
|
347
|
-
: tokens.colors.border,
|
|
348
|
-
backgroundColor:
|
|
349
|
-
opacity === o
|
|
350
|
-
? tokens.colors.primary
|
|
351
|
-
: tokens.colors.surface,
|
|
352
|
-
},
|
|
353
|
-
]}
|
|
354
|
-
>
|
|
355
|
-
<AtomicText
|
|
356
|
-
style={{
|
|
357
|
-
color: opacity === o ? "white" : tokens.colors.textPrimary,
|
|
358
|
-
}}
|
|
359
|
-
>
|
|
360
|
-
{Math.round(o * 100)}%
|
|
361
|
-
</AtomicText>
|
|
362
|
-
</TouchableOpacity>
|
|
363
|
-
))}
|
|
364
|
-
</ScrollView>
|
|
365
|
-
</View>
|
|
366
|
-
|
|
367
|
-
{onDelete && (
|
|
368
|
-
<TouchableOpacity
|
|
369
|
-
onPress={onDelete}
|
|
370
|
-
style={[
|
|
371
|
-
styles.deleteButton,
|
|
372
|
-
{
|
|
373
|
-
flexDirection: "row",
|
|
374
|
-
alignItems: "center",
|
|
375
|
-
justifyContent: "center",
|
|
376
|
-
gap: tokens.spacing.sm,
|
|
377
|
-
padding: tokens.spacing.md,
|
|
378
|
-
borderRadius: tokens.borders.radius.md,
|
|
379
|
-
borderWidth: 1,
|
|
380
|
-
borderColor: tokens.colors.error,
|
|
381
|
-
},
|
|
382
|
-
]}
|
|
383
|
-
>
|
|
384
|
-
<AtomicIcon name="trash" size={20} color="error" />
|
|
385
|
-
<AtomicText
|
|
386
|
-
style={{
|
|
387
|
-
...tokens.typography.labelMedium,
|
|
388
|
-
color: tokens.colors.error,
|
|
389
|
-
}}
|
|
390
|
-
>
|
|
391
|
-
Delete Layer
|
|
392
|
-
</AtomicText>
|
|
393
|
-
</TouchableOpacity>
|
|
394
|
-
)}
|
|
395
|
-
</View>
|
|
396
|
-
);
|
|
397
|
-
};
|
|
398
|
-
|
|
399
|
-
const styles = StyleSheet.create({
|
|
400
|
-
textInput: {
|
|
401
|
-
borderWidth: 1,
|
|
402
|
-
textAlignVertical: "top",
|
|
403
|
-
},
|
|
404
|
-
fontButton: {
|
|
405
|
-
paddingVertical: 8,
|
|
406
|
-
minWidth: 80,
|
|
407
|
-
alignItems: "center",
|
|
408
|
-
},
|
|
409
|
-
colorButton: {
|
|
410
|
-
width: 40,
|
|
411
|
-
height: 40,
|
|
412
|
-
},
|
|
413
|
-
sizeButton: {
|
|
414
|
-
minWidth: 50,
|
|
415
|
-
alignItems: "center",
|
|
416
|
-
},
|
|
417
|
-
transformButton: {
|
|
418
|
-
minWidth: 60,
|
|
419
|
-
alignItems: "center",
|
|
420
|
-
},
|
|
421
|
-
deleteButton: {
|
|
422
|
-
alignSelf: "flex-start",
|
|
423
|
-
},
|
|
424
|
-
});
|