Skip to content

Commit

Permalink
feat: support .update() method (#179)
Browse files Browse the repository at this point in the history
  • Loading branch information
limonte authored Oct 18, 2021
1 parent f91c096 commit e9ce05c
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 34 deletions.
89 changes: 55 additions & 34 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,40 @@ import ReactDOM from 'react-dom'
import { mounts } from './mounts'

const noop = () => {} // eslint-disable-line @typescript-eslint/no-empty-function
const error = message => new Error(`sweetalert2-react-content: ${message}`)

export default function withReactContent (ParentSwal) {
/* Returns `params` separated into a tuple of `reactParams` (the React params that need to be rendered)
and`otherParams` (all the other parameters, with any React params replaced with a space ' ') */
function extractReactParams (params) {
const reactParams = {}
const otherParams = {}
const mountKeys = mounts.map(mount => mount.key)
Object.entries(params).forEach(([key, value]) => {
if (mountKeys.includes(key) && React.isValidElement(value)) {
reactParams[key] = value
otherParams[key] = ' '
} else {
otherParams[key] = value
}
})
return [reactParams, otherParams]
}
function render (swal, reactParams) {
Object.entries(reactParams).forEach(([key, value]) => {
const mount = mounts.find(mount => mount.key === key)
const domElement = mount.getter(ParentSwal)
ReactDOM.render(value, domElement)
swal.__mountedDomElements.push(domElement)
})
}

function unrender (swal) {
swal.__mountedDomElements.forEach(domElement => {
ReactDOM.unmountComponentAtNode(domElement)
})
swal.__mountedDomElements = []
}

return class extends ParentSwal {
static argsToParams (args) {
if (React.isValidElement(args[0]) || React.isValidElement(args[1])) {
Expand All @@ -22,41 +53,31 @@ export default function withReactContent (ParentSwal) {
}

_main (params, mixinParams) {
params = Object.assign({}, mixinParams, params)

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

let domElement

const openHookName = 'didOpen'
const superOpenHook = params[openHookName] || noop
params[openHookName] = (element) => {
domElement = getter(ParentSwal)
domElement && ReactDOM.render(reactElement, domElement)
superOpenHook(element)
}

const destroyHookName = 'didDestroy'
const superDestroyHook = params[destroyHookName] || noop
params[destroyHookName] = (element) => {
superDestroyHook(element)
if (domElement) {
ReactDOM.unmountComponentAtNode(domElement)
}
}
}
})

return super._main(params, mixinParams)
this.__mountedDomElements = []
this.__params = Object.assign({}, mixinParams, params)
const [reactParams, otherParams] = extractReactParams(this.__params)
const superDidOpen = otherParams.didOpen || noop
const superDidDestroy = otherParams.didDestroy || noop
return super._main(
Object.assign({}, otherParams, {
didOpen: popup => {
render(this, reactParams)
superDidOpen(popup)
},
didDestroy: popup => {
superDidDestroy(popup)
unrender(this)
},
}),
)
}

update () {
throw error(
'Swal.update() is not yet supported. See https://github.com/sweetalert2/sweetalert2-react-content/issues/73',
)
update (params) {
Object.assign(this.__params, params)
unrender(this)
const [reactParams, otherParams] = extractReactParams(this.__params)
super.update(otherParams)
render(this, reactParams)
}
}
}
16 changes: 16 additions & 0 deletions test/integration.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,20 @@ describe('integration', () => {
MySwal.clickConfirm()
await swal
})
it('can update params via .update()', async () => {
await cleanSwalState()
const MySwal = withReactContent(Swal)
const swal = MySwal.fire(<span>title</span>, <span>html</span>, 'error')
await timeout(100)
MySwal.update({
title: <span>new title</span>,
html: <span>new html</span>,
icon: 'success',
})
expect(MySwal.getTitle().innerHTML).toEqual('<span>new title</span>')
expect(MySwal.getHtmlContainer().innerHTML).toEqual('<span>new html</span>')
expect(getVisibleSwalIconNames()).toEqual(['success'])
MySwal.clickConfirm()
await swal
})
})

0 comments on commit e9ce05c

Please sign in to comment.