Skip to content

Commit

Permalink
fix(xml): extract tags map to separate entry point for mobile & web (#…
Browse files Browse the repository at this point in the history
…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:
- #1279
- #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>
  • Loading branch information
joshuayoes and bohdanprog committed Jul 29, 2024
1 parent c5e601a commit 360e0ee
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 67 deletions.
2 changes: 1 addition & 1 deletion src/elements/filters/FeColorMatrix.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export type FeColorMatrixProps = {
export default class FeColorMatrix extends FilterPrimitive<FeColorMatrixProps> {
static displayName = 'FeColorMatrix';

static defaultProps = {
static defaultProps: React.ComponentProps<typeof FeColorMatrix> = {
...this.defaultPrimitiveProps,
type: 'matrix',
values: '',
Expand Down
2 changes: 1 addition & 1 deletion src/elements/filters/FeGaussianBlur.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface FeGaussianBlurProps {
export default class FeGaussianBlur extends FilterPrimitive<FeGaussianBlurProps> {
static displayName = 'FeGaussianBlur';

static defaultProps = {
static defaultProps: React.ComponentProps<typeof FeGaussianBlur> = {
...this.defaultPrimitiveProps,
stdDeviation: 0,
edgeMode: 'none',
Expand Down
2 changes: 1 addition & 1 deletion src/elements/filters/FeOffset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface FeOffsetProps {
export default class FeOffset extends FilterPrimitive<FeOffsetProps> {
static displayName = 'FeOffset';

static defaultProps = {
static defaultProps: React.ComponentProps<typeof FeOffset> = {
...this.defaultPrimitiveProps,
dx: 0,
dy: 0,
Expand Down
2 changes: 1 addition & 1 deletion src/elements/filters/Filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface FilterProps {
export default class Filter extends Shape<FilterProps> {
static displayName = 'Filter';

static defaultProps = {
static defaultProps: React.ComponentProps<typeof Filter> = {
x: '-10%',
y: '-10%',
width: '120%',
Expand Down
2 changes: 1 addition & 1 deletion src/elements/filters/FilterPrimitive.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default class FilterPrimitive<P> extends Component<
[x: string]: unknown;
root: (FilterPrimitive<P> & NativeMethods) | null = null;

static defaultPrimitiveProps = {
static defaultPrimitiveProps: React.ComponentProps<typeof FilterPrimitive> = {
x: '0%',
y: '0%',
width: '100%',
Expand Down
2 changes: 1 addition & 1 deletion src/filter-image/extract/extractFilters.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { tags } from '../../xml';
import { tags } from '../../tags';
import { FilterElement, Filters } from '../types';
import { parse } from './extractFiltersString';

Expand Down
57 changes: 57 additions & 0 deletions src/tags.tsx
Original file line number Diff line number Diff line change
@@ -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 changes: 50 additions & 0 deletions src/tags.web.tsx
Original file line number Diff line number Diff line change
@@ -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 changes: 10 additions & 61 deletions src/xml.tsx
Original file line number Diff line number Diff line change
@@ -1,69 +1,14 @@
import type { ComponentType } from 'react';
import type { ComponentType, ComponentProps } from 'react';
import * as React 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 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: { [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,
};
import { tags } from './tags';

function missingTag() {
return null;
}

type Tag = ComponentType<ComponentProps<(typeof tags)[keyof typeof tags]>>;
export interface AST {
tag: string;
style?: Styles;
Expand All @@ -74,7 +19,7 @@ export interface AST {
props: {
[prop: string]: Styles | string | undefined;
};
Tag: ComponentType<React.PropsWithChildren>;
Tag: Tag;
}

export interface XmlAST extends AST {
Expand Down Expand Up @@ -106,6 +51,9 @@ export function SvgAst({ ast, override }: AstProps) {
return null;
}
const { props, children } = ast;

const Svg = tags.svg;

return (
<Svg {...props} {...override}>
{children}
Expand Down Expand Up @@ -385,14 +333,14 @@ export function parse(source: string, middleware?: Middleware): JsxAST | null {
return closingTag;
}

const tag = getName();
const tag = getName() as keyof typeof tags;
const props: { [prop: string]: Styles | string | undefined } = {};
const element: XmlAST = {
tag,
props,
children: [],
parent: currentElement,
Tag: tags[tag] || missingTag,
Tag: (tags[tag] || missingTag) as Tag,
};

if (currentElement) {
Expand Down Expand Up @@ -594,3 +542,4 @@ export function parse(source: string, middleware?: Middleware): JsxAST | null {

return null;
}
export { tags };

0 comments on commit 360e0ee

Please sign in to comment.