@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 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';