@abraca/nuxt 0.1.1 → 0.3.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.
Files changed (154) hide show
  1. package/dist/module.d.mts +46 -0
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +95 -2
  4. package/dist/runtime/assets/editor.css +1 -0
  5. package/dist/runtime/components/ACommandPalette.vue +4 -1
  6. package/dist/runtime/components/ADocRenderer.d.vue.ts +29 -0
  7. package/dist/runtime/components/ADocRenderer.vue +99 -0
  8. package/dist/runtime/components/ADocRenderer.vue.d.ts +29 -0
  9. package/dist/runtime/components/ADocTypeSelect.vue +4 -1
  10. package/dist/runtime/components/ADocumentTree.vue +78 -19
  11. package/dist/runtime/components/AEditor.d.vue.ts +9 -4
  12. package/dist/runtime/components/AEditor.vue +102 -7
  13. package/dist/runtime/components/AEditor.vue.d.ts +9 -4
  14. package/dist/runtime/components/AFloatingWindow.vue +1 -1
  15. package/dist/runtime/components/AIconPicker.vue +8 -2
  16. package/dist/runtime/components/ANodePanel.vue +100 -61
  17. package/dist/runtime/components/ANotifications.vue +35 -8
  18. package/dist/runtime/components/APermissionGuard.vue +3 -1
  19. package/dist/runtime/components/APresence.vue +14 -3
  20. package/dist/runtime/components/AProvider.vue +7 -1
  21. package/dist/runtime/components/AVoiceBar.vue +57 -15
  22. package/dist/runtime/components/AVoiceTile.vue +4 -1
  23. package/dist/runtime/components/AWindowLayer.vue +1 -1
  24. package/dist/runtime/components/aware/AArea.vue +1 -1
  25. package/dist/runtime/components/aware/AAvatar.vue +85 -16
  26. package/dist/runtime/components/aware/AButton.vue +5 -1
  27. package/dist/runtime/components/aware/ACursorLabel.vue +5 -1
  28. package/dist/runtime/components/aware/ADocBadge.vue +4 -1
  29. package/dist/runtime/components/aware/AFacepile.vue +13 -3
  30. package/dist/runtime/components/aware/AInput.vue +5 -1
  31. package/dist/runtime/components/aware/ATextarea.vue +5 -1
  32. package/dist/runtime/components/aware/AUserList.vue +8 -2
  33. package/dist/runtime/components/renderers/ACalendarRenderer.d.vue.ts +12 -1
  34. package/dist/runtime/components/renderers/ACalendarRenderer.vue +388 -114
  35. package/dist/runtime/components/renderers/ACalendarRenderer.vue.d.ts +12 -1
  36. package/dist/runtime/components/renderers/ACallRenderer.d.vue.ts +13 -0
  37. package/dist/runtime/components/renderers/ACallRenderer.vue +169 -0
  38. package/dist/runtime/components/renderers/ACallRenderer.vue.d.ts +13 -0
  39. package/dist/runtime/components/renderers/AChecklistRenderer.d.vue.ts +19 -0
  40. package/dist/runtime/components/renderers/AChecklistRenderer.vue +581 -0
  41. package/dist/runtime/components/renderers/AChecklistRenderer.vue.d.ts +19 -0
  42. package/dist/runtime/components/renderers/ADashboardRenderer.d.vue.ts +19 -0
  43. package/dist/runtime/components/renderers/ADashboardRenderer.vue +1372 -0
  44. package/dist/runtime/components/renderers/ADashboardRenderer.vue.d.ts +19 -0
  45. package/dist/runtime/components/renderers/AGalleryCoverImage.d.vue.ts +8 -0
  46. package/dist/runtime/components/renderers/AGalleryCoverImage.vue +60 -0
  47. package/dist/runtime/components/renderers/AGalleryCoverImage.vue.d.ts +8 -0
  48. package/dist/runtime/components/renderers/AGalleryRenderer.d.vue.ts +12 -1
  49. package/dist/runtime/components/renderers/AGalleryRenderer.vue +221 -55
  50. package/dist/runtime/components/renderers/AGalleryRenderer.vue.d.ts +12 -1
  51. package/dist/runtime/components/renderers/AGraphRenderer.d.vue.ts +19 -0
  52. package/dist/runtime/components/renderers/AGraphRenderer.vue +1027 -0
  53. package/dist/runtime/components/renderers/AGraphRenderer.vue.d.ts +19 -0
  54. package/dist/runtime/components/renderers/AKanbanRenderer.d.vue.ts +13 -1
  55. package/dist/runtime/components/renderers/AKanbanRenderer.vue +474 -140
  56. package/dist/runtime/components/renderers/AKanbanRenderer.vue.d.ts +13 -1
  57. package/dist/runtime/components/renderers/AMapRenderer.d.vue.ts +19 -0
  58. package/dist/runtime/components/renderers/AMapRenderer.vue +1622 -0
  59. package/dist/runtime/components/renderers/AMapRenderer.vue.d.ts +19 -0
  60. package/dist/runtime/components/renderers/AOutlineRenderer.d.vue.ts +12 -1
  61. package/dist/runtime/components/renderers/AOutlineRenderer.vue +294 -134
  62. package/dist/runtime/components/renderers/AOutlineRenderer.vue.d.ts +12 -1
  63. package/dist/runtime/components/renderers/ATableRenderer.d.vue.ts +12 -1
  64. package/dist/runtime/components/renderers/ATableRenderer.vue +437 -145
  65. package/dist/runtime/components/renderers/ATableRenderer.vue.d.ts +12 -1
  66. package/dist/runtime/components/renderers/ATimelineRenderer.d.vue.ts +19 -0
  67. package/dist/runtime/components/renderers/ATimelineRenderer.vue +446 -0
  68. package/dist/runtime/components/renderers/ATimelineRenderer.vue.d.ts +19 -0
  69. package/dist/runtime/composables/useAwareness.js +5 -0
  70. package/dist/runtime/composables/useBroadcastSync.d.ts +18 -0
  71. package/dist/runtime/composables/useBroadcastSync.js +26 -0
  72. package/dist/runtime/composables/useChat.js +4 -2
  73. package/dist/runtime/composables/useChatUsers.js +2 -1
  74. package/dist/runtime/composables/useCommandPalette.js +62 -3
  75. package/dist/runtime/composables/useConnectionStatus.js +7 -0
  76. package/dist/runtime/composables/useDevicePairing.d.ts +58 -0
  77. package/dist/runtime/composables/useDevicePairing.js +108 -0
  78. package/dist/runtime/composables/useDocExport.d.ts +5 -0
  79. package/dist/runtime/composables/useDocExport.js +2 -2
  80. package/dist/runtime/composables/useDocImport.js +4 -3
  81. package/dist/runtime/composables/useDocSeo.d.ts +20 -0
  82. package/dist/runtime/composables/useDocSeo.js +44 -0
  83. package/dist/runtime/composables/useDocSlugs.d.ts +7 -0
  84. package/dist/runtime/composables/useDocSlugs.js +20 -0
  85. package/dist/runtime/composables/useDocTree.d.ts +34 -0
  86. package/dist/runtime/composables/useDocTree.js +35 -0
  87. package/dist/runtime/composables/useEditorDragHandle.js +2 -1
  88. package/dist/runtime/composables/useEditorMentions.js +4 -2
  89. package/dist/runtime/composables/useEditorSuggestions.d.ts +1 -0
  90. package/dist/runtime/composables/useEditorSuggestions.js +9 -2
  91. package/dist/runtime/composables/useEditorToolbar.js +2 -1
  92. package/dist/runtime/composables/useFileIndex.js +2 -1
  93. package/dist/runtime/composables/useFileTransfer.d.ts +112 -0
  94. package/dist/runtime/composables/useFileTransfer.js +171 -0
  95. package/dist/runtime/composables/useFollowUser.js +2 -1
  96. package/dist/runtime/composables/useInvites.d.ts +56 -0
  97. package/dist/runtime/composables/useInvites.js +77 -0
  98. package/dist/runtime/composables/useNodePanel.d.ts +14 -0
  99. package/dist/runtime/composables/useNodePanel.js +52 -0
  100. package/dist/runtime/composables/useNotifications.js +4 -2
  101. package/dist/runtime/composables/usePasskeyAccounts.js +4 -2
  102. package/dist/runtime/composables/useSearchIndex.d.ts +1 -0
  103. package/dist/runtime/composables/useSearchIndex.js +13 -5
  104. package/dist/runtime/composables/useServerInfo.d.ts +31 -0
  105. package/dist/runtime/composables/useServerInfo.js +80 -0
  106. package/dist/runtime/composables/useSlugRoute.d.ts +6 -0
  107. package/dist/runtime/composables/useSlugRoute.js +19 -0
  108. package/dist/runtime/composables/useSpaces.d.ts +37 -0
  109. package/dist/runtime/composables/useSpaces.js +83 -0
  110. package/dist/runtime/composables/useTouchDrag.d.ts +34 -0
  111. package/dist/runtime/composables/useTouchDrag.js +191 -0
  112. package/dist/runtime/composables/useTrash.d.ts +1 -1
  113. package/dist/runtime/composables/useTrash.js +6 -3
  114. package/dist/runtime/composables/useWebRTC.d.ts +50 -0
  115. package/dist/runtime/composables/useWebRTC.js +177 -0
  116. package/dist/runtime/extensions/meta-field.d.ts +4 -1
  117. package/dist/runtime/extensions/steps.js +1 -1
  118. package/dist/runtime/extensions/views/AccordionItemView.vue +13 -3
  119. package/dist/runtime/extensions/views/AccordionView.vue +4 -1
  120. package/dist/runtime/extensions/views/BadgeView.vue +11 -2
  121. package/dist/runtime/extensions/views/CalloutView.vue +4 -1
  122. package/dist/runtime/extensions/views/CardGroupView.vue +4 -1
  123. package/dist/runtime/extensions/views/CardView.vue +17 -3
  124. package/dist/runtime/extensions/views/CodeGroupView.vue +4 -1
  125. package/dist/runtime/extensions/views/CollapsibleView.vue +8 -2
  126. package/dist/runtime/extensions/views/FileNodeView.vue +32 -8
  127. package/dist/runtime/extensions/views/KbdView.vue +8 -2
  128. package/dist/runtime/extensions/views/MetaFieldView.vue +208 -46
  129. package/dist/runtime/extensions/views/ProseIconView.vue +8 -2
  130. package/dist/runtime/extensions/views/TabsView.vue +17 -4
  131. package/dist/runtime/locale.d.ts +71 -0
  132. package/dist/runtime/locale.js +71 -0
  133. package/dist/runtime/plugin-abracadabra.client.js +29 -3
  134. package/dist/runtime/plugin-abracadabra.server.js +2 -0
  135. package/dist/runtime/server/api/_abracadabra/render/[docId].get.d.ts +1 -1
  136. package/dist/runtime/server/api/_abracadabra/render/[docId].get.js +29 -4
  137. package/dist/runtime/server/api/_abracadabra/resolve/[...slug].get.d.ts +2 -0
  138. package/dist/runtime/server/api/_abracadabra/resolve/[...slug].get.js +43 -0
  139. package/dist/runtime/server/api/_abracadabra/slugs.get.d.ts +2 -0
  140. package/dist/runtime/server/api/_abracadabra/slugs.get.js +7 -0
  141. package/dist/runtime/server/plugins/abracadabra-service.js +10 -5
  142. package/dist/runtime/server/runners/doc-tree-cache.js +4 -0
  143. package/dist/runtime/server/utils/slugMap.d.ts +32 -0
  144. package/dist/runtime/server/utils/slugMap.js +58 -0
  145. package/dist/runtime/types.d.ts +1 -0
  146. package/dist/runtime/utils/docTypes.d.ts +29 -1
  147. package/dist/runtime/utils/docTypes.js +129 -1
  148. package/dist/runtime/utils/markdownToYjs.js +2 -2
  149. package/dist/runtime/utils/sdkRef.d.ts +2 -0
  150. package/dist/runtime/utils/sdkRef.js +7 -0
  151. package/dist/runtime/utils/slugify.d.ts +40 -0
  152. package/dist/runtime/utils/slugify.js +36 -0
  153. package/dist/types.d.mts +6 -0
  154. package/package.json +32 -19
