@idealyst/components 1.0.52 → 1.0.54

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 CHANGED
@@ -5,7 +5,7 @@ This file provides comprehensive component documentation for LLMs working with t
5
5
  ## Library Overview
6
6
 
7
7
  @idealyst/components is a cross-platform React/React Native component library with:
8
- - 13 core components organized into 6 categories
8
+ - 14 core components organized into 7 categories
9
9
  - Theme-based styling with Unistyles
10
10
  - Intent-based color system (primary, neutral, success, error, warning)
11
11
  - Cross-platform compatibility (React & React Native)
@@ -33,6 +33,7 @@ This file provides comprehensive component documentation for LLMs working with t
33
33
 
34
34
  ### Utility Components
35
35
  - **Icon**: Icon display (`name`, `size`, `color`, `intent`)
36
+ - **SVGImage**: SVG rendering (`source`, `width`, `height`, `size`, `color`, `intent`)
36
37
 
37
38
  ### Overlay Components
38
39
  - **Dialog**: Modal dialog (`open`, `onOpenChange`, `title`, `size="small|medium|large"`, `variant="default"`, `showCloseButton`, `closeOnBackdropClick`, `closeOnEscapeKey`)
@@ -67,6 +68,14 @@ All components use a consistent intent-based color system:
67
68
  </View>
68
69
  ```
69
70
 
71
+ ### SVG Usage
72
+ ```tsx
73
+ import MyIcon from './assets/icon.svg';
74
+
75
+ <SVGImage source={MyIcon} size={24} intent="primary" />
76
+ <SVGImage source={{ uri: "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/react.svg" }} size={32} color="#61dafb" />
77
+ ```
78
+
70
79
  ### Card with Content
71
80
  ```tsx
72
81
  <Card variant="outlined" clickable onPress={handlePress}>
