@json-canvas-viewer/vue 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 Hesprs (Hēsperus)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,100 @@
1
+ <h1 align="center">
2
+ <img src="../../assets/logo.svg" alt="JSON Canvas Viewer logo" width="280px">
3
+ <br />
4
+ JSON Canvas Viewer Vue
5
+ <br />
6
+ </h1>
7
+
8
+ <h4 align="center">JSON Canvas Viewer as a Vue component</h4>
9
+
10
+ <p align="center">
11
+ <a href="https://github.com/hesprs/json-canvas-viewer/wiki">
12
+ <strong>Documentation</strong>
13
+ </a> •
14
+ <a href="https://www.npmjs.com/package/json-canvas-viewer">
15
+ <strong>Vanilla</strong>
16
+ </a> •
17
+ <a href="https://www.npmjs.com/package/vite-plugin-json-canvas">
18
+ <strong>Vite Plugin</strong>
19
+ </a> •
20
+ <a href="https://www.npmjs.com/package/@json-canvas-viewer/react">
21
+ <strong>React Component</strong>
22
+ </a> •
23
+ <strong>Vue Component</strong> •
24
+ <a href="https://www.npmjs.com/package/@json-canvas-viewer/preact">
25
+ <strong>Preact Component</strong>
26
+ </a>
27
+ </p>
28
+
29
+ ## ✏️ Description
30
+
31
+ This is the Vue component of JSON Canvas Viewer, it wraps around the vanilla viewer class to provide a seamless integration with Vue. This package additionally re-exports everything from the core package, so you do not need to install the core package separately.
32
+
33
+ Install this package if you want to use JSON Canvas Viewer in a **Vue** project. If you are not using it, please head to the corresponding package in the navigation bar above.
34
+
35
+ ## 📦 Installation
36
+
37
+ Install with your favorite package manager:
38
+
39
+ ```bash
40
+ npm add @json-canvas-viewer/vue
41
+
42
+ # or
43
+ pnpm add @json-canvas-viewer/vue
44
+
45
+ # or
46
+ yarn add @json-canvas-viewer/vue
47
+
48
+ # or
49
+ bun add @json-canvas-viewer/vue
50
+ ```
51
+
52
+ Now you have two options: **build-time** canvas parsing or **client-side** canvas parsing.
53
+
54
+ ### Build-time Canvas Parsing
55
+
56
+ This is the recommended way to parse canvas data, it will result in significantly smaller bundle size and faster load times.
57
+
58
+ Firstly, you need a bundler. JSON Canvas Viewer currently supports [Vite](https://vitejs.dev/) only. Please install [Vite Plugin](https://www.npmjs.com/package/vite-plugin-json-canvas) and setup it.
59
+
60
+ After bundler setup, you can directly import a canvas file and use it in viewer instantiation:
61
+
62
+ ```vue
63
+ <script setup>
64
+ import { JSONCanvasViewerComponent } from '@json-canvas-viewer/vue';
65
+ import canvas from 'path/to/your.canvas';
66
+ </script>
67
+
68
+ <template>
69
+ <Suspense>
70
+ <!-- Suspense is crucial -->
71
+ <JSONCanvasViewerComponent :canvas="canvas" />
72
+ </Suspense>
73
+ </template>
74
+ ```
75
+
76
+ ### Client-side Canvas Parsing
77
+
78
+ This method doesn't require any bundler setup. You just need to import the parser and fetch the canvas file:
79
+
80
+ ```vue
81
+ <script setup>
82
+ import { JSONCanvasViewerComponent, fetchCanvas, parser } from '@json-canvas-viewer/vue';
83
+ </script>
84
+
85
+ <template>
86
+ <Suspense>
87
+ <!-- Suspense is crucial -->
88
+ <JSONCanvasViewerComponent
89
+ :canvas="await fetchCanvas('path/to/your.canvas')"
90
+ :options="{ parser }"
91
+ />
92
+ </Suspense>
93
+ </template>
94
+ ```
95
+
96
+ Refer to the [documentation](https://github.com/hesprs/json-canvas-viewer/wiki/) for more details.
97
+
98
+ ## 📝 Copyright & License
99
+
100
+ Copyright ©️ 2025-2026 Hesprs (Hēsperus) | [MIT License](https://mit-license.org/)
@@ -0,0 +1,57 @@
1
+ import { Options, GeneralModuleCtor, Hook, JSONCanvasTextNode, JSONCanvasLinkNode, JSONCanvasFileNode, JSONCanvas } from 'json-canvas-viewer';
2
+ export type ModuleInputCtor = Array<GeneralModuleCtor>;
3
+ export interface TextSlotProps {
4
+ content: string;
5
+ node: JSONCanvasTextNode;
6
+ onActive: Hook;
7
+ onLoseActive: Hook;
8
+ }
9
+ export interface LinkSlotProps {
10
+ content: string;
11
+ node: JSONCanvasLinkNode;
12
+ onActive: Hook;
13
+ onLoseActive: Hook;
14
+ }
15
+ export interface FileSlotProps {
16
+ content: string;
17
+ node: JSONCanvasFileNode;
18
+ onActive: Hook;
19
+ onLoseActive: Hook;
20
+ }
21
+ declare const _default: <T extends ModuleInputCtor>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
22
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, never>, never> & {
23
+ modules?: T | undefined;
24
+ canvas?: JSONCanvas;
25
+ attachmentDir?: string;
26
+ attachments?: Record<string, string>;
27
+ options?: Omit<Options<T>, "canvas" | "attachmentDir" | "attachments" | "theme" | "container" | "nodeComponents"> | undefined;
28
+ isPrerendering?: boolean;
29
+ theme?: "dark" | "light";
30
+ } & Partial<{}>> & import('vue').PublicProps;
31
+ expose(exposed: import('vue').ShallowUnwrapRef<{
32
+ viewer: null;
33
+ }>): void;
34
+ attrs: any;
35
+ slots: Readonly<{
36
+ text?(props: TextSlotProps): unknown;
37
+ markdown?(props: FileSlotProps): unknown;
38
+ image?(props: FileSlotProps): unknown;
39
+ video?(props: FileSlotProps): unknown;
40
+ audio?(props: FileSlotProps): unknown;
41
+ link?(props: LinkSlotProps): unknown;
42
+ }> & {
43
+ text?(props: TextSlotProps): unknown;
44
+ markdown?(props: FileSlotProps): unknown;
45
+ image?(props: FileSlotProps): unknown;
46
+ video?(props: FileSlotProps): unknown;
47
+ audio?(props: FileSlotProps): unknown;
48
+ link?(props: LinkSlotProps): unknown;
49
+ };
50
+ emit: {};
51
+ }>) => import('vue').VNode & {
52
+ __ctx?: Awaited<typeof __VLS_setup>;
53
+ };
54
+ export default _default;
55
+ type __VLS_PrettifyLocal<T> = {
56
+ [K in keyof T]: T[K];
57
+ } & {};
@@ -0,0 +1,2 @@
1
+ export * from 'json-canvas-viewer';
2
+ export { default as JSONCanvasViewerComponent } from './Viewer.vue';
package/dist/vue.js ADDED
@@ -0,0 +1,2 @@
1
+ import{renderToString as t,JSONCanvasViewer as e}from"json-canvas-viewer";export*from"json-canvas-viewer";import{defineComponent as n,useTemplateRef as a,getCurrentInstance as o,withAsyncContext as s,useSlots as c,watch as r,onMounted as i,onUnmounted as m,openBlock as h,createElementBlock as v,unref as u,createApp as p,reactive as l}from"vue";const d=["innerHTML"],w=/* @__PURE__ */n({__name:"Viewer",props:{modules:{},canvas:{},attachmentDir:{},attachments:{},options:{},isPrerendering:{type:Boolean},theme:{}},async setup(n,{expose:w}){let f,D;const x=n,g=x.isPrerendering??!1,y=a("viewerRef");let C=null;const _=o(),b=g?([f,D]=s(()=>t({canvas:x.canvas??{},attachmentDir:x.attachmentDir,attachments:x.attachments,...x.options})),f=await f,D(),f):"",j=c();function k(t){return(e,n,a,o,s,c)=>{const r=p({render:()=>t(l({content:n,node:a,onActive:s,onLoseActive:c}))});r._context=_.appContext,r.mount(e),o.subscribe(r.unmount)}}return w({viewer:C}),r(()=>x.theme,t=>C?.changeTheme(t)),r(()=>({canvas:x.canvas,attachmentDir:x.attachmentDir,attachments:x.attachments}),({canvas:t,attachmentDir:e,attachments:n})=>C?.load({canvas:t,attachmentDir:e,attachments:n})),i(()=>{if(!y.value)return;const t=["text","markdown","link","audio","image","video"],n={};for(const e of t){const t=j[e];t&&(n[e]=k(t))}C=new e(Object.assign(x.options??{},{container:y.value,theme:x.theme,canvas:x.canvas,attachmentDir:x.attachmentDir,attachments:x.attachments,nodeComponents:n}),x.modules)}),m(()=>{C?.dispose(),C=null}),(t,e)=>(h(),v("section",{ref_key:"viewerRef",ref:y,innerHTML:u(b),style:{"max-height":"100vh","max-width":"100vw"}},null,8,d))}});export{w as JSONCanvasViewerComponent};
2
+ //# sourceMappingURL=vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue.js","sources":["../src/Viewer.vue"],"sourcesContent":["<script lang=\"ts\" generic=\"T extends ModuleInputCtor\" setup>\nimport {\n\tonMounted,\n\tonUnmounted,\n\tuseTemplateRef,\n\twatch,\n\tgetCurrentInstance,\n\ttype ComponentInternalInstance,\n\tcreateApp,\n\treactive,\n} from 'vue';\nimport {\n\tJSONCanvasViewer,\n\ttype Options,\n\ttype JSONCanvasViewerInterface,\n\trenderToString,\n\ttype GeneralModuleCtor,\n\ttype Hook,\n\ttype JSONCanvasTextNode,\n\ttype JSONCanvasLinkNode,\n\ttype JSONCanvasFileNode,\n\ttype JSONCanvas,\n} from 'json-canvas-viewer';\n\nexport type ModuleInputCtor = Array<GeneralModuleCtor>;\n\nexport interface TextSlotProps {\n\tcontent: string;\n\tnode: JSONCanvasTextNode;\n\tonActive: Hook;\n\tonLoseActive: Hook;\n}\n\nexport interface LinkSlotProps {\n\tcontent: string;\n\tnode: JSONCanvasLinkNode;\n\tonActive: Hook;\n\tonLoseActive: Hook;\n}\n\nexport interface FileSlotProps {\n\tcontent: string;\n\tnode: JSONCanvasFileNode;\n\tonActive: Hook;\n\tonLoseActive: Hook;\n}\n\ntype ComponentOptions<T extends ModuleInputCtor> = {\n\tmodules?: T;\n\tcanvas?: JSONCanvas;\n\tattachmentDir?: string;\n\tattachments?: Record<string, string>;\n\toptions?: Omit<\n\t\tOptions<T>,\n\t\t'container' | 'theme' | 'canvas' | 'attachmentDir' | 'nodeComponents' | 'attachments'\n\t>;\n\tisPrerendering?: boolean;\n\ttheme?: 'dark' | 'light';\n};\n\nconst props = defineProps<ComponentOptions<T>>();\nconst isPrerendering = props.isPrerendering ?? false;\nconst viewerRef = useTemplateRef('viewerRef');\nlet viewer: JSONCanvasViewerInterface<T> | null = null;\nconst instance = getCurrentInstance() as ComponentInternalInstance;\nconst prerender = isPrerendering\n\t? await renderToString({\n\t\t\tcanvas: props.canvas ?? {},\n\t\t\tattachmentDir: props.attachmentDir,\n\t\t\tattachments: props.attachments,\n\t\t\t...props.options,\n\t\t})\n\t: '';\n\nconst slots = defineSlots<{\n\ttext?(props: TextSlotProps): unknown;\n\tmarkdown?(props: FileSlotProps): unknown;\n\timage?(props: FileSlotProps): unknown;\n\tvideo?(props: FileSlotProps): unknown;\n\taudio?(props: FileSlotProps): unknown;\n\tlink?(props: LinkSlotProps): unknown;\n}>();\ndefineExpose({ viewer });\n\nfunction createNodeFunc<N extends TextSlotProps | FileSlotProps | LinkSlotProps>(\n\tslotFn: (props: N) => unknown,\n) {\n\treturn (\n\t\tcontainer: HTMLDivElement,\n\t\tcontent: string,\n\t\tnode: N['node'],\n\t\tonBeforeUnmount: Hook,\n\t\tonActive: Hook,\n\t\tonLoseActive: Hook,\n\t) => {\n\t\tconst app = createApp({\n\t\t\trender: () =>\n\t\t\t\tslotFn(\n\t\t\t\t\treactive({\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t\tnode,\n\t\t\t\t\t\tonActive,\n\t\t\t\t\t\tonLoseActive,\n\t\t\t\t\t}) as N,\n\t\t\t\t),\n\t\t});\n\t\tapp._context = instance.appContext;\n\t\tapp.mount(container);\n\t\tonBeforeUnmount.subscribe(app.unmount);\n\t};\n}\n\nwatch(\n\t() => props.theme,\n\t(theme) => viewer?.changeTheme(theme),\n);\nwatch(\n\t() => {\n\t\treturn {\n\t\t\tcanvas: props.canvas,\n\t\t\tattachmentDir: props.attachmentDir,\n\t\t\tattachments: props.attachments,\n\t\t};\n\t},\n\t({ canvas, attachmentDir, attachments }) =>\n\t\tviewer?.load({ canvas, attachmentDir, attachments }),\n);\n\nonMounted(() => {\n\tif (!viewerRef.value) return;\n\tconst supportedNodes = ['text', 'markdown', 'link', 'audio', 'image', 'video'] as const;\n\tconst nodeComponents: Options['nodeComponents'] = {};\n\tfor (const nodeType of supportedNodes) {\n\t\tconst slotFunc = slots[nodeType];\n\t\tif (!slotFunc) continue;\n\t\tnodeComponents[nodeType] = createNodeFunc(slotFunc as never);\n\t}\n\tviewer = new JSONCanvasViewer(\n\t\tObject.assign(props.options ?? {}, {\n\t\t\tcontainer: viewerRef.value,\n\t\t\ttheme: props.theme,\n\t\t\tcanvas: props.canvas,\n\t\t\tattachmentDir: props.attachmentDir,\n\t\t\tattachments: props.attachments,\n\t\t\tnodeComponents,\n\t\t}) as Options<T>,\n\t\tprops.modules,\n\t);\n});\n\nonUnmounted(() => {\n\tviewer?.dispose();\n\tviewer = null;\n});\n</script>\n\n<template>\n\t<section ref=\"viewerRef\" v-html=\"prerender\" style=\"max-height: 100vh; max-width: 100vw\" />\n</template>\n"],"names":["props","__props","isPrerendering","viewerRef","useTemplateRef","viewer","instance","getCurrentInstance","prerender","__temp","__restore","_withAsyncContext","renderToString","canvas","attachmentDir","attachments","options","slots","_useSlots","createNodeFunc","slotFn","container","content","node","onBeforeUnmount","onActive","onLoseActive","app","createApp","render","reactive","_context","appContext","mount","subscribe","unmount","__expose","watch","theme","changeTheme","load","onMounted","value","supportedNodes","nodeComponents","nodeType","slotFunc","JSONCanvasViewer","Object","assign","modules","onUnmounted","dispose","_createElementBlock","ref","innerHTML","_unref","style"],"mappings":"qiBA4DA,MAAMA,EAAQC,EACRC,EAAiBF,EAAME,iBAAkB,EACzCC,EAAYC,EAAe,aACjC,IAAIC,EAA8C,KAClD,MAAMC,EAAWC,IACXC,EAAYN,IACfO,EAAAC,GAAAC,EAAA,IAAMC,EAAe,CACrBC,OAAQb,EAAMa,QAAU,CAAA,EACxBC,cAAed,EAAMc,cACrBC,YAAaf,EAAMe,eAChBf,EAAMgB,4BAET,GAEGC,EAAQC,IAUd,SAASC,EACRC,GAEA,MAAO,CACNC,EACAC,EACAC,EACAC,EACAC,EACAC,KAEA,MAAMC,EAAMC,EAAU,CACrBC,OAAQ,IACPT,EACCU,EAAS,CACRR,UACAC,OACAE,WACAC,oBAIJC,EAAII,SAAWzB,EAAS0B,WACxBL,EAAIM,MAAMZ,GACVG,EAAgBU,UAAUP,EAAIQ,SAEhC,QA5BAC,EAAa,CAAE/B,WA8BfgC,EACC,IAAMrC,EAAMsC,MACXA,GAAUjC,GAAQkC,YAAYD,IAEhCD,EACC,KACQ,CACNxB,OAAQb,EAAMa,OACdC,cAAed,EAAMc,cACrBC,YAAaf,EAAMe,cAGrB,EAAGF,SAAQC,gBAAeC,iBACzBV,GAAQmC,KAAK,CAAE3B,SAAQC,gBAAeC,iBAGxC0B,EAAU,KACT,IAAKtC,EAAUuC,MAAO,OACtB,MAAMC,EAAiB,CAAC,OAAQ,WAAY,OAAQ,QAAS,QAAS,SAChEC,EAA4C,CAAA,EAClD,IAAA,MAAWC,KAAYF,EAAgB,CACtC,MAAMG,EAAW7B,EAAM4B,GAClBC,IACLF,EAAeC,GAAY1B,EAAe2B,GAC3C,CACAzC,EAAS,IAAI0C,EACZC,OAAOC,OAAOjD,EAAMgB,SAAW,CAAA,EAAI,CAClCK,UAAWlB,EAAUuC,MACrBJ,MAAOtC,EAAMsC,MACbzB,OAAQb,EAAMa,OACdC,cAAed,EAAMc,cACrBC,YAAaf,EAAMe,YACnB6B,mBAED5C,EAAMkD,WAIRC,EAAY,KACX9C,GAAQ+C,UACR/C,EAAS,mBAKTgD,EAA0F,UAAA,SAA7E,YAAJC,IAAInD,EAAYoD,UAAQC,EAAAhD,GAAWiD,MAAA,CAAA,aAAA,QAAA,YAAA"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@json-canvas-viewer/vue",
3
+ "version": "1.0.0",
4
+ "description": "An extensible web-based viewer for JSON Canvas in the form of a Vue component, easy to embed into websites.",
5
+ "keywords": [
6
+ "frontend",
7
+ "html-canvas",
8
+ "json-canvas",
9
+ "obsidian-md",
10
+ "typescript",
11
+ "vue",
12
+ "vue-component"
13
+ ],
14
+ "homepage": "https://github.com/hesprs/json-canvas-viewer",
15
+ "bugs": {
16
+ "url": "https://github.com/hesprs/json-canvas-viewer/issues"
17
+ },
18
+ "license": "MIT",
19
+ "author": {
20
+ "name": "Hēsperus",
21
+ "email": "hesprs@outlook.com"
22
+ },
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/hesprs/json-canvas-viewer.git"
26
+ },
27
+ "files": [
28
+ "./dist"
29
+ ],
30
+ "type": "module",
31
+ "sideEffects": false,
32
+ "main": "./dist/index.js",
33
+ "module": "./dist/index.js",
34
+ "types": "./dist/index.d.ts",
35
+ "exports": {
36
+ ".": {
37
+ "types": "./dist/index.d.ts",
38
+ "import": "./dist/index.js"
39
+ }
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "dependencies": {
45
+ "json-canvas-viewer": "4.0.0"
46
+ },
47
+ "devDependencies": {
48
+ "@vitejs/plugin-vue": "^6.0.4",
49
+ "vite": "^7.3.1",
50
+ "@repo/shared": "0.0.1",
51
+ "vite-plugin-json-canvas": "1.0.0"
52
+ },
53
+ "peerDependencies": {
54
+ "vue": "^3.5.29"
55
+ },
56
+ "scripts": {
57
+ "lint": "oxlint --type-aware --fix && oxfmt",
58
+ "build": "vite build",
59
+ "check": "tsc && oxfmt --check && oxlint --type-aware",
60
+ "dev": "vite"
61
+ }
62
+ }