mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-08 17:15:04 +00:00
feat: implement SvgWithCss and SvgWithCssUri with Animated support
Expose types of SvgCss, SvgWithCss, SvgCssUri & SvgWithCssUri Move css-select and css-tree to peerDependencies & devDependencies
This commit is contained in:
Generated
+31
-11
@@ -4183,7 +4183,8 @@
|
||||
"boolbase": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
|
||||
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
|
||||
"dev": true
|
||||
},
|
||||
"bottleneck": {
|
||||
"version": "2.19.5",
|
||||
@@ -5188,6 +5189,7 @@
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz",
|
||||
"integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"boolbase": "^1.0.0",
|
||||
"css-what": "^2.1.2",
|
||||
@@ -5196,18 +5198,28 @@
|
||||
}
|
||||
},
|
||||
"css-tree": {
|
||||
"version": "1.0.0-alpha.36",
|
||||
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.36.tgz",
|
||||
"integrity": "sha512-AFAFvEOaB8NPmPtSIy1wVyD6K1bC8YBc07BYTCmeB3EbQUqKBU/TUIbJGSgDWbrHPX1a6QsJExx7rd6mzagK0w==",
|
||||
"version": "1.0.0-alpha.37",
|
||||
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
|
||||
"integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mdn-data": "2.0.4",
|
||||
"source-map": "^0.5.3"
|
||||
"source-map": "^0.6.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"css-what": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
|
||||
"integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg=="
|
||||
"integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
|
||||
"dev": true
|
||||
},
|
||||
"cssom": {
|
||||
"version": "0.3.8",
|
||||
@@ -5529,6 +5541,7 @@
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz",
|
||||
"integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"entities": "^2.0.0"
|
||||
@@ -5537,7 +5550,8 @@
|
||||
"domelementtype": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz",
|
||||
"integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ=="
|
||||
"integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -5550,7 +5564,8 @@
|
||||
"domelementtype": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
|
||||
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
|
||||
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
|
||||
"dev": true
|
||||
},
|
||||
"domexception": {
|
||||
"version": "1.0.1",
|
||||
@@ -5565,6 +5580,7 @@
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
|
||||
"integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dom-serializer": "0",
|
||||
"domelementtype": "1"
|
||||
@@ -5661,7 +5677,8 @@
|
||||
"entities": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz",
|
||||
"integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw=="
|
||||
"integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==",
|
||||
"dev": true
|
||||
},
|
||||
"env-ci": {
|
||||
"version": "4.5.0",
|
||||
@@ -10315,7 +10332,8 @@
|
||||
"mdn-data": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
|
||||
"integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA=="
|
||||
"integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==",
|
||||
"dev": true
|
||||
},
|
||||
"mem": {
|
||||
"version": "4.3.0",
|
||||
@@ -15825,6 +15843,7 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
|
||||
"integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"boolbase": "~1.0.0"
|
||||
}
|
||||
@@ -18518,7 +18537,8 @@
|
||||
"source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
|
||||
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
|
||||
"dev": true
|
||||
},
|
||||
"source-map-resolve": {
|
||||
"version": "0.5.2",
|
||||
|
||||
+5
-4
@@ -46,13 +46,12 @@
|
||||
"semantic-release": "semantic-release"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"css-select": "^2.0.2",
|
||||
"css-tree": "^1.0.0-alpha.37",
|
||||
"react": "*",
|
||||
"react-native": ">=0.50.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"css-select": "^2.0.2",
|
||||
"css-tree": "^1.0.0-alpha.36"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@react-native-community/bob": "^0.7.0",
|
||||
"@react-native-community/eslint-config": "^0.0.5",
|
||||
@@ -63,6 +62,8 @@
|
||||
"@types/react-native": "^0.60.21",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"babel-jest": "^24.9.0",
|
||||
"css-select": "^2.0.2",
|
||||
"css-tree": "^1.0.0-alpha.37",
|
||||
"eslint": "^6.5.1",
|
||||
"eslint-plugin-flowtype": "^4.3.0",
|
||||
"eslint-plugin-prettier": "^3.1.1",
|
||||
|
||||
@@ -23,7 +23,13 @@ import Pattern, { RNSVGPattern } from './elements/Pattern';
|
||||
import Mask, { RNSVGMask } from './elements/Mask';
|
||||
import Marker, { RNSVGMarker } from './elements/Marker';
|
||||
import { parse, SvgAst, SvgFromUri, SvgFromXml, SvgUri, SvgXml } from './xml';
|
||||
import { SvgCss, SvgCssUri, inlineStyles } from './css';
|
||||
import {
|
||||
SvgCss,
|
||||
SvgCssUri,
|
||||
SvgWithCss,
|
||||
SvgWithCssUri,
|
||||
inlineStyles,
|
||||
} from './css';
|
||||
|
||||
export {
|
||||
Svg,
|
||||
@@ -57,6 +63,8 @@ export {
|
||||
SvgXml,
|
||||
SvgCss,
|
||||
SvgCssUri,
|
||||
SvgWithCss,
|
||||
SvgWithCssUri,
|
||||
inlineStyles,
|
||||
Shape,
|
||||
RNSVGMarker,
|
||||
|
||||
+64
-3
@@ -1,15 +1,18 @@
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import React, { Component, useEffect, useMemo, useState } from 'react';
|
||||
import {
|
||||
camelCase,
|
||||
err,
|
||||
fetchText,
|
||||
JsxAST,
|
||||
Middleware,
|
||||
parse,
|
||||
Styles,
|
||||
SvgAst,
|
||||
UriProps,
|
||||
UriState,
|
||||
XmlAST,
|
||||
XmlProps,
|
||||
XmlState,
|
||||
} from './xml';
|
||||
import csstree, {
|
||||
Atrule,
|
||||
@@ -595,7 +598,9 @@ const parseProps = {
|
||||
* @author strarsis <strarsis@gmail.com>
|
||||
* @author modified by: msand <msand@abo.fi>
|
||||
*/
|
||||
export function inlineStyles(document: XmlAST) {
|
||||
export const inlineStyles: Middleware = function inlineStyles(
|
||||
document: XmlAST,
|
||||
) {
|
||||
// collect <style/>s
|
||||
const styleElements = querySelectorAll('style', document);
|
||||
|
||||
@@ -685,7 +690,7 @@ export function inlineStyles(document: XmlAST) {
|
||||
}
|
||||
|
||||
return document;
|
||||
}
|
||||
};
|
||||
|
||||
export function SvgCss(props: XmlProps) {
|
||||
const { xml, override } = props;
|
||||
@@ -708,3 +713,59 @@ export function SvgCssUri(props: UriProps) {
|
||||
}, [uri]);
|
||||
return <SvgCss xml={xml} override={props} />;
|
||||
}
|
||||
|
||||
// Extending Component is required for Animated support.
|
||||
|
||||
export class SvgWithCss extends Component<XmlProps, XmlState> {
|
||||
state = { ast: null };
|
||||
componentDidMount() {
|
||||
this.parse(this.props.xml);
|
||||
}
|
||||
componentDidUpdate(prevProps: { xml: string | null }) {
|
||||
const { xml } = this.props;
|
||||
if (xml !== prevProps.xml) {
|
||||
this.parse(xml);
|
||||
}
|
||||
}
|
||||
parse(xml: string | null) {
|
||||
try {
|
||||
this.setState({ ast: xml ? parse(xml, inlineStyles) : null });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
render() {
|
||||
const {
|
||||
props,
|
||||
state: { ast },
|
||||
} = this;
|
||||
return <SvgAst ast={ast} override={props.override || props} />;
|
||||
}
|
||||
}
|
||||
|
||||
export class SvgWithCssUri extends Component<UriProps, UriState> {
|
||||
state = { xml: null };
|
||||
componentDidMount() {
|
||||
this.fetch(this.props.uri);
|
||||
}
|
||||
componentDidUpdate(prevProps: { uri: string | null }) {
|
||||
const { uri } = this.props;
|
||||
if (uri !== prevProps.uri) {
|
||||
this.fetch(uri);
|
||||
}
|
||||
}
|
||||
async fetch(uri: string | null) {
|
||||
try {
|
||||
this.setState({ xml: uri ? await fetchText(uri) : null });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
render() {
|
||||
const {
|
||||
props,
|
||||
state: { xml },
|
||||
} = this;
|
||||
return <SvgWithCss xml={xml} override={props} />;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+31
-4
@@ -446,13 +446,30 @@ export interface MaskProps extends CommonPathProps {
|
||||
}
|
||||
export const Mask: React.ComponentClass<MaskProps>;
|
||||
|
||||
export type Styles = { [property: string]: string };
|
||||
|
||||
export interface AST {
|
||||
tag: string;
|
||||
style?: Styles;
|
||||
styles?: string;
|
||||
priority?: Map<string, boolean | undefined>;
|
||||
parent: AST | null;
|
||||
children: (AST | string)[] | (JSX.Element | string)[];
|
||||
props: {};
|
||||
props: {
|
||||
[prop: string]: Styles | string | undefined;
|
||||
};
|
||||
Tag: React.ComponentType;
|
||||
}
|
||||
|
||||
export interface XmlAST extends AST {
|
||||
children: (XmlAST | string)[];
|
||||
parent: XmlAST | null;
|
||||
}
|
||||
|
||||
export interface JsxAST extends AST {
|
||||
children: (JSX.Element | string)[];
|
||||
}
|
||||
|
||||
export interface UriProps extends SvgProps {
|
||||
uri: string | null;
|
||||
override?: SvgProps;
|
||||
@@ -463,14 +480,16 @@ export interface XmlProps extends SvgProps {
|
||||
xml: string | null;
|
||||
override?: SvgProps;
|
||||
}
|
||||
export type XmlState = { ast: AST | null };
|
||||
export type XmlState = { ast: JsxAST | null };
|
||||
|
||||
export interface AstProps extends SvgProps {
|
||||
ast: AST | null;
|
||||
ast: JsxAST | null;
|
||||
override?: SvgProps;
|
||||
}
|
||||
|
||||
export function parse(xml: string): AST | null;
|
||||
export type Middleware = (ast: XmlAST) => XmlAST;
|
||||
|
||||
export function parse(source: string, middleware?: Middleware): JsxAST | null;
|
||||
|
||||
export const SvgAst: React.FunctionComponent<AstProps>;
|
||||
|
||||
@@ -479,3 +498,11 @@ export const SvgFromXml: React.ComponentClass<XmlProps, XmlState>;
|
||||
|
||||
export const SvgUri: React.FunctionComponent<UriProps>;
|
||||
export const SvgFromUri: React.ComponentClass<UriProps, UriState>;
|
||||
|
||||
export const SvgCss: React.FunctionComponent<XmlProps>;
|
||||
export const SvgWithCss: React.ComponentClass<XmlProps, XmlState>;
|
||||
|
||||
export const SvgCssUri: React.FunctionComponent<UriProps>;
|
||||
export const SvgWithCssUri: React.ComponentClass<UriProps, UriState>;
|
||||
|
||||
export const inlineStyles: Middleware;
|
||||
|
||||
+3
-4
@@ -263,10 +263,9 @@ const validNameCharacters = /[a-zA-Z0-9:_-]/;
|
||||
const whitespace = /[\s\t\r\n]/;
|
||||
const quotemarks = /['"]/;
|
||||
|
||||
export function parse(
|
||||
source: string,
|
||||
middleware?: (ast: XmlAST) => XmlAST,
|
||||
): JsxAST | null {
|
||||
export type Middleware = (ast: XmlAST) => XmlAST;
|
||||
|
||||
export function parse(source: string, middleware?: Middleware): JsxAST | null {
|
||||
const length = source.length;
|
||||
let currentElement: XmlAST | null = null;
|
||||
let state = metadata;
|
||||
|
||||
Reference in New Issue
Block a user