diff --git a/.prettierrc b/.prettierrc index 20374fd9..a20502b7 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,7 +1,4 @@ { - "requirePragma": true, "singleQuote": true, - "trailingComma": "all", - "bracketSpacing": false, - "jsxBracketSameLine": true + "trailingComma": "all" } diff --git a/README.md b/README.md index 8933b402..c1d110db 100644 --- a/README.md +++ b/README.md @@ -13,38 +13,39 @@ 2. Easy to [convert SVG code](https://svgr.now.sh/) to react-native-svg. - [Installation](#installation) - - [Automatically](#automatically) - - [Manually](#manually) - - [Android](#android) - - [iOS](#ios) + - [Automatically](#automatically) + - [Manually](#manually) + - [Android](#android-pre-rn-060) + - [iOS](#ios-pre-rn-060) - [Troubleshooting](#troubleshooting) +- [Opening issues](#opening-issues) - [Usage](#usage) - - [Use with content loaded from uri](#use-with-content-loaded-from-uri) - - [Use with svg files](#use-with-svg-files) - - [Use with xml strings](#use-with-xml-strings) + - [Use with content loaded from uri](#use-with-content-loaded-from-uri) + - [Use with svg files](#use-with-svg-files) + - [Use with xml strings](#use-with-xml-strings) - [Common props](#common-props) - [Supported elements](#supported-elements) - - [Svg](#svg) - - [Rect](#rect) - - [Circle](#circle) - - [Ellipse](#ellipse) - - [Line](#line) - - [Polygon](#polygon) - - [Polyline](#polyline) - - [Path](#path) - - [Text](#text) - - [TSpan](#tspan) - - [TextPath](#textpath) - - [G](#g) - - [Use](#use) - - [Symbol](#symbol) - - [Defs](#defs) - - [Image](#image) - - [ClipPath](#clippath) - - [LinearGradient](#lineargradient) - - [RadialGradient](#radialgradient) - - [Mask](#mask) - - [Pattern](#pattern) + - [Svg](#svg) + - [Rect](#rect) + - [Circle](#circle) + - [Ellipse](#ellipse) + - [Line](#line) + - [Polygon](#polygon) + - [Polyline](#polyline) + - [Path](#path) + - [Text](#text) + - [TSpan](#tspan) + - [TextPath](#textpath) + - [G](#g) + - [Use](#use) + - [Symbol](#symbol) + - [Defs](#defs) + - [Image](#image) + - [ClipPath](#clippath) + - [LinearGradient](#lineargradient) + - [RadialGradient](#radialgradient) + - [Mask](#mask) + - [Pattern](#pattern) - [Touch Events](#touch-events) - [Run example](#run-example) - [TODO](#todo) @@ -54,26 +55,27 @@ #### Automatically -*With Expo, this is pre-installed. Jump ahead to [Usage](#Usage)* +_With Expo, this is pre-installed. Jump ahead to [Usage](#Usage)_ 1. Install library from `npm` - ```bash - yarn add react-native-svg - ``` + ```bash + yarn add react-native-svg + ``` 2. Link native code - With autolinking (react-native 0.60+) - ```bash - cd ios && pod install - ``` + With autolinking (react-native 0.60+) - Pre 0.60 - ```bash - react-native link react-native-svg - ``` + ```bash + cd ios && pod install + ``` + Pre 0.60 + + ```bash + react-native link react-native-svg + ``` # NOTICE: @@ -87,7 +89,7 @@ of the react-native version you are using. The latest version of react-native-svg should always work in a clean react-native project. | react-native-svg | react-native | -|------------------|--------------| +| ---------------- | ------------ | | 3.2.0 | 0.29 | | 4.2.0 | 0.32 | | 4.3.0 | 0.33 | @@ -117,20 +119,21 @@ v7 and newer requires the patch for making android thread safe, to get native an 2. Append the following lines to `android/settings.gradle`: - ```gradle - include ':react-native-svg' - project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-svg/android') - ``` + ```gradle + include ':react-native-svg' + project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-svg/android') + ``` 3. Insert the following lines inside the dependencies block in `android/app/build.gradle`: - ```gradle - implementation project(':react-native-svg') - ``` + ```gradle + implementation project(':react-native-svg') + ``` 4. Open up `android/app/src/main/java/[...]/MainApplication.java` - - Add `import com.horcrux.svg.SvgPackage;` to the imports at the top of the file - - Add `new SvgPackage()` to the list returned by the `getPackages()` method. Add a comma to the previous item if there's already something there. + +- Add `import com.horcrux.svg.SvgPackage;` to the imports at the top of the file +- Add `new SvgPackage()` to the list returned by the `getPackages()` method. Add a comma to the previous item if there's already something there. ##### iOS pre RN 0.60 @@ -147,6 +150,7 @@ To install react-native-svg on iOS visit the link referenced above or do the fol Alternatively, you can use [CocoaPods](https://cocoapods.org/) to manage your native (Objective-C and Swift) dependencies: 1. Add RNSVG to your Podfile (with RN 0.60+ autolinking, this is not needed) + ```ruby pod 'RNSVG', :path => '../node_modules/react-native-svg' ``` @@ -206,7 +210,7 @@ Verify that it is still an issue with the latest version as specified in the pre react-native info ``` -If you suspect that you've found a spec conformance bug, then you can test using your component in a react-native-web project by forking this codesandbox, to see how different browsers render the same content: https://codesandbox.io/s/pypn6mn3y7 If any evergreen brower with significant userbase or other svg user agent renders some svg content better, or supports more of the svg and related specs, please open an issue asap. +If you suspect that you've found a spec conformance bug, then you can test using your component in a react-native-web project by forking this codesandbox, to see how different browsers render the same content: If any evergreen brower with significant userbase or other svg user agent renders some svg content better, or supports more of the svg and related specs, please open an issue asap. ### Usage @@ -217,28 +221,28 @@ Here's a simple example. To render output like this: Use the following code: ```jsx -import Svg,{ - Circle, - Ellipse, - G, - Text, - TSpan, - TextPath, - Path, - Polygon, - Polyline, - Line, - Rect, - Use, - Image, - Symbol, - Defs, - LinearGradient, - RadialGradient, - Stop, - ClipPath, - Pattern, - Mask, +import Svg, { + Circle, + Ellipse, + G, + Text, + TSpan, + TextPath, + Path, + Polygon, + Polyline, + Line, + Rect, + Use, + Image, + Symbol, + Defs, + LinearGradient, + RadialGradient, + Stop, + ClipPath, + Pattern, + Mask, } from 'react-native-svg'; /* Use this if you are using Expo @@ -256,7 +260,8 @@ export default class SvgExample extends React.Component { style={[ StyleSheet.absoluteFill, { alignItems: 'center', justifyContent: 'center' }, - ]}> + ]} + > ( ### Use with svg files Try [react-native-svg-transformer](https://github.com/kristerkari/react-native-svg-transformer) to get compile time conversion and cached transformations. -https://github.com/kristerkari/react-native-svg-transformer#installation-and-configuration -https://github.com/kristerkari/react-native-svg-transformer#for-react-native-v057-or-newer--expo-sdk-v3100-or-newer + + `metro.config.js` ```js -const { getDefaultConfig } = require("metro-config"); +const { getDefaultConfig } = require('metro-config'); module.exports = (async () => { const { - resolver: { sourceExts, assetExts } + resolver: { sourceExts, assetExts }, } = await getDefaultConfig(); return { transformer: { - babelTransformerPath: require.resolve("react-native-svg-transformer") + babelTransformerPath: require.resolve('react-native-svg-transformer'), }, resolver: { - assetExts: assetExts.filter(ext => ext !== "svg"), - sourceExts: [...sourceExts, "svg"] - } + assetExts: assetExts.filter(ext => ext !== 'svg'), + sourceExts: [...sourceExts, 'svg'], + }, }; })(); ``` @@ -329,7 +334,7 @@ module.exports = (async () => { Import your .svg file inside a React component: ```jsx -import Logo from "./logo.svg"; +import Logo from './logo.svg'; ``` You can then use your image as a component: @@ -341,31 +346,28 @@ You can then use your image as a component: Alternatively, you can use SvgXml with [babel-plugin-inline-import](https://github.com/credcollective/babel-plugin-inline-import/), but with transforms done at run-time. .babelrc + ```json { "presets": ["module:metro-react-native-babel-preset"], "plugins": [ - ["babel-plugin-inline-import", { - "extensions": [ - ".svg" - ] - }] + [ + "babel-plugin-inline-import", + { + "extensions": [".svg"] + } + ] ] } ``` App.js + ```jsx import * as React from 'react'; import { SvgXml } from 'react-native-svg'; import testSvg from './test.svg'; -export default () => ( - -); +export default () => ; ``` ### Use with xml strings @@ -397,46 +399,42 @@ const xml = ` `; -export default () => ; +export default () => ; ``` ### Common props: -Name | Default | Description -----------------|------------|-------------- -fill | '#000' | The fill prop refers to the color inside the shape. -fillOpacity | 1 | This prop specifies the opacity of the color or the content the current object is filled with. -fillRule | nonzero | The fillRule prop determines what side of a path is inside a shape, which determines how fill will paint the shape, can be `nonzero` or `evenodd` -stroke | 'none' | The stroke prop controls how the outline of a shape appears. -strokeWidth | 1 | The strokeWidth prop specifies the width of the outline on the current object. -strokeOpacity | 1 | The strokeOpacity prop specifies the opacity of the outline on the current object. -strokeLinecap | 'square' | The strokeLinecap prop specifies the shape to be used at the end of open subpaths when they are stroked. Can be either `'butt'`, `'square'` or `'round'`. -strokeLinejoin | 'miter' | The strokeLinejoin prop specifies the shape to be used at the corners of paths or basic shapes when they are stroked. Can be either `'miter'`, `'bevel'` or `'round'`. -strokeDasharray | [] | The strokeDasharray prop controls the pattern of dashes and gaps used to stroke paths. -strokeDashoffset| null | The strokeDashoffset prop specifies the distance into the dash pattern to start the dash. -x | 0 | Translate distance on x-axis. -y | 0 | Translate distance on y-axis. -rotation | 0 | Rotation degree value on the current object. -scale | 1 | Scale value on the current object. -origin | 0, 0 | Transform origin coordinates for the current object. -originX | 0 | Transform originX coordinates for the current object. -originY | 0 | Transform originY coordinates for the current object. - +| Name | Default | Description | +| ---------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| fill | '#000' | The fill prop refers to the color inside the shape. | +| fillOpacity | 1 | This prop specifies the opacity of the color or the content the current object is filled with. | +| fillRule | nonzero | The fillRule prop determines what side of a path is inside a shape, which determines how fill will paint the shape, can be `nonzero` or `evenodd` | +| stroke | 'none' | The stroke prop controls how the outline of a shape appears. | +| strokeWidth | 1 | The strokeWidth prop specifies the width of the outline on the current object. | +| strokeOpacity | 1 | The strokeOpacity prop specifies the opacity of the outline on the current object. | +| strokeLinecap | 'square' | The strokeLinecap prop specifies the shape to be used at the end of open subpaths when they are stroked. Can be either `'butt'`, `'square'` or `'round'`. | +| strokeLinejoin | 'miter' | The strokeLinejoin prop specifies the shape to be used at the corners of paths or basic shapes when they are stroked. Can be either `'miter'`, `'bevel'` or `'round'`. | +| strokeDasharray | [] | The strokeDasharray prop controls the pattern of dashes and gaps used to stroke paths. | +| strokeDashoffset | null | The strokeDashoffset prop specifies the distance into the dash pattern to start the dash. | +| x | 0 | Translate distance on x-axis. | +| y | 0 | Translate distance on y-axis. | +| rotation | 0 | Rotation degree value on the current object. | +| scale | 1 | Scale value on the current object. | +| origin | 0, 0 | Transform origin coordinates for the current object. | +| originX | 0 | Transform originX coordinates for the current object. | +| originY | 0 | Transform originY coordinates for the current object. | ### Supported elements: #### Svg ```jsx - - - - - - + + + + + + ``` @@ -444,83 +442,71 @@ Colors set in the Svg element are inherited by its children: ```jsx - - + + ``` ![Pencil](https://raw.githubusercontent.com/react-native-community/react-native-svg/master/screenShoots/pencil.png) - Code explanation: +Code explanation: - * The fill prop defines the color inside the object. - * The stroke prop defines the color of the line drawn around the object. - * The color prop is a bit special in the sense that it won't color anything by itself, but define a kind of color variable that can be used by children elements. In this example we're defining a "green" color in the Svg element and using it in the second Path element via stroke="currentColor". The "currentColor" is what refers to that "green" value, and it can be used in other props that accept colors too, e.g. fill="currentColor". +- The fill prop defines the color inside the object. +- The stroke prop defines the color of the line drawn around the object. +- The color prop is a bit special in the sense that it won't color anything by itself, but define a kind of color variable that can be used by children elements. In this example we're defining a "green" color in the Svg element and using it in the second Path element via stroke="currentColor". The "currentColor" is what refers to that "green" value, and it can be used in other props that accept colors too, e.g. fill="currentColor". ### Rect The element is used to create a rectangle and variations of a rectangle shape: - ```jsx - - + + ``` ![Rect](https://raw.githubusercontent.com/react-native-community/react-native-svg/master/screenShoots/rect.png) - Code explanation: +Code explanation: - * The width and height props of the element define the height and the width of the rectangle. - * The x prop defines the left position of the rectangle (e.g. x="25" places the rectangle 25 px from the left margin). - * The y prop defines the top position of the rectangle (e.g. y="5" places the rectangle 5 px from the top margin). +- The width and height props of the element define the height and the width of the rectangle. +- The x prop defines the left position of the rectangle (e.g. x="25" places the rectangle 25 px from the left margin). +- The y prop defines the top position of the rectangle (e.g. y="5" places the rectangle 5 px from the top margin). ##### Circle The element is used to create a circle: ```jsx - - + + ``` ![Rect](https://raw.githubusercontent.com/react-native-community/react-native-svg/master/screenShoots/circle.png) - Code explanation: +Code explanation: - * The cx and cy props define the x and y coordinates of the center of the circle. If cx and cy are omitted, the circle's center is set to (0,0) - * The r prop defines the radius of the circle +- The cx and cy props define the x and y coordinates of the center of the circle. If cx and cy are omitted, the circle's center is set to (0,0) +- The r prop defines the radius of the circle #### Ellipse @@ -529,47 +515,35 @@ The element is used to create an ellipse. An ellipse is closely related to a circle. The difference is that an ellipse has an x and a y radius that differs from each other, while a circle has equal x and y radius. ```jsx - - + + ``` + ![Rect](https://raw.githubusercontent.com/react-native-community/react-native-svg/master/screenShoots/ellipse.png) Code explanation: -* The cx prop defines the x coordinate of the center of the ellipse -* The cy prop defines the y coordinate of the center of the ellipse -* The rx prop defines the horizontal radius -* The ry prop defines the vertical radius +- The cx prop defines the x coordinate of the center of the ellipse +- The cy prop defines the y coordinate of the center of the ellipse +- The rx prop defines the horizontal radius +- The ry prop defines the vertical radius #### Line The element is an SVG basic shape, used to create a line connecting two points. ```jsx - - + + ``` @@ -577,26 +551,23 @@ The element is an SVG basic shape, used to create a line connecting two p Code explanation: -* The x1 prop defines the start of the line on the x-axis. -* The y1 prop defines the start of the line on the y-axis. -* The x2 prop defines the end of the line on the x-axis. -* The y2 prop defines the end of the line on the y-axis. +- The x1 prop defines the start of the line on the x-axis. +- The y1 prop defines the start of the line on the y-axis. +- The x2 prop defines the end of the line on the x-axis. +- The y2 prop defines the end of the line on the y-axis. #### Polygon The element is used to create a graphic that contains at least three sides. Polygons are made of straight lines, and the shape is "closed" (all the lines connect up). ```jsx - - + + ``` @@ -604,23 +575,20 @@ The element is used to create a graphic that contains at least three s Code explanation: -* The points prop defines the x and y coordinates for each corner of the polygon +- The points prop defines the x and y coordinates for each corner of the polygon #### Polyline The element is used to create any shape that consists of only straight lines: ```jsx - - + + ``` @@ -628,7 +596,7 @@ The element is used to create any shape that consists of only straigh Code explanation: -* The points prop defines the x and y coordinates for each point of the polyline +- The points prop defines the x and y coordinates for each point of the polyline #### Path @@ -636,53 +604,48 @@ The element is used to define a path. The following commands are available for path data: - * M = moveto - * L = lineto - * H = horizontal lineto - * V = vertical lineto - * C = curveto - * S = smooth curveto - * Q = quadratic Bézier curve - * T = smooth quadratic Bézier curveto - * A = elliptical Arc - * Z = closepath +- M = moveto +- L = lineto +- H = horizontal lineto +- V = vertical lineto +- C = curveto +- S = smooth curveto +- Q = quadratic Bézier curve +- T = smooth quadratic Bézier curveto +- A = elliptical Arc +- Z = closepath `Note:` All of the commands above can also be expressed with lower letters. Capital letters means absolutely positioned, lower cases means relatively positioned. See [Path document of SVG](https://www.w3.org/TR/SVG/paths.html) to know parameters for each command. ```jsx - - + + ``` ![Rect](https://raw.githubusercontent.com/react-native-community/react-native-svg/master/screenShoots/path.png) - #### Text The element is used to define text. ```jsx - - STROKED TEXT + + + STROKED TEXT + ``` @@ -693,24 +656,29 @@ The element is used to define text. The element is used to draw multiple lines of text in SVG. Rather than having to position each line of text absolutely, the element makes it possible to position a line of text relatively to the previous line of text. ```jsx - - - tspan line 1 - tspan line 2 - tspan line 3 - - - 12345 - - 6 - 7 - - 89a - - delta on text + + + tspan line 1 + + tspan line 2 + + + tspan line 3 + + + + 12345 + + 6 + 7 + + + 89a + + + + delta on text + ``` @@ -721,33 +689,21 @@ The element is used to draw multiple lines of text in SVG. Rather than h In addition to text drawn in a straight line, SVG also includes the ability to place text along the shape of a element. To specify that a block of text is to be rendered along the shape of a , include the given text within a element which includes an href attribute with a reference to a element. ```jsx - - - - - - - - We go up and down, - then up again - - - - + + + + + + + + We go up and down, + + then up again + + + + + ``` @@ -758,42 +714,19 @@ In addition to text drawn in a straight line, SVG also includes the ability to p The element is a container used to group other SVG elements. Transformations applied to the g element are performed on all of its child elements, and any of its props are inherited by its child elements. It can also group multiple elements to be referenced later with the [<Use />](#use) element. ```jsx - - - + + + - + - - Text grouped with shapes - + + Text grouped with shapes + + ``` + ![G](https://raw.githubusercontent.com/react-native-community/react-native-svg/master/screenShoots/g.png) #### Use @@ -801,21 +734,18 @@ The element is a container used to group other SVG elements. Transformations The element can reuse an SVG shape from elsewhere in the SVG document, including elements and elements. The reused shape can be defined inside the [<Defs>](#defs) element (which makes the shape invisible until used) or outside. ```jsx - - - - - - - - - - - - + + + + + + + + + + + + ``` @@ -827,40 +757,27 @@ The element specifies where to show the reused shapes via its x and y prop ![use](https://raw.githubusercontent.com/react-native-community/react-native-svg/master/screenShoots/use.png) - #### Symbol The SVG element is used to define reusable symbols. The shapes nested inside a are not displayed unless referenced by a element. ```jsx - - - - - + + + + + - - - + + + ``` @@ -875,47 +792,35 @@ The element is used to embed definitions that can be reused inside an SVG The element allows a raster image to be included in an Svg componenet. ```jsx - - - - - - - - + + + + + + + + - - HOGWARTS + + + HOGWARTS + ``` @@ -926,48 +831,48 @@ The element allows a raster image to be included in an Svg componenet. The SVG element defines a clipping path. A clipping path is used/referenced using the clipPath property ```jsx - + + + + + + + + + + + + + Q + + + + + - - - - - - - - - - - - Q - - - - + height="100" + fill="url(#grad)" + clipPath="url(#clip)" + /> ``` @@ -980,42 +885,41 @@ The element must be nested within a [<Defs>](#defs) tag. Linear gradients can be defined as horizontal, vertical or angular gradients: - * Horizontal gradients are created when y1 and y2 are equal and x1 and x2 differ - * Vertical gradients are created when x1 and x2 are equal and y1 and y2 differ - * Angular gradients are created when x1 and x2 differ and y1 and y2 differ +- Horizontal gradients are created when y1 and y2 are equal and x1 and x2 differ +- Vertical gradients are created when x1 and x2 are equal and y1 and y2 differ +- Angular gradients are created when x1 and x2 differ and y1 and y2 differ ```jsx - - - - - - - - + + + + + + + + ``` Code explanation: - * The id prop of the tag defines a unique name for the gradient - * The x1, x2, y1,y2 props of the tag define the start and end position of the gradient - * The color range for a gradient can be composed of two or more colors. Each color is specified with a tag. The offset prop is used to define where the gradient color begin and end - * The fill prop links the ellipse element to the gradient +- The id prop of the tag defines a unique name for the gradient +- The x1, x2, y1,y2 props of the tag define the start and end position of the gradient +- The color range for a gradient can be composed of two or more colors. Each color is specified with a tag. The offset prop is used to define where the gradient color begin and end +- The fill prop links the ellipse element to the gradient ![LinearGradient](https://raw.githubusercontent.com/react-native-community/react-native-svg/master/screenShoots/lineargradient.png) -*NOTICE:* +_NOTICE:_ LinearGradient also supports percentage as prop: + ```jsx - - + + ``` + This result is same as the example before. But it's recommend to use exact number instead; it has performance advantages over using percentages. #### RadialGradient @@ -1023,40 +927,37 @@ This result is same as the example before. But it's recommend to use exact numbe The element is used to define a radial gradient. The element must be nested within a [<Defs>](#defs) tag. The [<Defs>](#defs) tag is short for definitions and contains definition of special elements (such as gradients). ```jsx - - - - - - - - + + + + + + + + ``` Code explanation: - * The id prop of the tag defines a unique name for the gradient - * The cx, cy and r props define the outermost circle and the fx and fy define the innermost circle - * The color range for a gradient can be composed of two or more colors. Each color is specified with a tag. The offset prop is used to define where the gradient color begin and end - * The fill prop links the ellipse element to the gradient +- The id prop of the tag defines a unique name for the gradient +- The cx, cy and r props define the outermost circle and the fx and fy define the innermost circle +- The color range for a gradient can be composed of two or more colors. Each color is specified with a tag. The offset prop is used to define where the gradient color begin and end +- The fill prop links the ellipse element to the gradient ![RadialGradient](https://raw.githubusercontent.com/react-native-community/react-native-svg/master/screenShoots/radialgradient.png) #### Mask - In SVG, you can specify that any other graphics object or ‘G’ element can be used as an alpha mask for compositing the current object into the background. A mask is defined with a ‘Mask’ element. A mask is used/referenced using the ‘mask’ property. @@ -1065,55 +966,50 @@ A ‘Mask’ can contain any graphical elements or container elements such as a The element must be nested within a [<Defs>](#defs) tag. The [<Defs>](#defs) tag is short for definitions and contains definition of special elements (such as gradients). -https://www.w3.org/TR/SVG11/images/masking/mask01.svg + + ```jsx - - - - - - - - - - - Masked text - - - - - - + + + + + + + + + + + Masked text + + + + + + ``` -Code explanation: https://www.w3.org/TR/SVG11/masking.html#MaskElement +Code explanation: ![Mask](https://www.w3.org/TR/SVG11/images/masking/mask01.svg) @@ -1122,43 +1018,37 @@ Code explanation: https://www.w3.org/TR/SVG11/masking.html#MaskElement A pattern is used to fill or stroke an object using a pre-defined graphic object which can be replicated ("tiled") at fixed intervals in x and y to cover the areas to be painted. Patterns are defined using a ‘pattern’ element and then referenced by properties ‘fill’ and ‘stroke’ on a given graphics element to indicate that the given element shall be filled or stroked with the referenced pattern. The element must be nested within a [<Defs>](#defs) tag. The [<Defs>](#defs) tag is short for definitions and contains definition of special elements (such as gradients). -https://www.w3.org/TR/SVG11/images/pservers/pattern01.svg + + ```jsx - - - - - - - - - + + + + + + + + + ``` -Code explanation: https://www.w3.org/TR/SVG11/pservers.html#PatternElement +Code explanation: ![Pattern](https://www.w3.org/TR/SVG11/images/pservers/pattern01.svg) @@ -1166,24 +1056,24 @@ Code explanation: https://www.w3.org/TR/SVG11/pservers.html#PatternElement Touch events are supported in react-native-svg. These include: - - `disabled` - - `onPress` - - `onPressIn` - - `onPressOut` - - `onLongPress` - - `delayPressIn` - - `delayPressOut` - - `delayLongPress` +- `disabled` +- `onPress` +- `onPressIn` +- `onPressOut` +- `onLongPress` +- `delayPressIn` +- `delayPressOut` +- `delayLongPress` You can use these events to provide interactivity to your react-native-svg components. ```jsx alert('Press on Circle')} + cx="50%" + cy="50%" + r="38%" + fill="red" + onPress={() => alert('Press on Circle')} /> ``` @@ -1204,11 +1094,12 @@ yarn ``` - ### TODO: + 1. Add Native methods for elements. 2. Marker element. 3. Filters ### Known issues: + 1. Unable to apply focus point of RadialGradient on Android. diff --git a/elements/ClipPath.js b/elements/ClipPath.js index 15a1807f..3a1f8abe 100644 --- a/elements/ClipPath.js +++ b/elements/ClipPath.js @@ -10,11 +10,7 @@ export default class ClipPath extends Shape { const { props } = this; const { id, children } = props; return ( - + {children} ); diff --git a/elements/Symbol.js b/elements/Symbol.js index ec087a21..342f6ee7 100644 --- a/elements/Symbol.js +++ b/elements/Symbol.js @@ -10,11 +10,7 @@ export default class Symbol extends Shape { const { props } = this; const { id, children } = props; return ( - + {children} ); diff --git a/index.js b/index.js index e597ca5a..6161f54d 100644 --- a/index.js +++ b/index.js @@ -20,14 +20,7 @@ import Stop from './elements/Stop'; import ClipPath from './elements/ClipPath'; import Pattern from './elements/Pattern'; import Mask from './elements/Mask'; -import { - parse, - SvgAst, - SvgFromUri, - SvgFromXml, - SvgUri, - SvgXml, -} from './xml' +import { parse, SvgAst, SvgFromUri, SvgFromXml, SvgUri, SvgXml } from './xml'; export { Svg, diff --git a/lib/extract/extractResponder.js b/lib/extract/extractResponder.js index c60d4529..07423bd4 100644 --- a/lib/extract/extractResponder.js +++ b/lib/extract/extractResponder.js @@ -48,7 +48,8 @@ export default function extractResponder(props, ref) { o.onResponderRelease = ref.touchableHandleResponderRelease; o.onResponderTerminate = ref.touchableHandleResponderTerminate; o.onStartShouldSetResponder = ref.touchableHandleStartShouldSetResponder; - o.onResponderTerminationRequest = ref.touchableHandleResponderTerminationRequest; + o.onResponderTerminationRequest = + ref.touchableHandleResponderTerminationRequest; } if (responsible) { diff --git a/lib/extract/extractTransform.js b/lib/extract/extractTransform.js index 17dd0c44..e9f36769 100644 --- a/lib/extract/extractTransform.js +++ b/lib/extract/extractTransform.js @@ -3,7 +3,15 @@ import { parse } from './transform'; function appendTransformProps(props) { const { - x, y, originX, originY, scaleX, scaleY, rotation, skewX, skewY, + x, + y, + originX, + originY, + scaleX, + scaleY, + rotation, + skewX, + skewY, } = props; appendTransform( x + originX, @@ -55,12 +63,21 @@ function universal2axis(universal, axisX, axisY, defaultValue) { export function props2transform(props) { const { - translate, translateX, translateY, - origin, originX, originY, - scale, scaleX, scaleY, - skew, skewX, skewY, + translate, + translateX, + translateY, + origin, + originX, + originY, + scale, + scaleX, + scaleY, + skew, + skewX, + skewY, rotation, - x, y, + x, + y, } = props; const tr = universal2axis(translate, translateX || x, translateY || y); diff --git a/package-lock.json b/package-lock.json index cc4a39f2..8eb81fad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -248,15 +248,15 @@ } }, "acorn": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", - "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", + "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", "dev": true }, "acorn-jsx": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", - "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", + "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", "dev": true }, "ajv": { @@ -318,17 +318,28 @@ "dev": true }, "babel-eslint": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.2.tgz", - "integrity": "sha512-UdsurWPtgiPgpJ06ryUnuaSXC2s0WoSZnQmEpbAH65XZSdwowgN5MvyP7e88nW07FYXv72erVtpBkxyDVKhH1Q==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.3.tgz", + "integrity": "sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/parser": "^7.0.0", "@babel/traverse": "^7.0.0", "@babel/types": "^7.0.0", - "eslint-scope": "3.7.1", - "eslint-visitor-keys": "^1.0.0" + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } } }, "balanced-match": { @@ -490,9 +501,9 @@ "dev": true }, "eslint": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.1.0.tgz", - "integrity": "sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.2.2.tgz", + "integrity": "sha512-mf0elOkxHbdyGX1IJEUsNBzCDdyoUgljF3rRlgfyYh0pwGnreLc0jjD6ZuleOibjmnUWZLY2eXwSooeOgGJ2jw==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -502,9 +513,9 @@ "debug": "^4.0.1", "doctrine": "^3.0.0", "eslint-scope": "^5.0.0", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^6.0.0", + "eslint-utils": "^1.4.2", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.1", "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", @@ -553,6 +564,21 @@ "estraverse": "^4.1.1" } }, + "eslint-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", + "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.0.0" + } + }, + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true + }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", @@ -602,9 +628,9 @@ } }, "eslint-plugin-react": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.14.2.tgz", - "integrity": "sha512-jZdnKe3ip7FQOdjxks9XPN0pjUKZYq48OggNMd16Sk+8VXx6JOvXmlElxROCgp7tiUsTsze3jd78s/9AFJP2mA==", + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz", + "integrity": "sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA==", "dev": true, "requires": { "array-includes": "^3.0.3", @@ -616,17 +642,6 @@ "object.values": "^1.1.0", "prop-types": "^15.7.2", "resolve": "^1.10.1" - }, - "dependencies": { - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - } } }, "eslint-plugin-react-hooks": { @@ -661,9 +676,9 @@ } }, "eslint-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.0.tgz", - "integrity": "sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", + "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", "dev": true, "requires": { "eslint-visitor-keys": "^1.0.0" @@ -676,14 +691,22 @@ "dev": true }, "espree": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.0.0.tgz", - "integrity": "sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", + "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", "dev": true, "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" + "acorn": "^7.0.0", + "acorn-jsx": "^5.0.2", + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true + } } }, "esprima": { @@ -908,9 +931,9 @@ "dev": true }, "inquirer": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz", - "integrity": "sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", "dev": true, "requires": { "ansi-escapes": "^3.2.0", @@ -1302,15 +1325,14 @@ "dev": true }, "react": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", - "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.9.0.tgz", + "integrity": "sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w==", "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.13.6" + "prop-types": "^15.6.2" } }, "react-is": { @@ -1383,16 +1405,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "scheduler": { - "version": "0.13.6", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", - "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", @@ -1497,9 +1509,9 @@ } }, "table": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.4.tgz", - "integrity": "sha512-IIfEAUx5QlODLblLrGTTLJA7Tk0iLSGBvgY8essPRVNGHAzThujww1YqHLs6h3HfTg55h++RzLHH5Xw/rfv+mg==", + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", "dev": true, "requires": { "ajv": "^6.10.2", @@ -1588,9 +1600,9 @@ } }, "v8-compile-cache": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", - "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", "dev": true }, "which": { diff --git a/package.json b/package.json index 97f7656f..4625c79f 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ ], "scripts": { "lint": "eslint ./", - "format": "prettier index.js index.web.js './{elements,lib}/*.js' './lib/extract/e*.js' --write", + "format": "prettier index.js index.web.js xml.js README.md './{elements,lib}/*.js' './lib/extract/e*.js' --write", "peg": "pegjs -o ./lib/extract/transform.js ./lib/extract/transform.peg" }, "peerDependencies": { @@ -31,13 +31,13 @@ "dependencies": {}, "devDependencies": { "@react-native-community/eslint-config": "^0.0.5", - "babel-eslint": "^10.0.2", - "eslint": "^6.1.0", + "babel-eslint": "^10.0.3", + "eslint": "^6.2.2", "eslint-plugin-prettier": "^3.1.0", - "eslint-plugin-react": "^7.14.2", + "eslint-plugin-react": "^7.14.3", "pegjs": "^0.10.0", "prettier": "^1.18.2", - "react": "^16.8.6" + "react": "^16.9.0" }, "nativePackage": true } diff --git a/xml.js b/xml.js index 5ff0199c..94a4037e 100644 --- a/xml.js +++ b/xml.js @@ -1,4 +1,4 @@ -import React, { Component, useState, useEffect, useMemo } from "react"; +import React, { Component, useState, useEffect, useMemo } from 'react'; import Rect from './elements/Rect'; import Circle from './elements/Circle'; import Ellipse from './elements/Ellipse'; @@ -44,7 +44,7 @@ export const tags = { stop: Stop, clipPath: ClipPath, pattern: Pattern, - mask: Mask + mask: Mask, }; export function SvgAst({ ast, override }) { @@ -138,22 +138,22 @@ const camelCase = phrase => phrase.replace(/-([a-z])/g, upperCase); export function getStyle(string) { const style = {}; - const declarations = string.split(";"); + const declarations = string.split(';'); const { length } = declarations; for (let i = 0; i < length; i++) { const declaration = declarations[i]; if (declaration.length !== 0) { - const split = declaration.split(":"); + const split = declaration.split(':'); const property = split[0]; const value = split[1]; - style[camelCase(property.trim())] = value.trim(); - } + style[camelCase(property.trim())] = value.trim(); + } } return style; } export function astToReact(child, i) { - if (typeof child === "object") { + if (typeof child === 'object') { const { Tag, props, children } = child; return ( @@ -167,7 +167,7 @@ export function astToReact(child, i) { // slimmed down parser based on https://github.com/Rich-Harris/svg-parser function locate(source, search) { - const lines = source.split("\n"); + const lines = source.split('\n'); const nLines = lines.length; for (let line = 0; line < nLines; line++) { const { length } = lines[line]; @@ -181,11 +181,13 @@ function locate(source, search) { const validNameCharacters = /[a-zA-Z0-9:_-]/; const whitespace = /[\s\t\r\n]/; -const quotemark = /['"]/; +const quotemarks = /['"]/; function repeat(str, i) { - let result = ""; - while (i--) result += str; + let result = ''; + while (i--) { + result += str; + } return result; } @@ -201,26 +203,26 @@ export function parse(source) { const { line, column } = locate(source, i); const before = source .slice(0, i) - .replace(/^\t+/, match => repeat(" ", match.length)); + .replace(/^\t+/, match => repeat(' ', match.length)); const beforeLine = /(^|\n).*$/.exec(before)[0]; const after = source.slice(i); const afterLine = /.*(\n|$)/.exec(after)[0]; const snippet = `${beforeLine}${afterLine}\n${repeat( - " ", - beforeLine.length + ' ', + beforeLine.length, )}^`; throw new Error( - `${message} (${line}:${column}). If this is valid SVG, it's probably a bug. Please raise an issue\n\n${snippet}` + `${message} (${line}:${column}). If this is valid SVG, it's probably a bug. Please raise an issue\n\n${snippet}`, ); } function metadata() { while ( i + 1 < length && - (source[i] !== "<" || !validNameCharacters.test(source[i + 1])) - ) { + (source[i] !== '<' || !validNameCharacters.test(source[i + 1])) + ) { i++; } @@ -228,9 +230,9 @@ export function parse(source) { } function neutral() { - let text = ""; + let text = ''; let char; - while (i < length && (char = source[i]) !== "<") { + while (i < length && (char = source[i]) !== '<') { text += char; i += 1; } @@ -239,7 +241,7 @@ export function parse(source) { children.push(text); } - if (source[i] === "<") { + if (source[i] === '<') { return openingTag; } @@ -249,16 +251,26 @@ export function parse(source) { function openingTag() { const char = source[i]; - if (char === "?") return neutral; // ") { - error("Expected >"); + if (source[i] !== '>') { + error('Expected >'); } if (!selfClosing) { @@ -303,16 +315,20 @@ export function parse(source) { } function comment() { - const index = source.indexOf("-->", i); - if (!~index) error("expected -->"); + const index = source.indexOf('-->', i); + if (!~index) { + error('expected -->'); + } i = index + 2; return neutral; } function cdata() { - const index = source.indexOf("]]>", i); - if (!~index) error("expected ]]>"); + const index = source.indexOf(']]>', i); + if (!~index) { + error('expected ]]>'); + } i = index + 2; return neutral; @@ -321,18 +337,18 @@ export function parse(source) { function closingTag() { const tag = getName(); - if (!tag) error("Expected tag name"); + if (!tag) { + error('Expected tag name'); + } if (tag !== currentElement.tag) { error( - `Expected closing tag to match opening tag <${ - currentElement.tag - }>` + `Expected closing tag to match opening tag <${currentElement.tag}>`, ); } - if (source[i] !== ">") { - error("Expected >"); + if (source[i] !== '>') { + error('Expected >'); } stack.pop(); @@ -345,7 +361,7 @@ export function parse(source) { } function getName() { - let name = ""; + let name = ''; let char; while (i < length && validNameCharacters.test((char = source[i]))) { name += char; @@ -357,21 +373,27 @@ export function parse(source) { function getAttributes(props) { while (i < length) { - if (!whitespace.test(source[i])) return; + if (!whitespace.test(source[i])) { + return; + } allowSpaces(); const name = getName(); - if (!name) return; + if (!name) { + return; + } let value = true; allowSpaces(); - if (source[i] === "=") { + if (source[i] === '=') { i += 1; allowSpaces(); value = getAttributeValue(); - if (!isNaN(value) && value.trim() !== "") value = +value; + if (!isNaN(value) && value.trim() !== '') { + value = +value; + } } props[camelCase(name)] = value; @@ -379,16 +401,16 @@ export function parse(source) { } function getAttributeValue() { - return quotemark.test(source[i]) + return quotemarks.test(source[i]) ? getQuotedAttributeValue() : getUnquotedAttributeValue(); } function getUnquotedAttributeValue() { - let value = ""; + let value = ''; do { const char = source[i]; - if (char === " " || char === ">" || char === "/") { + if (char === ' ' || char === '>' || char === '/') { return value; } @@ -402,7 +424,7 @@ export function parse(source) { function getQuotedAttributeValue() { const quotemark = source[i++]; - let value = ""; + let value = ''; let escaped = false; while (i < length) { @@ -411,7 +433,7 @@ export function parse(source) { return value; } - if (char === "\\" && !escaped) { + if (char === '\\' && !escaped) { escaped = true; } @@ -421,18 +443,22 @@ export function parse(source) { } function allowSpaces() { - while (i < length && whitespace.test(source[i])) i += 1; + while (i < length && whitespace.test(source[i])) { + i += 1; + } } let i = 0; while (i < length) { - if (!state) error("Unexpected character"); + if (!state) { + error('Unexpected character'); + } state = state(); i += 1; } if (state !== neutral) { - error("Unexpected end of input"); + error('Unexpected end of input'); } root.children = root.children.map(astToReact); diff --git a/yarn.lock b/yarn.lock index b1b87b5a..bc162c6b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -155,15 +155,15 @@ lodash.unescape "4.0.1" semver "5.5.0" -acorn-jsx@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" - integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== +acorn-jsx@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.2.tgz#84b68ea44b373c4f8686023a551f61a21b7c4a4f" + integrity sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw== -acorn@^6.0.7: - version "6.2.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.0.tgz#67f0da2fc339d6cfb5d6fb244fd449f33cd8bbe3" - integrity sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw== +acorn@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.0.0.tgz#26b8d1cd9a9b700350b71c0905546f64d1284e7a" + integrity sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ== ajv@^6.10.0, ajv@^6.10.2: version "6.10.2" @@ -229,17 +229,17 @@ babel-eslint@10.0.1: eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" -babel-eslint@^10.0.2: - version "10.0.2" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.2.tgz#182d5ac204579ff0881684b040560fdcc1558456" - integrity sha512-UdsurWPtgiPgpJ06ryUnuaSXC2s0WoSZnQmEpbAH65XZSdwowgN5MvyP7e88nW07FYXv72erVtpBkxyDVKhH1Q== +babel-eslint@^10.0.3: + version "10.0.3" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.3.tgz#81a2c669be0f205e19462fed2482d33e4687a88a" + integrity sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA== dependencies: "@babel/code-frame" "^7.0.0" "@babel/parser" "^7.0.0" "@babel/traverse" "^7.0.0" "@babel/types" "^7.0.0" - eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" + resolve "^1.12.0" balanced-match@^1.0.0: version "1.0.0" @@ -442,10 +442,10 @@ eslint-plugin-react@7.12.4: prop-types "^15.6.2" resolve "^1.9.0" -eslint-plugin-react@^7.14.2: - version "7.14.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.2.tgz#94c193cc77a899ac0ecbb2766fbef88685b7ecc1" - integrity sha512-jZdnKe3ip7FQOdjxks9XPN0pjUKZYq48OggNMd16Sk+8VXx6JOvXmlElxROCgp7tiUsTsze3jd78s/9AFJP2mA== +eslint-plugin-react@^7.14.3: + version "7.14.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz#911030dd7e98ba49e1b2208599571846a66bdf13" + integrity sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA== dependencies: array-includes "^3.0.3" doctrine "^2.1.0" @@ -488,15 +488,27 @@ eslint-utils@^1.3.1: dependencies: eslint-visitor-keys "^1.0.0" +eslint-utils@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab" + integrity sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q== + dependencies: + eslint-visitor-keys "^1.0.0" + eslint-visitor-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== -eslint@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.1.0.tgz#06438a4a278b1d84fb107d24eaaa35471986e646" - integrity sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ== +eslint-visitor-keys@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" + integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== + +eslint@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.2.2.tgz#03298280e7750d81fcd31431f3d333e43d93f24f" + integrity sha512-mf0elOkxHbdyGX1IJEUsNBzCDdyoUgljF3rRlgfyYh0pwGnreLc0jjD6ZuleOibjmnUWZLY2eXwSooeOgGJ2jw== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -505,9 +517,9 @@ eslint@^6.1.0: debug "^4.0.1" doctrine "^3.0.0" eslint-scope "^5.0.0" - eslint-utils "^1.3.1" - eslint-visitor-keys "^1.0.0" - espree "^6.0.0" + eslint-utils "^1.4.2" + eslint-visitor-keys "^1.1.0" + espree "^6.1.1" esquery "^1.0.1" esutils "^2.0.2" file-entry-cache "^5.0.1" @@ -536,14 +548,14 @@ eslint@^6.1.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.0.0.tgz#716fc1f5a245ef5b9a7fdb1d7b0d3f02322e75f6" - integrity sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q== +espree@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.1.tgz#7f80e5f7257fc47db450022d723e356daeb1e5de" + integrity sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ== dependencies: - acorn "^6.0.7" - acorn-jsx "^5.0.0" - eslint-visitor-keys "^1.0.0" + acorn "^7.0.0" + acorn-jsx "^5.0.2" + eslint-visitor-keys "^1.1.0" esprima@^4.0.0: version "4.0.1" @@ -1074,15 +1086,14 @@ react-is@^16.8.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA== -react@^16.8.6: - version "16.8.6" - resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe" - integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw== +react@^16.9.0: + version "16.9.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.9.0.tgz#40ba2f9af13bc1a38d75dbf2f4359a5185c4f7aa" + integrity sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.13.6" regexpp@^2.0.1: version "2.0.1" @@ -1101,6 +1112,13 @@ resolve@^1.10.1, resolve@^1.9.0: dependencies: path-parse "^1.0.6" +resolve@^1.12.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6" + integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w== + dependencies: + path-parse "^1.0.6" + restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -1135,14 +1153,6 @@ rxjs@^6.4.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -scheduler@^0.13.6: - version "0.13.6" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889" - integrity sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - semver@5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"