@idealyst/components 1.1.7 → 1.1.8
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 +3 -3
- package/src/Accordion/Accordion.native.tsx +8 -6
- package/src/Accordion/Accordion.styles.old.tsx +298 -0
- package/src/Accordion/Accordion.styles.tsx +102 -236
- package/src/ActivityIndicator/ActivityIndicator.styles.old.tsx +94 -0
- package/src/ActivityIndicator/ActivityIndicator.styles.tsx +44 -74
- package/src/Alert/Alert.native.tsx +16 -6
- package/src/Alert/Alert.styles.old.tsx +209 -0
- package/src/Alert/Alert.styles.tsx +67 -149
- package/src/Avatar/Avatar.styles.old.tsx +99 -0
- package/src/Avatar/Avatar.styles.tsx +35 -80
- package/src/Badge/Badge.styles.old.tsx +157 -0
- package/src/Badge/Badge.styles.tsx +61 -121
- package/src/Breadcrumb/Breadcrumb.styles.old.tsx +231 -0
- package/src/Breadcrumb/Breadcrumb.styles.tsx +83 -200
- package/src/Breadcrumb/Breadcrumb.web.tsx +28 -23
- package/src/Button/Button.styles.tsx +89 -141
- package/src/Card/Card.native.tsx +7 -11
- package/src/Card/Card.styles.old.tsx +160 -0
- package/src/Card/Card.styles.tsx +105 -142
- package/src/Card/Card.web.tsx +5 -4
- package/src/Checkbox/Checkbox.native.tsx +9 -5
- package/src/Checkbox/Checkbox.styles.old.tsx +271 -0
- package/src/Checkbox/Checkbox.styles.tsx +104 -216
- package/src/Checkbox/Checkbox.web.tsx +6 -6
- package/src/Chip/Chip.styles.old.tsx +184 -0
- package/src/Chip/Chip.styles.tsx +34 -72
- package/src/Dialog/Dialog.native.tsx +7 -4
- package/src/Dialog/Dialog.styles.old.tsx +202 -0
- package/src/Dialog/Dialog.styles.tsx +69 -133
- package/src/Divider/Divider.styles.old.tsx +172 -0
- package/src/Divider/Divider.styles.tsx +62 -84
- package/src/Icon/Icon.native.tsx +8 -8
- package/src/Icon/Icon.styles.old.tsx +81 -0
- package/src/Icon/Icon.styles.tsx +52 -66
- package/src/Icon/Icon.web.tsx +43 -7
- package/src/Icon/IconSvg/IconSvg.web.tsx +2 -0
- package/src/Image/Image.styles.old.tsx +69 -0
- package/src/Image/Image.styles.tsx +46 -60
- package/src/Input/Input.native.tsx +138 -53
- package/src/Input/Input.styles.old.tsx +289 -0
- package/src/Input/Input.styles.tsx +127 -198
- package/src/List/List.native.tsx +5 -2
- package/src/List/List.styles.old.tsx +242 -0
- package/src/List/List.styles.tsx +179 -215
- package/src/List/ListItem.native.tsx +12 -6
- package/src/List/ListItem.web.tsx +23 -13
- package/src/Menu/Menu.styles.old.tsx +197 -0
- package/src/Menu/Menu.styles.tsx +68 -150
- package/src/Menu/MenuItem.native.tsx +5 -3
- package/src/Menu/MenuItem.styles.old.tsx +114 -0
- package/src/Menu/MenuItem.styles.tsx +57 -89
- package/src/Menu/MenuItem.web.tsx +8 -3
- package/src/Popover/Popover.native.tsx +10 -4
- package/src/Popover/Popover.styles.old.tsx +135 -0
- package/src/Popover/Popover.styles.tsx +51 -112
- package/src/Pressable/Pressable.styles.old.tsx +27 -0
- package/src/Pressable/Pressable.styles.tsx +35 -27
- package/src/Progress/Progress.styles.old.tsx +200 -0
- package/src/Progress/Progress.styles.tsx +75 -164
- package/src/RadioButton/RadioButton.native.tsx +4 -3
- package/src/RadioButton/RadioButton.styles.old.tsx +175 -0
- package/src/RadioButton/RadioButton.styles.tsx +83 -154
- package/src/RadioButton/RadioButton.web.tsx +2 -2
- package/src/SVGImage/SVGImage.styles.old.tsx +86 -0
- package/src/SVGImage/SVGImage.styles.tsx +35 -78
- package/src/Screen/Screen.native.tsx +18 -25
- package/src/Screen/Screen.styles.old.tsx +87 -0
- package/src/Screen/Screen.styles.tsx +105 -67
- package/src/Screen/Screen.web.tsx +1 -1
- package/src/Select/Select.native.tsx +42 -33
- package/src/Select/Select.styles.old.tsx +353 -0
- package/src/Select/Select.styles.tsx +223 -292
- package/src/Skeleton/Skeleton.styles.old.tsx +67 -0
- package/src/Skeleton/Skeleton.styles.tsx +29 -53
- package/src/Slider/Slider.styles.old.tsx +259 -0
- package/src/Slider/Slider.styles.tsx +153 -234
- package/src/Switch/Switch.native.tsx +7 -5
- package/src/Switch/Switch.styles.old.tsx +203 -0
- package/src/Switch/Switch.styles.tsx +101 -174
- package/src/Switch/Switch.web.tsx +5 -5
- package/src/TabBar/TabBar.native.tsx +3 -2
- package/src/TabBar/TabBar.styles.old.tsx +343 -0
- package/src/TabBar/TabBar.styles.tsx +145 -279
- package/src/Table/Table.native.tsx +18 -9
- package/src/Table/Table.styles.old.tsx +311 -0
- package/src/Table/Table.styles.tsx +152 -286
- package/src/Text/Text.native.tsx +1 -3
- package/src/Text/Text.style.demo.tsx +16 -0
- package/src/Text/Text.styles.old.tsx +219 -0
- package/src/Text/Text.styles.tsx +94 -84
- package/src/Text/Text.web.tsx +2 -2
- package/src/Text/index.ts +1 -0
- package/src/TextArea/TextArea.styles.old.tsx +213 -0
- package/src/TextArea/TextArea.styles.tsx +93 -181
- package/src/Tooltip/Tooltip.styles.old.tsx +82 -0
- package/src/Tooltip/Tooltip.styles.tsx +32 -56
- package/src/Video/Video.styles.old.tsx +51 -0
- package/src/Video/Video.styles.tsx +32 -44
- package/src/View/View.native.tsx +12 -14
- package/src/View/View.styles.old.tsx +125 -0
- package/src/View/View.styles.tsx +76 -106
- package/src/View/View.web.tsx +1 -0
- package/src/examples/CardExamples.tsx +0 -6
- package/src/extensions/extendComponent.ts +61 -0
|
@@ -1,8 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Button styles using defineStyle with $iterator expansion.
|
|
3
|
+
*
|
|
4
|
+
* Dynamic style functions are used for intent/type combinations since
|
|
5
|
+
* the color depends on both values (compound logic).
|
|
6
|
+
*/
|
|
1
7
|
import { StyleSheet } from 'react-native-unistyles';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
8
|
+
import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
|
|
9
|
+
import type { Theme as BaseTheme, Intent, Size } from '@idealyst/theme';
|
|
4
10
|
import { ButtonGradient } from './types';
|
|
5
|
-
|
|
11
|
+
|
|
12
|
+
// Required: Unistyles must see StyleSheet usage in original source to process this file
|
|
13
|
+
void StyleSheet;
|
|
14
|
+
|
|
15
|
+
// Wrap theme for $iterator support
|
|
16
|
+
type Theme = ThemeStyleWrapper<BaseTheme>;
|
|
6
17
|
|
|
7
18
|
type ButtonSize = Size;
|
|
8
19
|
type ButtonType = 'contained' | 'outlined' | 'text';
|
|
@@ -17,8 +28,6 @@ export type ButtonVariants = {
|
|
|
17
28
|
|
|
18
29
|
/**
|
|
19
30
|
* All dynamic props passed to button style functions.
|
|
20
|
-
* Every style function receives all props for maximum flexibility
|
|
21
|
-
* when using extensions or replacements.
|
|
22
31
|
*/
|
|
23
32
|
export type ButtonDynamicProps = {
|
|
24
33
|
intent?: Intent;
|
|
@@ -29,149 +38,88 @@ export type ButtonDynamicProps = {
|
|
|
29
38
|
};
|
|
30
39
|
|
|
31
40
|
/**
|
|
32
|
-
*
|
|
41
|
+
* Button styles with $iterator expansion for size variants.
|
|
42
|
+
*
|
|
43
|
+
* Intent/type combinations use dynamic functions with inlined theme accesses
|
|
44
|
+
* so Unistyles can trace all possible theme paths.
|
|
33
45
|
*/
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Create dynamic button styles
|
|
66
|
-
* Receives all ButtonDynamicProps for flexibility in extensions/replacements
|
|
67
|
-
*/
|
|
68
|
-
function createButtonStyles(theme: Theme) {
|
|
69
|
-
return (props: ButtonDynamicProps) => {
|
|
70
|
-
const { intent = 'primary', type = 'contained' } = props;
|
|
71
|
-
return {
|
|
72
|
-
boxSizing: 'border-box',
|
|
73
|
-
alignItems: 'center',
|
|
74
|
-
justifyContent: 'center',
|
|
75
|
-
borderRadius: 8,
|
|
76
|
-
fontWeight: '600',
|
|
77
|
-
textAlign: 'center',
|
|
78
|
-
backgroundColor: getButtonBackgroundColor(theme, intent, type),
|
|
79
|
-
borderColor: getButtonBorderColor(theme, intent, type),
|
|
80
|
-
borderWidth: type === 'outlined' ? 1 : 0,
|
|
81
|
-
borderStyle: type === 'outlined' ? 'solid' as const : undefined,
|
|
82
|
-
_web: {
|
|
83
|
-
display: 'flex',
|
|
84
|
-
transition: 'all 0.1s ease',
|
|
46
|
+
export const buttonStyles = defineStyle('Button', (theme: Theme) => ({
|
|
47
|
+
button: ({ intent = 'primary', type = 'contained' }: ButtonDynamicProps) => ({
|
|
48
|
+
boxSizing: 'border-box',
|
|
49
|
+
alignItems: 'center',
|
|
50
|
+
justifyContent: 'center',
|
|
51
|
+
borderRadius: 8,
|
|
52
|
+
fontWeight: '600',
|
|
53
|
+
textAlign: 'center',
|
|
54
|
+
// Inline theme accesses so Unistyles can trace them
|
|
55
|
+
backgroundColor: type === 'contained'
|
|
56
|
+
? theme.intents[intent].primary
|
|
57
|
+
: type === 'outlined'
|
|
58
|
+
? theme.colors.surface.primary
|
|
59
|
+
: 'transparent',
|
|
60
|
+
borderColor: type === 'outlined'
|
|
61
|
+
? theme.intents[intent].primary
|
|
62
|
+
: 'transparent',
|
|
63
|
+
borderWidth: type === 'outlined' ? 1 : 0,
|
|
64
|
+
borderStyle: type === 'outlined' ? 'solid' as const : undefined,
|
|
65
|
+
_web: {
|
|
66
|
+
display: 'flex',
|
|
67
|
+
transition: 'all 0.1s ease',
|
|
68
|
+
},
|
|
69
|
+
variants: {
|
|
70
|
+
// $iterator expands for each button size
|
|
71
|
+
size: {
|
|
72
|
+
paddingVertical: theme.sizes.$button.paddingVertical,
|
|
73
|
+
paddingHorizontal: theme.sizes.$button.paddingHorizontal,
|
|
74
|
+
minHeight: theme.sizes.$button.minHeight,
|
|
85
75
|
},
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
paddingHorizontal: size.paddingHorizontal,
|
|
90
|
-
minHeight: size.minHeight,
|
|
91
|
-
})),
|
|
92
|
-
disabled: {
|
|
93
|
-
true: { opacity: 0.6 },
|
|
94
|
-
false: { opacity: 1, _web: { cursor: 'pointer', _hover: { opacity: 0.90 }, _active: { opacity: 0.75 } } },
|
|
95
|
-
},
|
|
96
|
-
gradient: {
|
|
97
|
-
darken: { _web: { backgroundImage: 'linear-gradient(135deg, transparent 0%, rgba(0, 0, 0, 0.15) 100%)' } },
|
|
98
|
-
lighten: { _web: { backgroundImage: 'linear-gradient(135deg, transparent 0%, rgba(255, 255, 255, 0.2) 100%)' } },
|
|
99
|
-
},
|
|
76
|
+
disabled: {
|
|
77
|
+
true: { opacity: 0.6 },
|
|
78
|
+
false: { opacity: 1, _web: { cursor: 'pointer', _hover: { opacity: 0.90 }, _active: { opacity: 0.75 } } },
|
|
100
79
|
},
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Create dynamic text styles
|
|
107
|
-
* Receives all ButtonDynamicProps for flexibility in extensions/replacements
|
|
108
|
-
*/
|
|
109
|
-
function createTextStyles(theme: Theme) {
|
|
110
|
-
return (props: ButtonDynamicProps) => {
|
|
111
|
-
const { intent = 'primary', type = 'contained' } = props;
|
|
112
|
-
return {
|
|
113
|
-
fontWeight: '600',
|
|
114
|
-
textAlign: 'center',
|
|
115
|
-
color: getTextColor(theme, intent, type),
|
|
116
|
-
variants: {
|
|
117
|
-
size: buildSizeVariants(theme, 'button', size => ({
|
|
118
|
-
fontSize: size.fontSize,
|
|
119
|
-
lineHeight: size.fontSize,
|
|
120
|
-
})),
|
|
121
|
-
disabled: {
|
|
122
|
-
true: { opacity: 0.6 },
|
|
123
|
-
false: { opacity: 1 },
|
|
124
|
-
},
|
|
80
|
+
gradient: {
|
|
81
|
+
darken: { _web: { backgroundImage: 'linear-gradient(135deg, transparent 0%, rgba(0, 0, 0, 0.15) 100%)' } },
|
|
82
|
+
lighten: { _web: { backgroundImage: 'linear-gradient(135deg, transparent 0%, rgba(255, 255, 255, 0.2) 100%)' } },
|
|
125
83
|
},
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
alignItems: 'center',
|
|
140
|
-
justifyContent: 'center',
|
|
141
|
-
color: getTextColor(theme, intent, type),
|
|
142
|
-
variants: {
|
|
143
|
-
size: buildSizeVariants(theme, 'button', size => ({
|
|
144
|
-
width: size.iconSize,
|
|
145
|
-
height: size.iconSize,
|
|
146
|
-
})),
|
|
84
|
+
},
|
|
85
|
+
}),
|
|
86
|
+
text: ({ intent = 'primary', type = 'contained' }: ButtonDynamicProps) => ({
|
|
87
|
+
fontWeight: '600',
|
|
88
|
+
textAlign: 'center',
|
|
89
|
+
// Inline: contained uses contrast, others use primary
|
|
90
|
+
color: type === 'contained'
|
|
91
|
+
? theme.intents[intent].contrast
|
|
92
|
+
: theme.intents[intent].primary,
|
|
93
|
+
variants: {
|
|
94
|
+
size: {
|
|
95
|
+
fontSize: theme.sizes.$button.fontSize,
|
|
96
|
+
lineHeight: theme.sizes.$button.fontSize,
|
|
147
97
|
},
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
98
|
+
disabled: {
|
|
99
|
+
true: { opacity: 0.6 },
|
|
100
|
+
false: { opacity: 1 },
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
}),
|
|
104
|
+
icon: ({ intent = 'primary', type = 'contained' }: ButtonDynamicProps) => ({
|
|
105
|
+
display: 'flex',
|
|
106
|
+
alignItems: 'center',
|
|
107
|
+
justifyContent: 'center',
|
|
108
|
+
color: type === 'contained'
|
|
109
|
+
? theme.intents[intent].contrast
|
|
110
|
+
: theme.intents[intent].primary,
|
|
111
|
+
variants: {
|
|
112
|
+
size: {
|
|
113
|
+
width: theme.sizes.$button.iconSize,
|
|
114
|
+
height: theme.sizes.$button.iconSize,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
}),
|
|
118
|
+
iconContainer: (_props: ButtonDynamicProps) => ({
|
|
160
119
|
display: 'flex' as const,
|
|
161
120
|
flexDirection: 'row' as const,
|
|
162
121
|
alignItems: 'center' as const,
|
|
163
122
|
justifyContent: 'center' as const,
|
|
164
123
|
gap: 4,
|
|
165
|
-
})
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Styles use dynamic functions for intent/type to support theme extensions
|
|
169
|
-
// applyExtensions handles both replacements and extensions automatically
|
|
170
|
-
export const buttonStyles = StyleSheet.create((theme: Theme) => {
|
|
171
|
-
return applyExtensions('Button', theme, {
|
|
172
|
-
button: createButtonStyles(theme),
|
|
173
|
-
text: createTextStyles(theme),
|
|
174
|
-
icon: createIconStyles(theme),
|
|
175
|
-
iconContainer: createIconContainerStyles(),
|
|
176
|
-
});
|
|
177
|
-
});
|
|
124
|
+
}),
|
|
125
|
+
}));
|
package/src/Card/Card.native.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import React, { forwardRef, ComponentRef, useMemo } from 'react';
|
|
|
2
2
|
import { View, Pressable } from 'react-native';
|
|
3
3
|
import { useUnistyles } from 'react-native-unistyles';
|
|
4
4
|
import { CardProps } from './types';
|
|
5
|
-
import { cardStyles
|
|
5
|
+
import { cardStyles } from './Card.styles';
|
|
6
6
|
import { getNativeInteractiveAccessibilityProps } from '../utils/accessibility';
|
|
7
7
|
|
|
8
8
|
const Card = forwardRef<ComponentRef<typeof View> | ComponentRef<typeof Pressable>, CardProps>(({
|
|
@@ -44,11 +44,10 @@ const Card = forwardRef<ComponentRef<typeof View> | ComponentRef<typeof Pressabl
|
|
|
44
44
|
});
|
|
45
45
|
}, [accessibilityLabel, accessibilityHint, accessibilityDisabled, disabled, accessibilityHidden, accessibilityRole, clickable, accessibilityPressed]);
|
|
46
46
|
|
|
47
|
-
//
|
|
48
|
-
const { theme } = useUnistyles();
|
|
49
|
-
|
|
50
|
-
// Apply variants (for spacing only - radius is applied directly below)
|
|
47
|
+
// Apply variants
|
|
51
48
|
cardStyles.useVariants({
|
|
49
|
+
type,
|
|
50
|
+
radius,
|
|
52
51
|
clickable,
|
|
53
52
|
disabled,
|
|
54
53
|
gap,
|
|
@@ -60,11 +59,8 @@ const Card = forwardRef<ComponentRef<typeof View> | ComponentRef<typeof Pressabl
|
|
|
60
59
|
marginHorizontal,
|
|
61
60
|
});
|
|
62
61
|
|
|
63
|
-
// Get
|
|
64
|
-
const cardStyle = (cardStyles.card as any)({
|
|
65
|
-
|
|
66
|
-
// Get border radius from theme - variants don't work with dynamic styles on iOS
|
|
67
|
-
const borderRadius = getCardBorderRadius(theme, radius);
|
|
62
|
+
// Get card style
|
|
63
|
+
const cardStyle = (cardStyles.card as any)({});
|
|
68
64
|
|
|
69
65
|
// Use appropriate component based on clickable state
|
|
70
66
|
const Component = clickable ? Pressable : View;
|
|
@@ -72,7 +68,7 @@ const Card = forwardRef<ComponentRef<typeof View> | ComponentRef<typeof Pressabl
|
|
|
72
68
|
const componentProps = {
|
|
73
69
|
ref,
|
|
74
70
|
nativeID: id,
|
|
75
|
-
style: [cardStyle,
|
|
71
|
+
style: [cardStyle, style],
|
|
76
72
|
testID,
|
|
77
73
|
...nativeA11yProps,
|
|
78
74
|
...(clickable && {
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
2
|
+
import { Theme, Intent, Radius } from '@idealyst/theme';
|
|
3
|
+
import {
|
|
4
|
+
buildGapVariants,
|
|
5
|
+
buildPaddingVariants,
|
|
6
|
+
buildPaddingVerticalVariants,
|
|
7
|
+
buildPaddingHorizontalVariants,
|
|
8
|
+
buildMarginVariants,
|
|
9
|
+
buildMarginVerticalVariants,
|
|
10
|
+
buildMarginHorizontalVariants,
|
|
11
|
+
} from '../utils/buildViewStyleVariants';
|
|
12
|
+
import { ViewStyleSize } from '../utils/viewStyleProps';
|
|
13
|
+
import { applyExtensions } from '../extensions/applyExtension';
|
|
14
|
+
|
|
15
|
+
type CardType = 'outlined' | 'elevated' | 'filled';
|
|
16
|
+
type CardRadius = Radius;
|
|
17
|
+
type CardIntent = Intent | 'info' | 'neutral';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get border radius value from theme
|
|
21
|
+
*/
|
|
22
|
+
export function getCardBorderRadius(theme: Theme, radius: CardRadius): number {
|
|
23
|
+
return theme.radii[radius];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type CardVariants = {
|
|
27
|
+
type: CardType;
|
|
28
|
+
radius: CardRadius;
|
|
29
|
+
intent: CardIntent;
|
|
30
|
+
clickable: boolean;
|
|
31
|
+
disabled: boolean;
|
|
32
|
+
// Spacing variants from ContainerStyleProps
|
|
33
|
+
gap: ViewStyleSize;
|
|
34
|
+
padding: ViewStyleSize;
|
|
35
|
+
paddingVertical: ViewStyleSize;
|
|
36
|
+
paddingHorizontal: ViewStyleSize;
|
|
37
|
+
margin: ViewStyleSize;
|
|
38
|
+
marginVertical: ViewStyleSize;
|
|
39
|
+
marginHorizontal: ViewStyleSize;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
type CardDynamicProps = {
|
|
43
|
+
intent?: CardIntent;
|
|
44
|
+
type?: CardType;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Get the border color based on intent (only used for outlined type)
|
|
49
|
+
*/
|
|
50
|
+
function getBorderColor(theme: Theme, intent: CardIntent): string {
|
|
51
|
+
if (intent === 'info' || intent === 'neutral') {
|
|
52
|
+
return theme.colors.border.secondary;
|
|
53
|
+
}
|
|
54
|
+
if (intent in theme.intents) {
|
|
55
|
+
return theme.intents[intent as Intent].primary;
|
|
56
|
+
}
|
|
57
|
+
return theme.colors.border.secondary;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Get type-specific styles
|
|
62
|
+
*/
|
|
63
|
+
function getTypeStyles(theme: Theme, type: CardType, intent: CardIntent) {
|
|
64
|
+
switch (type) {
|
|
65
|
+
case 'outlined':
|
|
66
|
+
return {
|
|
67
|
+
backgroundColor: 'transparent',
|
|
68
|
+
borderWidth: 1,
|
|
69
|
+
borderStyle: 'solid' as const,
|
|
70
|
+
borderColor: getBorderColor(theme, intent),
|
|
71
|
+
};
|
|
72
|
+
case 'elevated':
|
|
73
|
+
return {
|
|
74
|
+
backgroundColor: theme.colors.surface.primary,
|
|
75
|
+
borderWidth: 0,
|
|
76
|
+
...theme.shadows.md,
|
|
77
|
+
};
|
|
78
|
+
case 'filled':
|
|
79
|
+
return {
|
|
80
|
+
backgroundColor: theme.colors.surface.secondary,
|
|
81
|
+
borderWidth: 0,
|
|
82
|
+
};
|
|
83
|
+
default:
|
|
84
|
+
return {};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Create dynamic card styles
|
|
90
|
+
*/
|
|
91
|
+
function createCardStyles(theme: Theme) {
|
|
92
|
+
return ({ intent = 'neutral', type = 'elevated' }: CardDynamicProps) => {
|
|
93
|
+
const typeStyles = getTypeStyles(theme, type, intent);
|
|
94
|
+
return {
|
|
95
|
+
...typeStyles,
|
|
96
|
+
position: 'relative',
|
|
97
|
+
overflow: 'hidden',
|
|
98
|
+
variants: {
|
|
99
|
+
radius: {
|
|
100
|
+
none: { borderRadius: 0 },
|
|
101
|
+
xs: { borderRadius: 2 },
|
|
102
|
+
sm: { borderRadius: 4 },
|
|
103
|
+
md: { borderRadius: 8 },
|
|
104
|
+
lg: { borderRadius: 12 },
|
|
105
|
+
xl: { borderRadius: 16 },
|
|
106
|
+
},
|
|
107
|
+
clickable: {
|
|
108
|
+
true: {
|
|
109
|
+
_web: {
|
|
110
|
+
cursor: 'pointer',
|
|
111
|
+
transition: 'all 0.2s ease',
|
|
112
|
+
_hover: {
|
|
113
|
+
transform: 'translateY(-2px)',
|
|
114
|
+
boxShadow:
|
|
115
|
+
'0 4px 12px rgba(0, 0, 0, 0.08), 0 2px 4px rgba(0, 0, 0, 0.06)',
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
false: {
|
|
120
|
+
_web: {
|
|
121
|
+
cursor: 'default',
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
disabled: {
|
|
126
|
+
true: {
|
|
127
|
+
opacity: 0.6,
|
|
128
|
+
_web: {
|
|
129
|
+
cursor: 'not-allowed',
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
false: {
|
|
133
|
+
opacity: 1,
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
// Spacing variants from ContainerStyleProps
|
|
137
|
+
gap: buildGapVariants(theme),
|
|
138
|
+
padding: buildPaddingVariants(theme),
|
|
139
|
+
paddingVertical: buildPaddingVerticalVariants(theme),
|
|
140
|
+
paddingHorizontal: buildPaddingHorizontalVariants(theme),
|
|
141
|
+
margin: buildMarginVariants(theme),
|
|
142
|
+
marginVertical: buildMarginVerticalVariants(theme),
|
|
143
|
+
marginHorizontal: buildMarginHorizontalVariants(theme),
|
|
144
|
+
},
|
|
145
|
+
_web: {
|
|
146
|
+
display: 'flex',
|
|
147
|
+
flexDirection: 'column',
|
|
148
|
+
boxSizing: 'border-box',
|
|
149
|
+
},
|
|
150
|
+
} as const;
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
|
|
155
|
+
// transform on native cannot resolve function calls to extract variant structures.
|
|
156
|
+
export const cardStyles = StyleSheet.create((theme: Theme) => {
|
|
157
|
+
return applyExtensions('Card', theme, {
|
|
158
|
+
card: createCardStyles(theme),
|
|
159
|
+
});
|
|
160
|
+
});
|