apiCreateIf.ts 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import { type Block, type BlockFn, insert } from './block'
  2. import { advanceHydrationNode, isHydrating } from './dom/hydration'
  3. import {
  4. insertionAnchor,
  5. insertionParent,
  6. isLastInsertion,
  7. resetInsertionState,
  8. } from './insertionState'
  9. import { renderEffect } from './renderEffect'
  10. import { DynamicFragment } from './fragment'
  11. import { createComment, createTextNode } from './dom/node'
  12. export function createIf(
  13. condition: () => any,
  14. b1: BlockFn,
  15. b2?: BlockFn,
  16. once?: boolean,
  17. index?: number,
  18. ): Block {
  19. const _insertionParent = insertionParent
  20. const _insertionAnchor = insertionAnchor
  21. const _isLastInsertion = isLastInsertion
  22. if (!isHydrating) resetInsertionState()
  23. let frag: Block
  24. if (once) {
  25. frag = condition()
  26. ? b1()
  27. : b2
  28. ? b2()
  29. : [__DEV__ ? createComment('if') : createTextNode()]
  30. } else {
  31. // DynamicFragment should be keyed for correct transition behavior
  32. const keyed = index != null
  33. frag =
  34. isHydrating || __DEV__
  35. ? new DynamicFragment('if', keyed)
  36. : new DynamicFragment(undefined, keyed)
  37. renderEffect(() => {
  38. const ok = condition()
  39. ;(frag as DynamicFragment).update(
  40. ok ? b1 : b2,
  41. keyed ? `${index}${ok ? 0 : 1}` : undefined,
  42. )
  43. })
  44. }
  45. if (!isHydrating) {
  46. if (_insertionParent) insert(frag, _insertionParent, _insertionAnchor)
  47. } else {
  48. if (_isLastInsertion) {
  49. advanceHydrationNode(_insertionParent!)
  50. }
  51. }
  52. return frag
  53. }