@hankchen/canvas-editor-vue 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/canvas/CanvasSurface.d.ts +28 -1
  2. package/dist/canvas/{ContentTypePill.d.ts → EditOverlayToolbar.d.ts} +19 -0
  3. package/dist/canvas/TextEditingOverlay.d.ts +31 -3
  4. package/dist/canvas/index.d.ts +1 -1
  5. package/dist/canvas/useTextEditing.d.ts +30 -8
  6. package/dist/{canvas-C70NSsoF.js → canvas-DqQislJ_.js} +813 -434
  7. package/dist/canvas.js +2 -2
  8. package/dist/index.js +15 -14
  9. package/dist/{layer-panel-BEcT9HhJ.js → layer-panel-DskyCgF5.js} +10 -10
  10. package/dist/layer-panel.js +1 -1
  11. package/dist/panel-theme.css +24 -0
  12. package/dist/popupPosition-Ck5Gsvjy.js +526 -0
  13. package/dist/property-panel/PropertyField.d.ts +6 -0
  14. package/dist/property-panel/fieldSchema.d.ts +7 -1
  15. package/dist/property-panel/fields/ImageSrcField.d.ts +5 -1
  16. package/dist/property-panel/fields/ResourceValueField.d.ts +19 -0
  17. package/dist/property-panel/fields/TextareaField.d.ts +1 -0
  18. package/dist/property-panel/fields/ValueTypeSegmented.d.ts +3 -1
  19. package/dist/property-panel/index.d.ts +5 -3
  20. package/dist/property-panel/usePropertyPanel.d.ts +16 -4
  21. package/dist/{property-panel-C2etsIhF.js → property-panel-B32ZBQdf.js} +472 -376
  22. package/dist/property-panel.js +3 -2
  23. package/dist/resourceTemplate-cdcQtp9a.js +246 -0
  24. package/dist/shared/ExpressionPathPicker.d.ts +25 -0
  25. package/dist/shared/completion.d.ts +40 -16
  26. package/dist/shared/expressionContext.d.ts +2 -2
  27. package/dist/shared/index.d.ts +14 -1
  28. package/dist/shared/mergeKey.d.ts +2 -0
  29. package/dist/shared/pathPickerModel.d.ts +11 -0
  30. package/dist/shared/popupPosition.d.ts +41 -0
  31. package/dist/shared/resourceTemplate.d.ts +7 -0
  32. package/dist/shared/useExpressionCompletion.d.ts +0 -7
  33. package/dist/shared/useExpressionDiagnostics.d.ts +15 -0
  34. package/dist/shared.js +10 -9
  35. package/dist/style.css +1 -1
  36. package/dist/uploadFile-D1RY-ji0.js +516 -0
  37. package/dist/usePathCompletion-Do17CQ6l.js +220 -0
  38. package/package.json +2 -2
  39. package/dist/completionAnchor-CDR5YZhu.js +0 -273
  40. package/dist/uploadFile-BOfv8aLG.js +0 -331
  41. package/dist/usePathCompletion-uJ5c_gQ0.js +0 -229
  42. /package/dist/{property-panel → shared}/fontPicker.d.ts +0 -0
