@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/src/index.ts ADDED
@@ -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
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.web';
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';
@@ -0,0 +1,496 @@
1
+ import React, { forwardRef } from 'react';
2
+ import RNSvg, {
3
+ G as RNG,
4
+ Path as RNPath,
5
+ Rect as RNRect,
6
+ Circle as RNCircle,
7
+ Ellipse as RNEllipse,
8
+ Line as RNLine,
9
+ Polyline as RNPolyline,
10
+ Polygon as RNPolygon,
11
+ Text as RNText,
12
+ TSpan as RNTSpan,
13
+ TextPath as RNTextPath,
14
+ Use as RNUse,
15
+ Symbol as RNSymbol,
16
+ Defs as RNDefs,
17
+ Image as RNImage,
18
+ ClipPath as RNClipPath,
19
+ Mask as RNMask,
20
+ LinearGradient as RNLinearGradient,
21
+ RadialGradient as RNRadialGradient,
22
+ Stop as RNStop,
23
+ Pattern as RNPattern,
24
+ Marker as RNMarker,
25
+ ForeignObject as RNForeignObject,
26
+ } from 'react-native-svg';
27
+ import type {
28
+ SvgProps,
29
+ GProps,
30
+ PathProps,
31
+ RectProps,
32
+ CircleProps,
33
+ EllipseProps,
34
+ LineProps,
35
+ PolylineProps,
36
+ PolygonProps,
37
+ TextProps,
38
+ TSpanProps,
39
+ TextPathProps,
40
+ UseProps,
41
+ SymbolProps,
42
+ DefsProps,
43
+ ImageProps,
44
+ ClipPathProps,
45
+ MaskProps,
46
+ LinearGradientProps,
47
+ RadialGradientProps,
48
+ StopProps,
49
+ PatternProps,
50
+ MarkerProps,
51
+ ForeignObjectProps,
52
+ } from './types';
53
+
54
+ /**
55
+ * Helper to convert stroke-dasharray from string to array for native
56
+ */
57
+ function convertStrokeDasharray(value: string | number[] | undefined): number[] | undefined {
58
+ if (typeof value === 'string') {
59
+ return value.split(/[\s,]+/).map(Number).filter(n => !isNaN(n));
60
+ }
61
+ return value;
62
+ }
63
+
64
+ /**
65
+ * Helper to convert points string to array for native
66
+ */
67
+ function convertPoints(points: string | number[]): string {
68
+ // react-native-svg expects a string for points
69
+ if (Array.isArray(points)) {
70
+ const pairs: string[] = [];
71
+ for (let i = 0; i < points.length; i += 2) {
72
+ if (i + 1 < points.length) {
73
+ pairs.push(`${points[i]},${points[i + 1]}`);
74
+ }
75
+ }
76
+ return pairs.join(' ');
77
+ }
78
+ return points;
79
+ }
80
+
81
+ /**
82
+ * Helper to convert common props for native
83
+ */
84
+ function convertCommonProps(props: Record<string, unknown>): Record<string, unknown> {
85
+ const {
86
+ testID,
87
+ onPress,
88
+ onLongPress,
89
+ onPressIn,
90
+ onPressOut,
91
+ strokeDasharray,
92
+ ...rest
93
+ } = props;
94
+
95
+ const result: Record<string, unknown> = { ...rest };
96
+
97
+ if (testID) {
98
+ result.testID = testID;
99
+ }
100
+ if (onPress) {
101
+ result.onPress = onPress;
102
+ }
103
+ if (onLongPress) {
104
+ result.onLongPress = onLongPress;
105
+ }
106
+ if (onPressIn) {
107
+ result.onPressIn = onPressIn;
108
+ }
109
+ if (onPressOut) {
110
+ result.onPressOut = onPressOut;
111
+ }
112
+ if (strokeDasharray !== undefined) {
113
+ result.strokeDasharray = convertStrokeDasharray(strokeDasharray);
114
+ }
115
+
116
+ return result;
117
+ }
118
+
119
+ /**
120
+ * Root SVG element
121
+ */
122
+ export const Svg = forwardRef<typeof RNSvg, SvgProps>(
123
+ ({ children, title, desc, xmlns, xmlnsXlink, color, ...props }, ref) => {
124
+ const svgProps = convertCommonProps(props);
125
+
126
+ return (
127
+ <RNSvg ref={ref as any} color={color} {...(svgProps as any)}>
128
+ {children}
129
+ </RNSvg>
130
+ );
131
+ }
132
+ );
133
+ Svg.displayName = 'Svg';
134
+
135
+ /**
136
+ * Group element
137
+ */
138
+ export const G = forwardRef<typeof RNG, GProps>(
139
+ ({ children, x, y, rotation, scale, originX, originY, ...props }, ref) => {
140
+ const gProps = convertCommonProps(props);
141
+
142
+ // Build transform string from convenience props
143
+ let transform = props.transform || '';
144
+ if (x !== undefined || y !== undefined) {
145
+ transform = `translate(${x || 0}, ${y || 0}) ${transform}`;
146
+ }
147
+ if (rotation !== undefined) {
148
+ const ox = originX || 0;
149
+ const oy = originY || 0;
150
+ transform = `${transform} rotate(${rotation}, ${ox}, ${oy})`;
151
+ }
152
+ if (scale !== undefined) {
153
+ transform = `${transform} scale(${scale})`;
154
+ }
155
+
156
+ return (
157
+ <RNG
158
+ ref={ref as any}
159
+ transform={transform.trim() || undefined}
160
+ {...(gProps as any)}
161
+ >
162
+ {children}
163
+ </RNG>
164
+ );
165
+ }
166
+ );
167
+ G.displayName = 'G';
168
+
169
+ /**
170
+ * Path element
171
+ */
172
+ export const Path = forwardRef<typeof RNPath, PathProps>(
173
+ ({ d, ...props }, ref) => {
174
+ const pathProps = convertCommonProps(props);
175
+
176
+ return <RNPath ref={ref as any} d={d} {...(pathProps as any)} />;
177
+ }
178
+ );
179
+ Path.displayName = 'Path';
180
+
181
+ /**
182
+ * Rectangle element
183
+ */
184
+ export const Rect = forwardRef<typeof RNRect, RectProps>(
185
+ (props, ref) => {
186
+ const rectProps = convertCommonProps(props);
187
+
188
+ return <RNRect ref={ref as any} {...(rectProps as any)} />;
189
+ }
190
+ );
191
+ Rect.displayName = 'Rect';
192
+
193
+ /**
194
+ * Circle element
195
+ */
196
+ export const Circle = forwardRef<typeof RNCircle, CircleProps>(
197
+ (props, ref) => {
198
+ const circleProps = convertCommonProps(props);
199
+
200
+ return <RNCircle ref={ref as any} {...(circleProps as any)} />;
201
+ }
202
+ );
203
+ Circle.displayName = 'Circle';
204
+
205
+ /**
206
+ * Ellipse element
207
+ */
208
+ export const Ellipse = forwardRef<typeof RNEllipse, EllipseProps>(
209
+ (props, ref) => {
210
+ const ellipseProps = convertCommonProps(props);
211
+
212
+ return <RNEllipse ref={ref as any} {...(ellipseProps as any)} />;
213
+ }
214
+ );
215
+ Ellipse.displayName = 'Ellipse';
216
+
217
+ /**
218
+ * Line element
219
+ */
220
+ export const Line = forwardRef<typeof RNLine, LineProps>(
221
+ (props, ref) => {
222
+ const lineProps = convertCommonProps(props);
223
+
224
+ return <RNLine ref={ref as any} {...(lineProps as any)} />;
225
+ }
226
+ );
227
+ Line.displayName = 'Line';
228
+
229
+ /**
230
+ * Polyline element (open shape)
231
+ */
232
+ export const Polyline = forwardRef<typeof RNPolyline, PolylineProps>(
233
+ ({ points, ...props }, ref) => {
234
+ const polylineProps = convertCommonProps(props);
235
+
236
+ return (
237
+ <RNPolyline
238
+ ref={ref as any}
239
+ points={convertPoints(points)}
240
+ {...(polylineProps as any)}
241
+ />
242
+ );
243
+ }
244
+ );
245
+ Polyline.displayName = 'Polyline';
246
+
247
+ /**
248
+ * Polygon element (closed shape)
249
+ */
250
+ export const Polygon = forwardRef<typeof RNPolygon, PolygonProps>(
251
+ ({ points, ...props }, ref) => {
252
+ const polygonProps = convertCommonProps(props);
253
+
254
+ return (
255
+ <RNPolygon
256
+ ref={ref as any}
257
+ points={convertPoints(points)}
258
+ {...(polygonProps as any)}
259
+ />
260
+ );
261
+ }
262
+ );
263
+ Polygon.displayName = 'Polygon';
264
+
265
+ /**
266
+ * Text element
267
+ */
268
+ export const Text = forwardRef<typeof RNText, TextProps>(
269
+ ({ children, ...props }, ref) => {
270
+ const textProps = convertCommonProps(props);
271
+
272
+ return (
273
+ <RNText ref={ref as any} {...(textProps as any)}>
274
+ {children}
275
+ </RNText>
276
+ );
277
+ }
278
+ );
279
+ Text.displayName = 'Text';
280
+
281
+ /**
282
+ * TSpan element (text span)
283
+ */
284
+ export const TSpan = forwardRef<typeof RNTSpan, TSpanProps>(
285
+ ({ children, inlineSize, ...props }, ref) => {
286
+ const tspanProps = convertCommonProps(props);
287
+
288
+ return (
289
+ <RNTSpan ref={ref as any} {...(tspanProps as any)}>
290
+ {children}
291
+ </RNTSpan>
292
+ );
293
+ }
294
+ );
295
+ TSpan.displayName = 'TSpan';
296
+
297
+ /**
298
+ * TextPath element (text along a path)
299
+ */
300
+ export const TextPath = forwardRef<typeof RNTextPath, TextPathProps>(
301
+ ({ children, href, path, ...props }, ref) => {
302
+ const textPathProps = convertCommonProps(props);
303
+
304
+ return (
305
+ <RNTextPath ref={ref as any} href={href} {...(textPathProps as any)}>
306
+ {children}
307
+ </RNTextPath>
308
+ );
309
+ }
310
+ );
311
+ TextPath.displayName = 'TextPath';
312
+
313
+ /**
314
+ * Use element (reference another element)
315
+ */
316
+ export const Use = forwardRef<typeof RNUse, UseProps>(
317
+ ({ href, ...props }, ref) => {
318
+ const useProps = convertCommonProps(props);
319
+
320
+ return <RNUse ref={ref as any} href={href} {...(useProps as any)} />;
321
+ }
322
+ );
323
+ Use.displayName = 'Use';
324
+
325
+ /**
326
+ * Symbol element (reusable graphics)
327
+ */
328
+ export const Symbol = forwardRef<typeof RNSymbol, SymbolProps>(
329
+ ({ children, ...props }, ref) => {
330
+ const symbolProps = convertCommonProps(props);
331
+
332
+ return (
333
+ <RNSymbol ref={ref as any} {...(symbolProps as any)}>
334
+ {children}
335
+ </RNSymbol>
336
+ );
337
+ }
338
+ );
339
+ Symbol.displayName = 'Symbol';
340
+
341
+ /**
342
+ * Defs element (definitions container)
343
+ */
344
+ export const Defs = forwardRef<typeof RNDefs, DefsProps>(
345
+ ({ children, ...props }, ref) => {
346
+ const defsProps = convertCommonProps(props);
347
+
348
+ return (
349
+ <RNDefs ref={ref as any} {...(defsProps as any)}>
350
+ {children}
351
+ </RNDefs>
352
+ );
353
+ }
354
+ );
355
+ Defs.displayName = 'Defs';
356
+
357
+ /**
358
+ * Image element
359
+ */
360
+ export const Image = forwardRef<typeof RNImage, ImageProps>(
361
+ ({ href, ...props }, ref) => {
362
+ const imageProps = convertCommonProps(props);
363
+
364
+ return <RNImage ref={ref as any} href={href} {...(imageProps as any)} />;
365
+ }
366
+ );
367
+ Image.displayName = 'Image';
368
+
369
+ /**
370
+ * ClipPath element
371
+ */
372
+ export const ClipPath = forwardRef<typeof RNClipPath, ClipPathProps>(
373
+ ({ children, ...props }, ref) => {
374
+ const clipPathProps = convertCommonProps(props);
375
+
376
+ return (
377
+ <RNClipPath ref={ref as any} {...(clipPathProps as any)}>
378
+ {children}
379
+ </RNClipPath>
380
+ );
381
+ }
382
+ );
383
+ ClipPath.displayName = 'ClipPath';
384
+
385
+ /**
386
+ * Mask element
387
+ */
388
+ export const Mask = forwardRef<typeof RNMask, MaskProps>(
389
+ ({ children, ...props }, ref) => {
390
+ const maskProps = convertCommonProps(props);
391
+
392
+ return (
393
+ <RNMask ref={ref as any} {...(maskProps as any)}>
394
+ {children}
395
+ </RNMask>
396
+ );
397
+ }
398
+ );
399
+ Mask.displayName = 'Mask';
400
+
401
+ /**
402
+ * LinearGradient element
403
+ */
404
+ export const LinearGradient = forwardRef<typeof RNLinearGradient, LinearGradientProps>(
405
+ ({ children, ...props }, ref) => {
406
+ const linearGradientProps = convertCommonProps(props);
407
+
408
+ return (
409
+ <RNLinearGradient ref={ref as any} {...(linearGradientProps as any)}>
410
+ {children}
411
+ </RNLinearGradient>
412
+ );
413
+ }
414
+ );
415
+ LinearGradient.displayName = 'LinearGradient';
416
+
417
+ /**
418
+ * RadialGradient element
419
+ */
420
+ export const RadialGradient = forwardRef<typeof RNRadialGradient, RadialGradientProps>(
421
+ ({ children, ...props }, ref) => {
422
+ const radialGradientProps = convertCommonProps(props);
423
+
424
+ return (
425
+ <RNRadialGradient ref={ref as any} {...(radialGradientProps as any)}>
426
+ {children}
427
+ </RNRadialGradient>
428
+ );
429
+ }
430
+ );
431
+ RadialGradient.displayName = 'RadialGradient';
432
+
433
+ /**
434
+ * Stop element (for gradients)
435
+ */
436
+ export const Stop = forwardRef<typeof RNStop, StopProps>(
437
+ ({ offset, stopColor, stopOpacity }, ref) => {
438
+ return (
439
+ <RNStop
440
+ ref={ref as any}
441
+ offset={offset}
442
+ stopColor={stopColor}
443
+ stopOpacity={stopOpacity}
444
+ />
445
+ );
446
+ }
447
+ );
448
+ Stop.displayName = 'Stop';
449
+
450
+ /**
451
+ * Pattern element
452
+ */
453
+ export const Pattern = forwardRef<typeof RNPattern, PatternProps>(
454
+ ({ children, ...props }, ref) => {
455
+ const patternProps = convertCommonProps(props);
456
+
457
+ return (
458
+ <RNPattern ref={ref as any} {...(patternProps as any)}>
459
+ {children}
460
+ </RNPattern>
461
+ );
462
+ }
463
+ );
464
+ Pattern.displayName = 'Pattern';
465
+
466
+ /**
467
+ * Marker element
468
+ */
469
+ export const Marker = forwardRef<typeof RNMarker, MarkerProps>(
470
+ ({ children, ...props }, ref) => {
471
+ const markerProps = convertCommonProps(props);
472
+
473
+ return (
474
+ <RNMarker ref={ref as any} {...(markerProps as any)}>
475
+ {children}
476
+ </RNMarker>
477
+ );
478
+ }
479
+ );
480
+ Marker.displayName = 'Marker';
481
+
482
+ /**
483
+ * ForeignObject element (embed HTML/native views in SVG)
484
+ */
485
+ export const ForeignObject = forwardRef<typeof RNForeignObject, ForeignObjectProps>(
486
+ ({ children, ...props }, ref) => {
487
+ const foreignObjectProps = convertCommonProps(props);
488
+
489
+ return (
490
+ <RNForeignObject ref={ref as any} {...(foreignObjectProps as any)}>
491
+ {children}
492
+ </RNForeignObject>
493
+ );
494
+ }
495
+ );
496
+ ForeignObject.displayName = 'ForeignObject';