Skip to content

Commit

Permalink
feat(api): integrate changes from sweetalert2/sweetalert2#1036
Browse files Browse the repository at this point in the history
  • Loading branch information
zenflow committed Mar 27, 2018
1 parent 4231d0c commit b661367
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 143 deletions.
12 changes: 6 additions & 6 deletions README.md
Expand Up @@ -21,20 +21,20 @@ The following options can be React elements:
## Example

```jsx
import swal from 'sweetalert2'
import Swal from 'sweetalert2'
import withReactContent from 'sweetalert2-react-content'

const mySwal = withReactContent(swal)
// or just `const mySwal = withReactContent()`
const MySwal = withReactContent(Swal)
// or just `const MySwal = withReactContent()`

mySwal({
MySwal.fire({
title: <p>Hello World</p>,
footer: 'Copyright 2018',
onOpen: () => {
mySwal.clickConfirm() // `mySwal` comes with all of the methods of `swal`
MySwal.clickConfirm() // `MySwal` is a subclass of `Swal` with all the same instance & static methods
}
}).then(() => {
return mySwal(<p>Shordhand works too</p>)
return MySwal.fire(<p>Shorthand works too</p>)
})
```

Expand Down
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -48,7 +48,7 @@
"peerDependencies": {
"react": "^16.0.0",
"react-dom": "^16.0.0",
"sweetalert2": "^7.14.0"
"sweetalert2": "^7.18.0"
},
"devDependencies": {
"@semantic-release/changelog": "^2.0.0",
Expand All @@ -75,7 +75,7 @@
"react": "^16.2.0",
"react-dom": "^16.2.0",
"semantic-release": "^15.0.0",
"sweetalert2": "^7.15.1",
"sweetalert2": "^7.18.0",
"tslint": "^5.9.1",
"typescript": "^2.7.2",
"webpack": "^4.1.1",
Expand Down
84 changes: 42 additions & 42 deletions src/index.js
@@ -1,54 +1,54 @@
import swal from 'sweetalert2'
import Swal from 'sweetalert2'
import React from 'react'
import ReactDOM from 'react-dom'
import { mounts } from './mounts'

const noop = () => {}

export default function withReactContent(parentSwal = swal) {
const argsToParams = args => {
if (React.isValidElement(args[0]) || React.isValidElement(args[1])) {
const params = {}
;['title', 'html', 'type'].forEach((name, index) => {
if (args[index] !== undefined) {
params[name] = args[index]
}
})
return params
} else {
return parentSwal.argsToParams(args)
export default function withReactContent(ParentSwal = Swal) {
return class extends ParentSwal {
static argsToParams(args) {
if (React.isValidElement(args[0]) || React.isValidElement(args[1])) {
const params = {}
;['title', 'html', 'type'].forEach((name, index) => {
if (args[index] !== undefined) {
params[name] = args[index]
}
})
return params
} else {
return ParentSwal.argsToParams(args)
}
}
}

const fn = (...args) => {
const params = Object.assign({}, argsToParams(args)) // safe to mutate this

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

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

let domElement

const childOnOpen = params.onOpen
params.onOpen = () => {
domElement = getter(parentSwal)
ReactDOM.render(reactElement, domElement)
childOnOpen()
_main(params) {
params = Object.assign({}, params)

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

mounts.forEach(({ key, getter }) => {
if (React.isValidElement(params[key])) {
const reactElement = params[key]
params[key] = ' '

let domElement

const superOnOpen = params.onOpen
params.onOpen = () => {
domElement = getter(ParentSwal)
ReactDOM.render(reactElement, domElement)
superOnOpen()
}

const superOnClose = params.onClose
params.onClose = () => {
superOnClose()
ReactDOM.unmountComponentAtNode(domElement)
}
}
})

const childOnClose = params.onClose
params.onClose = () => {
childOnClose()
ReactDOM.unmountComponentAtNode(domElement)
}
}
return super._main(params)
}
return parentSwal(params)
}

return Object.assign(fn, parentSwal, { argsToParams })
}
6 changes: 3 additions & 3 deletions test/test-build.html
Expand Up @@ -9,10 +9,10 @@
</head>
<body>
<script>
let withReactContent = sweetalert2ReactContent.default
let mySwal = withReactContent(swal)
let withReactContent = sweetalert2ReactContent
let MySwal = withReactContent(Swal)
Promise.resolve().then(async () => {
await mySwal(React.createElement('strong', {}, ['Hello World']))
await MySwal.fire(React.createElement('strong', {}, ['Hello World']))
}).catch(console.error)
</script>
</body>
Expand Down
83 changes: 83 additions & 0 deletions test/tests/integration.js
@@ -0,0 +1,83 @@
import Swal from 'sweetalert2'
import withReactContent from '../../src/index'
import { describe, expect, it } from '../util/framework'
import {
cleanSwalState,
getSwalContentContent,
getVisibleSwalIconNames,
} from '../util/swalUtil'
import { timeout } from '../util/util'

describe('integration', () => {
it('renders React elements for each supported option', async () => {
await cleanSwalState()
const MySwal = withReactContent()
await MySwal.fire({
animation: false,
title: <span>title</span>,
html: <span>html</span>,
confirmButtonText: <span>confirmButtonText</span>,
cancelButtonText: <span>cancelButtonText</span>,
footer: <span>footer</span>,
onOpen: () => {
expect(MySwal.getTitle().innerHTML).toEqual('<span>title</span>')
expect(MySwal.getContent().innerHTML).toEqual('<span>html</span>')
expect(MySwal.getConfirmButton().innerHTML).toEqual(
'<span>confirmButtonText</span>',
)
expect(MySwal.getCancelButton().innerHTML).toEqual(
'<span>cancelButtonText</span>',
)
expect(MySwal.getFooter().innerHTML).toEqual('<span>footer</span>')
MySwal.clickConfirm()
},
})
})
it('can mix React and non-React params', async () => {
await cleanSwalState()
const MySwal = withReactContent()
await MySwal.fire({
animation: false,
title: <span>React element</span>,
footer: 'plain text',
onOpen: () => {
expect(MySwal.getTitle().innerHTML).toEqual(
'<span>React element</span>',
)
expect(MySwal.getFooter().innerHTML).toEqual('plain text')
MySwal.clickConfirm()
},
})
})
it('returns a class with the same instance & static properties as Swal', async () => {
const MySwal = withReactContent()
Object.keys(Swal).forEach(key => {
expect(typeof MySwal[key]).toBe(typeof Swal[key])
})
Object.keys(Swal.prototype).forEach(key => {
expect(typeof MySwal.prototype[key]).toBe(typeof Swal.prototype[key])
})
})
it('works with shorthand Swal calls', async () => {
await cleanSwalState()
const MySwal = withReactContent()
const swal = MySwal.fire(<span>title</span>, <span>html</span>, 'info')
await timeout(100)
expect(MySwal.getTitle().innerHTML).toEqual('<span>title</span>')
expect(MySwal.getContent().innerHTML).toEqual('<span>html</span>')
expect(getVisibleSwalIconNames()).toEqual(['info'])
MySwal.clickConfirm()
await swal
})
it('has no effect on normal shorthand Swal calls', async () => {
await cleanSwalState()
const MySwal = withReactContent()
const swal = MySwal.fire('my title', 'my html', 'error')
await timeout(100)
expect(MySwal.getTitle().innerHTML).toEqual('my title')
expect(getSwalContentContent().innerHTML).toEqual('my html')
expect(getVisibleSwalIconNames()).toEqual(['error'])
MySwal.clickConfirm()
await swal
})
})
90 changes: 0 additions & 90 deletions test/tests/main.js

This file was deleted.

0 comments on commit b661367

Please sign in to comment.