@idealyst/components 1.0.53 → 1.0.56
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/CLAUDE.md +10 -1
- package/README.md +111 -319
- package/package.json +5 -4
- package/src/Pressable/Pressable.native.tsx +9 -8
- package/src/SVGImage/README.md +209 -0
- package/src/SVGImage/SVGImage.native.tsx +60 -0
- package/src/SVGImage/SVGImage.styles.tsx +70 -0
- package/src/SVGImage/SVGImage.web.tsx +93 -0
- package/src/SVGImage/index.native.ts +2 -0
- package/src/SVGImage/index.ts +5 -0
- package/src/SVGImage/index.web.ts +2 -0
- package/src/SVGImage/types.ts +14 -0
- package/src/examples/AllExamples.tsx +4 -0
- package/src/examples/SVGImageExamples.tsx +188 -0
- package/src/examples/index.ts +1 -0
- package/src/examples/test-logo.svg +8 -0
- package/src/index.native.ts +4 -0
- package/src/index.ts +4 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# SVGImage Component
|
|
2
|
+
|
|
3
|
+
A cross-platform React/React Native component for rendering SVG images with theme support and consistent styling.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The SVGImage component provides a unified way to display SVG images across web and React Native platforms. It supports both imported SVG files (as React components) and remote SVG URLs, with built-in theming and styling capabilities.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
The SVGImage component is part of the `@idealyst/components` package:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
yarn add @idealyst/components
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
For React Native projects, you also need:
|
|
18
|
+
```bash
|
|
19
|
+
yarn add react-native-svg react-native-svg-transformer
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Basic Usage
|
|
23
|
+
|
|
24
|
+
### Imported SVG Files (Recommended)
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import { SVGImage } from '@idealyst/components';
|
|
28
|
+
import MyLogo from './assets/logo.svg';
|
|
29
|
+
|
|
30
|
+
function MyComponent() {
|
|
31
|
+
return (
|
|
32
|
+
<SVGImage
|
|
33
|
+
source={MyLogo}
|
|
34
|
+
width={100}
|
|
35
|
+
height={50}
|
|
36
|
+
/>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Remote SVG URLs
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
import { SVGImage } from '@idealyst/components';
|
|
45
|
+
|
|
46
|
+
function MyComponent() {
|
|
47
|
+
return (
|
|
48
|
+
<SVGImage
|
|
49
|
+
source={{ uri: "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/react.svg" }}
|
|
50
|
+
width={60}
|
|
51
|
+
height={60}
|
|
52
|
+
color="#61dafb"
|
|
53
|
+
/>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Props
|
|
59
|
+
|
|
60
|
+
| Prop | Type | Default | Description |
|
|
61
|
+
|------|------|---------|-------------|
|
|
62
|
+
| `source` | `string \| { uri: string } \| React.FC<SvgProps>` | **Required** | SVG source - can be imported component, URL string, or URI object |
|
|
63
|
+
| `width` | `number \| string` | `24` | Width of the SVG |
|
|
64
|
+
| `height` | `number \| string` | `24` | Height of the SVG |
|
|
65
|
+
| `size` | `number \| string` | - | Sets both width and height (overrides individual width/height) |
|
|
66
|
+
| `color` | `string` | - | Fill color for the SVG |
|
|
67
|
+
| `intent` | `'primary' \| 'success' \| 'error' \| 'warning' \| 'neutral'` | - | Theme-based color intent |
|
|
68
|
+
| `style` | `ViewStyle` | - | Additional container styles |
|
|
69
|
+
| `testID` | `string` | - | Test identifier |
|
|
70
|
+
|
|
71
|
+
## Theme Integration
|
|
72
|
+
|
|
73
|
+
The SVGImage component integrates with the Idealyst theme system:
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
<SVGImage
|
|
77
|
+
source={MyIcon}
|
|
78
|
+
size={24}
|
|
79
|
+
intent="primary" // Uses theme's primary color
|
|
80
|
+
/>
|
|
81
|
+
|
|
82
|
+
<SVGImage
|
|
83
|
+
source={MyIcon}
|
|
84
|
+
size={24}
|
|
85
|
+
intent="success" // Uses theme's success color
|
|
86
|
+
/>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Platform Setup
|
|
90
|
+
|
|
91
|
+
### React Native Setup
|
|
92
|
+
|
|
93
|
+
1. **Install dependencies:**
|
|
94
|
+
```bash
|
|
95
|
+
yarn add react-native-svg react-native-svg-transformer
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
2. **Configure Metro bundler** (`metro.config.js`):
|
|
99
|
+
```javascript
|
|
100
|
+
const config = {
|
|
101
|
+
transformer: {
|
|
102
|
+
babelTransformerPath: require.resolve('react-native-svg-transformer'),
|
|
103
|
+
},
|
|
104
|
+
resolver: {
|
|
105
|
+
sourceExts: ['js', 'jsx', 'ts', 'tsx', 'svg'],
|
|
106
|
+
assetExts: ['png', 'jpg', 'jpeg', 'gif', 'webp'],
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
3. **Add TypeScript declarations** (`types/svg.d.ts`):
|
|
112
|
+
```typescript
|
|
113
|
+
declare module '*.svg' {
|
|
114
|
+
import React from 'react';
|
|
115
|
+
import { SvgProps } from 'react-native-svg';
|
|
116
|
+
const content: React.FC<SvgProps>;
|
|
117
|
+
export default content;
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
4. **iOS: Install pods:**
|
|
122
|
+
```bash
|
|
123
|
+
cd ios && pod install
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Web Setup
|
|
127
|
+
|
|
128
|
+
For web projects using Vite, SVG imports work out of the box. Add TypeScript declarations if needed:
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
// types/svg.d.ts
|
|
132
|
+
declare module '*.svg' {
|
|
133
|
+
import React from 'react';
|
|
134
|
+
const content: React.FC<React.SVGProps<SVGSVGElement>>;
|
|
135
|
+
export default content;
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Examples
|
|
140
|
+
|
|
141
|
+
### Basic Usage
|
|
142
|
+
```tsx
|
|
143
|
+
import { SVGImage } from '@idealyst/components';
|
|
144
|
+
import LogoIcon from './logo.svg';
|
|
145
|
+
|
|
146
|
+
<SVGImage source={LogoIcon} size={40} />
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### With Theme Colors
|
|
150
|
+
```tsx
|
|
151
|
+
<SVGImage
|
|
152
|
+
source={LogoIcon}
|
|
153
|
+
size={32}
|
|
154
|
+
intent="primary"
|
|
155
|
+
/>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Remote SVG
|
|
159
|
+
```tsx
|
|
160
|
+
<SVGImage
|
|
161
|
+
source={{ uri: "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/typescript.svg" }}
|
|
162
|
+
width={48}
|
|
163
|
+
height={48}
|
|
164
|
+
color="#3178c6"
|
|
165
|
+
/>
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Custom Styling
|
|
169
|
+
```tsx
|
|
170
|
+
<SVGImage
|
|
171
|
+
source={LogoIcon}
|
|
172
|
+
size={60}
|
|
173
|
+
style={{
|
|
174
|
+
backgroundColor: '#f0f0f0',
|
|
175
|
+
borderRadius: 8,
|
|
176
|
+
padding: 8
|
|
177
|
+
}}
|
|
178
|
+
/>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Best Practices
|
|
182
|
+
|
|
183
|
+
1. **Prefer imported SVGs over URLs** - Better performance and reliability
|
|
184
|
+
2. **Use theme intents** - Ensures consistency with your design system
|
|
185
|
+
3. **Provide dimensions** - Always specify width/height or size
|
|
186
|
+
4. **Test on both platforms** - Verify SVGs render correctly on web and mobile
|
|
187
|
+
5. **Use CDN URLs** - For remote SVGs, use reliable CDNs like jsDelivr
|
|
188
|
+
|
|
189
|
+
## Limitations
|
|
190
|
+
|
|
191
|
+
- **React Native**: Local SVG files must be imported as components (not file paths)
|
|
192
|
+
- **Remote URLs**: Some servers may block requests from mobile apps (403 errors)
|
|
193
|
+
- **Coloring**: Works best with single-color SVG icons
|
|
194
|
+
|
|
195
|
+
## Troubleshooting
|
|
196
|
+
|
|
197
|
+
### SVGs not showing on React Native
|
|
198
|
+
- Ensure `react-native-svg-transformer` is configured in Metro
|
|
199
|
+
- Check that SVGs are imported as components, not file paths
|
|
200
|
+
- Verify pods are installed on iOS
|
|
201
|
+
|
|
202
|
+
### Remote SVGs failing
|
|
203
|
+
- Use CDN URLs (e.g., jsDelivr, unpkg) instead of direct server URLs
|
|
204
|
+
- Check browser console for CORS or 403 errors
|
|
205
|
+
- Consider hosting SVGs on your own CDN
|
|
206
|
+
|
|
207
|
+
### TypeScript errors
|
|
208
|
+
- Add SVG type declarations to your project
|
|
209
|
+
- Ensure `react-native-svg` types are installed
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { SvgUri } from 'react-native-svg';
|
|
4
|
+
import { SVGImageProps } from './types';
|
|
5
|
+
import { svgImageStyles } from './SVGImage.styles';
|
|
6
|
+
|
|
7
|
+
const SVGImage: React.FC<SVGImageProps> = ({
|
|
8
|
+
source,
|
|
9
|
+
width,
|
|
10
|
+
height,
|
|
11
|
+
size,
|
|
12
|
+
color,
|
|
13
|
+
intent,
|
|
14
|
+
style,
|
|
15
|
+
testID,
|
|
16
|
+
...props
|
|
17
|
+
}) => {
|
|
18
|
+
// Apply variants using Unistyles 3.0 pattern
|
|
19
|
+
if (intent) {
|
|
20
|
+
svgImageStyles.useVariants({
|
|
21
|
+
intent: intent as 'primary' | 'success' | 'error' | 'warning' | 'neutral',
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Determine dimensions - size takes precedence over individual width/height
|
|
26
|
+
const finalWidth = size || width || 24;
|
|
27
|
+
const finalHeight = size || height || 24;
|
|
28
|
+
|
|
29
|
+
// Mode 1: Handle React components (imported SVG components)
|
|
30
|
+
if (typeof source === 'function') {
|
|
31
|
+
const SvgComponent = source;
|
|
32
|
+
return (
|
|
33
|
+
<View style={[svgImageStyles.container, style]} testID={testID} {...props}>
|
|
34
|
+
<SvgComponent
|
|
35
|
+
width={finalWidth}
|
|
36
|
+
height={finalHeight}
|
|
37
|
+
fill={color}
|
|
38
|
+
color={color}
|
|
39
|
+
/>
|
|
40
|
+
</View>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Mode 2: Handle URI-based SVG loading
|
|
45
|
+
const sourceUri = typeof source === 'string' ? source : source.uri;
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<View style={[svgImageStyles.container, style]} testID={testID} {...props}>
|
|
49
|
+
<SvgUri
|
|
50
|
+
uri={sourceUri}
|
|
51
|
+
width={finalWidth}
|
|
52
|
+
height={finalHeight}
|
|
53
|
+
fill={color}
|
|
54
|
+
color={color}
|
|
55
|
+
/>
|
|
56
|
+
</View>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export default SVGImage;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
2
|
+
|
|
3
|
+
export const svgImageStyles = StyleSheet.create((theme) => ({
|
|
4
|
+
container: {
|
|
5
|
+
alignItems: 'center',
|
|
6
|
+
justifyContent: 'center',
|
|
7
|
+
|
|
8
|
+
variants: {
|
|
9
|
+
intent: {
|
|
10
|
+
primary: {
|
|
11
|
+
// Use CSS filter for web, tintColor for React Native
|
|
12
|
+
filter: `brightness(0) saturate(100%) invert(27%) sepia(51%) saturate(2878%) hue-rotate(346deg) brightness(104%) contrast(97%)`,
|
|
13
|
+
},
|
|
14
|
+
success: {
|
|
15
|
+
filter: `brightness(0) saturate(100%) invert(64%) sepia(88%) saturate(3323%) hue-rotate(84deg) brightness(119%) contrast(119%)`,
|
|
16
|
+
},
|
|
17
|
+
error: {
|
|
18
|
+
filter: `brightness(0) saturate(100%) invert(23%) sepia(89%) saturate(7395%) hue-rotate(4deg) brightness(102%) contrast(118%)`,
|
|
19
|
+
},
|
|
20
|
+
warning: {
|
|
21
|
+
filter: `brightness(0) saturate(100%) invert(54%) sepia(98%) saturate(4341%) hue-rotate(21deg) brightness(101%) contrast(101%)`,
|
|
22
|
+
},
|
|
23
|
+
neutral: {
|
|
24
|
+
filter: `brightness(0) saturate(100%) invert(52%) sepia(23%) saturate(3207%) hue-rotate(314deg) brightness(99%) contrast(96%)`,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
// Web-specific styles
|
|
30
|
+
_web: {
|
|
31
|
+
userSelect: 'none',
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
// Native-specific styles
|
|
35
|
+
_native: {
|
|
36
|
+
variants: {
|
|
37
|
+
intent: {
|
|
38
|
+
primary: {
|
|
39
|
+
tintColor: theme.intents?.primary?.main || '#3b82f6',
|
|
40
|
+
},
|
|
41
|
+
success: {
|
|
42
|
+
tintColor: theme.intents?.success?.main || '#22c55e',
|
|
43
|
+
},
|
|
44
|
+
error: {
|
|
45
|
+
tintColor: theme.intents?.error?.main || '#ef4444',
|
|
46
|
+
},
|
|
47
|
+
warning: {
|
|
48
|
+
tintColor: theme.intents?.warning?.main || '#f59e0b',
|
|
49
|
+
},
|
|
50
|
+
neutral: {
|
|
51
|
+
tintColor: theme.intents?.neutral?.main || '#6b7280',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
image: {
|
|
59
|
+
// Base image styles
|
|
60
|
+
_web: {
|
|
61
|
+
display: 'block',
|
|
62
|
+
maxWidth: '100%',
|
|
63
|
+
height: 'auto',
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
_native: {
|
|
67
|
+
// Native image styles will be applied via Image component
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
}));
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { getWebProps } from 'react-native-unistyles/web';
|
|
3
|
+
import { SVGImageProps } from './types';
|
|
4
|
+
import { svgImageStyles } from './SVGImage.styles';
|
|
5
|
+
|
|
6
|
+
const SVGImage: React.FC<SVGImageProps> = ({
|
|
7
|
+
source,
|
|
8
|
+
width,
|
|
9
|
+
height,
|
|
10
|
+
size,
|
|
11
|
+
color,
|
|
12
|
+
intent,
|
|
13
|
+
resizeMode = 'contain',
|
|
14
|
+
style,
|
|
15
|
+
testID,
|
|
16
|
+
...props
|
|
17
|
+
}) => {
|
|
18
|
+
// Apply variants using Unistyles 3.0 pattern
|
|
19
|
+
if (intent) {
|
|
20
|
+
svgImageStyles.useVariants({
|
|
21
|
+
intent: intent as 'primary' | 'success' | 'error' | 'warning' | 'neutral',
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Determine dimensions - size takes precedence over individual width/height
|
|
26
|
+
const finalWidth = size || width;
|
|
27
|
+
const finalHeight = size || height;
|
|
28
|
+
|
|
29
|
+
// Handle React components (imported SVG components)
|
|
30
|
+
if (typeof source === 'function') {
|
|
31
|
+
const SvgComponent = source;
|
|
32
|
+
return (
|
|
33
|
+
<div {...getWebProps([svgImageStyles.container, style])} {...props} data-testid={testID}>
|
|
34
|
+
<SvgComponent
|
|
35
|
+
width={finalWidth || 24}
|
|
36
|
+
height={finalHeight || 24}
|
|
37
|
+
fill={color || 'currentColor'}
|
|
38
|
+
color={color || 'currentColor'}
|
|
39
|
+
/>
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Determine source URL
|
|
45
|
+
const sourceUrl = typeof source === 'string' ? source : source.uri;
|
|
46
|
+
|
|
47
|
+
// Create the style array
|
|
48
|
+
const containerStyleArray = [
|
|
49
|
+
svgImageStyles.container,
|
|
50
|
+
style,
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
const imageStyleArray = [
|
|
54
|
+
svgImageStyles.image,
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
// Use getWebProps to generate className and ref for web
|
|
58
|
+
const containerWebProps = getWebProps(containerStyleArray);
|
|
59
|
+
const imageWebProps = getWebProps(imageStyleArray);
|
|
60
|
+
|
|
61
|
+
// Apply custom color if provided
|
|
62
|
+
// Convert React Native resize modes to CSS object-fit values
|
|
63
|
+
const getObjectFit = (mode: 'contain' | 'cover' | 'stretch'): React.CSSProperties['objectFit'] => {
|
|
64
|
+
switch (mode) {
|
|
65
|
+
case 'contain': return 'contain';
|
|
66
|
+
case 'cover': return 'cover';
|
|
67
|
+
case 'stretch': return 'fill';
|
|
68
|
+
default: return 'contain';
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const imageStyle: React.CSSProperties = {
|
|
73
|
+
width: finalWidth,
|
|
74
|
+
height: finalHeight,
|
|
75
|
+
objectFit: getObjectFit(resizeMode),
|
|
76
|
+
...(color && {
|
|
77
|
+
filter: `brightness(0) saturate(100%) ${color}`,
|
|
78
|
+
}),
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<div {...containerWebProps} {...props} data-testid={testID}>
|
|
83
|
+
<img
|
|
84
|
+
{...imageWebProps}
|
|
85
|
+
src={sourceUrl}
|
|
86
|
+
alt="SVG Image"
|
|
87
|
+
style={imageStyle}
|
|
88
|
+
/>
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export default SVGImage;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ViewProps } from 'react-native';
|
|
3
|
+
import { SvgProps } from 'react-native-svg';
|
|
4
|
+
import { IntentNames } from '../theme';
|
|
5
|
+
|
|
6
|
+
export interface SVGImageProps extends Omit<ViewProps, 'children'> {
|
|
7
|
+
source: string | { uri: string } | React.FC<SvgProps>;
|
|
8
|
+
width?: number | string;
|
|
9
|
+
height?: number | string;
|
|
10
|
+
size?: number | string;
|
|
11
|
+
color?: string;
|
|
12
|
+
intent?: IntentNames;
|
|
13
|
+
resizeMode?: 'contain' | 'cover' | 'stretch';
|
|
14
|
+
}
|
|
@@ -11,6 +11,7 @@ import { DividerExamples } from './DividerExamples';
|
|
|
11
11
|
import { BadgeExamples } from './BadgeExamples';
|
|
12
12
|
import { AvatarExamples } from './AvatarExamples';
|
|
13
13
|
import { ScreenExamples } from './ScreenExamples';
|
|
14
|
+
import { SVGImageExamples } from './SVGImageExamples';
|
|
14
15
|
import { DialogExamples } from './DialogExamples';
|
|
15
16
|
import { PopoverExamples } from './PopoverExamples';
|
|
16
17
|
import { ThemeExtensionExamples } from './ThemeExtensionExamples';
|
|
@@ -63,6 +64,9 @@ export const AllExamples = () => {
|
|
|
63
64
|
<ScreenExamples />
|
|
64
65
|
<Divider spacing="medium" />
|
|
65
66
|
|
|
67
|
+
<SVGImageExamples />
|
|
68
|
+
<Divider spacing="medium" />
|
|
69
|
+
|
|
66
70
|
<DialogExamples />
|
|
67
71
|
<Divider spacing="medium" />
|
|
68
72
|
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { Screen, View, SVGImage, Text } from '../index';
|
|
2
|
+
import testLogo from './test-logo.svg';
|
|
3
|
+
|
|
4
|
+
export const SVGImageExamples = () => {
|
|
5
|
+
return (
|
|
6
|
+
<Screen background="primary" padding="lg">
|
|
7
|
+
<View spacing="none">
|
|
8
|
+
<Text size="large" weight="bold" align="center">
|
|
9
|
+
SVG Image Examples
|
|
10
|
+
</Text>
|
|
11
|
+
|
|
12
|
+
{/* Local SVG File Example */}
|
|
13
|
+
<View spacing="md">
|
|
14
|
+
<Text size="medium" weight="semibold">Loading Local SVG File</Text>
|
|
15
|
+
<Text size="small">
|
|
16
|
+
Using the test-logo.svg file - works on web, limited support on React Native
|
|
17
|
+
</Text>
|
|
18
|
+
<View style={{ flexDirection: 'row', gap: 16, flexWrap: 'wrap', alignItems: 'center' }}>
|
|
19
|
+
{/* Original size */}
|
|
20
|
+
<SVGImage
|
|
21
|
+
source={testLogo}
|
|
22
|
+
width={102}
|
|
23
|
+
height={30}
|
|
24
|
+
/>
|
|
25
|
+
|
|
26
|
+
{/* Smaller version */}
|
|
27
|
+
<SVGImage
|
|
28
|
+
source={testLogo}
|
|
29
|
+
width={68}
|
|
30
|
+
height={20}
|
|
31
|
+
/>
|
|
32
|
+
|
|
33
|
+
{/* Using size prop */}
|
|
34
|
+
<SVGImage
|
|
35
|
+
source={testLogo}
|
|
36
|
+
size={40}
|
|
37
|
+
/>
|
|
38
|
+
</View>
|
|
39
|
+
</View>
|
|
40
|
+
|
|
41
|
+
{/* Intent Colors */}
|
|
42
|
+
<View spacing="md">
|
|
43
|
+
<Text size="medium" weight="semibold">Intent Colors</Text>
|
|
44
|
+
<Text size="small">
|
|
45
|
+
SVG images with theme-based coloring
|
|
46
|
+
</Text>
|
|
47
|
+
<View style={{ flexDirection: 'row', gap: 16, flexWrap: 'wrap', alignItems: 'center' }}>
|
|
48
|
+
<SVGImage
|
|
49
|
+
source={testLogo}
|
|
50
|
+
width={102}
|
|
51
|
+
height={30}
|
|
52
|
+
intent="primary"
|
|
53
|
+
/>
|
|
54
|
+
<SVGImage
|
|
55
|
+
source={testLogo}
|
|
56
|
+
width={102}
|
|
57
|
+
height={30}
|
|
58
|
+
intent="success"
|
|
59
|
+
/>
|
|
60
|
+
<SVGImage
|
|
61
|
+
source={testLogo}
|
|
62
|
+
width={102}
|
|
63
|
+
height={30}
|
|
64
|
+
intent="error"
|
|
65
|
+
/>
|
|
66
|
+
<SVGImage
|
|
67
|
+
source={testLogo}
|
|
68
|
+
width={102}
|
|
69
|
+
height={30}
|
|
70
|
+
intent="warning"
|
|
71
|
+
/>
|
|
72
|
+
</View>
|
|
73
|
+
</View>
|
|
74
|
+
|
|
75
|
+
{/* Custom Colors */}
|
|
76
|
+
<View spacing="md">
|
|
77
|
+
<Text size="medium" weight="semibold">Custom Colors</Text>
|
|
78
|
+
<Text size="small">
|
|
79
|
+
Direct color specification
|
|
80
|
+
</Text>
|
|
81
|
+
<View style={{ flexDirection: 'row', gap: 16, flexWrap: 'wrap', alignItems: 'center' }}>
|
|
82
|
+
<SVGImage
|
|
83
|
+
source={testLogo}
|
|
84
|
+
width={102}
|
|
85
|
+
height={30}
|
|
86
|
+
color="#ff6b6b"
|
|
87
|
+
/>
|
|
88
|
+
<SVGImage
|
|
89
|
+
source={testLogo}
|
|
90
|
+
width={102}
|
|
91
|
+
height={30}
|
|
92
|
+
color="#4ecdc4"
|
|
93
|
+
/>
|
|
94
|
+
<SVGImage
|
|
95
|
+
source={testLogo}
|
|
96
|
+
width={102}
|
|
97
|
+
height={30}
|
|
98
|
+
color="#45b7d1"
|
|
99
|
+
/>
|
|
100
|
+
</View>
|
|
101
|
+
</View>
|
|
102
|
+
|
|
103
|
+
{/* Remote URL Example */}
|
|
104
|
+
<View spacing="md">
|
|
105
|
+
<Text size="medium" weight="semibold">Loading from URL</Text>
|
|
106
|
+
<Text size="small">
|
|
107
|
+
SVG images loaded from remote URLs (web only for security)
|
|
108
|
+
</Text>
|
|
109
|
+
<View style={{ flexDirection: 'row', gap: 16, flexWrap: 'wrap', alignItems: 'center' }}>
|
|
110
|
+
<SVGImage
|
|
111
|
+
source={{ uri: "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/react.svg" }}
|
|
112
|
+
width={60}
|
|
113
|
+
height={60}
|
|
114
|
+
/>
|
|
115
|
+
<SVGImage
|
|
116
|
+
source={{ uri: "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/javascript.svg" }}
|
|
117
|
+
width={60}
|
|
118
|
+
height={60}
|
|
119
|
+
intent="primary"
|
|
120
|
+
/>
|
|
121
|
+
<SVGImage
|
|
122
|
+
source={{ uri: "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/typescript.svg" }}
|
|
123
|
+
width={60}
|
|
124
|
+
height={60}
|
|
125
|
+
intent="success"
|
|
126
|
+
/>
|
|
127
|
+
</View>
|
|
128
|
+
</View>
|
|
129
|
+
|
|
130
|
+
{/* Resize Modes */}
|
|
131
|
+
<View spacing="md">
|
|
132
|
+
<Text size="medium" weight="semibold">Resize Modes</Text>
|
|
133
|
+
<Text size="small">
|
|
134
|
+
Different ways to fit SVG images in containers
|
|
135
|
+
</Text>
|
|
136
|
+
<View style={{ flexDirection: 'row', gap: 16, flexWrap: 'wrap', alignItems: 'center' }}>
|
|
137
|
+
<View style={{ width: 80, height: 40, backgroundColor: 'rgba(0,0,0,0.1)' }}>
|
|
138
|
+
<SVGImage
|
|
139
|
+
source={testLogo}
|
|
140
|
+
width="100%"
|
|
141
|
+
height="100%"
|
|
142
|
+
resizeMode="contain"
|
|
143
|
+
/>
|
|
144
|
+
</View>
|
|
145
|
+
<View style={{ width: 80, height: 40, backgroundColor: 'rgba(0,0,0,0.1)' }}>
|
|
146
|
+
<SVGImage
|
|
147
|
+
source={testLogo}
|
|
148
|
+
width="100%"
|
|
149
|
+
height="100%"
|
|
150
|
+
resizeMode="cover"
|
|
151
|
+
/>
|
|
152
|
+
</View>
|
|
153
|
+
<View style={{ width: 80, height: 40, backgroundColor: 'rgba(0,0,0,0.1)' }}>
|
|
154
|
+
<SVGImage
|
|
155
|
+
source={testLogo}
|
|
156
|
+
width="100%"
|
|
157
|
+
height="100%"
|
|
158
|
+
resizeMode="stretch"
|
|
159
|
+
/>
|
|
160
|
+
</View>
|
|
161
|
+
</View>
|
|
162
|
+
</View>
|
|
163
|
+
|
|
164
|
+
{/* Usage Tips */}
|
|
165
|
+
<View spacing="md">
|
|
166
|
+
<Text size="medium" weight="semibold">Usage Tips</Text>
|
|
167
|
+
<View spacing="sm">
|
|
168
|
+
<Text size="small">
|
|
169
|
+
• <Text weight="semibold">Local files:</Text> Use relative paths for bundled SVG files
|
|
170
|
+
</Text>
|
|
171
|
+
<Text size="small">
|
|
172
|
+
• <Text weight="semibold">Remote URLs:</Text> Use {`{ uri: "https://..." }`} format
|
|
173
|
+
</Text>
|
|
174
|
+
<Text size="small">
|
|
175
|
+
• <Text weight="semibold">React Native:</Text> Local SVGs have limited support - use remote URLs or convert to PNG
|
|
176
|
+
</Text>
|
|
177
|
+
<Text size="small">
|
|
178
|
+
• <Text weight="semibold">Coloring:</Text> Works best with single-color SVG icons
|
|
179
|
+
</Text>
|
|
180
|
+
<Text size="small">
|
|
181
|
+
• <Text weight="semibold">Performance:</Text> Cache remote SVGs for better performance
|
|
182
|
+
</Text>
|
|
183
|
+
</View>
|
|
184
|
+
</View>
|
|
185
|
+
</View>
|
|
186
|
+
</Screen>
|
|
187
|
+
);
|
|
188
|
+
};
|
package/src/examples/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ export { DividerExamples } from './DividerExamples';
|
|
|
9
9
|
export { BadgeExamples } from './BadgeExamples';
|
|
10
10
|
export { AvatarExamples } from './AvatarExamples';
|
|
11
11
|
export { ScreenExamples } from './ScreenExamples';
|
|
12
|
+
export { SVGImageExamples } from './SVGImageExamples';
|
|
12
13
|
export { DialogExamples } from './DialogExamples';
|
|
13
14
|
export { PopoverExamples } from './PopoverExamples';
|
|
14
15
|
export { ThemeExtensionExamples } from './ThemeExtensionExamples';
|