UNPKG

@ithinkdt/naive

Version:

iThinkDT Naive UI

574 lines (573 loc) 16 kB
import { defineComponent as M, watch as O, ref as b, shallowReactive as pe, computed as X, h as fe, shallowRef as ve, createVNode as e, createTextVNode as y, Fragment as q, mergeProps as me } from "vue"; import { NScrollbar as ge, NInput as Y, NIcon as R, NDivider as J, NUpload as xe, NUploadDragger as he, NP as ye, NFlex as be, NButton as U, NImage as ae, NVirtualList as _e } from "ithinkdt-ui"; import { useFormItem as we } from "ithinkdt-ui/es/_mixins/index"; import { debouncedWatch as K, asyncComputed as $e, useElementSize as Se } from "@vueuse/core"; import { useTheme as Ce, useModal as Ae } from "@ithinkdt/core"; import { c as h, cB as Q, CSS_STYLE_PREFIX as l, cM as j, cE as n, fullWH as Z, flexCenter as I, flex as Ee, flexDirCol as B, flexGap as ee, flexAlignCenter as ke, flexJustifySB as te, CSS_MOUNT_ANCHOR_META_NAME as Ie } from "@ithinkdt/core/cssr"; import { changeColor as F } from "seemly"; import { parseIconSet as ze } from "@iconify/utils/lib/icon-set/parse"; import { iconToSVG as Ne } from "@iconify/utils/lib/svg/build"; import { defaultIconCustomisations as De } from "@iconify/utils/lib/customisations/defaults"; import { p as oe, q as re, r as le, s as Be, t as Fe, u as Re, v as Me, S as Te } from "./index-CAZgbTxt.js"; const g = `${l}-icon-select`, s = `${g}-modal`, Qe = /* @__PURE__ */ M({ name: "IconSelect", props: { value: { type: Object, default: void 0 }, disabled: { type: Boolean, default: void 0 }, status: { type: String, default: void 0 }, accept: { type: String, default: "image/*" }, colls: { type: Object, default: () => ({}) }, loader: { type: Function, default: void 0 } }, emits: { "update:value": () => !0, "update-value": () => !0 }, setup(i, { emit: p }) { const c = Ce(); O(() => c.isDark, (t) => { z?.unmount(), z = void 0, Oe(g, c.vars, t); }, { immediate: !0 }); const f = we(i), { mergedDisabledRef: E, mergedStatusRef: V } = f, k = b(!1); O(() => i.value?.body, () => { k.value = !1; }, { immediate: !0 }); const ne = () => { k.value = !0; }, C = pe(/* @__PURE__ */ new Map()), ie = X(() => { C.clear(); const t = Object.entries(i.colls).map(([u, r]) => { r = { key: u, load: () => i.loader(r.key), ...r }; const w = r.load; return r = { ...r, onClick: () => { _.value = r.key; }, load: async () => { if (r.result) return r.result; const v = await w(), $ = r.result = []; return ze(v, (S, N) => { if (!N) return; const x = Ne(N, { ...De, height: "auto" }), D = { ...x.attributes, width: "1em", height: "1em", [oe]: v.prefix, [re]: S }, a = `<svg xmlns="http://www.w3.org/2000/svg" ${Object.entries(D).map(([m, o]) => `${m}="${o}"`).join(" ")}>${x.body}</svg>`; $.push([S, a, () => fe("svg", { xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", ...D, innerHTML: x.body }), `${v.prefix}:${S}`, v.prefix, { [oe]: v.prefix, [re]: S + ".svg" }, $.length]); }), $; } }, C.set(r.key, r), r; }), d = [{ key: "", name: "全部", total: t.reduce((u, r) => u + r.total, 0), onClick: () => { _.value = ""; }, load: () => Promise.all(t.map((u) => u.load())).then((u) => u.flat()) }, ...t]; return C.set("", d[0]), d; }), T = b(""), _ = b("mdi"), L = ve(); K([T, ie], ([t, d]) => { t = t?.trim(), L.value = d, t && (L.value = d.filter(([u, { name: r }]) => u.includes(t) || r.includes(t))); }, { debounce: 300, immediate: !0 }); const A = b(), ue = /* @__PURE__ */ M({ setup() { const t = b(!1); let d = 0; const u = $e(() => (t.value = !0, d = _.value ? 0 : 3, C.get(_.value).load().finally(() => { t.value = !1; }))), r = b(), w = b(""), v = b([]); function $(a, m) { const o = m?.trim(); v.value = o ? a.filter((P) => P[0].includes(o)) : a; } O(u, (a) => $(a, w.value)), setTimeout(() => { $(u.value, w.value); }, 500), K(w, (a) => $(u.value, a), { immediate: !0, debounce: 300 }); const S = 48, { width: N } = Se(r); let x = 10; const D = X(() => { let a = []; if (v.value?.length) { x = Math.max(Math.floor(N.value / S), 10); const m = Math.ceil(v.value.length / x); a = Array.from({ length: m }); for (let o = 0; o < m; o++) a[o] = { key: o, icons: v.value.slice(o * x, o * x + x) }; } return a; }); function W(a) { const m = a.currentTarget.dataset, o = v.value[m.index]; A.value = { ...m, body: Te + btoa(o[1]), source: o[1], svg: !0, it: o, index: o[6] }; } return () => e("div", { class: `${s}__icons` }, [e("div", { class: `${s}__icons-search` }, [e("div", { style: "flex: 1 0 auto; " }, [e("span", { style: "font-weight: bold; font-size: 18px" }, [C.get(_.value || "")?.name]), e("span", { style: "margin-left: 12px; color: #777" }, [C.get(_.value)?.total, y(" 个")])]), e(Y, { value: w.value, "onUpdate:value": (a) => w.value = a, clearable: !0, placeholder: "搜索图标", style: "width: 300px" }, { suffix: () => e(R, null, { default: () => [e(le, null, null)] }) })]), t.value ? "加载中..." : e("div", { class: `${s}__list`, ref: r }, [e(_e, { items: D.value, ignoreItemResize: !0, itemSize: S, paddingBottom: 30, scrollbarProps: { size: 10 } }, { default: ({ item: a, index: m }) => e("div", { class: `${s}__row` }, [a.icons.map((o, P) => e("div", me({ class: `${s}__item`, key: o[3] }, o[5], { "data-index": x * m + P, onClick: W }), [e("div", { class: `${s}__item-icon` }, [o[2]()]), e("div", { class: `${s}__item-name` }, [o[d]])]))]) })])]); } }), se = [], ce = async ([t]) => { A.value = void 0, t && (A.value = { category: "", name: t.name, body: await new Promise((d) => { const u = new FileReader(); u.addEventListener("load", () => { d(u.result); }), u.readAsDataURL(t.file); }), svg: t.name?.endsWith(".svg") }); }; function G(t = A.value ?? i.value ?? void 0) { p("update:value", t), p("update-value", t); } const { show: de, hide: H } = Ae({ title: "选择图标", width: "160vh", style: { maxWidth: "87vw", maxHeight: "100%" }, onAfterLeave: () => { A.value = void 0; }, content: () => { const t = A.value ?? i.value ?? {}; return e("div", { class: s }, [e("div", { class: `${s}__categories` }, [e(ge, null, { default: () => [e(Y, { class: `${s}__categories-search`, value: T.value, "onUpdate:value": (d) => T.value = d, clearable: !0, placeholder: "搜索类别" }, { suffix: () => e(R, null, { default: () => [e(le, null, null)] }) }), e(Le, { categories: L.value, curr: _.value }, null)] })]), e(J, { vertical: !0, style: "height: 100%; flex: 0 0 auto" }, null), e("div", { class: `${s}__container` }, [e(ue, null, null)]), e(J, { vertical: !0, style: "height: 100%; flex: 0 0 auto" }, null), e("div", { class: `${s}__info` }, [e("div", { style: "font-weight: bold; font-size: 18px; margin-bottom: 16px;" }, [y("图标")]), e(Pe, t, null), e(xe, { fileList: se, defaultUpload: !1, accept: i.accept, onUpdateFileList: ce }, { default: () => [e(he, { class: `${s}__dragger` }, { default: () => [e("div", { style: "font-size: 16px; color: #333" }, [y("点击或拖动文件至此")]), e(ye, { depth: "3", style: "font-size: 13px" }, { default: () => [y("SVG 文件建议"), e("br", null, null), y("宽度 1em 高度 1em"), e("br", null, null), y("颜色 currentColor")] })] })] }), e(be, { justify: "flex-end" }, { default: () => [e(U, { onClick: H }, { default: () => [y("取 消")] }), e(U, { type: "primary", onClick: () => { G(), H(); } }, { default: () => [y("确 定")] })] })])]); } }); return () => e("div", { class: [g, V.value ? `${g}--${V.value}-status` : "", E.value ? `${g}--disabled` : ""], tabindex: "0", onClick: () => { !E.value && de(); } }, [!i.value || k.value ? e(R, { class: [`${g}__wrapper`, k.value ? `${g}__error` : `${g}__add`] }, { default: () => [k.value ? e(Be, null, null) : e(Fe, null, null)] }) : e(ae, { class: [`${g}__wrapper`, `${g}__img`], width: "62%", height: "62%", src: i.value.body || "none", onError: ne, previewDisabled: !0 }, null), i.value && !E.value ? e("div", { class: `${g}__remove`, onClick: (t) => { t.stopPropagation(), G(null); } }, [e(U, { text: !0, type: "error", style: "font-size: 24px" }, { default: () => [e(Re, null, null)] })]) : void 0]); } }), Le = /* @__PURE__ */ M({ props: { categories: { type: Object, required: !0 }, curr: { type: String, default: void 0 } }, setup(i) { return () => i.categories.map(({ key: p, name: c, onClick: f }) => e("div", { key: c, class: [`${s}__category`, i.curr === p ? `${s}__category--curr` : ""], onClick: f }, [c])); } }), Pe = /* @__PURE__ */ M({ props: { category: { type: String, default: void 0 }, name: { type: String, default: void 0 }, body: { type: String, default: void 0 }, svg: { type: Boolean, default: !1 } }, setup(i) { return () => { const { svg: p, body: c, category: f, name: E } = i; return e("div", { class: `${s}__selected` }, [c ? e(q, null, [e(ae, { width: 120, height: 120, src: c, style: { opacity: p ? 0.618 : 1 } }, null), e("div", { style: "text-align: center; margin-top: 12px; font-size: 16px" }, [f ? f + ":" : "", E])]) : e(q, null, [e(R, { size: 120, color: "#ccc" }, { default: () => [e(Me, null, null)] }), e("div", { style: "margin-top: 12px; color: #999; font-size: 16px" }, [y("未选择")])])]); }; } }); let z; function Oe(i, p, c) { z || (z = h([Q("icon-select", { width: "96px", height: "96px", cursor: "pointer", boxSizing: "border-box", border: `1px solid var(--${l}-border-color)`, borderRadius: `var(--${l}-border-radius)`, transition: "color, border-color 0.3s ease-in-out", position: "relative", overflow: "hidden" }, [h("&:hover, &:focus", { borderColor: `var(--${l}-primary-color-hover)` }), h("&:focus", { outline: "none", boxShadow: c ? `0 0 0 2px ${F(p.primaryColor, { alpha: 0.2 })}` : `0 0 8px 0 ${F(p.primaryColor, { alpha: 0.3 })}` }), j("disabled", { cursor: "not-allowed", border: `1px solid var(--${l}-border-color)`, background: `var(--${l}-input-color-disabled)`, boxShadow: "none" }), ...["success", "warning", "error"].map((f) => j(`${f}-status`, { borderColor: `var(--${l}-${f}-color-hover)` }, [h("&:focus", { boxShadow: c ? `0 0 0 2px ${F(p[f + "Color"], { alpha: 0.2 })}` : `0 0 8px 0 ${F(p[f + "Color"], { alpha: 0.3 })}` })])), n("wrapper", { fontSize: "32px", ...Z, ...I }), n("error", { color: `var(--${l}-error-color)` }), n("add", { fontSize: "24px" }, [h("&:hover", { borderColor: `var(--${l}-primary-color)` })]), n("remove", { position: "absolute", left: 0, top: 0, ...Z, ...I, background: c ? "#00000070" : "#ffffffe0", opacity: "0", transition: "opacity 0.3s ease-in-out" }, [h("&:hover", { opacity: "1" })])]), Q("icon-select-modal", { height: "calc(85vh - 40px)", overflow: "hidden", ...Ee }, [n("categories", { flex: "0 0 240px" }), n("category", { cursor: "pointer", fontSize: "16px", padding: "8px 0 8px 20px" }, [h("&:hover", { color: `var(--${l}-primary-color-hover)` }), j("curr", { color: `var(--${l}-primary-color)` })]), n("categories-search", { width: "calc(100% - 20px)", position: "sticky", top: 0, marginBottom: "12px" }), n("container", { flex: "1 1 auto" }), n("icons", { height: "100%", overflow: "hidden", ...B, padding: "0 20px", ...ee("20px") }), n("icons-search", { ...ke, ...te, ...ee("12px") }), n("list", { flex: "1 1 auto", overflow: "hidden", fontSize: "28px", color: "#666" }), n("row", { textAlign: "center", lineHeight: "1" }), n("item", { display: "inline-block", textAlign: "center", width: "48px", height: "48px", position: "relative", cursor: "pointer", boxSizing: "border-box" }, [h("&:hover", [h(`.${l}-icon-select-modal__item-icon`, { color: `var(--${l}-primary-color)`, borderColor: `var(--${l}-primary-color)` }), h(`.${l}-icon-select-modal__item-name`, { display: "block" })])]), n("item-icon", { width: "34px", height: "34px", ...I, border: "1px solid transparent", borderRadius: `var(--${l}-border-radius)` }), n("item-name", { fontSize: "14px", position: "absolute", bottom: "-20px", left: "20px", transform: "translateX(-50%)", pointerEvents: "none", zIndex: "2", whiteSpace: "nowrap", display: "none", textAlign: "center", color: `var(--${l}-primary-color)`, background: `var(--${l}-base-color)`, boxShadow: `var(--${l}-box-shadow1)`, padding: "6px 8px" }), n("info", { flex: "0 0 240px", padding: "0 8px 8px 20px", ...B, ...te, overflow: "hidden" }), n("selected", { ...B, ...I, flex: "0 0 200px" }), n("dragger", { background: "transparent", height: "calc(85vh - 420px)", ...B, ...I })])]), z.mount({ id: i, anchorMetaName: Ie })); } export { Qe as DtIconSelect };