@elf-framework/ui
Version:
ELF - An easy and customizable set of developers
1,749 lines • 215 kB
JavaScript
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
var __accessCheck = (obj, member, msg) => {
if (!member.has(obj))
throw TypeError("Cannot " + msg);
};
var __privateGet = (obj, member, getter) => {
__accessCheck(obj, member, "read from private field");
return getter ? getter.call(obj) : member.get(obj);
};
var __privateAdd = (obj, member, value) => {
if (member.has(obj))
throw TypeError("Cannot add the same private member more than once");
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
};
var __privateSet = (obj, member, value, setter) => {
__accessCheck(obj, member, "write to private field");
setter ? setter.call(obj, value) : member.set(obj, value);
return value;
};
var __privateMethod = (obj, member, method) => {
__accessCheck(obj, member, "access private method");
return method;
};
var _idMap, _items, _parentList, _initialize, initialize_fn, _traverse, traverse_fn;
import { isFunction, useMagicMethod, POINTERSTART, isUndefined, isArray, AFTER, UIElement, useState, useCallback, useMemo, classnames, createElementJsx, potal, isString, POINTERENTER, IF, POINTERLEAVE, CLICK, FOCUS, useEffect, Dom, PREVENT, STOP, OBSERVER, PARAMS, POINTEROVER, useRef, isNumber, FOCUSIN, FOCUSOUT, SCROLL, SUBSCRIBE_SELF, DEBOUNCE, FRAME, POINTERMOVE, POINTEREND, debounce, SUBSCRIBE_ALL, pendingComponent, removePendingComponent, useRender } from "@elf-framework/sapa";
import { parse, format, RGBtoHSL, RGBtoHSV, checkHueColor, HSVtoHSL, HSVtoRGB } from "@elf-framework/color";
const style = "";
function usePointerStart(...args) {
let [selector, downAction, moveAction, upAction] = args;
if (isFunction(selector)) {
[downAction, moveAction, upAction] = args;
selector = null;
}
return useMagicMethod(POINTERSTART(selector), (evt) => {
if (isFunction(downAction)) {
const ret = downAction(evt);
if (!isUndefined(ret)) {
return ret;
}
}
const move = (e) => {
if (isFunction(moveAction)) {
moveAction(e);
}
};
const end = (e) => {
if (isFunction(upAction))
upAction(e);
document.removeEventListener("mousemove", move);
document.removeEventListener("mouseup", end);
};
if (isFunction(moveAction)) {
document.addEventListener("mousemove", move);
}
if (isFunction(upAction) || isFunction(moveAction)) {
document.addEventListener("mouseup", end);
}
});
}
class BaseTreeViewProvider {
get items() {
}
get ids() {
}
has(id) {
}
get(id) {
}
set(id, obj) {
}
remove(id) {
}
setParent(targetId, parentId) {
}
removeParent(targetId) {
}
appendChild(parentId, obj) {
}
getParentId(childId) {
}
deleteInfo(childObj) {
}
removeChild(parentId, childId) {
}
insertChild(targetParentId, targetIndex, currentObject) {
}
findIndex(list = [], id) {
}
insertItem(targetId, currentId, type = "before") {
}
insertBefore(targetId, currentId) {
}
insertAfter(targetId, currentId) {
}
insertLast(parentId, childId) {
}
}
class TreeViewProvider extends BaseTreeViewProvider {
constructor(items = []) {
super();
__privateAdd(this, _initialize);
__privateAdd(this, _traverse);
__privateAdd(this, _idMap, {});
__privateAdd(this, _items, []);
__privateAdd(this, _parentList, {});
__privateSet(this, _items, items);
__privateMethod(this, _initialize, initialize_fn).call(this);
}
get items() {
return __privateGet(this, _items);
}
get ids() {
return Object.keys(__privateGet(this, _idMap));
}
has(id) {
return Boolean(__privateGet(this, _idMap)[id]);
}
get(id) {
return __privateGet(this, _idMap)[id];
}
set(id, obj) {
const target = this.get(id);
if (target) {
Object.assign(target, obj);
} else {
__privateGet(this, _idMap)[id] = obj;
}
}
remove(id) {
const obj = __privateGet(this, _idMap)[id];
delete __privateGet(this, _idMap)[id];
return obj;
}
setParent(targetId, parentId) {
__privateGet(this, _parentList)[targetId] = parentId;
}
removeParent(targetId) {
delete __privateGet(this, _parentList)[targetId];
}
appendChild(parentId, obj) {
const parent = this.get(parentId);
if (!parent)
return;
if (!obj.id)
throw new Error("obj.id is required.");
if (isArray(parent.children)) {
parent.children.push(obj);
} else {
parent.children = [obj];
}
this.set(obj.id, obj);
this.setParent(obj.id, parentId);
return obj;
}
getParentId(childId) {
return __privateGet(this, _parentList)[childId];
}
deleteInfo(childObj) {
if (childObj) {
this.remove(childObj.id);
this.removeParent(childObj.id);
return childObj;
}
}
removeChild(parentId, childId) {
var _a;
const parent = this.get(parentId);
const index = this.findIndex(parent.children, childId);
if (index < 0) {
return;
}
let childObj;
if (parent) {
[childObj] = parent.children.splice(index, 1);
if (((_a = parent.children) == null ? void 0 : _a.length) === 0) {
delete parent.children;
}
} else {
[childObj] = __privateGet(this, _items).splice(index, 1);
}
return this.deleteInfo(childObj);
}
insertChild(targetParentId, targetIndex, currentObject) {
const targetParent = this.get(targetParentId);
this.set(currentObject.id, currentObject);
if (targetParent) {
targetParent.children.splice(targetIndex, 0, currentObject);
this.setParent(currentObject.id, targetParentId);
} else {
__privateGet(this, _items).splice(targetIndex, 0, currentObject);
this.removeParent(currentObject.id);
}
}
findIndex(list = __privateGet(this, _items), id) {
return list.findIndex((it) => it.id === id);
}
insertItem(targetId, currentId, type = "before") {
const targetParentId = this.getParentId(targetId);
const targetParent = this.get(targetParentId);
const targetIndex = this.findIndex(targetParent == null ? void 0 : targetParent.children, targetId);
const currentParentId = this.getParentId(currentId);
const currentObject = this.removeChild(currentParentId, currentId);
this.insertChild(
targetParentId,
type === "before" ? targetIndex : targetIndex + 1,
currentObject
);
}
insertBefore(targetId, currentId) {
return this.insertItem(targetId, currentId, "before");
}
insertAfter(targetId, currentId) {
return this.insertItem(targetId, currentId, "after");
}
insertLast(parentId, childId) {
const lastParentId = this.getParentId(childId);
const childObj = this.removeChild(lastParentId, childId);
if (childObj) {
this.appendChild(parentId, childObj);
}
}
}
_idMap = new WeakMap();
_items = new WeakMap();
_parentList = new WeakMap();
_initialize = new WeakSet();
initialize_fn = function() {
__privateMethod(this, _traverse, traverse_fn).call(this, __privateGet(this, _items));
};
_traverse = new WeakSet();
traverse_fn = function(items = [], parentId) {
items.forEach((it) => {
var _a;
if (__privateGet(this, _idMap)[it.id])
throw new Error("id is duplicated.");
__privateGet(this, _idMap)[it.id] = it;
__privateGet(this, _parentList)[it.id] = parentId;
if ((_a = it.children) == null ? void 0 : _a.length) {
__privateMethod(this, _traverse, traverse_fn).call(this, it.children, it.id);
}
});
};
const NumberStyleKeys = {
width: true,
height: true,
top: true,
left: true,
right: true,
bottom: true,
maxWidth: true,
maxHeight: true,
minWidth: true,
minHeight: true,
margin: true,
marginTop: true,
marginRight: true,
marginBottom: true,
marginLeft: true,
padding: true,
paddingTop: true,
paddingRight: true,
paddingBottom: true,
paddingLeft: true,
border: true,
borderTop: true,
borderRight: true,
borderBottom: true,
borderLeft: true,
borderWidth: true,
borderTopWidth: true,
borderRightWidth: true,
borderBottomWidth: true,
borderLeftWidth: true,
gap: true
};
const ComponentPropsToStylePropsMap = {
alignContent: "alignContent",
alignItems: "alignItems",
alignSelf: "alignSelf",
area: "gridArea",
autoColumns: "gridAutoColumns",
autoFlow: "gridAutoFlow",
autoRows: "gridAutoRows",
backgroundColor: "backgroundColor",
backgroundImage: "backgroundImage",
basis: "flexBasis",
border: "border",
borderRadius: "borderRadius",
bottom: "bottom",
boxShadow: "boxShadow",
color: "color",
column: "gridColumn",
columnEnd: "gridColumnEnd",
columnGap: "columnGap",
columnSpan: "gridColumn",
columnStart: "gridColumnStart",
direction: "flexDirection",
display: "display",
flex: "flex",
fontFamily: "fontFamily",
fontSize: "fontSize",
fontStyle: "fontStyle",
fontWeight: "fontWeight",
gap: "gap",
grow: "flexGrow",
height: "height",
justifyContent: "justifyContent",
left: "left",
letterSpacing: "letterSpacing",
lineHeight: "lineHeight",
margin: "margin",
marginBlock: "marginBlock",
marginBlockEnd: "marginBlockEnd",
marginBlockStart: "marginBlockStart",
marginBottom: "marginBlockEnd",
marginInline: "marginInline",
marginInlineEnd: "marginInlineEnd",
marginInlineStart: "marginInlineStart",
marginLeft: "marginInlineStart",
marginRight: "marginInlineEnd",
marginTop: "marginBlockStart",
maxHeight: "maxHeight",
maxWidth: "maxWidth",
minHeight: "minHeight",
minWidth: "minWidth",
objectFit: "objectFit",
objectPosition: "objectPosition",
opacity: "opacity",
order: "order",
overflow: "overflow",
padding: "padding",
paddingBlock: "paddingBlock",
paddingBlockEnd: "paddingBlockEnd",
paddingBlockStart: "paddingBlockStart",
paddingBottom: "paddingBlockEnd",
paddingInline: "paddingInline",
paddingInlineEnd: "paddingInlineEnd",
paddingInlineStart: "paddingInlineStart",
paddingLeft: "paddingInlineStart",
paddingRight: "paddingInlineEnd",
paddingTop: "paddingBlockStart",
position: "position",
resize: "resize",
right: "right",
row: "gridRow",
rowEnd: "gridRowEnd",
rowGap: "rowGap",
rowSpan: "gridRow",
rowStart: "gridRowStart",
shrink: "flexShrink",
templateAreas: "gridTemplateAreas",
templateColumns: "gridTemplateColumns",
templateRows: "gridTemplateRows",
textAlign: "textAlign",
textDecoration: "textDecoration",
textTransform: "textTransform",
top: "top",
transform: "transform",
transformOrigin: "transformOrigin",
width: "width",
whiteSpace: "whiteSpace",
wrap: "flexWrap",
zIndex: "zIndex"
};
const styleKeys = {};
const uppercasePattern = /([A-Z])/g;
const convertStyleKey = (key) => {
if (styleKeys[key]) {
return styleKeys[key];
}
const upperKey = key.replace(uppercasePattern, "-$1").toLowerCase();
styleKeys[key] = upperKey;
return upperKey;
};
function makeCssVariablePrefixMap(prefix, obj = {}) {
const newObj = {};
Object.keys(obj).forEach((key) => {
newObj[key] = prefix + "-" + convertStyleKey(key);
});
return newObj;
}
function splitStyleKeyAndNoneStyleKey(properties) {
const style2 = {};
const noneStyle = {};
Object.keys(properties).forEach((key) => {
const value = properties[key];
const styleKey = ComponentPropsToStylePropsMap[key];
if (styleKey) {
style2[styleKey] = value;
} else {
noneStyle[key] = value;
}
});
return { style: style2, noneStyle };
}
function convertNumberStyleValue(key, value) {
if (typeof value === "number") {
if (NumberStyleKeys[key]) {
value = value + "px";
}
}
return value;
}
function propertyMap(styles = {}, mapper = {}) {
const styleObj = {};
Object.keys(styles).forEach((key) => {
if (typeof styles[key] !== "undefined") {
styleObj[mapper[key] || key] = convertNumberStyleValue(key, styles[key]);
}
});
return Object.keys(styleObj).length ? styleObj : void 0;
}
const ADD_BODY_FIRST_MOUSEMOVE = "add/body/first/mousemove";
const ADD_BODY_MOUSEMOVE = "add/body/mousemove";
const ADD_BODY_MOUSEUP = "add/body/mouseup";
const BODY_MOVE_EVENT = "body/move/event";
const FIRSTMOVE = (method = "move") => {
return AFTER(`bodyMouseFirstMove ${method}`);
};
const MOVE = (method = "move") => {
return AFTER(`bodyMouseMove ${method}`);
};
const END = (method = "end") => {
return AFTER(`bodyMouseUp ${method}`);
};
const _components = {};
function registerComponent(key, Component) {
if (key && Component) {
if (_components[key]) {
console.warn(
`Component ${key} is already registered. Rename key string for `,
Component
);
} else {
_components[key] = Component;
}
}
return Component;
}
const cssProperties$U = makeCssVariablePrefixMap("--elf--alert", {
borderColor: true,
backgroundColor: true,
selectedBackgroundColor: true,
disabledColor: true,
color: true,
fontSize: true,
fontWeight: true,
height: true,
padding: true,
borderRadius: true
});
class Alert extends UIElement {
template() {
const {
variant = "default",
title = "",
content = "",
shape = "rect",
style: style2 = {},
closable = false,
dismissable = false,
delay = 0,
actions,
weak,
icon,
...extrProps
} = this.props;
const [localDelay, setLocalDelay] = useState(delay);
const [hide, setHide] = useState(false);
this.state.hideCallback = useCallback(
(hideDelay = 0) => {
setLocalDelay(hideDelay);
},
[setLocalDelay]
);
const localClass = useMemo(() => {
return classnames("elf--alert", {
[variant]: true,
weak,
hide,
closable,
[shape]: true,
dismissable
});
}, [variant, weak, hide, closable, shape, dismissable]);
const styleObject = {
class: localClass,
style: {
...propertyMap(style2, cssProperties$U),
...{
transition: `opacity ${localDelay}ms ease-in-out`,
opacity: hide ? 0 : 1
}
},
...extrProps
};
const titleIcon = title && icon ? icon : void 0;
const contentIcon = content && icon && !title ? icon : void 0;
const titleActions = title && actions ? actions : void 0;
const contentActions = content && actions && !title ? actions : void 0;
return /* @__PURE__ */ createElementJsx(
"div",
{
...styleObject,
onContextMenu: (e) => e.preventDefault(),
onTransitionEnd: () => {
this.props.onHide && this.props.onHide();
this.destroy(true);
}
},
title ? /* @__PURE__ */ createElementJsx("div", { class: "elf--alert-title" }, titleIcon, " ", /* @__PURE__ */ createElementJsx("span", null, title), " ", titleActions ? /* @__PURE__ */ createElementJsx("div", { class: "elf--alert-actions" }, titleActions) : void 0) : null,
content ? /* @__PURE__ */ createElementJsx("div", { class: "elf--alert-content" }, contentIcon, " ", /* @__PURE__ */ createElementJsx("span", null, content), " ", contentActions ? /* @__PURE__ */ createElementJsx("div", { class: "elf--alert-actions" }, contentActions) : void 0) : null,
closable ? /* @__PURE__ */ createElementJsx(
"div",
{
class: "elf--alert-close",
onClick: () => {
setHide(true);
if (localDelay === 0) {
this.props.onHide && this.props.onHide();
this.destroy(true);
}
}
},
"×"
) : null
);
}
hide(hideDelay = 0) {
var _a;
(_a = this.state) == null ? void 0 : _a.hideCallback(hideDelay);
}
}
function alert({ content = void 0, options = {}, ...extraProps }) {
return potal(/* @__PURE__ */ createElementJsx(Alert, { ...extraProps }, content), options);
}
registerComponent("Alert", Alert);
registerComponent("alert", Alert);
const cssProperties$T = makeCssVariablePrefixMap("--elf--animation", {
name: true,
iterationCount: true,
timingFunction: true,
duration: true,
delay: true,
playState: true
});
class Animation extends UIElement {
template() {
const {
name = "spin",
delay = "0s",
iterationCount,
timingFunction,
duration = "1s",
style: style2 = {},
content,
play = false,
onEnd: onAnimationEnd,
onIteration: onAnimationIteration,
onStart: onAnimationStart,
onCancel: onAnimationCancel
} = this.props;
const styleObject = {
class: "elf--animation",
style: propertyMap(
{
...style2,
duration,
name,
iterationCount,
timingFunction,
delay,
playState: play ? "running" : "paused"
},
cssProperties$T
),
onAnimationStart,
onAnimationEnd,
onAnimationIteration,
onAnimationCancel
};
return /* @__PURE__ */ createElementJsx("div", { ...styleObject }, content);
}
}
Animation.spin = function(props) {
return /* @__PURE__ */ createElementJsx(Animation, { ...props, name: "spin" });
};
Animation.ping = function(props) {
return /* @__PURE__ */ createElementJsx(Animation, { ...props, name: "ping" });
};
Animation.fade = function(props) {
return /* @__PURE__ */ createElementJsx(Animation, { ...props, name: "fade" });
};
Animation.scaledown = function(props) {
return /* @__PURE__ */ createElementJsx(Animation, { ...props, name: "scaledown" });
};
Animation.bounce = function(props) {
return /* @__PURE__ */ createElementJsx(Animation, { ...props, name: "bounce" });
};
Animation.flash = function(props) {
return /* @__PURE__ */ createElementJsx(Animation, { ...props, name: "flash" });
};
Animation.pulse = function(props) {
return /* @__PURE__ */ createElementJsx(Animation, { ...props, name: "pulse" });
};
Animation.rubberBand = function(props) {
return /* @__PURE__ */ createElementJsx(Animation, { ...props, name: "rubberBand" });
};
Animation.shake = function(props) {
return /* @__PURE__ */ createElementJsx(Animation, { ...props, name: "shake" });
};
Animation.headShake = function(props) {
return /* @__PURE__ */ createElementJsx(Animation, { ...props, name: "headShake" });
};
Animation.swing = function(props) {
return /* @__PURE__ */ createElementJsx(Animation, { ...props, name: "swing" });
};
Animation.tada = function(props) {
return /* @__PURE__ */ createElementJsx(Animation, { ...props, name: "tada" });
};
Animation.wobble = function(props) {
return /* @__PURE__ */ createElementJsx(Animation, { ...props, name: "wobble" });
};
Animation.jello = function(props) {
return /* @__PURE__ */ createElementJsx(Animation, { ...props, name: "jello" });
};
Animation.heartBeat = function(props) {
return /* @__PURE__ */ createElementJsx(Animation, { ...props, name: "heartBeat" });
};
registerComponent("animation", Animation);
registerComponent("Animation", Animation);
const cssProperties$S = makeCssVariablePrefixMap("--elf--progress-circle", {
backgroundColor: true,
color: true,
duration: true,
offset: true,
width: true
});
class ProgressCircle extends UIElement {
template() {
const {
min = 0,
max = 100,
value = min,
variant = "default",
size = "medium",
style: style2 = {},
indeterminate = false,
animated = false,
animationType = "normal"
} = this.props;
const localClass = useMemo(() => {
return classnames("elf--progress-circle", {
[variant]: true,
[size]: true,
animated,
indeterminate,
[animationType]: true
});
}, [variant, size, indeterminate, animated, animationType]);
const percentValue = (value - min) / (max - min);
const styleObject = {
class: localClass,
style: propertyMap(
{
...style2,
offset: percentValue
},
cssProperties$S
)
};
return /* @__PURE__ */ createElementJsx("div", { ...styleObject }, /* @__PURE__ */ createElementJsx("div", { class: "progress-area" }, /* @__PURE__ */ createElementJsx("svg", null, /* @__PURE__ */ createElementJsx("circle", { class: "progress-circle track", r: "50%", cx: "50%", cy: "50%" }), /* @__PURE__ */ createElementJsx("circle", { class: "progress-circle fill", r: "50%", cx: "50%", cy: "50%" }))));
}
}
registerComponent("progress-circle", ProgressCircle);
registerComponent("progresscircle", ProgressCircle);
registerComponent("ProgressCircle", ProgressCircle);
const cssProperties$R = makeCssVariablePrefixMap("--elf--button", {
borderColor: true,
backgroundColor: true,
selectedBackgroundColor: true,
disabledColor: true,
color: true,
textColor: true,
fontSize: true,
fontWeight: true,
height: true,
padding: true,
borderRadius: true
});
class Button extends UIElement {
template() {
const {
variant = "default",
size = "medium",
disabled,
selected,
focused,
shape = "none",
quiet = false,
outline = false,
thin = false,
closable = false,
place = "",
style: style2 = {},
href = "",
target = "_blank",
content,
class: className,
iconOnly = false,
justified = false,
pending = false,
play = false,
hover = false,
as = "button",
hasMinWidth = false,
...extraProps
} = this.props;
const localClass = useMemo(() => {
return classnames([
"elf--button",
{
outline,
focused,
quiet,
selected,
closable,
justified,
[variant]: true,
[size]: true,
[shape]: true,
[place]: true,
thin,
hover,
"icon-only": iconOnly,
"has-min-width": hasMinWidth
},
className
]);
}, [
variant,
size,
selected,
shape,
quiet,
outline,
place,
closable,
iconOnly,
className,
justified,
focused,
hover,
hasMinWidth,
thin
]);
const styleObject = {
class: localClass,
disabled: disabled ? "disabled" : void 0,
style: propertyMap(style2, cssProperties$R),
...extraProps
};
const buttonContent = /* @__PURE__ */ createElementJsx("span", null, pending ? /* @__PURE__ */ createElementJsx(Animation.spin, { play }, /* @__PURE__ */ createElementJsx(ProgressCircle, { value: 80, size, variant })) : content || "");
if (as === "link") {
return /* @__PURE__ */ createElementJsx("a", { ...styleObject, href, target }, buttonContent);
} else {
return /* @__PURE__ */ createElementJsx("button", { ...styleObject }, buttonContent);
}
}
}
registerComponent("button", Button);
registerComponent("btn", Button);
registerComponent("Button", Button);
const cssProperties$Q = makeCssVariablePrefixMap("--elf--tooltip", {
backgroundColor: true,
color: true,
height: true,
hoverColor: true,
borderColor: true,
boxShadow: true,
toolsBorderColor: true,
toolsBorderRadius: true,
hgap: true,
vgap: true,
delay: true,
contentPadding: true,
maxWidth: true,
position: true
});
const TooltipPlacement = {
TOP: "top",
BOTTOM: "bottom",
LEFT: "left",
RIGHT: "right",
BOTTOM_LEFT: "bottom-left",
BOTTOM_RIGHT: "bottom-right",
TOP_LEFT: "top-left",
TOP_RIGHT: "top-right"
};
class Tooltip extends UIElement {
initState() {
const trigger = this.props.trigger || "hover";
return {
trigger: isString(trigger) ? [trigger] : trigger,
delay: 1e3,
show: this.props.show || false
};
}
template() {
const {
style: style2 = {},
message = "",
content,
placement = "bottom",
animated = false,
hideArrow = false,
variant = "default",
position = "relative",
icon
} = this.props;
const { show } = this.state;
const localClass = useMemo(() => {
return classnames("elf--tooltip", {
[placement]: true,
animated,
[variant]: true,
[position]: true
});
}, [placement, animated, variant, position]);
const styleObject = {
class: localClass,
style: propertyMap(style2, cssProperties$Q)
};
return /* @__PURE__ */ createElementJsx("div", { ...styleObject }, /* @__PURE__ */ createElementJsx("div", { class: "content" }, content), show || this.props.show ? /* @__PURE__ */ createElementJsx("div", { class: "message" }, hideArrow ? void 0 : /* @__PURE__ */ createElementJsx("div", { class: "arrow" }), icon ? /* @__PURE__ */ createElementJsx("div", { class: "icon" }, icon) : void 0, /* @__PURE__ */ createElementJsx("div", { class: "message-content" }, /* @__PURE__ */ createElementJsx("div", null, message))) : void 0);
}
show() {
this.open();
}
hide() {
this.close();
}
open() {
this.setState({
show: true
});
}
close() {
setTimeout(() => {
this.setState({
show: false
});
}, this.props.hideDelay);
}
toggle() {
this.setState({
show: !this.state.show
});
}
checkTriggerClick() {
return this.state.trigger.includes("click");
}
checkTriggerOver() {
return this.state.trigger.includes("hover");
}
checkTriggerFocus() {
return this.state.trigger.includes("focus");
}
[POINTERENTER("$el") + IF("checkTriggerOver")]() {
this.open();
}
[POINTERLEAVE("$el") + IF("checkTriggerOver")]() {
this.close();
}
[CLICK("$el") + IF("checkTriggerClick")]() {
this.toggle();
}
[FOCUS("$el") + IF("checkTriggerFocus")]() {
this.open();
}
remove() {
this.$el.remove();
}
}
function tooltip({
content,
message = "",
delay = 0,
position = "fixed",
placement = "top",
options = {},
style: style2,
variant = "default"
}) {
const tooltipInstance = potal(
/* @__PURE__ */ createElementJsx(
Tooltip,
{
variant,
delay,
position,
placement,
message,
style: style2,
show: true
},
content || /* @__PURE__ */ createElementJsx("span", null, " ")
),
options
);
return tooltipInstance;
}
const cssProperties$P = makeCssVariablePrefixMap("--elf--action-group", {
alignItems: true,
gap: true
});
class ActionGroup extends UIElement {
template() {
const {
direction = "horizontal",
quiet = false,
compact = false,
justified = false,
collapsed = false,
moreIcon = null,
boundary = 50,
style: style2 = {},
content,
shape = "normal",
...extraStyle
} = this.props;
const [visibleTargetList, setVisibilityTargetList] = useState([]);
const [rootRect, setRootRect] = useState(null);
const { style: styleProperties } = splitStyleKeyAndNoneStyleKey(extraStyle);
useEffect(() => {
var _a;
if (!collapsed)
return;
const list = [];
let totalWidth = 0;
const localRect = (_a = this.$el) == null ? void 0 : _a.rect();
if (!localRect)
return;
this.$el.children().forEach((child, index) => {
if (child.hasClass("hidden-tools"))
return;
const rect = child.rect();
let isVisible = rect.right + boundary < localRect.right;
if (isVisible) {
totalWidth += rect.width;
if (totalWidth + boundary > localRect.width) {
totalWidth = localRect.width - boundary;
isVisible = false;
}
}
list[index] = isVisible;
});
setVisibilityTargetList(list);
}, [collapsed, rootRect]);
useEffect(() => {
let resizeObserver;
if (collapsed) {
resizeObserver = new ResizeObserver((entries) => {
entries.forEach((entry) => {
setRootRect(Dom.create(entry.target).rect());
});
});
if (!this.$el)
return;
resizeObserver.observe(this.getEl());
}
return () => {
resizeObserver == null ? void 0 : resizeObserver.disconnect();
};
}, [collapsed]);
const localClass = useMemo(() => {
return classnames("elf--action-group", {
[direction]: true,
quiet,
compact,
collapsed,
justified,
[shape]: true
});
}, [direction, quiet, compact, collapsed, justified, shape]);
const styleObject = {
class: localClass,
style: propertyMap(
{
...style2,
...styleProperties
},
cssProperties$P
)
};
const items = collapsed ? content.filter((item, index) => {
return visibleTargetList[index];
}) : content;
const hiddenItems = collapsed ? content.filter((item, index) => {
return !visibleTargetList[index];
}) : [];
return /* @__PURE__ */ createElementJsx("div", { ...styleObject }, items, hiddenItems.length ? /* @__PURE__ */ createElementJsx(
Tooltip,
{
message: hiddenItems,
trigger: "click",
hideArrow: true,
position: "bottom-left",
style: { contentPadding: "0px" }
},
/* @__PURE__ */ createElementJsx(Button, { iconOnly: true }, moreIcon)
) : void 0);
}
}
registerComponent("action-group", ActionGroup);
registerComponent("ActionGroup", ActionGroup);
function RoundButton({ content, ...props }) {
return /* @__PURE__ */ createElementJsx(Button, { ...props, shape: "round" }, content);
}
function OutlineButton({ content, ...props }) {
return /* @__PURE__ */ createElementJsx(Button, { ...props, outline: true }, content);
}
function IconButton({ content, ...props }) {
return /* @__PURE__ */ createElementJsx(RoundButton, { ...props, iconOnly: true }, content);
}
registerComponent("icon-button", IconButton);
registerComponent("iconbutton", IconButton);
registerComponent("IconButton", IconButton);
const cssProperties$O = makeCssVariablePrefixMap("--elf--link-button", {
borderColor: true,
backgroundColor: true,
disabledColor: true,
color: true,
fontSize: true,
fontWeight: true,
padding: true
});
class LinkButton extends UIElement {
template() {
const { disabled, style: style2 = {}, content, onClick, href } = this.props;
const styleObject = {
class: "elf--link-button",
disabled: disabled ? "disabled" : void 0,
style: {
...propertyMap(style2, cssProperties$O)
}
};
return /* @__PURE__ */ createElementJsx("a", { ...styleObject, onClick, href: href || "#" }, /* @__PURE__ */ createElementJsx("span", null, content || ""));
}
}
registerComponent("link-button", LinkButton);
registerComponent("linkbutton", LinkButton);
registerComponent("LinkButton", LinkButton);
const cssProperties$N = makeCssVariablePrefixMap("--elf--radio", {
borderColor: true,
backgroundColor: true,
disabledColor: true,
color: true,
fontSize: true,
fontWeight: true,
height: true,
padding: true,
borderRadius: true
});
class Radio extends UIElement {
template() {
const {
disabled,
style: style2 = {},
value,
content,
name,
checked = false,
onChange,
size = "medium",
variant = "default"
} = this.props;
const localClass = useMemo(() => {
return classnames([
"elf--radio",
{
disabled,
[size]: true,
[variant]: true
}
]);
}, [disabled, size, variant]);
const styleObject = {
class: localClass,
style: propertyMap(style2, cssProperties$N)
};
return /* @__PURE__ */ createElementJsx("div", { ...styleObject }, /* @__PURE__ */ createElementJsx("label", null, /* @__PURE__ */ createElementJsx(
"input",
{
ref: "$input",
type: "radio",
...{
value,
name,
disabled: disabled ? "disabled" : void 0,
checked: checked ? "checked" : void 0
},
onChange: (e) => onChange == null ? void 0 : onChange(e, value)
}
), content));
}
}
registerComponent("radio", Radio);
registerComponent("Radio", Radio);
const cssProperties$M = makeCssVariablePrefixMap("--elf--radio", {
borderColor: true,
backgroundColor: true,
disabledColor: true,
color: true,
fontSize: true,
fontWeight: true,
height: true,
padding: true,
borderRadius: true
});
class RadioGroup extends UIElement {
template() {
const {
disabled,
style: style2 = {},
name,
value,
options = [],
onChange,
direction = "horizontal",
size = "medium",
variant = "default"
} = this.props;
const localClass = useMemo(() => {
return classnames("elf--radio-group", {
[direction]: true
});
}, [direction]);
const styleObject = {
class: localClass,
disabled: disabled ? "disabled" : void 0,
style: propertyMap(style2, cssProperties$M)
};
const radioName = name || "name-" + this.id;
return /* @__PURE__ */ createElementJsx("div", { ...styleObject }, options.map((it, index) => {
const checked = it.value === value;
return /* @__PURE__ */ createElementJsx(
Radio,
{
ref: `$${index}`,
name: radioName,
value: it.value,
onChange: (e, v) => {
this.setState({ value: v }, false);
onChange(e, v);
},
checked,
disabled,
size,
variant
},
it.label
);
}));
}
get value() {
return this.state.value || this.props.value;
}
set value(value) {
this.setState({ value });
}
}
registerComponent("RadioGroup", RadioGroup);
registerComponent("radio-group", RadioGroup);
registerComponent("radiogroup", RadioGroup);
const cssProperties$L = {
borderColor: "--elf--checkbox-border-color",
backgroundColor: "--elf--checkbox-background",
disabledColor: "--elf--checkbox-disabled-color",
color: "--elf--checkbox-color",
fontSize: "--elf--checkbox-font-size",
fontWeight: "--elf--checkbox-font-weight",
height: "--elf--checkbox-height",
padding: "--elf--checkbox-padding",
borderRadius: "--elf--checkbox-border-radius"
};
class Checkbox extends UIElement {
template() {
const {
disabled,
style: style2 = {},
value,
content,
name,
checked = false,
onChange,
indeterminate = false,
variant = "default",
size = "medium"
} = this.props;
const styleObject = {
class: classnames([
"elf--checkbox",
{
disabled,
[variant]: true,
[size]: true
}
]),
style: {
...propertyMap(style2, cssProperties$L)
}
};
return /* @__PURE__ */ createElementJsx("div", { ...styleObject }, /* @__PURE__ */ createElementJsx("label", null, /* @__PURE__ */ createElementJsx(
"input",
{
ref: "$input",
type: "checkbox",
...{
indeterminate,
value,
name,
disabled: disabled ? "disabled" : void 0,
checked: checked ? "checked" : void 0
},
onChange: (e) => onChange == null ? void 0 : onChange(e, value)
}
), (content == null ? void 0 : content.length) ? /* @__PURE__ */ createElementJsx("span", { class: "text" }, content) : void 0));
}
get checked() {
return this.refs.$input.checked;
}
get value() {
return this.props.value;
}
}
registerComponent("Checkbox", Checkbox);
registerComponent("checkbox", Checkbox);
const cssProperties$K = {
borderColor: "--elf--checkbox-border-color",
backgroundColor: "--elf--checkbox-background",
disabledColor: "--elf--checkbox-disabled-color",
color: "--elf--checkbox-color",
fontSize: "--elf--checkbox-font-size",
fontWeight: "--elf--checkbox-font-weight",
height: "--elf--checkbox-height",
padding: "--elf--checkbox-padding",
borderRadius: "--elf--checkbox-border-radius"
};
class CheckboxGroup extends UIElement {
initState() {
return {
value: this.props.value || []
};
}
template() {
const {
disabled,
style: style2 = {},
value = [],
options = [],
onChange,
direction = "horizontal",
size = "medium",
variant = "default"
} = this.props;
const styleObject = {
class: classnames([
"elf--checkbox-group",
{
[direction]: true
}
]),
disabled: disabled ? "disabled" : void 0,
style: {
...propertyMap(style2, cssProperties$K)
}
};
return /* @__PURE__ */ createElementJsx("div", { ...styleObject }, options.map((it, index) => {
return /* @__PURE__ */ createElementJsx(
Checkbox,
{
ref: `checkbox-${index}`,
value: it.value,
onChange: (e) => {
onChange(e, this.getValues());
},
checked: value == null ? void 0 : value.includes(it.value),
disabled,
indeterminate: it.indeterminate,
size,
variant
},
it.label
);
}));
}
getValues() {
const values = [];
Object.keys(this.children).forEach((key) => {
const child = this.children[key];
if (child.checked) {
values.push(child.value);
}
});
return values;
}
get disabled() {
return this.props.disabled;
}
get value() {
return this.getValues();
}
set value(values = []) {
this.setState({ values });
}
}
registerComponent("checkbox-group", CheckboxGroup);
registerComponent("CheckboxGroup", CheckboxGroup);
const cssProperties$J = makeCssVariablePrefixMap("--elf--divider", {
color: true,
margin: true,
height: true,
borderStyle: true
});
class Divider extends UIElement {
template() {
const {
style: style2 = {},
variant = "default",
size = "small",
margin = "10px",
orientation = "horizontal"
} = this.props;
const localClass = useMemo(() => {
return classnames("elf--divider", {
[size]: true,
[variant]: true,
[orientation]: true
});
}, [size, variant, orientation]);
const styleObject = {
class: localClass,
style: {
...propertyMap(
{
...style2,
margin
},
cssProperties$J
)
}
};
return /* @__PURE__ */ createElementJsx("div", { ...styleObject }, /* @__PURE__ */ createElementJsx("div", { className: "elf--divider-inner" }));
}
}
registerComponent("divider", Divider);
registerComponent("Divider", Divider);
const MenuItemType = {
DIVIDER: "divider",
SECTION: "section",
MENU: "menu",
ITEM: "item",
CUSTOM: "custom",
LINK: "link"
};
function makeMenuItem(items = [], variant, rootClose) {
return items.map((it, index) => {
const ref = `${it.type || "item"}${index}`;
if (isString(it) && it === "-") {
return /* @__PURE__ */ createElementJsx(DividerMenuItem, { ref, variant, rootClose });
} else if (isFunction(it)) {
return /* @__PURE__ */ createElementJsx(
CustomMenuItem,
{
variant,
ref: `custom${index}`,
render: it,
rootClose
}
);
} else if (it.type === MenuItemType.CUSTOM) {
return /* @__PURE__ */ createElementJsx(
CustomMenuItem,
{
variant,
ref,
...it,
rootClose
}
);
} else if (it.type === MenuItemType.LINK) {
return /* @__PURE__ */ createElementJsx(
LinkMenuItem,
{
variant,
ref,
...it,
rootClose
}
);
} else if (it.type === MenuItemType.SECTION) {
return /* @__PURE__ */ createElementJsx(
SectionMenuItem,
{
variant,
ref,
...it,
rootClose
}
);
} else if (it.type === MenuItemType.DIVIDER) {
return /* @__PURE__ */ createElementJsx(
DividerMenuItem,
{
variant,
ref,
...it,
rootClose
}
);
}
return /* @__PURE__ */ createElementJsx(MenuItem, { ref, variant, ...it, rootClose });
});
}
function DividerMenuItem({ dashed = false }) {
return /* @__PURE__ */ createElementJsx("li", { class: "elf--divider", dashed });
}
function CustomMenuItem({ render, rootClose }) {
return /* @__PURE__ */ createElementJsx("li", { class: "custom" }, render == null ? void 0 : render({ rootClose }));
}
function LinkMenuItem({ rootClose, title, link }) {
return /* @__PURE__ */ createElementJsx("li", { class: "link" }, /* @__PURE__ */ createElementJsx("a", { href: link, onClick: rootClose }, title));
}
function SectionMenuItem({ title = "" }) {
return /* @__PURE__ */ createElementJsx("li", { class: "section-title" }, title);
}
class MenuItem extends UIElement {
initState() {
const {
title = "",
hover = false,
shortcut,
icon,
items = [],
disabled = false,
selectable,
selected,
selectedIcon = "✓",
closable = true,
rootClose,
description,
variant
} = this.props;
return {
title,
hover,
shortcut,
icon,
items,
selectable,
selected,
selectedIcon,
disabled,
closable,
rootClose,
description,
variant
};
}
template() {
const {
title = "",
shortcut,
icon,
expandIcon = "▶",
items = [],
hover,
selected,
selectable,
selectedIcon,
disabled,
rootClose,
description,
variant,
show = false
} = this.state;
const hasItems = items.length > 0;
const selectedValue = isFunction(selected) ? selected() : selected;
const localClass = useMemo(() => {
return classnames({
hover
});
}, [hover]);
return /* @__PURE__ */ createElementJsx("li", { class: localClass, disabled: disabled ? true : void 0 }, /* @__PURE__ */ createElementJsx("div", { class: "menu-item-content" }, selectable ? /* @__PURE__ */ createElementJsx("span", { class: "selected-icon" }, selectedValue ? selectedIcon : void 0) : null, icon ? /* @__PURE__ */ createElementJsx("div", { class: "icon" }, icon) : void 0, title ? /* @__PURE__ */ createElementJsx("div", { class: "menu-title" }, title) : void 0, shortcut || hasItems ? /* @__PURE__ */ createElementJsx("div", { class: "value-area" }, shortcut ? /* @__PURE__ */ createElementJsx("div", { class: "shortcut" }, shortcut) : void 0, hasItems ? /* @__PURE__ */ createElementJsx("div", { class: "icon" }, expandIcon) : void 0) : void 0), description ? /* @__PURE__ */ createElementJsx("div", { class: "menu-item-description" }, description) : void 0, items.length > 0 || show ? /* @__PURE__ */ createElementJsx(Menu, { items, variant, rootClose }) : void 0);
}
checkClickable() {
if (this.state.disabled) {
return false;
}
const { type = MenuItemType.ITEM, items = [] } = this.props;
return type === MenuItemType.ITEM && items.length === 0;
}
[CLICK("$el") + IF("checkClickable") + PREVENT + STOP](e) {
var _a, _b;
const { selectable = false, onClick, closable = true } = this.props;
if (selectable) {
this.setSelected(!this.selected);
}
if (isFunction(onClick)) {
onClick(e, this);
}
if (closable) {
(_b = (_a = this.props).rootClose) == null ? void 0 : _b.call(_a);
}
}
setSelected(isSelected = false) {
this.setState({
selected: isSelected
});
}
get selected() {
return this.state.selected;
}
}
const cssProperties$I = makeCssVariablePrefixMap("--elf--menu", {
left: true,
top: true,
backgroundColor: true,
color: true,
fontSize: true,
fontWeight: true,
height: true,
padding: true,
borderRadius: true,
borderColor: true,
boxShadow: true,
width: true,
maxWidth: true,
sectionTitleColor: true,
sectionTitleBackgroundColor: true,
dividerColor: true,
directionLeft: true,
itemPadding: true
});
class Menu extends UIElement {
template() {
let {
style: style2 = {},
type = "menu",
x = 0,
y = 0,
direction = "left",
items = [],
rootClose,
autoPosition = false,
variant = "light",
compact = false
} = this.props;
let itemStyle = { ...style2 };
if (x !== 0)
itemStyle = { ...itemStyle, left: x };
if (y !== 0)
itemStyle = { ...itemStyle, top: y };
if (autoPosition) {
const index = items.findIndex((it) => {
return it.selectable && it.selected;
});
itemStyle = { ...itemStyle, top: -1 * (index * 24 + 8) };
}
const localClass = useMemo(() => {
return classnames("elf--menu", {
[type]: true,
[variant]: true,
compact
});
}, [type, variant, compact]);
const styleObject = {
"data-direction": direction,
class: localClass,
style: propertyMap(itemStyle, cssProperties$I)
};
return /* @__PURE__ */ createElementJsx("menu", { ...styleObject, onContextMenu: (e) => e.preventDefault() }, makeMenuItem(items, variant, rootClose));
}
[OBSERVER("intersection") + PARAMS({
root: document.body
})](intersects = []) {
const item = intersects.find(
(it) => it.isIntersecting && it.intersectionRatio < 1
);
if (item) {
const { left: bLeft, right: bRight } = item.boundingClientRect;
const { left: iLeft, right: iRight } = item.intersectionRect;
let direction = "left";
if (iRight != bRight && iLeft != bLeft) {
direction = "center";
} else if (iRight != bRight) {
direction = "right";
}
this.$el.attr("data-direction", direction);
}
}
}
registerComponent("Menu", Menu);
registerComponent("MenuItem", MenuItem);
registerComponent("SectionMenuItem", SectionMenuItem);
registerComponent("DividerMenuItem", DividerMenuItem);
registerComponent("menu", Menu);
registerComponent("menuitem", MenuItem);
registerComponent("sectionmenuitem", SectionMenuItem);
registerComponent("dividermenuitem", DividerMenuItem);
registerComponent("menu-item", MenuItem);
registerComponent("section-menu-item", SectionMenuItem);
registerComponent("divider-menu-item", DividerMenuItem);
function ArrowIcon() {
return /* @__PURE__ */ createElementJsx("svg", { viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ createElementJsx("path", { d: "M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z" }));
}
const cssProperties$H = makeCssVariablePrefixMap("--elf--option-menu", {
backgroundColor: true,
color: true,
width: true
});
class OptionMenu extends UIElement {
template() {
const {
icon,
content,
items,
quiet,
menuStyle = {},
disabled = void 0,
autoPosition = false,
style: style2
} = this.props;
const { isOpen } = this.state;
const showMenu = isOpen && items;
const localClass = useMemo(() => {
return classnames("elf--option-menu", {
quiet
});
}, [quiet]);
const styleObject = {
class: localClass,
disabled,
style: propertyMap(style2, cssProperties$H)
};
return /* @__PURE__ */ createElementJsx("div", { ...styleObject }, /* @__PURE__ */ createElementJsx(
"div",
{
class: "content",
onClick: () => {
this.setState({
isOpen: !this.state.isOpen
});
}
},
icon ? /* @__PURE__ */ createElementJsx("div", { class: "elf--option-menu-icon" }, icon) : void 0,
/* @__PURE__ */ createElementJsx("div", { class: "text" }, content),
/* @__PURE__ */ createElementJsx("div", { class: "arrow" }, /* @__PURE__ */ createElementJsx(ArrowIcon, null))
), showMenu ? /* @__PURE__ */ createElementJsx("div", { class: "menu-area" }, /* @__PURE__ */ createElementJsx(
Menu,
{
type: "dropdown",
autoPosition,
rootClose: () => {
this.close();
},
style: menuStyle,
items
}
)) : void 0);
}
close() {
this.setState({
isOpen: false
});
}
checkClickable(e) {
const $menu = Dom.create(e.target).closest("menu-area");
if ($menu)
return false;
return true;
}
checkNotInMenu(e) {
const $menu = Dom.create(e.target).closest("elf--option-menu");
if (!$menu)
return true;
return this.$el.is($menu) === false;
}
[CLICK("document") + IF("checkClickable") + IF("checkNotInMenu")]() {
this.close();
}
}
registerComponent("OptionMenu", OptionMenu);
registerComponent("optionmenu", OptionMenu);
registerComponent("option-menu", OptionMenu);
const cssProperties$G = makeCssVariablePrefixMap("--elf--dialog", {
position: true,
backgroundColor: true,
color: true,
fontSize: true,
fontWeight: true,
padding: true,
borderRadius: true,
borderColor: true,
boxShadow: true,
width: true,
height: true
});
class Dialog extends UIElement {
initState() {
const { visible = false, style: style2 = {}, center } = this.props;
return {
visible,
style: style2,
center
};
}
close() {
const { onClose } = this.props;
if (isFunction(onClose)) {
onClose(this);
}
}
ok() {
const { onOk } = this.props;
if (isFunction(onOk)) {
onOk(this);
}
}
cancel() {
const { onCancel } = this.props;
if (isFunction(onCancel)) {
onCancel(this);
}
}
makeDefaultTools() {
const {
footer,
cancelText = "Cancel",
okText = "OK",
okProps = {},
cancelProps = {}
} = this.props;
if