@@ -16,7 +16,10 @@ defineProps({
16
16
  </script>
17
17
 
18
18
  <template>
19
- <NodeViewWrapper as="div" class="grid grid-cols-1 sm:grid-cols-2 gap-5 my-5 [&>*]:my-0">
19
+ <NodeViewWrapper
20
+ as="div"
21
+ class="grid grid-cols-1 sm:grid-cols-2 gap-5 my-5 [&>*]:my-0"
22
+ >
20
23
  <NodeViewContent />
21
24
  </NodeViewWrapper>
22
25
  </template>
@@ -18,9 +18,23 @@ const icon = computed(() => props.node.attrs.icon || "");
18
18
  </script>
19
19
 
20
20
  <template>
21
- <NodeViewWrapper as="div" class="group relative block my-5 p-4 sm:p-6 border border-(--ui-border) rounded-md bg-(--ui-bg) transition-colors">
22
- <UIcon v-if="icon" :name="icon" class="size-6 mb-2 block text-(--ui-text-highlighted)" contenteditable="false" />
23
- <p v-if="title" class="text-(--ui-text-highlighted) font-semibold" contenteditable="false">{{ title }}</p>
21
+ <NodeViewWrapper
22
+ as="div"
23
+ class="group relative block my-5 p-4 sm:p-6 border border-(--ui-border) rounded-md bg-(--ui-bg) transition-colors"
24
+ >
25
+ <UIcon
26
+ v-if="icon"
27
+ :name="icon"
28
+ class="size-6 mb-2 block text-(--ui-text-highlighted)"
29
+ contenteditable="false"
30
+ />
31
+ <p
32
+ v-if="title"
33
+ class="text-(--ui-text-highlighted) font-semibold"
34
+ contenteditable="false"
35
+ >
36
+ {{ title }}
37
+ </p>
24
38
  <div :class="['text-[15px] text-(--ui-text-muted) [&>*:first-child]:mt-0 [&>*:last-child]:mb-0 [&>*]:my-1', title ? 'mt-1' : '']">
25
39
  <NodeViewContent />
26
40
  </div>
@@ -30,7 +30,10 @@ watch(() => props.node.childCount, () => {
30
30
  </script>
31
31
 
32
32
  <template>
33
- <NodeViewWrapper as="div" class="relative my-5 [&>*:not(:first-child)]:!my-0 [&>*:not(:first-child)]:!static">
33
+ <NodeViewWrapper
34
+ as="div"
35
+ class="relative my-5 [&>*:not(:first-child)]:!my-0 [&>*:not(:first-child)]:!static"
36
+ >
34
37
  <div
35
38
  class="relative flex items-center gap-1 border border-(--ui-border-muted) bg-(--ui-bg) border-b-0 rounded-t-md overflow-x-auto p-2"
36
39
  contenteditable="false"
@@ -22,7 +22,10 @@ const label = computed(() => props.node.attrs.label || "Details");
22
22
  </script>
23
23
 
24
24
  <template>
25
- <NodeViewWrapper as="div" class="my-5">
25
+ <NodeViewWrapper
26
+ as="div"
27
+ class="my-5"
28
+ >
26
29
  <button
27
30
  contenteditable="false"
28
31
  class="group relative rounded-xs inline-flex items-center gap-1.5 text-(--ui-text-muted) hover:text-(--ui-text) text-sm transition-colors focus-visible:ring-2 focus-visible:ring-(--ui-primary) focus:outline-none"
@@ -35,7 +38,10 @@ const label = computed(() => props.node.attrs.label || "Details");
35
38
  />
36
39
  <span class="truncate">{{ open ? "Hide" : "Show" }} {{ label }}</span>
37
40
  </button>
38
- <div v-show="open" class="[&>*:first-child]:mt-2.5 [&>*:last-child]:mb-0 [&>*]:my-1.5">
41
+ <div
42
+ v-show="open"
43
+ class="[&>*:first-child]:mt-2.5 [&>*:last-child]:mb-0 [&>*]:my-1.5"
44
+ >
39
45
  <NodeViewContent />
40
46
  </div>
41
47
  </NodeViewWrapper>
@@ -69,13 +69,25 @@ watch(client, (c) => {
69
69
  <NodeViewWrapper class="my-2">
70
70
  <div class="rounded-lg overflow-hidden border border-(--ui-border) bg-(--ui-bg-elevated)">
71
71
  <!-- Loading -->
72
- <div v-if="loading" class="flex items-center justify-center h-20">
73
- <UIcon name="i-lucide-loader-circle" class="animate-spin text-xl text-(--ui-text-muted)" />
72
+ <div
73
+ v-if="loading"
74
+ class="flex items-center justify-center h-20"
75
+ >
76
+ <UIcon
77
+ name="i-lucide-loader-circle"
78
+ class="animate-spin text-xl text-(--ui-text-muted)"
79
+ />
74
80
  </div>
75
81
 
76
82
  <!-- Error -->
77
- <div v-else-if="error" class="flex items-center gap-3 px-4 py-3">
78
- <UIcon name="i-lucide-alert-circle" class="text-error shrink-0" />
83
+ <div
84
+ v-else-if="error"
85
+ class="flex items-center gap-3 px-4 py-3"
86
+ >
87
+ <UIcon
88
+ name="i-lucide-alert-circle"
89
+ class="text-error shrink-0"
90
+ />
79
91
  <div class="min-w-0">
80
92
  <p class="text-sm font-medium text-(--ui-text) truncate">
81
93
  {{ filename }}
@@ -105,8 +117,14 @@ watch(client, (c) => {
105
117
  />
106
118
 
107
119
  <!-- Audio -->
108
- <div v-else-if="fileCategory === 'audio'" class="flex items-center gap-3 p-4">
109
- <UIcon name="i-lucide-music-2" class="text-(--ui-primary) text-2xl shrink-0" />
120
+ <div
121
+ v-else-if="fileCategory === 'audio'"
122
+ class="flex items-center gap-3 p-4"
123
+ >
124
+ <UIcon
125
+ name="i-lucide-music-2"
126
+ class="text-(--ui-primary) text-2xl shrink-0"
127
+ />
110
128
  <div class="flex-1 min-w-0">
111
129
  <p class="text-sm font-medium text-(--ui-text) truncate mb-1.5">
112
130
  {{ filename }}
@@ -128,12 +146,18 @@ watch(client, (c) => {
128
146
  class="flex items-center gap-3 p-4 hover:bg-(--ui-bg-accented) transition-colors no-underline"
129
147
  @click.stop
130
148
  >
131
- <UIcon :name="fileIcon" class="text-2xl text-(--ui-text-muted) shrink-0" />
149
+ <UIcon
150
+ :name="fileIcon"
151
+ class="text-2xl text-(--ui-text-muted) shrink-0"
152
+ />
132
153
  <div class="flex-1 min-w-0">
133
154
  <p class="text-sm font-medium text-(--ui-text) truncate">{{ filename }}</p>
134
155
  <p class="text-xs text-(--ui-text-muted)">Click to download</p>
135
156
  </div>
136
- <UIcon name="i-lucide-download" class="text-(--ui-text-muted) shrink-0" />
157
+ <UIcon
158
+ name="i-lucide-download"
159
+ class="text-(--ui-text-muted) shrink-0"
160
+ />
137
161
  </a>
138
162
  </div>
139
163
  </NodeViewWrapper>
@@ -17,7 +17,13 @@ const value = computed(() => props.node.attrs.value || "");
17
17
  </script>
18
18
 
19
19
  <template>
20
- <NodeViewWrapper as="span" class="inline">
21
- <UKbd :value="value" class="align-text-top" />
20
+ <NodeViewWrapper
21
+ as="span"
22
+ class="inline"
23
+ >
24
+ <UKbd
25
+ :value="value"
26
+ class="align-text-top"
27
+ />
22
28
  </NodeViewWrapper>
23
29
  </template>
@@ -55,7 +55,10 @@ function getBool(key) {
55
55
  return Boolean(storage()?.pageMeta?.[key]);
56
56
  }
57
57
  function patch(update) {
58
- storage()?.updateMeta?.(update);
58
+ const s = storage();
59
+ if (!s) return;
60
+ if (s.pageMeta) Object.assign(s.pageMeta, update);
61
+ s.updateMeta?.(update);
59
62
  }
60
63
  const labelDraft = ref("");
61
64
  function commitLabel() {
@@ -175,9 +178,15 @@ function commitText() {
175
178
  </script>
176
179
 
177
180
  <template>
178
- <NodeViewWrapper as="span" class="inline-flex items-center">
181
+ <NodeViewWrapper
182
+ as="span"
183
+ class="inline-flex items-center"
184
+ >
179
185
  <!-- ── Chip wrapper ─────────────────────────────────────────────────────── -->
180
- <UPopover v-model:open="popoverOpen" :content="{ side: 'bottom', align: 'start' }">
186
+ <UPopover
187
+ v-model:open="popoverOpen"
188
+ :content="{ side: 'bottom', align: 'start' }"
189
+ >
181
190
  <button
182
191
  type="button"
183
192
  class="inline-flex items-center gap-1 rounded-md border border-default bg-muted px-2 py-0.5 text-xs font-medium text-default hover:bg-elevated cursor-pointer select-none mx-0.5"
@@ -197,10 +206,16 @@ function commitText() {
197
206
  <span class="text-default">
198
207
  <!-- Toggle shows a switch icon -->
199
208
  <span v-if="fieldType === 'toggle'">
200
- <UIcon :name="getBool(metaKey) ? 'i-lucide-toggle-right' : 'i-lucide-toggle-left'" class="size-3.5 align-middle" />
209
+ <UIcon
210
+ :name="getBool(metaKey) ? 'i-lucide-toggle-right' : 'i-lucide-toggle-left'"
211
+ class="size-3.5 align-middle"
212
+ />
201
213
  </span>
202
214
  <!-- Rating shows stars -->
203
- <span v-else-if="fieldType === 'rating'" class="flex gap-0.5">
215
+ <span
216
+ v-else-if="fieldType === 'rating'"
217
+ class="flex gap-0.5"
218
+ >
204
219
  <UIcon
205
220
  v-for="i in sliderMax"
206
221
  :key="i"
@@ -235,11 +250,14 @@ function commitText() {
235
250
  class="flex-1 text-xs font-medium bg-transparent border-none outline-none"
236
251
  @blur="commitLabel"
237
252
  @keydown.enter.prevent="commitLabel"
238
- />
253
+ >
239
254
  </div>
240
255
 
241
256
  <!-- ── Toggle ──────────────────────────────────────────────────── -->
242
- <div v-if="fieldType === 'toggle'" class="flex items-center justify-between">
257
+ <div
258
+ v-if="fieldType === 'toggle'"
259
+ class="flex items-center justify-between"
260
+ >
243
261
  <span class="text-xs text-muted">{{ getBool(metaKey) ? "On" : "Off" }}</span>
244
262
  <USwitch
245
263
  :model-value="getBool(metaKey)"
@@ -248,7 +266,10 @@ function commitText() {
248
266
  </div>
249
267
 
250
268
  <!-- ── Color presets ───────────────────────────────────────────── -->
251
- <div v-else-if="fieldType === 'colorPreset'" class="flex flex-wrap gap-1.5">
269
+ <div
270
+ v-else-if="fieldType === 'colorPreset'"
271
+ class="flex flex-wrap gap-1.5"
272
+ >
252
273
  <button
253
274
  v-for="c in allPresets"
254
275
  :key="c"
@@ -263,18 +284,24 @@ function commitText() {
263
284
  class="size-5 rounded-full border border-default flex items-center justify-center text-muted hover:bg-muted"
264
285
  @click="patch({ [metaKey]: '' })"
265
286
  >
266
- <UIcon name="i-lucide-x" class="size-3" />
287
+ <UIcon
288
+ name="i-lucide-x"
289
+ class="size-3"
290
+ />
267
291
  </button>
268
292
  </div>
269
293
 
270
294
  <!-- ── Color picker ────────────────────────────────────────────── -->
271
- <div v-else-if="fieldType === 'colorPicker'" class="space-y-1">
295
+ <div
296
+ v-else-if="fieldType === 'colorPicker'"
297
+ class="space-y-1"
298
+ >
272
299
  <input
273
300
  type="color"
274
301
  :value="getStr(metaKey) || '#6366f1'"
275
302
  class="w-full h-8 rounded cursor-pointer"
276
303
  @input="(e) => patch({ [metaKey]: e.target.value })"
277
- />
304
+ >
278
305
  <UButton
279
306
  v-if="getStr(metaKey)"
280
307
  icon="i-lucide-x"
@@ -294,7 +321,7 @@ function commitText() {
294
321
  :value="getStr(metaKey)"
295
322
  class="w-full text-xs rounded border border-default bg-transparent px-2 py-1 outline-none"
296
323
  @change="(e) => patch({ [metaKey]: e.target.value })"
297
- />
324
+ >
298
325
  </div>
299
326
 
300
327
  <!-- ── Datetime ───────────────────────────────────────────────── -->
@@ -304,32 +331,85 @@ function commitText() {
304
331
  :value="getStr(metaKey)"
305
332
  class="w-full text-xs rounded border border-default bg-transparent px-2 py-1 outline-none"
306
333
  @change="(e) => patch({ [metaKey]: e.target.value })"
307
- />
334
+ >
308
335
  </div>
309
336
 
310
337
  <!-- ── Date range ─────────────────────────────────────────────── -->
311
- <div v-else-if="fieldType === 'daterange'" class="space-y-1">
312
- <div class="flex items-center gap-1 text-xs text-muted"><span class="w-8">Start</span><input type="date" :value="getStr(startKey)" class="flex-1 text-xs rounded border border-default bg-transparent px-2 py-1 outline-none" @change="(e) => patch({ [startKey]: e.target.value })" /></div>
313
- <div class="flex items-center gap-1 text-xs text-muted"><span class="w-8">End</span><input type="date" :value="getStr(endKey)" class="flex-1 text-xs rounded border border-default bg-transparent px-2 py-1 outline-none" @change="(e) => patch({ [endKey]: e.target.value })" /></div>
338
+ <div
339
+ v-else-if="fieldType === 'daterange'"
340
+ class="space-y-1"
341
+ >
342
+ <div class="flex items-center gap-1 text-xs text-muted">
343
+ <span class="w-8">Start</span><input
344
+ type="date"
345
+ :value="getStr(startKey)"
346
+ class="flex-1 text-xs rounded border border-default bg-transparent px-2 py-1 outline-none"
347
+ @change="(e) => patch({ [startKey]: e.target.value })"
348
+ >
349
+ </div>
350
+ <div class="flex items-center gap-1 text-xs text-muted">
351
+ <span class="w-8">End</span><input
352
+ type="date"
353
+ :value="getStr(endKey)"
354
+ class="flex-1 text-xs rounded border border-default bg-transparent px-2 py-1 outline-none"
355
+ @change="(e) => patch({ [endKey]: e.target.value })"
356
+ >
357
+ </div>
314
358
  </div>
315
359
 
316
360
  <!-- ── Datetime range ─────────────────────────────────────────── -->
317
- <div v-else-if="fieldType === 'datetimerange'" class="space-y-1">
318
- <div class="flex items-center gap-1 text-xs text-muted"><span class="w-8">Start</span><input type="datetime-local" :value="getStr(startKey)" class="flex-1 text-xs rounded border border-default bg-transparent px-2 py-1 outline-none" @change="(e) => patch({ [startKey]: e.target.value })" /></div>
319
- <div class="flex items-center gap-1 text-xs text-muted"><span class="w-8">End</span><input type="datetime-local" :value="getStr(endKey)" class="flex-1 text-xs rounded border border-default bg-transparent px-2 py-1 outline-none" @change="(e) => patch({ [endKey]: e.target.value })" /></div>
320
- <div class="flex items-center gap-2 text-xs"><USwitch :model-value="getBool(allDayKey)" @update:model-value="(v) => patch({ [allDayKey]: v })" /><span class="text-muted">All day</span></div>
361
+ <div
362
+ v-else-if="fieldType === 'datetimerange'"
363
+ class="space-y-1"
364
+ >
365
+ <div class="flex items-center gap-1 text-xs text-muted">
366
+ <span class="w-8">Start</span><input
367
+ type="datetime-local"
368
+ :value="getStr(startKey)"
369
+ class="flex-1 text-xs rounded border border-default bg-transparent px-2 py-1 outline-none"
370
+ @change="(e) => patch({ [startKey]: e.target.value })"
371
+ >
372
+ </div>
373
+ <div class="flex items-center gap-1 text-xs text-muted">
374
+ <span class="w-8">End</span><input
375
+ type="datetime-local"
376
+ :value="getStr(endKey)"
377
+ class="flex-1 text-xs rounded border border-default bg-transparent px-2 py-1 outline-none"
378
+ @change="(e) => patch({ [endKey]: e.target.value })"
379
+ >
380
+ </div>
381
+ <div class="flex items-center gap-2 text-xs">
382
+ <USwitch
383
+ :model-value="getBool(allDayKey)"
384
+ @update:model-value="(v) => patch({ [allDayKey]: v })"
385
+ /><span class="text-muted">All day</span>
386
+ </div>
321
387
  </div>
322
388
 
323
389
  <!-- ── Time ───────────────────────────────────────────────────── -->
324
390
  <div v-else-if="fieldType === 'time' || fieldType === 'timerange'">
325
391
  <div class="space-y-1">
326
- <input type="time" :value="fieldType === 'time' ? getStr(metaKey) : getStr(startKey)" class="w-full text-xs rounded border border-default bg-transparent px-2 py-1 outline-none" @change="(e) => patch({ [fieldType === 'time' ? metaKey : startKey]: e.target.value })" />
327
- <input v-if="fieldType === 'timerange'" type="time" :value="getStr(endKey)" class="w-full text-xs rounded border border-default bg-transparent px-2 py-1 outline-none" @change="(e) => patch({ [endKey]: e.target.value })" />
392
+ <input
393
+ type="time"
394
+ :value="fieldType === 'time' ? getStr(metaKey) : getStr(startKey)"
395
+ class="w-full text-xs rounded border border-default bg-transparent px-2 py-1 outline-none"
396
+ @change="(e) => patch({ [fieldType === 'time' ? metaKey : startKey]: e.target.value })"
397
+ >
398
+ <input
399
+ v-if="fieldType === 'timerange'"
400
+ type="time"
401
+ :value="getStr(endKey)"
402
+ class="w-full text-xs rounded border border-default bg-transparent px-2 py-1 outline-none"
403
+ @change="(e) => patch({ [endKey]: e.target.value })"
404
+ >
328
405
  </div>
329
406
  </div>
330
407
 
331
408
  <!-- ── Slider ─────────────────────────────────────────────────── -->
332
- <div v-else-if="fieldType === 'slider'" class="space-y-1">
409
+ <div
410
+ v-else-if="fieldType === 'slider'"
411
+ class="space-y-1"
412
+ >
333
413
  <div class="flex items-center gap-2">
334
414
  <USlider
335
415
  :model-value="getNum(metaKey, sliderMin)"
@@ -347,7 +427,10 @@ function commitText() {
347
427
  </div>
348
428
 
349
429
  <!-- ── Number ─────────────────────────────────────────────────── -->
350
- <div v-else-if="fieldType === 'number'" class="flex items-center gap-2">
430
+ <div
431
+ v-else-if="fieldType === 'number'"
432
+ class="flex items-center gap-2"
433
+ >
351
434
  <UInputNumber
352
435
  :model-value="getNum(metaKey)"
353
436
  :min="sliderMin"
@@ -357,11 +440,17 @@ function commitText() {
357
440
  size="xs"
358
441
  @update:model-value="(v) => patch({ [metaKey]: v })"
359
442
  />
360
- <span v-if="unit" class="text-xs text-muted">{{ unit }}</span>
443
+ <span
444
+ v-if="unit"
445
+ class="text-xs text-muted"
446
+ >{{ unit }}</span>
361
447
  </div>
362
448
 
363
449
  <!-- ── Rating ─────────────────────────────────────────────────── -->
364
- <div v-else-if="fieldType === 'rating'" class="flex gap-1">
450
+ <div
451
+ v-else-if="fieldType === 'rating'"
452
+ class="flex gap-1"
453
+ >
365
454
  <button
366
455
  v-for="i in sliderMax"
367
456
  :key="i"
@@ -377,7 +466,10 @@ function commitText() {
377
466
  </div>
378
467
 
379
468
  <!-- ── Select ─────────────────────────────────────────────────── -->
380
- <div v-else-if="fieldType === 'select'" class="space-y-1">
469
+ <div
470
+ v-else-if="fieldType === 'select'"
471
+ class="space-y-1"
472
+ >
381
473
  <button
382
474
  v-for="opt in options"
383
475
  :key="opt"
@@ -385,14 +477,26 @@ function commitText() {
385
477
  :class="getStr(metaKey) === opt ? 'bg-primary/10 text-primary' : ''"
386
478
  @click="toggleSelect(opt)"
387
479
  >
388
- <UIcon v-if="getStr(metaKey) === opt" name="i-lucide-check" class="size-3" />
480
+ <UIcon
481
+ v-if="getStr(metaKey) === opt"
482
+ name="i-lucide-check"
483
+ class="size-3"
484
+ />
389
485
  <span :class="getStr(metaKey) === opt ? '' : 'ml-5'">{{ opt }}</span>
390
486
  </button>
391
- <div v-if="!options.length" class="text-xs text-muted px-2">No options yet</div>
487
+ <div
488
+ v-if="!options.length"
489
+ class="text-xs text-muted px-2"
490
+ >
491
+ No options yet
492
+ </div>
392
493
  </div>
393
494
 
394
495
  <!-- ── Multi select ───────────────────────────────────────────── -->
395
- <div v-else-if="fieldType === 'multiselect'" class="space-y-1">
496
+ <div
497
+ v-else-if="fieldType === 'multiselect'"
498
+ class="space-y-1"
499
+ >
396
500
  <button
397
501
  v-for="opt in options"
398
502
  :key="opt"
@@ -400,14 +504,25 @@ function commitText() {
400
504
  :class="getStrArr(metaKey).includes(opt) ? 'bg-primary/10 text-primary' : ''"
401
505
  @click="toggleMultiSelect(opt)"
402
506
  >
403
- <UIcon :name="getStrArr(metaKey).includes(opt) ? 'i-lucide-check-square' : 'i-lucide-square'" class="size-3" />
507
+ <UIcon
508
+ :name="getStrArr(metaKey).includes(opt) ? 'i-lucide-check-square' : 'i-lucide-square'"
509
+ class="size-3"
510
+ />
404
511
  {{ opt }}
405
512
  </button>
406
- <div v-if="!options.length" class="text-xs text-muted px-2">No options yet</div>
513
+ <div
514
+ v-if="!options.length"
515
+ class="text-xs text-muted px-2"
516
+ >
517
+ No options yet
518
+ </div>
407
519
  </div>
408
520
 
409
521
  <!-- ── Tags ───────────────────────────────────────────────────── -->
410
- <div v-else-if="fieldType === 'tags'" class="space-y-2">
522
+ <div
523
+ v-else-if="fieldType === 'tags'"
524
+ class="space-y-2"
525
+ >
411
526
  <div class="flex flex-wrap gap-1">
412
527
  <span
413
528
  v-for="tag in getStrArr(metaKey)"
@@ -415,27 +530,43 @@ function commitText() {
415
530
  class="inline-flex items-center gap-0.5 rounded-full bg-primary/10 text-primary px-2 py-0.5 text-xs"
416
531
  >
417
532
  {{ tag }}
418
- <button @click="toggleTag(tag)"><UIcon name="i-lucide-x" class="size-3" /></button>
533
+ <button @click="toggleTag(tag)"><UIcon
534
+ name="i-lucide-x"
535
+ class="size-3"
536
+ /></button>
419
537
  </span>
420
538
  </div>
421
539
  <div class="flex gap-1">
422
- <UInput v-model="newOption" size="xs" placeholder="Add tag…" class="flex-1" @keydown.enter.prevent="() => {
540
+ <UInput
541
+ v-model="newOption"
542
+ size="xs"
543
+ placeholder="Add tag…"
544
+ class="flex-1"
545
+ @keydown.enter.prevent="() => {
423
546
  if (newOption.trim()) {
424
547
  toggleTag(newOption.trim());
425
548
  newOption = '';
426
549
  }
427
- }" />
428
- <UButton size="xs" icon="i-lucide-plus" @click="() => {
550
+ }"
551
+ />
552
+ <UButton
553
+ size="xs"
554
+ icon="i-lucide-plus"
555
+ @click="() => {
429
556
  if (newOption.trim()) {
430
557
  toggleTag(newOption.trim());
431
558
  newOption = '';
432
559
  }
433
- }" />
560
+ }"
561
+ />
434
562
  </div>
435
563
  </div>
436
564
 
437
565
  <!-- ── URL ────────────────────────────────────────────────────── -->
438
- <div v-else-if="fieldType === 'url'" class="space-y-1">
566
+ <div
567
+ v-else-if="fieldType === 'url'"
568
+ class="space-y-1"
569
+ >
439
570
  <UInput
440
571
  :model-value="getStr(metaKey)"
441
572
  size="xs"
@@ -443,8 +574,16 @@ function commitText() {
443
574
  leading-icon="i-lucide-link"
444
575
  @update:model-value="(v) => patch({ [metaKey]: v })"
445
576
  />
446
- <a v-if="getStr(metaKey)" :href="getStr(metaKey)" target="_blank" class="text-xs text-primary hover:underline flex items-center gap-1">
447
- <UIcon name="i-lucide-external-link" class="size-3" />
577
+ <a
578
+ v-if="getStr(metaKey)"
579
+ :href="getStr(metaKey)"
580
+ target="_blank"
581
+ class="text-xs text-primary hover:underline flex items-center gap-1"
582
+ >
583
+ <UIcon
584
+ name="i-lucide-external-link"
585
+ class="size-3"
586
+ />
448
587
  Open
449
588
  </a>
450
589
  </div>
@@ -461,19 +600,37 @@ function commitText() {
461
600
  </div>
462
601
 
463
602
  <!-- ── Location ───────────────────────────────────────────────── -->
464
- <div v-else-if="fieldType === 'location'" class="space-y-1">
603
+ <div
604
+ v-else-if="fieldType === 'location'"
605
+ class="space-y-1"
606
+ >
465
607
  <div class="flex items-center gap-1">
466
608
  <span class="text-xs text-muted w-7">Lat</span>
467
- <UInputNumber :model-value="getNum(props.node.attrs.latKey)" size="xs" class="flex-1" :step="1e-4" @update:model-value="(v) => patch({ [props.node.attrs.latKey]: v })" />
609
+ <UInputNumber
610
+ :model-value="getNum(props.node.attrs.latKey)"
611
+ size="xs"
612
+ class="flex-1"
613
+ :step="1e-4"
614
+ @update:model-value="(v) => patch({ [props.node.attrs.latKey]: v })"
615
+ />
468
616
  </div>
469
617
  <div class="flex items-center gap-1">
470
618
  <span class="text-xs text-muted w-7">Lng</span>
471
- <UInputNumber :model-value="getNum(props.node.attrs.lngKey)" size="xs" class="flex-1" :step="1e-4" @update:model-value="(v) => patch({ [props.node.attrs.lngKey]: v })" />
619
+ <UInputNumber
620
+ :model-value="getNum(props.node.attrs.lngKey)"
621
+ size="xs"
622
+ class="flex-1"
623
+ :step="1e-4"
624
+ @update:model-value="(v) => patch({ [props.node.attrs.lngKey]: v })"
625
+ />
472
626
  </div>
473
627
  </div>
474
628
 
475
629
  <!-- ── Icon ───────────────────────────────────────────────────── -->
476
- <div v-else-if="fieldType === 'icon'" class="space-y-1">
630
+ <div
631
+ v-else-if="fieldType === 'icon'"
632
+ class="space-y-1"
633
+ >
477
634
  <AIconPicker
478
635
  :model-value="getStr(metaKey)"
479
636
  @update:model-value="(v) => patch({ [metaKey]: v })"
@@ -481,7 +638,12 @@ function commitText() {
481
638
  </div>
482
639
 
483
640
  <!-- Fallback -->
484
- <div v-else class="text-xs text-muted">{{ fieldType }}</div>
641
+ <div
642
+ v-else
643
+ class="text-xs text-muted"
644
+ >
645
+ {{ fieldType }}
646
+ </div>
485
647
  </div>
486
648
  </template>
487
649
  </UPopover>
@@ -17,7 +17,13 @@ const iconName = computed(() => props.node.attrs.name || "i-lucide-star");
17
17
  </script>
18
18
 
19
19
  <template>
20
- <NodeViewWrapper as="span" class="inline">
21
- <UIcon :name="iconName" class="size-4 shrink-0 align-sub" />
20
+ <NodeViewWrapper
21
+ as="span"
22
+ class="inline"
23
+ >
24
+ <UIcon
25
+ :name="iconName"
26
+ class="size-4 shrink-0 align-sub"
27
+ />
22
28
  </NodeViewWrapper>
23
29
  </template>
@@ -32,8 +32,14 @@ watch(() => props.node.childCount, () => {
32
32
  </script>
33
33
 
34
34
  <template>
35
- <NodeViewWrapper as="div" class="my-5">
36
- <div class="relative flex items-center border-b border-(--ui-border)" contenteditable="false">
35
+ <NodeViewWrapper
36
+ as="div"
37
+ class="my-5"
38
+ >
39
+ <div
40
+ class="relative flex items-center border-b border-(--ui-border)"
41
+ contenteditable="false"
42
+ >
37
43
  <button
38
44
  v-for="(tab, i) in tabs"
39
45
  :key="i"
@@ -41,9 +47,16 @@ watch(() => props.node.childCount, () => {
41
47
  :class="activeIndex === i ? 'text-(--ui-primary)' : 'text-(--ui-text-muted) hover:text-(--ui-text)'"
42
48
  @click="activeIndex = i"
43
49
  >
44
- <UIcon v-if="tab.icon" :name="tab.icon" class="size-4 shrink-0 me-1.5 inline-block align-text-bottom" />
50
+ <UIcon
51
+ v-if="tab.icon"
52
+ :name="tab.icon"
53
+ class="size-4 shrink-0 me-1.5 inline-block align-text-bottom"
54
+ />
45
55
  <span>{{ tab.label }}</span>
46
- <span v-if="activeIndex === i" class="absolute bottom-0 inset-x-0 h-0.5 bg-(--ui-primary) rounded-full" />
56
+ <span
57
+ v-if="activeIndex === i"
58
+ class="absolute bottom-0 inset-x-0 h-0.5 bg-(--ui-primary) rounded-full"
59
+ />
47
60
  </button>
48
61
  </div>
49
62
  <div class="mt-4">