VTreeviewChildren.mjs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import { mergeProps as _mergeProps, resolveDirective as _resolveDirective, createVNode as _createVNode, Fragment as _Fragment } from "vue";
  2. // Components
  3. import { VTreeviewGroup } from "./VTreeviewGroup.mjs";
  4. import { VTreeviewItem } from "./VTreeviewItem.mjs";
  5. import { VCheckboxBtn } from "../../components/VCheckbox/index.mjs"; // Composables
  6. import { IconValue } from "../../composables/icons.mjs"; // Utilities
  7. import { computed, reactive, toRaw, withModifiers } from 'vue';
  8. import { genericComponent, propsFactory } from "../../util/index.mjs"; // Types
  9. export const makeVTreeviewChildrenProps = propsFactory({
  10. loadChildren: Function,
  11. loadingIcon: {
  12. type: String,
  13. default: '$loading'
  14. },
  15. items: Array,
  16. openOnClick: {
  17. type: Boolean,
  18. default: undefined
  19. },
  20. indeterminateIcon: {
  21. type: IconValue,
  22. default: '$checkboxIndeterminate'
  23. },
  24. falseIcon: IconValue,
  25. trueIcon: IconValue,
  26. returnObject: Boolean,
  27. selectable: Boolean,
  28. selectedColor: String,
  29. selectStrategy: [String, Function, Object]
  30. }, 'VTreeviewChildren');
  31. export const VTreeviewChildren = genericComponent()({
  32. name: 'VTreeviewChildren',
  33. props: makeVTreeviewChildrenProps(),
  34. setup(props, _ref) {
  35. let {
  36. slots
  37. } = _ref;
  38. const isLoading = reactive(new Set());
  39. const isClickOnOpen = computed(() => props.openOnClick != null ? props.openOnClick : props.selectable);
  40. async function checkChildren(item) {
  41. try {
  42. if (!props.items?.length || !props.loadChildren) return;
  43. if (item?.children?.length === 0) {
  44. isLoading.add(item.value);
  45. await props.loadChildren(item.raw);
  46. }
  47. } finally {
  48. isLoading.delete(item.value);
  49. }
  50. }
  51. function selectItem(select, isSelected) {
  52. if (props.selectable) {
  53. select(!isSelected);
  54. }
  55. }
  56. return () => slots.default?.() ?? props.items?.map(item => {
  57. const {
  58. children,
  59. props: itemProps
  60. } = item;
  61. const loading = isLoading.has(item.value);
  62. const slotsWithItem = {
  63. prepend: slotProps => _createVNode(_Fragment, null, [props.selectable && (!children || children && !['leaf', 'single-leaf'].includes(props.selectStrategy)) && _createVNode("div", null, [_createVNode(VCheckboxBtn, {
  64. "key": item.value,
  65. "modelValue": slotProps.isSelected,
  66. "loading": loading,
  67. "color": props.selectedColor,
  68. "indeterminate": slotProps.isIndeterminate,
  69. "indeterminateIcon": props.indeterminateIcon,
  70. "falseIcon": props.falseIcon,
  71. "trueIcon": props.trueIcon,
  72. "onClick": withModifiers(() => selectItem(slotProps.select, slotProps.isSelected), ['stop']),
  73. "onKeydown": e => {
  74. if (!['Enter', 'Space'].includes(e.key)) return;
  75. e.stopPropagation();
  76. selectItem(slotProps.select, slotProps.isSelected);
  77. }
  78. }, null)]), slots.prepend?.({
  79. ...slotProps,
  80. item: item.raw,
  81. internalItem: item
  82. })]),
  83. append: slots.append ? slotProps => slots.append?.({
  84. ...slotProps,
  85. item: item.raw,
  86. internalItem: item
  87. }) : undefined,
  88. title: slots.title ? slotProps => slots.title?.({
  89. ...slotProps,
  90. item: item.raw,
  91. internalItem: item
  92. }) : undefined
  93. };
  94. const treeviewGroupProps = VTreeviewGroup.filterProps(itemProps);
  95. const treeviewChildrenProps = VTreeviewChildren.filterProps(props);
  96. return children ? _createVNode(VTreeviewGroup, _mergeProps(treeviewGroupProps, {
  97. "value": props.returnObject ? item.raw : treeviewGroupProps?.value
  98. }), {
  99. activator: _ref2 => {
  100. let {
  101. props: activatorProps
  102. } = _ref2;
  103. const listItemProps = {
  104. ...itemProps,
  105. ...activatorProps,
  106. value: itemProps?.value,
  107. onToggleExpand: [() => checkChildren(item), activatorProps.onClick],
  108. onClick: isClickOnOpen.value ? [() => checkChildren(item), activatorProps.onClick] : undefined
  109. };
  110. return _createVNode(VTreeviewItem, _mergeProps(listItemProps, {
  111. "value": props.returnObject ? toRaw(item.raw) : itemProps.value,
  112. "loading": loading
  113. }), slotsWithItem);
  114. },
  115. default: () => _createVNode(VTreeviewChildren, _mergeProps(treeviewChildrenProps, {
  116. "items": children,
  117. "returnObject": props.returnObject
  118. }), slots)
  119. }) : slots.item?.({
  120. props: itemProps,
  121. item: item.raw,
  122. internalItem: item
  123. }) ?? _createVNode(VTreeviewItem, _mergeProps(itemProps, {
  124. "value": props.returnObject ? toRaw(item.raw) : itemProps.value
  125. }), slotsWithItem);
  126. });
  127. }
  128. });
  129. //# sourceMappingURL=VTreeviewChildren.mjs.map