diff --git a/package-lock.json b/package-lock.json index 411a3f0..f7300ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3382,6 +3382,12 @@ "esutils": "2.0.2" } }, + "dom-helpers": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.3.1.tgz", + "integrity": "sha512-2Sm+JaYn74OiTM2wHvxJOo3roiq/h25Yi69Fqk269cNUwIXsCvATB6CRSFC9Am/20G2b28hGv/+7NiWydIrPvg==", + "dev": true + }, "domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", @@ -9592,6 +9598,17 @@ "prop-types": "15.6.1" } }, + "react-transition-group": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.3.1.tgz", + "integrity": "sha512-hu4/LAOFSKjWt1+1hgnOv3ldxmt6lvZGTWz4KUkFrqzXrNDIVSu6txIcPszw7PNduR8en9YTN55JLRyd/L1ZiQ==", + "dev": true, + "requires": { + "dom-helpers": "3.3.1", + "loose-envify": "1.3.1", + "prop-types": "15.6.1" + } + }, "read-chunk": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-2.1.0.tgz", diff --git a/package.json b/package.json index 2d9dbd0..24cda54 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "eslint-plugin-react": "^7.8.2", "mini-css-extract-plugin": "^0.4.0", "node-sass": "^4.9.0", + "react-transition-group": "^2.3.1", "sass-loader": "^7.0.1", "style-loader": "^0.21.0", "webpack": "^4.8.3", diff --git a/src/widget.js b/src/widget.js index 658b5df..98eb49d 100644 --- a/src/widget.js +++ b/src/widget.js @@ -1,35 +1,69 @@ import React from 'react'; import PropTypes from 'prop-types'; -import './widget.scss' +import { Transition } from 'react-transition-group'; +import './widget.scss'; class Widget extends React.Component { state = { opened: false, + showDock: true, } - handleOpen = () => { + handleToggleOpen = () => { + this.setState((prev) => { + let showDock = prev.showDock; + if (!prev.opened) { + showDock = false; + } + return { + showDock, + opened: !prev.opened, + }; + }); + } + + handleWidgetExit = () => { + this.setState({ + showDock: true, + }); + } + + renderBody = () => { + if (this.state.showDock) { + return ( + + ^ OPEN ^ + + ); + } + return ""; } render() { - let body = ""; - if (this.state.opened) { - body = ( -
-
- Open -
-
- Body -
-
- Footer -
-
- ); - } + let body = this.renderBody(); + return ( -
- Open +
+ + {(status) => ( +
+
+
+ Header +
+ + X + +
+
+ Body +
+
+ Footer +
+
+ )} +
{body}
); diff --git a/src/widget.scss b/src/widget.scss index 899740e..4eb905b 100644 --- a/src/widget.scss +++ b/src/widget.scss @@ -1,17 +1,94 @@ -.widget { +@keyframes slideInUp { + from { + transform: translate3d(0, 100%, 0); + visibility: visible; + } + + to { + transform: translate3d(0, 0, 0); + } +} + +@keyframes slideOutDown { + from { + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + transform: translate3d(0, 100%, 0); + } +} + +.docked-widget { position: fixed; - bottom: 10px; + bottom: 0px; right: 10px; - - width: 50px; - height: 20px; - text-align: center; - border: 1px solid; - padding: 10px; + width: 200px; } -.widget:hover { - background-color: blue; - color: white; +.dock { cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + padding: 10px; + width: 180px; + border: 1px solid grey; +} + + +.widget { + width: 200px; + border: 1px solid grey; + border-bottom: none; + animation-duration: 0.2s; + animation-fill-mode: forwards; + + &-entering { + animation-name: slideInUp; + } + &-entered { + visibility: visible; + } + &-exiting { + animation-name: slideOutDown; + } + &-exited { + visibility: hidden; + } + + &-header { + height: 30px; + line-height: 30px; + background: lightgrey; + color: grey; + padding-left: 10px; + + display: flex; + align-items: stretch; + + &-title { + display: flex; + flex-grow: 1; + } + + &-icon { + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + padding: .75rem; + } + } + &-body { + background: white; + padding: 10px; + height: 150px; + } + &-footer { + background: green; + line-height: 30px; + padding-left: 10px; + } }