@idealyst/svg 1.2.63
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 +178 -0
- package/package.json +69 -0
- package/src/examples/SvgExamples.tsx +363 -0
- package/src/examples/index.ts +14 -0
- package/src/index.native.ts +64 -0
- package/src/index.ts +64 -0
- package/src/primitives.native.tsx +496 -0
- package/src/primitives.web.tsx +537 -0
- package/src/types.ts +446 -0
package/README.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# @idealyst/svg
|
|
2
|
+
|
|
3
|
+
Cross-platform SVG primitives for React and React Native with identical behavior.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @idealyst/svg
|
|
9
|
+
# or
|
|
10
|
+
yarn add @idealyst/svg
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### React Native
|
|
14
|
+
|
|
15
|
+
For React Native, you also need to install `react-native-svg`:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install react-native-svg
|
|
19
|
+
# or
|
|
20
|
+
yarn add react-native-svg
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Then run pod install for iOS:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
cd ios && pod install
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
import { Svg, Circle, Rect, Path, G, LinearGradient, Stop, Defs } from '@idealyst/svg';
|
|
33
|
+
|
|
34
|
+
function MyIcon() {
|
|
35
|
+
return (
|
|
36
|
+
<Svg width={100} height={100} viewBox="0 0 100 100">
|
|
37
|
+
<Defs>
|
|
38
|
+
<LinearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
39
|
+
<Stop offset="0%" stopColor="#667eea" />
|
|
40
|
+
<Stop offset="100%" stopColor="#764ba2" />
|
|
41
|
+
</LinearGradient>
|
|
42
|
+
</Defs>
|
|
43
|
+
|
|
44
|
+
<Circle
|
|
45
|
+
cx={50}
|
|
46
|
+
cy={50}
|
|
47
|
+
r={40}
|
|
48
|
+
fill="url(#grad1)"
|
|
49
|
+
stroke="#333"
|
|
50
|
+
strokeWidth={2}
|
|
51
|
+
/>
|
|
52
|
+
|
|
53
|
+
<Rect
|
|
54
|
+
x={30}
|
|
55
|
+
y={30}
|
|
56
|
+
width={40}
|
|
57
|
+
height={40}
|
|
58
|
+
rx={5}
|
|
59
|
+
fill="white"
|
|
60
|
+
opacity={0.8}
|
|
61
|
+
/>
|
|
62
|
+
</Svg>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Available Components
|
|
68
|
+
|
|
69
|
+
### Basic Shapes
|
|
70
|
+
- `Svg` - Root SVG element
|
|
71
|
+
- `Rect` - Rectangle
|
|
72
|
+
- `Circle` - Circle
|
|
73
|
+
- `Ellipse` - Ellipse
|
|
74
|
+
- `Line` - Line
|
|
75
|
+
- `Polyline` - Open polygon (connected line segments)
|
|
76
|
+
- `Polygon` - Closed polygon
|
|
77
|
+
- `Path` - Complex paths using SVG path commands
|
|
78
|
+
|
|
79
|
+
### Text
|
|
80
|
+
- `Text` - Text element
|
|
81
|
+
- `TSpan` - Text span for inline formatting
|
|
82
|
+
- `TextPath` - Text along a path
|
|
83
|
+
|
|
84
|
+
### Groups & Transforms
|
|
85
|
+
- `G` - Group element with transform support
|
|
86
|
+
- `Use` - Reference and reuse elements
|
|
87
|
+
- `Symbol` - Define reusable graphics
|
|
88
|
+
- `Defs` - Definitions container
|
|
89
|
+
|
|
90
|
+
### Gradients & Patterns
|
|
91
|
+
- `LinearGradient` - Linear gradient
|
|
92
|
+
- `RadialGradient` - Radial gradient
|
|
93
|
+
- `Stop` - Gradient stop
|
|
94
|
+
- `Pattern` - Pattern fill
|
|
95
|
+
|
|
96
|
+
### Clipping & Masking
|
|
97
|
+
- `ClipPath` - Clipping path
|
|
98
|
+
- `Mask` - Mask element
|
|
99
|
+
|
|
100
|
+
### Other
|
|
101
|
+
- `Image` - Embedded image
|
|
102
|
+
- `Marker` - Line markers
|
|
103
|
+
- `ForeignObject` - Embed HTML (web) or native views (RN)
|
|
104
|
+
|
|
105
|
+
## Props
|
|
106
|
+
|
|
107
|
+
All components support common SVG presentation attributes:
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
interface SvgPresentationProps {
|
|
111
|
+
fill?: string;
|
|
112
|
+
fillOpacity?: number;
|
|
113
|
+
stroke?: string;
|
|
114
|
+
strokeWidth?: number | string;
|
|
115
|
+
strokeOpacity?: number;
|
|
116
|
+
strokeLinecap?: 'butt' | 'round' | 'square';
|
|
117
|
+
strokeLinejoin?: 'miter' | 'round' | 'bevel';
|
|
118
|
+
strokeDasharray?: string | number[];
|
|
119
|
+
strokeDashoffset?: number | string;
|
|
120
|
+
opacity?: number;
|
|
121
|
+
transform?: string;
|
|
122
|
+
// ... and more
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Event Handlers
|
|
127
|
+
|
|
128
|
+
Components support touch/click handlers:
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
<Circle
|
|
132
|
+
cx={50}
|
|
133
|
+
cy={50}
|
|
134
|
+
r={40}
|
|
135
|
+
fill="blue"
|
|
136
|
+
onPress={() => console.log('Pressed!')}
|
|
137
|
+
onLongPress={() => console.log('Long pressed!')}
|
|
138
|
+
/>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Group Transforms
|
|
142
|
+
|
|
143
|
+
The `G` component supports convenience transform props:
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
<G x={100} y={50} rotation={45} scale={1.5} originX={0} originY={0}>
|
|
147
|
+
<Rect x={-25} y={-25} width={50} height={50} fill="red" />
|
|
148
|
+
</G>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Cross-Platform Behavior
|
|
152
|
+
|
|
153
|
+
This library ensures identical rendering on web and React Native:
|
|
154
|
+
|
|
155
|
+
- **Web**: Uses native SVG elements
|
|
156
|
+
- **React Native**: Wraps `react-native-svg` components
|
|
157
|
+
|
|
158
|
+
The same code works on both platforms:
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
// Works identically on web and React Native
|
|
162
|
+
<Svg width={200} height={200} viewBox="0 0 200 200">
|
|
163
|
+
<Path
|
|
164
|
+
d="M10,80 Q95,10 180,80"
|
|
165
|
+
fill="none"
|
|
166
|
+
stroke="#3498db"
|
|
167
|
+
strokeWidth={4}
|
|
168
|
+
/>
|
|
169
|
+
</Svg>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Examples
|
|
173
|
+
|
|
174
|
+
See the [examples](./src/examples) directory for more usage patterns.
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@idealyst/svg",
|
|
3
|
+
"version": "1.2.63",
|
|
4
|
+
"description": "Cross-platform SVG primitives for React and React Native with identical behavior",
|
|
5
|
+
"readme": "README.md",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"module": "src/index.ts",
|
|
8
|
+
"types": "src/index.ts",
|
|
9
|
+
"react-native": "src/index.native.ts",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/IdealystIO/idealyst-framework.git",
|
|
13
|
+
"directory": "packages/svg"
|
|
14
|
+
},
|
|
15
|
+
"author": "Idealyst <contact@idealyst.io>",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"react-native": "./src/index.native.ts",
|
|
23
|
+
"import": "./src/index.ts",
|
|
24
|
+
"require": "./src/index.ts",
|
|
25
|
+
"types": "./src/index.ts"
|
|
26
|
+
},
|
|
27
|
+
"./examples": {
|
|
28
|
+
"import": "./src/examples/index.ts",
|
|
29
|
+
"require": "./src/examples/index.ts",
|
|
30
|
+
"types": "./src/examples/index.ts"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"prepublishOnly": "echo 'Publishing TypeScript source directly'",
|
|
35
|
+
"publish:npm": "npm publish"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"react": ">=16.8.0",
|
|
39
|
+
"react-native": ">=0.60.0",
|
|
40
|
+
"react-native-svg": ">=13.0.0"
|
|
41
|
+
},
|
|
42
|
+
"peerDependenciesMeta": {
|
|
43
|
+
"react-native": {
|
|
44
|
+
"optional": true
|
|
45
|
+
},
|
|
46
|
+
"react-native-svg": {
|
|
47
|
+
"optional": true
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/react": "^19.1.0",
|
|
52
|
+
"react": "^19.1.0",
|
|
53
|
+
"react-native": "^0.80.1",
|
|
54
|
+
"react-native-svg": "^15.14.0",
|
|
55
|
+
"typescript": "^5.0.0"
|
|
56
|
+
},
|
|
57
|
+
"files": [
|
|
58
|
+
"src",
|
|
59
|
+
"README.md"
|
|
60
|
+
],
|
|
61
|
+
"keywords": [
|
|
62
|
+
"react",
|
|
63
|
+
"react-native",
|
|
64
|
+
"svg",
|
|
65
|
+
"cross-platform",
|
|
66
|
+
"vector-graphics",
|
|
67
|
+
"idealyst"
|
|
68
|
+
]
|
|
69
|
+
}
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Svg,
|
|
4
|
+
G,
|
|
5
|
+
Path,
|
|
6
|
+
Rect,
|
|
7
|
+
Circle,
|
|
8
|
+
Ellipse,
|
|
9
|
+
Line,
|
|
10
|
+
Polyline,
|
|
11
|
+
Polygon,
|
|
12
|
+
Text,
|
|
13
|
+
TSpan,
|
|
14
|
+
Defs,
|
|
15
|
+
LinearGradient,
|
|
16
|
+
RadialGradient,
|
|
17
|
+
Stop,
|
|
18
|
+
ClipPath,
|
|
19
|
+
Use,
|
|
20
|
+
Symbol,
|
|
21
|
+
} from '../index';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Basic shapes example
|
|
25
|
+
*/
|
|
26
|
+
export function BasicShapesExample() {
|
|
27
|
+
return (
|
|
28
|
+
<Svg width={200} height={200} viewBox="0 0 200 200">
|
|
29
|
+
{/* Rectangle */}
|
|
30
|
+
<Rect
|
|
31
|
+
x={10}
|
|
32
|
+
y={10}
|
|
33
|
+
width={50}
|
|
34
|
+
height={50}
|
|
35
|
+
fill="#3498db"
|
|
36
|
+
stroke="#2980b9"
|
|
37
|
+
strokeWidth={2}
|
|
38
|
+
rx={5}
|
|
39
|
+
/>
|
|
40
|
+
|
|
41
|
+
{/* Circle */}
|
|
42
|
+
<Circle
|
|
43
|
+
cx={120}
|
|
44
|
+
cy={35}
|
|
45
|
+
r={25}
|
|
46
|
+
fill="#e74c3c"
|
|
47
|
+
stroke="#c0392b"
|
|
48
|
+
strokeWidth={2}
|
|
49
|
+
/>
|
|
50
|
+
|
|
51
|
+
{/* Ellipse */}
|
|
52
|
+
<Ellipse
|
|
53
|
+
cx={50}
|
|
54
|
+
cy={120}
|
|
55
|
+
rx={40}
|
|
56
|
+
ry={20}
|
|
57
|
+
fill="#2ecc71"
|
|
58
|
+
stroke="#27ae60"
|
|
59
|
+
strokeWidth={2}
|
|
60
|
+
/>
|
|
61
|
+
|
|
62
|
+
{/* Line */}
|
|
63
|
+
<Line
|
|
64
|
+
x1={100}
|
|
65
|
+
y1={80}
|
|
66
|
+
x2={180}
|
|
67
|
+
y2={140}
|
|
68
|
+
stroke="#9b59b6"
|
|
69
|
+
strokeWidth={3}
|
|
70
|
+
strokeLinecap="round"
|
|
71
|
+
/>
|
|
72
|
+
</Svg>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Path example - drawing a star
|
|
78
|
+
*/
|
|
79
|
+
export function PathExample() {
|
|
80
|
+
const starPath = 'M50,5 L61,40 L98,40 L68,62 L79,97 L50,75 L21,97 L32,62 L2,40 L39,40 Z';
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<Svg width={100} height={100} viewBox="0 0 100 100">
|
|
84
|
+
<Path
|
|
85
|
+
d={starPath}
|
|
86
|
+
fill="#f1c40f"
|
|
87
|
+
stroke="#f39c12"
|
|
88
|
+
strokeWidth={2}
|
|
89
|
+
/>
|
|
90
|
+
</Svg>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Polygon and Polyline example
|
|
96
|
+
*/
|
|
97
|
+
export function PolygonPolylineExample() {
|
|
98
|
+
return (
|
|
99
|
+
<Svg width={200} height={100} viewBox="0 0 200 100">
|
|
100
|
+
{/* Polygon (closed shape) */}
|
|
101
|
+
<Polygon
|
|
102
|
+
points="25,5 45,45 5,45"
|
|
103
|
+
fill="#1abc9c"
|
|
104
|
+
stroke="#16a085"
|
|
105
|
+
strokeWidth={2}
|
|
106
|
+
/>
|
|
107
|
+
|
|
108
|
+
{/* Polyline (open shape) */}
|
|
109
|
+
<Polyline
|
|
110
|
+
points={[70, 40, 90, 10, 110, 40, 130, 10, 150, 40, 170, 10, 190, 40]}
|
|
111
|
+
fill="none"
|
|
112
|
+
stroke="#e67e22"
|
|
113
|
+
strokeWidth={3}
|
|
114
|
+
strokeLinecap="round"
|
|
115
|
+
strokeLinejoin="round"
|
|
116
|
+
/>
|
|
117
|
+
</Svg>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Text example
|
|
123
|
+
*/
|
|
124
|
+
export function TextExample() {
|
|
125
|
+
return (
|
|
126
|
+
<Svg width={200} height={80} viewBox="0 0 200 80">
|
|
127
|
+
<Text
|
|
128
|
+
x={100}
|
|
129
|
+
y={30}
|
|
130
|
+
textAnchor="middle"
|
|
131
|
+
fontSize={24}
|
|
132
|
+
fontWeight="bold"
|
|
133
|
+
fill="#34495e"
|
|
134
|
+
>
|
|
135
|
+
Hello SVG
|
|
136
|
+
</Text>
|
|
137
|
+
<Text
|
|
138
|
+
x={100}
|
|
139
|
+
y={55}
|
|
140
|
+
textAnchor="middle"
|
|
141
|
+
fontSize={14}
|
|
142
|
+
fill="#7f8c8d"
|
|
143
|
+
>
|
|
144
|
+
<TSpan fill="#e74c3c">Cross</TSpan>
|
|
145
|
+
<TSpan>-platform text</TSpan>
|
|
146
|
+
</Text>
|
|
147
|
+
</Svg>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Linear gradient example
|
|
153
|
+
*/
|
|
154
|
+
export function LinearGradientExample() {
|
|
155
|
+
return (
|
|
156
|
+
<Svg width={150} height={100} viewBox="0 0 150 100">
|
|
157
|
+
<Defs>
|
|
158
|
+
<LinearGradient id="linearGrad1" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
159
|
+
<Stop offset="0%" stopColor="#667eea" />
|
|
160
|
+
<Stop offset="100%" stopColor="#764ba2" />
|
|
161
|
+
</LinearGradient>
|
|
162
|
+
</Defs>
|
|
163
|
+
<Rect
|
|
164
|
+
x={10}
|
|
165
|
+
y={10}
|
|
166
|
+
width={130}
|
|
167
|
+
height={80}
|
|
168
|
+
rx={10}
|
|
169
|
+
fill="url(#linearGrad1)"
|
|
170
|
+
/>
|
|
171
|
+
</Svg>
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Radial gradient example
|
|
177
|
+
*/
|
|
178
|
+
export function RadialGradientExample() {
|
|
179
|
+
return (
|
|
180
|
+
<Svg width={100} height={100} viewBox="0 0 100 100">
|
|
181
|
+
<Defs>
|
|
182
|
+
<RadialGradient id="radialGrad1" cx="50%" cy="50%" r="50%">
|
|
183
|
+
<Stop offset="0%" stopColor="#fff" />
|
|
184
|
+
<Stop offset="100%" stopColor="#3498db" />
|
|
185
|
+
</RadialGradient>
|
|
186
|
+
</Defs>
|
|
187
|
+
<Circle
|
|
188
|
+
cx={50}
|
|
189
|
+
cy={50}
|
|
190
|
+
r={40}
|
|
191
|
+
fill="url(#radialGrad1)"
|
|
192
|
+
/>
|
|
193
|
+
</Svg>
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Group and transform example
|
|
199
|
+
*/
|
|
200
|
+
export function GroupTransformExample() {
|
|
201
|
+
return (
|
|
202
|
+
<Svg width={150} height={150} viewBox="0 0 150 150">
|
|
203
|
+
<G x={75} y={75}>
|
|
204
|
+
{/* Rotate group around center */}
|
|
205
|
+
<G rotation={45} originX={0} originY={0}>
|
|
206
|
+
<Rect
|
|
207
|
+
x={-25}
|
|
208
|
+
y={-25}
|
|
209
|
+
width={50}
|
|
210
|
+
height={50}
|
|
211
|
+
fill="#9b59b6"
|
|
212
|
+
/>
|
|
213
|
+
</G>
|
|
214
|
+
{/* Non-rotated rect for comparison */}
|
|
215
|
+
<Rect
|
|
216
|
+
x={-15}
|
|
217
|
+
y={-15}
|
|
218
|
+
width={30}
|
|
219
|
+
height={30}
|
|
220
|
+
fill="#3498db"
|
|
221
|
+
opacity={0.7}
|
|
222
|
+
/>
|
|
223
|
+
</G>
|
|
224
|
+
</Svg>
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* ClipPath example
|
|
230
|
+
*/
|
|
231
|
+
export function ClipPathExample() {
|
|
232
|
+
return (
|
|
233
|
+
<Svg width={100} height={100} viewBox="0 0 100 100">
|
|
234
|
+
<Defs>
|
|
235
|
+
<ClipPath id="circleClip">
|
|
236
|
+
<Circle cx={50} cy={50} r={40} />
|
|
237
|
+
</ClipPath>
|
|
238
|
+
</Defs>
|
|
239
|
+
<Rect
|
|
240
|
+
x={0}
|
|
241
|
+
y={0}
|
|
242
|
+
width={100}
|
|
243
|
+
height={100}
|
|
244
|
+
fill="#e74c3c"
|
|
245
|
+
clipPath="url(#circleClip)"
|
|
246
|
+
/>
|
|
247
|
+
</Svg>
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Use and Symbol example (reusable graphics)
|
|
253
|
+
*/
|
|
254
|
+
export function UseSymbolExample() {
|
|
255
|
+
return (
|
|
256
|
+
<Svg width={200} height={100} viewBox="0 0 200 100">
|
|
257
|
+
<Defs>
|
|
258
|
+
<Symbol id="heart" viewBox="0 0 32 32">
|
|
259
|
+
<Path
|
|
260
|
+
d="M16,28.3C16,28.3,3,19.5,3,10.5c0-4.8,3.9-8.5,8.5-8.5c2.6,0,4.9,1.1,6.5,2.9c1.6-1.8,3.9-2.9,6.5-2.9
|
|
261
|
+
c4.6,0,8.5,3.7,8.5,8.5C33,19.5,16,28.3,16,28.3z"
|
|
262
|
+
fill="currentColor"
|
|
263
|
+
/>
|
|
264
|
+
</Symbol>
|
|
265
|
+
</Defs>
|
|
266
|
+
|
|
267
|
+
{/* Reuse the heart symbol with different sizes and colors */}
|
|
268
|
+
<Use href="#heart" x={10} y={30} width={30} height={30} fill="#e74c3c" />
|
|
269
|
+
<Use href="#heart" x={60} y={20} width={50} height={50} fill="#e91e63" />
|
|
270
|
+
<Use href="#heart" x={130} y={35} width={25} height={25} fill="#9c27b0" />
|
|
271
|
+
</Svg>
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Dashed stroke example
|
|
277
|
+
*/
|
|
278
|
+
export function DashedStrokeExample() {
|
|
279
|
+
return (
|
|
280
|
+
<Svg width={200} height={80} viewBox="0 0 200 80">
|
|
281
|
+
{/* Solid line */}
|
|
282
|
+
<Line
|
|
283
|
+
x1={10}
|
|
284
|
+
y1={20}
|
|
285
|
+
x2={190}
|
|
286
|
+
y2={20}
|
|
287
|
+
stroke="#34495e"
|
|
288
|
+
strokeWidth={2}
|
|
289
|
+
/>
|
|
290
|
+
|
|
291
|
+
{/* Dashed line (string format) */}
|
|
292
|
+
<Line
|
|
293
|
+
x1={10}
|
|
294
|
+
y1={40}
|
|
295
|
+
x2={190}
|
|
296
|
+
y2={40}
|
|
297
|
+
stroke="#3498db"
|
|
298
|
+
strokeWidth={2}
|
|
299
|
+
strokeDasharray="10,5"
|
|
300
|
+
/>
|
|
301
|
+
|
|
302
|
+
{/* Dotted line (array format) */}
|
|
303
|
+
<Line
|
|
304
|
+
x1={10}
|
|
305
|
+
y1={60}
|
|
306
|
+
x2={190}
|
|
307
|
+
y2={60}
|
|
308
|
+
stroke="#e74c3c"
|
|
309
|
+
strokeWidth={2}
|
|
310
|
+
strokeDasharray={[2, 4]}
|
|
311
|
+
strokeLinecap="round"
|
|
312
|
+
/>
|
|
313
|
+
</Svg>
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Interactive SVG example
|
|
319
|
+
*/
|
|
320
|
+
export function InteractiveSvgExample() {
|
|
321
|
+
const [activeIndex, setActiveIndex] = React.useState<number | null>(null);
|
|
322
|
+
|
|
323
|
+
const colors = ['#e74c3c', '#3498db', '#2ecc71', '#f1c40f'];
|
|
324
|
+
|
|
325
|
+
return (
|
|
326
|
+
<Svg width={200} height={60} viewBox="0 0 200 60">
|
|
327
|
+
{colors.map((color, index) => (
|
|
328
|
+
<Rect
|
|
329
|
+
key={index}
|
|
330
|
+
x={10 + index * 48}
|
|
331
|
+
y={10}
|
|
332
|
+
width={40}
|
|
333
|
+
height={40}
|
|
334
|
+
rx={5}
|
|
335
|
+
fill={color}
|
|
336
|
+
opacity={activeIndex === index ? 1 : 0.6}
|
|
337
|
+
onPress={() => setActiveIndex(index === activeIndex ? null : index)}
|
|
338
|
+
/>
|
|
339
|
+
))}
|
|
340
|
+
</Svg>
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* All examples combined
|
|
346
|
+
*/
|
|
347
|
+
export function AllSvgExamples() {
|
|
348
|
+
return (
|
|
349
|
+
<>
|
|
350
|
+
<BasicShapesExample />
|
|
351
|
+
<PathExample />
|
|
352
|
+
<PolygonPolylineExample />
|
|
353
|
+
<TextExample />
|
|
354
|
+
<LinearGradientExample />
|
|
355
|
+
<RadialGradientExample />
|
|
356
|
+
<GroupTransformExample />
|
|
357
|
+
<ClipPathExample />
|
|
358
|
+
<UseSymbolExample />
|
|
359
|
+
<DashedStrokeExample />
|
|
360
|
+
<InteractiveSvgExample />
|
|
361
|
+
</>
|
|
362
|
+
);
|
|
363
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export {
|
|
2
|
+
BasicShapesExample,
|
|
3
|
+
PathExample,
|
|
4
|
+
PolygonPolylineExample,
|
|
5
|
+
TextExample,
|
|
6
|
+
LinearGradientExample,
|
|
7
|
+
RadialGradientExample,
|
|
8
|
+
GroupTransformExample,
|
|
9
|
+
ClipPathExample,
|
|
10
|
+
UseSymbolExample,
|
|
11
|
+
DashedStrokeExample,
|
|
12
|
+
InteractiveSvgExample,
|
|
13
|
+
AllSvgExamples,
|
|
14
|
+
} from './SvgExamples';
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @idealyst/svg - Cross-platform SVG primitives for React and React Native
|
|
3
|
+
*
|
|
4
|
+
* This package provides identical SVG components that work on both web and React Native.
|
|
5
|
+
* On web, it uses native SVG elements. On React Native, it wraps react-native-svg.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Export all primitives (native implementation)
|
|
9
|
+
export {
|
|
10
|
+
Svg,
|
|
11
|
+
G,
|
|
12
|
+
Path,
|
|
13
|
+
Rect,
|
|
14
|
+
Circle,
|
|
15
|
+
Ellipse,
|
|
16
|
+
Line,
|
|
17
|
+
Polyline,
|
|
18
|
+
Polygon,
|
|
19
|
+
Text,
|
|
20
|
+
TSpan,
|
|
21
|
+
TextPath,
|
|
22
|
+
Use,
|
|
23
|
+
Symbol,
|
|
24
|
+
Defs,
|
|
25
|
+
Image,
|
|
26
|
+
ClipPath,
|
|
27
|
+
Mask,
|
|
28
|
+
LinearGradient,
|
|
29
|
+
RadialGradient,
|
|
30
|
+
Stop,
|
|
31
|
+
Pattern,
|
|
32
|
+
Marker,
|
|
33
|
+
ForeignObject,
|
|
34
|
+
} from './primitives.native';
|
|
35
|
+
|
|
36
|
+
// Export all types
|
|
37
|
+
export type {
|
|
38
|
+
SvgPresentationProps,
|
|
39
|
+
SvgCommonProps,
|
|
40
|
+
SvgProps,
|
|
41
|
+
GProps,
|
|
42
|
+
PathProps,
|
|
43
|
+
RectProps,
|
|
44
|
+
CircleProps,
|
|
45
|
+
EllipseProps,
|
|
46
|
+
LineProps,
|
|
47
|
+
PolylineProps,
|
|
48
|
+
PolygonProps,
|
|
49
|
+
TextProps,
|
|
50
|
+
TSpanProps,
|
|
51
|
+
TextPathProps,
|
|
52
|
+
UseProps,
|
|
53
|
+
SymbolProps,
|
|
54
|
+
DefsProps,
|
|
55
|
+
ImageProps,
|
|
56
|
+
ClipPathProps,
|
|
57
|
+
MaskProps,
|
|
58
|
+
LinearGradientProps,
|
|
59
|
+
RadialGradientProps,
|
|
60
|
+
StopProps,
|
|
61
|
+
PatternProps,
|
|
62
|
+
MarkerProps,
|
|
63
|
+
ForeignObjectProps,
|
|
64
|
+
} from './types';
|