apiCreateFragment.ts 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. import { type Block, type BlockFn, insert } from './block'
  2. import { advanceHydrationNode, isHydrating } from './dom/hydration'
  3. import { DynamicFragment } from './fragment'
  4. import {
  5. insertionAnchor,
  6. insertionParent,
  7. isLastInsertion,
  8. resetInsertionState,
  9. } from './insertionState'
  10. import { renderEffect } from './renderEffect'
  11. /**
  12. * Create a dynamic fragment keyed by a reactive value for Vapor transitions.
  13. * The fragment is re-rendered when the key changes to trigger enter/leave
  14. * animations.
  15. *
  16. * Example:
  17. * <VaporTransition>
  18. * <h1 :key="count">{{ count }}</h1>
  19. * </VaporTransition>
  20. */
  21. export function createKeyedFragment(key: () => any, render: BlockFn): Block {
  22. const _insertionParent = insertionParent
  23. const _insertionAnchor = insertionAnchor
  24. const _isLastInsertion = isLastInsertion
  25. if (!isHydrating) resetInsertionState()
  26. const frag = __DEV__
  27. ? new DynamicFragment('keyed', true)
  28. : new DynamicFragment(undefined, true)
  29. renderEffect(() => frag.update(render, key()))
  30. if (!isHydrating) {
  31. if (_insertionParent) insert(frag, _insertionParent, _insertionAnchor)
  32. } else {
  33. if (_isLastInsertion) {
  34. advanceHydrationNode(_insertionParent!)
  35. }
  36. }
  37. return frag
  38. }