@moda-editor/vue 0.3.0 → 0.3.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.
@@ -30,6 +30,14 @@ const props = defineProps({
30
30
 
31
31
  const { state } = useEditorState(props.editor);
32
32
 
33
+ // editor의 비-state 크롬(editable/ariaLabel/placeholder)은 state 참조를
34
+ // 바꾸지 않는 notify로만 갱신 신호가 온다 — state.value를 먼저 읽어
35
+ // notify마다 재평가되도록 의존을 등록하고 실제 프로퍼티 값을 반환한다.
36
+ // 값이 같으면 computed가 downstream 트리거를 스킵해 비용이 없다
37
+ const editable = computed(() => (state.value, props.editor.editable));
38
+ const ariaLabel = computed(() => (state.value, props.editor.ariaLabel));
39
+ const placeholder = computed(() => (state.value, props.editor.placeholder));
40
+
33
41
  // doc 참조가 바뀔 때만 RenderNode 배열을 재생성 — selection-only
34
42
  // 변경이면 같은 배열이라 자식 vnode가 그대로 스킵된다
35
43
  let cachedDoc: DocNode | null = null;
@@ -74,17 +82,17 @@ onBeforeUnmount(() => binding?.unbind());
74
82
  </script>
75
83
 
76
84
  <template>
77
- <div class="me-root" :data-me-readonly="editor.editable ? undefined : ''">
85
+ <div class="me-root" :data-me-readonly="editable ? undefined : ''">
78
86
  <div
79
87
  ref="editableEl"
80
88
  class="me-editor"
81
89
  data-me-path=""
82
90
  role="textbox"
83
91
  aria-multiline="true"
84
- :aria-label="editor.ariaLabel"
85
- :data-me-placeholder="editor.placeholder"
86
- :aria-readonly="editor.editable ? undefined : true"
87
- :contenteditable="editor.editable"
92
+ :aria-label="ariaLabel"
93
+ :data-me-placeholder="placeholder"
94
+ :aria-readonly="editable ? undefined : true"
95
+ :contenteditable="editable"
88
96
  >
89
97
  <EditorNode
90
98
  v-for="n in nodes"
@@ -1,5 +1,5 @@
1
1
  import { createApp, defineComponent, h, nextTick } from "vue";
2
- import { runEditorConformance, runWidgetConformance, } from "@moda-editor/core/conformance";
2
+ import { runEditorConformance, runWidgetConformance, } from "@moda-editor/testkit";
3
3
  import { WidgetCore } from "@moda-editor/core";
4
4
  import WidgetView from "./WidgetView.vue";
5
5
  import EditorView from "./EditorView.vue";
@@ -1 +1 @@
1
- {"version":3,"file":"conformance.test.js","sourceRoot":"","sources":["../src/conformance.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC9D,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAE1C,uDAAuD;AACvD,MAAM,YAAY,GAAG,eAAe,CAAC;IACnC,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;IACjD,MAAM;QACJ,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE;YAC3C,MAAM,CACH,IAAI,CAAC,IAAyC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CACvE;YACD,sCAAsC;YACtC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC;SACtC,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC;AAEH,uDAAuD;AACvD,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAC1C,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACzC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,SAAS,CAAC,UAAU,EAAE;QAChC,MAAM;QACN,WAAW,EAAE,IAAI,CAAC,WAAW;KACrB,CAAC,CAAC;IACZ,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACd,OAAO;QACL,EAAE;QACF,KAAK,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE;QACvB,OAAO,EAAE,GAAG,EAAE;YACZ,GAAG,CAAC,OAAO,EAAE,CAAC;YACd,EAAE,CAAC,MAAM,EAAE,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,oDAAoD;AACpD,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE;IAC3D,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACzC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,SAAS;QACrB,CAAC,CAAC,MAAM,CAAC,WAAW,CAChB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;aACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;aAC3B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CACjC;QACH,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,GAAG,GAAG,SAAS,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAW,CAAC,CAAC;IACzE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACd,OAAO;QACL,EAAE;QACF,KAAK,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE;QACvB,OAAO,EAAE,GAAG,EAAE;YACZ,GAAG,CAAC,OAAO,EAAE,CAAC;YACd,EAAE,CAAC,MAAM,EAAE,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"conformance.test.js","sourceRoot":"","sources":["../src/conformance.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC9D,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAE1C,uDAAuD;AACvD,MAAM,YAAY,GAAG,eAAe,CAAC;IACnC,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;IACjD,MAAM;QACJ,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE;YAC3C,MAAM,CACH,IAAI,CAAC,IAAyC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CACvE;YACD,sCAAsC;YACtC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC;SACtC,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC;AAEH,uDAAuD;AACvD,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAC1C,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACzC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,SAAS,CAAC,UAAU,EAAE;QAChC,MAAM;QACN,WAAW,EAAE,IAAI,CAAC,WAAW;KACrB,CAAC,CAAC;IACZ,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACd,OAAO;QACL,EAAE;QACF,KAAK,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE;QACvB,OAAO,EAAE,GAAG,EAAE;YACZ,GAAG,CAAC,OAAO,EAAE,CAAC;YACd,EAAE,CAAC,MAAM,EAAE,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,oDAAoD;AACpD,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE;IAC3D,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACzC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,SAAS;QACrB,CAAC,CAAC,MAAM,CAAC,WAAW,CAChB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;aACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;aAC3B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CACjC;QACH,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,GAAG,GAAG,SAAS,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAW,CAAC,CAAC;IACzE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACd,OAAO;QACL,EAAE;QACF,KAAK,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE;QACvB,OAAO,EAAE,GAAG,EAAE;YACZ,GAAG,CAAC,OAAO,EAAE,CAAC;YACd,EAAE,CAAC,MAAM,EAAE,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useEditor.d.ts","sourceRoot":"","sources":["../src/useEditor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAEtC,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE5E,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IAC/B,WAAW,IAAI,IAAI,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,aAAkB,GAAG,eAAe,CAsBtE;AAED,kCAAkC;AAClC,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG;IAC9C,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IAC/B,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB,CAOA"}
1
+ {"version":3,"file":"useEditor.d.ts","sourceRoot":"","sources":["../src/useEditor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAEtC,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE5E,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IAC/B,WAAW,IAAI,IAAI,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,aAAkB,GAAG,eAAe,CAsBtE;AAED,kCAAkC;AAClC,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG;IAC9C,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IAC/B,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB,CAWA"}
package/dist/useEditor.js CHANGED
@@ -1,4 +1,4 @@
1
- import { onScopeDispose, shallowRef, toValue, watch } from "vue";
1
+ import { onScopeDispose, shallowRef, toValue, triggerRef, watch } from "vue";
2
2
  import { createEditor, normalizeDoc } from "@moda-editor/core";
3
3
  /**
4
4
  * Vue 3 어댑터 composable — Editor 생성 + 불변 state를 ShallowRef로 구독.
@@ -35,6 +35,10 @@ export function useEditorState(editor) {
35
35
  const state = shallowRef(editor.state);
36
36
  const unsubscribe = editor.subscribe(() => {
37
37
  state.value = editor.state;
38
+ // shallowRef는 같은 참조면 트리거를 스킵 — editor.setEditable처럼
39
+ // state를 바꾸지 않는 notify도 크롬(contenteditable/aria) 갱신이
40
+ // 필요하므로 강제 트리거해 computed/렌더를 다시 평가한다
41
+ triggerRef(state);
38
42
  });
39
43
  onScopeDispose(unsubscribe, true);
40
44
  return { state: state, unsubscribe };
@@ -1 +1 @@
1
- {"version":3,"file":"useEditor.js","sourceRoot":"","sources":["../src/useEditor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC;AAEjE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAW/D;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,UAAyB,EAAE;IACnD,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACtD,iDAAiD;IACjD,kDAAkD;IAClD,cAAc,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;IAE7C,4CAA4C;IAC5C,oCAAoC;IACpC,IAAI,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjD,KAAK,CACH,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAC1B,CAAC,GAAG,EAAE,EAAE;QACN,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;QAC9D,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO;QAC/B,SAAS,GAAG,IAAI,CAAC;QACjB,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9C,CAAC,CACF,CAAC;IAEF,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;AACxC,CAAC;AAED,kCAAkC;AAClC,MAAM,UAAU,cAAc,CAAC,MAAc;IAI3C,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,WAAW,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE;QACxC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC7B,CAAC,CAAC,CAAC;IACH,cAAc,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAClC,OAAO,EAAE,KAAK,EAAE,KAAgC,EAAE,WAAW,EAAE,CAAC;AAClE,CAAC"}
1
+ {"version":3,"file":"useEditor.js","sourceRoot":"","sources":["../src/useEditor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC;AAE7E,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAW/D;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,UAAyB,EAAE;IACnD,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACtD,iDAAiD;IACjD,kDAAkD;IAClD,cAAc,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;IAE7C,4CAA4C;IAC5C,oCAAoC;IACpC,IAAI,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjD,KAAK,CACH,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAC1B,CAAC,GAAG,EAAE,EAAE;QACN,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;QAC9D,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO;QAC/B,SAAS,GAAG,IAAI,CAAC;QACjB,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9C,CAAC,CACF,CAAC;IAEF,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;AACxC,CAAC;AAED,kCAAkC;AAClC,MAAM,UAAU,cAAc,CAAC,MAAc;IAI3C,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,WAAW,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE;QACxC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,oDAAoD;QACpD,qDAAqD;QACrD,qCAAqC;QACrC,UAAU,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;IACH,cAAc,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAClC,OAAO,EAAE,KAAK,EAAE,KAAgC,EAAE,WAAW,EAAE,CAAC;AAClE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moda-editor/vue",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Vue 3 adapter for @moda-editor — useWidget + WidgetView",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -34,7 +34,7 @@
34
34
  "library"
35
35
  ],
36
36
  "dependencies": {
37
- "@moda-editor/core": "0.3.0"
37
+ "@moda-editor/core": "0.3.2"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "vue": ">=3.3.0"
@@ -44,7 +44,8 @@
44
44
  "happy-dom": "^20.14.5",
45
45
  "typescript": "~5.9.2",
46
46
  "vitest": "^3.2.7",
47
- "vue": "^3.5.0"
47
+ "vue": "^3.5.0",
48
+ "@moda-editor/testkit": "0.3.2"
48
49
  },
49
50
  "scripts": {
50
51
  "build": "tsc -p tsconfig.json && cp src/styles.css src/*.vue dist/",