index.mjs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import { shallowRef, defineComponent, h, triggerRef, onMounted, isVNode } from 'vue';
  2. import { flattedChildren } from '../../utils/vue/vnode.mjs';
  3. const getOrderedChildren = (vm, childComponentName, children) => {
  4. const nodes = flattedChildren(vm.subTree).filter(
  5. (n) => {
  6. var _a;
  7. return isVNode(n) && ((_a = n.type) == null ? void 0 : _a.name) === childComponentName && !!n.component;
  8. }
  9. );
  10. const uids = nodes.map((n) => n.component.uid);
  11. return uids.map((uid) => children[uid]).filter((p) => !!p);
  12. };
  13. const useOrderedChildren = (vm, childComponentName) => {
  14. const children = shallowRef({});
  15. const orderedChildren = shallowRef([]);
  16. const nodesMap = /* @__PURE__ */ new WeakMap();
  17. const addChild = (child) => {
  18. children.value[child.uid] = child;
  19. triggerRef(children);
  20. onMounted(() => {
  21. const childNode = child.getVnode().el;
  22. const parentNode = childNode.parentNode;
  23. if (!nodesMap.has(parentNode)) {
  24. nodesMap.set(parentNode, []);
  25. const originalFn = parentNode.insertBefore.bind(parentNode);
  26. parentNode.insertBefore = (node, anchor) => {
  27. const shouldSortChildren = nodesMap.get(parentNode).some((el) => node === el || anchor === el);
  28. if (shouldSortChildren)
  29. triggerRef(children);
  30. return originalFn(node, anchor);
  31. };
  32. }
  33. nodesMap.get(parentNode).push(childNode);
  34. });
  35. };
  36. const removeChild = (child) => {
  37. delete children.value[child.uid];
  38. triggerRef(children);
  39. const childNode = child.getVnode().el;
  40. const parentNode = childNode.parentNode;
  41. const childNodes = nodesMap.get(parentNode);
  42. const index = childNodes.indexOf(childNode);
  43. childNodes.splice(index, 1);
  44. };
  45. const sortChildren = () => {
  46. orderedChildren.value = getOrderedChildren(
  47. vm,
  48. childComponentName,
  49. children.value
  50. );
  51. };
  52. const IsolatedRenderer = (props) => {
  53. return props.render();
  54. };
  55. const ChildrenSorter = defineComponent({
  56. setup(_, { slots }) {
  57. return () => {
  58. sortChildren();
  59. return slots.default ? h(IsolatedRenderer, {
  60. render: slots.default
  61. }) : null;
  62. };
  63. }
  64. });
  65. return {
  66. children: orderedChildren,
  67. addChild,
  68. removeChild,
  69. ChildrenSorter
  70. };
  71. };
  72. export { useOrderedChildren };
  73. //# sourceMappingURL=index.mjs.map