ant-design-x-vue-next
Version:
Ant Design X for Vue — community continuation aligned with @ant-design/x
526 lines (525 loc) • 17.1 kB
JavaScript
import { defineComponent as Ve, ref as C, computed as T, watch as J, nextTick as W, onBeforeUpdate as Ke, onUpdated as Ae, createVNode as y, mergeProps as Ie } from "vue";
import { Input as Me, Menu as Le, Dropdown as Ue } from "ant-design-vue";
import { b as U, K as je } from "../../chunks/module-chunk.mjs";
import Fe from "./Skill.mjs";
const Ye = /* @__PURE__ */ Ve({
name: "AXSenderSlotTextArea",
__name: "SlotTextArea",
props: {
prefixCls: null,
slotConfig: null,
skill: null,
disabled: {
type: Boolean
},
readOnly: {
type: Boolean
},
placeholder: null,
style: null,
class: null,
submitType: {
type: [String, Boolean]
},
onChange: {
type: Function
},
onKeyPress: null,
onKeyDown: null
},
setup(ie, {
expose: de
}) {
const fe = /* @__PURE__ */ new Set(["input", "select", "custom", "content"]), s = ie, k = C(null), $ = C([]), x = C([]), g = C(null), D = C(/* @__PURE__ */ new Set()), u = C({}), d = C({}), b = C(s.skill), j = C(!1), N = /* @__PURE__ */ new Map();
let E = null, P = null, R = 0;
const w = T(() => `${s.prefixCls}-slot`), ye = T(() => `${s.prefixCls}-slot-input`), X = T(() => `${s.prefixCls}-slot-select`), ve = T(() => `${s.prefixCls}-slot-tag`), pe = T(() => `${s.prefixCls}-slot-content`), Q = T(() => `${s.prefixCls}-input`), Z = T(() => !s.disabled && !s.readOnly), m = (e) => e.key || "", z = (e, t) => e.map((o, n) => o.type === "text" && !o.key ? {
...o,
key: `${t}_${n}`
} : o), F = (e) => e.reduce((t, o) => {
const n = o.key;
if (!n)
return t;
const l = o.props || {}, a = fe.has(o.type) ? l.defaultValue : l.value ?? l.label;
return t[n] = a ?? "", t;
}, {}), O = (e) => e.reduce((t, o) => {
if (o.type === "text") {
const n = m(o);
n && (t[n] = o.value ?? "");
}
return t;
}, {}), _ = T(() => g.value ?? [...$.value, ...x.value]), q = () => {
const e = k.value, t = window.getSelection();
if (e && t && t.rangeCount > 0 && t.anchorNode && e.contains(t.anchorNode))
try {
P = t.getRangeAt(0).cloneRange();
} catch {
}
}, ke = () => {
const e = k.value, t = window.getSelection();
if (e && t && t.rangeCount > 0 && t.anchorNode && e.contains(t.anchorNode))
try {
return t.getRangeAt(0).cloneRange();
} catch {
}
if (P && e)
try {
return P.startContainer, P.cloneRange();
} catch {
return null;
}
return null;
}, V = () => {
N.forEach((e, t) => {
if (document.activeElement === e)
return;
const [o, n] = t.split("::"), l = o === "text" ? d.value[n] ?? "" : String(u.value[n] ?? "");
e.textContent !== l && (e.textContent = l);
});
}, ee = (e, t) => {
if (!t) {
N.delete(e);
return;
}
N.set(e, t);
const [o, n] = e.split("::"), l = o === "text" ? d.value[n] ?? "" : String(u.value[n] ?? "");
document.activeElement !== t && t.textContent !== l && (t.textContent = l);
}, K = () => {
let e = !1;
return N.forEach((t, o) => {
const [n, l] = o.split("::"), a = t.textContent ?? "";
if (n === "text") {
d.value[l] !== a && (d.value = {
...d.value,
[l]: a
}, e = !0);
return;
}
u.value[l] !== a && (u.value = {
...u.value,
[l]: a
}, e = !0);
}), e;
};
J(() => s.slotConfig, (e) => {
g.value = null, $.value = z(e ?? [], "cfg");
const t = F($.value);
D.value.forEach((l) => {
l in u.value && (t[l] = u.value[l]);
}), u.value = t;
const o = O($.value), n = O(x.value);
d.value = {
...o,
...n,
...Object.fromEntries(Object.entries(d.value).filter(([l]) => D.value.has(l)))
}, W(V);
}, {
immediate: !0,
deep: !0
}), J(() => s.skill, (e) => {
b.value = e;
}, {
immediate: !0
}), J([u, d], () => {
W(V);
}), Ke(() => {
const e = k.value, t = window.getSelection();
if (e && t && t.rangeCount > 0 && t.anchorNode && e.contains(t.anchorNode))
try {
E = t.getRangeAt(0).cloneRange();
} catch {
E = null;
}
else
E = null;
}), Ae(() => {
if (V(), !E)
return;
const e = window.getSelection(), t = k.value;
if (!e || !t) {
E = null;
return;
}
try {
e.removeAllRanges(), e.addRange(E);
} catch {
}
E = null;
});
const te = (e) => {
var t, o;
if (e.type === "text") {
const n = m(e), l = n ? N.get(`text::${n}`) : void 0, a = n ? d.value[n] : void 0;
return l && !(l.textContent === "" && a) ? l.textContent ?? "" : a ?? e.value ?? "";
}
if (e.type === "tag")
return ((t = e.props) == null ? void 0 : t.value) ?? ((o = e.props) == null ? void 0 : o.label) ?? "";
if (e.type === "content" && e.key) {
const n = N.get(`content::${e.key}`), l = u.value[e.key];
if (n && !(n.textContent === "" && l))
return n.textContent ?? "";
}
return e.key ? u.value[e.key] ?? "" : "";
}, ne = (e, t) => {
var n;
const o = (n = e.formatResult) == null ? void 0 : n.call(e, t);
return o !== void 0 ? o : t == null ? "" : String(t);
}, le = () => _.value.map((e) => ne(e, te(e))).join(""), oe = () => _.value.map((e) => ({
...e,
value: ne(e, te(e))
})), h = (e) => {
var o;
const t = le();
(o = s.onChange) == null || o.call(s, t, e, oe(), b.value);
}, Y = (e, t) => {
u.value = {
...u.value,
[e]: t
}, h();
}, xe = () => ({
value: le(),
slotConfig: oe(),
skill: b.value
}), A = (e, t, o) => {
const n = z(e, `rt_${++R}`);
n.forEach((l) => {
l.key && D.value.add(l.key);
}), g.value = n, x.value = [], u.value = {
...u.value,
...F(n),
...t
}, d.value = {
...O(n),
...o
};
}, ge = (e) => {
var i;
const t = k.value;
if (!t) return null;
const o = e.startContainer, n = (i = o.nodeType === Node.ELEMENT_NODE ? o : o.parentElement) == null ? void 0 : i.closest("[data-slot-key]");
if (!n || !t.contains(n))
return null;
const l = n.getAttribute("data-slot-key") || "", a = n.getAttribute("data-slot-type") || "", c = _.value.findIndex((S) => S.key === l || m(S) === l);
if (c < 0)
return null;
let r = 0;
return o.nodeType === Node.TEXT_NODE ? r = e.startOffset : (a === "text" || a === "content") && (r = (n.textContent ?? "").length), {
index: c,
key: l,
slotType: a,
textOffset: r,
el: n
};
}, ae = (e, t = "end", o, n) => {
const l = z(e, `ins_${++R}`), a = F(l), c = O(l);
if (l.forEach((r) => {
r.key && D.value.add(r.key);
}), K(), t === "start")
g.value ? A([...l, ...g.value], a, c) : (x.value = [...l, ...x.value], u.value = {
...u.value,
...a
}, d.value = {
...d.value,
...c
});
else if (t === "cursor") {
const r = ke(), i = r ? ge(r) : null;
if (!i)
g.value ? A([...g.value, ...l], a, c) : (x.value = [...x.value, ...l], u.value = {
...u.value,
...a
}, d.value = {
...d.value,
...c
});
else {
const S = [..._.value], f = S[i.index];
let B = i.textOffset;
if (f.type === "text" || f.type === "content") {
const I = f.type === "text" ? d.value[m(f)] ?? f.value ?? "" : String(u.value[f.key] ?? "");
let ce = 0;
o && o.length > 0 && B >= o.length && I.slice(0, B).endsWith(o) && (ce = o.length);
const M = I.slice(0, B - ce), L = I.slice(B), De = S.slice(0, i.index), Pe = S.slice(i.index + 1), v = M.length > 0 ? f.type === "text" ? {
type: "text",
key: `${m(f)}_b_${R}`,
value: M
} : {
...f,
key: `${f.key}_b_${R}`,
props: {
...f.props,
defaultValue: M
}
} : null, p = L.length > 0 ? f.type === "text" ? {
type: "text",
key: `${m(f)}_a_${R}`,
value: L
} : {
...f,
key: `${f.key}_a_${R}`,
props: {
...f.props,
defaultValue: L
}
} : null, Oe = [...De, ...v ? [v] : [], ...l, ...p ? [p] : [], ...Pe], G = {
...c
}, H = {
...a
};
(v == null ? void 0 : v.type) === "text" && v.key && (G[v.key] = M), (p == null ? void 0 : p.type) === "text" && p.key && (G[p.key] = L), (v == null ? void 0 : v.type) === "content" && v.key && (H[v.key] = M), (p == null ? void 0 : p.type) === "content" && p.key && (H[p.key] = L), A(Oe, H, G);
} else {
const I = [...S.slice(0, i.index + 1), ...l, ...S.slice(i.index + 1)];
A(I, a, c);
}
}
} else
g.value ? A([...g.value, ...l], a, c) : (x.value = [...x.value, ...l], u.value = {
...u.value,
...a
}, d.value = {
...d.value,
...c
});
W(() => {
var r, i;
V(), h(), n || (i = (r = k.value) == null ? void 0 : r.scrollIntoView) == null || i.call(r, {
block: "nearest"
});
});
}, se = (e, t, o, n) => {
if (typeof e == "string") {
ae([{
type: "text",
value: e
}], t ?? "end", o, n);
return;
}
ae(e, t ?? "end", o, n);
}, Ce = () => {
g.value = null, x.value = [], D.value.clear(), P = null, u.value = F($.value), d.value = O($.value), b.value = s.skill, W(() => {
V(), h();
});
}, be = (e) => {
const t = k.value;
if (!t)
return;
const o = (e == null ? void 0 : e.preventScroll) ?? !1, n = (e == null ? void 0 : e.cursor) ?? "end";
t.focus({
preventScroll: o
});
const l = window.getSelection();
if (!l)
return;
const a = document.createRange();
if (n === "slot") {
const c = e && "key" in e ? e.key : void 0, r = c ? t.querySelector(`[data-slot-key="${c}"]`) : null;
if (r) {
a.selectNodeContents(r), a.collapse(!1), l.removeAllRanges(), l.addRange(a);
return;
}
}
n === "start" ? (a.selectNodeContents(t), a.collapse(!0)) : n === "all" ? a.selectNodeContents(t) : (a.selectNodeContents(t), a.collapse(!1)), l.removeAllRanges(), l.addRange(a);
}, he = () => {
var e;
(e = k.value) == null || e.blur();
}, Se = () => {
b.value = void 0, h();
}, ue = () => {
j.value = !0;
}, re = () => {
j.value = !1, K(), h();
}, Te = (e) => {
var n;
const t = e.key === "Enter" && !j.value;
switch (s.submitType ?? "enter") {
case "enter":
t && !e.shiftKey && e.preventDefault();
break;
case "shiftEnter":
t && e.shiftKey && e.preventDefault();
break;
}
(n = s.onKeyDown) == null || n.call(s, e);
}, Ee = (e) => {
var t;
(t = s.onKeyPress) == null || t.call(s, e);
}, me = () => {
j.value || (K(), h());
}, $e = (e) => e.replace(/\r\n/g, `
`).replace(/\r/g, `
`), Ne = (e) => {
var r;
const t = window.getSelection(), o = k.value;
if (!t || t.rangeCount === 0 || !o)
return !1;
const n = t.anchorNode;
if (!n || !o.contains(n))
return !1;
const l = ((r = n.nodeType === Node.ELEMENT_NODE ? n : n.parentElement) == null ? void 0 : r.closest('[data-slot-type="text"], [data-slot-type="content"]')) || null;
if (!l || !o.contains(l))
return !1;
const a = t.getRangeAt(0);
a.deleteContents();
const c = document.createTextNode(e);
return a.insertNode(c), a.setStartAfter(c), a.collapse(!0), t.removeAllRanges(), t.addRange(a), K(), h(), !0;
}, Re = (e) => {
var l;
if (!Z.value)
return;
e.preventDefault();
const t = (l = e.clipboardData) == null ? void 0 : l.getData("text/plain");
if (!t)
return;
const o = $e(t);
let n = !1;
if (typeof document.execCommand == "function")
try {
n = document.execCommand("insertText", !1, o);
} catch {
n = !1;
}
if (n) {
K(), h();
return;
}
Ne(o) || se([{
type: "text",
value: o
}], "end");
}, we = (e) => {
var c, r;
const t = e.key, o = ((c = e.props) == null ? void 0 : c.options) ?? [], n = u.value[t] ?? ((r = e.props) == null ? void 0 : r.defaultValue) ?? "", l = !n, a = y(Le, {
onClick: ({
key: i
}) => {
!s.disabled && !s.readOnly && Y(t, i);
},
items: o.map((i) => ({
key: i,
label: i
}))
}, null);
return y(Ue, {
trigger: ["click"],
disabled: s.disabled || s.readOnly
}, {
overlay: () => a,
default: () => {
var i;
return y("span", {
class: U(X.value, w.value, {
placeholder: l
}),
"data-slot-key": t,
contenteditable: "false"
}, [y("span", {
class: `${X.value}-value`,
"data-placeholder": (i = e.props) == null ? void 0 : i.placeholder
}, [n || ""]), y("span", {
class: `${X.value}-arrow`
}, [y(je, null, null)])]);
}
});
}, _e = (e) => {
var t, o, n, l;
switch (e.type) {
case "text": {
const a = m(e);
return y("span", {
key: a,
ref: (c) => ee(`text::${a}`, c),
class: w.value,
"data-slot-key": a,
"data-slot-type": "text"
}, null);
}
case "input":
return y("span", {
key: e.key,
contenteditable: "false",
"data-slot-key": e.key
}, [y(Me, {
bordered: !1,
disabled: s.disabled,
readonly: s.readOnly,
class: U(ye.value, w.value),
placeholder: (t = e.props) == null ? void 0 : t.placeholder,
value: u.value[e.key] ?? "",
"onUpdate:value": (a) => Y(e.key, a),
onCompositionstart: ue,
onCompositionend: re
}, null)]);
case "content":
return y("span", {
key: e.key,
ref: (a) => ee(`content::${e.key}`, a),
class: U(pe.value, w.value),
"data-slot-key": e.key,
"data-slot-type": "content",
"data-placeholder": (o = e.props) == null ? void 0 : o.placeholder
}, null);
case "select":
return y("span", {
key: e.key,
contenteditable: "false"
}, [we(e)]);
case "tag":
return y("span", {
key: e.key,
class: U(ve.value, w.value),
"data-slot-key": e.key,
contenteditable: "false"
}, [(n = e.props) == null ? void 0 : n.label]);
case "custom":
return y("span", {
key: e.key,
class: w.value,
"data-slot-key": e.key,
contenteditable: "false"
}, [(l = e.customRender) == null ? void 0 : l.call(e, u.value[e.key], (a) => Y(e.key, a), {
disabled: s.disabled,
readOnly: s.readOnly
}, e)]);
default:
return null;
}
};
return de({
getValue: xe,
insert: se,
clear: Ce,
focus: be,
blur: he,
nativeElement: k
}), () => {
const e = !_.value.length && !b.value && s.placeholder;
return y("div", {
ref: k,
role: "textbox",
class: U(Q.value, `${Q.value}-slot`, s.class),
style: s.style,
tabindex: 0,
"data-placeholder": e ? s.placeholder : void 0,
contenteditable: Z.value ? "true" : "false",
spellcheck: !1,
onKeydown: Te,
onKeypress: Ee,
onKeyup: q,
onMouseup: q,
onSelect: q,
onBlur: q,
onCompositionstart: ue,
onCompositionend: re,
onInput: me,
onPaste: Re
}, [b.value && y("span", {
contenteditable: "false"
}, [y(Fe, Ie(b.value, {
prefixCls: s.prefixCls,
removeSkill: Se
}), null)]), _.value.map((t) => _e(t))]);
};
}
});
export {
Ye as default
};