diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 00000000..b45236f1
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,32 @@
+---
+name: Publish to NPM
+
+on:
+ release:
+ types: [created]
+jobs:
+ npm_publish:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ # Setup .npmrc file to publish to npm
+ - uses: actions/setup-node@v2
+ with:
+ node-version: "14.x"
+ registry-url: "https://registry.npmjs.org"
+ - run: npm ci
+ - run: npm publish
+ env:
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
+ deploy_storybook:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ # Setup .npmrc file to publish to npm
+ - uses: actions/setup-node@v2
+ with:
+ node-version: "14.x"
+ registry-url: "https://registry.npmjs.org"
+ - run: npm ci
+ - run: npm run build-storybook
+ - run: npm run deploy-storybook
diff --git a/README.md b/README.md
index f920cbc9..fd00d7ef 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,20 @@ It aims to provide high-level components that require minial configuration to pr
`yarn add @chart-it/react-d3`
+# Getting Started
+
+The best way to get started is to take a look at some of the examples in this Storybook https://ipwright83.github.io/chart-it/?path=/story/introduction--page.
+
+Here is an example of a very basic Scatter chart
+
+```
+
+
+
+
+
+```
+
## Run Locally
Clone the project
diff --git a/config/jest/setupTests.js b/config/jest/setupTests.js
index 75c1a621..2dde7968 100644
--- a/config/jest/setupTests.js
+++ b/config/jest/setupTests.js
@@ -11,3 +11,6 @@ window.crypto = {
return nodeCrypto.randomFillSync(buffer);
},
};
+
+// Dump debug messages to the void
+console.debug = () => {};
diff --git a/package-lock.json b/package-lock.json
index 7da759d5..3edfad09 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "@chart-it/react-d3",
- "version": "0.1.4",
+ "version": "0.1.6",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -2581,6 +2581,141 @@
}
}
},
+ "@mapbox/node-pre-gyp": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.6.tgz",
+ "integrity": "sha512-qK1ECws8UxuPqOA8F5LFD90vyVU33W7N3hGfgsOVfrJaRVc8McC3JClTDHpeSbL9CBrOHly/4GsNPAvIgNZE+g==",
+ "dev": true,
+ "requires": {
+ "detect-libc": "^1.0.3",
+ "https-proxy-agent": "^5.0.0",
+ "make-dir": "^3.1.0",
+ "node-fetch": "^2.6.5",
+ "nopt": "^5.0.0",
+ "npmlog": "^5.0.1",
+ "rimraf": "^3.0.2",
+ "semver": "^7.3.5",
+ "tar": "^6.1.11"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "are-we-there-yet": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
+ "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
+ "dev": true,
+ "requires": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^3.6.0"
+ }
+ },
+ "gauge": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.1.tgz",
+ "integrity": "sha512-6STz6KdQgxO4S/ko+AbjlFGGdGcknluoqU+79GOFCDqqyYj5OanQf9AjxwN0jCidtT+ziPMmPSt9E4hfQ0CwIQ==",
+ "dev": true,
+ "requires": {
+ "aproba": "^1.0.3 || ^2.0.0",
+ "color-support": "^1.1.2",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.1",
+ "object-assign": "^4.1.1",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1 || ^2.0.0",
+ "strip-ansi": "^3.0.1 || ^4.0.0",
+ "wide-align": "^1.1.2"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "requires": {
+ "semver": "^6.0.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "npmlog": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
+ "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
+ "dev": true,
+ "requires": {
+ "are-we-there-yet": "^2.0.0",
+ "console-control-strings": "^1.1.0",
+ "gauge": "^3.0.0",
+ "set-blocking": "^2.0.0"
+ }
+ },
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
"@mdx-js/loader": {
"version": "1.6.22",
"resolved": "https://registry.npmjs.org/@mdx-js/loader/-/loader-1.6.22.tgz",
@@ -4227,6 +4362,107 @@
}
}
},
+ "@testing-library/dom": {
+ "version": "8.11.0",
+ "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.11.0.tgz",
+ "integrity": "sha512-8Ay4UDiMlB5YWy+ZvCeRyFFofs53ebxrWnOFvCoM1HpMAX4cHyuSrCuIM9l2lVuUWUt+Gr3loz/nCwdrnG6ShQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/runtime": "^7.12.5",
+ "@types/aria-query": "^4.2.0",
+ "aria-query": "^5.0.0",
+ "chalk": "^4.1.0",
+ "dom-accessibility-api": "^0.5.9",
+ "lz-string": "^1.4.4",
+ "pretty-format": "^27.0.2"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "27.2.5",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz",
+ "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "requires": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "27.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz",
+ "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.2.5",
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ }
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@testing-library/react": {
+ "version": "12.1.2",
+ "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.2.tgz",
+ "integrity": "sha512-ihQiEOklNyHIpo2Y8FREkyD1QAea054U0MVbwH1m8N9TxeFz+KoJ9LkqoKqJlzx2JDm56DVwaJ1r36JYxZM05g==",
+ "dev": true,
+ "requires": {
+ "@babel/runtime": "^7.12.5",
+ "@testing-library/dom": "^8.0.0"
+ }
+ },
"@tootallnate/once": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
@@ -4239,6 +4475,12 @@
"integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
"dev": true
},
+ "@types/aria-query": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz",
+ "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==",
+ "dev": true
+ },
"@types/babel__core": {
"version": "7.1.16",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz",
@@ -5205,6 +5447,12 @@
"integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==",
"dev": true
},
+ "abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+ "dev": true
+ },
"accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
@@ -5426,6 +5674,12 @@
"sprintf-js": "~1.0.2"
}
},
+ "aria-query": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz",
+ "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==",
+ "dev": true
+ },
"arr-diff": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
@@ -6671,6 +6925,17 @@
"integrity": "sha512-YzBnspggWV5hep1m9Z6sZVLOt7vrju8xWooFAgN6BA5qvy98qPAPb7vNUzypFaoh2pb3vlfzbDO8tB57UPGbtw==",
"dev": true
},
+ "canvas": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.8.0.tgz",
+ "integrity": "sha512-gLTi17X8WY9Cf5GZ2Yns8T5lfBOcGgFehDFb+JQwDqdOoBOcECS9ZWMEAqMSVcMYwXD659J8NyzjRY/2aE+C2Q==",
+ "dev": true,
+ "requires": {
+ "@mapbox/node-pre-gyp": "^1.0.0",
+ "nan": "^2.14.0",
+ "simple-get": "^3.0.3"
+ }
+ },
"capture-exit": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
@@ -6955,6 +7220,12 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
+ "color-support": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
+ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+ "dev": true
+ },
"colord": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/colord/-/colord-2.8.0.tgz",
@@ -8194,6 +8465,15 @@
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
"dev": true
},
+ "decompress-response": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
+ "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
+ "dev": true,
+ "requires": {
+ "mimic-response": "^2.0.0"
+ }
+ },
"dedent": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
@@ -8322,6 +8602,12 @@
"repeat-string": "^1.5.4"
}
},
+ "detect-libc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+ "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
+ "dev": true
+ },
"detect-newline": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
@@ -8398,6 +8684,12 @@
"esutils": "^2.0.2"
}
},
+ "dom-accessibility-api": {
+ "version": "0.5.10",
+ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.10.tgz",
+ "integrity": "sha512-Xu9mD0UjrJisTmv7lmVSDMagQcU9R5hwAbxsaAE/35XPnPLJobbuREfV/rraiSaEj/UOvgrzQs66zyTWTlyd+g==",
+ "dev": true
+ },
"dom-converter": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
@@ -8633,11 +8925,6 @@
"hoist-non-react-statics": "^3.3.0"
}
},
- "emptyfunction": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/emptyfunction/-/emptyfunction-1.0.0.tgz",
- "integrity": "sha1-9aHmg3GBSMK5gdU+cAQ5OPO430o="
- },
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@@ -12029,6 +12316,12 @@
}
}
},
+ "jest-canvas-snapshot-serializer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/jest-canvas-snapshot-serializer/-/jest-canvas-snapshot-serializer-1.0.1.tgz",
+ "integrity": "sha512-JOJkLhNninP1PltYJOuw8brUbobTQVUq9Lx0JYaTcUxGpz7OnO63EaUA7RHaEHASaglW/fizZ0dR8PEKt6Gnag==",
+ "dev": true
+ },
"jest-changed-files": {
"version": "27.3.0",
"resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.3.0.tgz",
@@ -12253,6 +12546,32 @@
"picomatch": "^2.2.3"
}
},
+ "pretty-format": {
+ "version": "27.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz",
+ "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.2.5",
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ }
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -12357,6 +12676,32 @@
"picomatch": "^2.2.3"
}
},
+ "pretty-format": {
+ "version": "27.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz",
+ "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.2.5",
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ }
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -12380,22 +12725,70 @@
"pretty-format": "^27.3.1"
},
"dependencies": {
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "@jest/types": {
+ "version": "27.2.5",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz",
+ "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==",
"dev": true,
"requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "has-flag": {
- "version": "4.0.0",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "requires": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
+ "pretty-format": {
+ "version": "27.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz",
+ "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.2.5",
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ }
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -12487,6 +12880,32 @@
"picomatch": "^2.2.3"
}
},
+ "pretty-format": {
+ "version": "27.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz",
+ "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.2.5",
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ }
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -12777,6 +13196,32 @@
"picomatch": "^2.2.3"
}
},
+ "pretty-format": {
+ "version": "27.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz",
+ "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.2.5",
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ }
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -12796,6 +13241,90 @@
"requires": {
"jest-get-type": "^27.3.1",
"pretty-format": "^27.3.1"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "27.2.5",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz",
+ "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "requires": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ }
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "27.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz",
+ "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.2.5",
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
}
},
"jest-matcher-utils": {
@@ -12810,6 +13339,28 @@
"pretty-format": "^27.3.1"
},
"dependencies": {
+ "@jest/types": {
+ "version": "27.2.5",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz",
+ "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "requires": {
+ "@types/yargs-parser": "*"
+ }
+ },
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -12826,6 +13377,32 @@
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
+ "pretty-format": {
+ "version": "27.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz",
+ "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.2.5",
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ }
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -12892,6 +13469,32 @@
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
+ "pretty-format": {
+ "version": "27.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz",
+ "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.2.5",
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ }
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -13831,6 +14434,32 @@
}
}
},
+ "pretty-format": {
+ "version": "27.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz",
+ "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.2.5",
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ }
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
"semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
@@ -13956,6 +14585,32 @@
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
+ "pretty-format": {
+ "version": "27.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz",
+ "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^27.2.5",
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ }
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -14496,6 +15151,12 @@
"yallist": "^4.0.0"
}
},
+ "lz-string": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz",
+ "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=",
+ "dev": true
+ },
"magic-string": {
"version": "0.25.7",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
@@ -14747,6 +15408,12 @@
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true
},
+ "mimic-response": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
+ "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
+ "dev": true
+ },
"min-document": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
@@ -14903,6 +15570,12 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
+ "nan": {
+ "version": "2.15.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
+ "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==",
+ "dev": true
+ },
"nanocolors": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.1.12.tgz",
@@ -15050,6 +15723,15 @@
"integrity": "sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ==",
"dev": true
},
+ "nopt": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
+ "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
+ "dev": true,
+ "requires": {
+ "abbrev": "1"
+ }
+ },
"normalize-package-data": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
@@ -16287,86 +16969,44 @@
}
},
"pretty-format": {
- "version": "27.3.1",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz",
- "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==",
+ "version": "22.1.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-22.1.0.tgz",
+ "integrity": "sha512-0HHR5hCmjDGU4sez3w5zRDAAwn7V0vT4SgPiYPZ1XDm5sT3Icb+Bh+fsOP3+Y3UwPjMr7TbRj+L7eQyMkPAxAw==",
"dev": true,
"requires": {
- "@jest/types": "^27.2.5",
- "ansi-regex": "^5.0.1",
- "ansi-styles": "^5.0.0",
- "react-is": "^17.0.1"
+ "ansi-regex": "^3.0.0",
+ "ansi-styles": "^3.2.0"
},
"dependencies": {
- "@jest/types": {
- "version": "27.2.5",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz",
- "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==",
- "dev": true,
- "requires": {
- "@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^3.0.0",
- "@types/node": "*",
- "@types/yargs": "^16.0.0",
- "chalk": "^4.0.0"
- }
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
},
- "@types/yargs": {
- "version": "16.0.4",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
- "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
- "@types/yargs-parser": "*"
+ "color-convert": "^1.9.0"
}
},
- "ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- }
+ "color-name": "1.1.3"
}
},
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "react-is": {
- "version": "17.0.2",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
- "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
}
}
},
@@ -17038,6 +17678,15 @@
"use-latest": "^1.0.0"
}
},
+ "react-use-compare-debugger": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/react-use-compare-debugger/-/react-use-compare-debugger-1.0.5.tgz",
+ "integrity": "sha512-jtpQi/s0PrnD30MAII/R5Fk2hPJ98PqJY45l5K8jhrQnHny1EqFfaHcazOiGfSxVj9PPCvEGEhHMZ/bhjxvUsQ==",
+ "dev": true,
+ "requires": {
+ "react": "^17.0.1"
+ }
+ },
"read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
@@ -18143,6 +18792,23 @@
"integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==",
"dev": true
},
+ "simple-concat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+ "dev": true
+ },
+ "simple-get": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
+ "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
+ "dev": true,
+ "requires": {
+ "decompress-response": "^4.2.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
"sisteransi": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
@@ -19996,7 +20662,10 @@
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"dev": true,
- "optional": true
+ "optional": true,
+ "requires": {
+ "nan": "^2.12.1"
+ }
},
"glob-parent": {
"version": "3.1.0",
diff --git a/package.json b/package.json
index 8c5586fe..2d6dc899 100644
--- a/package.json
+++ b/package.json
@@ -1,12 +1,13 @@
{
"name": "@chart-it/react-d3",
- "version": "0.1.4",
+ "version": "0.1.6",
"description": "chart-it is a react-d3 charting library",
"repository": "git@github.com:IPWright83/chart-it.git",
"author": "\"Ian Wright\" <\"ipwright83+dev@gmail.com\">",
"main": "lib/index.js",
"module": "lib/index.esm.js",
"types": "lib/index.d.ts",
+ "homepage": "http://localhost:6006/?path=/story/introduction--page",
"scripts": {
"test": "jest",
"lint": "eslint -c .eslintrc.json .",
@@ -28,7 +29,6 @@
"dependencies": {
"d3": "^6.2.0",
"d3-interpolate-path": "^2.2.3",
- "emptyfunction": "^1.0.0",
"lodash.debounce": "^4.0.8",
"lodash.isequal": "^4.5.0"
},
@@ -45,10 +45,12 @@
"@storybook/addon-links": "^6.1.9",
"@storybook/react": "^6.1.9",
"@storybook/storybook-deployer": "^2.8.10",
+ "@testing-library/react": "^12.1.2",
"@types/d3": "^7.1.0",
"@types/react": "^17.0.0",
"babel-jest": "^27.3.1",
"babel-loader": "^8.2.2",
+ "canvas": "^2.8.0",
"chromatic": "^6.0.4",
"crypto": "^1.0.1",
"eslint": "^8.0.1",
@@ -56,16 +58,19 @@
"eslint-plugin-jest": "^25.2.1",
"eslint-plugin-react": "^7.26.1",
"jest": "^27.3.1",
+ "jest-canvas-snapshot-serializer": "^1.0.1",
"jest-circus": "^27.3.1",
"jest-resolve": "^27.3.1",
"jest-watch-typeahead": "^1.0.0",
"postcss": "^8.2.1",
+ "pretty-format": "22.1.0",
"prop-types": "^15.7.2",
"react": "^17.0.2",
"react-app-polyfill": "^2.0.0",
"react-dom": "^17.0.2",
"react-redux": "^7.2.2",
"react-test-renderer": "^17.0.2",
+ "react-use-compare-debugger": "^1.0.5",
"redux": "^4.0.5",
"redux-devtools-extension": "^2.13.8",
"redux-thunk": "^2.3.0",
diff --git a/rollup.config.js b/rollup.config.js
index 5ea9521c..1ebb2867 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -29,6 +29,7 @@ export default {
babel({
exclude: "node_modules/**",
presets: ["@babel/env", "@babel/preset-react"],
+ runtimeHelpers: true,
}),
commonjs(),
//typescript({ useTsconfigDeclarationDir: true }),
diff --git a/src/components/Chart/Chart.js b/src/components/Chart/Chart.js
index 52643621..df4b9e5b 100644
--- a/src/components/Chart/Chart.js
+++ b/src/components/Chart/Chart.js
@@ -1,15 +1,11 @@
import React, { useEffect } from "react";
import PropTypes from "prop-types";
-import { useDispatch, useSelector } from "react-redux";
+import { useDispatch } from "react-redux";
-import { Background } from "../Background";
-import { Droplines } from "../Droplines";
-import { Legend } from "../Legend";
-import { Markers } from "../Markers";
import { VirtualCanvas } from "../VirtualCanvas";
-import { getColumnInfos } from "../../detection";
-import { chartActions, chartSelectors } from "../../store";
+// import { getColumnInfos } from "../../detection";
+import { chartActions } from "../../store";
import { getChildrenWithProps } from "./getChildrenWithProps";
import { getThemeName } from "./getThemeName";
@@ -26,7 +22,6 @@ const Chart = ({
onMouseOut,
onClick,
theme = "light",
- ...props
}) => {
const dispatch = useDispatch();
const themeName = getThemeName(theme);
@@ -66,7 +61,6 @@ const Chart = ({
return (
);
};
Chart.propTypes = {
+ /**
+ * The child components for the chart
+ * @type {Array || Node}
+ */
+ children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
+
/**
* The width of the chart
* @default 500
diff --git a/src/components/Droplines/Droplines.unit.js b/src/components/Droplines/Droplines.unit.js
new file mode 100644
index 00000000..c7522977
--- /dev/null
+++ b/src/components/Droplines/Droplines.unit.js
@@ -0,0 +1,75 @@
+import React from "react";
+import { Provider } from "react-redux";
+import TestRenderer from "react-test-renderer";
+import { render } from "@testing-library/react";
+
+import { Droplines } from "./Droplines";
+
+describe("Droplines", () => {
+ const store = {
+ getState: () => ({
+ event: {
+ droplines: [
+ { isHorizontal: true, color: "red", x1: 50, x2: 0, y1: 50, y2: 50 },
+ { isVertical: true, color: "red", x1: 50, x2: 50, y1: 50, y2: 0 },
+ ],
+ },
+ }),
+ dispatch: () => {},
+ subscribe: () => {},
+ };
+
+ it("should render correctly", async () => {
+ const layer = { current: document.createElement("custom") };
+
+ render(
+
+
+
+ );
+
+ expect(layer.current).toMatchSnapshot();
+ });
+
+ it("should render just vertical lines correctly", () => {
+ const layer = { current: document.createElement("custom") };
+
+ TestRenderer.act(() => {
+ TestRenderer.create(
+
+
+
+ ).toJSON();
+ });
+
+ expect(layer.current).toMatchSnapshot();
+ });
+
+ it("should render just horizontal lines correctly", () => {
+ const layer = { current: document.createElement("custom") };
+
+ TestRenderer.act(() => {
+ TestRenderer.create(
+
+
+
+ ).toJSON();
+ });
+
+ expect(layer.current).toMatchSnapshot();
+ });
+
+ it("should skip if there is no layer avaliable", () => {
+ const layer = { current: null };
+ TestRenderer.act(() => {
+ TestRenderer.create(
+
+
+
+ ).toJSON();
+ });
+
+ // Should be empty
+ expect(layer.current).toMatchSnapshot();
+ });
+});
diff --git a/src/components/Droplines/__snapshots__/Droplines.unit.js.snap b/src/components/Droplines/__snapshots__/Droplines.unit.js.snap
new file mode 100644
index 00000000..aa99feaa
--- /dev/null
+++ b/src/components/Droplines/__snapshots__/Droplines.unit.js.snap
@@ -0,0 +1,50 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Droplines should render correctly 1`] = `
+
+
+
+
+`;
+
+exports[`Droplines should render just horizontal lines correctly 1`] = `
+
+
+
+`;
+
+exports[`Droplines should render just vertical lines correctly 1`] = `
+
+
+
+`;
+
+exports[`Droplines should skip if there is no layer avaliable 1`] = `null`;
diff --git a/src/components/Markers/Markers.unit.js b/src/components/Markers/Markers.unit.js
new file mode 100644
index 00000000..040f9134
--- /dev/null
+++ b/src/components/Markers/Markers.unit.js
@@ -0,0 +1,45 @@
+import React from "react";
+import { Provider } from "react-redux";
+import TestRenderer from "react-test-renderer";
+
+import { Markers } from "./Markers";
+
+describe("Markers", () => {
+ const store = {
+ getState: () => ({
+ event: {
+ markers: [{ fill: "red", stroke: "blue", r1: 5, r2: 5, cx: 50, cy: 50 }],
+ },
+ }),
+ dispatch: () => {},
+ subscribe: () => {},
+ };
+
+ it("should render correctly", () => {
+ const layer = { current: document.createElement("custom") };
+
+ TestRenderer.act(() => {
+ TestRenderer.create(
+
+
+
+ ).toJSON();
+ });
+
+ expect(layer.current).toMatchSnapshot();
+ });
+
+ it("should skip if there is no layer avaliable", () => {
+ const layer = { current: null };
+ TestRenderer.act(() => {
+ TestRenderer.create(
+
+
+
+ ).toJSON();
+ });
+
+ // Should be empty
+ expect(layer.current).toMatchSnapshot();
+ });
+});
diff --git a/src/components/Markers/__snapshots__/Markers.unit.js.snap b/src/components/Markers/__snapshots__/Markers.unit.js.snap
new file mode 100644
index 00000000..43dc1701
--- /dev/null
+++ b/src/components/Markers/__snapshots__/Markers.unit.js.snap
@@ -0,0 +1,15 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Markers should render correctly 1`] = `
+
+
+
+`;
+
+exports[`Markers should skip if there is no layer avaliable 1`] = `null`;
diff --git a/src/components/Plots/Area/Area.stories.jsx b/src/components/Plots/Area/Area.stories.jsx
index 304179bc..53891179 100644
--- a/src/components/Plots/Area/Area.stories.jsx
+++ b/src/components/Plots/Area/Area.stories.jsx
@@ -4,7 +4,7 @@ import { argTypes } from "../../../../stories/argTypes";
import { sales_records_dataset } from "../../../../data/sales_records_dataset";
import { Area } from "./Area";
import { Areas } from "./Areas";
-import { Chart } from "../../Chart";
+import { XYChart } from "../../XYChart";
import { XAxis, YAxis } from "../../Axis";
import mdx from "./Area.mdx";
@@ -17,6 +17,12 @@ export default {
parameters: {
docs: {
page: mdx,
+ transformSource: (src) => {
+ src = src.replace(/data={\[.*?\]}/gs, "data={[ ...dataset ]}");
+ src = src.replaceAll(/undefined,?/g, "");
+ src = src.replace(/^\s*\n/gm, "");
+ return src;
+ },
},
chromatic: { delay: 300 },
},
@@ -34,41 +40,48 @@ export default {
};
const AreaTemplate = (args) => (
-
-
+
-
+
);
const AreasTemplate = (args) => (
-
-
-
+
+
);
const StackedAreasTemplate = (args) => (
-
-
-
+
+
);
export const Basic = AreaTemplate.bind({});
@@ -123,7 +136,7 @@ MultipleAreas.args = {
};
export const StackedAreas = StackedAreasTemplate.bind({});
-StackedAreas.storyName = "Staced Area Plots";
+StackedAreas.storyName = "Stacked Area Plots";
StackedAreas.args = {
...Basic.args,
y: "Total Revenue",
diff --git a/src/components/Plots/Area/Area/AreaBase.js b/src/components/Plots/Area/Area/AreaBase.js
index 80f24ac0..e05e8146 100644
--- a/src/components/Plots/Area/Area/AreaBase.js
+++ b/src/components/Plots/Area/Area/AreaBase.js
@@ -81,7 +81,7 @@ const AreaBase = ({ x, y, y2, color, layer, canvas }) => {
}, [x, y, sortedData, xScale, yScale, layer, canvas, width, height, theme.colors, animationDuration]);
// If possible respond to global mouse events for tooltips etc
- useDatumFocus(dispatch, layer, x, y, xScale, yScale, sortedData, eventMode, position, strokeColor);
+ useDatumFocus(dispatch, layer, x, y, xScale, yScale, sortedData, eventMode, position, strokeColor.toString());
return null;
};
diff --git a/src/components/Plots/Bar/Bar.stories.jsx b/src/components/Plots/Bar/Bar.stories.jsx
index c32a39b8..c803ea7d 100644
--- a/src/components/Plots/Bar/Bar.stories.jsx
+++ b/src/components/Plots/Bar/Bar.stories.jsx
@@ -4,7 +4,7 @@ import { argTypes } from "../../../../stories/argTypes";
import { sales_records_dataset } from "../../../../data/sales_records_dataset";
import { Bar } from "./Bar";
import { Bars } from "./Bars";
-import { Chart } from "../../Chart";
+import { XYChart } from "../../XYChart";
import { XAxis, YAxis } from "../../Axis";
import mdx from "./Bar.mdx";
@@ -17,6 +17,12 @@ export default {
parameters: {
docs: {
page: mdx,
+ transformSource: (src) => {
+ src = src.replace(/data={\[.*?\]}/gs, "data={[ ...dataset ]}");
+ src = src.replaceAll(/undefined,?/g, "");
+ src = src.replace(/^\s*\n/gm, "");
+ return src;
+ },
},
chromatic: { delay: 300 },
},
@@ -34,40 +40,34 @@ export default {
};
const BarTemplate = (args) => (
-
-
- {args.x2 ? (
-
- ) : undefined}
-
+
+ {args.x2 ? : undefined}
+
);
const BarsTemplate = (args) => (
-
-
-
+
+
);
export const Basic = BarTemplate.bind({});
diff --git a/src/components/Plots/Column/Column.stories.jsx b/src/components/Plots/Column/Column.stories.jsx
index 9bed664d..afada6f6 100644
--- a/src/components/Plots/Column/Column.stories.jsx
+++ b/src/components/Plots/Column/Column.stories.jsx
@@ -4,7 +4,7 @@ import { argTypes } from "../../../../stories/argTypes";
import { sales_records_dataset } from "../../../../data/sales_records_dataset";
import { Column } from "./Column";
import { Columns } from "./Columns";
-import { Chart } from "../../Chart";
+import { XYChart } from "../../XYChart";
import { XAxis, YAxis } from "../../Axis";
import mdx from "./Column.mdx";
@@ -17,6 +17,12 @@ export default {
parameters: {
docs: {
page: mdx,
+ transformSource: (src) => {
+ src = src.replace(/data={\[.*?\]}/gs, "data={[ ...dataset ]}");
+ src = src.replaceAll(/undefined,?/g, "");
+ src = src.replace(/^\s*\n/gm, "");
+ return src;
+ },
},
chromatic: { delay: 300 },
},
@@ -34,40 +40,34 @@ export default {
};
const ColumnTemplate = (args) => (
-
-
- {args.y2 ? (
-
- ) : undefined}
-
+
+ {args.y2 ? : undefined}
+
);
const ColumnsTemplate = (args) => (
-
-
-
+
+
);
export const Basic = ColumnTemplate.bind({});
diff --git a/src/components/Plots/Line/Line.stories.jsx b/src/components/Plots/Line/Line.stories.jsx
index eebce371..b42dc855 100644
--- a/src/components/Plots/Line/Line.stories.jsx
+++ b/src/components/Plots/Line/Line.stories.jsx
@@ -4,7 +4,7 @@ import { argTypes } from "../../../../stories/argTypes";
import { sales_records_dataset } from "../../../../data/sales_records_dataset";
import { Line } from "./Line";
import { Lines } from "./Lines";
-import { Chart } from "../../Chart";
+import { XYChart } from "../../XYChart";
import { XAxis, YAxis } from "../../Axis";
import mdx from "./Line.mdx";
@@ -17,6 +17,12 @@ export default {
parameters: {
docs: {
page: mdx,
+ transformSource: (src) => {
+ src = src.replace(/data={\[.*?\]}/gs, "data={[ ...dataset ]}");
+ src = src.replaceAll(/undefined,?/g, "");
+ src = src.replace(/^\s*\n/gm, "");
+ return src;
+ },
},
chromatic: { delay: 300 },
},
@@ -34,29 +40,33 @@ export default {
};
const LineTemplate = (args) => (
-
-
+
-
+
);
const LinesTemplate = (args) => (
-
-
-
+
+
);
export const Basic = LineTemplate.bind({});
diff --git a/src/components/Plots/Scatter/Scatter.stories.jsx b/src/components/Plots/Scatter/Scatter.stories.jsx
index da5e2b39..c7e6dbf8 100644
--- a/src/components/Plots/Scatter/Scatter.stories.jsx
+++ b/src/components/Plots/Scatter/Scatter.stories.jsx
@@ -5,7 +5,7 @@ import { sales_records_dataset } from "../../../../data/sales_records_dataset";
import { huge_data_set } from "../../../../data/huge_data_set";
import { Scatter } from "./Scatter";
import { Scatters } from "./Scatters";
-import { Chart } from "../../Chart";
+import { XYChart } from "../../XYChart";
import { XAxis, YAxis } from "../../Axis";
import mdx from "./Scatter.mdx";
@@ -18,6 +18,12 @@ export default {
parameters: {
docs: {
page: mdx,
+ transformSource: (src) => {
+ src = src.replace(/data={\[.*?\]}/gs, "data={[ ...dataset ]}");
+ src = src.replaceAll(/undefined,?/g, "");
+ src = src.replace(/^\s*\n/gm, "");
+ return src;
+ },
},
chromatic: { delay: 300 },
},
@@ -40,40 +46,33 @@ export default {
};
const ScatterTemplate = (args) => (
-
-
+
-
+
);
const ScattersTemplate = (args) => (
-
-
+
-
+
);
export const Basic = ScatterTemplate.bind({});
diff --git a/src/components/Plots/Scatter/Scatter/Scatter.unit.js b/src/components/Plots/Scatter/Scatter/Scatter.unit.js
new file mode 100644
index 00000000..615f7fce
--- /dev/null
+++ b/src/components/Plots/Scatter/Scatter/Scatter.unit.js
@@ -0,0 +1,184 @@
+import * as d3 from "d3";
+import React from "react";
+import { Provider } from "react-redux";
+import { render, fireEvent } from "@testing-library/react";
+import { themes } from "../../../../themes";
+import canvasSerializer from "jest-canvas-snapshot-serializer";
+
+import { Scatter } from "./Scatter";
+
+expect.addSnapshotSerializer(canvasSerializer);
+
+describe("Scatter", () => {
+ let chartState;
+
+ beforeEach(() => {
+ chartState = {
+ animationDuration: 0,
+ dimensions: {
+ height: 200,
+ width: 200,
+ },
+ data: [
+ { x: 5, y: 5 },
+ { x: 10, y: 10 },
+ ],
+ scales: {
+ x: d3.scaleLinear().domain([0, 20]).range([0, 100]),
+ y: d3.scaleLinear().domain([0, 20]).range([0, 100]),
+ },
+ theme: themes.light,
+ };
+ });
+
+ const store = {
+ getState: () => ({
+ chart: chartState,
+ }),
+ dispatch: () => {},
+ subscribe: () => {},
+ };
+
+ describe("using SVG", () => {
+ it("should render correctly", () => {
+ const { asFragment } = render(
+
+
+
+ );
+
+ expect(asFragment()).toMatchSnapshot();
+ });
+
+ describe("should handle event", () => {
+ it("mouseover correctly", () => {
+ const onMouseOver = jest.fn();
+ jest.spyOn(store, "dispatch");
+
+ const { container } = render(
+
+
+
+ );
+
+ fireEvent.mouseOver(container.querySelector("circle"));
+ expect(onMouseOver).toHaveBeenCalledWith(
+ {
+ x: 5,
+ y: 5,
+ },
+ expect.anything(),
+ expect.anything()
+ );
+
+ expect(store.dispatch.mock.calls[0]).toMatchSnapshot("ADD_MARKER action");
+ expect(store.dispatch.mock.calls[1]).toMatchSnapshot("ADD_DROPLINE action");
+ expect(store.dispatch.mock.calls[2]).toMatchSnapshot("ADD_DROPLINE action");
+ });
+
+ it("mouseexit correctly", () => {
+ const onMouseOut = jest.fn();
+ jest.spyOn(store, "dispatch");
+
+ const { container } = render(
+
+
+
+ );
+
+ fireEvent.mouseOver(container.querySelector("circle"));
+ fireEvent.mouseLeave(container.querySelector("circle"));
+ expect(onMouseOut).toHaveBeenCalledWith(
+ {
+ x: 5,
+ y: 5,
+ },
+ expect.anything(),
+ expect.anything()
+ );
+
+ expect(store.dispatch.mock.calls[3]).toMatchSnapshot("REMOVE_MARKER action");
+ expect(store.dispatch.mock.calls[4]).toMatchSnapshot("REMOVE_DROPLINE action");
+ expect(store.dispatch.mock.calls[5]).toMatchSnapshot("REMOVE_DROPLINE action");
+ });
+
+ it("click correctly", () => {
+ const onClick = jest.fn();
+ jest.spyOn(store, "dispatch");
+
+ const { container } = render(
+
+
+
+ );
+
+ fireEvent.click(container.querySelector("circle"));
+ expect(onClick).toHaveBeenCalledWith(
+ {
+ x: 5,
+ y: 5,
+ },
+ expect.anything(),
+ expect.anything()
+ );
+ });
+ });
+
+ describe("should skip rendering if", () => {
+ it("there is no x scale avaliable", () => {
+ delete chartState.scales.x;
+
+ const { asFragment } = render(
+
+
+
+ );
+
+ expect(asFragment()).toMatchSnapshot();
+ });
+
+ it("there is no y scale avaliable", () => {
+ delete chartState.scales.y;
+
+ const { asFragment } = render(
+
+
+
+ );
+
+ expect(asFragment()).toMatchSnapshot();
+ });
+ });
+ });
+
+ describe("using Canvas", () => {
+ it("should render correctly", async () => {
+ const { container } = render(
+
+
+
+ );
+
+ await new Promise((resolve) => {
+ setTimeout(resolve, 250);
+ });
+
+ const canvas = container.querySelector("canvas");
+ expect(canvas).toMatchSnapshot();
+ });
+ });
+});
diff --git a/src/components/Plots/Scatter/Scatter/ScatterBase.js b/src/components/Plots/Scatter/Scatter/ScatterBase.js
index f24a88e3..2033fb3a 100644
--- a/src/components/Plots/Scatter/Scatter/ScatterBase.js
+++ b/src/components/Plots/Scatter/Scatter/ScatterBase.js
@@ -3,7 +3,6 @@ import PropTypes from "prop-types";
import { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
-import { useRender } from "../../../../hooks";
import { chartSelectors, eventActions } from "../../../../store";
import { eventDefaultProps, eventPropTypes, plotDefaultProps, plotPropTypes } from "../../../../types";
@@ -87,7 +86,7 @@ const ScatterBase = ({
}, [dispatch, xScale, yScale, focused]);
// This is the main render function
- useRender(() => {
+ useEffect(() => {
// D3 data join
const join = d3
.select(layer.current)
@@ -113,15 +112,15 @@ const ScatterBase = ({
const update = enter
.merge(join)
.on("mouseover", function (event, datum) {
- onMouseOver && onMouseOver(datum, this, event);
+ onMouseOver(datum, this, event);
setFocused({ element: this, event, datum });
})
.on("mouseout", function (event, datum) {
- onMouseOut && onMouseOut(datum, this, event);
+ onMouseOut(datum, this, event);
setFocused(null);
})
.on("click", function (event, datum) {
- onClick && onClick(datum, this, event);
+ onClick(datum, this, event);
})
.transition("scatter")
.duration(animationDuration)
diff --git a/src/components/Plots/Scatter/Scatter/__snapshots__/Scatter.unit.js.snap b/src/components/Plots/Scatter/Scatter/__snapshots__/Scatter.unit.js.snap
new file mode 100644
index 00000000..7254d217
--- /dev/null
+++ b/src/components/Plots/Scatter/Scatter/__snapshots__/Scatter.unit.js.snap
@@ -0,0 +1,150 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Scatter using Canvas should render correctly 1`] = `
+
+`;
+
+exports[`Scatter using SVG should handle event mouseexit correctly: REMOVE_DROPLINE action 1`] = `
+Array [
+ Object {
+ "payload": Object {
+ "color": "rgba(153, 193, 220, 0.8)",
+ "isHorizontal": true,
+ "x1": 21,
+ "x2": 0,
+ "y1": 25,
+ "y2": 25,
+ },
+ "type": "EVENT.REMOVE_DROPLINE",
+ },
+]
+`;
+
+exports[`Scatter using SVG should handle event mouseexit correctly: REMOVE_DROPLINE action 2`] = `
+Array [
+ Object {
+ "payload": Object {
+ "color": "rgba(153, 193, 220, 0.8)",
+ "isVertical": true,
+ "x1": 25,
+ "x2": 25,
+ "y1": 29,
+ "y2": 0,
+ },
+ "type": "EVENT.REMOVE_DROPLINE",
+ },
+]
+`;
+
+exports[`Scatter using SVG should handle event mouseexit correctly: REMOVE_MARKER action 1`] = `
+Array [
+ Object {
+ "payload": Object {
+ "cx": 25,
+ "cy": 25,
+ "r1": 0,
+ "r2": 4,
+ "stroke": "rgba(153, 193, 220, 0.8)",
+ },
+ "type": "EVENT.REMOVE_MARKER",
+ },
+]
+`;
+
+exports[`Scatter using SVG should handle event mouseover correctly: ADD_DROPLINE action 1`] = `
+Array [
+ Object {
+ "payload": Object {
+ "color": "rgba(153, 193, 220, 0.8)",
+ "isHorizontal": true,
+ "x1": 21,
+ "x2": 0,
+ "y1": 25,
+ "y2": 25,
+ },
+ "type": "EVENT.ADD_DROPLINE",
+ },
+]
+`;
+
+exports[`Scatter using SVG should handle event mouseover correctly: ADD_DROPLINE action 2`] = `
+Array [
+ Object {
+ "payload": Object {
+ "color": "rgba(153, 193, 220, 0.8)",
+ "isVertical": true,
+ "x1": 25,
+ "x2": 25,
+ "y1": 29,
+ "y2": 0,
+ },
+ "type": "EVENT.ADD_DROPLINE",
+ },
+]
+`;
+
+exports[`Scatter using SVG should handle event mouseover correctly: ADD_MARKER action 1`] = `
+Array [
+ Object {
+ "payload": Object {
+ "cx": 25,
+ "cy": 25,
+ "r1": 0,
+ "r2": 4,
+ "stroke": "rgba(153, 193, 220, 0.8)",
+ },
+ "type": "EVENT.ADD_MARKER",
+ },
+]
+`;
+
+exports[`Scatter using SVG should render correctly 1`] = `
+
+
+
+`;
+
+exports[`Scatter using SVG should skip rendering if there is no x scale avaliable 1`] = `
+
+
+
+`;
+
+exports[`Scatter using SVG should skip rendering if there is no y scale avaliable 1`] = `
+
+
+
+`;
diff --git a/src/components/Plots/Scatter/Scatter/__snapshots__/Scatter.unit.js.snap.Scatter-using-Canvas-should-render-correctly.canvas-image.png b/src/components/Plots/Scatter/Scatter/__snapshots__/Scatter.unit.js.snap.Scatter-using-Canvas-should-render-correctly.canvas-image.png
new file mode 100644
index 00000000..f0d91799
Binary files /dev/null and b/src/components/Plots/Scatter/Scatter/__snapshots__/Scatter.unit.js.snap.Scatter-using-Canvas-should-render-correctly.canvas-image.png differ
diff --git a/src/components/VirtualCanvas/VirtualCanvas.js b/src/components/VirtualCanvas/VirtualCanvas.js
index 54f26b3a..9d4c901d 100644
--- a/src/components/VirtualCanvas/VirtualCanvas.js
+++ b/src/components/VirtualCanvas/VirtualCanvas.js
@@ -1,6 +1,5 @@
import "./VirtualCanvas.css";
-import emptyFunction from "emptyfunction";
import debounce from "lodash.debounce";
import PropTypes from "prop-types";
import React, { useEffect, useRef } from "react";
@@ -80,7 +79,11 @@ const VirtualCanvas = (props) => {
// Many layers don't require the virtual canvas. If
// they are all of these types then disable the canvas
- const childTypes = children.filter((c) => !!c).map((c) => c.props.mdxType);
+ const childTypes = children
+ // Fix for storybook
+ .filter((c) => !!c && !!c.props)
+ .map((c) => c.props.mdxType);
+
const typesNeedingCanvas = childTypes.filter((type) => !ignoreTypes.includes(type));
const includeVirtualCanvas = typesNeedingCanvas.length > 0;
@@ -135,9 +138,9 @@ VirtualCanvas.propTypes = {
};
VirtualCanvas.defaultProps = {
- onMouseOver: emptyFunction,
- onMouseOut: emptyFunction,
- onClick: emptyFunction,
+ onMouseOver: () => {},
+ onMouseOut: () => {},
+ onClick: () => {},
};
export { VirtualCanvas };
diff --git a/src/components/XYChart/XYChart.js b/src/components/XYChart/XYChart.js
index 926ff275..de89a931 100644
--- a/src/components/XYChart/XYChart.js
+++ b/src/components/XYChart/XYChart.js
@@ -5,15 +5,12 @@ import { Background } from "../Background";
import { Droplines } from "../Droplines";
import { Markers } from "../Markers";
import { Chart } from "../Chart";
-import { XAxis, YAxis } from "../Axis";
-const XYChart = ({ children, xs, ys, ...props }) => {
+const XYChart = ({ children, ...props }) => {
return (
{children}
-
-
@@ -21,16 +18,6 @@ const XYChart = ({ children, xs, ys, ...props }) => {
};
XYChart.propTypes = {
- /**
- * The set of x fields to use to access the data for each plot
- * @type {Array}
- */
- xs: PropTypes.arrayOf(PropTypes.string).isRequired,
- /**
- * The set of y fields to use to access the data for each plot
- * @type {Array}
- */
- ys: PropTypes.arrayOf(PropTypes.string).isRequired,
/**
* The child components (Plots) for the chart
* @type {Array}
diff --git a/src/hoc/canvas/canvasRenderLoop.js b/src/hoc/canvas/canvasRenderLoop.js
index 2da527ec..4db6c2e3 100644
--- a/src/hoc/canvas/canvasRenderLoop.js
+++ b/src/hoc/canvas/canvasRenderLoop.js
@@ -19,12 +19,14 @@ const canvasRenderLoop = async (canvas, width, height, exit, update) => {
// Ensure we've got the contexts to draw upon
const context = canvas.getContext("2d");
- // Create a render loop that will run until the transitions complete
- const renderLoop = d3.timer(() => {
+ const render = () => {
context.clearRect(0, 0, width, height);
renderElements(context, exit);
renderElements(context, update);
- });
+ };
+
+ // Create a render loop that will run until the transitions complete
+ const renderLoop = d3.timer(render);
try {
await exit.end();
@@ -35,12 +37,9 @@ const canvasRenderLoop = async (canvas, width, height, exit, update) => {
// eslint-disable-next-line no-empty
} catch (e) {}
- // Run 1 final render after animations have finished, but
- // only of the update selection. As exit elements should
- // now have been removed
- setTimeout(() => {
- renderLoop.stop();
- }, 0);
+ // Run 1 final render after animations have finished
+ renderLoop.stop();
+ render();
};
export { canvasRenderLoop };
diff --git a/src/hoc/canvas/renderCircle.js b/src/hoc/canvas/renderCircle.js
index a6e13c19..6bc0eb23 100644
--- a/src/hoc/canvas/renderCircle.js
+++ b/src/hoc/canvas/renderCircle.js
@@ -8,13 +8,13 @@ import * as d3 from "d3";
*/
const renderCircle = (context, node, overrideColor) => {
const selection = d3.select(node);
- const cx = selection.attr("cx");
- const cy = selection.attr("cy");
- const r = selection.attr("r");
+ const cx = Number(selection.attr("cx"));
+ const cy = Number(selection.attr("cy"));
+ const r = Number(selection.attr("r"));
const fill = selection.style("fill");
const opacity = Number(selection.style("opacity")) || 1;
const stroke = selection.style("stroke");
- const strokeWidth = selection.style("stroke-width") || 1;
+ const strokeWidth = Number(selection.style("stroke-width")) || 1;
context.beginPath();
context.arc(cx, cy, r, 0, 2 * Math.PI);
diff --git a/src/store/telemetry/telemetryActions.js b/src/store/telemetry/telemetryActions.js
index 47467978..cf2a81cf 100644
--- a/src/store/telemetry/telemetryActions.js
+++ b/src/store/telemetry/telemetryActions.js
@@ -1,3 +1,5 @@
+/* eslint-disable */
+
// import { getColumnInfos } from "lib/detection";
// import { telemetrySelectors } from "./telemetrySelectors";
@@ -27,18 +29,16 @@ const generateDataAnalytics = (data) => (dispatch, getState) => {
* @param {Number} options.children The child components of the chart
* @return {Object} A redux action object
*/
-const generateChartAnalytics =
- ({ height, width, margin, useCanvas, animationDuration, children }) =>
- () => {
- // console.log({
- // height,
- // width,
- // margin,
- // useCanvas,
- // animationDuration,
- // children: children.map((c) => ({ name: c.type.name, props: c.props })),
- // });
- };
+const generateChartAnalytics = ({ height, width, margin, useCanvas, animationDuration, children }) => () => {
+ // console.log({
+ // height,
+ // width,
+ // margin,
+ // useCanvas,
+ // animationDuration,
+ // children: children.map((c) => ({ name: c.type.name, props: c.props })),
+ // });
+};
const telemetryActions = {
generateDataAnalytics,
diff --git a/src/types/plot/eventDefaultProps.js b/src/types/plot/eventDefaultProps.js
index 080239ef..361a3500 100644
--- a/src/types/plot/eventDefaultProps.js
+++ b/src/types/plot/eventDefaultProps.js
@@ -1,13 +1,11 @@
-import emptyFunction from "emptyfunction";
-
/**
* Default set of props used for various plots that support their own events
* @type {Object}
*/
const eventDefaultProps = {
- onMouseOver: emptyFunction,
- onMouseOut: emptyFunction,
- onClick: emptyFunction,
+ onMouseOver: () => {},
+ onMouseOut: () => {},
+ onClick: () => {},
};
export { eventDefaultProps };