@abraca/nuxt 2.10.0 → 2.13.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.d.mts +14 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +9 -0
- package/dist/runtime/assets/editor.css +1 -1
- package/dist/runtime/components/AConnectionBadge.d.vue.ts +29 -0
- package/dist/runtime/components/AConnectionBadge.vue +79 -0
- package/dist/runtime/components/AConnectionBadge.vue.d.ts +29 -0
- package/dist/runtime/components/ADocPickerModal.d.vue.ts +31 -0
- package/dist/runtime/components/ADocPickerModal.vue +191 -0
- package/dist/runtime/components/ADocPickerModal.vue.d.ts +31 -0
- package/dist/runtime/components/ADocumentTree.vue +65 -0
- package/dist/runtime/components/AEditor.d.vue.ts +19 -12
- package/dist/runtime/components/AEditor.vue +243 -165
- package/dist/runtime/components/AEditor.vue.d.ts +19 -12
- package/dist/runtime/components/AEncryptionModePicker.d.vue.ts +33 -0
- package/dist/runtime/components/AEncryptionModePicker.vue +211 -0
- package/dist/runtime/components/AEncryptionModePicker.vue.d.ts +33 -0
- package/dist/runtime/components/AModalShell.d.vue.ts +48 -0
- package/dist/runtime/components/AModalShell.vue +105 -0
- package/dist/runtime/components/AModalShell.vue.d.ts +48 -0
- package/dist/runtime/components/ANodePanel.d.vue.ts +17 -7
- package/dist/runtime/components/ANodePanel.vue +550 -451
- package/dist/runtime/components/ANodePanel.vue.d.ts +17 -7
- package/dist/runtime/components/ANodePanelHeader.d.vue.ts +20 -10
- package/dist/runtime/components/ANodePanelHeader.vue +17 -3
- package/dist/runtime/components/ANodePanelHeader.vue.d.ts +20 -10
- package/dist/runtime/components/ANodeSettingsPanel.d.vue.ts +2 -0
- package/dist/runtime/components/ANodeSettingsPanel.vue +21 -1
- package/dist/runtime/components/ANodeSettingsPanel.vue.d.ts +2 -0
- package/dist/runtime/components/ASnapshotPreviewModal.d.vue.ts +33 -0
- package/dist/runtime/components/ASnapshotPreviewModal.vue +430 -0
- package/dist/runtime/components/ASnapshotPreviewModal.vue.d.ts +33 -0
- package/dist/runtime/components/ATagsEditor.d.vue.ts +19 -0
- package/dist/runtime/components/ATagsEditor.vue +60 -0
- package/dist/runtime/components/ATagsEditor.vue.d.ts +19 -0
- package/dist/runtime/components/aware/AMedia.d.vue.ts +1 -1
- package/dist/runtime/components/aware/AMedia.vue.d.ts +1 -1
- package/dist/runtime/components/chat/AChatInput.d.vue.ts +11 -6
- package/dist/runtime/components/chat/AChatInput.vue +33 -2
- package/dist/runtime/components/chat/AChatInput.vue.d.ts +11 -6
- package/dist/runtime/components/chat/AChatList.d.vue.ts +12 -0
- package/dist/runtime/components/chat/AChatList.vue +76 -32
- package/dist/runtime/components/chat/AChatList.vue.d.ts +12 -0
- package/dist/runtime/components/chat/AChatMessages.d.vue.ts +4 -0
- package/dist/runtime/components/chat/AChatMessages.vue +57 -4
- package/dist/runtime/components/chat/AChatMessages.vue.d.ts +4 -0
- package/dist/runtime/components/chat/AChatPanel.d.vue.ts +6 -2
- package/dist/runtime/components/chat/AChatPanel.vue +17 -1
- package/dist/runtime/components/chat/AChatPanel.vue.d.ts +6 -2
- package/dist/runtime/components/chat/ANodeChatPanel.vue +1 -1
- package/dist/runtime/components/docs/ADocsSearch.d.vue.ts +1 -1
- package/dist/runtime/components/docs/ADocsSearch.vue.d.ts +1 -1
- package/dist/runtime/components/editor/ALocationPickerPopover.vue +28 -7
- package/dist/runtime/components/registry/APluginDetail.d.vue.ts +2 -2
- package/dist/runtime/components/registry/APluginDetail.vue.d.ts +2 -2
- package/dist/runtime/components/renderers/AChartRenderer.client.d.vue.ts +17 -0
- package/dist/runtime/components/renderers/AChartRenderer.client.vue +622 -0
- package/dist/runtime/components/renderers/AChartRenderer.client.vue.d.ts +17 -0
- package/dist/runtime/components/renderers/AGraphRenderer.vue +64 -15
- package/dist/runtime/components/renderers/AProseRenderer.d.vue.ts +2 -2
- package/dist/runtime/components/renderers/AProseRenderer.vue.d.ts +2 -2
- package/dist/runtime/components/renderers/calendar/ACalendarToolbar.d.vue.ts +2 -2
- package/dist/runtime/components/renderers/calendar/ACalendarToolbar.vue.d.ts +2 -2
- package/dist/runtime/components/renderers/media/MediaTransportBar.d.vue.ts +2 -2
- package/dist/runtime/components/renderers/media/MediaTransportBar.vue.d.ts +2 -2
- package/dist/runtime/components/renderers/sheets/ASheetsGrid.d.vue.ts +2 -2
- package/dist/runtime/components/renderers/sheets/ASheetsGrid.vue.d.ts +2 -2
- package/dist/runtime/components/settings/ASettingsAppearancePanel.d.vue.ts +3 -0
- package/dist/runtime/components/settings/ASettingsAppearancePanel.vue +67 -0
- package/dist/runtime/components/settings/ASettingsAppearancePanel.vue.d.ts +3 -0
- package/dist/runtime/components/settings/ASettingsGroup.d.vue.ts +24 -0
- package/dist/runtime/components/settings/ASettingsGroup.vue +31 -0
- package/dist/runtime/components/settings/ASettingsGroup.vue.d.ts +24 -0
- package/dist/runtime/components/settings/ASettingsModal.vue +84 -53
- package/dist/runtime/components/settings/ASettingsPlaceholder.d.vue.ts +20 -0
- package/dist/runtime/components/settings/ASettingsPlaceholder.vue +32 -0
- package/dist/runtime/components/settings/ASettingsPlaceholder.vue.d.ts +20 -0
- package/dist/runtime/components/settings/ASettingsRow.d.vue.ts +34 -0
- package/dist/runtime/components/settings/ASettingsRow.vue +34 -0
- package/dist/runtime/components/settings/ASettingsRow.vue.d.ts +34 -0
- package/dist/runtime/components/settings/sections.d.ts +37 -0
- package/dist/runtime/components/settings/sections.js +45 -0
- package/dist/runtime/components/shell/ABreadcrumbForDoc.d.vue.ts +6 -0
- package/dist/runtime/components/shell/ABreadcrumbForDoc.vue +75 -3
- package/dist/runtime/components/shell/ABreadcrumbForDoc.vue.d.ts +6 -0
- package/dist/runtime/components/shell/ADocPanelServerSettings.d.vue.ts +17 -0
- package/dist/runtime/components/shell/ADocPanelServerSettings.vue +253 -0
- package/dist/runtime/components/shell/ADocPanelServerSettings.vue.d.ts +17 -0
- package/dist/runtime/components/shell/ADocPanelSettings.d.vue.ts +2 -0
- package/dist/runtime/components/shell/ADocPanelSettings.vue +15 -4
- package/dist/runtime/components/shell/ADocPanelSettings.vue.d.ts +2 -0
- package/dist/runtime/components/shell/AUserProfilePopover.d.vue.ts +1 -1
- package/dist/runtime/components/shell/AUserProfilePopover.vue.d.ts +1 -1
- package/dist/runtime/composables/useChat.d.ts +22 -1
- package/dist/runtime/composables/useChat.js +79 -8
- package/dist/runtime/composables/useDocBreadcrumb.d.ts +17 -2
- package/dist/runtime/composables/useDocBreadcrumb.js +17 -3
- package/dist/runtime/composables/useDocSnapshots.d.ts +2 -1
- package/dist/runtime/composables/useDocSnapshots.js +5 -0
- package/dist/runtime/composables/useEditor.d.ts +1 -1
- package/dist/runtime/composables/useEditor.js +120 -0
- package/dist/runtime/composables/useEditorToolbar.d.ts +12 -4
- package/dist/runtime/composables/useEditorToolbar.js +78 -56
- package/dist/runtime/composables/useNodeContextMenu.d.ts +14 -0
- package/dist/runtime/composables/useNodeContextMenu.js +59 -1
- package/dist/runtime/composables/useSettingsModal.d.ts +1 -1
- package/dist/runtime/composables/useSwipeGesture.d.ts +48 -0
- package/dist/runtime/composables/useSwipeGesture.js +140 -0
- package/dist/runtime/extensions/document-header.js +16 -6
- package/dist/runtime/extensions/document-meta.js +344 -19
- package/dist/runtime/extensions/meta-field.js +42 -0
- package/dist/runtime/extensions/views/DocumentMetaView.vue +33 -7
- package/dist/runtime/extensions/views/FieldView.vue +51 -19
- package/dist/runtime/extensions/views/MetaFieldView.vue +30 -4
- package/dist/runtime/locale.d.ts +8 -0
- package/dist/runtime/locale.js +9 -1
- package/dist/runtime/middleware/abracadabra-auth.d.ts +1 -1
- package/dist/runtime/plugin-abracadabra.client.d.ts +1 -1
- package/dist/runtime/plugin-abracadabra.client.js +12 -2
- package/dist/runtime/plugin-abracadabra.server.d.ts +1 -1
- package/dist/runtime/plugin-shared-globals.client.d.ts +1 -1
- package/dist/runtime/utils/chatContent.d.ts +20 -2
- package/dist/runtime/utils/chatContent.js +20 -1
- package/dist/runtime/utils/docTypes.js +43 -0
- package/dist/runtime/utils/titleSync.d.ts +130 -0
- package/dist/runtime/utils/titleSync.js +53 -0
- package/package.json +11 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from "vue";
|
|
3
3
|
import { useRuntimeConfig } from "#imports";
|
|
4
|
-
import { useRafFn, useEventListener } from "@vueuse/core";
|
|
4
|
+
import { useRafFn, useEventListener, useLocalStorage } from "@vueuse/core";
|
|
5
5
|
import { getIcon, loadIcon } from "@iconify/vue";
|
|
6
6
|
import { useRendererBase } from "../../composables/useRendererBase";
|
|
7
7
|
import { useNodePanel } from "../../composables/useNodePanel";
|
|
@@ -161,20 +161,39 @@ function svgCoord(clientX, clientY) {
|
|
|
161
161
|
}
|
|
162
162
|
function onWheel(e) {
|
|
163
163
|
e.preventDefault();
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
164
|
+
const wantsZoom = e.ctrlKey ? scrollBehavior.value === "pan" : scrollBehavior.value === "zoom";
|
|
165
|
+
if (wantsZoom) {
|
|
166
|
+
const sensitivity = e.ctrlKey ? 8e-3 : 25e-4;
|
|
167
|
+
const delta = Math.sign(e.deltaY) * Math.min(Math.abs(e.deltaY), 100);
|
|
168
|
+
const scale = 1 + delta * sensitivity;
|
|
169
|
+
const rect = svgRef.value.getBoundingClientRect();
|
|
170
|
+
const tv = targetVb.value;
|
|
171
|
+
const px = (e.clientX - rect.left) / rect.width * tv.w + tv.x;
|
|
172
|
+
const py = (e.clientY - rect.top) / rect.height * tv.h + tv.y;
|
|
173
|
+
targetVb.value = {
|
|
174
|
+
x: px - (px - tv.x) * scale,
|
|
175
|
+
y: py - (py - tv.y) * scale,
|
|
176
|
+
w: Math.max(100, Math.min(8e3, tv.w * scale)),
|
|
177
|
+
h: Math.max(100, Math.min(8e3, tv.h * scale))
|
|
178
|
+
};
|
|
179
|
+
if (!zoomRafId) zoomRafId = requestAnimationFrame(animateZoom);
|
|
180
|
+
} else {
|
|
181
|
+
if (zoomRafId) {
|
|
182
|
+
cancelAnimationFrame(zoomRafId);
|
|
183
|
+
zoomRafId = null;
|
|
184
|
+
}
|
|
185
|
+
vb.value = { ...targetVb.value };
|
|
186
|
+
const rect = svgRef.value.getBoundingClientRect();
|
|
187
|
+
const sx = vb.value.w / rect.width;
|
|
188
|
+
const sy = vb.value.h / rect.height;
|
|
189
|
+
vb.value = {
|
|
190
|
+
x: vb.value.x + e.deltaX * sx,
|
|
191
|
+
y: vb.value.y + e.deltaY * sy,
|
|
192
|
+
w: vb.value.w,
|
|
193
|
+
h: vb.value.h
|
|
194
|
+
};
|
|
195
|
+
targetVb.value = { ...vb.value };
|
|
196
|
+
}
|
|
178
197
|
}
|
|
179
198
|
const activePointers = /* @__PURE__ */ new Map();
|
|
180
199
|
let isPinching = false;
|
|
@@ -371,6 +390,7 @@ watch(() => savedDocMeta.value?.graphEdgeThickness, (v) => {
|
|
|
371
390
|
if (v && v !== edgeThickness.value) edgeThickness.value = v;
|
|
372
391
|
});
|
|
373
392
|
const edgeScale = computed(() => EDGE_THICKNESS_SCALE[edgeThickness.value]);
|
|
393
|
+
const scrollBehavior = useLocalStorage("abracadabra_graph_scroll_behavior", "pan");
|
|
374
394
|
const spacingIcon = computed(() => {
|
|
375
395
|
const icons = {
|
|
376
396
|
compact: "i-lucide-dot",
|
|
@@ -1179,6 +1199,35 @@ defineExpose({ connectedUsers });
|
|
|
1179
1199
|
</UButton>
|
|
1180
1200
|
</div>
|
|
1181
1201
|
</div>
|
|
1202
|
+
|
|
1203
|
+
<!-- Personal (device-local) — not shared via the doc -->
|
|
1204
|
+
<div class="h-px bg-(--ui-border)" />
|
|
1205
|
+
<div class="flex items-center justify-between gap-2">
|
|
1206
|
+
<div class="flex flex-col min-w-0">
|
|
1207
|
+
<span class="text-xs text-(--ui-text-muted)">{{ locale.scrollBehavior }}</span>
|
|
1208
|
+
<span class="text-[10px] text-(--ui-text-dimmed)">{{ locale.personalSetting }}</span>
|
|
1209
|
+
</div>
|
|
1210
|
+
<div class="flex gap-0.5 shrink-0">
|
|
1211
|
+
<UButton
|
|
1212
|
+
size="xs"
|
|
1213
|
+
:variant="scrollBehavior === 'pan' ? 'soft' : 'ghost'"
|
|
1214
|
+
:color="scrollBehavior === 'pan' ? 'primary' : 'neutral'"
|
|
1215
|
+
class="text-[10px] px-1.5"
|
|
1216
|
+
@click="scrollBehavior = 'pan'"
|
|
1217
|
+
>
|
|
1218
|
+
{{ locale.scrollPan }}
|
|
1219
|
+
</UButton>
|
|
1220
|
+
<UButton
|
|
1221
|
+
size="xs"
|
|
1222
|
+
:variant="scrollBehavior === 'zoom' ? 'soft' : 'ghost'"
|
|
1223
|
+
:color="scrollBehavior === 'zoom' ? 'primary' : 'neutral'"
|
|
1224
|
+
class="text-[10px] px-1.5"
|
|
1225
|
+
@click="scrollBehavior = 'zoom'"
|
|
1226
|
+
>
|
|
1227
|
+
{{ locale.scrollZoom }}
|
|
1228
|
+
</UButton>
|
|
1229
|
+
</div>
|
|
1230
|
+
</div>
|
|
1182
1231
|
</div>
|
|
1183
1232
|
</template>
|
|
1184
1233
|
</UPopover>
|
|
@@ -10,14 +10,14 @@ type __VLS_Props = {
|
|
|
10
10
|
};
|
|
11
11
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, Record<PropertyKey, unknown>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
12
12
|
rename: (label: string) => any;
|
|
13
|
+
ready: () => any;
|
|
13
14
|
update: (content: any) => any;
|
|
14
15
|
updateMeta: (patch: Partial<DocPageMeta>) => any;
|
|
15
|
-
ready: () => any;
|
|
16
16
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
17
17
|
onRename?: ((label: string) => any) | undefined;
|
|
18
|
+
onReady?: (() => any) | undefined;
|
|
18
19
|
onUpdate?: ((content: any) => any) | undefined;
|
|
19
20
|
onUpdateMeta?: ((patch: Partial<DocPageMeta>) => any) | undefined;
|
|
20
|
-
onReady?: (() => any) | undefined;
|
|
21
21
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
22
22
|
declare const _default: typeof __VLS_export;
|
|
23
23
|
export default _default;
|
|
@@ -10,14 +10,14 @@ type __VLS_Props = {
|
|
|
10
10
|
};
|
|
11
11
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, Record<PropertyKey, unknown>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
12
12
|
rename: (label: string) => any;
|
|
13
|
+
ready: () => any;
|
|
13
14
|
update: (content: any) => any;
|
|
14
15
|
updateMeta: (patch: Partial<DocPageMeta>) => any;
|
|
15
|
-
ready: () => any;
|
|
16
16
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
17
17
|
onRename?: ((label: string) => any) | undefined;
|
|
18
|
+
onReady?: (() => any) | undefined;
|
|
18
19
|
onUpdate?: ((content: any) => any) | undefined;
|
|
19
20
|
onUpdateMeta?: ((patch: Partial<DocPageMeta>) => any) | undefined;
|
|
20
|
-
onReady?: (() => any) | undefined;
|
|
21
21
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
22
22
|
declare const _default: typeof __VLS_export;
|
|
23
23
|
export default _default;
|
|
@@ -20,16 +20,16 @@ type __VLS_Props = {
|
|
|
20
20
|
};
|
|
21
21
|
};
|
|
22
22
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
23
|
+
next: () => any;
|
|
23
24
|
"update:viewMode": (mode: CalendarViewMode) => any;
|
|
24
25
|
prev: () => any;
|
|
25
|
-
next: () => any;
|
|
26
26
|
today: () => any;
|
|
27
27
|
"add-event": () => any;
|
|
28
28
|
"navigate-to-month": (year: number, month: number) => any;
|
|
29
29
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
30
|
+
onNext?: (() => any) | undefined;
|
|
30
31
|
"onUpdate:viewMode"?: ((mode: CalendarViewMode) => any) | undefined;
|
|
31
32
|
onPrev?: (() => any) | undefined;
|
|
32
|
-
onNext?: (() => any) | undefined;
|
|
33
33
|
onToday?: (() => any) | undefined;
|
|
34
34
|
"onAdd-event"?: (() => any) | undefined;
|
|
35
35
|
"onNavigate-to-month"?: ((year: number, month: number) => any) | undefined;
|
|
@@ -20,16 +20,16 @@ type __VLS_Props = {
|
|
|
20
20
|
};
|
|
21
21
|
};
|
|
22
22
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
23
|
+
next: () => any;
|
|
23
24
|
"update:viewMode": (mode: CalendarViewMode) => any;
|
|
24
25
|
prev: () => any;
|
|
25
|
-
next: () => any;
|
|
26
26
|
today: () => any;
|
|
27
27
|
"add-event": () => any;
|
|
28
28
|
"navigate-to-month": (year: number, month: number) => any;
|
|
29
29
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
30
|
+
onNext?: (() => any) | undefined;
|
|
30
31
|
"onUpdate:viewMode"?: ((mode: CalendarViewMode) => any) | undefined;
|
|
31
32
|
onPrev?: (() => any) | undefined;
|
|
32
|
-
onNext?: (() => any) | undefined;
|
|
33
33
|
onToday?: (() => any) | undefined;
|
|
34
34
|
"onAdd-event"?: (() => any) | undefined;
|
|
35
35
|
"onNavigate-to-month"?: ((year: number, month: number) => any) | undefined;
|
|
@@ -8,13 +8,13 @@ type __VLS_Props = {
|
|
|
8
8
|
isLoading: boolean;
|
|
9
9
|
};
|
|
10
10
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
11
|
-
prev: () => any;
|
|
12
11
|
next: () => any;
|
|
12
|
+
prev: () => any;
|
|
13
13
|
togglePlay: () => any;
|
|
14
14
|
seek: (position: number) => any;
|
|
15
15
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
16
|
-
onPrev?: (() => any) | undefined;
|
|
17
16
|
onNext?: (() => any) | undefined;
|
|
17
|
+
onPrev?: (() => any) | undefined;
|
|
18
18
|
onTogglePlay?: (() => any) | undefined;
|
|
19
19
|
onSeek?: ((position: number) => any) | undefined;
|
|
20
20
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -8,13 +8,13 @@ type __VLS_Props = {
|
|
|
8
8
|
isLoading: boolean;
|
|
9
9
|
};
|
|
10
10
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
11
|
-
prev: () => any;
|
|
12
11
|
next: () => any;
|
|
12
|
+
prev: () => any;
|
|
13
13
|
togglePlay: () => any;
|
|
14
14
|
seek: (position: number) => any;
|
|
15
15
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
16
|
-
onPrev?: (() => any) | undefined;
|
|
17
16
|
onNext?: (() => any) | undefined;
|
|
17
|
+
onPrev?: (() => any) | undefined;
|
|
18
18
|
onTogglePlay?: (() => any) | undefined;
|
|
19
19
|
onSeek?: ((position: number) => any) | undefined;
|
|
20
20
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -60,10 +60,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
|
|
|
60
60
|
keydown: (e: KeyboardEvent) => any;
|
|
61
61
|
paste: (e: ClipboardEvent) => any;
|
|
62
62
|
renameColumn: (colId: string, label: string) => any;
|
|
63
|
-
commitEdit: () => any;
|
|
64
63
|
"update:editValue": (value: string) => any;
|
|
65
64
|
selectCell: (colIdx: number, rowIdx: number, shiftKey: boolean) => any;
|
|
66
65
|
activateCell: (colIdx: number, rowIdx: number) => any;
|
|
66
|
+
commitEdit: () => any;
|
|
67
67
|
cancelEdit: () => any;
|
|
68
68
|
resizeColumn: (colId: string, width: number) => any;
|
|
69
69
|
selectRow: (rowIdx: number) => any;
|
|
@@ -86,10 +86,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
|
|
|
86
86
|
onKeydown?: ((e: KeyboardEvent) => any) | undefined;
|
|
87
87
|
onPaste?: ((e: ClipboardEvent) => any) | undefined;
|
|
88
88
|
onRenameColumn?: ((colId: string, label: string) => any) | undefined;
|
|
89
|
-
onCommitEdit?: (() => any) | undefined;
|
|
90
89
|
"onUpdate:editValue"?: ((value: string) => any) | undefined;
|
|
91
90
|
onSelectCell?: ((colIdx: number, rowIdx: number, shiftKey: boolean) => any) | undefined;
|
|
92
91
|
onActivateCell?: ((colIdx: number, rowIdx: number) => any) | undefined;
|
|
92
|
+
onCommitEdit?: (() => any) | undefined;
|
|
93
93
|
onCancelEdit?: (() => any) | undefined;
|
|
94
94
|
onResizeColumn?: ((colId: string, width: number) => any) | undefined;
|
|
95
95
|
onSelectRow?: ((rowIdx: number) => any) | undefined;
|
|
@@ -60,10 +60,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
|
|
|
60
60
|
keydown: (e: KeyboardEvent) => any;
|
|
61
61
|
paste: (e: ClipboardEvent) => any;
|
|
62
62
|
renameColumn: (colId: string, label: string) => any;
|
|
63
|
-
commitEdit: () => any;
|
|
64
63
|
"update:editValue": (value: string) => any;
|
|
65
64
|
selectCell: (colIdx: number, rowIdx: number, shiftKey: boolean) => any;
|
|
66
65
|
activateCell: (colIdx: number, rowIdx: number) => any;
|
|
66
|
+
commitEdit: () => any;
|
|
67
67
|
cancelEdit: () => any;
|
|
68
68
|
resizeColumn: (colId: string, width: number) => any;
|
|
69
69
|
selectRow: (rowIdx: number) => any;
|
|
@@ -86,10 +86,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
|
|
|
86
86
|
onKeydown?: ((e: KeyboardEvent) => any) | undefined;
|
|
87
87
|
onPaste?: ((e: ClipboardEvent) => any) | undefined;
|
|
88
88
|
onRenameColumn?: ((colId: string, label: string) => any) | undefined;
|
|
89
|
-
onCommitEdit?: (() => any) | undefined;
|
|
90
89
|
"onUpdate:editValue"?: ((value: string) => any) | undefined;
|
|
91
90
|
onSelectCell?: ((colIdx: number, rowIdx: number, shiftKey: boolean) => any) | undefined;
|
|
92
91
|
onActivateCell?: ((colIdx: number, rowIdx: number) => any) | undefined;
|
|
92
|
+
onCommitEdit?: (() => any) | undefined;
|
|
93
93
|
onCancelEdit?: (() => any) | undefined;
|
|
94
94
|
onResizeColumn?: ((colId: string, width: number) => any) | undefined;
|
|
95
95
|
onSelectRow?: ((rowIdx: number) => any) | undefined;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, onMounted, ref } from "vue";
|
|
3
|
+
import { useNuxtApp } from "#imports";
|
|
4
|
+
const colorMode = useNuxtApp().$colorMode;
|
|
5
|
+
const THEME_OPTIONS = [
|
|
6
|
+
{ value: "system", label: "System", icon: "i-lucide-monitor" },
|
|
7
|
+
{ value: "light", label: "Light", icon: "i-lucide-sun" },
|
|
8
|
+
{ value: "dark", label: "Dark", icon: "i-lucide-moon" }
|
|
9
|
+
];
|
|
10
|
+
const theme = computed({
|
|
11
|
+
get: () => colorMode?.preference || "system",
|
|
12
|
+
set: (v) => {
|
|
13
|
+
if (colorMode) colorMode.preference = v;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
const REDUCE_MOTION_KEY = "abracadabra_reduce_motion";
|
|
17
|
+
const reduceMotion = ref(false);
|
|
18
|
+
function applyReduceMotion(on) {
|
|
19
|
+
if (typeof document === "undefined") return;
|
|
20
|
+
if (on) document.documentElement.setAttribute("data-reduce-motion", "");
|
|
21
|
+
else document.documentElement.removeAttribute("data-reduce-motion");
|
|
22
|
+
}
|
|
23
|
+
onMounted(() => {
|
|
24
|
+
reduceMotion.value = localStorage.getItem(REDUCE_MOTION_KEY) === "1";
|
|
25
|
+
applyReduceMotion(reduceMotion.value);
|
|
26
|
+
});
|
|
27
|
+
function setReduceMotion(on) {
|
|
28
|
+
reduceMotion.value = on;
|
|
29
|
+
if (typeof localStorage !== "undefined") localStorage.setItem(REDUCE_MOTION_KEY, on ? "1" : "0");
|
|
30
|
+
applyReduceMotion(on);
|
|
31
|
+
}
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<template>
|
|
35
|
+
<ASettingsGroup
|
|
36
|
+
title="Appearance"
|
|
37
|
+
description="Theme and motion preferences for this device."
|
|
38
|
+
>
|
|
39
|
+
<ASettingsRow
|
|
40
|
+
label="Theme"
|
|
41
|
+
description="Match your system, or always use light or dark."
|
|
42
|
+
>
|
|
43
|
+
<div class="flex items-center gap-1 rounded-(--ui-radius) bg-(--ui-bg-elevated) p-0.5">
|
|
44
|
+
<UButton
|
|
45
|
+
v-for="opt in THEME_OPTIONS"
|
|
46
|
+
:key="opt.value"
|
|
47
|
+
:icon="opt.icon"
|
|
48
|
+
:label="opt.label"
|
|
49
|
+
size="xs"
|
|
50
|
+
:color="theme === opt.value ? 'primary' : 'neutral'"
|
|
51
|
+
:variant="theme === opt.value ? 'soft' : 'ghost'"
|
|
52
|
+
@click="theme = opt.value"
|
|
53
|
+
/>
|
|
54
|
+
</div>
|
|
55
|
+
</ASettingsRow>
|
|
56
|
+
|
|
57
|
+
<ASettingsRow
|
|
58
|
+
label="Reduced motion"
|
|
59
|
+
description="Minimise animations and transitions across the app."
|
|
60
|
+
>
|
|
61
|
+
<USwitch
|
|
62
|
+
:model-value="reduceMotion"
|
|
63
|
+
@update:model-value="setReduceMotion($event)"
|
|
64
|
+
/>
|
|
65
|
+
</ASettingsRow>
|
|
66
|
+
</ASettingsGroup>
|
|
67
|
+
</template>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <ASettingsGroup>
|
|
3
|
+
*
|
|
4
|
+
* A titled group of settings rows: optional title + description header above a
|
|
5
|
+
* column of <ASettingsRow>s. Shared building block — ported from cou-sh
|
|
6
|
+
* SettingsV2/Group.vue.
|
|
7
|
+
*/
|
|
8
|
+
type __VLS_Props = {
|
|
9
|
+
title?: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
};
|
|
12
|
+
declare var __VLS_1: {};
|
|
13
|
+
type __VLS_Slots = {} & {
|
|
14
|
+
default?: (props: typeof __VLS_1) => any;
|
|
15
|
+
};
|
|
16
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
17
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
18
|
+
declare const _default: typeof __VLS_export;
|
|
19
|
+
export default _default;
|
|
20
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
21
|
+
new (): {
|
|
22
|
+
$slots: S;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
defineProps({
|
|
3
|
+
title: { type: String, required: false },
|
|
4
|
+
description: { type: String, required: false }
|
|
5
|
+
});
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<section class="flex flex-col gap-3">
|
|
10
|
+
<header
|
|
11
|
+
v-if="title || description"
|
|
12
|
+
class="flex flex-col gap-1"
|
|
13
|
+
>
|
|
14
|
+
<h3
|
|
15
|
+
v-if="title"
|
|
16
|
+
class="text-base font-semibold text-(--ui-text-highlighted)"
|
|
17
|
+
>
|
|
18
|
+
{{ title }}
|
|
19
|
+
</h3>
|
|
20
|
+
<p
|
|
21
|
+
v-if="description"
|
|
22
|
+
class="text-sm text-(--ui-text-muted)"
|
|
23
|
+
>
|
|
24
|
+
{{ description }}
|
|
25
|
+
</p>
|
|
26
|
+
</header>
|
|
27
|
+
<div class="flex flex-col">
|
|
28
|
+
<slot />
|
|
29
|
+
</div>
|
|
30
|
+
</section>
|
|
31
|
+
</template>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <ASettingsGroup>
|
|
3
|
+
*
|
|
4
|
+
* A titled group of settings rows: optional title + description header above a
|
|
5
|
+
* column of <ASettingsRow>s. Shared building block — ported from cou-sh
|
|
6
|
+
* SettingsV2/Group.vue.
|
|
7
|
+
*/
|
|
8
|
+
type __VLS_Props = {
|
|
9
|
+
title?: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
};
|
|
12
|
+
declare var __VLS_1: {};
|
|
13
|
+
type __VLS_Slots = {} & {
|
|
14
|
+
default?: (props: typeof __VLS_1) => any;
|
|
15
|
+
};
|
|
16
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
17
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
18
|
+
declare const _default: typeof __VLS_export;
|
|
19
|
+
export default _default;
|
|
20
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
21
|
+
new (): {
|
|
22
|
+
$slots: S;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
import { ref, computed, watch } from "vue";
|
|
3
3
|
import { useSettingsModal } from "../../composables/useSettingsModal";
|
|
4
4
|
import { useAbracadabra } from "../../composables/useAbracadabra";
|
|
5
|
+
import {
|
|
6
|
+
BUILTIN_SETTINGS_SECTIONS,
|
|
7
|
+
GROUP_LABELS,
|
|
8
|
+
GROUP_MODE,
|
|
9
|
+
searchSections,
|
|
10
|
+
visibleSections
|
|
11
|
+
} from "./sections";
|
|
5
12
|
const { isOpen, activeTab } = useSettingsModal();
|
|
6
13
|
const abra = useAbracadabra();
|
|
7
14
|
const effectiveRole = computed(() => abra.provider.value?.effectiveRole ?? null);
|
|
@@ -9,53 +16,56 @@ const isAdmin = computed(() => {
|
|
|
9
16
|
const role = effectiveRole.value;
|
|
10
17
|
return role === "admin" || role === "service";
|
|
11
18
|
});
|
|
12
|
-
const
|
|
13
|
-
{ key: "profile", label: "Profile", icon: "i-lucide-user" },
|
|
14
|
-
{ key: "security", label: "Security", icon: "i-lucide-shield" },
|
|
15
|
-
{ key: "offline", label: "Offline", icon: "i-lucide-database" }
|
|
16
|
-
];
|
|
17
|
-
const adminLinks = computed(() => [
|
|
18
|
-
{ key: "spaces", label: "Spaces", icon: "i-lucide-layers" },
|
|
19
|
-
{ key: "members", label: "Members", icon: "i-lucide-users" },
|
|
20
|
-
{ key: "connection", label: "Connection", icon: "i-lucide-wifi" },
|
|
21
|
-
{ key: "trash", label: "Trash", icon: "i-lucide-trash-2" },
|
|
22
|
-
{ key: "plugins", label: "Plugins", icon: "i-lucide-plug" },
|
|
23
|
-
...isAdmin.value ? [
|
|
24
|
-
{ key: "invites", label: "Invites", icon: "i-lucide-ticket" },
|
|
25
|
-
{ key: "admin", label: "Admin", icon: "i-lucide-shield-alert" }
|
|
26
|
-
] : []
|
|
27
|
-
]);
|
|
19
|
+
const search = ref("");
|
|
28
20
|
const settingsMode = ref("user");
|
|
29
21
|
const headerTabs = [
|
|
30
22
|
{ value: "user", label: "User Settings", icon: "i-lucide-user" },
|
|
31
23
|
{ value: "admin", label: "Administration", icon: "i-lucide-shield" }
|
|
32
24
|
];
|
|
33
|
-
const
|
|
34
|
-
() =>
|
|
25
|
+
const modeSections = computed(
|
|
26
|
+
() => visibleSections(BUILTIN_SETTINGS_SECTIONS, isAdmin.value).filter((s) => GROUP_MODE[s.group] === settingsMode.value)
|
|
35
27
|
);
|
|
28
|
+
const filteredSections = computed(() => searchSections(search.value, modeSections.value));
|
|
29
|
+
const groupedSections = computed(() => {
|
|
30
|
+
const groups = [];
|
|
31
|
+
for (const section of filteredSections.value) {
|
|
32
|
+
let g = groups.find((x) => x.group === section.group);
|
|
33
|
+
if (!g) {
|
|
34
|
+
g = { group: section.group, label: GROUP_LABELS[section.group], items: [] };
|
|
35
|
+
groups.push(g);
|
|
36
|
+
}
|
|
37
|
+
g.items.push(section);
|
|
38
|
+
}
|
|
39
|
+
return groups;
|
|
40
|
+
});
|
|
36
41
|
const currentDescription = computed(
|
|
37
42
|
() => settingsMode.value === "admin" ? "Manage spaces, members, and server settings." : "Personalize your profile, security, and preferences."
|
|
38
43
|
);
|
|
39
|
-
const
|
|
40
|
-
() =>
|
|
44
|
+
const selectedSection = computed(
|
|
45
|
+
() => modeSections.value.find((s) => s.key === activeTab.value) ?? modeSections.value[0]
|
|
41
46
|
);
|
|
42
|
-
|
|
43
|
-
|
|
47
|
+
const activeComponent = computed(() => selectedSection.value?.component ?? null);
|
|
48
|
+
function selectSection(section) {
|
|
49
|
+
activeTab.value = section.key;
|
|
44
50
|
}
|
|
45
51
|
const showMobileNav = ref(true);
|
|
46
|
-
function selectMobile(
|
|
47
|
-
selectSection(
|
|
52
|
+
function selectMobile(section) {
|
|
53
|
+
selectSection(section);
|
|
48
54
|
showMobileNav.value = false;
|
|
49
55
|
}
|
|
50
56
|
watch(isOpen, (val) => {
|
|
51
57
|
if (val) {
|
|
52
58
|
showMobileNav.value = true;
|
|
59
|
+
search.value = "";
|
|
60
|
+
const target = BUILTIN_SETTINGS_SECTIONS.find((s) => s.key === activeTab.value);
|
|
61
|
+
if (target) settingsMode.value = GROUP_MODE[target.group];
|
|
53
62
|
}
|
|
54
63
|
});
|
|
55
64
|
watch(settingsMode, () => {
|
|
56
65
|
showMobileNav.value = true;
|
|
57
|
-
|
|
58
|
-
|
|
66
|
+
search.value = "";
|
|
67
|
+
const first = modeSections.value[0];
|
|
68
|
+
if (first) activeTab.value = first.key;
|
|
59
69
|
});
|
|
60
70
|
</script>
|
|
61
71
|
|
|
@@ -112,28 +122,54 @@ watch(settingsMode, () => {
|
|
|
112
122
|
showMobileNav ? 'w-full sm:w-52' : 'hidden sm:block sm:w-52'
|
|
113
123
|
]"
|
|
114
124
|
>
|
|
115
|
-
<div class="p-
|
|
116
|
-
<p class="text-xs text-(--ui-text-muted)">
|
|
125
|
+
<div class="p-3 pb-2 space-y-2">
|
|
126
|
+
<p class="text-xs text-(--ui-text-muted) px-1">
|
|
117
127
|
{{ currentDescription }}
|
|
118
128
|
</p>
|
|
129
|
+
<UInput
|
|
130
|
+
v-model="search"
|
|
131
|
+
icon="i-lucide-search"
|
|
132
|
+
placeholder="Search settings…"
|
|
133
|
+
size="xs"
|
|
134
|
+
class="w-full"
|
|
135
|
+
:ui="{ root: 'w-full' }"
|
|
136
|
+
/>
|
|
119
137
|
</div>
|
|
120
138
|
|
|
121
|
-
<nav class="flex flex-col gap-
|
|
122
|
-
<
|
|
123
|
-
v-for="
|
|
124
|
-
:key="
|
|
125
|
-
class="flex
|
|
126
|
-
|
|
127
|
-
|
|
139
|
+
<nav class="flex flex-col gap-2 p-2">
|
|
140
|
+
<div
|
|
141
|
+
v-for="grp in groupedSections"
|
|
142
|
+
:key="grp.group"
|
|
143
|
+
class="flex flex-col gap-0.5"
|
|
144
|
+
>
|
|
145
|
+
<p
|
|
146
|
+
v-if="groupedSections.length > 1"
|
|
147
|
+
class="px-3 pt-1 pb-0.5 text-[10px] font-semibold uppercase tracking-wider text-(--ui-text-dimmed)"
|
|
148
|
+
>
|
|
149
|
+
{{ grp.label }}
|
|
150
|
+
</p>
|
|
151
|
+
<button
|
|
152
|
+
v-for="item in grp.items"
|
|
153
|
+
:key="item.key"
|
|
154
|
+
class="flex items-center gap-3 px-3 py-2 rounded-lg text-sm transition-colors text-left w-full"
|
|
155
|
+
:class="[
|
|
156
|
+
selectedSection?.key === item.key ? 'bg-(--ui-bg-elevated) text-(--ui-text-highlighted) font-medium' : 'text-(--ui-text-muted) hover:text-(--ui-text) hover:bg-(--ui-bg-elevated)/50'
|
|
128
157
|
]"
|
|
129
|
-
|
|
158
|
+
@click="selectMobile(item)"
|
|
159
|
+
>
|
|
160
|
+
<UIcon
|
|
161
|
+
:name="item.icon"
|
|
162
|
+
class="size-4 shrink-0"
|
|
163
|
+
/>
|
|
164
|
+
<span class="truncate">{{ item.label }}</span>
|
|
165
|
+
</button>
|
|
166
|
+
</div>
|
|
167
|
+
<p
|
|
168
|
+
v-if="filteredSections.length === 0"
|
|
169
|
+
class="px-3 py-4 text-center text-xs text-(--ui-text-dimmed)"
|
|
130
170
|
>
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
class="size-4 shrink-0"
|
|
134
|
-
/>
|
|
135
|
-
<span class="truncate">{{ item.label }}</span>
|
|
136
|
-
</button>
|
|
171
|
+
No matching settings.
|
|
172
|
+
</p>
|
|
137
173
|
</nav>
|
|
138
174
|
</div>
|
|
139
175
|
|
|
@@ -151,21 +187,16 @@ watch(settingsMode, () => {
|
|
|
151
187
|
size="xs"
|
|
152
188
|
@click="showMobileNav = true"
|
|
153
189
|
/>
|
|
154
|
-
<span class="text-sm font-medium truncate">{{
|
|
190
|
+
<span class="text-sm font-medium truncate">{{ selectedSection?.label }}</span>
|
|
155
191
|
</div>
|
|
156
192
|
|
|
157
193
|
<div class="p-4 sm:p-6 lg:p-8">
|
|
158
194
|
<div class="flex flex-col gap-6 max-w-2xl mx-auto">
|
|
159
|
-
<
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
<ASettingsMembersPanel v-else-if="activeTab === 'members'" />
|
|
165
|
-
<ASettingsTrashPanel v-else-if="activeTab === 'trash'" />
|
|
166
|
-
<ASettingsOfflinePanel v-else-if="activeTab === 'offline'" />
|
|
167
|
-
<ASettingsPluginsPanel v-else-if="activeTab === 'plugins'" />
|
|
168
|
-
<ASettingsAdminPanel v-else-if="activeTab === 'admin'" />
|
|
195
|
+
<component
|
|
196
|
+
:is="activeComponent"
|
|
197
|
+
v-if="activeComponent"
|
|
198
|
+
:key="selectedSection?.key"
|
|
199
|
+
/>
|
|
169
200
|
</div>
|
|
170
201
|
</div>
|
|
171
202
|
</div>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <ASettingsPlaceholder>
|
|
3
|
+
*
|
|
4
|
+
* Centered empty-state card for a not-yet-implemented (or empty) settings
|
|
5
|
+
* section: icon bubble + title + description, with an optional badge.
|
|
6
|
+
* Ported from cou-sh SettingsV2/Placeholder.vue — the badge is configurable
|
|
7
|
+
* here (cou-sh hardcoded "Coming next"); omit `badge` to hide it.
|
|
8
|
+
*/
|
|
9
|
+
type __VLS_Props = {
|
|
10
|
+
icon: string;
|
|
11
|
+
title: string;
|
|
12
|
+
description: string;
|
|
13
|
+
/** Optional badge label (e.g. "Coming next"). Omit to hide the badge. */
|
|
14
|
+
badge?: string;
|
|
15
|
+
};
|
|
16
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
17
|
+
badge: string;
|
|
18
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
19
|
+
declare const _default: typeof __VLS_export;
|
|
20
|
+
export default _default;
|