@idealyst/components 1.2.29 → 1.2.31
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/README.md +3 -3
- package/package.json +4 -4
- package/plugin/__tests__/web.test.ts +2 -2
- package/plugin/web.js +2 -0
- package/src/Accordion/Accordion.native.tsx +3 -2
- package/src/ActivityIndicator/ActivityIndicator.native.tsx +4 -2
- package/src/ActivityIndicator/ActivityIndicator.styles.tsx +22 -27
- package/src/ActivityIndicator/ActivityIndicator.web.tsx +17 -29
- package/src/Alert/Alert.native.tsx +20 -10
- package/src/Alert/Alert.styles.tsx +173 -86
- package/src/Alert/Alert.web.tsx +34 -30
- package/src/Alert/types.ts +53 -3
- package/src/Avatar/Avatar.native.tsx +3 -2
- package/src/Avatar/Avatar.web.tsx +2 -1
- package/src/Avatar/types.ts +1 -1
- package/src/Badge/Badge.native.tsx +18 -6
- package/src/Badge/Badge.styles.tsx +22 -5
- package/src/Badge/Badge.web.tsx +12 -4
- package/src/Badge/types.ts +14 -2
- package/src/Breadcrumb/Breadcrumb.native.tsx +3 -2
- package/src/Button/Button.native.tsx +16 -6
- package/src/Button/Button.styles.tsx +2 -2
- package/src/Button/Button.web.tsx +19 -15
- package/src/Button/types.ts +6 -10
- package/src/Card/Card.native.tsx +27 -3
- package/src/Card/Card.web.tsx +30 -4
- package/src/Card/types.ts +15 -0
- package/src/Checkbox/Checkbox.native.tsx +5 -4
- package/src/Checkbox/Checkbox.styles.tsx +62 -52
- package/src/Checkbox/Checkbox.web.tsx +4 -3
- package/src/Checkbox/types.ts +1 -1
- package/src/Chip/Chip.native.tsx +30 -7
- package/src/Chip/Chip.web.tsx +28 -5
- package/src/Chip/types.ts +15 -0
- package/src/Dialog/Dialog.native.tsx +6 -6
- package/src/Dialog/Dialog.web.tsx +5 -5
- package/src/Dialog/types.ts +2 -2
- package/src/Divider/Divider.native.tsx +20 -17
- package/src/Divider/Divider.styles.tsx +51 -29
- package/src/Divider/Divider.web.tsx +5 -4
- package/src/Divider/types.ts +3 -3
- package/src/Icon/Icon.native.tsx +3 -2
- package/src/Icon/Icon.web.tsx +2 -1
- package/src/Icon/IconSvg/IconSvg.native.tsx +3 -2
- package/src/IconButton/IconButton.native.tsx +219 -0
- package/src/IconButton/IconButton.styles.tsx +127 -0
- package/src/IconButton/IconButton.web.tsx +198 -0
- package/src/IconButton/index.native.ts +5 -0
- package/src/IconButton/index.ts +5 -0
- package/src/IconButton/index.web.ts +5 -0
- package/src/IconButton/types.ts +84 -0
- package/src/Image/Image.native.tsx +3 -2
- package/src/Input/Input.native.tsx +42 -290
- package/src/Input/Input.styles.tsx +1 -1
- package/src/Input/Input.web.tsx +37 -288
- package/src/Input/index.native.ts +9 -2
- package/src/Input/index.ts +8 -1
- package/src/Input/index.web.ts +8 -1
- package/src/Input/types.ts +1 -1
- package/src/List/List.native.tsx +3 -2
- package/src/List/ListItem.native.tsx +3 -2
- package/src/List/ListSection.native.tsx +3 -2
- package/src/Menu/Menu.native.tsx +2 -1
- package/src/Menu/Menu.styles.tsx +79 -29
- package/src/Menu/Menu.web.tsx +2 -1
- package/src/Menu/MenuItem.native.tsx +4 -3
- package/src/Menu/MenuItem.styles.tsx +81 -32
- package/src/Menu/MenuItem.web.tsx +2 -1
- package/src/Menu/docs.ts +1 -1
- package/src/Popover/Popover.native.tsx +2 -1
- package/src/Popover/Popover.web.tsx +2 -1
- package/src/Popover/types.ts +15 -4
- package/src/Pressable/Pressable.native.tsx +3 -2
- package/src/Pressable/Pressable.web.tsx +3 -5
- package/src/Progress/Progress.native.tsx +5 -4
- package/src/Progress/Progress.web.tsx +3 -3
- package/src/Progress/types.ts +3 -3
- package/src/RadioButton/RadioButton.native.tsx +4 -3
- package/src/RadioButton/RadioButton.styles.tsx +53 -33
- package/src/RadioButton/RadioGroup.native.tsx +3 -2
- package/src/SVGImage/SVGImage.native.tsx +5 -4
- package/src/SVGImage/SVGImage.styles.tsx +44 -10
- package/src/SVGImage/SVGImage.web.tsx +2 -1
- package/src/Screen/Screen.native.tsx +2 -1
- package/src/Screen/Screen.web.tsx +2 -1
- package/src/Select/Select.native.tsx +6 -5
- package/src/Select/Select.styles.tsx +1 -1
- package/src/Select/Select.web.tsx +4 -3
- package/src/Select/types.ts +1 -1
- package/src/Skeleton/Skeleton.native.tsx +2 -1
- package/src/Skeleton/Skeleton.web.tsx +1 -1
- package/src/Slider/Slider.native.tsx +9 -8
- package/src/Slider/Slider.web.tsx +10 -9
- package/src/Slider/types.ts +9 -2
- package/src/Switch/Switch.native.tsx +7 -6
- package/src/Switch/Switch.styles.tsx +52 -17
- package/src/Switch/Switch.web.tsx +15 -16
- package/src/Switch/types.ts +44 -4
- package/src/TabBar/TabBar.native.tsx +3 -2
- package/src/Text/Text.native.tsx +3 -2
- package/src/Text/Text.web.tsx +2 -1
- package/src/TextArea/TextArea.native.tsx +3 -2
- package/src/TextArea/TextArea.styles.tsx +2 -2
- package/src/TextArea/TextArea.web.tsx +2 -1
- package/src/TextInput/TextInput.native.tsx +300 -0
- package/src/TextInput/TextInput.styles.tsx +207 -0
- package/src/TextInput/TextInput.web.tsx +301 -0
- package/src/TextInput/index.native.ts +3 -0
- package/src/TextInput/index.ts +5 -0
- package/src/TextInput/index.web.ts +5 -0
- package/src/TextInput/types.ts +163 -0
- package/src/Tooltip/Tooltip.native.tsx +3 -2
- package/src/Video/Video.native.tsx +4 -3
- package/src/View/View.native.tsx +2 -1
- package/src/View/View.styles.tsx +1 -0
- package/src/View/View.web.tsx +9 -2
- package/src/examples/ActivityIndicatorExamples.tsx +177 -0
- package/src/examples/AlertExamples.tsx +5 -5
- package/src/examples/ButtonExamples.tsx +12 -12
- package/src/examples/CardExamples.tsx +1 -1
- package/src/examples/CheckboxExamples.tsx +2 -2
- package/src/examples/ChipExamples.tsx +6 -6
- package/src/examples/DialogExamples.tsx +1 -1
- package/src/examples/DividerExamples.tsx +1 -1
- package/src/examples/InputExamples.tsx +1 -1
- package/src/examples/LinkExamples.tsx +1 -1
- package/src/examples/ListExamples.tsx +1 -1
- package/src/examples/MenuExamples.tsx +2 -2
- package/src/examples/ProgressExamples.tsx +1 -1
- package/src/examples/RadioButtonExamples.tsx +5 -5
- package/src/examples/SVGImageExamples.tsx +1 -1
- package/src/examples/SelectExamples.tsx +1 -1
- package/src/examples/SliderExamples.tsx +5 -5
- package/src/examples/SwitchExamples.tsx +26 -26
- package/src/examples/TableExamples.tsx +1 -1
- package/src/examples/TooltipExamples.tsx +2 -2
- package/src/examples/index.ts +1 -0
- package/src/extensions/index.ts +1 -0
- package/src/extensions/types.ts +22 -3
- package/src/index.native.ts +4 -0
- package/src/index.ts +27 -2
- package/src/utils/index.ts +12 -0
- package/src/utils/refTypes.ts +50 -0
package/README.md
CHANGED
|
@@ -198,15 +198,15 @@ The library includes a comprehensive theme system with light and dark mode suppo
|
|
|
198
198
|
All components use a consistent intent-based color system:
|
|
199
199
|
|
|
200
200
|
- `primary`: Main brand actions
|
|
201
|
-
- `neutral`: Secondary actions
|
|
201
|
+
- `neutral`: Secondary actions
|
|
202
202
|
- `success`: Positive actions (save, confirm)
|
|
203
|
-
- `
|
|
203
|
+
- `danger`: Destructive actions (delete, cancel)
|
|
204
204
|
- `warning`: Caution actions
|
|
205
205
|
|
|
206
206
|
```tsx
|
|
207
207
|
<Button variant="contained" intent="primary">Primary Action</Button>
|
|
208
208
|
<Button variant="contained" intent="success">Save</Button>
|
|
209
|
-
<Button variant="contained" intent="
|
|
209
|
+
<Button variant="contained" intent="danger">Delete</Button>
|
|
210
210
|
```
|
|
211
211
|
|
|
212
212
|
### Theme Integration
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idealyst/components",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.31",
|
|
4
4
|
"description": "Shared component library for React and React Native",
|
|
5
5
|
"documentation": "https://github.com/IdealystIO/idealyst-framework/tree/main/packages/components#readme",
|
|
6
6
|
"readme": "README.md",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"publish:npm": "npm publish"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@idealyst/theme": "^1.2.
|
|
59
|
+
"@idealyst/theme": "^1.2.31",
|
|
60
60
|
"@mdi/js": ">=7.0.0",
|
|
61
61
|
"@mdi/react": ">=1.0.0",
|
|
62
62
|
"@react-native-vector-icons/common": ">=12.0.0",
|
|
@@ -106,8 +106,8 @@
|
|
|
106
106
|
}
|
|
107
107
|
},
|
|
108
108
|
"devDependencies": {
|
|
109
|
-
"@idealyst/theme": "^1.2.
|
|
110
|
-
"@idealyst/tooling": "^1.2.
|
|
109
|
+
"@idealyst/theme": "^1.2.31",
|
|
110
|
+
"@idealyst/tooling": "^1.2.30",
|
|
111
111
|
"@mdi/react": "^1.6.1",
|
|
112
112
|
"@types/react": "^19.1.0",
|
|
113
113
|
"react": "^19.1.0",
|
|
@@ -468,12 +468,12 @@ describe('MDI Icon Registry Babel Plugin', () => {
|
|
|
468
468
|
|
|
469
469
|
it('does not detect icon-like strings in other props', () => {
|
|
470
470
|
const code = `
|
|
471
|
-
<Button
|
|
471
|
+
<Button data-name="home" aria-label="eye">Click me</Button>
|
|
472
472
|
`;
|
|
473
473
|
const result = transform(code);
|
|
474
474
|
const icons = getDetectedIcons(result?.code);
|
|
475
475
|
|
|
476
|
-
//
|
|
476
|
+
// data-name and aria-label are not icon props
|
|
477
477
|
expect(icons).not.toContain('home');
|
|
478
478
|
expect(icons).not.toContain('eye');
|
|
479
479
|
});
|
package/plugin/web.js
CHANGED
|
@@ -248,6 +248,8 @@ module.exports = function ({ types: t }, options = {}) {
|
|
|
248
248
|
'Alert': ['icon'],
|
|
249
249
|
'Chip': ['icon', 'deleteIcon'],
|
|
250
250
|
'Input': ['leftIcon', 'rightIcon'],
|
|
251
|
+
'TextInput': ['leftIcon', 'rightIcon'],
|
|
252
|
+
'IconButton': ['icon'],
|
|
251
253
|
};
|
|
252
254
|
|
|
253
255
|
const iconProps = iconPropMap[componentName];
|
|
@@ -6,6 +6,7 @@ import { accordionStyles } from './Accordion.styles';
|
|
|
6
6
|
import Text from '../Text';
|
|
7
7
|
import type { AccordionProps, AccordionItem as AccordionItemType } from './types';
|
|
8
8
|
import { getNativeAccessibilityProps } from '../utils/accessibility';
|
|
9
|
+
import type { IdealystElement } from '../utils/refTypes';
|
|
9
10
|
|
|
10
11
|
interface AccordionItemProps {
|
|
11
12
|
item: AccordionItemType;
|
|
@@ -135,7 +136,7 @@ const AccordionItem: React.FC<AccordionItemProps> = ({
|
|
|
135
136
|
);
|
|
136
137
|
};
|
|
137
138
|
|
|
138
|
-
const Accordion = forwardRef<
|
|
139
|
+
const Accordion = forwardRef<IdealystElement, AccordionProps>(({
|
|
139
140
|
items,
|
|
140
141
|
allowMultiple = false,
|
|
141
142
|
defaultExpanded = [],
|
|
@@ -204,7 +205,7 @@ const Accordion = forwardRef<View, AccordionProps>(({
|
|
|
204
205
|
const containerStyle = (accordionStyles.container as any)({});
|
|
205
206
|
|
|
206
207
|
return (
|
|
207
|
-
<View ref={ref} nativeID={id} style={[containerStyle, style]} testID={testID} {...nativeA11yProps}>
|
|
208
|
+
<View ref={ref as any} nativeID={id} style={[containerStyle, style]} testID={testID} {...nativeA11yProps}>
|
|
208
209
|
{items.map((item, index) => (
|
|
209
210
|
<AccordionItem
|
|
210
211
|
key={item.id}
|
|
@@ -3,8 +3,9 @@ import { ActivityIndicator as RNActivityIndicator, View } from 'react-native';
|
|
|
3
3
|
import { ActivityIndicatorProps } from './types';
|
|
4
4
|
import { activityIndicatorStyles } from './ActivityIndicator.styles';
|
|
5
5
|
import { getNativeLiveRegionAccessibilityProps } from '../utils/accessibility';
|
|
6
|
+
import type { IdealystElement } from '../utils/refTypes';
|
|
6
7
|
|
|
7
|
-
const ActivityIndicator = forwardRef<
|
|
8
|
+
const ActivityIndicator = forwardRef<IdealystElement, ActivityIndicatorProps>(({
|
|
8
9
|
animating = true,
|
|
9
10
|
size = 'md',
|
|
10
11
|
intent = 'primary',
|
|
@@ -36,6 +37,7 @@ const ActivityIndicator = forwardRef<View, ActivityIndicatorProps>(({
|
|
|
36
37
|
activityIndicatorStyles.useVariants({
|
|
37
38
|
size: sizeVariant,
|
|
38
39
|
animating,
|
|
40
|
+
intent,
|
|
39
41
|
});
|
|
40
42
|
|
|
41
43
|
// Call dynamic style with intent variant
|
|
@@ -55,7 +57,7 @@ const ActivityIndicator = forwardRef<View, ActivityIndicatorProps>(({
|
|
|
55
57
|
},
|
|
56
58
|
style
|
|
57
59
|
]}
|
|
58
|
-
ref={ref}
|
|
60
|
+
ref={ref as any}
|
|
59
61
|
nativeID={id}
|
|
60
62
|
testID={testID}
|
|
61
63
|
{...nativeA11yProps}
|
|
@@ -22,10 +22,10 @@ export type ActivityIndicatorDynamicProps = {
|
|
|
22
22
|
*/
|
|
23
23
|
export const activityIndicatorStyles = defineStyle('ActivityIndicator', (theme: Theme) => ({
|
|
24
24
|
container: (_props: ActivityIndicatorDynamicProps) => ({
|
|
25
|
+
display: 'flex' as const,
|
|
25
26
|
alignItems: 'center' as const,
|
|
26
27
|
justifyContent: 'center' as const,
|
|
27
28
|
variants: {
|
|
28
|
-
// $iterator expands for each activityIndicator size
|
|
29
29
|
size: {
|
|
30
30
|
width: theme.sizes.$activityIndicator.size,
|
|
31
31
|
height: theme.sizes.$activityIndicator.size,
|
|
@@ -37,32 +37,27 @@ export const activityIndicatorStyles = defineStyle('ActivityIndicator', (theme:
|
|
|
37
37
|
},
|
|
38
38
|
}),
|
|
39
39
|
|
|
40
|
-
spinner: (
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
variants: {
|
|
49
|
-
size: {
|
|
50
|
-
width: theme.sizes.$activityIndicator.size,
|
|
51
|
-
height: theme.sizes.$activityIndicator.size,
|
|
52
|
-
borderWidth: theme.sizes.$activityIndicator.borderWidth,
|
|
53
|
-
},
|
|
54
|
-
animating: {
|
|
55
|
-
true: {},
|
|
56
|
-
false: {},
|
|
57
|
-
},
|
|
40
|
+
spinner: (_props: ActivityIndicatorDynamicProps) => ({
|
|
41
|
+
borderRadius: 9999,
|
|
42
|
+
borderStyle: 'solid' as const,
|
|
43
|
+
variants: {
|
|
44
|
+
size: {
|
|
45
|
+
width: theme.sizes.$activityIndicator.size,
|
|
46
|
+
height: theme.sizes.$activityIndicator.size,
|
|
47
|
+
borderWidth: theme.sizes.$activityIndicator.borderWidth,
|
|
58
48
|
},
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
49
|
+
intent: {
|
|
50
|
+
color: theme.$intents.primary,
|
|
51
|
+
_web: {
|
|
52
|
+
borderColor: 'transparent',
|
|
53
|
+
borderTopColor: theme.$intents.primary,
|
|
54
|
+
borderRightColor: theme.$intents.primary,
|
|
55
|
+
},
|
|
65
56
|
},
|
|
66
|
-
}
|
|
67
|
-
|
|
57
|
+
},
|
|
58
|
+
_web: {
|
|
59
|
+
animation: 'spin 1s linear infinite',
|
|
60
|
+
boxSizing: 'border-box',
|
|
61
|
+
},
|
|
62
|
+
}),
|
|
68
63
|
}));
|
|
@@ -4,12 +4,13 @@ import { ActivityIndicatorProps } from './types';
|
|
|
4
4
|
import { activityIndicatorStyles } from './ActivityIndicator.styles';
|
|
5
5
|
import useMergeRefs from '../hooks/useMergeRefs';
|
|
6
6
|
import { getWebLiveRegionAriaProps } from '../utils/accessibility';
|
|
7
|
+
import type { IdealystElement } from '../utils/refTypes';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Spinning loading indicator for async operations and content loading.
|
|
10
11
|
* Supports intent-based coloring and automatic hiding when stopped.
|
|
11
12
|
*/
|
|
12
|
-
const ActivityIndicator = forwardRef<
|
|
13
|
+
const ActivityIndicator = forwardRef<IdealystElement, ActivityIndicatorProps>(({
|
|
13
14
|
animating = true,
|
|
14
15
|
size = 'md',
|
|
15
16
|
intent = 'primary',
|
|
@@ -41,8 +42,9 @@ const ActivityIndicator = forwardRef<HTMLDivElement, ActivityIndicatorProps>(({
|
|
|
41
42
|
|
|
42
43
|
// Apply variants using the correct Unistyles 3.0 pattern
|
|
43
44
|
activityIndicatorStyles.useVariants({
|
|
44
|
-
size:
|
|
45
|
+
size: size,
|
|
45
46
|
animating,
|
|
47
|
+
intent,
|
|
46
48
|
});
|
|
47
49
|
|
|
48
50
|
// Don't render if not animating and hidesWhenStopped is true
|
|
@@ -50,35 +52,21 @@ const ActivityIndicator = forwardRef<HTMLDivElement, ActivityIndicatorProps>(({
|
|
|
50
52
|
return null;
|
|
51
53
|
}
|
|
52
54
|
|
|
53
|
-
//
|
|
54
|
-
const
|
|
55
|
-
(activityIndicatorStyles.container as any)({}),
|
|
56
|
-
customSize && {
|
|
57
|
-
width: customSize,
|
|
58
|
-
height: customSize,
|
|
59
|
-
},
|
|
60
|
-
style,
|
|
61
|
-
];
|
|
55
|
+
// Dynamic props for style functions
|
|
56
|
+
const dynamicProps = { size: sizeVariant, animating, intent };
|
|
62
57
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
height: customSize,
|
|
70
|
-
borderWidth: Math.max(2, customSize / 10),
|
|
71
|
-
} : {},
|
|
72
|
-
color ? { borderTopColor: color, borderRightColor: color } : {},
|
|
73
|
-
// Add inline CSS animation
|
|
74
|
-
{
|
|
75
|
-
animation: animating ? 'spin 1s linear infinite' : undefined,
|
|
76
|
-
},
|
|
77
|
-
];
|
|
58
|
+
// Use getWebProps - same pattern as Alert
|
|
59
|
+
const containerProps = getWebProps([
|
|
60
|
+
(activityIndicatorStyles.container as any)(dynamicProps),
|
|
61
|
+
customSize && { width: customSize, height: customSize },
|
|
62
|
+
style,
|
|
63
|
+
]);
|
|
78
64
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
65
|
+
const spinnerProps = getWebProps([
|
|
66
|
+
(activityIndicatorStyles.spinner as any)(dynamicProps),
|
|
67
|
+
customSize && { width: customSize, height: customSize, borderWidth: Math.max(2, customSize / 10) },
|
|
68
|
+
color && { borderTopColor: color, borderRightColor: color },
|
|
69
|
+
]);
|
|
82
70
|
|
|
83
71
|
const mergedRef = useMergeRefs(ref, containerProps.ref);
|
|
84
72
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { isValidElement, forwardRef
|
|
1
|
+
import { isValidElement, forwardRef } from 'react';
|
|
2
2
|
import { View, Text, TouchableOpacity } from 'react-native';
|
|
3
3
|
import MaterialDesignIcons from '@react-native-vector-icons/material-design-icons';
|
|
4
|
-
import { alertStyles } from './Alert.styles';
|
|
4
|
+
import { alertStyles, alertSizeConfig } from './Alert.styles';
|
|
5
5
|
import { isIconName } from '../Icon/icon-resolver';
|
|
6
6
|
import type { AlertProps } from './types';
|
|
7
|
+
import type { IdealystElement } from '../utils/refTypes';
|
|
7
8
|
|
|
8
9
|
// Default icon names for each intent
|
|
9
10
|
const defaultIcons: Record<string, string> = {
|
|
@@ -15,12 +16,13 @@ const defaultIcons: Record<string, string> = {
|
|
|
15
16
|
neutral: 'circle',
|
|
16
17
|
};
|
|
17
18
|
|
|
18
|
-
const Alert = forwardRef<
|
|
19
|
+
const Alert = forwardRef<IdealystElement, AlertProps>(({
|
|
19
20
|
title,
|
|
20
21
|
message,
|
|
21
22
|
children,
|
|
22
23
|
intent = 'neutral',
|
|
23
24
|
type = 'soft',
|
|
25
|
+
size = 'md',
|
|
24
26
|
icon,
|
|
25
27
|
showIcon = true,
|
|
26
28
|
dismissible = false,
|
|
@@ -30,17 +32,25 @@ const Alert = forwardRef<ComponentRef<typeof View>, AlertProps>(({
|
|
|
30
32
|
testID,
|
|
31
33
|
id,
|
|
32
34
|
}, ref) => {
|
|
35
|
+
// Apply variants for size, intent, and type
|
|
36
|
+
alertStyles.useVariants({ size, intent, type });
|
|
37
|
+
|
|
33
38
|
// Call all styles as functions to get theme-reactive styles
|
|
34
|
-
const dynamicProps = { intent, type };
|
|
39
|
+
const dynamicProps = { intent, type, size };
|
|
35
40
|
const containerStyle = (alertStyles.container as any)(dynamicProps);
|
|
36
41
|
const iconContainerStyle = (alertStyles.iconContainer as any)(dynamicProps);
|
|
37
42
|
const titleStyle = (alertStyles.title as any)(dynamicProps);
|
|
38
43
|
const messageStyle = (alertStyles.message as any)(dynamicProps);
|
|
39
|
-
const contentStyle = (alertStyles.content as any)(
|
|
40
|
-
const actionsStyle = (alertStyles.actions as any)(
|
|
41
|
-
const closeButtonStyle = (alertStyles.closeButton as any)(
|
|
44
|
+
const contentStyle = (alertStyles.content as any)(dynamicProps);
|
|
45
|
+
const actionsStyle = (alertStyles.actions as any)(dynamicProps);
|
|
46
|
+
const closeButtonStyle = (alertStyles.closeButton as any)(dynamicProps);
|
|
42
47
|
const closeIconStyle = (alertStyles.closeIcon as any)(dynamicProps);
|
|
43
48
|
|
|
49
|
+
// Get size-specific icon dimensions
|
|
50
|
+
const sizeConfig = alertSizeConfig[size];
|
|
51
|
+
const iconSize = sizeConfig.iconSize;
|
|
52
|
+
const closeIconSize = sizeConfig.closeIconSize;
|
|
53
|
+
|
|
44
54
|
const displayIcon = icon !== undefined ? icon : (showIcon ? defaultIcons[intent] : null);
|
|
45
55
|
|
|
46
56
|
// Helper to render icon
|
|
@@ -51,7 +61,7 @@ const Alert = forwardRef<ComponentRef<typeof View>, AlertProps>(({
|
|
|
51
61
|
return (
|
|
52
62
|
<MaterialDesignIcons
|
|
53
63
|
name={displayIcon}
|
|
54
|
-
size={
|
|
64
|
+
size={iconSize}
|
|
55
65
|
style={iconContainerStyle}
|
|
56
66
|
/>
|
|
57
67
|
);
|
|
@@ -63,7 +73,7 @@ const Alert = forwardRef<ComponentRef<typeof View>, AlertProps>(({
|
|
|
63
73
|
|
|
64
74
|
return (
|
|
65
75
|
<View
|
|
66
|
-
ref={ref}
|
|
76
|
+
ref={ref as any}
|
|
67
77
|
nativeID={id}
|
|
68
78
|
style={[containerStyle, style]}
|
|
69
79
|
testID={testID}
|
|
@@ -112,7 +122,7 @@ const Alert = forwardRef<ComponentRef<typeof View>, AlertProps>(({
|
|
|
112
122
|
>
|
|
113
123
|
<MaterialDesignIcons
|
|
114
124
|
name="close"
|
|
115
|
-
size={
|
|
125
|
+
size={closeIconSize}
|
|
116
126
|
style={closeIconStyle}
|
|
117
127
|
/>
|
|
118
128
|
</TouchableOpacity>
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Alert styles using defineStyle with
|
|
2
|
+
* Alert styles using defineStyle with variant expansion.
|
|
3
|
+
*
|
|
4
|
+
* Alert has compound logic between type+intent that's handled via compoundVariants.
|
|
5
|
+
* The $intents iterator in compoundVariants expands for all intent values.
|
|
3
6
|
*/
|
|
4
7
|
import { StyleSheet } from 'react-native-unistyles';
|
|
5
8
|
import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
|
|
6
|
-
import type { Theme as BaseTheme, Intent } from '@idealyst/theme';
|
|
9
|
+
import type { Theme as BaseTheme, Intent, Size } from '@idealyst/theme';
|
|
7
10
|
|
|
8
11
|
// Required: Unistyles must see StyleSheet usage in original source to process this file
|
|
9
12
|
void StyleSheet;
|
|
@@ -16,98 +19,154 @@ type AlertType = 'filled' | 'outlined' | 'soft';
|
|
|
16
19
|
export type AlertDynamicProps = {
|
|
17
20
|
intent?: Intent;
|
|
18
21
|
type?: AlertType;
|
|
22
|
+
size?: Size;
|
|
19
23
|
};
|
|
20
24
|
|
|
21
25
|
/**
|
|
22
|
-
* Alert styles with intent/type
|
|
26
|
+
* Alert styles with variant expansion for size/intent/type.
|
|
27
|
+
*
|
|
28
|
+
* The intent variant is expanded via $intents iterator.
|
|
29
|
+
* CompoundVariants handle type+intent combinations for colors.
|
|
23
30
|
*/
|
|
24
31
|
export const alertStyles = defineStyle('Alert', (theme: Theme) => ({
|
|
25
|
-
container: (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
:
|
|
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
|
-
alignItems: 'center' as const,
|
|
61
|
-
justifyContent: 'center' as const,
|
|
62
|
-
alignSelf: 'flex-start' as const,
|
|
63
|
-
flexShrink: 0,
|
|
64
|
-
width: 24,
|
|
65
|
-
height: 24,
|
|
66
|
-
marginTop: 2,
|
|
67
|
-
color,
|
|
68
|
-
} as const;
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
title: ({ intent = 'neutral', type = 'soft' }: AlertDynamicProps) => {
|
|
72
|
-
const intentValue = theme.intents[intent];
|
|
73
|
-
const color = type === 'filled' ? intentValue.contrast : intentValue.primary;
|
|
32
|
+
container: (_props: AlertDynamicProps) => ({
|
|
33
|
+
display: 'flex' as const,
|
|
34
|
+
flexDirection: 'row' as const,
|
|
35
|
+
alignItems: 'flex-start' as const,
|
|
36
|
+
borderWidth: 1,
|
|
37
|
+
borderStyle: 'solid' as const,
|
|
38
|
+
variants: {
|
|
39
|
+
size: {
|
|
40
|
+
gap: theme.sizes.$alert.gap,
|
|
41
|
+
padding: theme.sizes.$alert.padding,
|
|
42
|
+
borderRadius: theme.sizes.$alert.borderRadius,
|
|
43
|
+
},
|
|
44
|
+
// Intent variant - expands to primary, success, danger, etc.
|
|
45
|
+
intent: {
|
|
46
|
+
// Base styles per intent (overridden by type+intent compoundVariants)
|
|
47
|
+
backgroundColor: theme.$intents.primary,
|
|
48
|
+
borderColor: theme.$intents.primary,
|
|
49
|
+
},
|
|
50
|
+
type: {
|
|
51
|
+
filled: {},
|
|
52
|
+
outlined: {
|
|
53
|
+
backgroundColor: 'transparent',
|
|
54
|
+
},
|
|
55
|
+
soft: {},
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
compoundVariants: [
|
|
59
|
+
// filled: use intent primary for bg and border
|
|
60
|
+
{ type: 'filled', styles: { backgroundColor: theme.$intents.primary, borderColor: theme.$intents.primary } },
|
|
61
|
+
// outlined: transparent bg, intent primary for border
|
|
62
|
+
{ type: 'outlined', styles: { backgroundColor: 'transparent', borderColor: theme.$intents.primary } },
|
|
63
|
+
// soft: intent light for bg and border
|
|
64
|
+
{ type: 'soft', styles: { backgroundColor: theme.$intents.light, borderColor: theme.$intents.light } },
|
|
65
|
+
],
|
|
66
|
+
}),
|
|
74
67
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
68
|
+
iconContainer: (_props: AlertDynamicProps) => ({
|
|
69
|
+
display: 'flex' as const,
|
|
70
|
+
alignItems: 'center' as const,
|
|
71
|
+
justifyContent: 'center' as const,
|
|
72
|
+
alignSelf: 'flex-start' as const,
|
|
73
|
+
flexShrink: 0,
|
|
74
|
+
marginTop: 2,
|
|
75
|
+
variants: {
|
|
76
|
+
size: {
|
|
77
|
+
width: theme.sizes.$alert.iconSize,
|
|
78
|
+
height: theme.sizes.$alert.iconSize,
|
|
79
|
+
},
|
|
80
|
+
intent: {
|
|
81
|
+
color: theme.$intents.primary,
|
|
82
|
+
},
|
|
83
|
+
type: {
|
|
84
|
+
filled: {},
|
|
85
|
+
outlined: {},
|
|
86
|
+
soft: {},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
compoundVariants: [
|
|
90
|
+
// filled: contrast color for icon
|
|
91
|
+
{ type: 'filled', styles: { color: theme.$intents.contrast } },
|
|
92
|
+
// outlined/soft: primary color for icon
|
|
93
|
+
{ type: 'outlined', styles: { color: theme.$intents.primary } },
|
|
94
|
+
{ type: 'soft', styles: { color: theme.$intents.primary } },
|
|
95
|
+
],
|
|
96
|
+
}),
|
|
82
97
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
98
|
+
title: (_props: AlertDynamicProps) => ({
|
|
99
|
+
fontWeight: '600' as const,
|
|
100
|
+
variants: {
|
|
101
|
+
size: {
|
|
102
|
+
fontSize: theme.sizes.$alert.titleFontSize,
|
|
103
|
+
lineHeight: theme.sizes.$alert.titleLineHeight,
|
|
104
|
+
},
|
|
105
|
+
intent: {
|
|
106
|
+
color: theme.$intents.primary,
|
|
107
|
+
},
|
|
108
|
+
type: {
|
|
109
|
+
filled: {},
|
|
110
|
+
outlined: {},
|
|
111
|
+
soft: {},
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
compoundVariants: [
|
|
115
|
+
// filled: contrast color for title
|
|
116
|
+
{ type: 'filled', styles: { color: theme.$intents.contrast } },
|
|
117
|
+
// outlined/soft: primary color for title
|
|
118
|
+
{ type: 'outlined', styles: { color: theme.$intents.primary } },
|
|
119
|
+
{ type: 'soft', styles: { color: theme.$intents.primary } },
|
|
120
|
+
],
|
|
121
|
+
}),
|
|
86
122
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
123
|
+
message: (_props: AlertDynamicProps) => ({
|
|
124
|
+
variants: {
|
|
125
|
+
size: {
|
|
126
|
+
fontSize: theme.sizes.$alert.messageFontSize,
|
|
127
|
+
lineHeight: theme.sizes.$alert.messageLineHeight,
|
|
128
|
+
},
|
|
129
|
+
intent: {
|
|
130
|
+
color: theme.colors.text.primary,
|
|
131
|
+
},
|
|
132
|
+
type: {
|
|
133
|
+
filled: {},
|
|
134
|
+
outlined: {},
|
|
135
|
+
soft: {},
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
compoundVariants: [
|
|
139
|
+
// filled: contrast color for message
|
|
140
|
+
{ type: 'filled', styles: { color: theme.$intents.contrast } },
|
|
141
|
+
// outlined/soft: use default text color (set in intent variant)
|
|
142
|
+
{ type: 'outlined', styles: { color: theme.colors.text.primary } },
|
|
143
|
+
{ type: 'soft', styles: { color: theme.colors.text.primary } },
|
|
144
|
+
],
|
|
145
|
+
}),
|
|
93
146
|
|
|
94
147
|
content: (_props: AlertDynamicProps) => ({
|
|
95
148
|
flex: 1,
|
|
96
149
|
display: 'flex' as const,
|
|
97
150
|
flexDirection: 'column' as const,
|
|
98
|
-
|
|
151
|
+
variants: {
|
|
152
|
+
size: {
|
|
153
|
+
gap: theme.sizes.$alert.gap,
|
|
154
|
+
},
|
|
155
|
+
},
|
|
99
156
|
}),
|
|
100
157
|
|
|
101
158
|
actions: (_props: AlertDynamicProps) => ({
|
|
102
|
-
marginTop: 4,
|
|
103
159
|
display: 'flex' as const,
|
|
104
160
|
flexDirection: 'row' as const,
|
|
105
|
-
|
|
161
|
+
variants: {
|
|
162
|
+
size: {
|
|
163
|
+
marginTop: theme.sizes.$alert.gap,
|
|
164
|
+
gap: theme.sizes.$alert.gap,
|
|
165
|
+
},
|
|
166
|
+
},
|
|
106
167
|
}),
|
|
107
168
|
|
|
108
169
|
closeButton: (_props: AlertDynamicProps) => ({
|
|
109
|
-
padding: 4,
|
|
110
|
-
borderRadius: 4,
|
|
111
170
|
display: 'flex' as const,
|
|
112
171
|
alignItems: 'center' as const,
|
|
113
172
|
justifyContent: 'center' as const,
|
|
@@ -126,19 +185,47 @@ export const alertStyles = defineStyle('Alert', (theme: Theme) => ({
|
|
|
126
185
|
backgroundColor: 'rgba(0, 0, 0, 0.1)',
|
|
127
186
|
},
|
|
128
187
|
},
|
|
188
|
+
variants: {
|
|
189
|
+
size: {
|
|
190
|
+
padding: theme.sizes.$alert.padding,
|
|
191
|
+
borderRadius: theme.sizes.$alert.borderRadius,
|
|
192
|
+
},
|
|
193
|
+
},
|
|
129
194
|
}),
|
|
130
195
|
|
|
131
|
-
closeIcon: (
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
196
|
+
closeIcon: (_props: AlertDynamicProps) => ({
|
|
197
|
+
display: 'flex' as const,
|
|
198
|
+
alignItems: 'center' as const,
|
|
199
|
+
justifyContent: 'center' as const,
|
|
200
|
+
variants: {
|
|
201
|
+
size: {
|
|
202
|
+
width: theme.sizes.$alert.closeIconSize,
|
|
203
|
+
height: theme.sizes.$alert.closeIconSize,
|
|
204
|
+
},
|
|
205
|
+
intent: {
|
|
206
|
+
color: theme.$intents.primary,
|
|
207
|
+
},
|
|
208
|
+
type: {
|
|
209
|
+
filled: {},
|
|
210
|
+
outlined: {},
|
|
211
|
+
soft: {},
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
compoundVariants: [
|
|
215
|
+
// filled: contrast color for close icon
|
|
216
|
+
{ type: 'filled', styles: { color: theme.$intents.contrast } },
|
|
217
|
+
// outlined/soft: primary color for close icon
|
|
218
|
+
{ type: 'outlined', styles: { color: theme.$intents.primary } },
|
|
219
|
+
{ type: 'soft', styles: { color: theme.$intents.primary } },
|
|
220
|
+
],
|
|
221
|
+
}),
|
|
144
222
|
}));
|
|
223
|
+
|
|
224
|
+
// Export theme sizes for use in components (for icon sizing in native)
|
|
225
|
+
export const alertSizeConfig = {
|
|
226
|
+
xs: { padding: 8, gap: 6, borderRadius: 4, titleFontSize: 12, titleLineHeight: 16, messageFontSize: 11, messageLineHeight: 14, iconSize: 16, closeIconSize: 12 },
|
|
227
|
+
sm: { padding: 12, gap: 8, borderRadius: 6, titleFontSize: 14, titleLineHeight: 20, messageFontSize: 12, messageLineHeight: 16, iconSize: 20, closeIconSize: 14 },
|
|
228
|
+
md: { padding: 16, gap: 10, borderRadius: 8, titleFontSize: 16, titleLineHeight: 24, messageFontSize: 14, messageLineHeight: 20, iconSize: 24, closeIconSize: 16 },
|
|
229
|
+
lg: { padding: 20, gap: 12, borderRadius: 10, titleFontSize: 18, titleLineHeight: 28, messageFontSize: 16, messageLineHeight: 24, iconSize: 28, closeIconSize: 18 },
|
|
230
|
+
xl: { padding: 24, gap: 14, borderRadius: 12, titleFontSize: 20, titleLineHeight: 32, messageFontSize: 18, messageLineHeight: 28, iconSize: 32, closeIconSize: 20 },
|
|
231
|
+
};
|