@aicut/vue 0.4.1 → 0.4.2

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.
@@ -10,7 +10,13 @@ type __VLS_Props = {
10
10
  /** UI string overrides (English default). Reactive — swap to `localeZh` for Chinese. */
11
11
  locale?: Partial<Locale>;
12
12
  };
13
- declare const _default: import("vue").DefineComponent<__VLS_Props, {
13
+ declare var __VLS_5: {}, __VLS_11: {};
14
+ type __VLS_Slots = {} & {
15
+ headerLeft?: (props: typeof __VLS_5) => any;
16
+ } & {
17
+ headerRight?: (props: typeof __VLS_11) => any;
18
+ };
19
+ declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {
14
20
  /** Returns the underlying core API or null if not yet mounted. */
15
21
  api: () => EditorApi | null;
16
22
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
@@ -32,5 +38,11 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {
32
38
  onSelectionChange?: ((clipId: string | null) => any) | undefined;
33
39
  onError?: ((error: Error) => any) | undefined;
34
40
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
41
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
35
42
  export default _default;
43
+ type __VLS_WithSlots<T, S> = T & {
44
+ new (): {
45
+ $slots: S;
46
+ };
47
+ };
36
48
  //# sourceMappingURL=VideoEditor.vue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"VideoEditor.vue.d.ts","sourceRoot":"","sources":["../src/VideoEditor.vue"],"names":[],"mappings":"AA+FA,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,MAAM,EAEX,KAAK,OAAO,EACZ,KAAK,KAAK,EACX,MAAM,aAAa,CAAC;AAErB;;;;GAIG;AACH,KAAK,WAAW,GAAG;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,wFAAwF;IACxF,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1B,CAAC;;IAiEA,kEAAkE;eACzD,SAAS,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;AAuC3B,wBAQG"}
1
+ {"version":3,"file":"VideoEditor.vue.d.ts","sourceRoot":"","sources":["../src/VideoEditor.vue"],"names":[],"mappings":"AA+GA,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,MAAM,EAEX,KAAK,OAAO,EACZ,KAAK,KAAK,EACX,MAAM,aAAa,CAAC;AAErB;;;;GAIG;AACH,KAAK,WAAW,GAAG;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,wFAAwF;IACxF,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1B,CAAC;AA2HF,QAAA,IAAI,OAAO,IAAU,EAAE,QAAQ,IAAY,CAAE;AAC7C,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAC/C;IAAE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,CAAC;AAwBpD,QAAA,MAAM,eAAe;IA5EnB,kEAAkE;eACzD,SAAS,GAAG,IAAI;;;;;;;;;;;;;;;;;;;kFAmFzB,CAAC;wBACkB,eAAe,CAAC,OAAO,eAAe,EAAE,WAAW,CAAC;AAAzE,wBAA0E;AAQ1E,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("vue"),c=require("@aicut/core"),u=a.defineComponent({__name:"VideoEditor",props:{defaultProject:{},theme:{},locale:{}},emits:["ready","change","export","timeUpdate","play","pause","selectionChange","error"],setup(i,{expose:s,emit:p}){const l=i,n=p,r=a.ref(null);let e=null;const o=[];return a.onMounted(()=>{r.value&&(e=c.Editor.create({container:r.value,project:l.defaultProject,theme:l.theme,locale:l.locale}),o.push(e.on("change",({project:t})=>n("change",t)),e.on("export",({project:t})=>n("export",t)),e.on("time",({timeMs:t})=>n("timeUpdate",t)),e.on("play",()=>n("play")),e.on("pause",()=>n("pause")),e.on("selectionChange",({clipId:t})=>n("selectionChange",t)),e.on("error",({error:t})=>n("error",t))),n("ready",e))}),a.watch(()=>l.theme,t=>{t&&e&&e.setTheme(t)}),a.watch(()=>l.locale,t=>{t&&e&&e.setLocale(t)}),a.onBeforeUnmount(()=>{for(const t of o)t();o.length=0,e==null||e.destroy(),e=null}),s({api:()=>e}),(t,f)=>(a.openBlock(),a.createElementBlock("div",{ref_key:"host",ref:r,"data-aicut-host":""},null,512))}}),d=a.defineComponent({__name:"Timeline",props:{defaultProject:{},defaultScale:{},defaultTime:{},defaultSelectedClipId:{},showHeader:{type:Boolean},readOnly:{type:Boolean},snap:{type:Boolean},autoFit:{type:Boolean},locale:{}},emits:["seek","selectClip","scaleChange","moveClip","resizeClip","change"],setup(i,{expose:s,emit:p}){const l=i,n=p,r=a.ref(null);let e=null;return a.onMounted(()=>{r.value&&(e=c.Timeline.create({container:r.value,project:l.defaultProject,pxPerSec:l.defaultScale,time:l.defaultTime,selectedClipId:l.defaultSelectedClipId??null,showHeader:l.showHeader,readOnly:l.readOnly,snap:l.snap,autoFit:l.autoFit,locale:l.locale,onSeek:o=>n("seek",o),onSelectClip:o=>n("selectClip",o),onScaleChange:o=>n("scaleChange",o),onMoveClip:(o,t)=>n("moveClip",o,t),onResizeClip:(o,t)=>n("resizeClip",o,t),onChange:o=>n("change",o)}))}),a.watch(()=>l.locale,o=>{o&&e&&e.setLocale(o)}),a.onBeforeUnmount(()=>{e==null||e.destroy(),e=null}),s({api:()=>e}),(o,t)=>(a.openBlock(),a.createElementBlock("div",{ref_key:"host",ref:r,"data-aicut-timeline-host":"",style:{width:"100%",height:"240px"}},null,512))}});Object.defineProperty(exports,"createEmptyProject",{enumerable:!0,get:()=>c.createEmptyProject});Object.defineProperty(exports,"createId",{enumerable:!0,get:()=>c.createId});Object.defineProperty(exports,"localeEn",{enumerable:!0,get:()=>c.localeEn});Object.defineProperty(exports,"localeZh",{enumerable:!0,get:()=>c.localeZh});exports.Timeline=d;exports.VideoEditor=u;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("vue"),i=require("@aicut/core"),h=t.defineComponent({__name:"VideoEditor",props:{defaultProject:{},theme:{},locale:{}},emits:["ready","change","export","timeUpdate","play","pause","selectionChange","error"],setup(s,{expose:p,emit:d}){const a=s,n=d,c=t.ref(null);let e=null;const l=[],r=t.ref(null),u=t.ref(null);return t.onMounted(()=>{c.value&&(e=i.Editor.create({container:c.value,project:a.defaultProject,theme:a.theme,locale:a.locale}),l.push(e.on("change",({project:o})=>n("change",o)),e.on("export",({project:o})=>n("export",o)),e.on("time",({timeMs:o})=>n("timeUpdate",o)),e.on("play",()=>n("play")),e.on("pause",()=>n("pause")),e.on("selectionChange",({clipId:o})=>n("selectionChange",o)),e.on("error",({error:o})=>n("error",o))),r.value=e.headerLeft,u.value=e.headerRight,n("ready",e))}),t.watch(()=>a.theme,o=>{o&&e&&e.setTheme(o)}),t.watch(()=>a.locale,o=>{o&&e&&e.setLocale(o)}),t.onBeforeUnmount(()=>{for(const o of l)o();l.length=0,e==null||e.destroy(),e=null,r.value=null,u.value=null}),p({api:()=>e}),(o,m)=>(t.openBlock(),t.createElementBlock("div",{ref_key:"host",ref:c,"data-aicut-host":""},[r.value?(t.openBlock(),t.createBlock(t.Teleport,{key:0,to:r.value},[t.renderSlot(o.$slots,"headerLeft")],8,["to"])):t.createCommentVNode("",!0),u.value?(t.openBlock(),t.createBlock(t.Teleport,{key:1,to:u.value},[t.renderSlot(o.$slots,"headerRight")],8,["to"])):t.createCommentVNode("",!0)],512))}}),f=t.defineComponent({__name:"Timeline",props:{defaultProject:{},defaultScale:{},defaultTime:{},defaultSelectedClipId:{},showHeader:{type:Boolean},readOnly:{type:Boolean},snap:{type:Boolean},autoFit:{type:Boolean},locale:{}},emits:["seek","selectClip","scaleChange","moveClip","resizeClip","change"],setup(s,{expose:p,emit:d}){const a=s,n=d,c=t.ref(null);let e=null;return t.onMounted(()=>{c.value&&(e=i.Timeline.create({container:c.value,project:a.defaultProject,pxPerSec:a.defaultScale,time:a.defaultTime,selectedClipId:a.defaultSelectedClipId??null,showHeader:a.showHeader,readOnly:a.readOnly,snap:a.snap,autoFit:a.autoFit,locale:a.locale,onSeek:l=>n("seek",l),onSelectClip:l=>n("selectClip",l),onScaleChange:l=>n("scaleChange",l),onMoveClip:(l,r)=>n("moveClip",l,r),onResizeClip:(l,r)=>n("resizeClip",l,r),onChange:l=>n("change",l)}))}),t.watch(()=>a.locale,l=>{l&&e&&e.setLocale(l)}),t.onBeforeUnmount(()=>{e==null||e.destroy(),e=null}),p({api:()=>e}),(l,r)=>(t.openBlock(),t.createElementBlock("div",{ref_key:"host",ref:c,"data-aicut-timeline-host":"",style:{width:"100%",height:"240px"}},null,512))}});Object.defineProperty(exports,"createEmptyProject",{enumerable:!0,get:()=>i.createEmptyProject});Object.defineProperty(exports,"createId",{enumerable:!0,get:()=>i.createId});Object.defineProperty(exports,"localeEn",{enumerable:!0,get:()=>i.localeEn});Object.defineProperty(exports,"localeZh",{enumerable:!0,get:()=>i.localeZh});exports.Timeline=f;exports.VideoEditor=h;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/VideoEditor.vue","../src/Timeline.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref, watch } from \"vue\";\nimport {\n Editor,\n type EditorApi,\n type Locale,\n type Ms,\n type Project,\n type Theme,\n} from \"@aicut/core\";\n\n/**\n * Vue 3 wrapper around `@aicut/core`. Same shape as `@aicut/react`:\n * uncontrolled for project state, theme is reactive, API exposed via\n * `defineExpose` so a parent `ref` can call cut/seek/setProject/etc.\n */\nconst props = defineProps<{\n defaultProject?: Project;\n theme?: Theme;\n /** UI string overrides (English default). Reactive — swap to `localeZh` for Chinese. */\n locale?: Partial<Locale>;\n}>();\n\nconst emit = defineEmits<{\n (e: \"ready\", api: EditorApi): void;\n (e: \"change\", project: Project): void;\n (e: \"export\", project: Project): void;\n (e: \"timeUpdate\", timeMs: Ms): void;\n (e: \"play\"): void;\n (e: \"pause\"): void;\n (e: \"selectionChange\", clipId: string | null): void;\n (e: \"error\", error: Error): void;\n}>();\n\nconst host = ref<HTMLDivElement | null>(null);\nlet editor: Editor | null = null;\nconst offs: Array<() => void> = [];\n\nonMounted(() => {\n if (!host.value) return;\n editor = Editor.create({\n container: host.value,\n project: props.defaultProject,\n theme: props.theme,\n locale: props.locale,\n });\n\n offs.push(\n editor.on(\"change\", ({ project }) => emit(\"change\", project)),\n editor.on(\"export\", ({ project }) => emit(\"export\", project)),\n editor.on(\"time\", ({ timeMs }) => emit(\"timeUpdate\", timeMs)),\n editor.on(\"play\", () => emit(\"play\")),\n editor.on(\"pause\", () => emit(\"pause\")),\n editor.on(\"selectionChange\", ({ clipId }) =>\n emit(\"selectionChange\", clipId),\n ),\n editor.on(\"error\", ({ error }) => emit(\"error\", error)),\n );\n\n emit(\"ready\", editor);\n});\n\nwatch(\n () => props.theme,\n (theme) => {\n if (theme && editor) editor.setTheme(theme);\n },\n);\n\nwatch(\n () => props.locale,\n (locale) => {\n if (locale && editor) editor.setLocale(locale);\n },\n);\n\nonBeforeUnmount(() => {\n for (const off of offs) off();\n offs.length = 0;\n editor?.destroy();\n editor = null;\n});\n\ndefineExpose({\n /** Returns the underlying core API or null if not yet mounted. */\n api: (): EditorApi | null => editor,\n});\n</script>\n\n<template>\n <div ref=\"host\" data-aicut-host=\"\" />\n</template>\n","<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref, watch } from \"vue\";\nimport {\n Timeline as CoreTimeline,\n type Clip,\n type Locale,\n type Ms,\n type Project,\n} from \"@aicut/core\";\n\n/**\n * Standalone canvas Timeline wrapped for Vue 3. Same surface as the\n * React `<Timeline>`: pass `defaultProject`, drive imperatively via\n * the exposed `api()` ref.\n */\nconst props = defineProps<{\n defaultProject: Project;\n defaultScale?: number;\n defaultTime?: Ms;\n defaultSelectedClipId?: string | null;\n showHeader?: boolean;\n readOnly?: boolean;\n snap?: boolean;\n autoFit?: boolean;\n locale?: Partial<Locale>;\n}>();\n\nconst emit = defineEmits<{\n (e: \"seek\", timeMs: Ms): void;\n (e: \"selectClip\", clipId: string | null): void;\n (e: \"scaleChange\", pxPerSec: number): void;\n (e: \"moveClip\", clipId: string, opts: { start?: Ms; trackId?: string }): void;\n (\n e: \"resizeClip\",\n clipId: string,\n edits: Partial<Pick<Clip, \"in\" | \"out\" | \"start\">>,\n ): void;\n (e: \"change\", project: Project): void;\n}>();\n\nconst host = ref<HTMLDivElement | null>(null);\nlet timeline: CoreTimeline | null = null;\n\nonMounted(() => {\n if (!host.value) return;\n timeline = CoreTimeline.create({\n container: host.value,\n project: props.defaultProject,\n pxPerSec: props.defaultScale,\n time: props.defaultTime,\n selectedClipId: props.defaultSelectedClipId ?? null,\n showHeader: props.showHeader,\n readOnly: props.readOnly,\n snap: props.snap,\n autoFit: props.autoFit,\n locale: props.locale,\n onSeek: (t) => emit(\"seek\", t),\n onSelectClip: (id) => emit(\"selectClip\", id),\n onScaleChange: (s) => emit(\"scaleChange\", s),\n onMoveClip: (id, opts) => emit(\"moveClip\", id, opts),\n onResizeClip: (id, edits) => emit(\"resizeClip\", id, edits),\n onChange: (p) => emit(\"change\", p),\n });\n});\n\nwatch(\n () => props.locale,\n (locale) => {\n if (locale && timeline) timeline.setLocale(locale);\n },\n);\n\nonBeforeUnmount(() => {\n timeline?.destroy();\n timeline = null;\n});\n\ndefineExpose({\n api: (): CoreTimeline | null => timeline,\n});\n</script>\n\n<template>\n <div ref=\"host\" data-aicut-timeline-host=\"\" :style=\"{ width: '100%', height: '240px' }\" />\n</template>\n"],"names":["props","__props","emit","__emit","host","ref","editor","offs","onMounted","Editor","project","timeMs","clipId","error","watch","theme","locale","onBeforeUnmount","off","__expose","_createElementBlock","timeline","CoreTimeline","t","id","s","opts","edits","p"],"mappings":"0UAgBA,MAAMA,EAAQC,EAORC,EAAOC,EAWPC,EAAOC,EAAAA,IAA2B,IAAI,EAC5C,IAAIC,EAAwB,KAC5B,MAAMC,EAA0B,CAAA,EAEhCC,OAAAA,EAAAA,UAAU,IAAM,CACTJ,EAAK,QACVE,EAASG,EAAAA,OAAO,OAAO,CACrB,UAAWL,EAAK,MAChB,QAASJ,EAAM,eACf,MAAOA,EAAM,MACb,OAAQA,EAAM,MAAA,CACf,EAEDO,EAAK,KACHD,EAAO,GAAG,SAAU,CAAC,CAAE,QAAAI,KAAcR,EAAK,SAAUQ,CAAO,CAAC,EAC5DJ,EAAO,GAAG,SAAU,CAAC,CAAE,QAAAI,KAAcR,EAAK,SAAUQ,CAAO,CAAC,EAC5DJ,EAAO,GAAG,OAAQ,CAAC,CAAE,OAAAK,KAAaT,EAAK,aAAcS,CAAM,CAAC,EAC5DL,EAAO,GAAG,OAAQ,IAAMJ,EAAK,MAAM,CAAC,EACpCI,EAAO,GAAG,QAAS,IAAMJ,EAAK,OAAO,CAAC,EACtCI,EAAO,GAAG,kBAAmB,CAAC,CAAE,OAAAM,CAAA,IAC9BV,EAAK,kBAAmBU,CAAM,CAAA,EAEhCN,EAAO,GAAG,QAAS,CAAC,CAAE,MAAAO,KAAYX,EAAK,QAASW,CAAK,CAAC,CAAA,EAGxDX,EAAK,QAASI,CAAM,EACtB,CAAC,EAEDQ,EAAAA,MACE,IAAMd,EAAM,MACXe,GAAU,CACLA,GAAST,GAAQA,EAAO,SAASS,CAAK,CAC5C,CAAA,EAGFD,EAAAA,MACE,IAAMd,EAAM,OACXgB,GAAW,CACNA,GAAUV,GAAQA,EAAO,UAAUU,CAAM,CAC/C,CAAA,EAGFC,EAAAA,gBAAgB,IAAM,CACpB,UAAWC,KAAOX,EAAMW,EAAA,EACxBX,EAAK,OAAS,EACdD,GAAA,MAAAA,EAAQ,UACRA,EAAS,IACX,CAAC,EAEDa,EAAa,CAEX,IAAK,IAAwBb,CAAA,CAC9B,wBAICc,EAAAA,mBAAqC,MAAA,SAA5B,OAAJ,IAAIhB,EAAO,kBAAgB,EAAA,sVC3ElC,MAAMJ,EAAQC,EAYRC,EAAOC,EAaPC,EAAOC,EAAAA,IAA2B,IAAI,EAC5C,IAAIgB,EAAgC,KAEpCb,OAAAA,EAAAA,UAAU,IAAM,CACTJ,EAAK,QACViB,EAAWC,EAAAA,SAAa,OAAO,CAC7B,UAAWlB,EAAK,MAChB,QAASJ,EAAM,eACf,SAAUA,EAAM,aAChB,KAAMA,EAAM,YACZ,eAAgBA,EAAM,uBAAyB,KAC/C,WAAYA,EAAM,WAClB,SAAUA,EAAM,SAChB,KAAMA,EAAM,KACZ,QAASA,EAAM,QACf,OAAQA,EAAM,OACd,OAASuB,GAAMrB,EAAK,OAAQqB,CAAC,EAC7B,aAAeC,GAAOtB,EAAK,aAAcsB,CAAE,EAC3C,cAAgBC,GAAMvB,EAAK,cAAeuB,CAAC,EAC3C,WAAY,CAACD,EAAIE,IAASxB,EAAK,WAAYsB,EAAIE,CAAI,EACnD,aAAc,CAACF,EAAIG,IAAUzB,EAAK,aAAcsB,EAAIG,CAAK,EACzD,SAAWC,GAAM1B,EAAK,SAAU0B,CAAC,CAAA,CAClC,EACH,CAAC,EAEDd,EAAAA,MACE,IAAMd,EAAM,OACXgB,GAAW,CACNA,GAAUK,GAAUA,EAAS,UAAUL,CAAM,CACnD,CAAA,EAGFC,EAAAA,gBAAgB,IAAM,CACpBI,GAAA,MAAAA,EAAU,UACVA,EAAW,IACb,CAAC,EAEDF,EAAa,CACX,IAAK,IAA2BE,CAAA,CACjC,wBAICD,EAAAA,mBAA0F,MAAA,SAAjF,OAAJ,IAAIhB,EAAO,2BAAyB,GAAI,MAAO,CAAA,MAAA,OAAA,OAAA,OAAA,CAAA"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/VideoEditor.vue","../src/Timeline.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref, watch } from \"vue\";\nimport {\n Editor,\n type EditorApi,\n type Locale,\n type Ms,\n type Project,\n type Theme,\n} from \"@aicut/core\";\n\n/**\n * Vue 3 wrapper around `@aicut/core`. Same shape as `@aicut/react`:\n * uncontrolled for project state, theme is reactive, API exposed via\n * `defineExpose` so a parent `ref` can call cut/seek/setProject/etc.\n */\nconst props = defineProps<{\n defaultProject?: Project;\n theme?: Theme;\n /** UI string overrides (English default). Reactive — swap to `localeZh` for Chinese. */\n locale?: Partial<Locale>;\n}>();\n\nconst emit = defineEmits<{\n (e: \"ready\", api: EditorApi): void;\n (e: \"change\", project: Project): void;\n (e: \"export\", project: Project): void;\n (e: \"timeUpdate\", timeMs: Ms): void;\n (e: \"play\"): void;\n (e: \"pause\"): void;\n (e: \"selectionChange\", clipId: string | null): void;\n (e: \"error\", error: Error): void;\n}>();\n\nconst host = ref<HTMLDivElement | null>(null);\nlet editor: Editor | null = null;\nconst offs: Array<() => void> = [];\n/** Header slot DOM nodes — set after editor mount so Vue Teleports\n * have a valid target. Library renders nothing here; named slots\n * `#headerLeft` / `#headerRight` portal whatever the host provides. */\nconst headerLeftSlot = ref<HTMLElement | null>(null);\nconst headerRightSlot = ref<HTMLElement | null>(null);\n\nonMounted(() => {\n if (!host.value) return;\n editor = Editor.create({\n container: host.value,\n project: props.defaultProject,\n theme: props.theme,\n locale: props.locale,\n });\n\n offs.push(\n editor.on(\"change\", ({ project }) => emit(\"change\", project)),\n editor.on(\"export\", ({ project }) => emit(\"export\", project)),\n editor.on(\"time\", ({ timeMs }) => emit(\"timeUpdate\", timeMs)),\n editor.on(\"play\", () => emit(\"play\")),\n editor.on(\"pause\", () => emit(\"pause\")),\n editor.on(\"selectionChange\", ({ clipId }) =>\n emit(\"selectionChange\", clipId),\n ),\n editor.on(\"error\", ({ error }) => emit(\"error\", error)),\n );\n\n headerLeftSlot.value = editor.headerLeft;\n headerRightSlot.value = editor.headerRight;\n emit(\"ready\", editor);\n});\n\nwatch(\n () => props.theme,\n (theme) => {\n if (theme && editor) editor.setTheme(theme);\n },\n);\n\nwatch(\n () => props.locale,\n (locale) => {\n if (locale && editor) editor.setLocale(locale);\n },\n);\n\nonBeforeUnmount(() => {\n for (const off of offs) off();\n offs.length = 0;\n editor?.destroy();\n editor = null;\n headerLeftSlot.value = null;\n headerRightSlot.value = null;\n});\n\ndefineExpose({\n /** Returns the underlying core API or null if not yet mounted. */\n api: (): EditorApi | null => editor,\n});\n</script>\n\n<template>\n <div ref=\"host\" data-aicut-host=\"\">\n <Teleport v-if=\"headerLeftSlot\" :to=\"headerLeftSlot\">\n <slot name=\"headerLeft\" />\n </Teleport>\n <Teleport v-if=\"headerRightSlot\" :to=\"headerRightSlot\">\n <slot name=\"headerRight\" />\n </Teleport>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref, watch } from \"vue\";\nimport {\n Timeline as CoreTimeline,\n type Clip,\n type Locale,\n type Ms,\n type Project,\n} from \"@aicut/core\";\n\n/**\n * Standalone canvas Timeline wrapped for Vue 3. Same surface as the\n * React `<Timeline>`: pass `defaultProject`, drive imperatively via\n * the exposed `api()` ref.\n */\nconst props = defineProps<{\n defaultProject: Project;\n defaultScale?: number;\n defaultTime?: Ms;\n defaultSelectedClipId?: string | null;\n showHeader?: boolean;\n readOnly?: boolean;\n snap?: boolean;\n autoFit?: boolean;\n locale?: Partial<Locale>;\n}>();\n\nconst emit = defineEmits<{\n (e: \"seek\", timeMs: Ms): void;\n (e: \"selectClip\", clipId: string | null): void;\n (e: \"scaleChange\", pxPerSec: number): void;\n (e: \"moveClip\", clipId: string, opts: { start?: Ms; trackId?: string }): void;\n (\n e: \"resizeClip\",\n clipId: string,\n edits: Partial<Pick<Clip, \"in\" | \"out\" | \"start\">>,\n ): void;\n (e: \"change\", project: Project): void;\n}>();\n\nconst host = ref<HTMLDivElement | null>(null);\nlet timeline: CoreTimeline | null = null;\n\nonMounted(() => {\n if (!host.value) return;\n timeline = CoreTimeline.create({\n container: host.value,\n project: props.defaultProject,\n pxPerSec: props.defaultScale,\n time: props.defaultTime,\n selectedClipId: props.defaultSelectedClipId ?? null,\n showHeader: props.showHeader,\n readOnly: props.readOnly,\n snap: props.snap,\n autoFit: props.autoFit,\n locale: props.locale,\n onSeek: (t) => emit(\"seek\", t),\n onSelectClip: (id) => emit(\"selectClip\", id),\n onScaleChange: (s) => emit(\"scaleChange\", s),\n onMoveClip: (id, opts) => emit(\"moveClip\", id, opts),\n onResizeClip: (id, edits) => emit(\"resizeClip\", id, edits),\n onChange: (p) => emit(\"change\", p),\n });\n});\n\nwatch(\n () => props.locale,\n (locale) => {\n if (locale && timeline) timeline.setLocale(locale);\n },\n);\n\nonBeforeUnmount(() => {\n timeline?.destroy();\n timeline = null;\n});\n\ndefineExpose({\n api: (): CoreTimeline | null => timeline,\n});\n</script>\n\n<template>\n <div ref=\"host\" data-aicut-timeline-host=\"\" :style=\"{ width: '100%', height: '240px' }\" />\n</template>\n"],"names":["props","__props","emit","__emit","host","ref","editor","offs","headerLeftSlot","headerRightSlot","onMounted","Editor","project","timeMs","clipId","error","watch","theme","locale","onBeforeUnmount","off","__expose","_createElementBlock","_createBlock","_Teleport","_renderSlot","_ctx","timeline","CoreTimeline","t","id","s","opts","edits","p"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { defineComponent as p, ref as u, onMounted as d, watch as s, onBeforeUnmount as h, openBlock as m, createElementBlock as f } from "vue";
2
- import { Editor as C, Timeline as y } from "@aicut/core";
3
- import { createEmptyProject as B, createId as E, localeEn as P, localeZh as T } from "@aicut/core";
4
- const v = /* @__PURE__ */ p({
1
+ import { defineComponent as g, ref as i, onMounted as v, watch as h, onBeforeUnmount as _, openBlock as s, createElementBlock as S, createBlock as f, Teleport as m, renderSlot as C, createCommentVNode as y } from "vue";
2
+ import { Editor as k, Timeline as x } from "@aicut/core";
3
+ import { createEmptyProject as I, createId as R, localeEn as z, localeZh as F } from "@aicut/core";
4
+ const E = /* @__PURE__ */ g({
5
5
  __name: "VideoEditor",
6
6
  props: {
7
7
  defaultProject: {},
@@ -9,13 +9,13 @@ const v = /* @__PURE__ */ p({
9
9
  locale: {}
10
10
  },
11
11
  emits: ["ready", "change", "export", "timeUpdate", "play", "pause", "selectionChange", "error"],
12
- setup(r, { expose: c, emit: i }) {
13
- const l = r, a = i, n = u(null);
12
+ setup(p, { expose: u, emit: d }) {
13
+ const l = p, a = d, r = i(null);
14
14
  let e = null;
15
- const o = [];
16
- return d(() => {
17
- n.value && (e = C.create({
18
- container: n.value,
15
+ const o = [], n = i(null), c = i(null);
16
+ return v(() => {
17
+ r.value && (e = k.create({
18
+ container: r.value,
19
19
  project: l.defaultProject,
20
20
  theme: l.theme,
21
21
  locale: l.locale
@@ -30,30 +30,43 @@ const v = /* @__PURE__ */ p({
30
30
  ({ clipId: t }) => a("selectionChange", t)
31
31
  ),
32
32
  e.on("error", ({ error: t }) => a("error", t))
33
- ), a("ready", e));
34
- }), s(
33
+ ), n.value = e.headerLeft, c.value = e.headerRight, a("ready", e));
34
+ }), h(
35
35
  () => l.theme,
36
36
  (t) => {
37
37
  t && e && e.setTheme(t);
38
38
  }
39
- ), s(
39
+ ), h(
40
40
  () => l.locale,
41
41
  (t) => {
42
42
  t && e && e.setLocale(t);
43
43
  }
44
- ), h(() => {
44
+ ), _(() => {
45
45
  for (const t of o) t();
46
- o.length = 0, e == null || e.destroy(), e = null;
47
- }), c({
46
+ o.length = 0, e == null || e.destroy(), e = null, n.value = null, c.value = null;
47
+ }), u({
48
48
  /** Returns the underlying core API or null if not yet mounted. */
49
49
  api: () => e
50
- }), (t, g) => (m(), f("div", {
50
+ }), (t, B) => (s(), S("div", {
51
51
  ref_key: "host",
52
- ref: n,
52
+ ref: r,
53
53
  "data-aicut-host": ""
54
- }, null, 512));
54
+ }, [
55
+ n.value ? (s(), f(m, {
56
+ key: 0,
57
+ to: n.value
58
+ }, [
59
+ C(t.$slots, "headerLeft")
60
+ ], 8, ["to"])) : y("", !0),
61
+ c.value ? (s(), f(m, {
62
+ key: 1,
63
+ to: c.value
64
+ }, [
65
+ C(t.$slots, "headerRight")
66
+ ], 8, ["to"])) : y("", !0)
67
+ ], 512));
55
68
  }
56
- }), S = /* @__PURE__ */ p({
69
+ }), P = /* @__PURE__ */ g({
57
70
  __name: "Timeline",
58
71
  props: {
59
72
  defaultProject: {},
@@ -67,12 +80,12 @@ const v = /* @__PURE__ */ p({
67
80
  locale: {}
68
81
  },
69
82
  emits: ["seek", "selectClip", "scaleChange", "moveClip", "resizeClip", "change"],
70
- setup(r, { expose: c, emit: i }) {
71
- const l = r, a = i, n = u(null);
83
+ setup(p, { expose: u, emit: d }) {
84
+ const l = p, a = d, r = i(null);
72
85
  let e = null;
73
- return d(() => {
74
- n.value && (e = y.create({
75
- container: n.value,
86
+ return v(() => {
87
+ r.value && (e = x.create({
88
+ container: r.value,
76
89
  project: l.defaultProject,
77
90
  pxPerSec: l.defaultScale,
78
91
  time: l.defaultTime,
@@ -85,33 +98,33 @@ const v = /* @__PURE__ */ p({
85
98
  onSeek: (o) => a("seek", o),
86
99
  onSelectClip: (o) => a("selectClip", o),
87
100
  onScaleChange: (o) => a("scaleChange", o),
88
- onMoveClip: (o, t) => a("moveClip", o, t),
89
- onResizeClip: (o, t) => a("resizeClip", o, t),
101
+ onMoveClip: (o, n) => a("moveClip", o, n),
102
+ onResizeClip: (o, n) => a("resizeClip", o, n),
90
103
  onChange: (o) => a("change", o)
91
104
  }));
92
- }), s(
105
+ }), h(
93
106
  () => l.locale,
94
107
  (o) => {
95
108
  o && e && e.setLocale(o);
96
109
  }
97
- ), h(() => {
110
+ ), _(() => {
98
111
  e == null || e.destroy(), e = null;
99
- }), c({
112
+ }), u({
100
113
  api: () => e
101
- }), (o, t) => (m(), f("div", {
114
+ }), (o, n) => (s(), S("div", {
102
115
  ref_key: "host",
103
- ref: n,
116
+ ref: r,
104
117
  "data-aicut-timeline-host": "",
105
118
  style: { width: "100%", height: "240px" }
106
119
  }, null, 512));
107
120
  }
108
121
  });
109
122
  export {
110
- S as Timeline,
111
- v as VideoEditor,
112
- B as createEmptyProject,
113
- E as createId,
114
- P as localeEn,
115
- T as localeZh
123
+ P as Timeline,
124
+ E as VideoEditor,
125
+ I as createEmptyProject,
126
+ R as createId,
127
+ z as localeEn,
128
+ F as localeZh
116
129
  };
117
130
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/VideoEditor.vue","../src/Timeline.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref, watch } from \"vue\";\nimport {\n Editor,\n type EditorApi,\n type Locale,\n type Ms,\n type Project,\n type Theme,\n} from \"@aicut/core\";\n\n/**\n * Vue 3 wrapper around `@aicut/core`. Same shape as `@aicut/react`:\n * uncontrolled for project state, theme is reactive, API exposed via\n * `defineExpose` so a parent `ref` can call cut/seek/setProject/etc.\n */\nconst props = defineProps<{\n defaultProject?: Project;\n theme?: Theme;\n /** UI string overrides (English default). Reactive — swap to `localeZh` for Chinese. */\n locale?: Partial<Locale>;\n}>();\n\nconst emit = defineEmits<{\n (e: \"ready\", api: EditorApi): void;\n (e: \"change\", project: Project): void;\n (e: \"export\", project: Project): void;\n (e: \"timeUpdate\", timeMs: Ms): void;\n (e: \"play\"): void;\n (e: \"pause\"): void;\n (e: \"selectionChange\", clipId: string | null): void;\n (e: \"error\", error: Error): void;\n}>();\n\nconst host = ref<HTMLDivElement | null>(null);\nlet editor: Editor | null = null;\nconst offs: Array<() => void> = [];\n\nonMounted(() => {\n if (!host.value) return;\n editor = Editor.create({\n container: host.value,\n project: props.defaultProject,\n theme: props.theme,\n locale: props.locale,\n });\n\n offs.push(\n editor.on(\"change\", ({ project }) => emit(\"change\", project)),\n editor.on(\"export\", ({ project }) => emit(\"export\", project)),\n editor.on(\"time\", ({ timeMs }) => emit(\"timeUpdate\", timeMs)),\n editor.on(\"play\", () => emit(\"play\")),\n editor.on(\"pause\", () => emit(\"pause\")),\n editor.on(\"selectionChange\", ({ clipId }) =>\n emit(\"selectionChange\", clipId),\n ),\n editor.on(\"error\", ({ error }) => emit(\"error\", error)),\n );\n\n emit(\"ready\", editor);\n});\n\nwatch(\n () => props.theme,\n (theme) => {\n if (theme && editor) editor.setTheme(theme);\n },\n);\n\nwatch(\n () => props.locale,\n (locale) => {\n if (locale && editor) editor.setLocale(locale);\n },\n);\n\nonBeforeUnmount(() => {\n for (const off of offs) off();\n offs.length = 0;\n editor?.destroy();\n editor = null;\n});\n\ndefineExpose({\n /** Returns the underlying core API or null if not yet mounted. */\n api: (): EditorApi | null => editor,\n});\n</script>\n\n<template>\n <div ref=\"host\" data-aicut-host=\"\" />\n</template>\n","<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref, watch } from \"vue\";\nimport {\n Timeline as CoreTimeline,\n type Clip,\n type Locale,\n type Ms,\n type Project,\n} from \"@aicut/core\";\n\n/**\n * Standalone canvas Timeline wrapped for Vue 3. Same surface as the\n * React `<Timeline>`: pass `defaultProject`, drive imperatively via\n * the exposed `api()` ref.\n */\nconst props = defineProps<{\n defaultProject: Project;\n defaultScale?: number;\n defaultTime?: Ms;\n defaultSelectedClipId?: string | null;\n showHeader?: boolean;\n readOnly?: boolean;\n snap?: boolean;\n autoFit?: boolean;\n locale?: Partial<Locale>;\n}>();\n\nconst emit = defineEmits<{\n (e: \"seek\", timeMs: Ms): void;\n (e: \"selectClip\", clipId: string | null): void;\n (e: \"scaleChange\", pxPerSec: number): void;\n (e: \"moveClip\", clipId: string, opts: { start?: Ms; trackId?: string }): void;\n (\n e: \"resizeClip\",\n clipId: string,\n edits: Partial<Pick<Clip, \"in\" | \"out\" | \"start\">>,\n ): void;\n (e: \"change\", project: Project): void;\n}>();\n\nconst host = ref<HTMLDivElement | null>(null);\nlet timeline: CoreTimeline | null = null;\n\nonMounted(() => {\n if (!host.value) return;\n timeline = CoreTimeline.create({\n container: host.value,\n project: props.defaultProject,\n pxPerSec: props.defaultScale,\n time: props.defaultTime,\n selectedClipId: props.defaultSelectedClipId ?? null,\n showHeader: props.showHeader,\n readOnly: props.readOnly,\n snap: props.snap,\n autoFit: props.autoFit,\n locale: props.locale,\n onSeek: (t) => emit(\"seek\", t),\n onSelectClip: (id) => emit(\"selectClip\", id),\n onScaleChange: (s) => emit(\"scaleChange\", s),\n onMoveClip: (id, opts) => emit(\"moveClip\", id, opts),\n onResizeClip: (id, edits) => emit(\"resizeClip\", id, edits),\n onChange: (p) => emit(\"change\", p),\n });\n});\n\nwatch(\n () => props.locale,\n (locale) => {\n if (locale && timeline) timeline.setLocale(locale);\n },\n);\n\nonBeforeUnmount(() => {\n timeline?.destroy();\n timeline = null;\n});\n\ndefineExpose({\n api: (): CoreTimeline | null => timeline,\n});\n</script>\n\n<template>\n <div ref=\"host\" data-aicut-timeline-host=\"\" :style=\"{ width: '100%', height: '240px' }\" />\n</template>\n"],"names":["props","__props","emit","__emit","host","ref","editor","offs","onMounted","Editor","project","timeMs","clipId","error","watch","theme","locale","onBeforeUnmount","off","__expose","_createElementBlock","timeline","CoreTimeline","t","id","s","opts","edits","p"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/VideoEditor.vue","../src/Timeline.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref, watch } from \"vue\";\nimport {\n Editor,\n type EditorApi,\n type Locale,\n type Ms,\n type Project,\n type Theme,\n} from \"@aicut/core\";\n\n/**\n * Vue 3 wrapper around `@aicut/core`. Same shape as `@aicut/react`:\n * uncontrolled for project state, theme is reactive, API exposed via\n * `defineExpose` so a parent `ref` can call cut/seek/setProject/etc.\n */\nconst props = defineProps<{\n defaultProject?: Project;\n theme?: Theme;\n /** UI string overrides (English default). Reactive — swap to `localeZh` for Chinese. */\n locale?: Partial<Locale>;\n}>();\n\nconst emit = defineEmits<{\n (e: \"ready\", api: EditorApi): void;\n (e: \"change\", project: Project): void;\n (e: \"export\", project: Project): void;\n (e: \"timeUpdate\", timeMs: Ms): void;\n (e: \"play\"): void;\n (e: \"pause\"): void;\n (e: \"selectionChange\", clipId: string | null): void;\n (e: \"error\", error: Error): void;\n}>();\n\nconst host = ref<HTMLDivElement | null>(null);\nlet editor: Editor | null = null;\nconst offs: Array<() => void> = [];\n/** Header slot DOM nodes — set after editor mount so Vue Teleports\n * have a valid target. Library renders nothing here; named slots\n * `#headerLeft` / `#headerRight` portal whatever the host provides. */\nconst headerLeftSlot = ref<HTMLElement | null>(null);\nconst headerRightSlot = ref<HTMLElement | null>(null);\n\nonMounted(() => {\n if (!host.value) return;\n editor = Editor.create({\n container: host.value,\n project: props.defaultProject,\n theme: props.theme,\n locale: props.locale,\n });\n\n offs.push(\n editor.on(\"change\", ({ project }) => emit(\"change\", project)),\n editor.on(\"export\", ({ project }) => emit(\"export\", project)),\n editor.on(\"time\", ({ timeMs }) => emit(\"timeUpdate\", timeMs)),\n editor.on(\"play\", () => emit(\"play\")),\n editor.on(\"pause\", () => emit(\"pause\")),\n editor.on(\"selectionChange\", ({ clipId }) =>\n emit(\"selectionChange\", clipId),\n ),\n editor.on(\"error\", ({ error }) => emit(\"error\", error)),\n );\n\n headerLeftSlot.value = editor.headerLeft;\n headerRightSlot.value = editor.headerRight;\n emit(\"ready\", editor);\n});\n\nwatch(\n () => props.theme,\n (theme) => {\n if (theme && editor) editor.setTheme(theme);\n },\n);\n\nwatch(\n () => props.locale,\n (locale) => {\n if (locale && editor) editor.setLocale(locale);\n },\n);\n\nonBeforeUnmount(() => {\n for (const off of offs) off();\n offs.length = 0;\n editor?.destroy();\n editor = null;\n headerLeftSlot.value = null;\n headerRightSlot.value = null;\n});\n\ndefineExpose({\n /** Returns the underlying core API or null if not yet mounted. */\n api: (): EditorApi | null => editor,\n});\n</script>\n\n<template>\n <div ref=\"host\" data-aicut-host=\"\">\n <Teleport v-if=\"headerLeftSlot\" :to=\"headerLeftSlot\">\n <slot name=\"headerLeft\" />\n </Teleport>\n <Teleport v-if=\"headerRightSlot\" :to=\"headerRightSlot\">\n <slot name=\"headerRight\" />\n </Teleport>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref, watch } from \"vue\";\nimport {\n Timeline as CoreTimeline,\n type Clip,\n type Locale,\n type Ms,\n type Project,\n} from \"@aicut/core\";\n\n/**\n * Standalone canvas Timeline wrapped for Vue 3. Same surface as the\n * React `<Timeline>`: pass `defaultProject`, drive imperatively via\n * the exposed `api()` ref.\n */\nconst props = defineProps<{\n defaultProject: Project;\n defaultScale?: number;\n defaultTime?: Ms;\n defaultSelectedClipId?: string | null;\n showHeader?: boolean;\n readOnly?: boolean;\n snap?: boolean;\n autoFit?: boolean;\n locale?: Partial<Locale>;\n}>();\n\nconst emit = defineEmits<{\n (e: \"seek\", timeMs: Ms): void;\n (e: \"selectClip\", clipId: string | null): void;\n (e: \"scaleChange\", pxPerSec: number): void;\n (e: \"moveClip\", clipId: string, opts: { start?: Ms; trackId?: string }): void;\n (\n e: \"resizeClip\",\n clipId: string,\n edits: Partial<Pick<Clip, \"in\" | \"out\" | \"start\">>,\n ): void;\n (e: \"change\", project: Project): void;\n}>();\n\nconst host = ref<HTMLDivElement | null>(null);\nlet timeline: CoreTimeline | null = null;\n\nonMounted(() => {\n if (!host.value) return;\n timeline = CoreTimeline.create({\n container: host.value,\n project: props.defaultProject,\n pxPerSec: props.defaultScale,\n time: props.defaultTime,\n selectedClipId: props.defaultSelectedClipId ?? null,\n showHeader: props.showHeader,\n readOnly: props.readOnly,\n snap: props.snap,\n autoFit: props.autoFit,\n locale: props.locale,\n onSeek: (t) => emit(\"seek\", t),\n onSelectClip: (id) => emit(\"selectClip\", id),\n onScaleChange: (s) => emit(\"scaleChange\", s),\n onMoveClip: (id, opts) => emit(\"moveClip\", id, opts),\n onResizeClip: (id, edits) => emit(\"resizeClip\", id, edits),\n onChange: (p) => emit(\"change\", p),\n });\n});\n\nwatch(\n () => props.locale,\n (locale) => {\n if (locale && timeline) timeline.setLocale(locale);\n },\n);\n\nonBeforeUnmount(() => {\n timeline?.destroy();\n timeline = null;\n});\n\ndefineExpose({\n api: (): CoreTimeline | null => timeline,\n});\n</script>\n\n<template>\n <div ref=\"host\" data-aicut-timeline-host=\"\" :style=\"{ width: '100%', height: '240px' }\" />\n</template>\n"],"names":["props","__props","emit","__emit","host","ref","editor","offs","headerLeftSlot","headerRightSlot","onMounted","Editor","project","timeMs","clipId","error","watch","theme","locale","onBeforeUnmount","off","__expose","_createElementBlock","_createBlock","_Teleport","_renderSlot","_ctx","timeline","CoreTimeline","t","id","s","opts","edits","p"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aicut/vue",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Vue 3 wrapper for the AiCut video editor + lighting picker — thin declarative shells over @aicut/core.",
5
5
  "license": "MIT",
6
6
  "author": "ziqiang <ziqiangytu@gmail.com>",
@@ -60,7 +60,7 @@
60
60
  "README.md"
61
61
  ],
62
62
  "dependencies": {
63
- "@aicut/core": "0.4.1"
63
+ "@aicut/core": "0.4.2"
64
64
  },
65
65
  "peerDependencies": {
66
66
  "vue": "^3.4.0"