@farris/ui-vue
Version:
Farris Vue, a Farris Design based Vue3 component library.
542 lines (541 loc) • 15.2 kB
JavaScript
import { ref as c, defineComponent as E, createVNode as n, withDirectives as L, vShow as T, onMounted as W, Teleport as M, Fragment as X, inject as V } from "vue";
import { resolveAppearance as Z, createPropsResolver as G } from "../dynamic-resolver/index.esm.js";
import { useDesignerComponent as J } from "../designer-canvas/index.esm.js";
function K(e, r, s) {
return r;
}
const Q = /* @__PURE__ */ new Map([
["appearance", Z]
]), U = "https://json-schema.org/draft/2020-12/schema", _ = "https://farris-design.gitee.io/dropdown.schema.json", P = "dropdown", ee = "A Farris Component", te = "object", oe = {
id: {
description: "The unique identifier for dropdown",
type: "string"
},
type: {
description: "The type string of dropdown",
type: "string",
default: "dropdown"
},
appearance: {
description: "",
type: "object",
properties: {
class: {
type: "string"
},
style: {
type: "string"
}
},
default: {}
},
binding: {
description: "",
type: "object",
default: {}
},
disable: {
type: "string",
default: !1
},
editable: {
description: "",
type: "boolean",
default: !0
},
placeholder: {
description: "",
type: "string",
default: ""
},
readonly: {
description: "",
type: "boolean",
default: !1
},
require: {
description: "",
type: "boolean",
default: !1
},
tabindex: {
description: "",
type: "number",
default: -1
},
visible: {
description: "",
type: "boolean",
default: !0
}
}, ne = [
"id",
"type"
], ie = {
$schema: U,
$id: _,
title: P,
description: ee,
type: te,
properties: oe,
required: ne
}, se = "dropdown", le = "A Farris Component", re = "object", ae = {
basic: {
description: "Basic Infomation",
title: "基本信息",
properties: {
id: {
description: "组件标识",
title: "标识",
type: "string",
readonly: !0
},
type: {
description: "组件类型",
title: "控件类型",
type: "select",
editor: {
type: "waiting for modification",
enum: []
}
}
}
},
behavior: {
description: "Basic Infomation",
title: "行为",
properties: {
readonly: {
description: "",
title: "只读",
type: "string"
},
required: {
description: "",
title: "必填",
type: "boolean"
},
visible: {
description: "",
title: "可见",
type: "boolean"
},
placeholder: {
description: "",
title: "提示文本",
type: "string"
},
tabindex: {
description: "",
title: "tab索引",
type: "number"
}
}
}
}, de = {
title: se,
description: le,
type: re,
categories: ae
}, z = {
/**
* 默认展开或折叠 注意: 1、这个属性在出现滚动条的情况下,滚动会导致收折,看不到展开的面板。 2、如果是放置在没有滚动条的界面,可有实际效果
*/
show: { type: Boolean, default: !1 },
/**
* 下拉按钮是否禁用
* @default false
*/
disabled: { type: Boolean, default: !1 },
/**
* 下拉按钮对应文字
* @default '下拉示例'
*/
title: { type: String, default: "下拉示例" },
/**
* 下拉按钮尺寸,small小号,large大号 ,空为中号。默认为空
* @default ''
*/
size: { type: String, default: "" },
/**
* 下拉按钮类型
* @default 'primary'
*/
type: { type: String, default: "primary" },
/**
* 图标样式
* @default ''
*/
iconClass: { type: String, default: "" },
/**
* 是否处于当前选中状态
*/
active: { type: Boolean, default: !1 },
/**
* 下拉按钮是否分开展示
* @default false
*/
splitButton: { type: Boolean, default: !1 },
/**
* 下拉框展示方向
* @default 'bottom'
*/
position: { type: String, default: "bottom" },
/**
* 下拉框内容
* @default [ { label: '项目一', value: 'XM1' }, { label: '项目二', value: 'XM2' }, { label: '项目三', value: 'XM3' } ]
*/
model: {
type: Array,
default: [
{ label: "项目一", value: "XM1" },
{ label: "项目二", value: "XM2" },
{ label: "项目三", value: "XM3" }
]
},
/**
* 返回选中值
*/
onSelect: { type: Function, default: () => {
} }
}, N = G(z, ie, Q, K, de);
function O(e, r) {
const s = c(e.show), f = c(), u = c(), y = c(), p = () => u.value, l = 10, g = (o = 1) => {
const t = [
"body>.f-datagrid-settings-simple-host",
"body>div",
"body>farris-dialog>.farris-modal.show",
"body>.farris-modal.show",
"body>farris-filter-panel>.f-filter-panel-wrapper",
"body .f-sidebar-show>.f-sidebar-main",
"body>.popover.show",
"body>filter-row-panel>.f-datagrid-filter-panel",
"body>.f-section-maximize"
], m = Array.from(document.body.querySelectorAll(t.join(","))).filter((i) => i).map((i) => {
const { display: R, zIndex: B } = window.getComputedStyle(i);
return R === "none" ? 0 : parseInt(B, 10);
}).filter((i) => i);
let a = Math.max(...m);
return a < 1040 && (a = 1040), a + o;
}, S = (o, t) => {
const {
height: m,
left: a,
top: i,
width: R
} = o.getBoundingClientRect(), { width: B, height: A, top: pe } = t.getBoundingClientRect();
if (o.className.indexOf("dropdown-submenu") > -1 || o.closest(".dropdown-submenu") || o.classList.contains("dropright")) {
const H = window.innerWidth - a - o.offsetWidth, k = window.innerHeight - i, { position: h } = getComputedStyle(t);
if (h === "fixed") {
let w = a + o.offsetWidth;
t.offsetWidth > H && a > H && (w = a - B), t.style.left = w + "px", t.style.right = "auto", window.innerHeight - 2 * l < t.offsetHeight ? (t.style.top = l + "px", t.style.bottom = l + "px", t.style.maxHeight = window.innerHeight - 2 * l + "px", t.style.overflowY = "auto", t.className += " dropdown-menu-maxheight") : k < t.offsetHeight ? (t.style.top = "auto", t.style.bottom = l + "px") : (t.style.top = i + "px", t.style.bottom = "auto");
} else {
if (t.offsetWidth > H) {
const w = -B;
t.style.left = w + "px";
}
window.innerHeight - 2 * l < t.offsetHeight ? (t.style.top = -1 * (i - l) + "px", t.style.bottom = "auto", t.style.maxHeight = window.innerHeight - 2 * l + "px", t.style.overflowY = "auto", t.className += " dropdown-menu-maxheight") : k < t.offsetHeight && (t.style.top = k - t.offsetHeight - l + "px", t.style.bottom = "auto");
}
} else {
const { marginTop: H, marginBottom: k } = getComputedStyle(t);
let h = 0;
const w = Math.ceil(parseFloat(H)) + Math.ceil(parseFloat(k));
let b = i + m, q = a;
window.innerHeight - b - w < A && (b = i - A, b < 0 && (window.innerHeight - i - m > i ? (b = i + m, h = window.innerHeight - b - w - l) : (b = l, h = i - b - w))), window.innerWidth - a < B && window.innerWidth - a < a + R && (q = a - B + R), document.body.append(t), t.style.cssText = `position:fixed;bottom:unset;left:${q}px
!important;top:${b}px !important;right: unset;${h ? "max-height:" + h + "px;overflow-y:auto;" : ""}`, h && (t.className += " dropdown-menu-maxheight"), t.style.zIndex = g().toString();
}
}, v = () => {
S(f.value, u.value);
}, d = () => {
var o, t;
e.hover || (s.value = !1, u.value.style = null, document.removeEventListener("click", d), (o = p()) == null || o.removeEventListener("click", d), document.removeEventListener("scroll", d), (t = p()) == null || t.removeEventListener("scroll", d));
}, x = (o = null, t = !1) => {
var m, a;
e.hover || e.disabled || (o == null || o.stopPropagation(), t ? (setTimeout(() => {
v();
}), s.value = !0) : (s.value || setTimeout(() => {
v();
}), s.value = !s.value), document.addEventListener("click", d), document.addEventListener("scroll", d), e.hideOnClick || ((m = p()) == null || m.addEventListener("click", (i) => {
i.stopPropagation();
}), (a = p()) == null || a.addEventListener("scroll", (i) => {
i.stopPropagation();
})));
};
return {
show: s,
dropdownRef: f,
dropdownMenuRef: u,
clickEventRef: y,
showDropMenu: (o) => {
x(o, !1);
},
showDropMenuByForce: x,
hoverDropdown: (o) => {
e.hover && (s.value || setTimeout(() => {
}), s.value = !s.value);
},
leftButtonClick: () => {
},
closeDropMenu: d,
selectItem: (o) => {
r.emit("select", o);
},
resolveSize: (o) => {
const t = /px|em|rem|pt|%/;
return t.test(o) ? `${parseInt(o, 10)}${o.match(t)[0]}` : `${o}px`;
}
};
}
const ce = {
/** 下拉框标签 */
label: { type: String, default: "XM1" },
/** 下拉框名称 */
value: { type: String || Number, default: "项目一" },
/** 是否禁用该下拉框属性 */
disabled: { type: Boolean, default: !1 },
active: { type: Boolean, default: !1 },
divide: { type: Boolean, default: !1 },
onSelect: { type: Function, default: () => {
} }
}, Y = /* @__PURE__ */ E({
name: "FDropdownItem",
props: ce,
emits: ["select"],
setup(e, r) {
const s = c(e.value), f = c(e.label), u = c(e.disabled), y = c(e.active), p = c(e.divide), l = () => {
u.value || r.emit("select", e);
};
return () => n("div", null, [L(n("div", {
class: "dropdown-divider"
}, null), [[T, p.value]]), n("li", {
class: `dropdown-item${y.value ? " active" : ""} ${u.value ? " disabled" : ""}`,
onClick: l,
title: s.value.toString()
}, [f.value])]);
}
});
function ue() {
const e = c(!1);
return W(() => {
e.value = !0;
}), e;
}
const F = /* @__PURE__ */ E({
name: "FDropdown",
props: z,
emits: ["select"],
setup(e, r) {
const s = c(e.model), {
show: f,
dropdownMenuRef: u,
dropdownRef: y,
clickEventRef: p,
showDropMenu: l,
hoverDropdown: g,
leftButtonClick: S,
showDropMenuByForce: v,
closeDropMenu: d
} = O(e, r), x = ue();
function $(C) {
d(), r.emit("select", C);
}
function D() {
return [{
"dropdown-item": e.nest
}, {
"btn-lg": e.size === "large"
}, {
"btn-sm": e.size === "small"
}, {
"btn-primary": e.type === "primary"
}, {
"btn-success": e.type === "success"
}, {
"btn-warning": e.type === "warning"
}, {
"btn-danger": e.type === "danger"
}, {
"btn-info": e.type === "info"
}, {
"btn-secondary": e.type === "secondary"
}, {
"btn-link": e.type === "link"
}, {
disabled: e.disabled
}];
}
return W(() => {
f.value && v(null, !0);
}), () => n("div", {
ref: y
}, [n("div", {
class: ["farris-dropdown", "btn-group", {
dropup: e.position === "top"
}, {
dropdown: e.position === "bottom"
}, {
dropleft: e.position === "left"
}, {
dropright: e.position === "right"
}]
}, [e.splitButton && n("span", {
class: ["btn", ...D()],
style: "width:100%",
onClick: S
}, [e.title]), n("span", {
ref: p,
class: ["dropdown-toggle", {
btn: !e.nest
}, {
"dropdown-toggle-split": e.splitButton
}, ...D()],
style: "width:100%",
onClick: l,
onMouseenter: g,
onMouseleave: g
}, [e.splitButton ? "" : e.title, e.iconClass && n("span", {
class: `f-icon ${e.iconClass}`
}, null)]), x.value && n(M, {
to: "body"
}, {
default: () => [n("div", {
ref: u,
class: `dropdown-menu${f.value ? " show" : ""}`
}, [n(X, null, [s.value.map(({
label: C,
value: I,
disabled: j,
active: o,
divide: t
}) => n(Y, {
value: I.toString(),
label: C,
disabled: j,
active: o,
divide: t,
onSelect: (m) => $(m)
}, null))])])]
})])]);
}
}), fe = /* @__PURE__ */ E({
name: "FDropdownDesign",
props: z,
emits: ["select"],
setup(e, r) {
const s = c(e.model), {
show: f,
showDropMenu: u,
hoverDropdown: y,
leftButtonClick: p
} = O(e, r);
function l(d) {
r.emit("select", d);
}
const g = c(), S = V("design-item-context"), v = J(g, S);
return W(() => {
g.value.componentInstance = v;
}), r.expose(v.value), () => n("div", {
ref: g
}, [n("div", {
class: ["farris-dropdown", "btn-group", {
dropup: e.position === "top"
}, {
dropdown: e.position === "bottom"
}, {
dropleft: e.position === "left"
}, {
dropright: e.position === "right"
}],
style: {
width: e.width
}
}, [e.splitButton && n("span", {
class: ["btn", {
"dropdown-item": e.nest
}, {
"btn-lg": e.size === "large"
}, {
"btn-sm": e.size === "small"
}, {
"btn-primary": e.type === "primary"
}, {
"btn-success": e.type === "success"
}, {
"btn-warning": e.type === "warning"
}, {
"btn-danger": e.type === "danger"
}, {
"btn-info": e.type === "info"
}],
style: "width:100%",
onClick: p
}, [e.title]), n("span", {
class: ["dropdown-toggle", {
btn: !e.nest
}, {
"dropdown-item": e.nest
}, {
"dropdown-toggle-split": e.splitButton
}, {
"btn-lg": e.size === "large"
}, {
"btn-sm": e.size === "small"
}, {
"btn-primary": e.type === "primary"
}, {
"btn-success": e.type === "success"
}, {
"btn-warning": e.type === "warning"
}, {
"btn-danger": e.type === "danger"
}, {
"btn-info": e.type === "info"
}, {
"btn-secondary": e.type === "secondary"
}, {
"btn-link": e.type === "link"
}, {
disabled: e.disabled
}],
style: "width:100%",
onClick: u,
onMouseenter: y,
onMouseleave: y
}, [L(n("span", {
class: "sr-only"
}, null), [[T, e.splitButton]]), e.splitButton ? "" : e.title, L(n("span", {
class: `f-icon ${e.iconClass.toString()}`
}, null), [[T, e.iconClass]])]), n("div", {
class: `dropdown-menu${f.value ? " show" : ""}`
}, [n(X, null, [s.value.map(({
label: d,
value: x,
disabled: $,
active: D,
divide: C
}) => n(Y, {
value: x.toString(),
label: d,
disabled: $,
active: D,
divide: C,
onSelect: (I) => l(I)
}, null))])])])]);
}
}), be = {
install(e) {
e.component(F.name, F);
},
register(e, r, s, f) {
e.dropdown = F, r.dropdown = N;
},
registerDesigner(e, r, s) {
e.dropdown = fe, r.dropdown = N;
}
};
export {
F as Dropdown,
be as default,
z as dropdownProps,
N as propsResolver
};