mirror of
https://github.com/zoriya/react-native-svg.git
synced 2025-12-06 07:06:11 +00:00
fix(xml): extract tags map to separate entry point for mobile & web (#1916)
# Summary **What issues does the pull request solve? Please tag them so that they will get automatically closed once the PR is merged** When utilizing with `react-native-web`: SvgXml and SvgUri are not exported in the `src/ReactNativeSVG.web.ts` extension. The logic for SvgXml and SvgUri do not have native dependencies, so they are safe to consume on web. Issues: - https://github.com/software-mansion/react-native-svg/issues/1279 - https://github.com/software-mansion/react-native-svg/issues/1742 **What is the feature? (if applicable)** Add SvgXml and SvgUri as consumable exports for `react-native-web` **How did you implement the solution?** Extract `tags` to shapes map into separate `tags.tsx` file, where native shape elements and web shape elements can be provided to their respective envs. **What areas of the library does it impact?** `src` directory ## Test Plan Demonstrate the code is solid. Example: The exact commands you ran and their output, screenshots / videos if the pull request changes UI. ### What's required for testing (prerequisites)? n/a ### What are the steps to reproduce (after prerequisites)? n/a ## Compatibility | OS | Implemented | | ------- | :---------: | | iOS | ✅ | | Android | ✅ | ## Checklist <!-- Check completed item, when applicable, via: [X] --> - [x] I have tested this on a device and a simulator - [x] I added documentation in `README.md` - [x] I updated the typed files (typescript) - [ ] I added a test for the API in the `__tests__` folder --------- Co-authored-by: bohdanprog <bohdan.artiukhov@swmansion.com>
This commit is contained in:
@@ -17,7 +17,7 @@ export type FeColorMatrixProps = {
|
|||||||
export default class FeColorMatrix extends FilterPrimitive<FeColorMatrixProps> {
|
export default class FeColorMatrix extends FilterPrimitive<FeColorMatrixProps> {
|
||||||
static displayName = 'FeColorMatrix';
|
static displayName = 'FeColorMatrix';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps: React.ComponentProps<typeof FeColorMatrix> = {
|
||||||
...this.defaultPrimitiveProps,
|
...this.defaultPrimitiveProps,
|
||||||
type: 'matrix',
|
type: 'matrix',
|
||||||
values: '',
|
values: '',
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export interface FeGaussianBlurProps {
|
|||||||
export default class FeGaussianBlur extends FilterPrimitive<FeGaussianBlurProps> {
|
export default class FeGaussianBlur extends FilterPrimitive<FeGaussianBlurProps> {
|
||||||
static displayName = 'FeGaussianBlur';
|
static displayName = 'FeGaussianBlur';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps: React.ComponentProps<typeof FeGaussianBlur> = {
|
||||||
...this.defaultPrimitiveProps,
|
...this.defaultPrimitiveProps,
|
||||||
stdDeviation: 0,
|
stdDeviation: 0,
|
||||||
edgeMode: 'none',
|
edgeMode: 'none',
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export interface FeOffsetProps {
|
|||||||
export default class FeOffset extends FilterPrimitive<FeOffsetProps> {
|
export default class FeOffset extends FilterPrimitive<FeOffsetProps> {
|
||||||
static displayName = 'FeOffset';
|
static displayName = 'FeOffset';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps: React.ComponentProps<typeof FeOffset> = {
|
||||||
...this.defaultPrimitiveProps,
|
...this.defaultPrimitiveProps,
|
||||||
dx: 0,
|
dx: 0,
|
||||||
dy: 0,
|
dy: 0,
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export interface FilterProps {
|
|||||||
export default class Filter extends Shape<FilterProps> {
|
export default class Filter extends Shape<FilterProps> {
|
||||||
static displayName = 'Filter';
|
static displayName = 'Filter';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps: React.ComponentProps<typeof Filter> = {
|
||||||
x: '-10%',
|
x: '-10%',
|
||||||
y: '-10%',
|
y: '-10%',
|
||||||
width: '120%',
|
width: '120%',
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export default class FilterPrimitive<P> extends Component<
|
|||||||
[x: string]: unknown;
|
[x: string]: unknown;
|
||||||
root: (FilterPrimitive<P> & NativeMethods) | null = null;
|
root: (FilterPrimitive<P> & NativeMethods) | null = null;
|
||||||
|
|
||||||
static defaultPrimitiveProps = {
|
static defaultPrimitiveProps: React.ComponentProps<typeof FilterPrimitive> = {
|
||||||
x: '0%',
|
x: '0%',
|
||||||
y: '0%',
|
y: '0%',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { tags } from '../../xml';
|
import { tags } from '../../tags';
|
||||||
import { FilterElement, Filters } from '../types';
|
import { FilterElement, Filters } from '../types';
|
||||||
import { parse } from './extractFiltersString';
|
import { parse } from './extractFiltersString';
|
||||||
|
|
||||||
|
|||||||
57
src/tags.tsx
Normal file
57
src/tags.tsx
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import Rect from './elements/Rect';
|
||||||
|
import Circle from './elements/Circle';
|
||||||
|
import Ellipse from './elements/Ellipse';
|
||||||
|
import Polygon from './elements/Polygon';
|
||||||
|
import Polyline from './elements/Polyline';
|
||||||
|
import Line from './elements/Line';
|
||||||
|
import Svg from './elements/Svg';
|
||||||
|
import Path from './elements/Path';
|
||||||
|
import G from './elements/G';
|
||||||
|
import Text from './elements/Text';
|
||||||
|
import TSpan from './elements/TSpan';
|
||||||
|
import TextPath from './elements/TextPath';
|
||||||
|
import Use from './elements/Use';
|
||||||
|
import Image from './elements/Image';
|
||||||
|
import Symbol from './elements/Symbol';
|
||||||
|
import Defs from './elements/Defs';
|
||||||
|
import LinearGradient from './elements/LinearGradient';
|
||||||
|
import RadialGradient from './elements/RadialGradient';
|
||||||
|
import Stop from './elements/Stop';
|
||||||
|
import ClipPath from './elements/ClipPath';
|
||||||
|
import Pattern from './elements/Pattern';
|
||||||
|
import Mask from './elements/Mask';
|
||||||
|
import Marker from './elements/Marker';
|
||||||
|
import Filter from './elements/filters/Filter';
|
||||||
|
import FeColorMatrix from './elements/filters/FeColorMatrix';
|
||||||
|
import FeGaussianBlur from './elements/filters/FeGaussianBlur';
|
||||||
|
import FeOffset from './elements/filters/FeOffset';
|
||||||
|
|
||||||
|
export const tags = {
|
||||||
|
circle: Circle,
|
||||||
|
clipPath: ClipPath,
|
||||||
|
defs: Defs,
|
||||||
|
ellipse: Ellipse,
|
||||||
|
filter: Filter,
|
||||||
|
feColorMatrix: FeColorMatrix,
|
||||||
|
feGaussianBlur: FeGaussianBlur,
|
||||||
|
feOffset: FeOffset,
|
||||||
|
g: G,
|
||||||
|
image: Image,
|
||||||
|
line: Line,
|
||||||
|
linearGradient: LinearGradient,
|
||||||
|
marker: Marker,
|
||||||
|
mask: Mask,
|
||||||
|
path: Path,
|
||||||
|
pattern: Pattern,
|
||||||
|
polygon: Polygon,
|
||||||
|
polyline: Polyline,
|
||||||
|
radialGradient: RadialGradient,
|
||||||
|
rect: Rect,
|
||||||
|
stop: Stop,
|
||||||
|
svg: Svg,
|
||||||
|
symbol: Symbol,
|
||||||
|
text: Text,
|
||||||
|
textPath: TextPath,
|
||||||
|
tspan: TSpan,
|
||||||
|
use: Use,
|
||||||
|
} as const;
|
||||||
50
src/tags.web.tsx
Normal file
50
src/tags.web.tsx
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import Svg, {
|
||||||
|
Circle,
|
||||||
|
ClipPath,
|
||||||
|
Defs,
|
||||||
|
Ellipse,
|
||||||
|
G,
|
||||||
|
Image,
|
||||||
|
Line,
|
||||||
|
LinearGradient,
|
||||||
|
Marker,
|
||||||
|
Mask,
|
||||||
|
Path,
|
||||||
|
Pattern,
|
||||||
|
Polygon,
|
||||||
|
Polyline,
|
||||||
|
RadialGradient,
|
||||||
|
Rect,
|
||||||
|
Stop,
|
||||||
|
Text,
|
||||||
|
TextPath,
|
||||||
|
TSpan,
|
||||||
|
Use,
|
||||||
|
Symbol,
|
||||||
|
} from './ReactNativeSVG.web';
|
||||||
|
|
||||||
|
export const tags = {
|
||||||
|
circle: Circle,
|
||||||
|
clipPath: ClipPath,
|
||||||
|
defs: Defs,
|
||||||
|
ellipse: Ellipse,
|
||||||
|
g: G,
|
||||||
|
image: Image,
|
||||||
|
line: Line,
|
||||||
|
linearGradient: LinearGradient,
|
||||||
|
marker: Marker,
|
||||||
|
mask: Mask,
|
||||||
|
path: Path,
|
||||||
|
pattern: Pattern,
|
||||||
|
polygon: Polygon,
|
||||||
|
polyline: Polyline,
|
||||||
|
radialGradient: RadialGradient,
|
||||||
|
rect: Rect,
|
||||||
|
stop: Stop,
|
||||||
|
svg: Svg,
|
||||||
|
symbol: Symbol,
|
||||||
|
text: Text,
|
||||||
|
textPath: TextPath,
|
||||||
|
tspan: TSpan,
|
||||||
|
use: Use,
|
||||||
|
} as const;
|
||||||
71
src/xml.tsx
71
src/xml.tsx
@@ -1,69 +1,14 @@
|
|||||||
import type { ComponentType } from 'react';
|
import type { ComponentType, ComponentProps } from 'react';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Component, useEffect, useMemo, useState } from 'react';
|
import { Component, useEffect, useMemo, useState } from 'react';
|
||||||
import Rect from './elements/Rect';
|
|
||||||
import Circle from './elements/Circle';
|
|
||||||
import Ellipse from './elements/Ellipse';
|
|
||||||
import Polygon from './elements/Polygon';
|
|
||||||
import Polyline from './elements/Polyline';
|
|
||||||
import Line from './elements/Line';
|
|
||||||
import type { SvgProps } from './elements/Svg';
|
import type { SvgProps } from './elements/Svg';
|
||||||
import Svg from './elements/Svg';
|
import { tags } from './tags';
|
||||||
import Path from './elements/Path';
|
|
||||||
import G from './elements/G';
|
|
||||||
import Text from './elements/Text';
|
|
||||||
import TSpan from './elements/TSpan';
|
|
||||||
import TextPath from './elements/TextPath';
|
|
||||||
import Use from './elements/Use';
|
|
||||||
import Image from './elements/Image';
|
|
||||||
import Symbol from './elements/Symbol';
|
|
||||||
import Defs from './elements/Defs';
|
|
||||||
import LinearGradient from './elements/LinearGradient';
|
|
||||||
import RadialGradient from './elements/RadialGradient';
|
|
||||||
import Stop from './elements/Stop';
|
|
||||||
import ClipPath from './elements/ClipPath';
|
|
||||||
import Pattern from './elements/Pattern';
|
|
||||||
import Mask from './elements/Mask';
|
|
||||||
import Marker from './elements/Marker';
|
|
||||||
import Filter from './elements/filters/Filter';
|
|
||||||
import FeColorMatrix from './elements/filters/FeColorMatrix';
|
|
||||||
import FeGaussianBlur from './elements/filters/FeGaussianBlur';
|
|
||||||
import FeOffset from './elements/filters/FeOffset';
|
|
||||||
|
|
||||||
export const tags: { [tag: string]: ComponentType } = {
|
|
||||||
svg: Svg,
|
|
||||||
circle: Circle,
|
|
||||||
ellipse: Ellipse,
|
|
||||||
g: G,
|
|
||||||
text: Text,
|
|
||||||
tspan: TSpan,
|
|
||||||
textPath: TextPath,
|
|
||||||
path: Path,
|
|
||||||
polygon: Polygon,
|
|
||||||
polyline: Polyline,
|
|
||||||
line: Line,
|
|
||||||
rect: Rect,
|
|
||||||
use: Use,
|
|
||||||
image: Image,
|
|
||||||
symbol: Symbol,
|
|
||||||
defs: Defs,
|
|
||||||
linearGradient: LinearGradient,
|
|
||||||
radialGradient: RadialGradient,
|
|
||||||
stop: Stop,
|
|
||||||
clipPath: ClipPath,
|
|
||||||
pattern: Pattern,
|
|
||||||
mask: Mask,
|
|
||||||
marker: Marker,
|
|
||||||
filter: Filter,
|
|
||||||
feColorMatrix: FeColorMatrix,
|
|
||||||
feGaussianBlur: FeGaussianBlur,
|
|
||||||
feOffset: FeOffset,
|
|
||||||
};
|
|
||||||
|
|
||||||
function missingTag() {
|
function missingTag() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Tag = ComponentType<ComponentProps<(typeof tags)[keyof typeof tags]>>;
|
||||||
export interface AST {
|
export interface AST {
|
||||||
tag: string;
|
tag: string;
|
||||||
style?: Styles;
|
style?: Styles;
|
||||||
@@ -74,7 +19,7 @@ export interface AST {
|
|||||||
props: {
|
props: {
|
||||||
[prop: string]: Styles | string | undefined;
|
[prop: string]: Styles | string | undefined;
|
||||||
};
|
};
|
||||||
Tag: ComponentType<React.PropsWithChildren>;
|
Tag: Tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface XmlAST extends AST {
|
export interface XmlAST extends AST {
|
||||||
@@ -106,6 +51,9 @@ export function SvgAst({ ast, override }: AstProps) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const { props, children } = ast;
|
const { props, children } = ast;
|
||||||
|
|
||||||
|
const Svg = tags.svg;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Svg {...props} {...override}>
|
<Svg {...props} {...override}>
|
||||||
{children}
|
{children}
|
||||||
@@ -385,14 +333,14 @@ export function parse(source: string, middleware?: Middleware): JsxAST | null {
|
|||||||
return closingTag;
|
return closingTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tag = getName();
|
const tag = getName() as keyof typeof tags;
|
||||||
const props: { [prop: string]: Styles | string | undefined } = {};
|
const props: { [prop: string]: Styles | string | undefined } = {};
|
||||||
const element: XmlAST = {
|
const element: XmlAST = {
|
||||||
tag,
|
tag,
|
||||||
props,
|
props,
|
||||||
children: [],
|
children: [],
|
||||||
parent: currentElement,
|
parent: currentElement,
|
||||||
Tag: tags[tag] || missingTag,
|
Tag: (tags[tag] || missingTag) as Tag,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (currentElement) {
|
if (currentElement) {
|
||||||
@@ -594,3 +542,4 @@ export function parse(source: string, middleware?: Middleware): JsxAST | null {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
export { tags };
|
||||||
|
|||||||
Reference in New Issue
Block a user