@umituz/react-native-design-system 2.1.7 → 2.2.0
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/atoms/AtomicText.tsx +15 -2
- package/src/index.ts +14 -0
- package/src/molecules/Container/Container.tsx +76 -0
- package/src/molecules/Container/index.ts +1 -0
- package/src/molecules/Grid/Grid.tsx +94 -0
- package/src/molecules/Grid/index.ts +1 -0
- package/src/molecules/List/List.tsx +85 -0
- package/src/molecules/List/index.ts +1 -0
- package/src/molecules/index.ts +5 -0
- package/src/organisms/FormLayout/FormLayout.tsx +117 -0
- package/src/organisms/FormLayout/index.ts +1 -0
- package/src/organisms/index.ts +6 -2
- package/src/theme/core/ResponsiveTokenFactory.ts +266 -0
- package/src/theme/hooks/useResponsiveDesignTokens.ts +82 -0
- package/src/theme/index.ts +13 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-design-system",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Universal design system for React Native apps - Consolidated package with atoms, molecules, organisms, theme, typography, responsive and safe area utilities",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
package/src/atoms/AtomicText.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Text, StyleProp, TextStyle } from 'react-native';
|
|
3
|
-
import { useAppDesignTokens } from '../theme';
|
|
3
|
+
import { useAppDesignTokens, useResponsiveDesignTokens } from '../theme';
|
|
4
4
|
import type { TextStyleVariant, ColorVariant } from '../typography';
|
|
5
5
|
import { getTextColor } from '../typography';
|
|
6
6
|
|
|
@@ -13,6 +13,8 @@ export interface AtomicTextProps {
|
|
|
13
13
|
textAlign?: 'auto' | 'left' | 'right' | 'center' | 'justify';
|
|
14
14
|
style?: StyleProp<TextStyle>;
|
|
15
15
|
testID?: string;
|
|
16
|
+
/** Enable responsive font sizing (scales based on device) */
|
|
17
|
+
responsive?: boolean;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
export const AtomicText: React.FC<AtomicTextProps> = ({
|
|
@@ -24,8 +26,13 @@ export const AtomicText: React.FC<AtomicTextProps> = ({
|
|
|
24
26
|
textAlign,
|
|
25
27
|
style,
|
|
26
28
|
testID,
|
|
29
|
+
responsive = false,
|
|
27
30
|
}) => {
|
|
28
|
-
const
|
|
31
|
+
const staticTokens = useAppDesignTokens();
|
|
32
|
+
const responsiveTokens = useResponsiveDesignTokens();
|
|
33
|
+
|
|
34
|
+
// Use responsive tokens if enabled, otherwise use static
|
|
35
|
+
const tokens = responsive ? responsiveTokens : staticTokens;
|
|
29
36
|
|
|
30
37
|
// Get typography style from tokens
|
|
31
38
|
const typographyStyle = (tokens.typography as Record<string, any>)[type];
|
|
@@ -33,10 +40,16 @@ export const AtomicText: React.FC<AtomicTextProps> = ({
|
|
|
33
40
|
// Get color from tokens or use custom color using utility function
|
|
34
41
|
const resolvedColor = getTextColor(color, tokens);
|
|
35
42
|
|
|
43
|
+
// Use responsive font size if enabled and available
|
|
44
|
+
const fontSize = responsive && typographyStyle.responsiveFontSize
|
|
45
|
+
? typographyStyle.responsiveFontSize
|
|
46
|
+
: typographyStyle.fontSize;
|
|
47
|
+
|
|
36
48
|
const textStyle: StyleProp<TextStyle> = [
|
|
37
49
|
typographyStyle,
|
|
38
50
|
{
|
|
39
51
|
color: resolvedColor,
|
|
52
|
+
...(fontSize && { fontSize }),
|
|
40
53
|
...(textAlign && { textAlign }),
|
|
41
54
|
},
|
|
42
55
|
style,
|
package/src/index.ts
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
export {
|
|
20
20
|
useAppDesignTokens,
|
|
21
|
+
useResponsiveDesignTokens,
|
|
21
22
|
useCommonStyles,
|
|
22
23
|
useDesignSystemTheme,
|
|
23
24
|
useTheme,
|
|
@@ -33,6 +34,7 @@ export {
|
|
|
33
34
|
typography,
|
|
34
35
|
borders,
|
|
35
36
|
createDesignTokens,
|
|
37
|
+
createResponsiveDesignTokens,
|
|
36
38
|
lightTheme,
|
|
37
39
|
darkTheme,
|
|
38
40
|
createResponsiveValue,
|
|
@@ -51,6 +53,10 @@ export {
|
|
|
51
53
|
type AvatarSizes,
|
|
52
54
|
type ComponentSizes,
|
|
53
55
|
type DesignTokens,
|
|
56
|
+
type ResponsiveDesignTokens,
|
|
57
|
+
type ResponsiveSpacing,
|
|
58
|
+
type ResponsiveTypography,
|
|
59
|
+
type ResponsiveBorderRadius,
|
|
54
60
|
type Theme,
|
|
55
61
|
type ExtendedColorPalette,
|
|
56
62
|
type NavigationTheme,
|
|
@@ -177,7 +183,13 @@ export {
|
|
|
177
183
|
ConfirmationModal,
|
|
178
184
|
useConfirmationModal,
|
|
179
185
|
StepProgress,
|
|
186
|
+
Grid,
|
|
187
|
+
List,
|
|
188
|
+
Container,
|
|
180
189
|
type BaseModalProps,
|
|
190
|
+
type GridProps,
|
|
191
|
+
type ListProps,
|
|
192
|
+
type ContainerProps,
|
|
181
193
|
} from './molecules';
|
|
182
194
|
|
|
183
195
|
// =============================================================================
|
|
@@ -188,6 +200,8 @@ export {
|
|
|
188
200
|
ScreenLayout,
|
|
189
201
|
AppHeader,
|
|
190
202
|
FormContainer,
|
|
203
|
+
FormLayout,
|
|
204
|
+
type FormLayoutProps,
|
|
191
205
|
} from './organisms';
|
|
192
206
|
|
|
193
207
|
// =============================================================================
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Container - Max-Width Content Container (Molecule)
|
|
3
|
+
*
|
|
4
|
+
* Centers content with responsive max-width based on device
|
|
5
|
+
* Prevents content from being too wide on tablets
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React, { useMemo } from 'react';
|
|
9
|
+
import { View, StyleSheet, type StyleProp, type ViewStyle } from 'react-native';
|
|
10
|
+
import { useResponsive } from '../../responsive';
|
|
11
|
+
import { useResponsiveDesignTokens } from '../../theme';
|
|
12
|
+
|
|
13
|
+
export interface ContainerProps {
|
|
14
|
+
/** Container content */
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
|
|
17
|
+
/** Maximum width (default: responsive based on device) */
|
|
18
|
+
maxWidth?: number;
|
|
19
|
+
|
|
20
|
+
/** Horizontal padding (uses responsive tokens) */
|
|
21
|
+
padding?: boolean;
|
|
22
|
+
|
|
23
|
+
/** Center content horizontally */
|
|
24
|
+
center?: boolean;
|
|
25
|
+
|
|
26
|
+
/** Container style */
|
|
27
|
+
style?: StyleProp<ViewStyle>;
|
|
28
|
+
|
|
29
|
+
/** Test ID */
|
|
30
|
+
testID?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Responsive container with max-width
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* <Container maxWidth={600} padding center>
|
|
39
|
+
* <Text>Centered content with max width</Text>
|
|
40
|
+
* </Container>
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export const Container: React.FC<ContainerProps> = ({
|
|
44
|
+
children,
|
|
45
|
+
maxWidth,
|
|
46
|
+
padding = true,
|
|
47
|
+
center = true,
|
|
48
|
+
style,
|
|
49
|
+
testID,
|
|
50
|
+
}) => {
|
|
51
|
+
const { maxContentWidth } = useResponsive();
|
|
52
|
+
const tokens = useResponsiveDesignTokens();
|
|
53
|
+
|
|
54
|
+
const containerWidth = maxWidth || maxContentWidth;
|
|
55
|
+
|
|
56
|
+
const styles = useMemo(
|
|
57
|
+
() =>
|
|
58
|
+
StyleSheet.create({
|
|
59
|
+
container: {
|
|
60
|
+
width: '100%',
|
|
61
|
+
maxWidth: containerWidth,
|
|
62
|
+
...(center && { alignSelf: 'center' }),
|
|
63
|
+
...(padding && {
|
|
64
|
+
paddingHorizontal: tokens.spacing.screenPadding,
|
|
65
|
+
}),
|
|
66
|
+
},
|
|
67
|
+
}),
|
|
68
|
+
[containerWidth, center, padding, tokens.spacing.screenPadding]
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<View style={[styles.container, style]} testID={testID}>
|
|
73
|
+
{children}
|
|
74
|
+
</View>
|
|
75
|
+
);
|
|
76
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Container, type ContainerProps } from './Container';
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grid - Responsive Grid Layout (Molecule)
|
|
3
|
+
*
|
|
4
|
+
* Automatic responsive grid that adjusts columns based on device
|
|
5
|
+
* Uses design system responsive utilities
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React, { useMemo } from 'react';
|
|
9
|
+
import { View, StyleSheet, type StyleProp, type ViewStyle } from 'react-native';
|
|
10
|
+
import { useResponsive } from '../../responsive';
|
|
11
|
+
import { useResponsiveDesignTokens } from '../../theme';
|
|
12
|
+
|
|
13
|
+
export interface GridProps {
|
|
14
|
+
/** Grid items to render */
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
|
|
17
|
+
/** Number of columns on mobile (default: 2) */
|
|
18
|
+
mobileColumns?: number;
|
|
19
|
+
|
|
20
|
+
/** Number of columns on tablet (default: 4) */
|
|
21
|
+
tabletColumns?: number;
|
|
22
|
+
|
|
23
|
+
/** Gap between grid items (uses design tokens spacing) */
|
|
24
|
+
gap?: number;
|
|
25
|
+
|
|
26
|
+
/** Container style */
|
|
27
|
+
style?: StyleProp<ViewStyle>;
|
|
28
|
+
|
|
29
|
+
/** Test ID for testing */
|
|
30
|
+
testID?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Responsive grid component
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* <Grid mobileColumns={2} tabletColumns={4} gap={16}>
|
|
39
|
+
* <Card />
|
|
40
|
+
* <Card />
|
|
41
|
+
* <Card />
|
|
42
|
+
* </Grid>
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export const Grid: React.FC<GridProps> = ({
|
|
46
|
+
children,
|
|
47
|
+
mobileColumns = 2,
|
|
48
|
+
tabletColumns = 4,
|
|
49
|
+
gap,
|
|
50
|
+
style,
|
|
51
|
+
testID,
|
|
52
|
+
}) => {
|
|
53
|
+
const { gridColumns, spacingMultiplier } = useResponsive();
|
|
54
|
+
const tokens = useResponsiveDesignTokens();
|
|
55
|
+
|
|
56
|
+
// Calculate responsive columns
|
|
57
|
+
const columns = gridColumns || (mobileColumns && tabletColumns
|
|
58
|
+
? undefined
|
|
59
|
+
: mobileColumns);
|
|
60
|
+
|
|
61
|
+
// Use responsive gap or default
|
|
62
|
+
const responsiveGap = gap ? gap * spacingMultiplier : tokens.spacing.md;
|
|
63
|
+
|
|
64
|
+
const styles = useMemo(
|
|
65
|
+
() =>
|
|
66
|
+
StyleSheet.create({
|
|
67
|
+
container: {
|
|
68
|
+
flexDirection: 'row',
|
|
69
|
+
flexWrap: 'wrap',
|
|
70
|
+
gap: responsiveGap,
|
|
71
|
+
},
|
|
72
|
+
}),
|
|
73
|
+
[responsiveGap]
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
// Convert children to array for mapping
|
|
77
|
+
const childArray = React.Children.toArray(children);
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<View style={[styles.container, style]} testID={testID}>
|
|
81
|
+
{childArray.map((child, index) => (
|
|
82
|
+
<View
|
|
83
|
+
key={index}
|
|
84
|
+
style={{
|
|
85
|
+
flex: columns ? 1 / columns - 0.01 : undefined,
|
|
86
|
+
minWidth: columns ? `${100 / columns - 1}%` : undefined,
|
|
87
|
+
}}
|
|
88
|
+
>
|
|
89
|
+
{child}
|
|
90
|
+
</View>
|
|
91
|
+
))}
|
|
92
|
+
</View>
|
|
93
|
+
);
|
|
94
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Grid, type GridProps } from './Grid';
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* List - Responsive List Wrapper (Molecule)
|
|
3
|
+
*
|
|
4
|
+
* FlatList wrapper with responsive item sizing and built-in pull-to-refresh
|
|
5
|
+
* Uses design system responsive utilities
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React from 'react';
|
|
9
|
+
import { FlatList, RefreshControl, type FlatListProps, type ListRenderItem } from 'react-native';
|
|
10
|
+
import { useResponsiveDesignTokens } from '../../theme';
|
|
11
|
+
|
|
12
|
+
export interface ListProps<T> extends Omit<FlatListProps<T>, 'renderItem'> {
|
|
13
|
+
/** Data array */
|
|
14
|
+
data: readonly T[] | null | undefined;
|
|
15
|
+
|
|
16
|
+
/** Render function for each item */
|
|
17
|
+
renderItem: ListRenderItem<T>;
|
|
18
|
+
|
|
19
|
+
/** Pull-to-refresh handler */
|
|
20
|
+
onRefresh?: () => void;
|
|
21
|
+
|
|
22
|
+
/** Refreshing state */
|
|
23
|
+
refreshing?: boolean;
|
|
24
|
+
|
|
25
|
+
/** Key extractor (required for proper list performance) */
|
|
26
|
+
keyExtractor: (item: T, index: number) => string;
|
|
27
|
+
|
|
28
|
+
/** Content container padding (uses responsive tokens) */
|
|
29
|
+
contentPadding?: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Responsive list component with pull-to-refresh
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```tsx
|
|
37
|
+
* <List
|
|
38
|
+
* data={items}
|
|
39
|
+
* renderItem={({ item }) => <ItemCard item={item} />}
|
|
40
|
+
* keyExtractor={(item) => item.id}
|
|
41
|
+
* onRefresh={handleRefresh}
|
|
42
|
+
* refreshing={isRefreshing}
|
|
43
|
+
* contentPadding
|
|
44
|
+
* />
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export const List = <T,>({
|
|
48
|
+
data,
|
|
49
|
+
renderItem,
|
|
50
|
+
onRefresh,
|
|
51
|
+
refreshing = false,
|
|
52
|
+
keyExtractor,
|
|
53
|
+
contentPadding = false,
|
|
54
|
+
...rest
|
|
55
|
+
}: ListProps<T>) => {
|
|
56
|
+
const tokens = useResponsiveDesignTokens();
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<FlatList
|
|
60
|
+
data={data}
|
|
61
|
+
renderItem={renderItem}
|
|
62
|
+
keyExtractor={keyExtractor}
|
|
63
|
+
refreshControl={
|
|
64
|
+
onRefresh ? (
|
|
65
|
+
<RefreshControl
|
|
66
|
+
refreshing={refreshing}
|
|
67
|
+
onRefresh={onRefresh}
|
|
68
|
+
tintColor={tokens.colors.primary}
|
|
69
|
+
colors={[tokens.colors.primary]}
|
|
70
|
+
/>
|
|
71
|
+
) : undefined
|
|
72
|
+
}
|
|
73
|
+
contentContainerStyle={
|
|
74
|
+
contentPadding
|
|
75
|
+
? {
|
|
76
|
+
paddingHorizontal: tokens.spacing.screenPadding,
|
|
77
|
+
paddingBottom: tokens.spacing.lg,
|
|
78
|
+
}
|
|
79
|
+
: undefined
|
|
80
|
+
}
|
|
81
|
+
showsVerticalScrollIndicator={false}
|
|
82
|
+
{...rest}
|
|
83
|
+
/>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { List, type ListProps } from './List';
|
package/src/molecules/index.ts
CHANGED
|
@@ -22,3 +22,8 @@ export type {
|
|
|
22
22
|
// Divider
|
|
23
23
|
export * from './Divider';
|
|
24
24
|
export * from "./StepProgress";
|
|
25
|
+
|
|
26
|
+
// Responsive Components
|
|
27
|
+
export { Grid, type GridProps } from './Grid';
|
|
28
|
+
export { List, type ListProps } from './List';
|
|
29
|
+
export { Container, type ContainerProps } from './Container';
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FormLayout - Responsive Form Container
|
|
3
|
+
*
|
|
4
|
+
* Organism for creating responsive forms with consistent spacing
|
|
5
|
+
* Automatically handles keyboard avoidance and scrolling
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React, { useMemo } from 'react';
|
|
9
|
+
import { View, ScrollView, KeyboardAvoidingView, StyleSheet, type StyleProp, type ViewStyle } from 'react-native';
|
|
10
|
+
import { useResponsiveDesignTokens } from '../../theme';
|
|
11
|
+
import { useResponsive } from '../../responsive';
|
|
12
|
+
|
|
13
|
+
export interface FormLayoutProps {
|
|
14
|
+
/** Form fields and content */
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
|
|
17
|
+
/** Footer content (e.g., submit button) */
|
|
18
|
+
footer?: React.ReactNode;
|
|
19
|
+
|
|
20
|
+
/** Form container style */
|
|
21
|
+
style?: StyleProp<ViewStyle>;
|
|
22
|
+
|
|
23
|
+
/** Disable keyboard avoiding behavior */
|
|
24
|
+
disableKeyboardAvoid?: boolean;
|
|
25
|
+
|
|
26
|
+
/** Disable scroll */
|
|
27
|
+
disableScroll?: boolean;
|
|
28
|
+
|
|
29
|
+
/** Test ID */
|
|
30
|
+
testID?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Responsive form layout with keyboard avoidance
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* <FormLayout
|
|
39
|
+
* footer={<AtomicButton title="Submit" onPress={handleSubmit} />}
|
|
40
|
+
* >
|
|
41
|
+
* <FormField label="Name" value={name} onChangeText={setName} />
|
|
42
|
+
* <FormField label="Email" value={email} onChangeText={setEmail} />
|
|
43
|
+
* </FormLayout>
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export const FormLayout: React.FC<FormLayoutProps> = ({
|
|
47
|
+
children,
|
|
48
|
+
footer,
|
|
49
|
+
style,
|
|
50
|
+
disableKeyboardAvoid = false,
|
|
51
|
+
disableScroll = false,
|
|
52
|
+
testID,
|
|
53
|
+
}) => {
|
|
54
|
+
const tokens = useResponsiveDesignTokens();
|
|
55
|
+
const { insets } = useResponsive();
|
|
56
|
+
|
|
57
|
+
const styles = useMemo(
|
|
58
|
+
() =>
|
|
59
|
+
StyleSheet.create({
|
|
60
|
+
container: {
|
|
61
|
+
flex: 1,
|
|
62
|
+
},
|
|
63
|
+
scrollContent: {
|
|
64
|
+
flexGrow: 1,
|
|
65
|
+
paddingHorizontal: tokens.spacing.screenPadding,
|
|
66
|
+
paddingTop: tokens.spacing.md,
|
|
67
|
+
paddingBottom: tokens.spacing.xl,
|
|
68
|
+
},
|
|
69
|
+
formContent: {
|
|
70
|
+
gap: tokens.spacing.lg,
|
|
71
|
+
},
|
|
72
|
+
footer: {
|
|
73
|
+
paddingHorizontal: tokens.spacing.screenPadding,
|
|
74
|
+
paddingBottom: Math.max(insets.bottom, tokens.spacing.md),
|
|
75
|
+
paddingTop: tokens.spacing.md,
|
|
76
|
+
backgroundColor: tokens.colors.surface,
|
|
77
|
+
borderTopWidth: 1,
|
|
78
|
+
borderTopColor: tokens.colors.border,
|
|
79
|
+
},
|
|
80
|
+
}),
|
|
81
|
+
[tokens, insets.bottom]
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const content = (
|
|
85
|
+
<View style={styles.formContent} testID={testID}>
|
|
86
|
+
{children}
|
|
87
|
+
</View>
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
const scrollableContent = disableScroll ? (
|
|
91
|
+
<View style={styles.scrollContent}>{content}</View>
|
|
92
|
+
) : (
|
|
93
|
+
<ScrollView
|
|
94
|
+
style={styles.container}
|
|
95
|
+
contentContainerStyle={styles.scrollContent}
|
|
96
|
+
keyboardShouldPersistTaps="handled"
|
|
97
|
+
showsVerticalScrollIndicator={false}
|
|
98
|
+
>
|
|
99
|
+
{content}
|
|
100
|
+
</ScrollView>
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
const mainContent = disableKeyboardAvoid ? (
|
|
104
|
+
scrollableContent
|
|
105
|
+
) : (
|
|
106
|
+
<KeyboardAvoidingView style={styles.container} behavior="padding">
|
|
107
|
+
{scrollableContent}
|
|
108
|
+
</KeyboardAvoidingView>
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<View style={[styles.container, style]}>
|
|
113
|
+
{mainContent}
|
|
114
|
+
{footer && <View style={styles.footer}>{footer}</View>}
|
|
115
|
+
</View>
|
|
116
|
+
);
|
|
117
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { FormLayout, type FormLayoutProps } from './FormLayout';
|
package/src/organisms/index.ts
CHANGED
|
@@ -14,18 +14,22 @@
|
|
|
14
14
|
export { AppHeader } from './AppHeader';
|
|
15
15
|
export { ScreenLayout } from './ScreenLayout';
|
|
16
16
|
export { FormContainer } from './FormContainer';
|
|
17
|
+
export { FormLayout } from './FormLayout';
|
|
17
18
|
|
|
18
19
|
// Type exports
|
|
19
20
|
export type { AppHeaderProps } from './AppHeader';
|
|
20
21
|
export type { ScreenLayoutProps } from './ScreenLayout';
|
|
21
22
|
export type { FormContainerProps } from './FormContainer';
|
|
23
|
+
export type { FormLayoutProps } from './FormLayout';
|
|
22
24
|
|
|
23
25
|
// Union type for all organism props (used for type narrowing)
|
|
24
26
|
import type { AppHeaderProps } from './AppHeader';
|
|
25
27
|
import type { ScreenLayoutProps } from './ScreenLayout';
|
|
26
28
|
import type { FormContainerProps } from './FormContainer';
|
|
29
|
+
import type { FormLayoutProps } from './FormLayout';
|
|
27
30
|
|
|
28
|
-
export type OrganismComponentProps =
|
|
31
|
+
export type OrganismComponentProps =
|
|
29
32
|
| { type: 'AppHeader'; props: AppHeaderProps }
|
|
30
33
|
| { type: 'ScreenLayout'; props: ScreenLayoutProps }
|
|
31
|
-
| { type: 'FormContainer'; props: FormContainerProps }
|
|
34
|
+
| { type: 'FormContainer'; props: FormContainerProps }
|
|
35
|
+
| { type: 'FormLayout'; props: FormLayoutProps };
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RESPONSIVE TOKEN FACTORY
|
|
3
|
+
*
|
|
4
|
+
* ✅ Extends base TokenFactory with responsive capabilities
|
|
5
|
+
* ✅ Device-aware spacing, typography, and sizing
|
|
6
|
+
* ✅ Automatically scales all tokens based on device type
|
|
7
|
+
* ✅ Backward compatible with existing token system
|
|
8
|
+
*
|
|
9
|
+
* @module ResponsiveTokenFactory
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { BASE_TOKENS } from './BaseTokens';
|
|
13
|
+
import { createDesignTokens, type DesignTokens, type ThemeMode } from './TokenFactory';
|
|
14
|
+
import { type CustomThemeColors } from './CustomColors';
|
|
15
|
+
|
|
16
|
+
// =============================================================================
|
|
17
|
+
// RESPONSIVE DESIGN TOKENS TYPE
|
|
18
|
+
// =============================================================================
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Responsive spacing tokens that scale based on device
|
|
22
|
+
*/
|
|
23
|
+
export type ResponsiveSpacing = {
|
|
24
|
+
// Base Spacing Scale (scales with spacingMultiplier)
|
|
25
|
+
xs: number;
|
|
26
|
+
sm: number;
|
|
27
|
+
md: number;
|
|
28
|
+
lg: number;
|
|
29
|
+
xl: number;
|
|
30
|
+
xxl: number;
|
|
31
|
+
xxxl: number;
|
|
32
|
+
|
|
33
|
+
// Semantic Spacing (scales with device)
|
|
34
|
+
screenPadding: number;
|
|
35
|
+
cardPadding: number;
|
|
36
|
+
buttonPadding: number;
|
|
37
|
+
inputPadding: number;
|
|
38
|
+
sectionSpacing: number;
|
|
39
|
+
|
|
40
|
+
// Icon Sizes (scales with device)
|
|
41
|
+
iconSizeSmall: number;
|
|
42
|
+
iconSizeMedium: number;
|
|
43
|
+
iconSizeLarge: number;
|
|
44
|
+
iconSizeXLarge: number;
|
|
45
|
+
iconSizeHero: number;
|
|
46
|
+
|
|
47
|
+
// Component Heights (scales with device)
|
|
48
|
+
buttonHeight: number;
|
|
49
|
+
inputHeight: number;
|
|
50
|
+
appBarHeight: number;
|
|
51
|
+
tabBarHeight: number;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Responsive typography tokens that scale based on device
|
|
56
|
+
*/
|
|
57
|
+
export type ResponsiveTypography = typeof BASE_TOKENS.typography & {
|
|
58
|
+
// Each typography level gets responsive fontSize
|
|
59
|
+
displayLarge: typeof BASE_TOKENS.typography.displayLarge & { responsiveFontSize: number };
|
|
60
|
+
displayMedium: typeof BASE_TOKENS.typography.displayMedium & { responsiveFontSize: number };
|
|
61
|
+
displaySmall: typeof BASE_TOKENS.typography.displaySmall & { responsiveFontSize: number };
|
|
62
|
+
headlineLarge: typeof BASE_TOKENS.typography.headlineLarge & { responsiveFontSize: number };
|
|
63
|
+
headlineMedium: typeof BASE_TOKENS.typography.headlineMedium & { responsiveFontSize: number };
|
|
64
|
+
headlineSmall: typeof BASE_TOKENS.typography.headlineSmall & { responsiveFontSize: number };
|
|
65
|
+
titleLarge: typeof BASE_TOKENS.typography.titleLarge & { responsiveFontSize: number };
|
|
66
|
+
titleMedium: typeof BASE_TOKENS.typography.titleMedium & { responsiveFontSize: number };
|
|
67
|
+
titleSmall: typeof BASE_TOKENS.typography.titleSmall & { responsiveFontSize: number };
|
|
68
|
+
bodyLarge: typeof BASE_TOKENS.typography.bodyLarge & { responsiveFontSize: number };
|
|
69
|
+
bodyMedium: typeof BASE_TOKENS.typography.bodyMedium & { responsiveFontSize: number };
|
|
70
|
+
bodySmall: typeof BASE_TOKENS.typography.bodySmall & { responsiveFontSize: number };
|
|
71
|
+
labelLarge: typeof BASE_TOKENS.typography.labelLarge & { responsiveFontSize: number };
|
|
72
|
+
labelMedium: typeof BASE_TOKENS.typography.labelMedium & { responsiveFontSize: number };
|
|
73
|
+
labelSmall: typeof BASE_TOKENS.typography.labelSmall & { responsiveFontSize: number };
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Responsive border radius tokens that scale based on device
|
|
78
|
+
*/
|
|
79
|
+
export type ResponsiveBorderRadius = {
|
|
80
|
+
none: number;
|
|
81
|
+
xs: number;
|
|
82
|
+
sm: number;
|
|
83
|
+
md: number;
|
|
84
|
+
lg: number;
|
|
85
|
+
xl: number;
|
|
86
|
+
xxl: number;
|
|
87
|
+
full: number;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Complete responsive design tokens
|
|
92
|
+
* Extends base DesignTokens with responsive capabilities
|
|
93
|
+
*/
|
|
94
|
+
export type ResponsiveDesignTokens = Omit<DesignTokens, 'spacing' | 'typography' | 'borderRadius'> & {
|
|
95
|
+
spacing: ResponsiveSpacing;
|
|
96
|
+
typography: ResponsiveTypography;
|
|
97
|
+
borderRadius: ResponsiveBorderRadius;
|
|
98
|
+
|
|
99
|
+
// Original base tokens (for backward compatibility)
|
|
100
|
+
baseSpacing: typeof BASE_TOKENS.spacing;
|
|
101
|
+
baseTypography: typeof BASE_TOKENS.typography;
|
|
102
|
+
baseBorderRadius: typeof BASE_TOKENS.borders.radius;
|
|
103
|
+
|
|
104
|
+
// Responsive multiplier value
|
|
105
|
+
spacingMultiplier: number;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// =============================================================================
|
|
109
|
+
// RESPONSIVE TOKEN FACTORY FUNCTION
|
|
110
|
+
// =============================================================================
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Create responsive design tokens for a specific theme mode
|
|
114
|
+
*
|
|
115
|
+
* @param mode - Theme mode ('light' or 'dark')
|
|
116
|
+
* @param spacingMultiplier - Device-based spacing multiplier (from useResponsive)
|
|
117
|
+
* @param getFontSize - Function to get responsive font size (from useResponsive)
|
|
118
|
+
* @param customColors - Optional custom colors to override default colors
|
|
119
|
+
* @returns Complete responsive design tokens object
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* const { spacingMultiplier, getFontSize } = useResponsive();
|
|
124
|
+
* const tokens = createResponsiveDesignTokens('light', spacingMultiplier, getFontSize);
|
|
125
|
+
*
|
|
126
|
+
* // Use in components
|
|
127
|
+
* <View style={{ padding: tokens.spacing.md }}> // Auto-scales: 16px * 1.2 = 19.2px on tablet
|
|
128
|
+
* <Text style={{ fontSize: tokens.typography.bodyLarge.responsiveFontSize }}>
|
|
129
|
+
* Hello!
|
|
130
|
+
* </Text>
|
|
131
|
+
* </View>
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
export const createResponsiveDesignTokens = (
|
|
135
|
+
mode: ThemeMode,
|
|
136
|
+
spacingMultiplier: number,
|
|
137
|
+
getFontSize: (baseFontSize: number) => number,
|
|
138
|
+
customColors?: CustomThemeColors,
|
|
139
|
+
): ResponsiveDesignTokens => {
|
|
140
|
+
// Get base tokens from existing factory
|
|
141
|
+
const baseTokens = createDesignTokens(mode, customColors);
|
|
142
|
+
|
|
143
|
+
// Create responsive spacing (multiply all base spacing values)
|
|
144
|
+
const responsiveSpacing: ResponsiveSpacing = {
|
|
145
|
+
// Base Spacing Scale
|
|
146
|
+
xs: BASE_TOKENS.spacing.xs * spacingMultiplier,
|
|
147
|
+
sm: BASE_TOKENS.spacing.sm * spacingMultiplier,
|
|
148
|
+
md: BASE_TOKENS.spacing.md * spacingMultiplier,
|
|
149
|
+
lg: BASE_TOKENS.spacing.lg * spacingMultiplier,
|
|
150
|
+
xl: BASE_TOKENS.spacing.xl * spacingMultiplier,
|
|
151
|
+
xxl: BASE_TOKENS.spacing.xxl * spacingMultiplier,
|
|
152
|
+
xxxl: BASE_TOKENS.spacing.xxxl * spacingMultiplier,
|
|
153
|
+
|
|
154
|
+
// Semantic Spacing
|
|
155
|
+
screenPadding: BASE_TOKENS.spacing.screenPadding * spacingMultiplier,
|
|
156
|
+
cardPadding: BASE_TOKENS.spacing.cardPadding * spacingMultiplier,
|
|
157
|
+
buttonPadding: BASE_TOKENS.spacing.buttonPadding * spacingMultiplier,
|
|
158
|
+
inputPadding: BASE_TOKENS.spacing.inputPadding * spacingMultiplier,
|
|
159
|
+
sectionSpacing: BASE_TOKENS.spacing.sectionSpacing * spacingMultiplier,
|
|
160
|
+
|
|
161
|
+
// Icon Sizes
|
|
162
|
+
iconSizeSmall: Math.round(BASE_TOKENS.spacing.iconSizeSmall * spacingMultiplier),
|
|
163
|
+
iconSizeMedium: Math.round(BASE_TOKENS.spacing.iconSizeMedium * spacingMultiplier),
|
|
164
|
+
iconSizeLarge: Math.round(BASE_TOKENS.spacing.iconSizeLarge * spacingMultiplier),
|
|
165
|
+
iconSizeXLarge: Math.round(BASE_TOKENS.spacing.iconSizeXLarge * spacingMultiplier),
|
|
166
|
+
iconSizeHero: Math.round(BASE_TOKENS.spacing.iconSizeHero * spacingMultiplier),
|
|
167
|
+
|
|
168
|
+
// Component Heights
|
|
169
|
+
buttonHeight: Math.round(BASE_TOKENS.spacing.buttonHeight * spacingMultiplier),
|
|
170
|
+
inputHeight: Math.round(BASE_TOKENS.spacing.inputHeight * spacingMultiplier),
|
|
171
|
+
appBarHeight: Math.round(BASE_TOKENS.spacing.appBarHeight * spacingMultiplier),
|
|
172
|
+
tabBarHeight: Math.round(BASE_TOKENS.spacing.tabBarHeight * spacingMultiplier),
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// Create responsive typography (add responsiveFontSize to each level)
|
|
176
|
+
const responsiveTypography: ResponsiveTypography = {
|
|
177
|
+
displayLarge: {
|
|
178
|
+
...BASE_TOKENS.typography.displayLarge,
|
|
179
|
+
responsiveFontSize: getFontSize(BASE_TOKENS.typography.displayLarge.fontSize!),
|
|
180
|
+
},
|
|
181
|
+
displayMedium: {
|
|
182
|
+
...BASE_TOKENS.typography.displayMedium,
|
|
183
|
+
responsiveFontSize: getFontSize(BASE_TOKENS.typography.displayMedium.fontSize!),
|
|
184
|
+
},
|
|
185
|
+
displaySmall: {
|
|
186
|
+
...BASE_TOKENS.typography.displaySmall,
|
|
187
|
+
responsiveFontSize: getFontSize(BASE_TOKENS.typography.displaySmall.fontSize!),
|
|
188
|
+
},
|
|
189
|
+
headlineLarge: {
|
|
190
|
+
...BASE_TOKENS.typography.headlineLarge,
|
|
191
|
+
responsiveFontSize: getFontSize(BASE_TOKENS.typography.headlineLarge.fontSize!),
|
|
192
|
+
},
|
|
193
|
+
headlineMedium: {
|
|
194
|
+
...BASE_TOKENS.typography.headlineMedium,
|
|
195
|
+
responsiveFontSize: getFontSize(BASE_TOKENS.typography.headlineMedium.fontSize!),
|
|
196
|
+
},
|
|
197
|
+
headlineSmall: {
|
|
198
|
+
...BASE_TOKENS.typography.headlineSmall,
|
|
199
|
+
responsiveFontSize: getFontSize(BASE_TOKENS.typography.headlineSmall.fontSize!),
|
|
200
|
+
},
|
|
201
|
+
titleLarge: {
|
|
202
|
+
...BASE_TOKENS.typography.titleLarge,
|
|
203
|
+
responsiveFontSize: getFontSize(BASE_TOKENS.typography.titleLarge.fontSize!),
|
|
204
|
+
},
|
|
205
|
+
titleMedium: {
|
|
206
|
+
...BASE_TOKENS.typography.titleMedium,
|
|
207
|
+
responsiveFontSize: getFontSize(BASE_TOKENS.typography.titleMedium.fontSize!),
|
|
208
|
+
},
|
|
209
|
+
titleSmall: {
|
|
210
|
+
...BASE_TOKENS.typography.titleSmall,
|
|
211
|
+
responsiveFontSize: getFontSize(BASE_TOKENS.typography.titleSmall.fontSize!),
|
|
212
|
+
},
|
|
213
|
+
bodyLarge: {
|
|
214
|
+
...BASE_TOKENS.typography.bodyLarge,
|
|
215
|
+
responsiveFontSize: getFontSize(BASE_TOKENS.typography.bodyLarge.fontSize!),
|
|
216
|
+
},
|
|
217
|
+
bodyMedium: {
|
|
218
|
+
...BASE_TOKENS.typography.bodyMedium,
|
|
219
|
+
responsiveFontSize: getFontSize(BASE_TOKENS.typography.bodyMedium.fontSize!),
|
|
220
|
+
},
|
|
221
|
+
bodySmall: {
|
|
222
|
+
...BASE_TOKENS.typography.bodySmall,
|
|
223
|
+
responsiveFontSize: getFontSize(BASE_TOKENS.typography.bodySmall.fontSize!),
|
|
224
|
+
},
|
|
225
|
+
labelLarge: {
|
|
226
|
+
...BASE_TOKENS.typography.labelLarge,
|
|
227
|
+
responsiveFontSize: getFontSize(BASE_TOKENS.typography.labelLarge.fontSize!),
|
|
228
|
+
},
|
|
229
|
+
labelMedium: {
|
|
230
|
+
...BASE_TOKENS.typography.labelMedium,
|
|
231
|
+
responsiveFontSize: getFontSize(BASE_TOKENS.typography.labelMedium.fontSize!),
|
|
232
|
+
},
|
|
233
|
+
labelSmall: {
|
|
234
|
+
...BASE_TOKENS.typography.labelSmall,
|
|
235
|
+
responsiveFontSize: getFontSize(BASE_TOKENS.typography.labelSmall.fontSize!),
|
|
236
|
+
},
|
|
237
|
+
} as ResponsiveTypography;
|
|
238
|
+
|
|
239
|
+
// Create responsive border radius
|
|
240
|
+
const responsiveBorderRadius: ResponsiveBorderRadius = {
|
|
241
|
+
none: 0,
|
|
242
|
+
xs: Math.round(BASE_TOKENS.borders.radius.xs * spacingMultiplier),
|
|
243
|
+
sm: Math.round(BASE_TOKENS.borders.radius.sm * spacingMultiplier),
|
|
244
|
+
md: Math.round(BASE_TOKENS.borders.radius.md * spacingMultiplier),
|
|
245
|
+
lg: Math.round(BASE_TOKENS.borders.radius.lg * spacingMultiplier),
|
|
246
|
+
xl: Math.round(BASE_TOKENS.borders.radius.xl * spacingMultiplier),
|
|
247
|
+
xxl: Math.round(BASE_TOKENS.borders.radius.xxl * spacingMultiplier),
|
|
248
|
+
full: 9999, // Always full circle
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
// Return complete responsive tokens
|
|
252
|
+
return {
|
|
253
|
+
...baseTokens,
|
|
254
|
+
spacing: responsiveSpacing,
|
|
255
|
+
typography: responsiveTypography,
|
|
256
|
+
borderRadius: responsiveBorderRadius,
|
|
257
|
+
|
|
258
|
+
// Keep original base tokens for backward compatibility
|
|
259
|
+
baseSpacing: BASE_TOKENS.spacing,
|
|
260
|
+
baseTypography: BASE_TOKENS.typography,
|
|
261
|
+
baseBorderRadius: BASE_TOKENS.borders.radius,
|
|
262
|
+
|
|
263
|
+
// Store multiplier for reference
|
|
264
|
+
spacingMultiplier,
|
|
265
|
+
};
|
|
266
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useResponsiveDesignTokens Hook
|
|
3
|
+
*
|
|
4
|
+
* ✅ Combines theme system + responsive utilities
|
|
5
|
+
* ✅ Returns device-aware design tokens
|
|
6
|
+
* ✅ Auto-updates on theme changes, orientation changes, screen resize
|
|
7
|
+
* ✅ Drop-in replacement for useAppDesignTokens with responsive capabilities
|
|
8
|
+
*
|
|
9
|
+
* @module useResponsiveDesignTokens
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { useMemo } from 'react';
|
|
13
|
+
import { useDesignSystemTheme } from '../infrastructure/globalThemeStore';
|
|
14
|
+
import { createResponsiveDesignTokens, type ResponsiveDesignTokens } from '../core/ResponsiveTokenFactory';
|
|
15
|
+
import { useResponsive } from '../../responsive/useResponsive';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Hook for responsive design tokens
|
|
19
|
+
*
|
|
20
|
+
* Returns complete design tokens with automatic responsive scaling based on device type.
|
|
21
|
+
* All spacing, typography, and border radius values automatically scale for tablets and large phones.
|
|
22
|
+
*
|
|
23
|
+
* @returns ResponsiveDesignTokens - Complete tokens with responsive spacing, typography, borders
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* import { useResponsiveDesignTokens } from '@umituz/react-native-design-system';
|
|
28
|
+
*
|
|
29
|
+
* const MyComponent = () => {
|
|
30
|
+
* const tokens = useResponsiveDesignTokens();
|
|
31
|
+
*
|
|
32
|
+
* return (
|
|
33
|
+
* <View style={{
|
|
34
|
+
* padding: tokens.spacing.md, // Auto-scales: 16px on phone, 19.2px on tablet
|
|
35
|
+
* borderRadius: tokens.borderRadius.lg, // Auto-scales based on device
|
|
36
|
+
* }}>
|
|
37
|
+
* <Text style={{
|
|
38
|
+
* fontSize: tokens.typography.bodyLarge.responsiveFontSize, // Responsive font
|
|
39
|
+
* color: tokens.colors.textPrimary, // Theme-aware color
|
|
40
|
+
* }}>
|
|
41
|
+
* Hello World!
|
|
42
|
+
* </Text>
|
|
43
|
+
* </View>
|
|
44
|
+
* );
|
|
45
|
+
* };
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @example Using backward-compatible base tokens
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const tokens = useResponsiveDesignTokens();
|
|
51
|
+
*
|
|
52
|
+
* // Use responsive tokens (recommended)
|
|
53
|
+
* const padding = tokens.spacing.md; // 16px * spacingMultiplier
|
|
54
|
+
*
|
|
55
|
+
* // Use original base tokens (backward compatibility)
|
|
56
|
+
* const basePadding = tokens.baseSpacing.md; // Always 16px
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @example Manual responsive calculation
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const tokens = useResponsiveDesignTokens();
|
|
62
|
+
*
|
|
63
|
+
* // Custom responsive value
|
|
64
|
+
* const customPadding = 20 * tokens.spacingMultiplier; // 20px * 1.2 = 24px on tablet
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export const useResponsiveDesignTokens = (): ResponsiveDesignTokens => {
|
|
68
|
+
// Get current theme mode and custom colors from theme store
|
|
69
|
+
const { themeMode, customColors } = useDesignSystemTheme();
|
|
70
|
+
|
|
71
|
+
// Get responsive utilities
|
|
72
|
+
const { spacingMultiplier, getFontSize } = useResponsive();
|
|
73
|
+
|
|
74
|
+
// Create and memoize responsive tokens
|
|
75
|
+
// Recalculates when: theme changes, screen size changes, orientation changes
|
|
76
|
+
const responsiveTokens = useMemo(
|
|
77
|
+
() => createResponsiveDesignTokens(themeMode, spacingMultiplier, getFontSize, customColors),
|
|
78
|
+
[themeMode, spacingMultiplier, getFontSize, customColors]
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
return responsiveTokens;
|
|
82
|
+
};
|
package/src/theme/index.ts
CHANGED
|
@@ -55,11 +55,24 @@ export {
|
|
|
55
55
|
type DesignTokens,
|
|
56
56
|
} from './core/TokenFactory';
|
|
57
57
|
|
|
58
|
+
// =============================================================================
|
|
59
|
+
// RESPONSIVE TOKEN FACTORY
|
|
60
|
+
// =============================================================================
|
|
61
|
+
|
|
62
|
+
export {
|
|
63
|
+
createResponsiveDesignTokens,
|
|
64
|
+
type ResponsiveDesignTokens,
|
|
65
|
+
type ResponsiveSpacing,
|
|
66
|
+
type ResponsiveTypography,
|
|
67
|
+
type ResponsiveBorderRadius,
|
|
68
|
+
} from './core/ResponsiveTokenFactory';
|
|
69
|
+
|
|
58
70
|
// =============================================================================
|
|
59
71
|
// HOOKS
|
|
60
72
|
// =============================================================================
|
|
61
73
|
|
|
62
74
|
export { useAppDesignTokens } from './hooks/useAppDesignTokens';
|
|
75
|
+
export { useResponsiveDesignTokens } from './hooks/useResponsiveDesignTokens';
|
|
63
76
|
export { useDesignSystemTheme } from './infrastructure/globalThemeStore';
|
|
64
77
|
export { useTheme } from './infrastructure/stores/themeStore';
|
|
65
78
|
export { useThemedStyles, useThemedStyleSheet } from './hooks/useThemedStyles';
|