From 309bfd6a5b4ac5573fee7464e870f3fbb28d5e50 Mon Sep 17 00:00:00 2001 From: Gavin Foster Date: Thu, 20 Jun 2019 12:26:02 -0500 Subject: [PATCH] Optional Mount Parameters (#123) * adding optional parameters * updating bodyText mount prop to default * updating snapshot for new props * adding parent element for mounting * adding null default for parentElement * adding dist to gitignore * adding test case for mounting to element * adding div to document in test * unmount after test * updating test to pass * updating eslint to handle certain rules as warning and fix others --- .eslintrc | 5 ++++- .gitignore | 1 + jest/cssTransform.js | 6 +++--- jest/fileTransform.js | 6 +++--- package.json | 3 ++- public/blank.html | 4 +++- .../__snapshots__/widget.test.js.snap | 18 ++++++++++++++--- src/components/widget.js | 20 ++++++++++++++++--- src/components/widget.test.js | 3 +-- src/outputs/embeddable-widget.js | 11 +++++++--- src/outputs/embeddable-widget.test.js | 14 +++++++++++++ webpack.config.js | 10 ++++++---- 12 files changed, 77 insertions(+), 24 deletions(-) diff --git a/.eslintrc b/.eslintrc index 7db87fb..a2e522c 100644 --- a/.eslintrc +++ b/.eslintrc @@ -7,7 +7,10 @@ "extends": "airbnb", "rules": { "no-underscore-dangle": 0, - "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }] + "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], + "import/prefer-default-export": 1, + "import/no-extraneous-dependencies": 1, + "no-await-in-loop": 1 }, "plugins": ["react"], "settings": { diff --git a/.gitignore b/.gitignore index ba2a97b..cd33ac2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules coverage +/dist/* \ No newline at end of file diff --git a/jest/cssTransform.js b/jest/cssTransform.js index 24f3811..6f1e714 100644 --- a/jest/cssTransform.js +++ b/jest/cssTransform.js @@ -1,8 +1,8 @@ module.exports = { process() { - return 'module.exports = {};' + return 'module.exports = {};'; }, getCacheKey() { - return 'cssTransform' + return 'cssTransform'; }, -} +}; diff --git a/jest/fileTransform.js b/jest/fileTransform.js index 98f79ba..dee01da 100644 --- a/jest/fileTransform.js +++ b/jest/fileTransform.js @@ -1,7 +1,7 @@ -const path = require('path') +const path = require('path'); module.exports = { process(src, filename) { - return `module.exports = ${JSON.stringify(path.basename(filename))};` + return `module.exports = ${JSON.stringify(path.basename(filename))};`; }, -} \ No newline at end of file +}; diff --git a/package.json b/package.json index 146f983..ed6f6cf 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "start": "webpack-dev-server", "test": "jest", "test-update-snapshots": "jest --updateSnapshot", - "deploy": "npm run build && gh-pages -d dist" + "deploy": "npm run build && gh-pages -d dist", + "lint": "./node_modules/.bin/eslint ." }, "babel": { "presets": [ diff --git a/public/blank.html b/public/blank.html index a25ee66..282005b 100644 --- a/public/blank.html +++ b/public/blank.html @@ -8,7 +8,9 @@ diff --git a/src/components/__snapshots__/widget.test.js.snap b/src/components/__snapshots__/widget.test.js.snap index 244c726..4041c21 100644 --- a/src/components/__snapshots__/widget.test.js.snap +++ b/src/components/__snapshots__/widget.test.js.snap @@ -1,7 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[` open/close 1`] = ` - +
@@ -65,7 +69,11 @@ exports[` open/close 1`] = ` `; exports[` open/close 2`] = ` - +
@@ -121,7 +129,11 @@ exports[` open/close 2`] = ` `; exports[` open/close 3`] = ` - +
diff --git a/src/components/widget.js b/src/components/widget.js index 9d379d3..36c1872 100644 --- a/src/components/widget.js +++ b/src/components/widget.js @@ -1,4 +1,5 @@ import React, { Component } from 'react'; +import PropTypes from 'prop-types'; import { Transition } from 'react-transition-group'; import './widget.scss'; @@ -47,6 +48,7 @@ class Widget extends Component { render() { const { opened } = this.state; const body = this.renderBody(); + const { bodyText, headerText, footerText } = this.props; return (
@@ -55,7 +57,7 @@ class Widget extends Component {
- Header + {headerText}
- Body + {bodyText}
- Footer + {footerText}
)} @@ -81,4 +83,16 @@ class Widget extends Component { } } +Widget.propTypes = { + headerText: PropTypes.string, + bodyText: PropTypes.string, + footerText: PropTypes.string, +}; + +Widget.defaultProps = { + headerText: 'Header', + bodyText: 'Body', + footerText: 'Footer', +}; + export default Widget; diff --git a/src/components/widget.test.js b/src/components/widget.test.js index 890a641..9eeed07 100644 --- a/src/components/widget.test.js +++ b/src/components/widget.test.js @@ -28,10 +28,9 @@ describe('', () => { { const dockAnchorEl = await waitForSelection(widgetDom, 'button.dock'); - expect(dockAnchorEl).toHaveLength(1); + expect(dockAnchorEl).toHaveLength(1); } expect(widgetDom).toMatchSnapshot(); }); - }); diff --git a/src/outputs/embeddable-widget.js b/src/outputs/embeddable-widget.js index 241c53d..9b21842 100644 --- a/src/outputs/embeddable-widget.js +++ b/src/outputs/embeddable-widget.js @@ -6,8 +6,8 @@ import '../../vendor/cleanslate.css'; export default class EmbeddableWidget { static el; - static mount() { - const component = ; + static mount({ parentElement = null, ...props } = {}) { + const component = ; function doRender() { if (EmbeddableWidget.el) { @@ -15,7 +15,12 @@ export default class EmbeddableWidget { } const el = document.createElement('div'); el.setAttribute('class', 'cleanslate'); - document.body.appendChild(el); + + if (parentElement) { + document.querySelector(parentElement).appendChild(el); + } else { + document.body.appendChild(el); + } ReactDOM.render( component, el, diff --git a/src/outputs/embeddable-widget.test.js b/src/outputs/embeddable-widget.test.js index 6d58519..d28f958 100644 --- a/src/outputs/embeddable-widget.test.js +++ b/src/outputs/embeddable-widget.test.js @@ -21,6 +21,20 @@ describe('EmbeddableWidget', () => { await waitForSelection(document, 'div'); }); + test('#mount to document element', async () => { + const newElement = document.createElement('span'); + newElement.setAttribute('id', 'widget-mount'); + document.body.appendChild(newElement); + + EmbeddableWidget.mount({ + parentElement: '#widget-mount', + }); + + await waitForSelection(document, 'div'); + + expect(document.querySelectorAll('#widget-mount')).toHaveLength(1); + }); + test('#mount twice', async () => { EmbeddableWidget.mount(); expect(() => EmbeddableWidget.mount()).toThrow('already mounted'); diff --git a/webpack.config.js b/webpack.config.js index ad8d670..72daa18 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,5 +1,4 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const CleanWebpackPlugin = require('clean-webpack-plugin'); const increaseSpecificity = require('postcss-increase-specificity'); const JavaScriptObfuscator = require('webpack-obfuscator'); const CopyPlugin = require('copy-webpack-plugin'); @@ -14,7 +13,7 @@ const defaultConfig = { mode: process.env.NODE_ENV || 'development', devServer: { contentBase: publicDir, - port: 9000 + port: 9000, }, plugins: [ // new CleanWebpackPlugin({protectWebpackAssets: false}), @@ -39,8 +38,11 @@ const defaultConfig = { { test: /\.js$/, exclude: /node_modules/, - use: ['eslint-loader'] - }, + loader: 'eslint-loader', + options: { + emitWarning: true, + }, + }, { test: /\.(scss|css)$/, use: [