@idealyst/components 1.1.1 → 1.1.3
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 +8 -3
- package/src/Accordion/Accordion.native.tsx +2 -1
- package/src/Accordion/Accordion.web.tsx +2 -1
- package/src/ActivityIndicator/ActivityIndicator.native.tsx +2 -0
- package/src/ActivityIndicator/ActivityIndicator.web.tsx +2 -1
- package/src/ActivityIndicator/types.ts +2 -1
- package/src/Alert/Alert.native.tsx +2 -0
- package/src/Alert/Alert.web.tsx +2 -0
- package/src/Alert/types.ts +2 -1
- package/src/Avatar/Avatar.native.tsx +2 -1
- package/src/Avatar/Avatar.web.tsx +2 -1
- package/src/Avatar/types.ts +2 -1
- package/src/Badge/Badge.native.tsx +3 -0
- package/src/Badge/Badge.web.tsx +3 -0
- package/src/Badge/types.ts +2 -1
- package/src/Breadcrumb/Breadcrumb.native.tsx +2 -0
- package/src/Breadcrumb/Breadcrumb.web.tsx +2 -1
- package/src/Breadcrumb/types.ts +2 -1
- package/src/Button/Button.native.tsx +17 -12
- package/src/Button/Button.styles.tsx +3 -2
- package/src/Button/Button.web.tsx +2 -0
- package/src/Button/types.ts +2 -1
- package/src/Card/Card.native.tsx +2 -0
- package/src/Card/Card.web.tsx +2 -0
- package/src/Checkbox/Checkbox.native.tsx +2 -1
- package/src/Checkbox/Checkbox.web.tsx +2 -1
- package/src/Chip/Chip.native.tsx +3 -1
- package/src/Chip/Chip.web.tsx +2 -0
- package/src/Chip/types.ts +2 -1
- package/src/Dialog/Dialog.native.tsx +2 -0
- package/src/Dialog/Dialog.web.tsx +2 -0
- package/src/Dialog/types.ts +2 -1
- package/src/Divider/Divider.native.tsx +4 -0
- package/src/Divider/Divider.web.tsx +3 -0
- package/src/Divider/types.ts +2 -1
- package/src/Icon/Icon.native.tsx +2 -0
- package/src/Icon/Icon.web.tsx +3 -1
- package/src/Icon/types.ts +2 -1
- package/src/Image/Image.native.tsx +2 -1
- package/src/Image/Image.web.tsx +2 -0
- package/src/Image/types.ts +2 -1
- package/src/Input/Input.native.tsx +2 -1
- package/src/Input/Input.styles.tsx +1 -0
- package/src/Input/Input.web.tsx +2 -1
- package/src/Link/Link.native.tsx +2 -0
- package/src/Link/Link.web.tsx +2 -0
- package/src/Link/types.ts +2 -1
- package/src/List/List.native.tsx +3 -1
- package/src/List/List.web.tsx +2 -0
- package/src/Menu/Menu.native.tsx +2 -1
- package/src/Menu/Menu.web.tsx +2 -0
- package/src/Menu/types.ts +2 -1
- package/src/Popover/Popover.native.tsx +2 -0
- package/src/Popover/Popover.web.tsx +2 -1
- package/src/Popover/types.ts +2 -1
- package/src/Pressable/Pressable.native.tsx +2 -1
- package/src/Pressable/Pressable.web.tsx +2 -0
- package/src/Progress/Progress.native.tsx +3 -2
- package/src/Progress/Progress.web.tsx +3 -2
- package/src/Progress/types.ts +2 -1
- package/src/RadioButton/RadioButton.native.tsx +2 -0
- package/src/RadioButton/RadioButton.web.tsx +2 -0
- package/src/RadioButton/RadioGroup.native.tsx +2 -0
- package/src/RadioButton/RadioGroup.web.tsx +2 -0
- package/src/RadioButton/types.ts +2 -2
- package/src/SVGImage/SVGImage.native.tsx +3 -2
- package/src/SVGImage/SVGImage.web.tsx +3 -2
- package/src/SVGImage/types.ts +2 -1
- package/src/Screen/Screen.native.tsx +3 -1
- package/src/Screen/Screen.web.tsx +2 -0
- package/src/Select/Select.native.tsx +2 -1
- package/src/Select/Select.web.tsx +2 -1
- package/src/Skeleton/Skeleton.native.tsx +4 -0
- package/src/Skeleton/Skeleton.web.tsx +4 -0
- package/src/Skeleton/types.ts +3 -2
- package/src/Slider/Slider.native.tsx +5 -4
- package/src/Slider/Slider.web.tsx +2 -1
- package/src/Switch/Switch.native.tsx +3 -0
- package/src/Switch/Switch.web.tsx +2 -0
- package/src/TabBar/TabBar.native.tsx +48 -6
- package/src/TabBar/TabBar.styles.tsx +88 -1
- package/src/TabBar/TabBar.web.tsx +50 -2
- package/src/TabBar/types.ts +10 -0
- package/src/Table/Table.native.tsx +2 -0
- package/src/Table/Table.web.tsx +2 -1
- package/src/Text/Text.native.tsx +7 -7
- package/src/Text/Text.styles.tsx +23 -30
- package/src/Text/Text.web.tsx +8 -8
- package/src/Text/types.ts +1 -9
- package/src/TextArea/TextArea.native.tsx +2 -1
- package/src/TextArea/TextArea.web.tsx +2 -1
- package/src/Tooltip/Tooltip.native.tsx +2 -1
- package/src/Tooltip/Tooltip.web.tsx +2 -0
- package/src/Tooltip/types.ts +2 -1
- package/src/Video/Video.native.tsx +3 -2
- package/src/Video/Video.web.tsx +2 -0
- package/src/Video/types.ts +2 -1
- package/src/View/View.native.tsx +3 -1
- package/src/View/View.web.tsx +2 -0
- package/src/examples/TabBarExamples.tsx +122 -1
- package/src/utils/index.ts +20 -0
- package/src/utils/viewStyleProps.ts +12 -4
package/src/Text/Text.native.tsx
CHANGED
|
@@ -5,9 +5,8 @@ import { textStyles } from './Text.styles';
|
|
|
5
5
|
|
|
6
6
|
const Text = forwardRef<RNText, TextProps>(({
|
|
7
7
|
children,
|
|
8
|
-
typography,
|
|
9
|
-
|
|
10
|
-
weight = 'normal',
|
|
8
|
+
typography = 'body1',
|
|
9
|
+
weight,
|
|
11
10
|
color,
|
|
12
11
|
align = 'left',
|
|
13
12
|
// Spacing variants from TextSpacingStyleProps
|
|
@@ -17,11 +16,11 @@ const Text = forwardRef<RNText, TextProps>(({
|
|
|
17
16
|
paddingHorizontal,
|
|
18
17
|
style,
|
|
19
18
|
testID,
|
|
19
|
+
id,
|
|
20
20
|
}, ref) => {
|
|
21
|
-
// When typography is set, it overrides size and weight (handled in styles)
|
|
22
21
|
textStyles.useVariants({
|
|
23
|
-
|
|
24
|
-
weight
|
|
22
|
+
typography,
|
|
23
|
+
weight,
|
|
25
24
|
align,
|
|
26
25
|
gap,
|
|
27
26
|
padding,
|
|
@@ -32,8 +31,9 @@ const Text = forwardRef<RNText, TextProps>(({
|
|
|
32
31
|
return (
|
|
33
32
|
<RNText
|
|
34
33
|
ref={ref}
|
|
34
|
+
nativeID={id}
|
|
35
35
|
style={[
|
|
36
|
-
textStyles.text({ color
|
|
36
|
+
textStyles.text({ color }),
|
|
37
37
|
style,
|
|
38
38
|
]}
|
|
39
39
|
testID={testID}
|
package/src/Text/Text.styles.tsx
CHANGED
|
@@ -1,47 +1,51 @@
|
|
|
1
1
|
import { StyleSheet } from "react-native-unistyles";
|
|
2
|
-
import { Theme } from '@idealyst/theme';
|
|
3
|
-
import { buildSizeVariants } from '../utils/buildSizeVariants';
|
|
2
|
+
import { Theme, Typography } from '@idealyst/theme';
|
|
4
3
|
import {
|
|
5
4
|
buildGapVariants,
|
|
6
5
|
buildPaddingVariants,
|
|
7
6
|
buildPaddingVerticalVariants,
|
|
8
7
|
buildPaddingHorizontalVariants,
|
|
9
8
|
} from '../utils/buildViewStyleVariants';
|
|
10
|
-
import { TextAlignVariant, TextColorVariant,
|
|
9
|
+
import { TextAlignVariant, TextColorVariant, TextWeightVariant, TextTypographyVariant } from "./types";
|
|
11
10
|
|
|
12
|
-
type TextVariants = {
|
|
13
|
-
|
|
11
|
+
export type TextVariants = {
|
|
12
|
+
typography: TextTypographyVariant;
|
|
14
13
|
weight: TextWeightVariant;
|
|
15
14
|
align: TextAlignVariant;
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
|
-
* Create
|
|
20
|
-
* @deprecated Use typography prop instead
|
|
18
|
+
* Create typography variants from theme
|
|
21
19
|
*/
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
function createTypographyVariants(theme: Theme) {
|
|
21
|
+
const variants: Record<string, object> = {};
|
|
22
|
+
|
|
23
|
+
for (const key in theme.sizes.typography) {
|
|
24
|
+
const typo = theme.sizes.typography[key as Typography];
|
|
25
|
+
variants[key] = {
|
|
26
|
+
fontSize: typo.fontSize,
|
|
27
|
+
lineHeight: typo.lineHeight,
|
|
28
|
+
fontWeight: typo.fontWeight,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return variants;
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
type TextStyleParams = {
|
|
30
36
|
color?: TextColorVariant;
|
|
31
|
-
typography?: TextTypographyVariant;
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
function createTextStyles(theme: Theme) {
|
|
35
|
-
return ({ color
|
|
36
|
-
const colorValue = theme.colors.text[color] || theme.colors.text.primary;
|
|
40
|
+
return ({ color }: TextStyleParams) => {
|
|
41
|
+
const colorValue = theme.colors.text[color ?? 'primary'] || theme.colors.text.primary;
|
|
37
42
|
|
|
38
|
-
|
|
39
|
-
const baseStyles: any = {
|
|
43
|
+
return {
|
|
40
44
|
margin: 0,
|
|
41
45
|
padding: 0,
|
|
42
46
|
color: colorValue,
|
|
43
47
|
variants: {
|
|
44
|
-
|
|
48
|
+
typography: createTypographyVariants(theme),
|
|
45
49
|
weight: {
|
|
46
50
|
light: {
|
|
47
51
|
fontWeight: '300',
|
|
@@ -78,19 +82,8 @@ function createTextStyles(theme: Theme) {
|
|
|
78
82
|
} as const,
|
|
79
83
|
_web: {
|
|
80
84
|
fontFamily: 'inherit',
|
|
81
|
-
lineHeight: 'inherit',
|
|
82
85
|
},
|
|
83
86
|
};
|
|
84
|
-
|
|
85
|
-
// If typography is set, apply typography styles (overrides size/weight variants)
|
|
86
|
-
if (typography && theme.sizes.typography[typography]) {
|
|
87
|
-
const typo = theme.sizes.typography[typography];
|
|
88
|
-
baseStyles.fontSize = typo.fontSize;
|
|
89
|
-
baseStyles.lineHeight = typo.lineHeight;
|
|
90
|
-
baseStyles.fontWeight = typo.fontWeight;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return baseStyles;
|
|
94
87
|
}
|
|
95
88
|
}
|
|
96
89
|
|
|
@@ -100,4 +93,4 @@ export const textStyles = StyleSheet.create((theme: Theme) => {
|
|
|
100
93
|
return {
|
|
101
94
|
text: createTextStyles(theme),
|
|
102
95
|
};
|
|
103
|
-
});
|
|
96
|
+
});
|
package/src/Text/Text.web.tsx
CHANGED
|
@@ -6,9 +6,8 @@ import useMergeRefs from '../hooks/useMergeRefs';
|
|
|
6
6
|
|
|
7
7
|
const Text = forwardRef<HTMLSpanElement, TextProps>(({
|
|
8
8
|
children,
|
|
9
|
-
typography,
|
|
10
|
-
|
|
11
|
-
weight = 'normal',
|
|
9
|
+
typography = 'body1',
|
|
10
|
+
weight,
|
|
12
11
|
color = 'primary',
|
|
13
12
|
align = 'left',
|
|
14
13
|
// Spacing variants from TextSpacingStyleProps
|
|
@@ -18,11 +17,11 @@ const Text = forwardRef<HTMLSpanElement, TextProps>(({
|
|
|
18
17
|
paddingHorizontal,
|
|
19
18
|
style,
|
|
20
19
|
testID,
|
|
20
|
+
id,
|
|
21
21
|
}, ref) => {
|
|
22
|
-
// When typography is set, it overrides size and weight (handled in styles)
|
|
23
22
|
textStyles.useVariants({
|
|
24
|
-
|
|
25
|
-
weight
|
|
23
|
+
typography,
|
|
24
|
+
weight,
|
|
26
25
|
align,
|
|
27
26
|
gap,
|
|
28
27
|
padding,
|
|
@@ -30,9 +29,9 @@ const Text = forwardRef<HTMLSpanElement, TextProps>(({
|
|
|
30
29
|
paddingHorizontal,
|
|
31
30
|
});
|
|
32
31
|
|
|
33
|
-
// Create the style array
|
|
32
|
+
// Create the style array
|
|
34
33
|
const textStyleArray = [
|
|
35
|
-
textStyles.text({ color
|
|
34
|
+
textStyles.text({ color }),
|
|
36
35
|
style,
|
|
37
36
|
];
|
|
38
37
|
|
|
@@ -45,6 +44,7 @@ const Text = forwardRef<HTMLSpanElement, TextProps>(({
|
|
|
45
44
|
<span
|
|
46
45
|
{...webProps}
|
|
47
46
|
ref={mergedRef}
|
|
47
|
+
id={id}
|
|
48
48
|
data-testid={testID}
|
|
49
49
|
>
|
|
50
50
|
{children}
|
package/src/Text/types.ts
CHANGED
|
@@ -5,7 +5,6 @@ import { TextSpacingStyleProps } from '../utils/viewStyleProps';
|
|
|
5
5
|
|
|
6
6
|
// Component-specific type aliases for future extensibility
|
|
7
7
|
export type TextColorVariant = Text;
|
|
8
|
-
export type TextSizeVariant = 'sm' | 'md' | 'lg' | 'xl'; // Using sm/md/lg/xl for consistency
|
|
9
8
|
export type TextWeightVariant = 'light' | 'normal' | 'medium' | 'semibold' | 'bold';
|
|
10
9
|
export type TextAlignVariant = 'left' | 'center' | 'right';
|
|
11
10
|
export type TextTypographyVariant = Typography;
|
|
@@ -19,19 +18,12 @@ export interface TextProps extends TextSpacingStyleProps {
|
|
|
19
18
|
/**
|
|
20
19
|
* Typography variant for semantic text styling.
|
|
21
20
|
* Automatically sets fontSize, lineHeight, and fontWeight.
|
|
22
|
-
* When set, overrides size and weight props.
|
|
23
21
|
*/
|
|
24
22
|
typography?: TextTypographyVariant;
|
|
25
23
|
|
|
26
|
-
/**
|
|
27
|
-
* The size variant of the text
|
|
28
|
-
* @deprecated Use `typography` prop instead for semantic text styling (e.g., 'h1', 'body1', 'caption')
|
|
29
|
-
*/
|
|
30
|
-
size?: TextSizeVariant;
|
|
31
|
-
|
|
32
24
|
/**
|
|
33
25
|
* The weight of the text.
|
|
34
|
-
*
|
|
26
|
+
* Overrides the weight from typography if both are set.
|
|
35
27
|
*/
|
|
36
28
|
weight?: TextWeightVariant;
|
|
37
29
|
|
|
@@ -28,6 +28,7 @@ const TextArea = forwardRef<TextInput, TextAreaProps>(({
|
|
|
28
28
|
style,
|
|
29
29
|
textareaStyle,
|
|
30
30
|
testID,
|
|
31
|
+
id,
|
|
31
32
|
}, ref) => {
|
|
32
33
|
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
33
34
|
const [contentHeight, setContentHeight] = useState<number | undefined>(undefined);
|
|
@@ -81,7 +82,7 @@ const TextArea = forwardRef<TextInput, TextAreaProps>(({
|
|
|
81
82
|
const showFooter = (error || helperText) || (showCharacterCount && maxLength);
|
|
82
83
|
|
|
83
84
|
return (
|
|
84
|
-
<View style={[textAreaStyles.container, style]} testID={testID}>
|
|
85
|
+
<View nativeID={id} style={[textAreaStyles.container, style]} testID={testID}>
|
|
85
86
|
{label && (
|
|
86
87
|
<Text style={textAreaStyles.label}>{label}</Text>
|
|
87
88
|
)}
|
|
@@ -29,6 +29,7 @@ const TextArea = forwardRef<HTMLDivElement, TextAreaProps>(({
|
|
|
29
29
|
style,
|
|
30
30
|
textareaStyle,
|
|
31
31
|
testID,
|
|
32
|
+
id,
|
|
32
33
|
}, ref) => {
|
|
33
34
|
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
34
35
|
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
|
@@ -112,7 +113,7 @@ const TextArea = forwardRef<HTMLDivElement, TextAreaProps>(({
|
|
|
112
113
|
const mergedTextareaRef = useMergeRefs(textareaRef, computedTextareaProps.ref);
|
|
113
114
|
|
|
114
115
|
return (
|
|
115
|
-
<div {...containerProps} ref={mergedRef} data-testid={testID}>
|
|
116
|
+
<div {...containerProps} ref={mergedRef} id={id} data-testid={testID}>
|
|
116
117
|
{label && (
|
|
117
118
|
<label {...labelProps}>{label}</label>
|
|
118
119
|
)}
|
|
@@ -12,6 +12,7 @@ const Tooltip = forwardRef<View, TooltipProps>(({
|
|
|
12
12
|
size = 'md',
|
|
13
13
|
style,
|
|
14
14
|
testID,
|
|
15
|
+
id,
|
|
15
16
|
}, ref) => {
|
|
16
17
|
const [visible, setVisible] = useState(false);
|
|
17
18
|
const [tooltipPosition, setTooltipPosition] = useState({ top: 0, left: 0, width: 0 });
|
|
@@ -126,7 +127,7 @@ const Tooltip = forwardRef<View, TooltipProps>(({
|
|
|
126
127
|
|
|
127
128
|
return (
|
|
128
129
|
<>
|
|
129
|
-
<View ref={ref} collapsable={false} style={style}>
|
|
130
|
+
<View ref={ref} nativeID={id} collapsable={false} style={style}>
|
|
130
131
|
{trigger}
|
|
131
132
|
</View>
|
|
132
133
|
|
|
@@ -13,6 +13,7 @@ const Tooltip: React.FC<TooltipProps> = ({
|
|
|
13
13
|
size = 'md',
|
|
14
14
|
style,
|
|
15
15
|
testID,
|
|
16
|
+
id,
|
|
16
17
|
}) => {
|
|
17
18
|
const [visible, setVisible] = useState(false);
|
|
18
19
|
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
|
|
@@ -60,6 +61,7 @@ const Tooltip: React.FC<TooltipProps> = ({
|
|
|
60
61
|
{...containerProps}
|
|
61
62
|
onMouseEnter={handleMouseEnter}
|
|
62
63
|
onMouseLeave={handleMouseLeave}
|
|
64
|
+
id={id}
|
|
63
65
|
data-testid={testID}
|
|
64
66
|
>
|
|
65
67
|
{children}
|
package/src/Tooltip/types.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { Intent, Size } from '@idealyst/theme';
|
|
2
2
|
import type { StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
import { BaseProps } from '../utils/viewStyleProps';
|
|
3
4
|
|
|
4
5
|
// Component-specific type aliases for future extensibility
|
|
5
6
|
export type TooltipIntentVariant = Intent;
|
|
6
7
|
export type TooltipSizeVariant = Size;
|
|
7
8
|
export type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';
|
|
8
9
|
|
|
9
|
-
export interface TooltipProps {
|
|
10
|
+
export interface TooltipProps extends BaseProps {
|
|
10
11
|
content: string | React.ReactNode;
|
|
11
12
|
children: React.ReactNode;
|
|
12
13
|
placement?: TooltipPlacement;
|
|
@@ -32,11 +32,12 @@ const Video = React.forwardRef<View, VideoProps>(({
|
|
|
32
32
|
borderRadius,
|
|
33
33
|
style,
|
|
34
34
|
testID,
|
|
35
|
+
id,
|
|
35
36
|
}, ref) => {
|
|
36
37
|
|
|
37
38
|
if (!RNVideo) {
|
|
38
39
|
return (
|
|
39
|
-
<View ref={ref} style={[videoStyles.container, { aspectRatio, borderRadius }, style]} testID={testID}>
|
|
40
|
+
<View ref={ref} nativeID={id} style={[videoStyles.container, { aspectRatio, borderRadius }, style]} testID={testID}>
|
|
40
41
|
<View style={videoStyles.fallback}>
|
|
41
42
|
{/* Fallback when react-native-video is not installed */}
|
|
42
43
|
</View>
|
|
@@ -79,7 +80,7 @@ const Video = React.forwardRef<View, VideoProps>(({
|
|
|
79
80
|
};
|
|
80
81
|
|
|
81
82
|
return (
|
|
82
|
-
<View ref={ref} style={containerStyle} testID={testID}>
|
|
83
|
+
<View ref={ref} nativeID={id} style={containerStyle} testID={testID}>
|
|
83
84
|
<RNVideo
|
|
84
85
|
source={videoSource}
|
|
85
86
|
poster={poster}
|
package/src/Video/Video.web.tsx
CHANGED
|
@@ -25,6 +25,7 @@ const Video: React.FC<VideoProps> = ({
|
|
|
25
25
|
borderRadius,
|
|
26
26
|
style,
|
|
27
27
|
testID,
|
|
28
|
+
id,
|
|
28
29
|
}) => {
|
|
29
30
|
const videoRef = useRef<HTMLVideoElement>(null);
|
|
30
31
|
|
|
@@ -85,6 +86,7 @@ const Video: React.FC<VideoProps> = ({
|
|
|
85
86
|
<div
|
|
86
87
|
{...containerProps}
|
|
87
88
|
style={containerStyle}
|
|
89
|
+
id={id}
|
|
88
90
|
data-testid={testID}
|
|
89
91
|
>
|
|
90
92
|
<video
|
package/src/Video/types.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { StyleProp, ViewStyle } from 'react-native';
|
|
2
|
+
import { BaseProps } from '../utils/viewStyleProps';
|
|
2
3
|
|
|
3
4
|
export interface VideoSource {
|
|
4
5
|
uri: string;
|
|
5
6
|
type?: string;
|
|
6
7
|
}
|
|
7
8
|
|
|
8
|
-
export interface VideoProps {
|
|
9
|
+
export interface VideoProps extends BaseProps {
|
|
9
10
|
source: VideoSource | string;
|
|
10
11
|
poster?: string;
|
|
11
12
|
width?: number | string;
|
package/src/View/View.native.tsx
CHANGED
|
@@ -24,6 +24,7 @@ const View = forwardRef<RNView | RNScrollView, ViewProps>(({
|
|
|
24
24
|
scrollable = false,
|
|
25
25
|
style,
|
|
26
26
|
testID,
|
|
27
|
+
id,
|
|
27
28
|
}, ref) => {
|
|
28
29
|
viewStyles.useVariants({
|
|
29
30
|
background,
|
|
@@ -56,6 +57,7 @@ const View = forwardRef<RNView | RNScrollView, ViewProps>(({
|
|
|
56
57
|
style={[{ flex: 1 }, style]}
|
|
57
58
|
contentContainerStyle={[viewStyles.view, getStyles()]}
|
|
58
59
|
testID={testID}
|
|
60
|
+
nativeID={id}
|
|
59
61
|
>
|
|
60
62
|
{children}
|
|
61
63
|
</RNScrollView>
|
|
@@ -63,7 +65,7 @@ const View = forwardRef<RNView | RNScrollView, ViewProps>(({
|
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
return (
|
|
66
|
-
<RNView ref={ref as any} style={[viewStyles.view, getStyles(), style]} testID={testID}>
|
|
68
|
+
<RNView ref={ref as any} style={[viewStyles.view, getStyles(), style]} testID={testID} nativeID={id}>
|
|
67
69
|
{children}
|
|
68
70
|
</RNView>
|
|
69
71
|
);
|
package/src/View/View.web.tsx
CHANGED
|
@@ -25,6 +25,7 @@ const View = forwardRef<HTMLDivElement, ViewProps>(({
|
|
|
25
25
|
scrollable, // accepted but no-op on web - layout handles scrolling
|
|
26
26
|
style,
|
|
27
27
|
testID,
|
|
28
|
+
id,
|
|
28
29
|
}, ref) => {
|
|
29
30
|
viewStyles.useVariants({
|
|
30
31
|
background,
|
|
@@ -56,6 +57,7 @@ const View = forwardRef<HTMLDivElement, ViewProps>(({
|
|
|
56
57
|
<div
|
|
57
58
|
{...webProps}
|
|
58
59
|
ref={mergedRef}
|
|
60
|
+
id={id}
|
|
59
61
|
data-testid={testID}
|
|
60
62
|
>
|
|
61
63
|
{children}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
|
-
import { Screen, View, Text } from '@idealyst/components';
|
|
2
|
+
import { Screen, View, Text, Icon } from '@idealyst/components';
|
|
3
3
|
import TabBar from '../TabBar';
|
|
4
4
|
import type { TabBarItem } from '../TabBar/types';
|
|
5
5
|
|
|
@@ -7,6 +7,8 @@ export const TabBarExamples: React.FC = () => {
|
|
|
7
7
|
const [activeTab, setActiveTab] = useState('tab1');
|
|
8
8
|
const [variantTab, setVariantTab] = useState('home');
|
|
9
9
|
const [pillTab, setPillTab] = useState('tab1');
|
|
10
|
+
const [iconTab, setIconTab] = useState('home');
|
|
11
|
+
const [justifyTab, setJustifyTab] = useState('tab1');
|
|
10
12
|
|
|
11
13
|
const basicTabs: TabBarItem[] = [
|
|
12
14
|
{ value: 'tab1', label: 'Tab 1' },
|
|
@@ -26,6 +28,38 @@ export const TabBarExamples: React.FC = () => {
|
|
|
26
28
|
{ value: 'tab3', label: 'Enabled' },
|
|
27
29
|
];
|
|
28
30
|
|
|
31
|
+
// Tabs with icons using render function
|
|
32
|
+
const iconTabs: TabBarItem[] = [
|
|
33
|
+
{
|
|
34
|
+
value: 'home',
|
|
35
|
+
label: 'Home',
|
|
36
|
+
icon: ({ active, size }) => (
|
|
37
|
+
<Icon name="home" size={size} color={active ? 'primary' : 'secondary'} />
|
|
38
|
+
),
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
value: 'search',
|
|
42
|
+
label: 'Search',
|
|
43
|
+
icon: ({ active, size }) => (
|
|
44
|
+
<Icon name="magnify" size={size} color={active ? 'primary' : 'secondary'} />
|
|
45
|
+
),
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
value: 'profile',
|
|
49
|
+
label: 'Profile',
|
|
50
|
+
icon: ({ active, size }) => (
|
|
51
|
+
<Icon name="account" size={size} color={active ? 'primary' : 'secondary'} />
|
|
52
|
+
),
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
value: 'settings',
|
|
56
|
+
label: 'Settings',
|
|
57
|
+
icon: ({ active, size }) => (
|
|
58
|
+
<Icon name="cog" size={size} color={active ? 'primary' : 'secondary'} />
|
|
59
|
+
),
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
|
|
29
63
|
return (
|
|
30
64
|
<Screen background="primary" padding="lg">
|
|
31
65
|
<View gap="lg">
|
|
@@ -135,6 +169,93 @@ export const TabBarExamples: React.FC = () => {
|
|
|
135
169
|
onChange={setActiveTab}
|
|
136
170
|
/>
|
|
137
171
|
</View>
|
|
172
|
+
|
|
173
|
+
<View gap="md">
|
|
174
|
+
<Text typography="h5">With Icons</Text>
|
|
175
|
+
<View gap="sm">
|
|
176
|
+
<View gap="xs">
|
|
177
|
+
<Text typography="body2">Icons Left (default)</Text>
|
|
178
|
+
<TabBar
|
|
179
|
+
items={iconTabs}
|
|
180
|
+
value={iconTab}
|
|
181
|
+
onChange={setIconTab}
|
|
182
|
+
iconPosition="left"
|
|
183
|
+
/>
|
|
184
|
+
</View>
|
|
185
|
+
<View gap="xs">
|
|
186
|
+
<Text typography="body2">Icons Top (stacked)</Text>
|
|
187
|
+
<TabBar
|
|
188
|
+
items={iconTabs}
|
|
189
|
+
value={iconTab}
|
|
190
|
+
onChange={setIconTab}
|
|
191
|
+
iconPosition="top"
|
|
192
|
+
/>
|
|
193
|
+
</View>
|
|
194
|
+
<View gap="xs">
|
|
195
|
+
<Text typography="body2">Pills with Icons</Text>
|
|
196
|
+
<TabBar
|
|
197
|
+
items={iconTabs}
|
|
198
|
+
value={iconTab}
|
|
199
|
+
onChange={setIconTab}
|
|
200
|
+
type="pills"
|
|
201
|
+
iconPosition="left"
|
|
202
|
+
/>
|
|
203
|
+
</View>
|
|
204
|
+
</View>
|
|
205
|
+
</View>
|
|
206
|
+
|
|
207
|
+
<View gap="md">
|
|
208
|
+
<Text typography="h5">Layout Justification</Text>
|
|
209
|
+
<View gap="sm">
|
|
210
|
+
<View gap="xs">
|
|
211
|
+
<Text typography="body2">Start (default)</Text>
|
|
212
|
+
<TabBar
|
|
213
|
+
items={basicTabs}
|
|
214
|
+
value={justifyTab}
|
|
215
|
+
onChange={setJustifyTab}
|
|
216
|
+
justify="start"
|
|
217
|
+
/>
|
|
218
|
+
</View>
|
|
219
|
+
<View gap="xs">
|
|
220
|
+
<Text typography="body2">Center</Text>
|
|
221
|
+
<TabBar
|
|
222
|
+
items={basicTabs}
|
|
223
|
+
value={justifyTab}
|
|
224
|
+
onChange={setJustifyTab}
|
|
225
|
+
justify="center"
|
|
226
|
+
/>
|
|
227
|
+
</View>
|
|
228
|
+
<View gap="xs">
|
|
229
|
+
<Text typography="body2">Equal (full width, equal tabs)</Text>
|
|
230
|
+
<TabBar
|
|
231
|
+
items={basicTabs}
|
|
232
|
+
value={justifyTab}
|
|
233
|
+
onChange={setJustifyTab}
|
|
234
|
+
justify="equal"
|
|
235
|
+
/>
|
|
236
|
+
</View>
|
|
237
|
+
<View gap="xs">
|
|
238
|
+
<Text typography="body2">Space Between</Text>
|
|
239
|
+
<TabBar
|
|
240
|
+
items={basicTabs}
|
|
241
|
+
value={justifyTab}
|
|
242
|
+
onChange={setJustifyTab}
|
|
243
|
+
justify="space-between"
|
|
244
|
+
/>
|
|
245
|
+
</View>
|
|
246
|
+
</View>
|
|
247
|
+
</View>
|
|
248
|
+
|
|
249
|
+
<View gap="md">
|
|
250
|
+
<Text typography="h5">Full Width with Icons</Text>
|
|
251
|
+
<TabBar
|
|
252
|
+
items={iconTabs}
|
|
253
|
+
value={iconTab}
|
|
254
|
+
onChange={setIconTab}
|
|
255
|
+
justify="equal"
|
|
256
|
+
iconPosition="top"
|
|
257
|
+
/>
|
|
258
|
+
</View>
|
|
138
259
|
</View>
|
|
139
260
|
</Screen>
|
|
140
261
|
);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Size variant builder
|
|
2
|
+
export { buildSizeVariants } from './buildSizeVariants';
|
|
3
|
+
|
|
4
|
+
// View/container style variant builders
|
|
5
|
+
export {
|
|
6
|
+
buildGapVariants,
|
|
7
|
+
buildPaddingVariants,
|
|
8
|
+
buildPaddingVerticalVariants,
|
|
9
|
+
buildPaddingHorizontalVariants,
|
|
10
|
+
buildMarginVariants,
|
|
11
|
+
buildMarginVerticalVariants,
|
|
12
|
+
buildMarginHorizontalVariants,
|
|
13
|
+
buildContainerStyleVariants,
|
|
14
|
+
buildPaddingStyleVariants,
|
|
15
|
+
buildMarginStyleVariants,
|
|
16
|
+
buildTextSpacingVariants,
|
|
17
|
+
} from './buildViewStyleVariants';
|
|
18
|
+
|
|
19
|
+
// General style helpers
|
|
20
|
+
export { deepMerge, isPlainObject } from './styleHelpers';
|
|
@@ -6,6 +6,14 @@ import { Size } from '@idealyst/theme';
|
|
|
6
6
|
*/
|
|
7
7
|
export type ViewStyleSize = Size;
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Base props shared by all components
|
|
11
|
+
*/
|
|
12
|
+
export interface BaseProps {
|
|
13
|
+
/** Unique identifier for the element (maps to id on web, nativeID on native) */
|
|
14
|
+
id?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
9
17
|
/**
|
|
10
18
|
* Gap style props - for controlling gap/spacing between children
|
|
11
19
|
*/
|
|
@@ -42,22 +50,22 @@ export interface MarginStyleProps {
|
|
|
42
50
|
* Full container style props - includes all spacing options
|
|
43
51
|
* For: View, Card, Screen, List, Accordion, Table, TabBar
|
|
44
52
|
*/
|
|
45
|
-
export interface ContainerStyleProps extends GapStyleProps, PaddingStyleProps, MarginStyleProps {}
|
|
53
|
+
export interface ContainerStyleProps extends BaseProps, GapStyleProps, PaddingStyleProps, MarginStyleProps {}
|
|
46
54
|
|
|
47
55
|
/**
|
|
48
56
|
* Text spacing style props - gap + padding only
|
|
49
57
|
* For: Text (gap for inline elements, padding for block-level)
|
|
50
58
|
*/
|
|
51
|
-
export interface TextSpacingStyleProps extends GapStyleProps, PaddingStyleProps {}
|
|
59
|
+
export interface TextSpacingStyleProps extends BaseProps, GapStyleProps, PaddingStyleProps {}
|
|
52
60
|
|
|
53
61
|
/**
|
|
54
62
|
* Pressable style props - padding only
|
|
55
63
|
* For: Pressable
|
|
56
64
|
*/
|
|
57
|
-
export interface PressableSpacingStyleProps extends PaddingStyleProps {}
|
|
65
|
+
export interface PressableSpacingStyleProps extends BaseProps, PaddingStyleProps {}
|
|
58
66
|
|
|
59
67
|
/**
|
|
60
68
|
* Form input style props - margin only
|
|
61
69
|
* For: Input, Select, TextArea, Checkbox, RadioButton, Switch, Slider
|
|
62
70
|
*/
|
|
63
|
-
export interface FormInputStyleProps extends MarginStyleProps {}
|
|
71
|
+
export interface FormInputStyleProps extends BaseProps, MarginStyleProps {}
|