@abraca/nuxt 2.25.0 → 2.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=4.0.0"
6
6
  },
7
- "version": "2.25.0",
7
+ "version": "2.26.0",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
@@ -1,5 +1,6 @@
1
1
  <script setup>
2
2
  import { ref, computed, nextTick, shallowRef, toRaw, watch } from "vue";
3
+ import { useVirtualizer } from "@tanstack/vue-virtual";
3
4
  import { useAbracadabra, useTrash, useChat, useVoice, useToast, useAppConfig, useSyncedMap, useDocImport, useDocExport, useWindowManager, useAwareness } from "#imports";
4
5
  import { resolveDocType, getAvailableDocTypes } from "../utils/docTypes";
5
6
  import { avatarBorderStyle } from "../utils/avatarStyle";
@@ -225,6 +226,20 @@ const flatItems = computed(() => {
225
226
  }
226
227
  return result;
227
228
  });
229
+ const scrollParent = ref(null);
230
+ const ROW_HEIGHT = 32;
231
+ const rowVirtualizer = useVirtualizer(
232
+ computed(() => ({
233
+ count: flatItems.value.length,
234
+ getScrollElement: () => scrollParent.value,
235
+ estimateSize: () => ROW_HEIGHT,
236
+ overscan: 12,
237
+ getItemKey: (index) => flatItems.value[index]?.id ?? index
238
+ }))
239
+ );
240
+ const virtualRows = computed(
241
+ () => rowVirtualizer.value.getVirtualItems().map((vRow) => ({ vRow, item: flatItems.value[vRow.index], idx: vRow.index })).filter((r) => r.item)
242
+ );
228
243
  function getItemIcon(item) {
229
244
  const meta = item.meta;
230
245
  if (meta?.icon && typeof meta.icon === "string") return `i-lucide-${meta.icon}`;
@@ -983,6 +998,9 @@ function onTreeDragOver(e) {
983
998
  onImportDragOver(e);
984
999
  }
985
1000
  const focusedIndex = ref(-1);
1001
+ watch(focusedIndex, (i) => {
1002
+ if (i >= 0 && i < flatItems.value.length) rowVirtualizer.value.scrollToIndex(i, { align: "auto" });
1003
+ });
986
1004
  function onTreeKeydown(e) {
987
1005
  const items = flatItems.value;
988
1006
  if (!items.length) return;
@@ -1117,7 +1135,7 @@ defineExpose({
1117
1135
 
1118
1136
  <div
1119
1137
  v-else-if="!collapsed"
1120
- class="flex flex-col min-h-0"
1138
+ class="flex flex-col min-h-0 h-full"
1121
1139
  :class="externalDragActive ? 'ring-2 ring-inset ring-(--ui-primary)/30 rounded-(--ui-radius) bg-(--ui-primary)/3' : ''"
1122
1140
  tabindex="0"
1123
1141
  role="tree"
@@ -12,8 +12,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
12
12
  awareness: boolean;
13
13
  tag: "video" | "audio";
14
14
  live: boolean;
15
- controls: boolean;
16
15
  total: boolean;
16
+ controls: boolean;
17
17
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
18
18
  declare const _default: typeof __VLS_export;
19
19
  export default _default;
@@ -12,8 +12,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
12
12
  awareness: boolean;
13
13
  tag: "video" | "audio";
14
14
  live: boolean;
15
- controls: boolean;
16
15
  total: boolean;
16
+ controls: boolean;
17
17
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
18
18
  declare const _default: typeof __VLS_export;
19
19
  export default _default;
@@ -23,9 +23,23 @@ export function useChildTree(rootDoc, parentDocId, options) {
23
23
  }
24
24
  return result;
25
25
  });
26
+ const childrenByParent = computed(() => {
27
+ const map = /* @__PURE__ */ new Map();
28
+ for (const e of entries.value) {
29
+ let arr = map.get(e.parentId);
30
+ if (!arr) {
31
+ arr = [];
32
+ map.set(e.parentId, arr);
33
+ }
34
+ arr.push(e);
35
+ }
36
+ for (const arr of map.values()) arr.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
37
+ return map;
38
+ });
26
39
  function childrenOf(parentId) {
27
40
  const target = parentId === null ? parentDocId : parentId;
28
- return entries.value.filter((e) => e.parentId === target).sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
41
+ const bucket = childrenByParent.value.get(target);
42
+ return bucket ? bucket.slice() : [];
29
43
  }
30
44
  function descendantsOf(id) {
31
45
  const result = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abraca/nuxt",
3
- "version": "2.25.0",
3
+ "version": "2.26.0",
4
4
  "description": "First-class Nuxt module for the Abracadabra CRDT collaboration platform",
5
5
  "repository": "abracadabra/abracadabra-nuxt",
6
6
  "license": "MIT",