1
0

x-show.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import { evaluateLater } from '../evaluator'
  2. import { directive } from '../directives'
  3. import { mutateDom } from '../mutation'
  4. import { once } from '../utils/once'
  5. directive('show', (el, { modifiers, expression }, { effect }) => {
  6. let evaluate = evaluateLater(el, expression)
  7. // We're going to set this function on the element directly so that
  8. // other plugins like "Collapse" can overwrite them with their own logic.
  9. if (! el._x_doHide) el._x_doHide = () => {
  10. mutateDom(() => {
  11. el.style.setProperty('display', 'none', modifiers.includes('important') ? 'important' : undefined)
  12. })
  13. }
  14. if (! el._x_doShow) el._x_doShow = () => {
  15. mutateDom(() => {
  16. if (el.style.length === 1 && el.style.display === 'none') {
  17. el.removeAttribute('style')
  18. } else {
  19. el.style.removeProperty('display')
  20. }
  21. })
  22. }
  23. let hide = () => {
  24. el._x_doHide()
  25. el._x_isShown = false
  26. }
  27. let show = () => {
  28. el._x_doShow()
  29. el._x_isShown = true
  30. }
  31. // We are wrapping this function in a setTimeout here to prevent
  32. // a race condition from happening where elements that have a
  33. // @click.away always view themselves as shown on the page.
  34. let clickAwayCompatibleShow = () => setTimeout(show)
  35. let toggle = once(
  36. value => value ? show() : hide(),
  37. value => {
  38. if (typeof el._x_toggleAndCascadeWithTransitions === 'function') {
  39. el._x_toggleAndCascadeWithTransitions(el, value, show, hide)
  40. } else {
  41. value ? clickAwayCompatibleShow() : hide()
  42. }
  43. }
  44. )
  45. let oldValue
  46. let firstTime = true
  47. effect(() => evaluate(value => {
  48. // Let's make sure we only call this effect if the value changed.
  49. // This prevents "blip" transitions. (1 tick out, then in)
  50. if (! firstTime && value === oldValue) return
  51. if (modifiers.includes('immediate')) value ? clickAwayCompatibleShow() : hide()
  52. toggle(value)
  53. oldValue = value
  54. firstTime = false
  55. }))
  56. })