package/README.md CHANGED
@@ -65,7 +65,7 @@ export default function App() {
65
65
 
66
66
  ## Available Components
67
67
 
68
- The library includes 10 core components organized by category. Each component has detailed documentation in its respective folder.
68
+ The library includes 14 core components organized by category. Each component has detailed documentation in its respective folder.
69
69
 
70
70
  ### Layout Components
71
71
 
@@ -102,6 +102,14 @@ The library includes 10 core components organized by category. Each component ha
102
102
  | Component | Description | Documentation |
103
103
  |-----------|-------------|---------------|
104
104
  | **[Icon](src/Icon/README.md)** | Icon library with extensive options | [Icon Docs](src/Icon/README.md) |
105
+ | **[SVGImage](src/SVGImage/README.md)** | SVG rendering with cross-platform support | [SVGImage Docs](src/SVGImage/README.md) |
106
+
107
+ ### Overlay Components
108
+
109
+ | Component | Description | Documentation |
110
+ |-----------|-------------|--------------|
111
+ | **[Dialog](src/Dialog/README.md)** | Modal dialogs with customizable content | [Dialog Docs](src/Dialog/README.md) |
112
+ | **[Popover](src/Popover/README.md)** | Contextual overlays and tooltips | [Popover Docs](src/Popover/README.md) |
105
113
 
106
114
  ## Quick Usage Examples
107
115
 
@@ -155,6 +163,26 @@ import { View, Card, Text, Avatar, Badge } from '@idealyst/components';
155
163
  </View>
156
164
  ```
157
165
 
166
+ ### SVG Icons
167
+ ```tsx
168
+ import { SVGImage, View, Text } from '@idealyst/components';
169
+ import LogoIcon from './assets/logo.svg';
170
+
171
+ <View spacing="md">
172
+ <Text size="large" weight="bold">My App</Text>
173
+
174
+ {/* Imported SVG */}
175
+ <SVGImage source={LogoIcon} size={40} intent="primary" />
176
+
177
+ {/* Remote SVG */}
178
+ <SVGImage
179
+ source={{ uri: "https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/react.svg" }}
180
+ size={24}
181
+ color="#61dafb"
182
+ />
183
+ </View>
184
+ ```
185
+
158
186
  ## Theme System
159
187
 
160
188
  The library includes a comprehensive theme system with light and dark mode support.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idealyst/components",
3
- "version": "1.0.52",
3
+ "version": "1.0.54",
4
4
  "description": "Shared component library for React and React Native",
5
5
  "documentation": "https://github.com/your-username/idealyst-framework/tree/main/packages/components#readme",
6
6
  "main": "src/index.ts",
@@ -40,7 +40,7 @@
40
40
  "publish:npm": "npm publish"
41
41
  },
42
42
  "peerDependencies": {
43
- "@idealyst/theme": "^1.0.52",
43
+ "@idealyst/theme": "^1.0.54",
44
44
  "@mdi/js": "^7.4.47",
45
45
  "@mdi/react": "^1.6.1",
46
46
  "@react-native-vector-icons/common": "^12.0.1",
@@ -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,2 @@
1
+ export { default } from './SVGImage.native';
2
+ export * from './types';
@@ -0,0 +1,5 @@
1
+ // Platform-agnostic SVGImage export
2
+ // Metro will resolve to index.native.ts for React Native
3
+ // This file serves as fallback for web environments
4
+ export { default } from './SVGImage.web';
5
+ export * from './types';
@@ -0,0 +1,2 @@
1
+ export { default } from './SVGImage.web';
2
+ export * from './types';
@@ -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
+ };
@@ -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';
@@ -0,0 +1,8 @@
1
+ <svg width="102" height="30" viewBox="0 0 102 30" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M3.01539 11.8959H2.82339C1.45806 11.8959 0.775391 11.2026 0.775391 9.81594V8.82394C0.775391 7.43728 1.45806 6.74394 2.82339 6.74394H3.23939V4.02394C3.23939 2.63728 3.93272 1.94394 5.31939 1.94394H7.59139C8.99939 1.94394 9.70339 2.63728 9.70339 4.02394V6.74394H10.8554C12.2634 6.74394 12.9674 7.43728 12.9674 8.82394V9.81594C12.9674 11.2026 12.2847 11.8959 10.9194 11.8959H9.70339V15.8639C9.70339 16.7386 10.1621 17.2399 11.0794 17.3679C11.4634 17.4319 11.7834 17.4959 12.0394 17.5599C12.2954 17.6239 12.4981 17.7306 12.6474 17.8799C12.8181 18.0079 12.9354 18.1893 12.9994 18.4239C13.0847 18.6373 13.1274 18.9253 13.1274 19.2879V21.0799C13.1274 21.8693 12.8927 22.4133 12.4234 22.7119C11.9754 23.0106 11.3034 23.1599 10.4074 23.1599C9.89539 23.1599 9.21272 23.0959 8.35939 22.9679C7.52739 22.8186 6.71672 22.5306 5.92739 22.1039C5.13806 21.6773 4.45539 21.0693 3.87939 20.2799C3.30339 19.4906 3.01539 18.4346 3.01539 17.1119V11.8959Z" fill="#0F77EE"/>
3
+ <path d="M14.9504 8.47194C14.9504 7.08528 15.6437 6.39194 17.0304 6.39194H19.2384C20.6464 6.39194 21.3504 7.08528 21.3504 8.47194V9.11194C21.3504 9.23994 21.3397 9.35728 21.3184 9.46394C21.3184 9.57061 21.3184 9.66661 21.3184 9.75194C21.2971 9.83728 21.2864 9.93328 21.2864 10.0399H21.3504C21.4784 9.67728 21.6704 9.27194 21.9264 8.82394C22.1824 8.37594 22.4917 7.95994 22.8544 7.57594C23.2384 7.19194 23.6437 6.87194 24.0704 6.61594C24.5184 6.33861 24.9877 6.19994 25.4784 6.19994C26.1397 6.19994 26.5877 6.38128 26.8224 6.74394C27.0784 7.10661 27.2064 7.62928 27.2064 8.31194V10.4879C27.2064 11.8959 26.5237 12.5999 25.1584 12.5999C23.9637 12.5999 23.0784 12.9839 22.5024 13.7519C21.9264 14.5199 21.6384 15.5119 21.6384 16.7279V20.9199C21.6384 22.3066 20.9344 22.9999 19.5264 22.9999H17.0304C15.6437 22.9999 14.9504 22.3066 14.9504 20.9199V8.47194Z" fill="#0F77EE"/>
4
+ <path d="M35.0096 15.7679C35.0096 16.3653 35.1376 16.7813 35.3936 17.0159C35.6496 17.2293 36.0123 17.3359 36.4816 17.3359C36.9723 17.3359 37.367 17.2293 37.6656 17.0159C37.9643 16.8026 38.199 16.5253 38.3696 16.1839C38.5403 15.8213 38.6576 15.4266 38.7216 14.9999C38.7856 14.5519 38.8176 14.1146 38.8176 13.6879V8.47194C38.8176 7.08528 39.5216 6.39194 40.9296 6.39194H43.4256C44.8123 6.39194 45.5056 7.08528 45.5056 8.47194V20.9199C45.5056 22.3066 44.8123 22.9999 43.4256 22.9999H41.2176C40.535 22.9999 40.023 22.8399 39.6816 22.5199C39.3403 22.1786 39.1696 21.7306 39.1696 21.1759V20.6639H39.1056C38.871 21.1973 38.583 21.6453 38.2416 22.0079C37.9003 22.3493 37.5163 22.6266 37.0896 22.8399C36.6843 23.0319 36.2363 23.1706 35.7456 23.2559C35.2763 23.3413 34.7963 23.3839 34.3056 23.3839C33.559 23.3839 32.823 23.2879 32.0976 23.0959C31.3723 22.9039 30.7323 22.5733 30.1776 22.1039C29.623 21.6346 29.175 21.0053 28.8336 20.2159C28.4923 19.4266 28.3216 18.4346 28.3216 17.2399V8.47194C28.3216 7.08528 29.0256 6.39194 30.4336 6.39194H32.9296C34.3163 6.39194 35.0096 7.08528 35.0096 8.47194V15.7679Z" fill="#0F77EE"/>
5
+ <path d="M47.2784 14.6479C47.2784 13.3893 47.4491 12.2373 47.7904 11.1919C48.1531 10.1253 48.6651 9.20794 49.3264 8.43994C50.0091 7.67194 50.8304 7.07461 51.7904 6.64794C52.7717 6.22128 53.8704 6.00794 55.0864 6.00794C55.8544 6.00794 56.4731 6.08261 56.9424 6.23194C57.4331 6.38128 57.8277 6.54128 58.1264 6.71194C58.4677 6.92528 58.7237 7.15994 58.8944 7.41594H58.9584C58.9371 7.33061 58.9264 7.24528 58.9264 7.15994V2.07194C58.9264 0.685277 59.6304 -0.00805664 61.0384 -0.00805664H63.5344C64.9211 -0.00805664 65.6144 0.685277 65.6144 2.07194V20.9199C65.6144 22.3066 64.9211 22.9999 63.5344 22.9999H61.4864C60.1851 22.9999 59.4811 22.3279 59.3744 20.9839H59.3424C58.8944 21.8373 58.2544 22.4559 57.4224 22.8399C56.5904 23.2026 55.6837 23.3839 54.7024 23.3839C53.6144 23.3839 52.6117 23.1706 51.6944 22.7439C50.7984 22.3173 50.0197 21.7199 49.3584 20.9519C48.6971 20.1839 48.1851 19.2666 47.8224 18.1999C47.4597 17.1333 47.2784 15.9493 47.2784 14.6479ZM53.9664 14.7119C53.9664 15.6719 54.2011 16.4506 54.6704 17.0479C55.1611 17.6239 55.7904 17.9119 56.5584 17.9119C57.2411 17.9119 57.8384 17.6559 58.3504 17.1439C58.8624 16.6319 59.1184 15.8426 59.1184 14.7759C59.1184 13.8586 58.8944 13.1013 58.4464 12.5039C58.0197 11.8853 57.4011 11.5759 56.5904 11.5759C55.8651 11.5759 55.2464 11.8426 54.7344 12.3759C54.2224 12.9093 53.9664 13.6879 53.9664 14.7119Z" fill="#0F77EE"/>
6
+ <path d="M67.2426 18.2639C67.2426 17.2826 67.5093 16.4613 68.0426 15.7999C68.5973 15.1173 69.3013 14.5626 70.1546 14.1359C71.0293 13.7093 72.0106 13.3999 73.0986 13.2079C74.1866 13.0159 75.2853 12.9199 76.3946 12.9199H76.7146V12.3759C76.7146 11.9706 76.5226 11.7039 76.1386 11.5759C75.7546 11.4266 75.3493 11.3519 74.9226 11.3519C74.5173 11.3519 74.08 11.4159 73.6106 11.5439C73.1413 11.6506 72.6933 11.7893 72.2666 11.9599C71.6266 12.2373 71.072 12.3013 70.6026 12.1519C70.1333 12.0026 69.7493 11.6186 69.4506 10.9999L69.0026 10.0399C68.7253 9.44261 68.6506 8.89861 68.7786 8.40794C68.9066 7.91728 69.2693 7.53328 69.8666 7.25594C70.5706 6.93594 71.4026 6.64794 72.3626 6.39194C73.3226 6.13594 74.3893 6.00794 75.5626 6.00794C76.7573 6.00794 77.8346 6.16794 78.7946 6.48794C79.7546 6.80794 80.576 7.26661 81.2586 7.86394C81.9413 8.46128 82.464 9.18661 82.8266 10.0399C83.1893 10.8933 83.3706 11.8533 83.3706 12.9199V20.9199C83.3706 22.3066 82.6773 22.9999 81.2906 22.9999H79.4026C78.1226 22.9999 77.4293 22.2639 77.3226 20.7919H77.2586C76.8106 21.4746 76.224 22.0826 75.4986 22.6159C74.7946 23.1279 73.824 23.3839 72.5866 23.3839C71.7546 23.3839 71.008 23.2453 70.3466 22.9679C69.6853 22.6906 69.12 22.3173 68.6506 21.8479C68.2026 21.3786 67.8506 20.8346 67.5946 20.2159C67.36 19.5973 67.2426 18.9466 67.2426 18.2639ZM73.2906 17.6879C73.2906 17.9226 73.3866 18.1679 73.5786 18.4239C73.7706 18.6586 74.112 18.7759 74.6026 18.7759C75.2213 18.7759 75.7333 18.5733 76.1386 18.1679C76.5653 17.7413 76.7786 17.2186 76.7786 16.5999V16.2799H76.4266C75.5093 16.2799 74.752 16.4079 74.1546 16.6639C73.5786 16.8986 73.2906 17.2399 73.2906 17.6879Z" fill="#0F77EE"/>
7
+ <path d="M85.2286 25.4959C85.506 24.8986 85.826 24.5253 86.1886 24.3759C86.5513 24.2266 86.9246 24.1839 87.3086 24.2479C87.4153 24.2693 87.5326 24.2906 87.6606 24.3119C87.81 24.3333 87.9806 24.3439 88.1726 24.3439C88.5993 24.3439 88.994 24.1946 89.3566 23.8959C89.7406 23.6186 90.0073 23.2773 90.1566 22.8719L90.2526 22.6159L84.2046 8.82394C83.8846 8.09861 83.8633 7.51194 84.1406 7.06394C84.4393 6.61594 84.994 6.39194 85.8046 6.39194H88.9086C89.5273 6.39194 90.0393 6.53061 90.4446 6.80794C90.8713 7.08528 91.1593 7.52261 91.3086 8.11994L92.4606 12.6959C92.5246 12.9306 92.5886 13.2293 92.6526 13.5919C92.7166 13.9333 92.77 14.2746 92.8126 14.6159C92.8766 14.9999 92.93 15.4159 92.9726 15.8639H93.0366C93.1006 15.4159 93.1646 14.9999 93.2286 14.6159C93.2713 14.2746 93.3246 13.9226 93.3886 13.5599C93.4526 13.1973 93.506 12.8986 93.5486 12.6639L94.3486 8.18394C94.4553 7.56528 94.7113 7.11728 95.1166 6.83994C95.5433 6.54128 96.066 6.39194 96.6846 6.39194H99.5646C100.333 6.39194 100.866 6.61594 101.165 7.06394C101.485 7.49061 101.517 8.06661 101.261 8.79194L95.7566 24.2479C95.3726 25.3146 94.8926 26.1999 94.3166 26.9039C93.7406 27.6079 93.1113 28.1626 92.4286 28.5679C91.746 28.9946 91.0313 29.2933 90.2846 29.4639C89.538 29.6346 88.8126 29.7199 88.1086 29.7199C87.682 29.7199 87.2766 29.6879 86.8926 29.6239C86.5086 29.5599 86.1353 29.4746 85.7726 29.3679C85.154 29.1546 84.7593 28.7919 84.5886 28.2799C84.418 27.7893 84.4713 27.2346 84.7486 26.6159L85.2286 25.4959Z" fill="#0F77EE"/>
8
+ </svg>
@@ -31,6 +31,9 @@ export * from './Screen/types';
31
31
  export { default as Icon } from './Icon';
32
32
  export * from './Icon/types';
33
33
 
34
+ export { default as SVGImage } from './SVGImage';
35
+ export * from './SVGImage/types';
36
+
34
37
  export { default as Dialog } from './Dialog';
35
38
  export * from './Dialog/types';
36
39
 
@@ -48,6 +51,7 @@ export type { BadgeProps } from './Badge/types';
48
51
  export type { AvatarProps } from './Avatar/types';
49
52
  export type { ScreenProps } from './Screen/types';
50
53
  export type { IconProps } from './Icon/types';
54
+ export type { SVGImageProps } from './SVGImage/types';
51
55
  export type { DialogProps } from './Dialog/types';
52
56
  export type { PopoverProps } from './Popover/types';
53
57
 
package/src/index.ts CHANGED
@@ -35,6 +35,9 @@ export * from './Screen/types';
35
35
  export { default as Icon } from './Icon';
36
36
  export * from './Icon/types';
37
37
 
38
+ export { default as SVGImage } from './SVGImage';
39
+ export * from './SVGImage/types';
40
+
38
41
  export { default as Dialog } from './Dialog';
39
42
  export * from './Dialog/types';
40
43
 
@@ -52,6 +55,7 @@ export type { BadgeProps } from './Badge/types';
52
55
  export type { AvatarProps } from './Avatar/types';
53
56
  export type { ScreenProps } from './Screen/types';
54
57
  export type { IconProps } from './Icon/types';
58
+ export type { SVGImageProps } from './SVGImage/types';
55
59
  export type { DialogProps } from './Dialog/types';
56
60
  export type { PopoverProps } from './Popover/types';
57
61