@umituz/react-native-design-system 2.4.12 → 2.5.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 +41 -35
- package/src/index.ts +0 -4
- package/src/layouts/Container/Container.tsx +2 -2
- package/src/layouts/FormLayout/FormLayout.tsx +2 -2
- package/src/layouts/Grid/Grid.tsx +2 -2
- package/src/molecules/List/List.tsx +2 -2
- package/src/theme/core/TokenFactory.ts +45 -66
- package/src/theme/hooks/useAppDesignTokens.ts +16 -8
- package/src/theme/index.ts +6 -13
- package/src/theme/types/ThemeTypes.ts +62 -0
- package/src/types/jsx.d.ts +1 -0
- package/src/theme/core/ResponsiveTokenFactory.ts +0 -266
- package/src/theme/hooks/useResponsiveDesignTokens.ts +0 -82
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-design-system",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.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,66 +1,72 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Text, StyleProp, TextStyle } from 'react-native';
|
|
3
|
-
import { useAppDesignTokens
|
|
4
|
-
import type
|
|
5
|
-
import { getTextColor } from '../typography';
|
|
2
|
+
import { Text, type StyleProp, type TextStyle, type TextProps } from 'react-native';
|
|
3
|
+
import { useAppDesignTokens } from '../theme';
|
|
4
|
+
import { getTextColor, type TextStyleVariant, type ColorVariant } from '../typography';
|
|
6
5
|
|
|
7
|
-
export interface AtomicTextProps {
|
|
8
|
-
|
|
6
|
+
export interface AtomicTextProps extends TextProps {
|
|
7
|
+
/** Typographic style variant from tokens */
|
|
9
8
|
type?: TextStyleVariant;
|
|
9
|
+
|
|
10
|
+
/** Color variant from tokens or custom hex color */
|
|
10
11
|
color?: ColorVariant | string;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
|
|
13
|
+
/** Text alignment */
|
|
14
|
+
align?: TextStyle['textAlign'];
|
|
15
|
+
|
|
16
|
+
/** Content to render */
|
|
17
|
+
children: React.ReactNode;
|
|
18
|
+
|
|
19
|
+
/** Custom text style */
|
|
14
20
|
style?: StyleProp<TextStyle>;
|
|
21
|
+
|
|
22
|
+
/** Test ID for automation */
|
|
15
23
|
testID?: string;
|
|
16
|
-
/** Enable responsive font sizing (scales based on device) */
|
|
17
|
-
responsive?: boolean;
|
|
18
24
|
}
|
|
19
25
|
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
/**
|
|
27
|
+
* AtomicText - Primitive Text Component
|
|
28
|
+
*
|
|
29
|
+
* ✅ Responsive by default
|
|
30
|
+
* ✅ Theme-aware
|
|
31
|
+
* ✅ SOLID, DRY, KISS
|
|
32
|
+
*/
|
|
33
|
+
export const AtomicText = ({
|
|
22
34
|
type = 'bodyMedium',
|
|
23
|
-
color,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
textAlign,
|
|
35
|
+
color = 'textPrimary',
|
|
36
|
+
align,
|
|
37
|
+
children,
|
|
27
38
|
style,
|
|
28
39
|
testID,
|
|
29
|
-
|
|
30
|
-
}) => {
|
|
31
|
-
const
|
|
32
|
-
const responsiveTokens = useResponsiveDesignTokens();
|
|
33
|
-
|
|
34
|
-
// Use responsive tokens if enabled, otherwise use static
|
|
35
|
-
const tokens = responsive ? responsiveTokens : staticTokens;
|
|
40
|
+
...props
|
|
41
|
+
}: AtomicTextProps) => {
|
|
42
|
+
const tokens = useAppDesignTokens();
|
|
36
43
|
|
|
37
44
|
// Get typography style from tokens
|
|
38
45
|
const typographyStyle = (tokens.typography as Record<string, any>)[type];
|
|
46
|
+
|
|
47
|
+
// Use responsive font size if available
|
|
48
|
+
const fontSize = typographyStyle?.responsiveFontSize || typographyStyle?.fontSize;
|
|
39
49
|
|
|
40
|
-
//
|
|
41
|
-
const resolvedColor =
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const fontSize = responsive && typographyStyle.responsiveFontSize
|
|
45
|
-
? typographyStyle.responsiveFontSize
|
|
46
|
-
: typographyStyle.fontSize;
|
|
50
|
+
// Resolve color
|
|
51
|
+
const resolvedColor = typeof color === 'string' && !color.includes('.')
|
|
52
|
+
? getTextColor(color as ColorVariant, tokens)
|
|
53
|
+
: color;
|
|
47
54
|
|
|
48
55
|
const textStyle: StyleProp<TextStyle> = [
|
|
49
56
|
typographyStyle,
|
|
50
57
|
{
|
|
51
|
-
color: resolvedColor,
|
|
58
|
+
color: resolvedColor as string,
|
|
52
59
|
...(fontSize && { fontSize }),
|
|
53
|
-
...(
|
|
60
|
+
...(align && { textAlign: align }),
|
|
54
61
|
},
|
|
55
62
|
style,
|
|
56
63
|
];
|
|
57
64
|
|
|
58
65
|
return (
|
|
59
66
|
<Text
|
|
60
|
-
numberOfLines={numberOfLines}
|
|
61
|
-
ellipsizeMode={ellipsizeMode}
|
|
62
67
|
style={textStyle}
|
|
63
68
|
testID={testID}
|
|
69
|
+
{...props}
|
|
64
70
|
>
|
|
65
71
|
{children}
|
|
66
72
|
</Text>
|
package/src/index.ts
CHANGED
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
|
|
19
19
|
export {
|
|
20
20
|
useAppDesignTokens,
|
|
21
|
-
useResponsiveDesignTokens,
|
|
22
21
|
useCommonStyles,
|
|
23
22
|
useDesignSystemTheme,
|
|
24
23
|
useTheme,
|
|
@@ -34,7 +33,6 @@ export {
|
|
|
34
33
|
typography,
|
|
35
34
|
borders,
|
|
36
35
|
createDesignTokens,
|
|
37
|
-
createResponsiveDesignTokens,
|
|
38
36
|
lightTheme,
|
|
39
37
|
darkTheme,
|
|
40
38
|
createResponsiveValue,
|
|
@@ -53,10 +51,8 @@ export {
|
|
|
53
51
|
type AvatarSizes,
|
|
54
52
|
type ComponentSizes,
|
|
55
53
|
type DesignTokens,
|
|
56
|
-
type ResponsiveDesignTokens,
|
|
57
54
|
type ResponsiveSpacing,
|
|
58
55
|
type ResponsiveTypography,
|
|
59
|
-
type ResponsiveBorderRadius,
|
|
60
56
|
type Theme,
|
|
61
57
|
type ExtendedColorPalette,
|
|
62
58
|
type NavigationTheme,
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import React, { useMemo } from 'react';
|
|
9
9
|
import { View, StyleSheet, type StyleProp, type ViewStyle } from 'react-native';
|
|
10
10
|
import { useResponsive } from '../../responsive';
|
|
11
|
-
import {
|
|
11
|
+
import { useAppDesignTokens } from '../../theme';
|
|
12
12
|
|
|
13
13
|
export interface ContainerProps {
|
|
14
14
|
/** Container content */
|
|
@@ -49,7 +49,7 @@ export const Container: React.FC<ContainerProps> = ({
|
|
|
49
49
|
testID,
|
|
50
50
|
}) => {
|
|
51
51
|
const { maxContentWidth } = useResponsive();
|
|
52
|
-
const tokens =
|
|
52
|
+
const tokens = useAppDesignTokens();
|
|
53
53
|
|
|
54
54
|
const containerWidth = maxWidth || maxContentWidth;
|
|
55
55
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import React, { useMemo } from 'react';
|
|
9
9
|
import { View, ScrollView, KeyboardAvoidingView, StyleSheet, type StyleProp, type ViewStyle } from 'react-native';
|
|
10
|
-
import {
|
|
10
|
+
import { useAppDesignTokens } from '../../theme';
|
|
11
11
|
import { useResponsive } from '../../responsive';
|
|
12
12
|
|
|
13
13
|
export interface FormLayoutProps {
|
|
@@ -51,7 +51,7 @@ export const FormLayout: React.FC<FormLayoutProps> = ({
|
|
|
51
51
|
disableScroll = false,
|
|
52
52
|
testID,
|
|
53
53
|
}) => {
|
|
54
|
-
const tokens =
|
|
54
|
+
const tokens = useAppDesignTokens();
|
|
55
55
|
const { insets } = useResponsive();
|
|
56
56
|
|
|
57
57
|
const styles = useMemo(
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import React, { useMemo } from 'react';
|
|
9
9
|
import { View, StyleSheet, type StyleProp, type ViewStyle } from 'react-native';
|
|
10
10
|
import { useResponsive } from '../../responsive';
|
|
11
|
-
import {
|
|
11
|
+
import { useAppDesignTokens } from '../../theme';
|
|
12
12
|
|
|
13
13
|
export interface GridProps {
|
|
14
14
|
/** Grid items to render */
|
|
@@ -51,7 +51,7 @@ export const Grid: React.FC<GridProps> = ({
|
|
|
51
51
|
testID,
|
|
52
52
|
}) => {
|
|
53
53
|
const { gridColumns, spacingMultiplier } = useResponsive();
|
|
54
|
-
const tokens =
|
|
54
|
+
const tokens = useAppDesignTokens();
|
|
55
55
|
|
|
56
56
|
// Calculate responsive columns
|
|
57
57
|
const columns = gridColumns || (mobileColumns && tabletColumns
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import React from 'react';
|
|
9
9
|
import { FlatList, RefreshControl, type FlatListProps, type ListRenderItem } from 'react-native';
|
|
10
|
-
import {
|
|
10
|
+
import { useAppDesignTokens } from '../../theme';
|
|
11
11
|
|
|
12
12
|
export interface ListProps<T> extends Omit<FlatListProps<T>, 'renderItem'> {
|
|
13
13
|
/** Data array */
|
|
@@ -53,7 +53,7 @@ export const List = <T,>({
|
|
|
53
53
|
contentPadding = false,
|
|
54
54
|
...rest
|
|
55
55
|
}: ListProps<T>) => {
|
|
56
|
-
const tokens =
|
|
56
|
+
const tokens = useAppDesignTokens();
|
|
57
57
|
|
|
58
58
|
return (
|
|
59
59
|
<FlatList
|
|
@@ -1,89 +1,68 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TOKEN FACTORY - THEME INJECTION LOGIC
|
|
3
|
-
*
|
|
4
|
-
* ✅ Factory Pattern for creating complete design tokens
|
|
5
|
-
* ✅ Combines static tokens (BaseTokens) + dynamic colors (ColorPalette)
|
|
6
|
-
* ✅ Type-safe token generation
|
|
7
|
-
* ✅ Zero duplication - SINGLE SOURCE OF TRUTH
|
|
8
|
-
*
|
|
9
|
-
* @module TokenFactory
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
1
|
import { BASE_TOKENS } from './BaseTokens';
|
|
13
2
|
import { getColorPalette, withAlpha, type ThemeMode, type ColorPalette } from './ColorPalette';
|
|
14
3
|
import { applyCustomColors, type CustomThemeColors } from './CustomColors';
|
|
15
|
-
|
|
16
|
-
// =============================================================================
|
|
17
|
-
// DESIGN TOKENS TYPE
|
|
18
|
-
// =============================================================================
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Complete design tokens shape
|
|
22
|
-
* Combines static tokens (spacing, typography, borders) + dynamic colors
|
|
23
|
-
*/
|
|
24
|
-
export type DesignTokens = {
|
|
25
|
-
colors: ColorPalette;
|
|
26
|
-
spacing: typeof BASE_TOKENS.spacing;
|
|
27
|
-
typography: typeof BASE_TOKENS.typography;
|
|
28
|
-
iconSizes: typeof BASE_TOKENS.iconSizes;
|
|
29
|
-
opacity: typeof BASE_TOKENS.opacity;
|
|
30
|
-
avatarSizes: typeof BASE_TOKENS.avatarSizes;
|
|
31
|
-
borderRadius: typeof BASE_TOKENS.borders.radius;
|
|
32
|
-
borders: typeof BASE_TOKENS.borders & {
|
|
33
|
-
card: typeof BASE_TOKENS.borders.card & { borderColor: string };
|
|
34
|
-
input: typeof BASE_TOKENS.borders.input & { borderColor: string };
|
|
35
|
-
};
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
// =============================================================================
|
|
39
|
-
// TOKEN FACTORY FUNCTION
|
|
40
|
-
// =============================================================================
|
|
4
|
+
import { type DesignTokens, type ResponsiveTypography } from '../types/ThemeTypes';
|
|
41
5
|
|
|
42
6
|
/**
|
|
43
7
|
* Create complete design tokens for a specific theme mode
|
|
8
|
+
*
|
|
9
|
+
* ✅ Responsive by default
|
|
10
|
+
* ✅ SINGLE SOURCE OF TRUTH
|
|
44
11
|
*
|
|
45
12
|
* @param mode - Theme mode ('light' or 'dark')
|
|
46
13
|
* @param customColors - Optional custom colors to override default colors
|
|
47
|
-
* @
|
|
48
|
-
*
|
|
49
|
-
* @
|
|
50
|
-
* ```typescript
|
|
51
|
-
* const lightTokens = createDesignTokens('light');
|
|
52
|
-
* const darkTokens = createDesignTokens('dark');
|
|
53
|
-
* const customTokens = createDesignTokens('dark', { primary: '#FF6B35' });
|
|
54
|
-
*
|
|
55
|
-
* // Use in components
|
|
56
|
-
* <View style={{ backgroundColor: lightTokens.colors.primary }}>
|
|
57
|
-
* <Text style={lightTokens.typography.bodyLarge}>Hello!</Text>
|
|
58
|
-
* </View>
|
|
59
|
-
* ```
|
|
14
|
+
* @param multiplier - Device-based spacing multiplier
|
|
15
|
+
* @param getFontSize - Function to get responsive font size
|
|
16
|
+
* @returns Complete responsive design tokens object
|
|
60
17
|
*/
|
|
61
18
|
export const createDesignTokens = (
|
|
62
19
|
mode: ThemeMode,
|
|
63
20
|
customColors?: CustomThemeColors,
|
|
21
|
+
multiplier: number = 1,
|
|
22
|
+
getFontSize: (size: number) => number = (s) => s,
|
|
64
23
|
): DesignTokens => {
|
|
65
|
-
// Get color palette for theme mode
|
|
66
24
|
const baseColors = getColorPalette(mode);
|
|
67
|
-
|
|
68
|
-
// Apply custom colors if provided
|
|
69
25
|
const colors = applyCustomColors(baseColors, customColors);
|
|
70
26
|
|
|
71
|
-
//
|
|
27
|
+
// Responsive Spacing
|
|
28
|
+
const spacing = Object.keys(BASE_TOKENS.spacing).reduce((acc, key) => {
|
|
29
|
+
const value = BASE_TOKENS.spacing[key as keyof typeof BASE_TOKENS.spacing];
|
|
30
|
+
acc[key as keyof typeof BASE_TOKENS.spacing] = typeof value === 'number' ? value * multiplier : value;
|
|
31
|
+
return acc;
|
|
32
|
+
}, {} as any);
|
|
33
|
+
|
|
34
|
+
// Responsive Typography
|
|
35
|
+
const typography = Object.keys(BASE_TOKENS.typography).reduce((acc, key) => {
|
|
36
|
+
const style = BASE_TOKENS.typography[key as keyof typeof BASE_TOKENS.typography];
|
|
37
|
+
if (typeof style === 'object' && style.fontSize) {
|
|
38
|
+
acc[key as keyof typeof BASE_TOKENS.typography] = {
|
|
39
|
+
...(style as any),
|
|
40
|
+
responsiveFontSize: getFontSize(style.fontSize as number),
|
|
41
|
+
};
|
|
42
|
+
} else {
|
|
43
|
+
acc[key as keyof typeof BASE_TOKENS.typography] = style as any;
|
|
44
|
+
}
|
|
45
|
+
return acc;
|
|
46
|
+
}, {} as any) as ResponsiveTypography;
|
|
47
|
+
|
|
48
|
+
// Responsive Borders
|
|
49
|
+
const borderRadius = Object.keys(BASE_TOKENS.borders.radius).reduce((acc, key) => {
|
|
50
|
+
const value = BASE_TOKENS.borders.radius[key as keyof typeof BASE_TOKENS.borders.radius];
|
|
51
|
+
acc[key as keyof typeof BASE_TOKENS.borders.radius] = value === 0 || key === 'full' ? value : Math.round(value * multiplier);
|
|
52
|
+
return acc;
|
|
53
|
+
}, {} as any);
|
|
54
|
+
|
|
72
55
|
return {
|
|
73
|
-
// ✅ DYNAMIC: Colors from theme mode + custom overrides
|
|
74
56
|
colors,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
spacing: BASE_TOKENS.spacing,
|
|
78
|
-
typography: BASE_TOKENS.typography,
|
|
57
|
+
spacing,
|
|
58
|
+
typography,
|
|
79
59
|
iconSizes: BASE_TOKENS.iconSizes,
|
|
80
60
|
opacity: BASE_TOKENS.opacity,
|
|
81
61
|
avatarSizes: BASE_TOKENS.avatarSizes,
|
|
82
|
-
borderRadius
|
|
83
|
-
|
|
84
|
-
// ✅ BORDERS: Static + injected border colors from theme
|
|
62
|
+
borderRadius,
|
|
85
63
|
borders: {
|
|
86
64
|
...BASE_TOKENS.borders,
|
|
65
|
+
radius: borderRadius,
|
|
87
66
|
card: {
|
|
88
67
|
...BASE_TOKENS.borders.card,
|
|
89
68
|
borderColor: colors.border,
|
|
@@ -93,13 +72,13 @@ export const createDesignTokens = (
|
|
|
93
72
|
borderColor: colors.border,
|
|
94
73
|
},
|
|
95
74
|
},
|
|
75
|
+
spacingMultiplier: multiplier,
|
|
76
|
+
baseSpacing: BASE_TOKENS.spacing,
|
|
77
|
+
baseTypography: BASE_TOKENS.typography,
|
|
78
|
+
baseBorderRadius: BASE_TOKENS.borders.radius,
|
|
96
79
|
};
|
|
97
80
|
};
|
|
98
81
|
|
|
99
|
-
// =============================================================================
|
|
100
|
-
// UTILITY EXPORTS
|
|
101
|
-
// =============================================================================
|
|
102
|
-
|
|
103
82
|
export { withAlpha };
|
|
104
83
|
export type { ThemeMode, ColorPalette };
|
|
105
84
|
|
|
@@ -1,27 +1,35 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
2
|
import { useDesignSystemTheme } from '../infrastructure/globalThemeStore';
|
|
3
|
-
import { createDesignTokens
|
|
3
|
+
import { createDesignTokens } from '../core/TokenFactory';
|
|
4
|
+
import { useResponsive } from '../../responsive/useResponsive';
|
|
5
|
+
import { type DesignTokens } from '../types/ThemeTypes';
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* Hook to access current design tokens (colors, spacing, typography, etc.)
|
|
7
9
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
10
|
+
* ✅ Responsive by default - Scales based on device type
|
|
11
|
+
* ✅ Theme-aware - Automatically updates on light/dark mode changes
|
|
12
|
+
* ✅ Dynamic - Supports custom color overrides
|
|
11
13
|
*
|
|
12
|
-
* @returns {DesignTokens} The current design tokens
|
|
14
|
+
* @returns {DesignTokens} The current responsive design tokens
|
|
13
15
|
*
|
|
14
16
|
* @example
|
|
15
17
|
* ```tsx
|
|
16
18
|
* const tokens = useAppDesignTokens();
|
|
17
|
-
* return
|
|
19
|
+
* return (
|
|
20
|
+
* <View style={{
|
|
21
|
+
* padding: tokens.spacing.md,
|
|
22
|
+
* backgroundColor: tokens.colors.backgroundPrimary
|
|
23
|
+
* }} />
|
|
24
|
+
* );
|
|
18
25
|
* ```
|
|
19
26
|
*/
|
|
20
27
|
export const useAppDesignTokens = (): DesignTokens => {
|
|
21
28
|
const { themeMode, customColors } = useDesignSystemTheme();
|
|
29
|
+
const { spacingMultiplier, getFontSize } = useResponsive();
|
|
22
30
|
|
|
23
31
|
return useMemo(
|
|
24
|
-
() => createDesignTokens(themeMode, customColors),
|
|
25
|
-
[themeMode, customColors]
|
|
32
|
+
() => createDesignTokens(themeMode, customColors, spacingMultiplier, getFontSize),
|
|
33
|
+
[themeMode, customColors, spacingMultiplier, getFontSize]
|
|
26
34
|
);
|
|
27
35
|
};
|
package/src/theme/index.ts
CHANGED
|
@@ -52,27 +52,20 @@ export {
|
|
|
52
52
|
|
|
53
53
|
export {
|
|
54
54
|
createDesignTokens,
|
|
55
|
-
type DesignTokens,
|
|
56
55
|
} from './core/TokenFactory';
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
type ResponsiveDesignTokens,
|
|
65
|
-
type ResponsiveSpacing,
|
|
66
|
-
type ResponsiveTypography,
|
|
67
|
-
type ResponsiveBorderRadius,
|
|
68
|
-
} from './core/ResponsiveTokenFactory';
|
|
57
|
+
export type {
|
|
58
|
+
DesignTokens,
|
|
59
|
+
ResponsiveSpacing,
|
|
60
|
+
ResponsiveTypography,
|
|
61
|
+
ResponsiveBorderRadius,
|
|
62
|
+
} from './types/ThemeTypes';
|
|
69
63
|
|
|
70
64
|
// =============================================================================
|
|
71
65
|
// HOOKS
|
|
72
66
|
// =============================================================================
|
|
73
67
|
|
|
74
68
|
export { useAppDesignTokens } from './hooks/useAppDesignTokens';
|
|
75
|
-
export { useResponsiveDesignTokens } from './hooks/useResponsiveDesignTokens';
|
|
76
69
|
export { useDesignSystemTheme } from './infrastructure/globalThemeStore';
|
|
77
70
|
export { useTheme } from './infrastructure/stores/themeStore';
|
|
78
71
|
export { useThemedStyles, useThemedStyleSheet } from './hooks/useThemedStyles';
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type TextStyle } from 'react-native';
|
|
2
|
+
import { type ColorPalette, type ThemeMode } from '../core/ColorPalette';
|
|
3
|
+
import { type BaseTokens, type Spacing, type Typography, type Borders } from '../core/tokens/BaseTokens';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Responsive Spacing Type
|
|
7
|
+
*/
|
|
8
|
+
export type ResponsiveSpacing = Spacing;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Responsive Border Radius Type
|
|
12
|
+
*/
|
|
13
|
+
export type ResponsiveBorderRadius = Borders['radius'];
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Responsive Typography Type
|
|
17
|
+
*/
|
|
18
|
+
export type ResponsiveTypography = Typography & {
|
|
19
|
+
displayLarge: TextStyle & { responsiveFontSize: number };
|
|
20
|
+
displayMedium: TextStyle & { responsiveFontSize: number };
|
|
21
|
+
displaySmall: TextStyle & { responsiveFontSize: number };
|
|
22
|
+
headlineLarge: TextStyle & { responsiveFontSize: number };
|
|
23
|
+
headlineMedium: TextStyle & { responsiveFontSize: number };
|
|
24
|
+
headlineSmall: TextStyle & { responsiveFontSize: number };
|
|
25
|
+
titleLarge: TextStyle & { responsiveFontSize: number };
|
|
26
|
+
titleMedium: TextStyle & { responsiveFontSize: number };
|
|
27
|
+
titleSmall: TextStyle & { responsiveFontSize: number };
|
|
28
|
+
bodyLarge: TextStyle & { responsiveFontSize: number };
|
|
29
|
+
bodyMedium: TextStyle & { responsiveFontSize: number };
|
|
30
|
+
bodySmall: TextStyle & { responsiveFontSize: number };
|
|
31
|
+
labelLarge: TextStyle & { responsiveFontSize: number };
|
|
32
|
+
labelMedium: TextStyle & { responsiveFontSize: number };
|
|
33
|
+
labelSmall: TextStyle & { responsiveFontSize: number };
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Combined Design Tokens Type
|
|
38
|
+
* Now responsive by default
|
|
39
|
+
*/
|
|
40
|
+
export type DesignTokens = {
|
|
41
|
+
colors: ColorPalette;
|
|
42
|
+
spacing: ResponsiveSpacing;
|
|
43
|
+
typography: ResponsiveTypography;
|
|
44
|
+
iconSizes: BaseTokens['iconSizes'];
|
|
45
|
+
opacity: BaseTokens['opacity'];
|
|
46
|
+
avatarSizes: BaseTokens['avatarSizes'];
|
|
47
|
+
borderRadius: ResponsiveBorderRadius;
|
|
48
|
+
borders: Borders & {
|
|
49
|
+
card: Borders['card'] & { borderColor: string };
|
|
50
|
+
input: Borders['input'] & { borderColor: string };
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Responsive metadata
|
|
54
|
+
spacingMultiplier: number;
|
|
55
|
+
|
|
56
|
+
// Base tokens for reference if needed
|
|
57
|
+
baseSpacing: Spacing;
|
|
58
|
+
baseTypography: Typography;
|
|
59
|
+
baseBorderRadius: Borders['radius'];
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export type { ThemeMode };
|
package/src/types/jsx.d.ts
CHANGED
|
@@ -1,266 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -1,82 +0,0 @@
|
|
|
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 '../../index';
|
|
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
|
-
};
|