@@ -0,0 +1,220 @@
1
+ import { a as e } from "./layerPath-uy2ywyld.js";
2
+ import { a as t, g as n, i as r, m as i, r as a } from "./popupPosition-Ck5Gsvjy.js";
3
+ import { nextTick as o, onMounted as s, onScopeDispose as c, reactive as l, toValue as u, watch as d } from "vue";
4
+ //#region ../canvas-editor/src/shared/rowsPathCandidates.ts
5
+ function f(e) {
6
+ return e.type === "array" || e.items !== void 0;
7
+ }
8
+ function p(e) {
9
+ return !f(e) && e.properties === void 0;
10
+ }
11
+ function m(e, t, n) {
12
+ let r = {
13
+ path: n === "" ? e : `${n}.${e}`,
14
+ segment: e
15
+ };
16
+ return t.description !== void 0 && (r.description = t.description), t.title !== void 0 && (r.title = t.title), f(t) && (r.type = "array"), r;
17
+ }
18
+ function h(e, t) {
19
+ let n = [];
20
+ if (e.properties !== void 0) for (let [r, i] of e.properties) p(i) || n.push(m(r, i, t));
21
+ return n;
22
+ }
23
+ function g(e, t) {
24
+ if (e === null) return null;
25
+ let r = t.split("."), i = t.endsWith(".") ? "" : r[r.length - 1], a = r.slice(0, -1), o = e;
26
+ for (let e of a) {
27
+ if (f(o)) return null;
28
+ let t = n(o, [e]);
29
+ if (t === null) return null;
30
+ o = t;
31
+ }
32
+ return f(o) || p(o) ? null : {
33
+ partial: i,
34
+ candidates: h(o, a.join("."))
35
+ };
36
+ }
37
+ function _(t, n, r) {
38
+ if (r === null) return null;
39
+ if (t === null || n === null) return r;
40
+ let a = null;
41
+ for (let o = 0; o < n.length; o += 1) {
42
+ if (n[o] !== "template") continue;
43
+ let s = e(t, n.slice(0, o));
44
+ if (s === null || s.type !== "TableLayer" || (a = i(a ?? r, s.rowsPath), a === null)) return null;
45
+ }
46
+ return a ?? r;
47
+ }
48
+ //#endregion
49
+ //#region src/shared/rowsPathCompletionSource.ts
50
+ function v(e) {
51
+ return e === null ? null : (t) => {
52
+ let n = g(e, t);
53
+ return n === null ? null : {
54
+ partial: n.partial,
55
+ candidates: n.candidates.map((e) => e.type === "array" ? {
56
+ ...e,
57
+ type: "行数组"
58
+ } : e)
59
+ };
60
+ };
61
+ }
62
+ //#endregion
63
+ //#region src/shared/usePathCompletion.ts
64
+ var y = [
65
+ "ArrowLeft",
66
+ "ArrowRight",
67
+ "Home",
68
+ "End",
69
+ "PageUp",
70
+ "PageDown"
71
+ ];
72
+ function b(e) {
73
+ return {
74
+ kind: "fragment",
75
+ start: -2,
76
+ end: e.length + 2,
77
+ raw: "",
78
+ expr: e,
79
+ error: null,
80
+ diagnostic: null
81
+ };
82
+ }
83
+ function x(e) {
84
+ let n = l({
85
+ open: !1,
86
+ items: [],
87
+ activeIndex: 0,
88
+ top: 0,
89
+ left: 0
90
+ }), i = null, f = !1, p = "";
91
+ function m() {
92
+ n.open = !1, n.items = [], n.activeIndex = 0, p = "";
93
+ }
94
+ function h() {
95
+ if (!n.open || !i) return;
96
+ let t = r(i), o = e.popupEl ? u(e.popupEl) : null, s = a({
97
+ anchor: t,
98
+ popupWidth: o?.offsetWidth ?? 0,
99
+ popupHeight: o?.offsetHeight ?? 0,
100
+ viewportWidth: window.innerWidth,
101
+ viewportHeight: window.innerHeight
102
+ });
103
+ n.top = s.top, n.left = s.left;
104
+ }
105
+ function g(t, r = !1) {
106
+ if (!u(e.enabled)) {
107
+ m();
108
+ return;
109
+ }
110
+ let a = i;
111
+ if (!a) {
112
+ m();
113
+ return;
114
+ }
115
+ let s = a.value.slice(0, a.selectionStart ?? a.value.length);
116
+ if (s === "" && !r) {
117
+ m();
118
+ return;
119
+ }
120
+ let c = e.resolve(s);
121
+ if (!c) {
122
+ m();
123
+ return;
124
+ }
125
+ let l = r ? c.candidates : c.candidates.filter((e) => e.segment.startsWith(c.partial));
126
+ if (l.length === 0) {
127
+ m();
128
+ return;
129
+ }
130
+ p = c.partial, (n.open || t) && (n.items = l, n.activeIndex = 0, n.open = !0, h(), o(h));
131
+ }
132
+ function _(e) {
133
+ let r = i;
134
+ if (!n.open || f || !r) return;
135
+ let a = n.items[e ?? n.activeIndex];
136
+ if (!a) return;
137
+ let o = r.value.slice(0, r.selectionStart ?? r.value.length), s = t(r.value, b(o), o.length, p, a);
138
+ if (!s) {
139
+ m();
140
+ return;
141
+ }
142
+ r.value = s.value, r.setSelectionRange(s.cursor, s.cursor), r.dispatchEvent(new Event("input", { bubbles: !0 })), r.dispatchEvent(new Event("change", { bubbles: !0 })), m();
143
+ }
144
+ function v(e) {
145
+ f || e.isComposing || g(!0);
146
+ }
147
+ function x() {
148
+ f = !0;
149
+ }
150
+ function S() {
151
+ f = !1, g(!0);
152
+ }
153
+ function C(e) {
154
+ return f || e.isComposing || e.keyCode === 229;
155
+ }
156
+ function w(e) {
157
+ if (!C(e)) {
158
+ if (e.key === " " && (e.ctrlKey || e.metaKey)) {
159
+ e.preventDefault(), g(!0, !0);
160
+ return;
161
+ }
162
+ if (n.open) {
163
+ if (e.key === "ArrowDown" || e.key === "ArrowUp") {
164
+ e.preventDefault();
165
+ let t = n.items.length;
166
+ t > 0 && (n.activeIndex = (n.activeIndex + (e.key === "ArrowDown" ? 1 : t - 1)) % t);
167
+ return;
168
+ }
169
+ if (e.key === "Enter" || e.key === "Tab") {
170
+ e.preventDefault(), _();
171
+ return;
172
+ }
173
+ e.key === "Escape" && (e.preventDefault(), m());
174
+ }
175
+ }
176
+ }
177
+ function T(e) {
178
+ n.open && !C(e) && y.includes(e.key) && g(!1);
179
+ }
180
+ function E() {
181
+ f || g(!1);
182
+ }
183
+ function D() {
184
+ m();
185
+ }
186
+ function O(e) {
187
+ n.open && e.target !== i && m();
188
+ }
189
+ function k() {
190
+ h();
191
+ }
192
+ let A = [
193
+ ["input", v],
194
+ ["keydown", w],
195
+ ["keyup", T],
196
+ ["click", E],
197
+ ["blur", D],
198
+ ["compositionstart", x],
199
+ ["compositionend", S]
200
+ ];
201
+ function j(e) {
202
+ for (let [t, n] of A) e.addEventListener(t, n);
203
+ }
204
+ function M(e) {
205
+ for (let [t, n] of A) e.removeEventListener(t, n);
206
+ }
207
+ function N(e) {
208
+ i !== e && (i && M(i), i = e, e && j(e));
209
+ }
210
+ return s(() => N(e.target.value)), d(e.target, (e) => N(e)), d(() => u(e.enabled), (e) => {
211
+ e || m();
212
+ }), document.addEventListener("mousedown", O), window.addEventListener("scroll", k, !0), window.addEventListener("resize", k), c(() => {
213
+ i && M(i), document.removeEventListener("mousedown", O), window.removeEventListener("scroll", k, !0), window.removeEventListener("resize", k);
214
+ }), {
215
+ popup: n,
216
+ accept: _
217
+ };
218
+ }
219
+ //#endregion
220
+ export { v as n, _ as r, x as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hankchen/canvas-editor-vue",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "license": "MIT",
5
5
  "description": "Vue 3 薄绑定:响应式桥、composables、画布表面组件、textarea 文本编辑 overlay、schema 驱动属性面板注册表",
6
6
  "type": "module",
@@ -58,7 +58,7 @@
58
58
  },
