Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
zenflow committed Feb 23, 2018
0 parents commit f9af0c8
Show file tree
Hide file tree
Showing 14 changed files with 291 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"presets": [
["env", {}],
["react"]
]
}
9 changes: 9 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
root = true

[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8
indent_style = space
indent_size = 2
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package-lock.json
node_modules/
.gatsby-context.js
docs/public/
14 changes: 14 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
language: node_js
dist: trusty
node_js: 8.9
sudo: true

addons:
google-chrome: latest

script:
- xvfb-run npm test

notifications:
email:
on_success: never
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# sweetalert2-react-content
sweetalert2 decorator adding support for React elements as content

[![Travis branch](https://img.shields.io/travis/zenflow/sweetalert2-react-content/master.svg)]()
17 changes: 17 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# TODO

- publish build
- library
- call `ReactDOM.unmountComponentAtNode` when parent node is destroyed (?) not in `onClose`
- remove `require('react')`
- remove `require('react-dom')` in favor of passing in via a closure
- Workflow
- use webpack dev server
- include (active) linting in `npm start` script (webpack dev server "overlay"?)
- eslint + eslint-plugin-prettier
- semantic-release
- Tests
- add test coverage
- add snapshot testing

(also search "TODO" in code)
49 changes: 49 additions & 0 deletions karma.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const webpack = require('webpack')

module.exports = config => {
config.set({
files: [
'node_modules/babel-polyfill/dist/polyfill.min.js',
'tests/*.js'
],
browsers: [
'Chrome'
],
reporters: ['spec'],
frameworks: ['jasmine'],
preprocessors: {
'{lib,tests}/**/*.js': ['webpack', 'sourcemap']
},
webpack: {
devtool: 'inline-source-map',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {/* babel options */}
}
}
]
},
plugins: [
new webpack.ProvidePlugin({
'React': 'react'
})
]
},
webpackMiddleware: {
stats: 'errors-only',
noInfo: true
},
plugins: [
'karma-chrome-launcher',
'karma-spec-reporter',
'karma-jasmine',
'karma-webpack',
'karma-sourcemap-loader'
]
})
}
45 changes: 45 additions & 0 deletions lib/sweetalert2-react-content.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const React = require('react')
const ReactDOM = require('react-dom')
const {toParams} = require('./toParams')

const noop = () => {}

function sweetalert2ReactContent (swal) {
return Object.assign((...args) => {
// const params = {...toParams(args)} // clone so we can mutate // TODO: Uncomment
const params = Object.assign({}, toParams(args)) // clone so we can mutate

params.onOpen = params.onOpen || noop
params.onClose = params.onClose || noop

const mounts = [
['title', () => swal.getTitle()],
['html', () => swal.getContent()],
['confirmButtonText', () => swal.getConfirmButton()],
['cancelButtonText', () => swal.getCancelButton()],
['footer', () => global.document.querySelector('.swal2-container .swal2-footer')]
]

for (const [paramKey, getter] of mounts) {
if (React.isValidElement(params[paramKey])) {
const reactElement = params[paramKey]
params[paramKey] = ' '

const childOnOpen = params.onOpen
params.onOpen = () => {
ReactDOM.render(reactElement, getter())
childOnOpen()
}

const childOnClose = params.onClose
params.onClose = () => {
childOnClose()
ReactDOM.unmountComponentAtNode(getter())
}
}
}
return swal(params)
}, swal)
}

module.exports = sweetalert2ReactContent
22 changes: 22 additions & 0 deletions lib/toParams.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const React = require('react')

function isAlreadyParams (args) {
return typeof args[0] === 'object' && !React.isValidElement(args[0])
}

const argNames = ['title', 'html', 'type']
function argsToParams (args) {
const params = {}
argNames.forEach((name, index) => {
if (args[index] !== undefined) {
params[name] = args[index]
}
})
return params
}

function toParams (args) {
return isAlreadyParams(args) ? args[0] : argsToParams(args)
}

module.exports = {toParams}
52 changes: 52 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"name": "sweetalert2-react-content",
"version": "0.0.1",
"repository": "zenflow/sweetalert2-react-content",
"description": "sweetalert2 decorator adding support for React elements as content",
"main": "lib/sweetalert2-react-content.js",
"files": [
"lib/**"
],
"scripts": {
"start": "karma start karma.conf.js",
"fix": "standard --fix",
"test": "npm run test:linting && npm run test:units",
"test:linting": "standard",
"test:units": "karma start karma.conf.js --single-run"
},
"keywords": [
"sweetalert",
"sweetalert2",
"react",
"content"
],
"author": {
"name": "Matthew Francis Brunetti",
"email": "[email protected]"
},
"license": "MIT",
"peerDependencies": {
"react": "^16.2.0",
"react-dom": "^16.2.0",
"sweetalert2": "^7.9.2"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1",
"jasmine": "^3.0.0",
"karma": "^2.0.0",
"karma-chrome-launcher": "^2.2.0",
"karma-jasmine": "^1.1.1",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.32",
"karma-webpack": "^2.0.9",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"standard": "^10.0.3",
"sweetalert2": "^7.9.2",
"webpack": "^3.11.0"
}
}
19 changes: 19 additions & 0 deletions tests/integration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* global describe, expect */
const {asyncIt} = require('./support/asyncIt')
const {cleanSwalState, swal, initialSwalProps} = require('./support/swal')

describe('integration', () => {
asyncIt('`swal` properties are consistent ', async () => {
await cleanSwalState()
const assertConsistent = () => expect(Object.keys(swal)).toEqual(initialSwalProps)
assertConsistent()
await swal({
title: 'test',
onOpen: () => {
assertConsistent()
swal.clickConfirm()
}
})
assertConsistent()
})
})
7 changes: 7 additions & 0 deletions tests/support/asyncIt.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* global it */

const asyncIt = (desc, fn) => {
it(desc, done => fn().then(done, done.fail))
}

module.exports = {asyncIt}
17 changes: 17 additions & 0 deletions tests/support/swal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const swal = require('sweetalert2')

const initialSwalProps = Object.keys(swal)

async function cleanSwalState () {
await swal({
animation: false,
title: 'clear',
onOpen: () => swal.clickConfirm()
})
}

module.exports = {
swal,
initialSwalProps,
cleanSwalState
}
26 changes: 26 additions & 0 deletions tests/sweetalert2-react-content.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* global describe, expect */
const {asyncIt} = require('./support/asyncIt')
const {cleanSwalState, swal} = require('./support/swal')
const withReact = require('../lib/sweetalert2-react-content')

describe('sweetalert2-react-content', () => {
asyncIt('basic usage', async () => {
await cleanSwalState()
const mySwal = withReact(swal)
expect(mySwal.isVisible()).toBe(false)
await mySwal({
animation: false,
title: <span>react content</span>,
onOpen: () => {
expect(mySwal.isVisible()).toBe(true)
expect(global.document.body.querySelector('.swal2-title').innerHTML).toEqual('<span>react content</span>')
mySwal.clickConfirm()
}
})
expect(mySwal.isVisible()).toBe(false)
})
asyncIt('returns a function with the same props as swal', async () => {
const mySwal = withReact(swal)
expect(Object.keys(mySwal)).toEqual(Object.keys(swal))
})
})

0 comments on commit f9af0c8

Please sign in to comment.