diff --git a/package-lock.json b/package-lock.json index a74dfb847..74bbfe18d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7006,13 +7006,13 @@ "dependencies": { "abbrev": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz", + "resolved": false, "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=", "optional": true }, "ajv": { "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "resolved": false, "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", "optional": true, "requires": { @@ -7022,18 +7022,18 @@ }, "ansi-regex": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "resolved": false, "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "aproba": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.1.tgz", + "resolved": false, "integrity": "sha1-ldNgDwdxCqDpKYxyatXs8urLq6s=", "optional": true }, "are-we-there-yet": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", + "resolved": false, "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", "optional": true, "requires": { @@ -7043,42 +7043,42 @@ }, "asn1": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "resolved": false, "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", "optional": true }, "assert-plus": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "resolved": false, "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", "optional": true }, "asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "resolved": false, "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "optional": true }, "aws-sign2": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "resolved": false, "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", "optional": true }, "aws4": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "resolved": false, "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", "optional": true }, "balanced-match": { "version": "0.4.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "resolved": false, "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" }, "bcrypt-pbkdf": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "resolved": false, "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", "optional": true, "requires": { @@ -7087,7 +7087,7 @@ }, "block-stream": { "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "resolved": false, "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", "requires": { "inherits": "~2.0.0" @@ -7095,7 +7095,7 @@ }, "boom": { "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "resolved": false, "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", "requires": { "hoek": "2.x.x" @@ -7103,7 +7103,7 @@ }, "brace-expansion": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", + "resolved": false, "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", "requires": { "balanced-match": "^0.4.1", @@ -7112,29 +7112,29 @@ }, "buffer-shims": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "resolved": false, "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" }, "caseless": { "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "resolved": false, "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "optional": true }, "co": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "resolved": false, "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "optional": true }, "code-point-at": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "resolved": false, "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "combined-stream": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "resolved": false, "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", "requires": { "delayed-stream": "~1.0.0" @@ -7142,22 +7142,22 @@ }, "concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "resolved": false, "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "console-control-strings": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "resolved": false, "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "core-util-is": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "resolved": false, "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cryptiles": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "resolved": false, "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", "requires": { "boom": "2.x.x" @@ -7165,7 +7165,7 @@ }, "dashdash": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "resolved": false, "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "optional": true, "requires": { @@ -7174,7 +7174,7 @@ "dependencies": { "assert-plus": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "resolved": false, "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "optional": true } @@ -7182,7 +7182,7 @@ }, "debug": { "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "resolved": false, "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", "optional": true, "requires": { @@ -7191,30 +7191,30 @@ }, "deep-extend": { "version": "0.4.2", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", + "resolved": false, "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", "optional": true }, "delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "resolved": false, "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "delegates": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "resolved": false, "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "optional": true }, "detect-libc": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.2.tgz", + "resolved": false, "integrity": "sha1-ca1dIEvxempsqPRQxhRUBm70YeE=", "optional": true }, "ecc-jsbn": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "resolved": false, "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", "optional": true, "requires": { @@ -7223,24 +7223,24 @@ }, "extend": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "resolved": false, "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", "optional": true }, "extsprintf": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", + "resolved": false, "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=" }, "forever-agent": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "resolved": false, "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", "optional": true }, "form-data": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "resolved": false, "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", "optional": true, "requires": { @@ -7251,12 +7251,12 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "resolved": false, "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fstream": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "resolved": false, "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", "requires": { "graceful-fs": "^4.1.2", @@ -7267,7 +7267,7 @@ }, "fstream-ignore": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz", + "resolved": false, "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", "optional": true, "requires": { @@ -7278,7 +7278,7 @@ }, "gauge": { "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "resolved": false, "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "optional": true, "requires": { @@ -7294,7 +7294,7 @@ }, "getpass": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "resolved": false, "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "optional": true, "requires": { @@ -7303,7 +7303,7 @@ "dependencies": { "assert-plus": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "resolved": false, "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "optional": true } @@ -7311,7 +7311,7 @@ }, "glob": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "resolved": false, "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "requires": { "fs.realpath": "^1.0.0", @@ -7324,18 +7324,18 @@ }, "graceful-fs": { "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "resolved": false, "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, "har-schema": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "resolved": false, "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", "optional": true }, "har-validator": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "resolved": false, "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", "optional": true, "requires": { @@ -7345,13 +7345,13 @@ }, "has-unicode": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "resolved": false, "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "optional": true }, "hawk": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "resolved": false, "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", "requires": { "boom": "2.x.x", @@ -7362,12 +7362,12 @@ }, "hoek": { "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "resolved": false, "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" }, "http-signature": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "resolved": false, "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", "optional": true, "requires": { @@ -7378,7 +7378,7 @@ }, "inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "resolved": false, "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { "once": "^1.3.0", @@ -7387,18 +7387,18 @@ }, "inherits": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "resolved": false, "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "resolved": false, "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "resolved": false, "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { "number-is-nan": "^1.0.0" @@ -7406,24 +7406,24 @@ }, "is-typedarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "resolved": false, "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "optional": true }, "isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "resolved": false, "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isstream": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "resolved": false, "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "optional": true }, "jodid25519": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", + "resolved": false, "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=", "optional": true, "requires": { @@ -7432,19 +7432,19 @@ }, "jsbn": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "resolved": false, "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "optional": true }, "json-schema": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "resolved": false, "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", "optional": true }, "json-stable-stringify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "resolved": false, "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", "optional": true, "requires": { @@ -7453,19 +7453,19 @@ }, "json-stringify-safe": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "resolved": false, "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "optional": true }, "jsonify": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "resolved": false, "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", "optional": true }, "jsprim": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", + "resolved": false, "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=", "optional": true, "requires": { @@ -7477,7 +7477,7 @@ "dependencies": { "assert-plus": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "resolved": false, "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "optional": true } @@ -7485,12 +7485,12 @@ }, "mime-db": { "version": "1.27.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz", + "resolved": false, "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=" }, "mime-types": { "version": "2.1.15", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz", + "resolved": false, "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=", "requires": { "mime-db": "~1.27.0" @@ -7498,7 +7498,7 @@ }, "minimatch": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "resolved": false, "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { "brace-expansion": "^1.1.7" @@ -7506,12 +7506,12 @@ }, "minimist": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "resolved": false, "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": false, "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" @@ -7519,13 +7519,13 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "resolved": false, "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "optional": true }, "node-pre-gyp": { "version": "0.6.39", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz", + "resolved": false, "integrity": "sha512-OsJV74qxnvz/AMGgcfZoDaeDXKD3oY3QVIbBmwszTFkRisTSXbMQyn4UWzUMOtA5SVhrBZOTp0wcoSBgfMfMmQ==", "optional": true, "requires": { @@ -7544,7 +7544,7 @@ }, "nopt": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "resolved": false, "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", "optional": true, "requires": { @@ -7554,7 +7554,7 @@ }, "npmlog": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.0.tgz", + "resolved": false, "integrity": "sha512-ocolIkZYZt8UveuiDS0yAkkIjid1o7lPG8cYm05yNYzBn8ykQtaiPMEGp8fY9tKdDgm8okpdKzkvu1y9hUYugA==", "optional": true, "requires": { @@ -7566,24 +7566,24 @@ }, "number-is-nan": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "resolved": false, "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "oauth-sign": { "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "resolved": false, "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", "optional": true }, "object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "resolved": false, "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "optional": true }, "once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "resolved": false, "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { "wrappy": "1" @@ -7591,19 +7591,19 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "resolved": false, "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "optional": true }, "os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": false, "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "optional": true }, "osenv": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", + "resolved": false, "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", "optional": true, "requires": { @@ -7613,35 +7613,35 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": false, "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "performance-now": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "resolved": false, "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", "optional": true }, "process-nextick-args": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "resolved": false, "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, "punycode": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "resolved": false, "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "optional": true }, "qs": { "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "resolved": false, "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", "optional": true }, "rc": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", + "resolved": false, "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", "optional": true, "requires": { @@ -7653,7 +7653,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": false, "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "optional": true } @@ -7661,7 +7661,7 @@ }, "readable-stream": { "version": "2.2.9", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "resolved": false, "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", "requires": { "buffer-shims": "~1.0.0", @@ -7675,7 +7675,7 @@ }, "request": { "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "resolved": false, "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", "optional": true, "requires": { @@ -7705,7 +7705,7 @@ }, "rimraf": { "version": "2.6.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "resolved": false, "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", "requires": { "glob": "^7.0.5" @@ -7713,30 +7713,30 @@ }, "safe-buffer": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", + "resolved": false, "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=" }, "semver": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "resolved": false, "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "optional": true }, "set-blocking": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "resolved": false, "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "optional": true }, "signal-exit": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "resolved": false, "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "optional": true }, "sntp": { "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "resolved": false, "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", "requires": { "hoek": "2.x.x" @@ -7744,7 +7744,7 @@ }, "sshpk": { "version": "1.13.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.0.tgz", + "resolved": false, "integrity": "sha1-/yo+T9BEl1Vf7Zezmg/YL6+zozw=", "optional": true, "requires": { @@ -7761,7 +7761,7 @@ "dependencies": { "assert-plus": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "resolved": false, "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "optional": true } @@ -7769,7 +7769,7 @@ }, "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "resolved": false, "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { "code-point-at": "^1.0.0", @@ -7779,7 +7779,7 @@ }, "string_decoder": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz", + "resolved": false, "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", "requires": { "safe-buffer": "^5.0.1" @@ -7787,13 +7787,13 @@ }, "stringstream": { "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "resolved": false, "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", "optional": true }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": false, "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -7801,13 +7801,13 @@ }, "strip-json-comments": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "resolved": false, "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "optional": true }, "tar": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "resolved": false, "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", "requires": { "block-stream": "*", @@ -7817,7 +7817,7 @@ }, "tar-pack": { "version": "3.4.0", - "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.0.tgz", + "resolved": false, "integrity": "sha1-I74tf2cagzk3bL2wuP4/3r8xeYQ=", "optional": true, "requires": { @@ -7833,7 +7833,7 @@ }, "tough-cookie": { "version": "2.3.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", + "resolved": false, "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", "optional": true, "requires": { @@ -7842,7 +7842,7 @@ }, "tunnel-agent": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "resolved": false, "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "optional": true, "requires": { @@ -7851,30 +7851,30 @@ }, "tweetnacl": { "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "resolved": false, "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "optional": true }, "uid-number": { "version": "0.0.6", - "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", + "resolved": false, "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=", "optional": true }, "util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "resolved": false, "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "uuid": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz", + "resolved": false, "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=", "optional": true }, "verror": { "version": "1.3.6", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", + "resolved": false, "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", "optional": true, "requires": { @@ -7883,7 +7883,7 @@ }, "wide-align": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", + "resolved": false, "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", "optional": true, "requires": { @@ -7892,7 +7892,7 @@ }, "wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "resolved": false, "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" } } diff --git a/src/analyzer/typescript-react-analyzer/slot-analzyer.ts b/src/analyzer/typescript-react-analyzer/slot-analzyer.ts index 1475c3de4..179642509 100644 --- a/src/analyzer/typescript-react-analyzer/slot-analzyer.ts +++ b/src/analyzer/typescript-react-analyzer/slot-analzyer.ts @@ -37,12 +37,25 @@ export function analyzeSlots( return; } + const propertyName = memberSymbol.getName(); + const label = TypescriptUtils.getJsDocValueFromSymbol(memberSymbol, 'name'); + const example = TypescriptUtils.getJsDocValueFromSymbol(memberSymbol, 'example') || ''; + const required = + (memberSymbol.flags & Ts.SymbolFlags.Optional) !== Ts.SymbolFlags.Optional; + const description = + TypescriptUtils.getJsDocValueFromSymbol(memberSymbol, 'description') || ''; + const hidden = TypescriptUtils.hasJsDocTagFromSymbol(memberSymbol, 'ignore'); + return { - contextId: memberSymbol.getName(), - displayName: memberSymbol.getName(), - id: ctx.getSlotId(memberSymbol.getName()), - propertyName: memberSymbol.getName(), - type: memberSymbol.getName() === 'children' ? 'children' : 'property' + contextId: propertyName, + label: label || propertyName, + description, + example, + hidden, + id: ctx.getSlotId(propertyName), + propertyName, + required, + type: propertyName === 'children' && !isExplicitSlot ? 'children' : 'property' }; }) .filter((slot): slot is Types.SerializedPatternSlot => typeof slot !== 'undefined'); diff --git a/src/components/element-slot/demo.tsx b/src/components/element-slot/demo.tsx new file mode 100644 index 000000000..49317c4de --- /dev/null +++ b/src/components/element-slot/demo.tsx @@ -0,0 +1,50 @@ +import DemoContainer from '../demo-container'; +import * as React from 'react'; +import { ElementSlot, ElementSlotState } from '.'; + +const FloatingButtonDemo: React.StatelessComponent = (): JSX.Element => ( + + <> + Default + + + <> + Open + + + <> + Disabled + + + <> + Highlighted + + + +); + +export default FloatingButtonDemo; diff --git a/src/components/element-slot/element-slot.tsx b/src/components/element-slot/element-slot.tsx new file mode 100644 index 000000000..ab4561ec7 --- /dev/null +++ b/src/components/element-slot/element-slot.tsx @@ -0,0 +1,130 @@ +import { Color } from '../colors'; +import { ElementAnchors } from '../element'; +import { Icon, IconName, IconSize } from '../icons'; +import * as React from 'react'; +import { getSpace, SpaceSize } from '../space'; +import styled from 'styled-components'; +import { tag } from '../tag'; + +export enum ElementSlotState { + Default = 'default', + Disabled = 'disabled', + Highlighted = 'highlighted' +} + +export interface ElementSlotProps { + children?: React.ReactNode; + description: string; + id: string; + open: boolean; + state: ElementSlotState; + title: string; +} + +interface StyledElementSlotLabelProps { + state: ElementSlotState; +} + +interface StyledIconProps { + open: boolean; +} + +const StyledElementSlot = styled.div` + position: relative; + z-index: 1; +`; + +const div = tag('div').omit(['active', 'highlight']); + +const LABEL_COLOR = (props: StyledElementSlotLabelProps): string => { + switch (props.state) { + case ElementSlotState.Disabled: + return Color.Grey60; + case ElementSlotState.Highlighted: + case ElementSlotState.Default: + default: + return 'inherit'; + } +}; + +const LABEL_BACKGROUND = (props: StyledElementSlotLabelProps): string => { + switch (props.state) { + case ElementSlotState.Highlighted: + return Color.Grey90; + default: + return 'transparent'; + } +}; + +const StyledElementSlotLabel = styled(div)` + position: relative; + display: flex; + align-items: center; + font-size: 15px; + line-height: 21px; + z-index: 1; + color: ${LABEL_COLOR}; + background: ${LABEL_BACKGROUND}; +`; + +const elementDiv = tag('div').omit(['open']); + +const StyledElementChildren = styled(elementDiv)` + flex-basis: 100%; + padding-left: ${getSpace(SpaceSize.L)}px; +`; + +const StyledIcon = styled(Icon)` + position: absolute; + left: ${getSpace(SpaceSize.XS) + getSpace(SpaceSize.XXS)}px; + fill: ${Color.Grey60}; + width: ${getSpace(SpaceSize.S)}px; + height: ${getSpace(SpaceSize.S)}px; + padding: ${getSpace(SpaceSize.XS)}px; + transition: transform 0.2s; + ${(props: StyledIconProps) => (props.open ? 'transform: rotate(90deg)' : '')}; +`; + +const StyledElementSlotLabelContent = styled.div` + box-sizing: border-box; + margin-left: ${getSpace(SpaceSize.XXL) - 3}px; + overflow: hidden; + padding: ${getSpace(SpaceSize.XS)}px ${getSpace(SpaceSize.XXS)}px; + text-overflow: ellipsis; + white-space: nowrap; + width: 100%; +`; + +const StyledElementSlotLabelDescription = styled.div` + box-sizing: border-box; + padding: 0 ${getSpace(SpaceSize.M)}px 0 ${getSpace(SpaceSize.XS)}px; + font-size: 12px; + justify-self: flex-end; +`; + +export class ElementSlot extends React.Component { + public render(): JSX.Element | null { + const { props } = this; + + return ( + + + + + {props.title} + + + {props.description} + + + {props.open && props.children} + + ); + } +} diff --git a/src/components/element-slot/index.tsx b/src/components/element-slot/index.tsx new file mode 100644 index 000000000..0e629a0b3 --- /dev/null +++ b/src/components/element-slot/index.tsx @@ -0,0 +1 @@ +export * from './element-slot'; diff --git a/src/components/element-slot/pattern.json b/src/components/element-slot/pattern.json new file mode 100644 index 000000000..e17ea73c0 --- /dev/null +++ b/src/components/element-slot/pattern.json @@ -0,0 +1,9 @@ +{ + "name": "element-slot", + "main": "./element-slot", + "description": "Slot in element tree", + "displayName": "Element Slot", + "flag": "alpha", + "version": "1.0.0", + "tags": [] +} diff --git a/src/components/element/demo.tsx b/src/components/element/demo.tsx index 0189f0a88..7f3a3cdb7 100644 --- a/src/components/element/demo.tsx +++ b/src/components/element/demo.tsx @@ -8,9 +8,11 @@ const NOOP = () => {}; const CHILD = ( = (): JSX.Element => ( Default @@ -35,9 +39,11 @@ const ElementDemo: React.StatelessComponent = (): JSX.Element => ( Active = (): JSX.Element => ( Highlighted = (): JSX.Element => ( Placeholder Highlighted = (): JSX.Element => ( Editable = (): JSX.Element => ( May open, closed = (): JSX.Element => ( May open, opened = (): JSX.Element => ( With child, active and open ; + open: boolean; + placeholder: boolean; + placeholderHighlighted?: boolean; + state: ElementState; + title: string; +} + +interface StyledElementLabelProps { + state: ElementState; +} + +interface StyledIconProps { + active: boolean; + open: boolean; +} + +interface LabelContentProps { + active: boolean; + editable?: boolean; +} + +export interface StyledElementChildProps { + open: boolean; +} + +const StyledElement = styled.div` + position: relative; + z-index: 1; +`; + +const div = tag('div').omit(['active', 'highlight']); + +const LABEL_COLOR = (props: StyledElementLabelProps): string => { + switch (props.state) { + case ElementState.Active: + case ElementState.Editable: + return Color.Blue; + case ElementState.Disabled: + return Color.Grey60; + default: + return 'inherit'; + } +}; + +const LABEL_BACKGROUND = (props: StyledElementLabelProps): string => { + switch (props.state) { + case ElementState.Active: + case ElementState.Editable: + return Color.Blue80; + case ElementState.Highlighted: + return Color.Grey90; + default: + return 'transparent'; + } +}; + +const StyledElementLabel = styled(div)` + position: relative; + display: flex; + align-items: center; + font-size: 15px; + line-height: 21px; + z-index: 1; + color: ${LABEL_COLOR}; + background: ${LABEL_BACKGROUND}; + &::before { + content: ''; + display: block; + position: absolute; + z-index: -1; + top: 0; + right: 100%; + height: 100%; + width: 100vw; + background: inherit; + } +`; + +interface StyledPlaceholderProps { + visible: boolean; +} + +const PLACEHOLDER_SCALE = (props: StyledPlaceholderProps): number => (props.visible ? 1 : 0); + +const StyledPlaceholder = styled.div` + position: relative; + height: ${getSpace(SpaceSize.S)}px; + width: 100%; + margin-top: -${getSpace(SpaceSize.XS)}px; + margin-bottom: -${getSpace(SpaceSize.XS)}px; + z-index: 10; + + &::before { + content: ''; + display: block; + position: absolute; + height: 6px; + width: 6px; + left: 0; + top: 3px; + border-radius: 3px; + background: ${Color.Blue40}; + transform: scale(${PLACEHOLDER_SCALE}); + transition: transform 0.2s; + z-index: 20; + } + + &::after { + content: ''; + display: block; + position: absolute; + height: 2px; + width: calc(100% - 6px); + left: ${getSpace(SpaceSize.XS)}; + top: 5px; + background: ${Color.Blue40}; + transform: scaleY(${PLACEHOLDER_SCALE}); + transition: transform 0.2s; + z-index: 20; + } +`; + +const elementDiv = tag('div').omit(['open']); + +const StyledElementChildren = styled(elementDiv)` + flex-basis: 100%; + padding-left: ${getSpace(SpaceSize.L)}px; +`; + +const StyledIcon = styled(Icon)` + position: absolute; + left: ${getSpace(SpaceSize.XS) + getSpace(SpaceSize.XXS)}px; + fill: ${Color.Grey60}; + width: ${getSpace(SpaceSize.S)}px; + height: ${getSpace(SpaceSize.S)}px; + padding: ${getSpace(SpaceSize.XS)}px; + transition: transform 0.2s; + + ${(props: StyledIconProps) => (props.open ? 'transform: rotate(90deg)' : '')}; + ${(props: StyledIconProps) => (props.active ? `fill: ${Color.Blue20}` : '')}; +`; + +const LabelContent = styled.div` + box-sizing: border-box; + margin-left: ${getSpace(SpaceSize.XXL) - 3}px; + overflow: hidden; + padding: ${getSpace(SpaceSize.XS)}px ${getSpace(SpaceSize.L)}px ${getSpace(SpaceSize.XS)}px 3px; + text-overflow: ellipsis; + white-space: nowrap; + width: 100%; + cursor: ${(props: LabelContentProps) => (props.active && props.editable ? 'text' : 'default')}; + user-select: none; +`; + +const StyledSeamlessInput = styled.input` + box-sizing: border-box; + width: 100%; + color: ${Color.Grey20}; + font-size: inherit; + line-height: inherit; + padding: ${getSpace(SpaceSize.XS - 1)}px ${getSpace(SpaceSize.L - 1)}px + ${getSpace(SpaceSize.XS - 1)}px 3px; + margin: 1px 1px 1px ${getSpace(SpaceSize.XXL - 3)}px; + border: 0; + &:focus { + outline: none; + } +`; + +interface SeamlessInputProps { + autoFocus?: boolean; + autoSelect?: boolean; + onChange?: React.FormEventHandler; + value: string; +} + +class SeamlessInput extends React.Component { + private ref: HTMLInputElement | null = null; + + public componentDidMount(): void { + if (this.ref !== null && this.props.autoSelect && this.props.autoFocus) { + const ref = this.ref as HTMLInputElement; + ref.setSelectionRange(0, this.props.value.length); + } + } + + public render(): JSX.Element { + const { props } = this; + return ( + (this.ref = ref)} + value={props.value} + onChange={props.onChange} + /> + ); + } +} + +export class Element extends React.Component { + public static ElementChildren: React.SFC = props => <>{props.children}; + public static ElementSlots: React.SFC = props => <>{props.children}; + + public render(): JSX.Element | null { + const { props } = this; + + const anchors = { + [ElementAnchors.content]: props.contentId, + [ElementAnchors.element]: props.id + }; + + return ( + + {props.placeholder && + props.dragging && ( + + )} + + {props.capabilities.includes(ElementCapability.Openable) && ( + + )} + {props.state === ElementState.Editable && + props.capabilities.includes(ElementCapability.Editable) ? ( + + ) : ( + + {props.title} + + )} + + + {props.open && containered(props.children, Element.ElementSlots)} + {props.open && containered(props.children, Element.ElementChildren)} + + + ); + } +} + +function containered(children: React.ReactNode, Container: React.SFC): React.ReactElement[] { + return React.Children.map(children, child => { + if (child === null) { + return; + } + + if (typeof child !== 'object') { + return; + } + + if (!child.hasOwnProperty('type')) { + return; + } + + if (child.type !== Container) { + return; + } + + return child; + }).filter((child): child is React.ReactElement => typeof child !== 'undefined'); +} diff --git a/src/components/element/index.tsx b/src/components/element/index.tsx index a5240795f..ef9f88ec6 100644 --- a/src/components/element/index.tsx +++ b/src/components/element/index.tsx @@ -1,282 +1 @@ -import { Color } from '../colors'; -import { Icon, IconName, IconSize } from '../icons'; -import * as React from 'react'; -import { getSpace, SpaceSize } from '../space'; -import styled from 'styled-components'; -import { tag } from '../tag'; - -export const ElementAnchors = { - element: 'data-id', - content: 'data-id', - icon: 'data-icon', - label: 'data-element-label', - placeholder: 'data-element-placeholder' -}; - -export enum ElementState { - Default = 'default', - Editable = 'editable', - Active = 'active', - Disabled = 'disabled', - Highlighted = 'highlighted', - Focused = 'focused' -} - -export enum ElementCapability { - Draggable = 'draggable', - Editable = 'editable', - Openable = 'openable' -} - -export interface ElementProps { - capabilities: ElementCapability[]; - children?: React.ReactNode; - dragging: boolean; - id: string; - onChange: React.FormEventHandler; - open: boolean; - placeholderHighlighted?: boolean; - state: ElementState; - title: string; -} - -interface StyledElementLabelProps { - state: ElementState; -} - -interface StyledIconProps { - active: boolean; - open: boolean; -} - -interface LabelContentProps { - active: boolean; - editable?: boolean; -} - -export interface StyledElementChildProps { - open: boolean; -} - -const StyledElement = styled.div` - position: relative; - z-index: 1; -`; - -const div = tag('div').omit(['active', 'highlight']); - -const LABEL_COLOR = (props: StyledElementLabelProps): string => { - switch (props.state) { - case ElementState.Active: - case ElementState.Editable: - return Color.Blue; - case ElementState.Disabled: - return Color.Grey60; - default: - return 'inherit'; - } -}; - -const LABEL_BACKGROUND = (props: StyledElementLabelProps): string => { - switch (props.state) { - case ElementState.Active: - case ElementState.Editable: - return Color.Blue80; - case ElementState.Highlighted: - return Color.Grey90; - default: - return 'transparent'; - } -}; - -const StyledElementLabel = styled(div)` - position: relative; - display: flex; - align-items: center; - color: ${Color.Grey20}; - position: relative; - font-size: 15px; - line-height: 21px; - z-index: 1; - color: ${LABEL_COLOR}; - background: ${LABEL_BACKGROUND}; - &::before { - content: ''; - display: block; - position: absolute; - z-index: -1; - top: 0; - right: 100%; - height: 100%; - width: 100vw; - background: inherit; - } -`; - -interface StyledPlaceholderProps { - visible: boolean; -} - -const PLACEHOLDER_SCALE = (props: StyledPlaceholderProps): number => (props.visible ? 1 : 0); - -const StyledPlaceholder = styled.div` - position: relative; - height: ${getSpace(SpaceSize.S)}px; - width: 100%; - margin-top: -${getSpace(SpaceSize.XS)}px; - margin-bottom: -${getSpace(SpaceSize.XS)}px; - z-index: 10; - - &::before { - content: ''; - display: block; - position: absolute; - height: 6px; - width: 6px; - left: 0; - top: 3px; - border-radius: 3px; - background: ${Color.Blue40}; - transform: scale(${PLACEHOLDER_SCALE}); - transition: transform 0.2s; - z-index: 20; - } - - &::after { - content: ''; - display: block; - position: absolute; - height: 2px; - width: calc(100% - 6px); - left: ${getSpace(SpaceSize.XS)}; - top: 5px; - background: ${Color.Blue40}; - transform: scaleY(${PLACEHOLDER_SCALE}); - transition: transform 0.2s; - z-index: 20; - } -`; - -const elementDiv = tag('div').omit(['open']); - -const StyledElementChildren = styled(elementDiv)` - flex-basis: 100%; - padding-left: ${getSpace(SpaceSize.L)}px; -`; - -const StyledIcon = styled(Icon)` - position: absolute; - left: ${getSpace(SpaceSize.XS) + getSpace(SpaceSize.XXS)}px; - fill: ${Color.Grey60}; - width: ${getSpace(SpaceSize.S)}px; - height: ${getSpace(SpaceSize.S)}px; - padding: ${getSpace(SpaceSize.XS)}px; - transition: transform 0.2s; - - ${(props: StyledIconProps) => (props.open ? 'transform: rotate(90deg)' : '')}; - ${(props: StyledIconProps) => (props.active ? `fill: ${Color.Blue20}` : '')}; -`; - -const LabelContent = styled.div` - box-sizing: border-box; - margin-left: ${getSpace(SpaceSize.XXL) - 3}px; - overflow: hidden; - padding: ${getSpace(SpaceSize.XS)}px ${getSpace(SpaceSize.L)}px ${getSpace(SpaceSize.XS)}px 3px; - text-overflow: ellipsis; - white-space: nowrap; - width: 100%; - cursor: ${(props: LabelContentProps) => (props.active && props.editable ? 'text' : 'default')}; - user-select: none; -`; - -const StyledSeamlessInput = styled.input` - box-sizing: border-box; - width: 100%; - color: ${Color.Grey20}; - font-size: inherit; - line-height: inherit; - padding: ${getSpace(SpaceSize.XS - 1)}px ${getSpace(SpaceSize.L - 1)}px - ${getSpace(SpaceSize.XS - 1)}px 3px; - margin: 1px 1px 1px ${getSpace(SpaceSize.XXL - 3)}px; - border: 0; - &:focus { - outline: none; - } -`; - -interface SeamlessInputProps { - autoFocus?: boolean; - autoSelect?: boolean; - onChange?: React.FormEventHandler; - value: string; -} - -class SeamlessInput extends React.Component { - private ref: HTMLInputElement | null = null; - - public componentDidMount(): void { - if (this.ref !== null && this.props.autoSelect && this.props.autoFocus) { - const ref = this.ref as HTMLInputElement; - ref.setSelectionRange(0, this.props.value.length); - } - } - - public render(): JSX.Element { - const { props } = this; - return ( - (this.ref = ref)} - value={props.value} - onChange={props.onChange} - /> - ); - } -} - -export const Element: React.StatelessComponent = props => ( - - {props.dragging && ( - - )} - - {props.capabilities.includes(ElementCapability.Openable) && ( - - )} - {props.state === ElementState.Editable && - props.capabilities.includes(ElementCapability.Editable) ? ( - - ) : ( - - {props.title} - - )} - - {props.open && props.children ? ( - {props.children} - ) : null} - -); +export * from './element'; diff --git a/src/components/element/pattern.json b/src/components/element/pattern.json index d4e31e7ac..f00c12713 100644 --- a/src/components/element/pattern.json +++ b/src/components/element/pattern.json @@ -4,5 +4,5 @@ "displayName": "Element", "flag": "alpha", "version": "1.0.0", - "tags": ["layout"] + "tags": [] } diff --git a/src/components/index.ts b/src/components/index.ts index 1366d58a3..991c49c05 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -6,6 +6,7 @@ export * from './colors'; export * from './copy'; export * from './create-select'; export * from './element'; +export * from './element-slot'; export * from './fonts'; export * from './global-styles'; export * from './headline'; diff --git a/src/container/dragged-element-image.tsx b/src/container/dragged-element-image.tsx new file mode 100644 index 000000000..a821a01f9 --- /dev/null +++ b/src/container/dragged-element-image.tsx @@ -0,0 +1,30 @@ +import * as React from 'react'; +import styled from 'styled-components'; +import * as Components from '../components'; +import * as Model from '../model'; + +const StyledDraggedElement = styled.div` + position: fixed; + top: 100vh; + background-color: ${Components.Color.White}; + color: ${Components.Color.Black}; + padding: 6px 18px; + border-radius: 3px; + font-size: 12px; + opacity: 1; +`; + +export class DraggedElementImage extends React.Component<{ + element?: Model.Element; + innerRef(ref: HTMLElement): void; +}> { + public render(): JSX.Element { + const { props } = this; + + return ( + + {props.element && props.element.getName()} + + ); + } +} diff --git a/src/container/element-list/element-container.tsx b/src/container/element-list/element-container.tsx index ff3c9a311..db12199ae 100644 --- a/src/container/element-list/element-container.tsx +++ b/src/container/element-list/element-container.tsx @@ -2,10 +2,12 @@ import * as AlvaUtil from '../../alva-util'; import * as Components from '../../components'; import { ElementCapability } from '../../components'; import { ElementContentContainer } from './element-content-container'; +import { ElementSlotContainer } from './element-slot-container'; +import { partition } from 'lodash'; import * as MobxReact from 'mobx-react'; import * as Model from '../../model'; import * as React from 'react'; -import { ElementRole } from '../../types'; +import * as Types from '../../types'; import { ViewStore } from '../../store'; export interface ElementContainerProps { @@ -21,42 +23,54 @@ export class ElementContainer extends React.Component { const { props } = this; const open = props.element.getOpen() || props.element.getForcedOpen(); - // Ensure mobx registers - props.element.getSelected(); - props.element.getNameEditable(); - props.element.getHighlighted(); - props.element.acceptsChildren(); + const contents = props.element.getContents(); + + const [[childContent], slotContents] = partition( + contents, + (content: Model.ElementContent): boolean => + content.getSlotType() === Types.SlotType.Children + ); return ( content.acceptsChildren()) && + props.element.getRole() !== Types.ElementRole.Root && ElementCapability.Openable ].filter((item): item is ElementCapability => Boolean(item))} dragging={store.getDragging()} id={props.element.getId()} + contentId={childContent ? childContent.getId() : ''} open={open} onChange={AlvaUtil.noop} + placeholder={props.element.getRole() !== Types.ElementRole.Root} placeholderHighlighted={props.element.getPlaceholderHighlighted()} - state={getState(props.element, store)} - title={props.element.getRole() === ElementRole.Root ? 'Page' : props.element.getName()} + state={getElementState(props.element, store)} + title={ + props.element.getRole() === Types.ElementRole.Root ? 'Page' : props.element.getName() + } > - {open - ? props.element - .getContents() - .map(content => ( - - )) - : []} + + {slotContents.map(slotContent => ( + + ))} + + {childContent && ( + + + + )} ); } } -const getState = (element: Model.Element, store: ViewStore): Components.ElementState => { +const getElementState = (element: Model.Element, store: ViewStore): Components.ElementState => { + const childContent = element.getContentBySlotType(Types.SlotType.Children); + const draggedElement = store.getDraggedElement(); + if (element.getSelected() && element.getNameEditable()) { return Components.ElementState.Editable; } @@ -69,7 +83,11 @@ const getState = (element: Model.Element, store: ViewStore): Components.ElementS return Components.ElementState.Disabled; } - if (element.getHighlighted()) { + if (draggedElement && !element.accepts(draggedElement)) { + return Components.ElementState.Disabled; + } + + if (element.getHighlighted() || (childContent && childContent.getHighlighted())) { return Components.ElementState.Highlighted; } diff --git a/src/container/element-list/element-list.tsx b/src/container/element-list/element-list.tsx index 7f970e775..f95232b52 100644 --- a/src/container/element-list/element-list.tsx +++ b/src/container/element-list/element-list.tsx @@ -75,6 +75,7 @@ export class ElementList extends React.Component { } const element = elementFromTarget(e.target, { sibling: false, store }); + const targetContent = elementContentFromTarget(e.target, { store }); const label = above(e.target, `[${ElementAnchors.label}]`); if (!element) { @@ -83,6 +84,11 @@ export class ElementList extends React.Component { e.stopPropagation(); + if (targetContent && targetContent.getSlotType() !== Types.SlotType.Children) { + targetContent.toggleOpen(); + return; + } + if (icon) { element.toggleOpen(); return; @@ -119,35 +125,50 @@ export class ElementList extends React.Component { private handleDragOver(e: React.DragEvent): void { const { store } = this.props as { store: Store.ViewStore }; + const target = e.target as HTMLElement; const isSibling = target.getAttribute(ElementAnchors.placeholder) === 'true'; + const visualTargetElement = elementFromTarget(e.target, { sibling: false, store }); - const targetParentElement = elementFromTarget(target, { sibling: isSibling, store }); - const visualTargetElement = elementFromTarget(target, { sibling: false, store }); + const targetContent = isSibling + ? visualTargetElement && visualTargetElement.getContainer() + : elementContentFromTarget(e.target, { store }); const draggedElement = store.getDraggedElement(); - if (!targetParentElement || !visualTargetElement) { + if (!targetContent || !visualTargetElement) { return; } Mobx.transaction(() => { if (!draggedElement) { - // e.dataTransfer.dropEffect = 'none'; - visualTargetElement.setHighlighted(false); + targetContent.setHighlighted(false); visualTargetElement.setPlaceholderHighlighted(false); return; } - const accepted = targetParentElement.accepts(draggedElement); + store + .getProject() + .getElementContents() + .filter(sec => sec.getHighlighted() && sec !== targetContent) + .forEach(se => se.setHighlighted(false)); + + store + .getProject() + .getElements() + .filter(se => se.getHighlighted() && se !== visualTargetElement) + .forEach(se => se.setHighlighted(false)); + + const accepted = targetContent.accepts(draggedElement); if (!accepted) { - // e.dataTransfer.dropEffect = 'none'; + targetContent.setHighlighted(false); + visualTargetElement.setPlaceholderHighlighted(false); return; } e.dataTransfer.dropEffect = 'copy'; - visualTargetElement.setHighlighted(!isSibling); + targetContent.setHighlighted(!isSibling); visualTargetElement.setPlaceholderHighlighted(isSibling); }); } @@ -161,6 +182,11 @@ export class ElementList extends React.Component { return; } + if (draggedElement.getRole() === Types.ElementRole.Root) { + e.preventDefault(); + return; + } + if (draggedElement.getNameEditable()) { e.preventDefault(); return; @@ -181,25 +207,27 @@ export class ElementList extends React.Component { const target = e.target as HTMLElement; const isSiblingDrop = target.getAttribute(ElementAnchors.placeholder) === 'true'; - const rawTargetElement = elementFromTarget(e.target, { sibling: false, store }); - const dropTargetElement = elementFromTarget(e.target, { sibling: isSiblingDrop, store }); - const dropTargetContent = contentFromTarget(e.target, { sibling: isSiblingDrop, store }); const draggedElement = store.getDraggedElement(); + const visualTargetElement = elementFromTarget(e.target, { sibling: false, store }); - if (!rawTargetElement || !dropTargetElement || !dropTargetContent || !draggedElement) { + if (!draggedElement || !visualTargetElement) { return; } - if (!dropTargetElement.accepts(draggedElement)) { + const targetContent = isSiblingDrop + ? visualTargetElement.getContainer() + : elementContentFromTarget(e.target, { store }); + + if (!targetContent) { return; } const getDropIndex = () => { if (!isSiblingDrop) { - return dropTargetContent.getElements().length; + return targetContent.getElements().length; } return calculateDropIndex({ - target: rawTargetElement, + target: visualTargetElement, dragged: draggedElement }); }; @@ -221,7 +249,7 @@ export class ElementList extends React.Component { store.executeElementMove({ element: draggedElement, - content: dropTargetContent, + content: targetContent, index }); @@ -274,6 +302,11 @@ export class ElementList extends React.Component { private handleMouseLeave(e: React.MouseEvent): void { const { store } = this.props as { store: Store.ViewStore }; const element = elementFromTarget(e.target as HTMLElement, { sibling: false, store }); + const targetContent = elementContentFromTarget(e.target, { store }); + + if (targetContent) { + targetContent.setHighlighted(false); + } if (element) { element.setHighlighted(false); @@ -282,23 +315,41 @@ export class ElementList extends React.Component { private handleMouseOver(e: React.MouseEvent): void { const { store } = this.props as { store: Store.ViewStore }; - const element = elementFromTarget(e.target as HTMLElement, { sibling: false, store }); + const targetElement = elementFromTarget(e.target as HTMLElement, { sibling: false, store }); + const targetContent = elementContentFromTarget(e.target, { store }); const label = above(e.target, `[${ElementAnchors.label}]`); - if ( - (label && element) || - (!label && element && element.getRole() === Types.ElementRole.Root) - ) { - store - .getProject() - .getElements() - .filter(se => se.getHighlighted()) - .forEach(se => se.setHighlighted(false)); - } + Mobx.transaction(() => { + if ( + (label && targetElement) || + (label && targetContent) || + (!label && targetElement && targetElement.getRole() === Types.ElementRole.Root) + ) { + store + .getProject() + .getElementContents() + .filter(sec => sec.getHighlighted()) + .forEach(se => se.setHighlighted(false)); + + store + .getProject() + .getElements() + .filter(se => se.getHighlighted()) + .forEach(se => se.setHighlighted(false)); + } - if (label && element) { - element.setHighlighted(true); - } + if ( + label && + targetElement && + targetContent === targetElement.getContentBySlotId(Types.SlotType.Children) + ) { + targetElement.setHighlighted(true); + } + + if (label && targetContent && targetContent.getSlotType() === Types.SlotType.Children) { + targetContent.setHighlighted(true); + } + }); } public render(): JSX.Element | null { @@ -315,10 +366,17 @@ export class ElementList extends React.Component { return null; } + const anchors = { + [ElementAnchors.content]: (rootElement.getContentBySlotType( + Types.SlotType.Children + ) as Model.ElementContent).getId(), + [ElementAnchors.element]: rootElement.getId() + }; + return ( this.handleBlur(e)} onChange={e => this.handleChange(e)} onClick={e => this.handleClick(e)} @@ -367,9 +425,9 @@ function above(node: EventTarget, selector: string): HTMLElement | null { return ended ? null : el; } -function contentFromTarget( +function elementContentFromTarget( target: EventTarget, - options: { sibling: boolean; store: Store.ViewStore } + options: { store: Store.ViewStore } ): Model.ElementContent | undefined { const el = above(target, `[${ElementAnchors.content}]`); @@ -377,30 +435,13 @@ function contentFromTarget( return; } - const id = el.getAttribute(ElementAnchors.element); + const id = el.getAttribute(ElementAnchors.content); if (typeof id !== 'string') { return; } - const content = options.store.getContentById(id); - const element = options.store.getElementById(id); - - if (content) { - return content; - } - - if (!element) { - return; - } - - const base = options.sibling ? element.getParent() : element; - - if (!base) { - return; - } - - return base.getContentBySlotType(Types.SlotType.Children); + return options.store.getContentById(id); } export function elementFromTarget( diff --git a/src/container/element-list/element-slot-container.tsx b/src/container/element-list/element-slot-container.tsx new file mode 100644 index 000000000..3739a321d --- /dev/null +++ b/src/container/element-list/element-slot-container.tsx @@ -0,0 +1,53 @@ +import * as Components from '../../components'; +import { ElementContainer } from './element-container'; +import * as MobxReact from 'mobx-react'; +import * as Model from '../../model'; +import * as React from 'react'; +import { ViewStore } from '../../store'; + +export interface ElementSlotContainerProps { + content: Model.ElementContent; +} + +@MobxReact.inject('store') +@MobxReact.observer +export class ElementSlotContainer extends React.Component { + public render(): JSX.Element | null { + const props = this.props as ElementSlotContainerProps & { store: ViewStore }; + + if (props.content.getSlot().getHidden()) { + return null; + } + + return ( + + {props.content + .getElements() + .map(element => )} + + ); + } +} + +const getSlotState = ( + slot: Model.ElementContent, + store: ViewStore +): Components.ElementSlotState => { + const draggedElement = store.getDraggedElement(); + + if (slot.getHighlighted()) { + return Components.ElementSlotState.Highlighted; + } + + if (draggedElement && slot.accepts(draggedElement)) { + return Components.ElementSlotState.Default; + } + + return Components.ElementSlotState.Disabled; +}; diff --git a/src/container/pattern-list/pattern-item-container.tsx b/src/container/pattern-list/pattern-item-container.tsx index 65c4aef05..c912ef407 100644 --- a/src/container/pattern-list/pattern-item-container.tsx +++ b/src/container/pattern-list/pattern-item-container.tsx @@ -47,6 +47,7 @@ export class PatternItemContainer extends React.Component e.getId()), + forcedOpen: false, id: uuid.v4(), - name: this.name, + open: false, slotId: this.slotId }, { @@ -104,10 +124,22 @@ export class ElementContent { .filter((element): element is Element => typeof element !== 'undefined'); } + public getForcedOpen(): boolean { + return this.forcedOpen; + } + + public getHighlighted(): boolean { + return this.highlighted; + } + public getId(): string { return this.id; } + public getOpen(): boolean { + return this.open; + } + public getParentElement(): Element | undefined { if (!this.parentElementId) { return; @@ -159,6 +191,21 @@ export class ElementContent { this.elementIds.splice(index, 1); } + @Mobx.action + public setForcedOpen(forcedOpen: boolean): void { + this.forcedOpen = forcedOpen; + } + + @Mobx.action + public setHighlighted(highlighted: boolean): void { + this.highlighted = highlighted; + } + + @Mobx.action + public setOpen(open: boolean): void { + this.open = open; + } + @Mobx.action public setParentElement(element: Element): void { this.parentElementId = element.getId(); @@ -169,11 +216,18 @@ export class ElementContent { this.patternLibrary = patternLibrary; } + @Mobx.action + public toggleOpen(): void { + this.setOpen(!this.getOpen() && !this.getForcedOpen()); + this.setForcedOpen(false); + } + public toJSON(): Types.SerializedElementContent { return { elementIds: Array.from(this.elementIds), + forcedOpen: this.forcedOpen, id: this.id, - name: this.name, + open: this.open, parentElementId: this.parentElementId, slotId: this.slotId }; diff --git a/src/model/element/element.ts b/src/model/element/element.ts index 89c11cf22..fb7518f82 100644 --- a/src/model/element/element.ts +++ b/src/model/element/element.ts @@ -152,7 +152,13 @@ export class Element { } public accepts(child: Element): boolean { - return !child.isAncestorOfById(this.getId()) && child !== this && this.acceptsChildren(); + const childrenContent = this.getContentBySlotType(Types.SlotType.Children); + + if (!childrenContent) { + return false; + } + + return childrenContent.accepts(child); } public acceptsChildren(): boolean { @@ -207,14 +213,16 @@ export class Element { return clone; } - public getAncestors(init: Element[] = []): Element[] { + public getAncestors(init: (Element | ElementContent)[] = []): (Element | ElementContent)[] { const parent = this.getParent(); + const container = this.getContainer(); - if (!parent) { + if (!parent || !container) { return init; } init.push(parent); + init.push(container); parent.getAncestors(init); return init; @@ -368,7 +376,7 @@ export class Element { public getParent(): Element | undefined { const container = this.getContainer(); - if (!container) { + if (!container || this.role === Types.ElementRole.Root) { return; } diff --git a/src/model/page/page.ts b/src/model/page/page.ts index 9af4e41b1..795d49b12 100644 --- a/src/model/page/page.ts +++ b/src/model/page/page.ts @@ -82,8 +82,9 @@ export class Page { new ElementContent( { elementIds: [], + forcedOpen: false, id: uuid.v4(), - name: slot.getName(), + open: false, slotId: slot.getId() }, context diff --git a/src/model/pattern-library/builtins/box.ts b/src/model/pattern-library/builtins/box.ts index a54cfcee9..f326fee7c 100644 --- a/src/model/pattern-library/builtins/box.ts +++ b/src/model/pattern-library/builtins/box.ts @@ -235,8 +235,12 @@ export const Box = (context: BuiltInContext): BuiltInResult => { new PatternSlot({ contextId: SLOT_CONTEXT_ID, displayName: 'Children', + description: '', + example: '', + hidden: false, propertyName: 'children', id: context.options.getGlobalSlotId(patternId, SLOT_CONTEXT_ID), + required: false, type: Types.SlotType.Children }) ]; diff --git a/src/model/pattern-library/builtins/link.ts b/src/model/pattern-library/builtins/link.ts index 582d9e544..c6c722a65 100644 --- a/src/model/pattern-library/builtins/link.ts +++ b/src/model/pattern-library/builtins/link.ts @@ -38,8 +38,12 @@ export const Link = (context: BuiltInContext): BuiltInResult => { new PatternSlot({ contextId: SLOT_CONTEXT_ID, displayName: 'Children', + description: '', + example: '', + hidden: false, propertyName: 'children', id: context.options.getGlobalSlotId(patternId, SLOT_CONTEXT_ID), + required: false, type: Types.SlotType.Children }) ]; diff --git a/src/model/pattern-library/builtins/page.ts b/src/model/pattern-library/builtins/page.ts index 03258bc15..ac807b29d 100644 --- a/src/model/pattern-library/builtins/page.ts +++ b/src/model/pattern-library/builtins/page.ts @@ -66,8 +66,12 @@ export const Page = (context: BuiltInContext): BuiltInResult => { new PatternSlot({ contextId: 'children', displayName: 'Children', + description: '', + example: '', + hidden: false, propertyName: 'children', id: context.options.getGlobalSlotId(patternId, SLOT_CONTEXT_ID), + required: false, type: Types.SlotType.Children }) ], diff --git a/src/model/pattern/pattern-slot.ts b/src/model/pattern/pattern-slot.ts index deef4b08c..41c81a6b8 100644 --- a/src/model/pattern/pattern-slot.ts +++ b/src/model/pattern/pattern-slot.ts @@ -3,22 +3,34 @@ import * as Types from '../../types'; export interface PatternSlotInit { contextId: string; displayName: string; + description: string; + example: string; + hidden: boolean; id: string; propertyName: string; + required: boolean; type: Types.SlotType; } export class PatternSlot { private contextId: string; private displayName: string; + private description: string; + private example: string; + private hidden: boolean; private id: string; private propertyName: string; + private required: boolean; private type: Types.SlotType; public constructor(init: PatternSlotInit) { this.type = init.type; this.id = init.id; this.displayName = init.displayName; + this.description = init.description; + this.example = init.example; + this.hidden = init.hidden; + this.required = init.required; this.type = init.type; this.propertyName = init.propertyName; this.contextId = init.contextId; @@ -27,9 +39,13 @@ export class PatternSlot { public static from(serialized: Types.SerializedPatternSlot): PatternSlot { return new PatternSlot({ contextId: serialized.contextId, - displayName: serialized.displayName, + description: serialized.description, + displayName: serialized.label, + example: serialized.example, + hidden: serialized.hidden, id: serialized.id, propertyName: serialized.propertyName, + required: serialized.required, type: toSlotType(serialized.type) }); } @@ -38,6 +54,10 @@ export class PatternSlot { return this.contextId; } + public getHidden(): boolean { + return this.hidden; + } + public getId(): string { return this.id; } @@ -57,9 +77,13 @@ export class PatternSlot { public toJSON(): Types.SerializedPatternSlot { return { contextId: this.contextId, - displayName: this.displayName, + description: this.description, + example: this.example, + hidden: this.hidden, + label: this.displayName, propertyName: this.propertyName, id: this.id, + required: this.required, type: this.type }; } diff --git a/src/store/view-store.ts b/src/store/view-store.ts index 88b48ae7c..0c44a982f 100644 --- a/src/store/view-store.ts +++ b/src/store/view-store.ts @@ -158,8 +158,9 @@ export class ViewStore { new Model.ElementContent( { elementIds: [], + forcedOpen: false, id: uuid.v4(), - name: slot.getName(), + open: false, slotId: slot.getId() }, { project, patternLibrary } @@ -1149,12 +1150,15 @@ export class ViewStore { return; } - this.project.getElements().forEach(element => { - element.setSelected(false); - element.getAncestors().forEach(ancestor => { - ancestor.setForcedOpen(false); + this.project + .getElements() + .filter(element => element.getSelected()) + .forEach(element => { + element.setSelected(false); + element.getAncestors().forEach(ancestor => { + ancestor.setForcedOpen(false); + }); }); - }); } @Mobx.action diff --git a/src/types/types.ts b/src/types/types.ts index 8ac6211f8..1ca418fba 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -51,8 +51,9 @@ export interface SerializedElement { export interface SerializedElementContent { elementIds: string[]; + forcedOpen: boolean; id: string; - name: string; + open: boolean; parentElementId?: string; slotId: string; } @@ -118,9 +119,13 @@ export interface SerializedPattern { export interface SerializedPatternSlot { contextId: string; - displayName: string; + description: string; + example: string; + hidden: boolean; id: string; + label: string; propertyName: string; + required: boolean; type: string; }