59
59
  "dependencies": {
60
60
  "@lucide/vue": "^1.48.0",
61
- "@hankchen/canvas-editor": "0.3.0"
61
+ "@hankchen/canvas-editor": "0.5.0"
62
62
  },
63
63
  "peerDependencies": {
64
64
  "vue": "^3.5.0"
@@ -1,273 +0,0 @@
1
- import { Fragment as e, Teleport as t, createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, defineComponent as o, mergeProps as s, nextTick as c, normalizeClass as l, normalizeStyle as u, openBlock as d, ref as f, renderList as p, resolveDynamicComponent as m, toDisplayString as h, watch as g, withModifiers as _ } from "vue";
2
- //#region ../canvas-editor/src/shared/expressionSchema.ts
3
- function v(e) {
4
- let t = e;
5
- for (; t !== void 0;) {
6
- if (t.properties !== void 0) return t.properties;
7
- t = t.items;
8
- }
9
- return null;
10
- }
11
- function y(e, t) {
12
- let n = e;
13
- for (let e of t) {
14
- let t = v(n)?.get(e);
15
- if (t === void 0) return null;
16
- n = t;
17
- }
18
- return n;
19
- }
20
- function b(e) {
21
- if (e.type === "array" || e.items !== void 0) return { entries: [] };
22
- let t = e.properties === void 0 ? [] : [...e.properties].map(([e, t]) => ({
23
- key: e,
24
- node: t
25
- }));
26
- return e.open === !0 ? {
27
- entries: t,
28
- open: !0
29
- } : { entries: t };
30
- }
31
- function x(e, t) {
32
- let n = t.split(".");
33
- return t === "" || n.includes("") ? null : y(e, n)?.items ?? null;
34
- }
35
- //#endregion
36
- //#region ../canvas-editor/src/shared/expressionPath.ts
37
- function S(e) {
38
- if (e === "") return {
39
- ok: !1,
40
- error: "expression_syntax_error"
41
- };
42
- let t = e.split(".");
43
- if (t.includes("")) return {
44
- ok: !1,
45
- error: "expression_syntax_error"
46
- };
47
- let n = t[0], r = t.slice(1);
48
- return n === "row" ? {
49
- ok: !0,
50
- head: { kind: "row" },
51
- rest: r
52
- } : n === "$root" ? {
53
- ok: !0,
54
- head: { kind: "root" },
55
- rest: r
56
- } : {
57
- ok: !0,
58
- head: {
59
- kind: "bare",
60
- name: n
61
- },
62
- rest: r
63
- };
64
- }
65
- function C(e) {
66
- let t = 0, n = e.length;
67
- for (; t < n && " \n\r\0\v".includes(e[t]);) t += 1;
68
- for (; n > t && " \n\r\0\v".includes(e[n - 1]);) --n;
69
- return e.slice(t, n);
70
- }
71
- function w(e) {
72
- let t = [], n = 0, r = e.indexOf("{{");
73
- for (; r !== -1;) {
74
- let i = e.indexOf("}}", r + 2);
75
- if (i === -1) {
76
- r > n && t.push({
77
- kind: "literal",
78
- start: n,
79
- end: r,
80
- text: e.slice(n, r)
81
- });
82
- let i = e.slice(r);
83
- return t.push({
84
- kind: "open",
85
- start: r,
86
- end: e.length,
87
- text: i,
88
- expr: C(i.slice(2))
89
- }), {
90
- template: e,
91
- parts: t
92
- };
93
- }
94
- r > n && t.push({
95
- kind: "literal",
96
- start: n,
97
- end: r,
98
- text: e.slice(n, r)
99
- });
100
- let a = e.slice(r + 2, i), o = C(a), s = S(o).ok ? null : "expression_syntax_error";
101
- t.push({
102
- kind: "fragment",
103
- start: r,
104
- end: i + 2,
105
- raw: a,
106
- expr: o,
107
- error: s
108
- }), n = i + 2, r = e.indexOf("{{", n);
109
- }
110
- return n < e.length && t.push({
111
- kind: "literal",
112
- start: n,
113
- end: e.length,
114
- text: e.slice(n)
115
- }), {
116
- template: e,
117
- parts: t
118
- };
119
- }
120
- function T(e, t) {
121
- for (let n of e.parts) if (n.kind !== "literal" && (n.kind === "open" ? t > n.start && t <= n.end : t > n.start && t < n.end)) return n;
122
- return null;
123
- }
124
- //#endregion
125
- //#region src/shared/PanelIcon.vue
126
- var E = /* @__PURE__ */ o({
127
- inheritAttrs: !1,
128
- __name: "PanelIcon",
129
- props: {
130
- icon: {},
131
- size: { default: 14 },
132
- strokeWidth: { default: 2 }
133
- },
134
- setup(e) {
135
- return (t, r) => (d(), n(m(e.icon), s({
136
- size: e.size,
137
- "stroke-width": e.strokeWidth
138
- }, t.$attrs), null, 16, ["size", "stroke-width"]));
139
- }
140
- }), D = {
141
- role: "listbox",
142
- "aria-label": "表达式路径候选"
143
- }, O = [
144
- "aria-selected",
145
- "title",
146
- "onClick"
147
- ], k = { class: "cn-completion__segment font-mono text-cn-fg" }, A = {
148
- key: 0,
149
- class: "shrink-0 rounded-sm bg-cn-field px-1 py-0.5 text-[9px] leading-none text-cn-muted"
150
- }, j = {
151
- key: 1,
152
- class: "truncate text-[10px] leading-none text-cn-muted"
153
- }, M = {
154
- key: 0,
155
- class: "cn-completion__hint px-2 py-1.5 text-[10px] leading-none text-cn-muted"
156
- }, N = /* @__PURE__ */ o({
157
- __name: "ExpressionCompletionPopup",
158
- props: { state: {} },
159
- emits: ["select"],
160
- setup(o, { expose: s, emit: m }) {
161
- let v = o, y = m, b = f(null);
162
- return s({ rootEl: b }), g(() => v.state.activeIndex, async () => {
163
- await c(), b.value?.querySelector(".cn-completion__option--active")?.scrollIntoView?.({ block: "nearest" });
164
- }), (s, c) => (d(), n(t, { to: "body" }, [o.state.open ? (d(), i("div", {
165
- key: 0,
166
- ref_key: "rootRef",
167
- ref: b,
168
- class: "cn-props cn-completion fixed z-50 max-h-[200px] min-w-[140px] max-w-[280px] overflow-y-auto rounded-md border border-cn-field-line py-1 text-[11px] leading-none",
169
- style: u({
170
- top: `${o.state.top}px`,
171
- left: `${o.state.left}px`
172
- }),
173
- onMousedown: c[0] ||= _(() => {}, ["prevent", "stop"]),
174
- onPointerdown: c[1] ||= _(() => {}, ["stop"])
175
- }, [a("div", D, [(d(!0), i(e, null, p(o.state.items, (e, t) => (d(), i("button", {
176
- key: `${t}:${e.segment}`,
177
- type: "button",
178
- role: "option",
179
- class: l(["cn-completion__option flex w-full items-center gap-1.5 px-2 py-1.5 text-left", t === o.state.activeIndex ? "cn-completion__option--active" : ""]),
180
- "aria-selected": t === o.state.activeIndex,
181
- title: e.path ?? e.segment,
182
- onClick: (e) => y("select", t)
183
- }, [
184
- a("span", k, h(e.segment), 1),
185
- e.type ? (d(), i("span", A, h(e.type), 1)) : r("", !0),
186
- e.description ?? e.title ? (d(), i("span", j, h(e.description ?? e.title), 1)) : r("", !0)
187
- ], 10, O))), 128))]), o.state.openMapping ? (d(), i("div", M, " 动态字段,键由模板定义 ")) : r("", !0)], 36)) : r("", !0)]));
188
- }
189
- });
190
- //#endregion
191
- //#region src/shared/completion.ts
192
- function P(e, t, n, r) {
193
- let i = t.start + 2, a = t.kind === "open" ? t.end : t.end - 2, o = 0;
194
- for (; a - o > i && " \n\r\0\v".includes(e[a - 1 - o]);) o += 1;
195
- let s = a - o, c = s - n.length;
196
- return c < i || e.slice(c, s) !== n ? null : {
197
- value: e.slice(0, c) + r + e.slice(s),
198
- cursor: c + r.length
199
- };
200
- }
201
- //#endregion
202
- //#region src/shared/completionAnchor.ts
203
- function F(e, t) {
204
- return parseFloat(e.getPropertyValue(t)) || 0;
205
- }
206
- function I(e, t, n) {
207
- for (let r of n) {
208
- let n = e.getPropertyValue(r);
209
- n && t.setProperty(r, n);
210
- }
211
- }
212
- var L = [
213
- "font-family",
214
- "font-size",
215
- "font-weight",
216
- "font-style",
217
- "font-stretch",
218
- "letter-spacing",
219
- "word-spacing",
220
- "line-height",
221
- "text-transform",
222
- "text-indent",
223
- "tab-size"
224
- ];
225
- function R(e) {
226
- return F(e, "line-height") || F(e, "font-size") * 1.4;
227
- }
228
- function z(e) {
229
- let t = document.createElement("div"), n = t.style;
230
- return n.position = "fixed", n.top = "0", n.left = "0", n.visibility = "hidden", e(t, n), document.body.appendChild(t), t;
231
- }
232
- function B(e, t) {
233
- let n = e.selectionStart ?? e.value.length, r = e.getBoundingClientRect(), i = getComputedStyle(e), a = F(i, "padding-left"), o = F(i, "padding-top"), s = null, c = z((t, r) => {
234
- r.whiteSpace = i.whiteSpace || "pre-wrap", r.boxSizing = "content-box", r.width = `${Math.max(0, e.clientWidth - a - F(i, "padding-right"))}px`, I(i, r, [
235
- "padding-left",
236
- "padding-right",
237
- "padding-top",
238
- "padding-bottom",
239
- "word-break",
240
- "overflow-wrap"
241
- ]), I(i, r, L), s = document.createElement("span"), s.textContent = "​", t.append(document.createTextNode(e.value.slice(0, n)), s);
242
- });
243
- try {
244
- let n = r.left + F(i, "border-left-width") + a + s.offsetLeft * t - e.scrollLeft, c = r.top + F(i, "border-top-width") + o + s.offsetTop * t - e.scrollTop;
245
- return {
246
- left: n,
247
- top: c,
248
- bottom: c + R(i) * t
249
- };
250
- } finally {
251
- c.remove();
252
- }
253
- }
254
- function V(e, t) {
255
- let n = e.selectionStart ?? e.value.length, r = e.getBoundingClientRect(), i = getComputedStyle(e), a = z((t, r) => {
256
- r.display = "inline-block", r.whiteSpace = "pre", I(i, r, L), t.textContent = e.value.slice(0, n);
257
- });
258
- try {
259
- let n = a.getBoundingClientRect().width || a.offsetWidth;
260
- return {
261
- left: r.left + F(i, "border-left-width") + F(i, "padding-left") + n * t - e.scrollLeft,
262
- top: r.top + F(i, "border-top-width"),
263
- bottom: r.bottom - F(i, "border-bottom-width")
264
- };
265
- } finally {
266
- a.remove();
267
- }
268
- }
269
- function H(e, t = 1) {
270
- return e instanceof HTMLTextAreaElement ? B(e, t) : V(e, t);
271
- }
272
- //#endregion
273
- export { T as a, x as c, E as i, b as l, P as n, w as o, N as r, S as s, H as t, y as u };