diff --git a/.gitignore b/.gitignore
index 7c8fc1c..9f4aeac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
node_modules
-npm-debug.log
.DS_Store
jsconfig.json
@@ -7,3 +6,4 @@ react-codemod
gh-pages/
lib
build
+*.log
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 0000000..feb9a63
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,7 @@
+{
+ "bracketSpacing": true,
+ "jsxBracketSameLine": true,
+ "printWidth": 80,
+ "singleQuote": true,
+ "trailingComma": "es5"
+}
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index 9ff837e..0000000
--- a/package-lock.json
+++ /dev/null
@@ -1,791 +0,0 @@
-{
- "name": "react-inspector",
- "version": "2.3.1",
- "lockfileVersion": 1,
- "dependencies": {
- "acorn": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.1.tgz",
- "integrity": "sha512-vOk6uEMctu0vQrvuSqFdJyqj1Q0S5VTDL79qtjo+DhRr+1mmaD+tluFSCZqhvi/JUhXSzoZN2BhtstaPEeE8cw==",
- "dev": true
- },
- "acorn-jsx": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
- "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
- "dev": true,
- "dependencies": {
- "acorn": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
- "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
- "dev": true
- }
- }
- },
- "ajv": {
- "version": "4.11.8",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
- "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
- "dev": true
- },
- "ajv-keywords": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz",
- "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=",
- "dev": true
- },
- "ansi-escapes": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz",
- "integrity": "sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs=",
- "dev": true
- },
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
- "dev": true
- },
- "ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
- "dev": true
- },
- "argparse": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
- "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
- "dev": true
- },
- "array-union": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
- "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
- "dev": true
- },
- "array-uniq": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
- "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
- "dev": true
- },
- "arrify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
- "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
- "dev": true
- },
- "babel-code-frame": {
- "version": "6.22.0",
- "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz",
- "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=",
- "dev": true
- },
- "balanced-match": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
- "dev": true
- },
- "brace-expansion": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
- "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
- "dev": true
- },
- "caller-path": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
- "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
- "dev": true
- },
- "callsites": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
- "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
- "dev": true
- },
- "chalk": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
- "dev": true
- },
- "circular-json": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.1.tgz",
- "integrity": "sha1-vos2rvzN6LPKeqLWr8B6NyQsDS0=",
- "dev": true
- },
- "cli-cursor": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
- "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
- "dev": true
- },
- "cli-width": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz",
- "integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=",
- "dev": true
- },
- "co": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
- "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
- "dev": true
- },
- "concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
- "dev": true
- },
- "concat-stream": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
- "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
- "dev": true
- },
- "core-util-is": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
- "dev": true
- },
- "debug": {
- "version": "2.6.8",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
- "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
- "dev": true
- },
- "deep-is": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
- "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
- "dev": true
- },
- "del": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
- "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
- "dev": true
- },
- "doctrine": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz",
- "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=",
- "dev": true
- },
- "escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
- "dev": true
- },
- "eslint": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.1.1.tgz",
- "integrity": "sha1-+svfz+Pg+s06i4DcmMTmwTrlgt8=",
- "dev": true
- },
- "eslint-plugin-react": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.1.0.tgz",
- "integrity": "sha1-J3cKzzn1/UnNCvQIPOWBBOs5DUw=",
- "dev": true
- },
- "eslint-scope": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
- "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
- "dev": true
- },
- "espree": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/espree/-/espree-3.4.3.tgz",
- "integrity": "sha1-KRC1zNSc6JPC//+qtP2LOjG4I3Q=",
- "dev": true
- },
- "esprima": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
- "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=",
- "dev": true
- },
- "esquery": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz",
- "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=",
- "dev": true
- },
- "esrecurse": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz",
- "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=",
- "dev": true
- },
- "estraverse": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
- "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
- "dev": true
- },
- "esutils": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
- "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
- "dev": true
- },
- "external-editor": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.4.tgz",
- "integrity": "sha1-HtkZnanL/i7y96MbL96LDRI2iXI=",
- "dev": true
- },
- "fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
- "dev": true
- },
- "figures": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
- "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
- "dev": true
- },
- "file-entry-cache": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
- "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
- "dev": true
- },
- "flat-cache": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz",
- "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=",
- "dev": true
- },
- "fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
- "dev": true
- },
- "function-bind": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz",
- "integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E=",
- "dev": true
- },
- "generate-function": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
- "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=",
- "dev": true
- },
- "generate-object-property": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
- "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
- "dev": true
- },
- "glob": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
- "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
- "dev": true
- },
- "globals": {
- "version": "9.18.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
- "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
- "dev": true
- },
- "globby": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
- "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
- "dev": true
- },
- "graceful-fs": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
- "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
- "dev": true
- },
- "has": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
- "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=",
- "dev": true
- },
- "has-ansi": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
- "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
- "dev": true
- },
- "iconv-lite": {
- "version": "0.4.18",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz",
- "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==",
- "dev": true
- },
- "ignore": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.3.tgz",
- "integrity": "sha1-QyNS5XrM2HqzEQ6C0/6g5HgSFW0=",
- "dev": true
- },
- "imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
- "dev": true
- },
- "inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
- "dev": true
- },
- "inherits": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
- "dev": true
- },
- "inquirer": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.1.1.tgz",
- "integrity": "sha512-H50sHQwgvvaTBd3HpKMVtL/u6LoHDvYym51gd7bGQe/+9HkCE+J0/3N5FJLfd6O6oz44hHewC2Pc2LodzWVafQ==",
- "dev": true
- },
- "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
- },
- "is-my-json-valid": {
- "version": "2.16.0",
- "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz",
- "integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=",
- "dev": true
- },
- "is-path-cwd": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
- "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
- "dev": true
- },
- "is-path-in-cwd": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
- "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=",
- "dev": true
- },
- "is-path-inside": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz",
- "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=",
- "dev": true
- },
- "is-promise": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
- "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
- "dev": true
- },
- "is-property": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
- "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
- "dev": true
- },
- "is-resolvable": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz",
- "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=",
- "dev": true
- },
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "js-tokens": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
- "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
- "dev": true
- },
- "js-yaml": {
- "version": "3.8.4",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.8.4.tgz",
- "integrity": "sha1-UgtFZPhlc7qWZir4Woyvp7S1pvY=",
- "dev": true
- },
- "jschardet": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.4.2.tgz",
- "integrity": "sha1-KqEH8UKvQSHRRWWdRPUIMJYeaZo=",
- "dev": true
- },
- "json-stable-stringify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
- "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
- "dev": true
- },
- "jsonify": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
- "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
- "dev": true
- },
- "jsonpointer": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
- "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
- "dev": true
- },
- "jsx-ast-utils": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz",
- "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=",
- "dev": true
- },
- "levn": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
- "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
- "dev": true
- },
- "lodash": {
- "version": "4.17.4",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
- "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=",
- "dev": true
- },
- "mimic-fn": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz",
- "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=",
- "dev": true
- },
- "minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
- "dev": true
- },
- "minimist": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
- "dev": true
- },
- "mkdirp": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
- "dev": true
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
- "dev": true
- },
- "mute-stream": {
- "version": "0.0.7",
- "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
- "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
- "dev": true
- },
- "natural-compare": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
- "dev": true
- },
- "object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
- "dev": true
- },
- "once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
- "dev": true
- },
- "onetime": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
- "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
- "dev": true
- },
- "optionator": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
- "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
- "dev": true
- },
- "os-tmpdir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
- "dev": true
- },
- "path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
- "dev": true
- },
- "path-is-inside": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
- "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
- "dev": true
- },
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
- "dev": true
- },
- "pinkie": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
- "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
- "dev": true
- },
- "pinkie-promise": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
- "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
- "dev": true
- },
- "pluralize": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-4.0.0.tgz",
- "integrity": "sha1-WbcIwcAZCi9pLxx2GMRGsFL9F2I=",
- "dev": true
- },
- "prelude-ls": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
- "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
- "dev": true
- },
- "process-nextick-args": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
- "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
- "dev": true
- },
- "progress": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
- "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true
- },
- "require-uncached": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
- "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
- "dev": true
- },
- "resolve-from": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
- "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
- "dev": true
- },
- "restore-cursor": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
- "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
- "dev": true
- },
- "rimraf": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz",
- "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=",
- "dev": true
- },
- "run-async": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
- "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
- "dev": true
- },
- "rx-lite": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
- "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
- "dev": true
- },
- "rx-lite-aggregates": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
- "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
- "dev": true
- },
- "safe-buffer": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
- "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
- "dev": true
- },
- "signal-exit": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
- "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
- "dev": true
- },
- "slice-ansi": {
- "version": "0.0.4",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
- "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
- "dev": true
- },
- "sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
- "dev": true
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true
- },
- "string-width": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.0.tgz",
- "integrity": "sha1-AwZkVh/BRslCPsfZeP4kV0N/5tA=",
- "dev": true,
- "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
- },
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "dev": true
- }
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "dev": true
- },
- "strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
- "dev": true
- },
- "supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
- "dev": true
- },
- "table": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/table/-/table-4.0.1.tgz",
- "integrity": "sha1-qBFsEz+sLGH0pCCrbN9cTWHw5DU=",
- "dev": true
- },
- "text-table": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
- "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
- "dev": true
- },
- "through": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
- "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
- "dev": true
- },
- "tmp": {
- "version": "0.0.31",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz",
- "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=",
- "dev": true
- },
- "tryit": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz",
- "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=",
- "dev": true
- },
- "type-check": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
- "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
- "dev": true
- },
- "typedarray": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
- "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
- "dev": true
- },
- "util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
- "dev": true
- },
- "wordwrap": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
- "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
- "dev": true
- },
- "wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
- "dev": true
- },
- "write": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
- "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
- "dev": true
- },
- "xtend": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
- "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
- "dev": true
- }
- }
-}
diff --git a/package.json b/package.json
index f31c0b9..2380001 100644
--- a/package.json
+++ b/package.json
@@ -65,11 +65,11 @@
"eslint-plugin-react": "^7.7.0",
"expect": "^22.4.3",
"jest": "^22.4.3",
- "prettier": "^1.11.1",
- "react": "^16.3.1",
- "react-dom": "^16.3.1",
+ "prettier": "^1.16.3",
+ "react": "^16.8.2",
+ "react-dom": "^16.8.2",
"react-hot-loader": "^4.0.1",
- "react-test-renderer": "^16.3.1",
+ "react-test-renderer": "^16.8.0-alpha.1",
"rebug": "^0.0.3",
"rimraf": "^2.6.2",
"style-loader": "^0.20.3",
@@ -78,6 +78,6 @@
"webpack-dev-server": "^3.1.3"
},
"peerDependencies": {
- "react": "^0.14.0 || ^15.0.0 || ^16.0.0"
+ "react": "^16.8.0"
}
}
diff --git a/src/dom-inspector/DOMInspector.js b/src/dom-inspector/DOMInspector.js
index d60bd80..551abeb 100644
--- a/src/dom-inspector/DOMInspector.js
+++ b/src/dom-inspector/DOMInspector.js
@@ -1,10 +1,12 @@
-import React, { Component } from 'react';
+import React from 'react';
import PropTypes from 'prop-types';
import DOMNodePreview from './DOMNodePreview';
import TreeView from '../tree-view/TreeView';
import shouldInline from './shouldInline';
+import { themeAcceptor } from '../styles';
+
const domIterator = function*(data) {
if (data && data.childNodes) {
const textInlined = shouldInline(data);
@@ -16,7 +18,11 @@ const domIterator = function*(data) {
for (let i = 0; i < data.childNodes.length; i++) {
const node = data.childNodes[i];
- if (node.nodeType === Node.TEXT_NODE && node.textContent.trim().length === 0) continue;
+ if (
+ node.nodeType === Node.TEXT_NODE &&
+ node.textContent.trim().length === 0
+ )
+ continue;
yield {
name: `${node.tagName}[${i}]`,
@@ -37,27 +43,19 @@ const domIterator = function*(data) {
}
};
-import ThemeProvider from '../styles/ThemeProvider';
-
-class DOMInspector extends Component {
- static propTypes = {
- /** The DOM Node to inspect */
- data: PropTypes.object.isRequired,
- };
-
- static defaultProps = {
- theme: 'chromeLight',
- };
-
- render() {
- const nodeRenderer = DOMNodePreview;
+const DOMInspector = props => {
+ return (
+
+ );
+};
- return (
-
-
-
- );
- }
-}
+DOMInspector.propTypes = {
+ // The DOM Node to inspect
+ data: PropTypes.object.isRequired,
+};
-export default DOMInspector;
+export default themeAcceptor(DOMInspector);
diff --git a/src/dom-inspector/DOMNodePreview.js b/src/dom-inspector/DOMNodePreview.js
index 0ecae54..ba8bd26 100644
--- a/src/dom-inspector/DOMNodePreview.js
+++ b/src/dom-inspector/DOMNodePreview.js
@@ -1,16 +1,14 @@
import React from 'react';
import PropTypes from 'prop-types';
-import createStyles from '../styles/createStyles';
+import { useStyles } from '../styles';
import shouldInline from './shouldInline';
const OpenTag = ({ tagName, attributes, styles }) => {
return (
{'<'}
-
- {tagName}
-
+ {tagName}
{(() => {
if (attributes) {
@@ -19,11 +17,12 @@ const OpenTag = ({ tagName, attributes, styles }) => {
const attribute = attributes[i];
attributeNodes.push(
- {' '}{attribute.name}
+ {' '}
+ {attribute.name}
{'="'}
{attribute.value}
{'"'}
- ,
+
);
}
return attributeNodes;
@@ -36,14 +35,14 @@ const OpenTag = ({ tagName, attributes, styles }) => {
};
// isChildNode style={{ marginLeft: -12 /* hack: offset placeholder */ }}
-const CloseTag = ({ tagName, isChildNode = false, styles }) =>
-
+const CloseTag = ({ tagName, isChildNode = false, styles }) => (
+
{''}
-
- {tagName}
-
+ {tagName}
{'>'}
- ;
+
+);
const nameByNodeType = {
1: 'ELEMENT_NODE',
@@ -55,11 +54,17 @@ const nameByNodeType = {
11: 'DOCUMENT_FRAGMENT_NODE',
};
-const DOMNodePreview = ({ isCloseTag, data, expanded }, { theme }) => {
- const styles = createStyles('DOMNodePreview', theme);
+const DOMNodePreview = ({ isCloseTag, data, expanded }) => {
+ const styles = useStyles('DOMNodePreview');
if (isCloseTag) {
- return ;
+ return (
+
+ );
}
switch (data.nodeType) {
@@ -74,21 +79,15 @@ const DOMNodePreview = ({ isCloseTag, data, expanded }, { theme }) => {
{shouldInline(data) ? data.textContent : !expanded && '…'}
- {!expanded && }
+ {!expanded && (
+
+ )}
);
case Node.TEXT_NODE:
- return (
-
- {data.textContent}
-
- );
+ return {data.textContent};
case Node.CDATA_SECTION_NODE:
- return (
-
- {''}
-
- );
+ return {''};
case Node.COMMENT_NODE:
return (
@@ -98,11 +97,7 @@ const DOMNodePreview = ({ isCloseTag, data, expanded }, { theme }) => {
);
case Node.PROCESSING_INSTRUCTION_NODE:
- return (
-
- {data.nodeName}
-
- );
+ return {data.nodeName};
case Node.DOCUMENT_TYPE_NODE:
return (
@@ -115,23 +110,11 @@ const DOMNodePreview = ({ isCloseTag, data, expanded }, { theme }) => {
);
case Node.DOCUMENT_NODE:
- return (
-
- {data.nodeName}
-
- );
+ return {data.nodeName};
case Node.DOCUMENT_FRAGMENT_NODE:
- return (
-
- {data.nodeName}
-
- );
+ return {data.nodeName};
default:
- return (
-
- {nameByNodeType[data.nodeType]}
-
- );
+ return {nameByNodeType[data.nodeType]};
}
};
@@ -146,8 +129,4 @@ DOMNodePreview.propTypes = {
expanded: PropTypes.bool.isRequired,
};
-DOMNodePreview.contextTypes = {
- theme: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired,
-};
-
export default DOMNodePreview;
diff --git a/src/object-inspector/ObjectInspector.js b/src/object-inspector/ObjectInspector.js
index a6bab27..9f2a2fa 100644
--- a/src/object-inspector/ObjectInspector.js
+++ b/src/object-inspector/ObjectInspector.js
@@ -1,15 +1,16 @@
-import React, { Component } from 'react';
+import React from 'react';
import PropTypes from 'prop-types';
import TreeView from '../tree-view/TreeView';
import ObjectRootLabel from './ObjectRootLabel';
import ObjectLabel from './ObjectLabel';
-import ThemeProvider from '../styles/ThemeProvider';
+import { themeAcceptor } from '../styles';
const createIterator = (showNonenumerable, sortObjectKeys) => {
const objectIterator = function*(data) {
- const shouldIterate = (typeof data === 'object' && data !== null) || typeof data === 'function';
+ const shouldIterate =
+ (typeof data === 'object' && data !== null) || typeof data === 'function';
if (!shouldIterate) return;
const dataIsArray = Array.isArray(data);
@@ -85,54 +86,50 @@ const createIterator = (showNonenumerable, sortObjectKeys) => {
};
const defaultNodeRenderer = ({ depth, name, data, isNonenumerable }) =>
- depth === 0
- ?
- : ;
+ depth === 0 ? (
+
+ ) : (
+
+ );
/**
* Tree-view for objects
*/
-class ObjectInspector extends Component {
- static defaultProps = {
- showNonenumerable: false,
-
- theme: 'chromeLight',
- };
-
- static propTypes = {
- /** An integer specifying to which level the tree should be initially expanded. */
- expandLevel: PropTypes.number,
- /** An array containing all the paths that should be expanded when the component is initialized, or a string of just one path */
- expandPaths: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
-
- name: PropTypes.string,
- /** Not required prop because we also allow undefined value */
- data: PropTypes.any,
-
- /** A known theme or theme object */
- theme: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
-
- /** Show non-enumerable properties */
- showNonenumerable: PropTypes.bool,
- /** Sort object keys with optional compare function. */
- sortObjectKeys: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),
+const ObjectInspector = ({
+ showNonenumerable = false,
+ sortObjectKeys,
+ nodeRenderer,
+ ...treeViewProps
+}) => {
+ const dataIterator = createIterator(showNonenumerable, sortObjectKeys);
+ const renderer = nodeRenderer ? nodeRenderer : defaultNodeRenderer;
+
+ return (
+
+ );
+};
- /** Provide a custom nodeRenderer */
- nodeRenderer: PropTypes.func,
- };
+ObjectInspector.propTypes = {
+ /** An integer specifying to which level the tree should be initially expanded. */
+ expandLevel: PropTypes.number,
+ /** An array containing all the paths that should be expanded when the component is initialized, or a string of just one path */
+ expandPaths: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
- render() {
- const { showNonenumerable, sortObjectKeys, nodeRenderer, ...rest } = this.props;
- const dataIterator = createIterator(showNonenumerable, sortObjectKeys);
+ name: PropTypes.string,
+ /** Not required prop because we also allow undefined value */
+ data: PropTypes.any,
- const renderer = nodeRenderer ? nodeRenderer : defaultNodeRenderer;
+ /** Show non-enumerable properties */
+ showNonenumerable: PropTypes.bool,
+ /** Sort object keys with optional compare function. */
+ sortObjectKeys: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),
- return (
-
-
-
- );
- }
-}
+ /** Provide a custom nodeRenderer */
+ nodeRenderer: PropTypes.func,
+};
-export default ObjectInspector;
+export default themeAcceptor(ObjectInspector);
diff --git a/src/object-inspector/ObjectInspector.spec.js b/src/object-inspector/ObjectInspector.spec.js
index 87eddd1..1e7d602 100644
--- a/src/object-inspector/ObjectInspector.spec.js
+++ b/src/object-inspector/ObjectInspector.spec.js
@@ -1,27 +1,20 @@
import React from 'react';
-import ShallowRenderer from 'react-test-renderer/shallow';
+import TestRenderer from 'react-test-renderer';
import ObjectInspector from './ObjectInspector';
-const TestRenderer = new ShallowRenderer();
-
describe('ObjectInspector', () => {
it('should render', () => {
- const tree = TestRenderer.render();
-
- expect(tree).toMatchSnapshot();
-
- expect(tree.type).toBeInstanceOf(Function);
- expect(tree.props.theme).toEqual('testvalue');
+ const tree = TestRenderer.create();
+ expect(tree).toMatchSnapshot();
});
it('passes `nodeRenderer` prop to ', () => {
- // Test that a custom `nodeRenderer` props is passed to
const nodeRenderer = () => unit test;
- const tree = TestRenderer.render();
- expect(tree).toMatchSnapshot();
-
- expect(tree.props.children.type).toBeInstanceOf(Function);
- expect(tree.props.children.props.nodeRenderer).toEqual(nodeRenderer);
+ const tree = TestRenderer.create(
+
+ );
+
+ expect(tree).toMatchSnapshot();
});
});
diff --git a/src/object-inspector/ObjectLabel.js b/src/object-inspector/ObjectLabel.js
index 2b9a8a4..ef3885a 100644
--- a/src/object-inspector/ObjectLabel.js
+++ b/src/object-inspector/ObjectLabel.js
@@ -6,7 +6,7 @@ import ObjectValue from '../object/ObjectValue';
/**
* if isNonenumerable is specified, render the name dimmed
*/
-const ObjectLabel = ({ name, data, isNonenumerable }) => {
+const ObjectLabel = ({ name, data, isNonenumerable = false }) => {
const object = data;
return (
@@ -23,8 +23,4 @@ ObjectLabel.propTypes = {
isNonenumerable: PropTypes.bool,
};
-ObjectLabel.defaultProps = {
- isNonenumerable: false,
-};
-
export default ObjectLabel;
diff --git a/src/object-inspector/ObjectPreview.js b/src/object-inspector/ObjectPreview.js
index 28a902e..99438c2 100644
--- a/src/object-inspector/ObjectPreview.js
+++ b/src/object-inspector/ObjectPreview.js
@@ -23,7 +23,7 @@ function intersperse(arr, sep) {
/**
* A preview of the object
*/
-const ObjectPreview = ({ data, maxProperties }) => {
+const ObjectPreview = ({ data, maxProperties = 5 }) => {
const object = data;
if (
@@ -45,11 +45,7 @@ const ObjectPreview = ({ data, maxProperties }) => {
return (
{`Array(${object.length})`}
-
- [
- {intersperse(previewArray, ",")}
- ]
-
+ [{intersperse(previewArray, ',')}]
);
} else {
@@ -70,7 +66,7 @@ const ObjectPreview = ({ data, maxProperties }) => {
:
{ellipsis}
- ,
+
);
if (ellipsis) break;
}
@@ -92,8 +88,5 @@ ObjectPreview.propTypes = {
*/
maxProperties: PropTypes.number,
};
-ObjectPreview.defaultProps = {
- maxProperties: 5,
-};
export default ObjectPreview;
diff --git a/src/object-inspector/__snapshots__/ObjectInspector.spec.js.snap b/src/object-inspector/__snapshots__/ObjectInspector.spec.js.snap
index 823860b..c6129da 100644
--- a/src/object-inspector/__snapshots__/ObjectInspector.spec.js.snap
+++ b/src/object-inspector/__snapshots__/ObjectInspector.spec.js.snap
@@ -1,27 +1,83 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ObjectInspector passes \`nodeRenderer\` prop to 1`] = `
-
-
+
+ unit test
+
+
+
-
+
`;
exports[`ObjectInspector should render 1`] = `
-
-
+
+ undefined
+
+
+
-
+
`;
diff --git a/src/object/ObjectName.js b/src/object/ObjectName.js
index 5b23da2..5015e19 100644
--- a/src/object/ObjectName.js
+++ b/src/object/ObjectName.js
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import createStyles from '../styles/createStyles';
+import { useStyles } from '../styles';
/**
* A view for object property names.
@@ -11,19 +11,15 @@ import createStyles from '../styles/createStyles';
* If the property name is not enumerable (`Object.prototype.propertyIsEnumerable()`),
* the property name will be dimmed to show the difference.
*/
-const ObjectName = ({ name, dimmed, styles }, { theme }) => {
- const themeStyles = createStyles('ObjectName', theme);
+const ObjectName = ({ name, dimmed = false, styles = {} }) => {
+ const themeStyles = useStyles('ObjectName');
const appliedStyles = {
...themeStyles.base,
...(dimmed ? themeStyles['dimmed'] : {}),
...styles,
};
- return (
-
- {name}
-
- );
+ return {name};
};
ObjectName.propTypes = {
@@ -33,12 +29,4 @@ ObjectName.propTypes = {
dimmed: PropTypes.bool,
};
-ObjectName.defaultProps = {
- dimmed: false,
-};
-
-ObjectName.contextTypes = {
- theme: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
-};
-
export default ObjectName;
diff --git a/src/object/ObjectValue.js b/src/object/ObjectValue.js
index 91a10e2..df55c84 100644
--- a/src/object/ObjectValue.js
+++ b/src/object/ObjectValue.js
@@ -1,35 +1,26 @@
import React from 'react';
import PropTypes from 'prop-types';
-import createStyles from '../styles/createStyles';
+
+import { useStyles } from '../styles';
/**
* A short description of the object values.
* Can be used to render tree node in ObjectInspector
* or render objects in TableInspector.
*/
-const ObjectValue = ({ object, styles }, { theme }) => {
- const themeStyles = createStyles('ObjectValue', theme);
+const ObjectValue = ({ object, styles }) => {
+ const themeStyles = useStyles('ObjectValue');
const mkStyle = key => ({ ...themeStyles[key], ...styles });
switch (typeof object) {
case 'number':
- return (
-
- {String(object)}
-
- );
+ return {String(object)};
case 'string':
- return (
-
- "{object}"
-
- );
+ return "{object}";
case 'boolean':
return (
-
- {String(object)}
-
+ {String(object)}
);
case 'undefined':
return undefined;
@@ -38,17 +29,11 @@ const ObjectValue = ({ object, styles }, { theme }) => {
return null;
}
if (object instanceof Date) {
- return (
-
- {object.toString()}
-
- );
+ return {object.toString()};
}
if (object instanceof RegExp) {
return (
-
- {object.toString()}
-
+ {object.toString()}
);
}
if (Array.isArray(object)) {
@@ -57,15 +42,14 @@ const ObjectValue = ({ object, styles }, { theme }) => {
if (!object.constructor) {
return Object;
}
- if (typeof object.constructor.isBuffer === 'function' && object.constructor.isBuffer(object)) {
+ if (
+ typeof object.constructor.isBuffer === 'function' &&
+ object.constructor.isBuffer(object)
+ ) {
return {`Buffer[${object.length}]`};
}
- return (
-
- {object.constructor.name}
-
- );
+ return {object.constructor.name};
case 'function':
return (
@@ -77,9 +61,7 @@ const ObjectValue = ({ object, styles }, { theme }) => {
);
case 'symbol':
return (
-
- {object.toString()}
-
+ {object.toString()}
);
default:
return ;
@@ -87,12 +69,8 @@ const ObjectValue = ({ object, styles }, { theme }) => {
};
ObjectValue.propTypes = {
- /** the object to describe */
+ // the object to describe
object: PropTypes.any,
};
-ObjectValue.contextTypes = {
- theme: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
-};
-
export default ObjectValue;
diff --git a/src/object/ObjectValue.spec.js b/src/object/ObjectValue.spec.js
index dcb7104..538d944 100644
--- a/src/object/ObjectValue.spec.js
+++ b/src/object/ObjectValue.spec.js
@@ -15,7 +15,9 @@ describe('ObjectValue', () => {
});
it('should render string with quotes', () => {
- const tree = TestRenderer.create().toJSON();
+ const tree = TestRenderer.create(
+
+ ).toJSON();
expect(tree.type).toBe('span');
expect(tree.children).toEqual(['"', 'octocat', '"']);
});
@@ -27,7 +29,9 @@ describe('ObjectValue', () => {
});
it('should render undefined', () => {
- const tree = TestRenderer.create().toJSON();
+ const tree = TestRenderer.create(
+
+ ).toJSON();
expect(tree.type).toBe('span');
expect(tree.children).toEqual(['undefined']);
});
@@ -47,7 +51,9 @@ describe('ObjectValue', () => {
});
it('should render array with length information', () => {
- const tree = TestRenderer.create().toJSON();
+ const tree = TestRenderer.create(
+
+ ).toJSON();
expect(tree.type).toBe('span');
expect(tree.children).toEqual(['Array(5)']);
});
@@ -59,13 +65,17 @@ describe('ObjectValue', () => {
});
it('should render a simple object', () => {
- const tree = TestRenderer.create().toJSON();
+ const tree = TestRenderer.create(
+
+ ).toJSON();
expect(tree.type).toBe('span');
expect(tree.children).toEqual(['Object']);
});
it('should render a null prototyped object', () => {
- const tree = TestRenderer.create().toJSON();
+ const tree = TestRenderer.create(
+
+ ).toJSON();
expect(tree.type).toBe('span');
expect(tree.children).toEqual(['Object']);
});
@@ -97,13 +107,17 @@ describe('ObjectValue', () => {
*/
it('should render a symbol', () => {
- const tree = TestRenderer.create().toJSON();
+ const tree = TestRenderer.create(
+
+ ).toJSON();
expect(tree.type).toBe('span');
expect(tree.children).toEqual(['Symbol()']);
});
it('should render a symbol foo', () => {
- const tree = TestRenderer.create().toJSON();
+ const tree = TestRenderer.create(
+
+ ).toJSON();
expect(tree.type).toBe('span');
expect(tree.children).toEqual(['Symbol(foo)']);
});
@@ -111,7 +125,9 @@ describe('ObjectValue', () => {
it('accepts and applies style from `styles` prop', () => {
// Custom `styles` prop gets applied to the element
const style = { color: 'blue' };
- const tree = TestRenderer.create().toJSON();
+ const tree = TestRenderer.create(
+
+ ).toJSON();
expect(tree.props.style.color).toEqual('blue');
});
});
diff --git a/src/styles/ThemeProvider.js b/src/styles/ThemeProvider.js
deleted file mode 100644
index 9f4123e..0000000
--- a/src/styles/ThemeProvider.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import { Component } from 'react';
-import PropTypes from 'prop-types';
-
-class ThemeProvider extends Component {
- getChildContext() {
- const theme = this.props.theme;
-
- return {
- // createStyles: createStyles
- theme: theme,
- };
- }
-
- render() {
- return this.props.children;
- }
-}
-
-ThemeProvider.childContextTypes = {
- theme: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
-};
-
-export default ThemeProvider;
diff --git a/src/styles/createStyles.js b/src/styles/createStyles.js
deleted file mode 100644
index bdf0300..0000000
--- a/src/styles/createStyles.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import * as themes from './themes';
-import base from './base';
-
-const styles = Object.keys(themes).reduce((styles, themeName) => {
- styles[themeName] = base(themes[themeName]);
- return styles;
-}, {});
-
-const createStyles = (key, theme) => {
- // console.debug(styles, theme, styles[theme])
- if (typeof theme === 'string') {
- return styles[theme][key];
- } else if (typeof theme === 'object') {
- return base(theme)[key];
- }
- // Default styles
- return styles['chromeLight'][key];
-};
-
-export default createStyles;
diff --git a/src/styles/index.js b/src/styles/index.js
new file mode 100644
index 0000000..864fe49
--- /dev/null
+++ b/src/styles/index.js
@@ -0,0 +1 @@
+export { useStyles, themeAcceptor } from './styles';
diff --git a/src/styles/styles.js b/src/styles/styles.js
new file mode 100644
index 0000000..fdc9d8d
--- /dev/null
+++ b/src/styles/styles.js
@@ -0,0 +1,51 @@
+import PropTypes from 'prop-types';
+import React, { createContext, useContext, useMemo } from 'react';
+
+import * as themes from './themes';
+import base from './base';
+
+const DEFAULT_THEME_NAME = 'chromeLight';
+
+const ThemeContext = createContext(base(themes[DEFAULT_THEME_NAME]));
+
+/**
+ * Hook to get the component styles for the current theme.
+ * @param {string} baseStylesKey - Name of the component to be styled
+ */
+export const useStyles = baseStylesKey => {
+ const themeStyles = useContext(ThemeContext);
+ return themeStyles[baseStylesKey];
+};
+
+/**
+ * HOC to create a component that accepts a "theme" prop and uses it to set
+ * the current theme. This is intended to be used by the top-level inspector
+ * components.
+ * @param {Object} WrappedComponent - React component to be wrapped
+ */
+export const themeAcceptor = WrappedComponent => {
+ const ThemeAcceptor = ({ theme = DEFAULT_THEME_NAME, ...restProps }) => {
+ const themeStyles = useMemo(() => {
+ switch (Object.prototype.toString.call(theme)) {
+ case '[object String]':
+ return base(themes[theme]);
+ case '[object Object]':
+ return base(theme);
+ default:
+ return base(themes[DEFAULT_THEME_NAME]);
+ }
+ }, [theme]);
+
+ return (
+
+
+
+ );
+ };
+
+ ThemeAcceptor.propTypes = {
+ theme: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
+ };
+
+ return ThemeAcceptor;
+};
diff --git a/src/table-inspector/DataContainer.js b/src/table-inspector/DataContainer.js
index a52b3da..1395592 100644
--- a/src/table-inspector/DataContainer.js
+++ b/src/table-inspector/DataContainer.js
@@ -1,22 +1,20 @@
import React from 'react';
-import PropTypes from 'prop-types';
-import createStyles from '../styles/createStyles';
import ObjectValue from '../object/ObjectValue';
-const DataContainer = ({ rows, columns, rowsData }, { theme }) => {
- const styles = createStyles('TableInspectorDataContainer', theme);
- const borderStyles = createStyles('TableInspectorLeftBorder', theme);
+import { useStyles } from '../styles';
+
+const DataContainer = ({ rows, columns, rowsData }) => {
+ const styles = useStyles('TableInspectorDataContainer');
+ const borderStyles = useStyles('TableInspectorLeftBorder');
return (
- {rows.map((row, i) =>
+ {rows.map((row, i) => (
-
- {row}
- |
+ {row} |
{columns.map(column => {
const rowData = rowsData[i];
@@ -36,24 +34,27 @@ const DataContainer = ({ rows, columns, rowsData }, { theme }) => {
rowData.hasOwnProperty(column)
) {
return (
-
+ |
|
);
} else {
- return | ;
+ return (
+ |
+ );
}
})}
-
,
- )}
+
+ ))}
);
};
-DataContainer.contextTypes = {
- theme: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired,
-};
-
export default DataContainer;
diff --git a/src/table-inspector/HeaderContainer.js b/src/table-inspector/HeaderContainer.js
index 9166e7e..64bbc1b 100644
--- a/src/table-inspector/HeaderContainer.js
+++ b/src/table-inspector/HeaderContainer.js
@@ -1,23 +1,19 @@
import React from 'react';
-import PropTypes from 'prop-types';
-import createStyles from '../styles/createStyles';
+import { useStyles } from '../styles';
import TH from './TH';
-const HeaderContainer = (
- {
- indexColumnText,
- columns,
- sorted,
- sortIndexColumn,
- sortColumn,
- sortAscending,
- onTHClick,
- onIndexTHClick,
- },
- { theme },
-) => {
- const styles = createStyles('TableInspectorHeaderContainer', theme);
- const borderStyles = createStyles('TableInspectorLeftBorder', theme);
+const HeaderContainer = ({
+ indexColumnText = '(index)',
+ columns = [],
+ sorted,
+ sortIndexColumn,
+ sortColumn,
+ sortAscending,
+ onTHClick,
+ onIndexTHClick,
+}) => {
+ const styles = useStyles('TableInspectorHeaderContainer');
+ const borderStyles = useStyles('TableInspectorLeftBorder');
return (
@@ -27,21 +23,19 @@ const HeaderContainer = (
borderStyle={borderStyles.none}
sorted={sorted && sortIndexColumn}
sortAscending={sortAscending}
- onClick={onIndexTHClick}
- >
+ onClick={onIndexTHClick}>
{indexColumnText}
- {columns.map(column =>
+ {columns.map(column => (
+ onClick={onTHClick.bind(this, column)}>
{column}
- | ,
- )}
+
+ ))}
@@ -49,13 +43,4 @@ const HeaderContainer = (
);
};
-HeaderContainer.defaultProps = {
- indexColumnText: '(index)',
- columns: [],
-};
-
-HeaderContainer.contextTypes = {
- theme: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired,
-};
-
export default HeaderContainer;
diff --git a/src/table-inspector/TH.js b/src/table-inspector/TH.js
index 77788ca..6f6ee2a 100644
--- a/src/table-inspector/TH.js
+++ b/src/table-inspector/TH.js
@@ -1,9 +1,8 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
+import React, { useCallback, useState } from 'react';
-import createStyles from '../styles/createStyles';
+import { useStyles } from '../styles';
-const SortIconContainer = props =>
+const SortIconContainer = props => (
bottom: 1,
display: 'flex',
alignItems: 'center',
- }}
- >
+ }}>
{props.children}
-
;
+
+);
-const SortIcon = ({ sortAscending }, { theme }) => {
+const SortIcon = ({ sortAscending }) => {
+ const styles = useStyles('TableInspectorSortIcon');
const glyph = sortAscending ? '▲' : '▼';
- const styles = createStyles('TableInspectorSortIcon', theme);
- return (
-
- {glyph}
-
- );
+ return {glyph}
;
};
-SortIcon.contextTypes = {
- theme: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired,
-};
-
-class TH extends Component {
- state = { hovered: false };
-
- toggleHovered(hovered) {
- this.setState({ hovered: hovered });
- }
+const TH = ({
+ sortAscending = false,
+ sorted = false,
+ onClick = undefined,
+ borderStyle = {},
+ children,
+ ...thProps
+}) => {
+ const styles = useStyles('TableInspectorTH');
+ const [hovered, setHovered] = useState(false);
- render() {
- // either not sorted, sort ascending or sort descending
- const {
- borderStyle,
- children,
- onClick,
- sortAscending,
- sorted,
- ...props
- } = this.props;
- const { theme } = this.context;
- const styles = createStyles('TableInspectorTH', theme);
+ const handleMouseEnter = useCallback(() => setHovered(true), []);
+ const handleMouseLeave = useCallback(() => setHovered(false), []);
- return (
-
-
- {children}
-
- {sorted && (
-
-
-
- )}
- |
- );
- }
-}
-
-TH.contextTypes = {
- theme: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired,
-};
-
-TH.defaultProps = {
- sortAscending: false,
- sorted: false,
- onClick: undefined,
+ return (
+
+ {children}
+ {sorted && (
+
+
+
+ )}
+ |
+ );
};
export default TH;
diff --git a/src/table-inspector/TableInspector.js b/src/table-inspector/TableInspector.js
index a4b1ee9..5a290f0 100644
--- a/src/table-inspector/TableInspector.js
+++ b/src/table-inspector/TableInspector.js
@@ -4,45 +4,49 @@
* https://developer.mozilla.org/en-US/docs/Web/API/Console/table
*/
-import React, { Component } from 'react';
+import React, { useCallback, useState } from 'react';
import PropTypes from 'prop-types';
-import ThemeProvider from '../styles/ThemeProvider';
-import createStyles from '../styles/createStyles';
import getHeaders from './getHeaders';
import DataContainer from './DataContainer';
import HeaderContainer from './HeaderContainer';
-export default class TableInspector extends Component {
- constructor(props) {
- super(props);
-
- this.state = {
- sorted: false, // has user ever clicked the tag to sort?
- sortIndexColumn: false, // is index column sorted?
- sortColumn: undefined, // which column is sorted?
- sortAscending: false, // is sorting ascending or descending?
- };
- }
-
- handleIndexTHClick() {
- this.setState(({
- sortIndexColumn,
- sortAscending
- }) => ({
+import { themeAcceptor, useStyles } from '../styles';
+
+const TableInspector = ({
+ // The JS object you would like to inspect, either an array or an object
+ data,
+ // An array of the names of the columns you'd like to display in the table
+ columns,
+}) => {
+ const styles = useStyles('TableInspector');
+
+ const [
+ { sorted, sortIndexColumn, sortColumn, sortAscending },
+ setState,
+ ] = useState({
+ // has user ever clicked the | tag to sort?
+ sorted: false,
+ // is index column sorted?
+ sortIndexColumn: false,
+ // which column is sorted?
+ sortColumn: undefined,
+ // is sorting ascending or descending?
+ sortAscending: false,
+ });
+
+ const handleIndexTHClick = useCallback(() => {
+ setState(({ sortIndexColumn, sortAscending }) => ({
sorted: true,
sortIndexColumn: true,
sortColumn: undefined,
// when changed to a new column, default to asending
sortAscending: sortIndexColumn ? !sortAscending : true,
}));
- }
+ }, []);
- handleTHClick(col) {
- this.setState(({
- sortColumn,
- sortAscending
- }) => ({
+ const handleTHClick = useCallback(col => {
+ setState(({ sortColumn, sortAscending }) => ({
sorted: true,
sortIndexColumn: false,
// update sort column
@@ -50,121 +54,111 @@ export default class TableInspector extends Component {
// when changed to a new column, default to asending
sortAscending: col === sortColumn ? !sortAscending : true,
}));
- }
-
- render() {
- const data = this.props.data;
- const columns = this.props.columns;
+ }, []);
- const { theme } = this.props;
- const styles = createStyles('TableInspector', theme);
-
- if (typeof data !== 'object' || data === null) {
- return ;
- }
-
- let { rowHeaders, colHeaders } = getHeaders(data);
-
- // columns to be displayed are specified
- // NOTE: there's some space for optimization here
- if (columns !== undefined) {
- colHeaders = columns;
- }
+ if (typeof data !== 'object' || data === null) {
+ return ;
+ }
- let rowsData = rowHeaders.map(rowHeader => data[rowHeader]);
+ let { rowHeaders, colHeaders } = getHeaders(data);
- const sortIndexColumn = this.state.sortIndexColumn,
- sortColumn = this.state.sortColumn,
- sortAscending = this.state.sortAscending;
+ // columns to be displayed are specified
+ // NOTE: there's some space for optimization here
+ if (columns !== undefined) {
+ colHeaders = columns;
+ }
- let columnDataWithRowIndexes; /* row indexes are [0..nRows-1] */
- // TODO: refactor
- if (sortColumn !== undefined) {
- // the column to be sorted (rowsData, column) => [[columnData, rowIndex]]
- columnDataWithRowIndexes = rowsData.map((rowData, index) => {
- // normalize rowData
- if (
- typeof rowData === 'object' &&
- rowData !== null /*&& rowData.hasOwnProperty(sortColumn)*/
- ) {
- const columnData = rowData[sortColumn];
- return [columnData, index];
- }
- return [undefined, index];
- });
- } else {
- if (sortIndexColumn) {
- columnDataWithRowIndexes = rowHeaders.map((rowData, index) => {
- const columnData = rowHeaders[index];
- return [columnData, index];
- });
+ let rowsData = rowHeaders.map(rowHeader => data[rowHeader]);
+
+ let columnDataWithRowIndexes; /* row indexes are [0..nRows-1] */
+ // TODO: refactor
+ if (sortColumn !== undefined) {
+ // the column to be sorted (rowsData, column) => [[columnData, rowIndex]]
+ columnDataWithRowIndexes = rowsData.map((rowData, index) => {
+ // normalize rowData
+ if (
+ typeof rowData === 'object' &&
+ rowData !== null /*&& rowData.hasOwnProperty(sortColumn)*/
+ ) {
+ const columnData = rowData[sortColumn];
+ return [columnData, index];
}
+ return [undefined, index];
+ });
+ } else {
+ if (sortIndexColumn) {
+ columnDataWithRowIndexes = rowHeaders.map((rowData, index) => {
+ const columnData = rowHeaders[index];
+ return [columnData, index];
+ });
}
- if (columnDataWithRowIndexes !== undefined) {
- // apply a mapper before sorting (because we need to access inside a container)
- const comparator = (mapper, ascending) => {
- return (a, b) => {
- const v1 = mapper(a); // the datum
- const v2 = mapper(b);
- const type1 = typeof v1;
- const type2 = typeof v2;
- // use '<' operator to compare same type of values or compare type precedence order #
- const lt = (v1, v2) => {
- if (v1 < v2) {
- return -1;
- } else if (v1 > v2) {
- return 1;
- } else {
- return 0;
- }
- };
- let result;
- if (type1 === type2) {
- result = lt(v1, v2);
+ }
+ if (columnDataWithRowIndexes !== undefined) {
+ // apply a mapper before sorting (because we need to access inside a container)
+ const comparator = (mapper, ascending) => {
+ return (a, b) => {
+ const v1 = mapper(a); // the datum
+ const v2 = mapper(b);
+ const type1 = typeof v1;
+ const type2 = typeof v2;
+ // use '<' operator to compare same type of values or compare type precedence order #
+ const lt = (v1, v2) => {
+ if (v1 < v2) {
+ return -1;
+ } else if (v1 > v2) {
+ return 1;
} else {
- // order of different types
- const order = {
- string: 0,
- number: 1,
- object: 2,
- symbol: 3,
- boolean: 4,
- undefined: 5,
- function: 6,
- };
- result = lt(order[type1], order[type2]);
+ return 0;
}
- // reverse result if descending
- if (!ascending) result = -result;
- return result;
};
+ let result;
+ if (type1 === type2) {
+ result = lt(v1, v2);
+ } else {
+ // order of different types
+ const order = {
+ string: 0,
+ number: 1,
+ object: 2,
+ symbol: 3,
+ boolean: 4,
+ undefined: 5,
+ function: 6,
+ };
+ result = lt(order[type1], order[type2]);
+ }
+ // reverse result if descending
+ if (!ascending) result = -result;
+ return result;
};
- const sortedRowIndexes = columnDataWithRowIndexes
- .sort(comparator(item => item[0], sortAscending))
- .map(item => item[1]); // sorted row indexes
- rowHeaders = sortedRowIndexes.map(i => rowHeaders[i]);
- rowsData = sortedRowIndexes.map(i => rowsData[i]);
- }
-
- return (
-
-
-
-
-
-
- );
+ };
+ const sortedRowIndexes = columnDataWithRowIndexes
+ .sort(comparator(item => item[0], sortAscending))
+ .map(item => item[1]); // sorted row indexes
+ rowHeaders = sortedRowIndexes.map(i => rowHeaders[i]);
+ rowsData = sortedRowIndexes.map(i => rowsData[i]);
}
-}
+
+ return (
+
+
+
+
+ );
+};
TableInspector.propTypes = {
/**
@@ -177,8 +171,4 @@ TableInspector.propTypes = {
columns: PropTypes.array,
};
-TableInspector.defaultProps = {
- data: undefined,
- columns: undefined,
- theme: 'chromeLight',
-};
+export default themeAcceptor(TableInspector);
diff --git a/src/tree-view/ExpandedPathsContext.js b/src/tree-view/ExpandedPathsContext.js
new file mode 100644
index 0000000..b37cb2c
--- /dev/null
+++ b/src/tree-view/ExpandedPathsContext.js
@@ -0,0 +1,5 @@
+import { createContext } from 'react';
+
+const ExpandedPathsContext = createContext([{}, () => {}]);
+
+export default ExpandedPathsContext;
diff --git a/src/tree-view/TreeNode.js b/src/tree-view/TreeNode.js
index 8da8cd3..e21f7aa 100644
--- a/src/tree-view/TreeNode.js
+++ b/src/tree-view/TreeNode.js
@@ -1,77 +1,71 @@
-import React, { createElement, Component, Children } from 'react';
+import React, { Children, memo } from 'react';
import PropTypes from 'prop-types';
-
-import createStyles from '../styles/createStyles';
-
-const Arrow = ({ expanded, styles }) =>
- ▶;
-
-class TreeNode extends Component {
- render() {
- const {
- expanded,
- onClick,
- children,
- nodeRenderer,
- title,
- shouldShowArrow,
- shouldShowPlaceholder,
- } = this.props;
-
- const { theme } = this.context;
- const styles = createStyles('TreeNode', theme);
-
- const renderedNode = createElement(nodeRenderer, this.props);
- const childNodes = expanded ? children : undefined;
-
- return (
-
-
- {shouldShowArrow || Children.count(children) > 0
- ?
- : shouldShowPlaceholder && }
- {renderedNode}
-
-
-
- {childNodes}
-
-
- );
- }
-}
+import { useStyles } from '../styles';
+
+const Arrow = ({ expanded, styles }) => (
+
+ ▶
+
+);
+
+const TreeNode = memo(props => {
+ props = {
+ expanded: true,
+ nodeRenderer: ({ name }) => {name},
+ onClick: () => {},
+ shouldShowArrow: false,
+ shouldShowPlaceholder: true,
+ ...props,
+ };
+ const {
+ expanded,
+ onClick,
+ children,
+ nodeRenderer,
+ title,
+ shouldShowArrow,
+ shouldShowPlaceholder,
+ } = props;
+
+ const styles = useStyles('TreeNode');
+ const NodeRenderer = nodeRenderer;
+
+ return (
+
+
+ {shouldShowArrow || Children.count(children) > 0 ? (
+
+ ) : (
+ shouldShowPlaceholder && (
+
+ )
+ )}
+
+
+
+
+ {expanded ? children : undefined}
+
+
+ );
+});
TreeNode.propTypes = {
name: PropTypes.string,
data: PropTypes.any,
-
expanded: PropTypes.bool,
shouldShowArrow: PropTypes.bool,
shouldShowPlaceholder: PropTypes.bool,
-
nodeRenderer: PropTypes.func,
-
onClick: PropTypes.func,
};
-TreeNode.defaultProps = {
- name: undefined,
- data: undefined,
- expanded: true,
-
- nodeRenderer: ({ name }) =>
-
- {name}
- ,
-
- onClick: () => {},
-
- shouldShowArrow: false,
- shouldShowPlaceholder: true,
-};
-
-TreeNode.contextTypes = {
- theme: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired,
-};
-
export default TreeNode;
diff --git a/src/tree-view/TreeView.js b/src/tree-view/TreeView.js
index 900c80d..b1fe7be 100644
--- a/src/tree-view/TreeView.js
+++ b/src/tree-view/TreeView.js
@@ -1,192 +1,117 @@
-import React, { Component } from 'react';
+import React, {
+ useContext,
+ useCallback,
+ useLayoutEffect,
+ useState,
+ memo,
+} from 'react';
import PropTypes from 'prop-types';
-
+import ExpandedPathsContext from './ExpandedPathsContext';
import TreeNode from './TreeNode';
-
-import { DEFAULT_ROOT_PATH, hasChildNodes, getExpandedPaths } from './pathUtils';
-
-const reducer = (state, action) => {
- switch (action.type) {
- case 'TOGGLE_EXPAND': {
- const path = action.path;
- const expandedPaths = state.expandedPaths;
- const expanded = !!expandedPaths[path];
-
- return Object.assign({}, state, {
- expandedPaths: Object.assign({}, state.expandedPaths, { [path]: !expanded }),
- });
- }
- default:
- return state;
- }
-};
-
-class ConnectedTreeNode extends Component {
- constructor(props, context) {
- super(props);
-
- this.state = context.store.storeState;
- }
-
- shouldComponentUpdate(nextProps, nextState) {
- return (
- !!nextState.expandedPaths[nextProps.path] !== !!this.state.expandedPaths[this.props.path] ||
- nextProps.data !== this.props.data ||
- nextProps.name !== this.props.name
- );
- }
-
- handleClick(path) {
- this.context.store.storeState = reducer(this.context.store.storeState, {
- type: 'TOGGLE_EXPAND',
- path: path,
- });
- this.setState(this.context.store.storeState);
- }
-
- renderChildNodes(parentData, parentPath) {
- const { dataIterator } = this.props;
- const { depth } = this.props;
-
- const { nodeRenderer } = this.props;
-
- let childNodes = [];
- for (let { name, data, ...props } of dataIterator(parentData)) {
- const key = name;
- const path = `${parentPath}.${key}`;
- childNodes.push(
- ,
- );
- }
- return childNodes;
- }
-
- render() {
- const { data, dataIterator, path, depth } = this.props;
-
- const nodeHasChildNodes = hasChildNodes(data, dataIterator);
- const { expandedPaths } = this.state;
- const expanded = !!expandedPaths[path];
-
- const { nodeRenderer } = this.props;
-
- return (
- {}}
- // show arrow anyway even if not expanded and not rendering children
- shouldShowArrow={nodeHasChildNodes}
- // show placeholder only for non root nodes
- shouldShowPlaceholder={depth > 0}
- // Render a node from name and data (or possibly other props like isNonenumerable)
- nodeRenderer={nodeRenderer}
- {...this.props}
- >
- {// only render if the node is expanded
- expanded ? this.renderChildNodes(data, path) : undefined}
-
- );
- }
-}
+import {
+ DEFAULT_ROOT_PATH,
+ hasChildNodes,
+ getExpandedPaths,
+} from './pathUtils';
+
+const ConnectedTreeNode = memo(props => {
+ const { data, dataIterator, path, depth, nodeRenderer } = props;
+ const [expandedPaths, setExpandedPaths] = useContext(ExpandedPathsContext);
+ const nodeHasChildNodes = hasChildNodes(data, dataIterator);
+ const expanded = !!expandedPaths[path];
+
+ const handleClick = useCallback(
+ () =>
+ nodeHasChildNodes &&
+ setExpandedPaths(prevExpandedPaths => ({
+ ...prevExpandedPaths,
+ [path]: !expanded,
+ })),
+ [nodeHasChildNodes, setExpandedPaths, path, expanded]
+ );
+
+ return (
+ 0}
+ // Render a node from name and data (or possibly other props like isNonenumerable)
+ nodeRenderer={nodeRenderer}
+ {...props}>
+ {// only render if the node is expanded
+ expanded
+ ? [...dataIterator(data)].map(({ name, data, ...renderNodeProps }) => {
+ return (
+
+ );
+ })
+ : null}
+
+ );
+});
ConnectedTreeNode.propTypes = {
name: PropTypes.string,
data: PropTypes.any,
dataIterator: PropTypes.func,
-
depth: PropTypes.number,
expanded: PropTypes.bool,
-
nodeRenderer: PropTypes.func,
};
-ConnectedTreeNode.contextTypes = {
- store: PropTypes.any,
-};
-
-class TreeView extends Component {
- static defaultProps = {
- expandLevel: 0,
- expandPaths: [],
- };
-
- constructor(props) {
- super(props);
-
- this.store = {
- storeState: {
- expandedPaths: getExpandedPaths(
- props.data,
- props.dataIterator,
- props.expandPaths,
- props.expandLevel,
+const TreeView = memo(
+ ({ name, data, dataIterator, nodeRenderer, expandPaths, expandLevel }) => {
+ const stateAndSetter = useState({});
+ const [, setExpandedPaths] = stateAndSetter;
+
+ useLayoutEffect(
+ () =>
+ setExpandedPaths(prevExpandedPaths =>
+ getExpandedPaths(
+ data,
+ dataIterator,
+ expandPaths,
+ expandLevel,
+ prevExpandedPaths
+ )
),
- },
- };
- }
-
- componentWillReceiveProps(nextProps) {
- this.store = {
- storeState: {
- expandedPaths: getExpandedPaths(
- nextProps.data,
- nextProps.dataIterator,
- nextProps.expandPaths,
- nextProps.expandLevel,
- this.store.storeState.expandedPaths,
- ),
- },
- };
- }
-
- getChildContext() {
- return {
- store: this.store,
- };
- }
-
- static childContextTypes = {
- store: PropTypes.any,
- };
-
- render() {
- const { name, data, dataIterator } = this.props;
- const { nodeRenderer } = this.props;
-
- const rootPath = DEFAULT_ROOT_PATH;
+ [data, dataIterator, expandPaths, expandLevel]
+ );
return (
-
+
+
+
);
}
-}
+);
TreeView.propTypes = {
name: PropTypes.string,
data: PropTypes.any,
dataIterator: PropTypes.func,
-
nodeRenderer: PropTypes.func,
-};
-
-TreeView.defaultProps = {
- name: undefined,
+ expandPaths: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
+ expandLevel: PropTypes.number,
};
export default TreeView;
diff --git a/src/tree-view/pathUtils.js b/src/tree-view/pathUtils.js
index c95ebc4..f832cf5 100644
--- a/src/tree-view/pathUtils.js
+++ b/src/tree-view/pathUtils.js
@@ -8,8 +8,8 @@ export function hasChildNodes(data, dataIterator) {
export const wildcardPathsFromLevel = level => {
// i is depth
- return Array.from({ length: level }, (_, i) =>
- [DEFAULT_ROOT_PATH].concat(Array.from({ length: i }, () => '*')).join('.'),
+ return Array.from({length: level}, (_, i) =>
+ [DEFAULT_ROOT_PATH].concat(Array.from({length: i}, () => '*')).join('.'),
);
};
@@ -18,7 +18,7 @@ export const getExpandedPaths = (
dataIterator,
expandPaths,
expandLevel,
- initialState = {},
+ prevExpandedPaths,
) => {
let wildcardPaths = []
.concat(wildcardPathsFromLevel(expandLevel))
@@ -43,7 +43,7 @@ export const getExpandedPaths = (
}
} else {
if (key === WILDCARD) {
- for (let { name, data } of dataIterator(curData)) {
+ for (let {name, data} of dataIterator(curData)) {
if (hasChildNodes(data, dataIterator)) {
populatePaths(data, `${curPath}.${name}`, depth + 1);
}
@@ -60,8 +60,11 @@ export const getExpandedPaths = (
populatePaths(data, '', 0);
});
- return expandedPaths.reduce((obj, path) => {
- obj[path] = true;
- return obj;
- }, initialState);
+ return expandedPaths.reduce(
+ (obj, path) => {
+ obj[path] = true;
+ return obj;
+ },
+ {...prevExpandedPaths},
+ );
};
diff --git a/yarn.lock b/yarn.lock
index 4eabb48..c8606df 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7062,7 +7062,12 @@ preserve@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
-prettier@^1.11.1, prettier@^1.5.3:
+prettier@^1.16.3:
+ version "1.16.3"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.16.3.tgz#8c62168453badef702f34b45b6ee899574a6a65d"
+ integrity sha512-kn/GU6SMRYPxUakNXhpP0EedT/KmaPzr0H5lIsDogrykbaxOpOfAFfk5XA7DZrJyMAv1wlMV3CPcZruGXVVUZw==
+
+prettier@^1.5.3:
version "1.11.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.1.tgz#61e43fc4cd44e68f2b0dfc2c38cd4bb0fccdcc75"
@@ -7142,6 +7147,14 @@ prop-types@^15.6.1:
loose-envify "^1.3.1"
object-assign "^4.1.1"
+prop-types@^15.6.2:
+ version "15.6.2"
+ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102"
+ integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==
+ dependencies:
+ loose-envify "^1.3.1"
+ object-assign "^4.1.1"
+
proxy-addr@~2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec"
@@ -7334,7 +7347,7 @@ react-docgen@^3.0.0-beta11:
node-dir "^0.1.10"
recast "^0.12.6"
-react-dom@^16.0.0, react-dom@^16.3.1:
+react-dom@^16.0.0:
version "16.3.1"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.3.1.tgz#6a3c90a4fb62f915bdbcf6204422d93a7d4ca573"
dependencies:
@@ -7343,6 +7356,16 @@ react-dom@^16.0.0, react-dom@^16.3.1:
object-assign "^4.1.1"
prop-types "^15.6.0"
+react-dom@^16.8.2:
+ version "16.8.2"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.2.tgz#7c8a69545dd554d45d66442230ba04a6a0a3c3d3"
+ integrity sha512-cPGfgFfwi+VCZjk73buu14pYkYBR1b/SRMSYqkLDdhSEHnSwcuYTPu6/Bh6ZphJFIk80XLvbSe2azfcRzNF+Xg==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+ prop-types "^15.6.2"
+ scheduler "^0.13.2"
+
react-error-overlay@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-4.0.0.tgz#d198408a85b4070937a98667f500c832f86bd5d4"
@@ -7389,9 +7412,10 @@ react-inspector@^2.2.2:
babel-runtime "^6.26.0"
is-dom "^1.0.9"
-react-is@^16.3.1:
- version "16.3.1"
- resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.3.1.tgz#ee66e6d8283224a83b3030e110056798488359ba"
+react-is@^16.8.0-alpha.1:
+ version "16.8.0-alpha.1"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.0-alpha.1.tgz#ac1aed207d6040f002b645af36702edf9ce2c40d"
+ integrity sha512-Gsh2u4ovhS2DY6fWgie/av5vzrIfW6P0lgWAsAQp9DjOImE0fJ26FfEdpFXtYBwi5s2krT9z0xvcQKvQsi4ekw==
react-modal@^3.3.2:
version "3.3.2"
@@ -7415,14 +7439,15 @@ react-style-proptype@^3.0.0:
dependencies:
prop-types "^15.5.4"
-react-test-renderer@^16.3.1:
- version "16.3.1"
- resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.3.1.tgz#d9257936d8535bd40f57f3d5a84e7b0452fb17f2"
+react-test-renderer@^16.8.0-alpha.1:
+ version "16.8.0-alpha.1"
+ resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.8.0-alpha.1.tgz#65f09023aeb83cbb1716f2364fed61c0017cd2ba"
+ integrity sha512-ayhWv47RYZuZ/vY/Asmf2qLgphHtwsq32Y7uNztyO4HcdFh6HrieDioYwbObfxl3+Uf3r4UezJ7uxqT5NndsHw==
dependencies:
- fbjs "^0.8.16"
object-assign "^4.1.1"
- prop-types "^15.6.0"
- react-is "^16.3.1"
+ prop-types "^15.6.2"
+ react-is "^16.8.0-alpha.1"
+ scheduler "^0.13.0-alpha.1"
react-transition-group@^1.1.2:
version "1.2.1"
@@ -7445,7 +7470,7 @@ react-treebeard@^2.1.0:
shallowequal "^0.2.2"
velocity-react "^1.3.1"
-react@^16.0.0, react@^16.3.1:
+react@^16.0.0:
version "16.3.1"
resolved "https://registry.yarnpkg.com/react/-/react-16.3.1.tgz#4a2da433d471251c69b6033ada30e2ed1202cfd8"
dependencies:
@@ -7454,6 +7479,16 @@ react@^16.0.0, react@^16.3.1:
object-assign "^4.1.1"
prop-types "^15.6.0"
+react@^16.8.2:
+ version "16.8.2"
+ resolved "https://registry.yarnpkg.com/react/-/react-16.8.2.tgz#83064596feaa98d9c2857c4deae1848b542c9c0c"
+ integrity sha512-aB2ctx9uQ9vo09HVknqv3DGRpI7OIGJhCx3Bt0QqoRluEjHSaObJl+nG12GDdYH6sTgE7YiPJ6ZUyMx9kICdXw==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+ prop-types "^15.6.2"
+ scheduler "^0.13.2"
+
read-chunk@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-2.1.0.tgz#6a04c0928005ed9d42e1a6ac5600e19cbc7ff655"
@@ -7964,6 +7999,22 @@ sax@^1.2.4, sax@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
+scheduler@^0.13.0-alpha.1:
+ version "0.13.0-alpha.1"
+ resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.0-alpha.1.tgz#753977fb4fb35d8cdd559868a11e46b640955556"
+ integrity sha512-W0sH0848sVuPKg+I18vTYQyzVtA4X1lrVgSeXK6KnOPUltFdJcY5nkbTkjGUeS/E0x+eBsNYfSdhJtGjT95njw==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+
+scheduler@^0.13.2:
+ version "0.13.2"
+ resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.2.tgz#969eaee2764a51d2e97b20a60963b2546beff8fa"
+ integrity sha512-qK5P8tHS7vdEMCW5IPyt8v9MJOHqTrOUgPXib7tqm9vh834ibBX5BNhwkplX/0iOzHW5sXyluehYfS9yrkz9+w==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+
schema-utils@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf"
|