@variantjs/vue
Version:
Vue VariantJS: Fully configurable Vue 3 components styled with TailwindCSS
1,448 lines • 179 kB
JavaScript
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
(function(global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("vue"), require("@variantjs/core"), require("@popperjs/core")) : typeof define === "function" && define.amd ? define(["exports", "vue", "@variantjs/core", "@popperjs/core"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.VariantJS = {}, global.Vue, global.core, global.core$1));
})(this, function(exports2, vue, core, core$1) {
"use strict";
class Emitter {
constructor() {
__publicField(this, "events", {});
}
on(name, callback) {
if (this.events[name] === void 0) {
this.events[name] = [callback];
} else {
this.events[name].push(callback);
}
}
once(name, callback) {
const listener = (...args) => {
callback(...args);
this.off(name, listener);
};
return this.on(name, listener);
}
emit(name, ...args) {
const events = this.events[name];
if (events === void 0) {
return;
}
events.forEach((callback) => {
callback(...args);
});
}
off(name, callback) {
const events = this.events[name];
if (events === void 0) {
return;
}
const index = events.findIndex((c) => c === callback);
if (index < 0) {
return;
}
events.splice(index, 1);
this.events[name] = events;
}
}
const getVariantProps = () => ({
classes: {
type: [String, Array, Object],
default: void 0
},
fixedClasses: {
type: [String, Array, Object],
default: void 0
},
variants: {
type: Object,
default: void 0
},
variant: {
type: String,
default: void 0
}
});
const getVariantPropsWithClassesList = () => ({
classes: {
type: [String, Array, Object],
default: void 0
},
fixedClasses: {
type: [String, Array, Object],
default: void 0
},
variants: {
type: Object,
default: void 0
},
variant: {
type: String,
default: void 0
}
});
const sameWidthModifier = {
name: "sameWidth",
enabled: true,
phase: "beforeWrite",
requires: ["computeStyles"],
fn: (options) => {
const { state } = options;
state.styles.popper.width = `${state.rects.reference.width}px`;
},
effect: (options) => {
const { state } = options;
const reference = state.elements.reference;
state.elements.popper.style.width = `${reference.offsetWidth}px`;
}
};
const icons = {};
const svgToVueComponent = (el, deep = 0) => {
let iconAsString = null;
if (deep === 0) {
iconAsString = typeof el === "string" ? el : el.outerHTML;
if (icons[iconAsString]) {
return icons[iconAsString];
}
}
let elToConvert = el;
if (typeof elToConvert === "string") {
const div = document.createElement("div");
div.innerHTML = elToConvert;
elToConvert = div.firstElementChild;
}
if (elToConvert === null) {
return vue.h("span");
}
const attributes = Array.from(elToConvert.attributes);
const children = Array.from(elToConvert.children);
const attrs = {};
attributes.filter((attribute) => !attribute.name.startsWith("on")).forEach((attribute) => {
attrs[attribute.name] = attribute.value;
});
const component = vue.h(elToConvert.tagName, attrs, children.map((child) => svgToVueComponent(child, deep + 1)));
if (deep === 0 && iconAsString !== null) {
icons[iconAsString] = component;
}
return component;
};
const extractDefinedProps = (vm) => {
const validProps = Object.keys(vm.props);
const definedProps = Object.keys(vm.vnode.props || {}).map((propName) => vue.camelize(propName)).filter((propName) => validProps.includes(propName) && propName !== "modelValue");
return definedProps;
};
function useAttributes(configuration) {
const vm = vue.getCurrentInstance();
const computedAttributes = vue.computed(() => {
const availableProps = Object.keys(vm.props);
return core.pick(configuration, (value, key) => core.isPrimitive(value) && !availableProps.includes(String(key)));
});
const attributes = vue.reactive(computedAttributes.value);
vue.watch(computedAttributes, (newValue) => {
Object.keys(newValue).forEach((key) => {
if (!core.isEqual(attributes[key], newValue[key])) {
attributes[key] = newValue[key];
}
});
});
return attributes;
}
function useConfigurationParts() {
const vm = vue.getCurrentInstance();
const variantGlobalConfiguration = vue.inject("configuration", {});
const componentGlobalConfiguration = core.get(variantGlobalConfiguration, vm == null ? void 0 : vm.type.name, {});
const propsValues = vue.computed(() => {
const values = {};
extractDefinedProps(vm).forEach((attributeName) => {
const normalizedAttribute = vue.camelize(attributeName);
values[normalizedAttribute] = vm.props[normalizedAttribute];
});
return values;
});
return {
componentGlobalConfiguration,
propsValues
};
}
function useConfiguration(defaultConfiguration) {
const vm = vue.getCurrentInstance();
const { propsValues, componentGlobalConfiguration } = useConfigurationParts();
const computedConfiguration = vue.computed(() => {
const props = __spreadValues({}, vm.props);
delete props.modelValue;
return __spreadValues(__spreadValues({}, props), core.parseVariant(propsValues.value, componentGlobalConfiguration, defaultConfiguration));
});
const configuration = vue.reactive(computedConfiguration.value);
vue.watch(computedConfiguration, (newValue) => {
Object.keys(newValue).forEach((key) => {
configuration[key] = newValue[key];
});
});
const attributes = useAttributes(configuration);
return {
configuration,
attributes
};
}
function useConfigurationWithClassesList(defaultConfiguration, classesListKeys) {
const vm = vue.getCurrentInstance();
const { propsValues, componentGlobalConfiguration } = useConfigurationParts();
const computedConfiguration = vue.computed(() => __spreadValues(__spreadValues({}, vm.props), core.parseVariantWithClassesList(propsValues.value, classesListKeys, componentGlobalConfiguration, defaultConfiguration)));
const configuration = vue.reactive(computedConfiguration.value);
vue.watch(computedConfiguration, (newValue) => {
Object.keys(newValue).forEach((key) => {
configuration[key] = newValue[key];
});
});
const attributes = useAttributes(configuration);
return {
configuration,
attributes
};
}
function useVModel(props, key) {
const vm = vue.getCurrentInstance();
const localValue = vue.ref(props[key]);
vue.watch(localValue, (value) => {
vm == null ? void 0 : vm.emit(`update:${key}`, value);
});
vue.watch(() => props[key], (value) => {
localValue.value = value;
});
return localValue;
}
function _toConsumableArray(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
arr2[i] = arr[i];
}
return arr2;
} else {
return Array.from(arr);
}
}
var hasPassiveEvents = false;
if (typeof window !== "undefined") {
var passiveTestOptions = {
get passive() {
hasPassiveEvents = true;
return void 0;
}
};
window.addEventListener("testPassive", null, passiveTestOptions);
window.removeEventListener("testPassive", null, passiveTestOptions);
}
var isIosDevice = typeof window !== "undefined" && window.navigator && window.navigator.platform && (/iP(ad|hone|od)/.test(window.navigator.platform) || window.navigator.platform === "MacIntel" && window.navigator.maxTouchPoints > 1);
var locks = [];
var documentListenerAdded = false;
var initialClientY = -1;
var previousBodyOverflowSetting = void 0;
var previousBodyPosition = void 0;
var previousBodyPaddingRight = void 0;
var allowTouchMove = function allowTouchMove2(el) {
return locks.some(function(lock) {
if (lock.options.allowTouchMove && lock.options.allowTouchMove(el)) {
return true;
}
return false;
});
};
var preventDefault = function preventDefault2(rawEvent) {
var e = rawEvent || window.event;
if (allowTouchMove(e.target)) {
return true;
}
if (e.touches.length > 1)
return true;
if (e.preventDefault)
e.preventDefault();
return false;
};
var setOverflowHidden = function setOverflowHidden2(options) {
if (previousBodyPaddingRight === void 0) {
var _reserveScrollBarGap = !!options && options.reserveScrollBarGap === true;
var scrollBarGap = window.innerWidth - document.documentElement.clientWidth;
if (_reserveScrollBarGap && scrollBarGap > 0) {
var computedBodyPaddingRight = parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right"), 10);
previousBodyPaddingRight = document.body.style.paddingRight;
document.body.style.paddingRight = computedBodyPaddingRight + scrollBarGap + "px";
}
}
if (previousBodyOverflowSetting === void 0) {
previousBodyOverflowSetting = document.body.style.overflow;
document.body.style.overflow = "hidden";
}
};
var restoreOverflowSetting = function restoreOverflowSetting2() {
if (previousBodyPaddingRight !== void 0) {
document.body.style.paddingRight = previousBodyPaddingRight;
previousBodyPaddingRight = void 0;
}
if (previousBodyOverflowSetting !== void 0) {
document.body.style.overflow = previousBodyOverflowSetting;
previousBodyOverflowSetting = void 0;
}
};
var setPositionFixed = function setPositionFixed2() {
return window.requestAnimationFrame(function() {
if (previousBodyPosition === void 0) {
previousBodyPosition = {
position: document.body.style.position,
top: document.body.style.top,
left: document.body.style.left
};
var _window = window, scrollY = _window.scrollY, scrollX = _window.scrollX, innerHeight = _window.innerHeight;
document.body.style.position = "fixed";
document.body.style.top = -scrollY;
document.body.style.left = -scrollX;
setTimeout(function() {
return window.requestAnimationFrame(function() {
var bottomBarHeight = innerHeight - window.innerHeight;
if (bottomBarHeight && scrollY >= innerHeight) {
document.body.style.top = -(scrollY + bottomBarHeight);
}
});
}, 300);
}
});
};
var restorePositionSetting = function restorePositionSetting2() {
if (previousBodyPosition !== void 0) {
var y = -parseInt(document.body.style.top, 10);
var x = -parseInt(document.body.style.left, 10);
document.body.style.position = previousBodyPosition.position;
document.body.style.top = previousBodyPosition.top;
document.body.style.left = previousBodyPosition.left;
window.scrollTo(x, y);
previousBodyPosition = void 0;
}
};
var isTargetElementTotallyScrolled = function isTargetElementTotallyScrolled2(targetElement) {
return targetElement ? targetElement.scrollHeight - targetElement.scrollTop <= targetElement.clientHeight : false;
};
var handleScroll = function handleScroll2(event, targetElement) {
var clientY = event.targetTouches[0].clientY - initialClientY;
if (allowTouchMove(event.target)) {
return false;
}
if (targetElement && targetElement.scrollTop === 0 && clientY > 0) {
return preventDefault(event);
}
if (isTargetElementTotallyScrolled(targetElement) && clientY < 0) {
return preventDefault(event);
}
event.stopPropagation();
return true;
};
var disableBodyScroll = function disableBodyScroll2(targetElement, options) {
if (!targetElement) {
console.error("disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.");
return;
}
if (locks.some(function(lock2) {
return lock2.targetElement === targetElement;
})) {
return;
}
var lock = {
targetElement,
options: options || {}
};
locks = [].concat(_toConsumableArray(locks), [lock]);
if (isIosDevice) {
setPositionFixed();
} else {
setOverflowHidden(options);
}
if (isIosDevice) {
targetElement.ontouchstart = function(event) {
if (event.targetTouches.length === 1) {
initialClientY = event.targetTouches[0].clientY;
}
};
targetElement.ontouchmove = function(event) {
if (event.targetTouches.length === 1) {
handleScroll(event, targetElement);
}
};
if (!documentListenerAdded) {
document.addEventListener("touchmove", preventDefault, hasPassiveEvents ? { passive: false } : void 0);
documentListenerAdded = true;
}
}
};
var enableBodyScroll = function enableBodyScroll2(targetElement) {
if (!targetElement) {
console.error("enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices.");
return;
}
locks = locks.filter(function(lock) {
return lock.targetElement !== targetElement;
});
if (isIosDevice) {
targetElement.ontouchstart = null;
targetElement.ontouchmove = null;
if (documentListenerAdded && locks.length === 0) {
document.removeEventListener("touchmove", preventDefault, hasPassiveEvents ? { passive: false } : void 0);
documentListenerAdded = false;
}
}
if (isIosDevice) {
restorePositionSetting();
} else {
restoreOverflowSetting();
}
};
var _export_sfc = (sfc, props) => {
const target = sfc.__vccOpts || sfc;
for (const [key, val] of props) {
target[key] = val;
}
return target;
};
const _sfc_main$F = {};
const _hoisted_1$n = {
xmlns: "http://www.w3.org/2000/svg",
fill: "none",
viewBox: "0 0 24 24",
stroke: "currentColor"
};
const _hoisted_2$h = /* @__PURE__ */ vue.createElementVNode("path", {
"stroke-linecap": "round",
"stroke-linejoin": "round",
"stroke-width": "2",
d: "M6 18L18 6M6 6l12 12"
}, null, -1);
const _hoisted_3$f = [
_hoisted_2$h
];
function _sfc_render$F(_ctx, _cache) {
return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$n, _hoisted_3$f);
}
var CloseIcon = /* @__PURE__ */ _export_sfc(_sfc_main$F, [["render", _sfc_render$F]]);
const _sfc_main$E = vue.defineComponent({
name: "Transitionable",
compatConfig: {
MODE: 3
},
props: {
classesList: {
type: Object,
default: () => ({})
},
enabled: {
type: Boolean,
default: true
}
}
});
function _sfc_render$E(_ctx, _cache, $props, $setup, $data, $options) {
var _a, _b, _c, _d, _e, _f;
return vue.openBlock(), vue.createBlock(vue.Transition, {
"enter-active-class": (_a = _ctx.classesList) == null ? void 0 : _a.enterActiveClass,
"enter-from-class": (_b = _ctx.classesList) == null ? void 0 : _b.enterFromClass,
"enter-to-class": (_c = _ctx.classesList) == null ? void 0 : _c.enterToClass,
"leave-active-class": (_d = _ctx.classesList) == null ? void 0 : _d.leaveActiveClass,
"leave-from-class": (_e = _ctx.classesList) == null ? void 0 : _e.leaveFromClass,
"leave-to-class": (_f = _ctx.classesList) == null ? void 0 : _f.leaveToClass,
css: _ctx.enabled
}, {
default: vue.withCtx(() => [
vue.renderSlot(_ctx.$slots, "default")
]),
_: 3
}, 8, ["enter-active-class", "enter-from-class", "enter-to-class", "leave-active-class", "leave-from-class", "leave-to-class", "css"]);
}
var Transitionable = /* @__PURE__ */ _export_sfc(_sfc_main$E, [["render", _sfc_render$E]]);
const _sfc_main$D = vue.defineComponent({
name: "TModal",
compatConfig: {
MODE: 3
},
components: {
CloseIcon,
Transitionable
},
props: __spreadProps(__spreadValues({}, getVariantPropsWithClassesList()), {
name: {
type: String,
default: void 0
},
modelValue: {
type: Boolean,
default: false
},
modalAttributes: {
type: Object,
default: () => ({})
},
header: {
type: String,
default: void 0
},
body: {
type: String,
default: void 0
},
footer: {
type: String,
default: void 0
},
focusOnOpen: {
type: Boolean,
default: true
},
clickToClose: {
type: Boolean,
default: true
},
escToClose: {
type: Boolean,
default: true
},
disableBodyScroll: {
type: Boolean,
default: true
},
noBody: {
type: Boolean,
default: false
},
hideCloseButton: {
type: Boolean,
default: false
},
bodyScrollLockOptions: {
type: Object,
default: () => ({})
},
teleport: {
type: Boolean,
default: true
},
teleportTo: {
type: [String, Object],
default: "body"
}
}),
emits: {
shown: () => true,
hidden: (reason) => true,
"before-show": ({ cancel, params }) => true,
"before-hide": ({ cancel, reason }) => true,
"update:modelValue": () => true
},
setup(props, { emit }) {
const { configuration, attributes } = useConfigurationWithClassesList(core.TModalConfig, core.TModalClassesKeys);
const overlay = vue.ref();
let modalParameters;
const showModel = useVModel(props, "modelValue");
const scrollIsDisabled = vue.ref(false);
const showComponent = vue.ref(showModel.value);
const showOverlay = vue.ref(showModel.value);
const showModal = vue.ref(showModel.value);
const hideReason = vue.ref(core.ModalHideReason.Value);
const canceled = vue.ref(false);
const hide = (reason = core.ModalHideReason.Other) => {
hideReason.value = reason;
showModel.value = false;
};
const show = (params) => {
modalParameters = params;
showModel.value = true;
};
const focusModal = () => {
overlay.value.focus();
};
const disableBodyScrollIfNeccesary = () => {
if (!configuration.disableBodyScroll || scrollIsDisabled.value) {
return;
}
disableBodyScroll(overlay.value, configuration.bodyScrollLockOptions);
scrollIsDisabled.value = true;
};
const enableBodyScrollIfNeccesary = () => {
if (!scrollIsDisabled.value) {
return;
}
enableBodyScroll(overlay.value);
scrollIsDisabled.value = false;
};
const initModal = () => {
if (configuration.focusOnOpen) {
focusModal();
}
disableBodyScrollIfNeccesary();
};
const reset = () => {
modalParameters = void 0;
hideReason.value = core.ModalHideReason.Value;
};
const onBeforeShow = () => new Promise((resolve, reject) => {
emit("before-show", {
cancel: reject,
params: modalParameters
});
resolve();
});
const onBeforeHide = () => new Promise((resolve, reject) => {
emit("before-hide", {
cancel: reject,
reason: hideReason.value
});
enableBodyScrollIfNeccesary();
resolve();
});
const onShown = () => {
emit("shown");
initModal();
};
const onHidden = () => {
emit("hidden", hideReason.value);
reset();
};
vue.watch(showModel, async (isShow) => {
if (canceled.value) {
canceled.value = false;
return;
}
if (isShow) {
try {
await onBeforeShow();
} catch (e) {
canceled.value = true;
showModel.value = false;
return;
}
showComponent.value = true;
vue.nextTick(() => {
showOverlay.value = true;
vue.nextTick(() => {
showModal.value = true;
vue.nextTick(() => {
onShown();
});
});
});
} else {
try {
await onBeforeHide();
} catch (e) {
canceled.value = true;
showModel.value = true;
return;
}
showModal.value = false;
vue.nextTick(() => {
showOverlay.value = false;
vue.nextTick(() => {
showComponent.value = false;
vue.nextTick(() => {
onHidden();
});
});
});
}
});
const onKeydownEscapeHandler = () => {
if (!configuration.escToClose) {
return;
}
hide(core.ModalHideReason.Esc);
};
const onClickHandler = () => {
if (!configuration.clickToClose) {
return;
}
hide(core.ModalHideReason.Outside);
};
vue.onMounted(() => {
if (showModel.value) {
initModal();
}
});
vue.onBeforeUnmount(() => {
reset();
enableBodyScrollIfNeccesary();
});
if (configuration.name) {
const emitter = vue.inject("emitter");
emitter.on("modal:show", (name, params) => {
if (configuration.name !== name) {
return;
}
show(params);
});
emitter.on("modal:hide", (name) => {
if (configuration.name !== name) {
return;
}
hide(core.ModalHideReason.Method);
});
}
const overlayTransitionClassesList = vue.computed(() => ({
enterActiveClass: configuration.classesList.overlayEnterActiveClass,
enterFromClass: configuration.classesList.overlayEnterFromClass,
enterToClass: configuration.classesList.overlayEnterToClass,
leaveActiveClass: configuration.classesList.overlayLeaveActiveClass,
leaveFromClass: configuration.classesList.overlayLeaveFromClass,
leaveToClass: configuration.classesList.overlayLeaveToClass
}));
return {
configuration,
attributes,
showOverlay,
showModal,
showComponent,
overlay,
overlayTransitionClassesList,
show,
hide,
focusModal,
onKeydownEscapeHandler,
onClickHandler,
ModalHideReason: core.ModalHideReason
};
}
});
function _sfc_render$D(_ctx, _cache, $props, $setup, $data, $options) {
const _component_close_icon = vue.resolveComponent("close-icon");
const _component_transitionable = vue.resolveComponent("transitionable");
return _ctx.showComponent ? (vue.openBlock(), vue.createBlock(vue.Teleport, {
key: 0,
to: _ctx.configuration.teleportTo,
disabled: !_ctx.configuration.teleport
}, [
vue.createVNode(_component_transitionable, { "classes-list": _ctx.overlayTransitionClassesList }, {
default: vue.withCtx(() => {
var _a;
return [
vue.withDirectives(vue.createElementVNode("div", vue.mergeProps(_ctx.attributes, {
ref: "overlay",
tabindex: "0",
class: (_a = _ctx.configuration.classesList) == null ? void 0 : _a.overlay,
onKeydown: _cache[2] || (_cache[2] = vue.withKeys((...args) => _ctx.onKeydownEscapeHandler && _ctx.onKeydownEscapeHandler(...args), ["escape"])),
onClick: _cache[3] || (_cache[3] = (...args) => _ctx.onClickHandler && _ctx.onClickHandler(...args))
}), [
vue.createVNode(_component_transitionable, {
"classes-list": _ctx.configuration.classesList
}, {
default: vue.withCtx(() => {
var _a2, _b, _c, _d, _e;
return [
vue.withDirectives(vue.createElementVNode("div", vue.mergeProps(_ctx.configuration.modalAttributes, {
ref: "modal",
class: (_a2 = _ctx.configuration.classesList) == null ? void 0 : _a2.wrapper,
onClick: _cache[1] || (_cache[1] = vue.withModifiers(() => {
}, ["stop"]))
}), [
_ctx.noBody ? vue.renderSlot(_ctx.$slots, "default", { key: 0 }) : (vue.openBlock(), vue.createElementBlock("div", {
key: 1,
class: vue.normalizeClass((_b = _ctx.configuration.classesList) == null ? void 0 : _b.modal)
}, [
!_ctx.configuration.hideCloseButton ? vue.renderSlot(_ctx.$slots, "closeButton", {
key: 0,
hide: _ctx.hide
}, () => {
var _a3;
return [
vue.createElementVNode("button", {
type: "button",
class: vue.normalizeClass((_a3 = _ctx.configuration.classesList) == null ? void 0 : _a3.close),
onClick: _cache[0] || (_cache[0] = ($event) => _ctx.hide(_ctx.ModalHideReason.Close))
}, [
vue.renderSlot(_ctx.$slots, "closeButtonIcon", { hide: _ctx.hide }, () => {
var _a4;
return [
vue.createVNode(_component_close_icon, {
class: vue.normalizeClass((_a4 = _ctx.configuration.classesList) == null ? void 0 : _a4.closeIcon)
}, null, 8, ["class"])
];
})
], 2)
];
}) : vue.createCommentVNode("", true),
_ctx.$slots.header || _ctx.configuration.header ? (vue.openBlock(), vue.createElementBlock("div", {
key: 1,
ref: "header",
class: vue.normalizeClass((_c = _ctx.configuration.classesList) == null ? void 0 : _c.header)
}, [
vue.renderSlot(_ctx.$slots, "header", { hide: _ctx.hide }, () => [
vue.createTextVNode(vue.toDisplayString(_ctx.configuration.header), 1)
])
], 2)) : vue.createCommentVNode("", true),
_ctx.$slots.default || _ctx.configuration.body ? (vue.openBlock(), vue.createElementBlock("div", {
key: 2,
ref: "body",
class: vue.normalizeClass((_d = _ctx.configuration.classesList) == null ? void 0 : _d.body)
}, [
vue.renderSlot(_ctx.$slots, "default", { hide: _ctx.hide }, () => [
vue.createTextVNode(vue.toDisplayString(_ctx.configuration.body), 1)
])
], 2)) : vue.createCommentVNode("", true),
_ctx.$slots.footer || _ctx.configuration.footer ? (vue.openBlock(), vue.createElementBlock("div", {
key: 3,
ref: "footer",
class: vue.normalizeClass((_e = _ctx.configuration.classesList) == null ? void 0 : _e.footer)
}, [
vue.renderSlot(_ctx.$slots, "footer", { hide: _ctx.hide }, () => [
vue.createTextVNode(vue.toDisplayString(_ctx.configuration.footer), 1)
])
], 2)) : vue.createCommentVNode("", true)
], 2))
], 16), [
[vue.vShow, _ctx.showModal]
])
];
}),
_: 3
}, 8, ["classes-list"])
], 16), [
[vue.vShow, _ctx.showOverlay]
])
];
}),
_: 3
}, 8, ["classes-list"])
], 8, ["to", "disabled"])) : vue.createCommentVNode("", true);
}
var TModal = /* @__PURE__ */ _export_sfc(_sfc_main$D, [["render", _sfc_render$D]]);
const _sfc_main$C = {};
const _hoisted_1$m = {
xmlns: "http://www.w3.org/2000/svg",
fill: "none",
viewBox: "0 0 24 24",
stroke: "currentColor"
};
const _hoisted_2$g = /* @__PURE__ */ vue.createElementVNode("path", {
"stroke-linecap": "round",
"stroke-linejoin": "round",
"stroke-width": "2",
d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
}, null, -1);
const _hoisted_3$e = [
_hoisted_2$g
];
function _sfc_render$C(_ctx, _cache) {
return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$m, _hoisted_3$e);
}
var CheckCircleIcon = /* @__PURE__ */ _export_sfc(_sfc_main$C, [["render", _sfc_render$C]]);
const _sfc_main$B = {};
const _hoisted_1$l = {
xmlns: "http://www.w3.org/2000/svg",
fill: "none",
viewBox: "0 0 24 24",
stroke: "currentColor"
};
const _hoisted_2$f = /* @__PURE__ */ vue.createElementVNode("path", {
"stroke-linecap": "round",
"stroke-linejoin": "round",
"stroke-width": "2",
d: "M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
}, null, -1);
const _hoisted_3$d = [
_hoisted_2$f
];
function _sfc_render$B(_ctx, _cache) {
return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$l, _hoisted_3$d);
}
var QuestionMarkCircleIcon = /* @__PURE__ */ _export_sfc(_sfc_main$B, [["render", _sfc_render$B]]);
const _sfc_main$A = {};
const _hoisted_1$k = {
xmlns: "http://www.w3.org/2000/svg",
class: "w-6 h-6",
fill: "none",
viewBox: "0 0 24 24",
stroke: "currentColor"
};
const _hoisted_2$e = /* @__PURE__ */ vue.createElementVNode("path", {
"stroke-linecap": "round",
"stroke-linejoin": "round",
"stroke-width": "2",
d: "M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
}, null, -1);
const _hoisted_3$c = [
_hoisted_2$e
];
function _sfc_render$A(_ctx, _cache) {
return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$k, _hoisted_3$c);
}
var InformationCircleIcon = /* @__PURE__ */ _export_sfc(_sfc_main$A, [["render", _sfc_render$A]]);
const _sfc_main$z = {};
const _hoisted_1$j = {
xmlns: "http://www.w3.org/2000/svg",
fill: "none",
viewBox: "0 0 24 24",
stroke: "currentColor"
};
const _hoisted_2$d = /* @__PURE__ */ vue.createElementVNode("path", {
"stroke-linecap": "round",
"stroke-linejoin": "round",
"stroke-width": "2",
d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
}, null, -1);
const _hoisted_3$b = [
_hoisted_2$d
];
function _sfc_render$z(_ctx, _cache) {
return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$j, _hoisted_3$b);
}
var ExclamationIcon = /* @__PURE__ */ _export_sfc(_sfc_main$z, [["render", _sfc_render$z]]);
const _sfc_main$y = {};
const _hoisted_1$i = {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 20 20",
fill: "currentColor"
};
const _hoisted_2$c = /* @__PURE__ */ vue.createElementVNode("path", {
"fill-rule": "evenodd",
d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z",
"clip-rule": "evenodd"
}, null, -1);
const _hoisted_3$a = [
_hoisted_2$c
];
function _sfc_render$y(_ctx, _cache) {
return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$i, _hoisted_3$a);
}
var SolidCheckCircleIcon = /* @__PURE__ */ _export_sfc(_sfc_main$y, [["render", _sfc_render$y]]);
const _sfc_main$x = {};
const _hoisted_1$h = {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 20 20",
fill: "currentColor"
};
const _hoisted_2$b = /* @__PURE__ */ vue.createElementVNode("path", {
"fill-rule": "evenodd",
d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-3a1 1 0 00-.867.5 1 1 0 11-1.731-1A3 3 0 0113 8a3.001 3.001 0 01-2 2.83V11a1 1 0 11-2 0v-1a1 1 0 011-1 1 1 0 100-2zm0 8a1 1 0 100-2 1 1 0 000 2z",
"clip-rule": "evenodd"
}, null, -1);
const _hoisted_3$9 = [
_hoisted_2$b
];
function _sfc_render$x(_ctx, _cache) {
return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$h, _hoisted_3$9);
}
var SolidQuestionMarkCircleIcon = /* @__PURE__ */ _export_sfc(_sfc_main$x, [["render", _sfc_render$x]]);
const _sfc_main$w = {};
const _hoisted_1$g = {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 20 20",
fill: "currentColor"
};
const _hoisted_2$a = /* @__PURE__ */ vue.createElementVNode("path", {
"fill-rule": "evenodd",
d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z",
"clip-rule": "evenodd"
}, null, -1);
const _hoisted_3$8 = [
_hoisted_2$a
];
function _sfc_render$w(_ctx, _cache) {
return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$g, _hoisted_3$8);
}
var SolidInformationCircleIcon = /* @__PURE__ */ _export_sfc(_sfc_main$w, [["render", _sfc_render$w]]);
const _sfc_main$v = {};
const _hoisted_1$f = {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 20 20",
fill: "currentColor"
};
const _hoisted_2$9 = /* @__PURE__ */ vue.createElementVNode("path", {
"fill-rule": "evenodd",
d: "M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z",
"clip-rule": "evenodd"
}, null, -1);
const _hoisted_3$7 = [
_hoisted_2$9
];
function _sfc_render$v(_ctx, _cache) {
return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$f, _hoisted_3$7);
}
var SolidExclamationIcon = /* @__PURE__ */ _export_sfc(_sfc_main$v, [["render", _sfc_render$v]]);
const _sfc_main$u = {};
const _hoisted_1$e = {
xmlns: "http://www.w3.org/2000/svg",
fill: "none",
viewBox: "0 0 24 24",
stroke: "currentColor"
};
const _hoisted_2$8 = /* @__PURE__ */ vue.createElementVNode("path", {
"stroke-linecap": "round",
"stroke-linejoin": "round",
"stroke-width": "2",
d: "M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
}, null, -1);
const _hoisted_3$6 = [
_hoisted_2$8
];
function _sfc_render$u(_ctx, _cache) {
return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$e, _hoisted_3$6);
}
var CrossCircleIcon = /* @__PURE__ */ _export_sfc(_sfc_main$u, [["render", _sfc_render$u]]);
const _sfc_main$t = {};
const _hoisted_1$d = {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 20 20",
fill: "currentColor"
};
const _hoisted_2$7 = /* @__PURE__ */ vue.createElementVNode("path", {
"fill-rule": "evenodd",
d: "M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z",
"clip-rule": "evenodd"
}, null, -1);
const _hoisted_3$5 = [
_hoisted_2$7
];
function _sfc_render$t(_ctx, _cache) {
return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$d, _hoisted_3$5);
}
var SolidCrossCircleIcon = /* @__PURE__ */ _export_sfc(_sfc_main$t, [["render", _sfc_render$t]]);
const _sfc_main$s = {};
const _hoisted_1$c = {
viewBox: "0 0 20 20",
xmlns: "http://www.w3.org/2000/svg"
};
const _hoisted_2$6 = /* @__PURE__ */ vue.createElementVNode("circle", {
cx: "10",
cy: "10",
fill: "none",
r: "8",
"stroke-width": "2",
stroke: "currentColor",
"transform-origin": "center",
opacity: "0.2"
}, null, -1);
const _hoisted_3$4 = /* @__PURE__ */ vue.createElementVNode("circle", {
cx: "10",
cy: "10",
fill: "none",
r: "8",
"stroke-width": "2",
stroke: "currentColor",
"stroke-dasharray": "80",
"stroke-dashoffset": "60",
"transform-origin": "center"
}, [
/* @__PURE__ */ vue.createElementVNode("animateTransform", {
attributeType: "xml",
attributeName: "transform",
type: "rotate",
from: "0",
to: "360",
begin: "0",
dur: "1s",
repeatCount: "indefinite"
})
], -1);
const _hoisted_4$1 = [
_hoisted_2$6,
_hoisted_3$4
];
function _sfc_render$s(_ctx, _cache) {
return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$c, _hoisted_4$1);
}
var LoadingIcon = /* @__PURE__ */ _export_sfc(_sfc_main$s, [["render", _sfc_render$s]]);
const _sfc_main$r = vue.defineComponent({
name: "TDialog",
compatConfig: {
MODE: 3
},
components: {
TModal,
CloseIcon,
LoadingIcon,
CrossCircleIcon,
SolidCrossCircleIcon,
CheckCircleIcon,
QuestionMarkCircleIcon,
InformationCircleIcon,
ExclamationIcon,
SolidQuestionMarkCircleIcon,
SolidInformationCircleIcon,
SolidExclamationIcon,
SolidCheckCircleIcon
},
props: __spreadProps(__spreadValues({}, getVariantPropsWithClassesList()), {
type: {
type: String,
default: core.DialogType.Alert
},
icon: {
type: String,
default: void 0
},
useSolidIcon: {
type: Boolean,
default: false
},
rejectOnCancel: {
type: Boolean,
default: true
},
rejectOnDismiss: {
type: Boolean,
default: void 0
},
title: {
type: String,
default: void 0
},
titleTag: {
type: String,
default: "h3"
},
textTag: {
type: String,
default: "p"
},
text: {
type: String,
default: void 0
},
cancelButtonText: {
type: String,
default: "Cancel"
},
cancelButtonAriaLabel: {
type: String,
default: "Cancel"
},
okButtonText: {
type: String,
default: "OK"
},
okButtonAriaLabel: {
type: String,
default: "OK"
},
preConfirm: {
type: Function,
default: void 0
},
name: {
type: String,
default: void 0
},
modelValue: {
type: Boolean,
default: false
},
dialogAttributes: {
type: Object,
default: () => ({})
},
focusOnOpen: {
type: Boolean,
default: true
},
clickToClose: {
type: Boolean,
default: true
},
escToClose: {
type: Boolean,
default: true
},
showCloseButton: {
type: Boolean,
default: true
},
disableBodyScroll: {
type: Boolean,
default: true
},
bodyScrollLockOptions: {
type: Object,
default: () => ({})
},
teleport: {
type: Boolean,
default: true
},
teleportTo: {
type: [String, Object],
default: "body"
},
inputAttributes: {
type: Object,
default: () => ({})
},
inputType: {
type: String,
default: "text"
},
inputValidator: {
type: Function,
default: void 0
},
inputValue: {
type: [String, Number, Boolean, Array, Object, Date, Function, Symbol],
default: void 0
}
}),
emits: {
shown: () => true,
hidden: (response) => true,
error: (response) => true,
"validation-error": (message) => true,
"before-show": (e) => true,
"before-hide": (e) => true,
"update:modelValue": () => true
},
setup(props, { emit }) {
const { configuration, attributes } = useConfigurationWithClassesList(core.TDialogConfig, core.TDialogClassesKeys);
const inputWrapperRef = vue.ref();
const modalRef = vue.ref();
const showModel = useVModel(props, "modelValue");
const inputModel = vue.ref(props.inputValue);
const busy = vue.ref(false);
const errorMessage = vue.ref(void 0);
const validationErrorMessage = vue.ref(void 0);
const hideReason = vue.ref(void 0);
const dialogResponse = vue.ref(void 0);
const preConfirmResponse = vue.ref(void 0);
const promiseResolve = vue.ref(void 0);
const promiseReject = vue.ref(void 0);
const isPrompt = vue.computed(() => configuration.type === core.DialogType.Prompt);
const setError = (error) => {
if (error instanceof Error) {
errorMessage.value = error.message;
} else {
errorMessage.value = error;
}
};
const setValidationError = (error) => {
validationErrorMessage.value = error;
};
const focusDialog = () => {
modalRef.value.focusModal();
};
const focusPromptInput = () => {
const focusableField = core.getFocusableElements(inputWrapperRef.value).shift();
if (focusableField) {
focusableField.focus();
} else {
focusDialog();
}
};
const initDialog = () => {
if (configuration.focusOnOpen) {
if (isPrompt.value) {
focusPromptInput();
} else {
focusDialog();
}
}
};
vue.onMounted(() => {
if (showModel.value) {
initDialog();
}
});
const setInputValue = (value) => {
inputModel.value = value;
};
const reset = () => {
promiseResolve.value = void 0;
promiseReject.value = void 0;
hideReason.value = void 0;
dialogResponse.value = void 0;
busy.value = false;
setError(void 0);
setValidationError(void 0);
preConfirmResponse.value = void 0;
setInputValue(props.inputValue);
};
const onBeforeShow = (e) => {
emit("before-show", e);
};
const onBeforeHide = (e) => {
const hideReasonValue = hideReason.value !== void 0 ? hideReason.value : e.reason;
if (busy.value && hideReasonValue !== core.DialogHideReason.Ok) {
e.cancel();
return;
}
const response = {
hideReason: hideReasonValue,
isOk: hideReasonValue === core.DialogHideReason.Ok,
isCancel: hideReasonValue === core.DialogHideReason.Cancel,
isDismissed: ![core.DialogHideReason.Cancel, core.DialogHideReason.Ok].includes(hideReasonValue)
};
if (configuration.preConfirm) {
response.response = preConfirmResponse.value;
}
if (isPrompt.value) {
response.input = inputModel.value;
}
dialogResponse.value = response;
emit("before-hide", {
cancel: e.cancel,
response
});
};
const rejectOnDismiss = vue.computed(() => {
if (configuration.rejectOnDismiss === void 0) {
return configuration.type !== core.DialogType.Alert;
}
return configuration.rejectOnDismiss;
});
const onHidden = () => {
const response = dialogResponse.value;
emit("hidden", response);
if (response.isCancel && configuration.rejectOnCancel || response.isDismissed && rejectOnDismiss.value) {
if (promiseReject.value) {
promiseReject.value(response);
}
} else if (promiseResolve.value) {
promiseResolve.value(response);
}
reset();
};
const onShown = () => {
emit("shown");
initDialog();
};
const hide = (reason = core.DialogHideReason.Other) => {
hideReason.value = reason;
showModel.value = false;
};
const ok = () => {
setValidationError(void 0);
setError(void 0);
if (configuration.inputValidator && isPrompt.value) {
const response = configuration.inputValidator(inputModel.value);
if (typeof response === "string" && response.length > 0) {
setValidationError(response);
emit("validation-error", response);
return;
}
}
if (configuration.preConfirm) {
const promise = core.promisifyFunctionResult(configuration.preConfirm, inputModel.value);
busy.value = true;
promise.then((response) => {
preConfirmResponse.value = response;
hide(core.DialogHideReason.Ok);
}).catch((error) => {
setError(error);
emit("error", error);
}).then(() => {
busy.value = false;
});
} else {
hide(core.DialogHideReason.Ok);
}
};
const cancel = () => {
hide(core.DialogHideReason.Cancel);
};
const show = () => {
const promise = new Promise((resolve, reject) => {
promiseResolve.value = resolve;
promiseReject.value = reject;
showModel.value = true;
});
return promise;
};
if (configuration.name) {
const emitter = vue.inject("emitter");
emitter.on("dialog:show", (name, resolve, reject) => {
if (configuration.name !== name) {
return;
}
promiseResolve.value = resolve;
promiseReject.value = reject;
showModel.value = true;
});
emitter.on("dialog:hide", (name) => {
if (configuration.name !== name) {
return;
}
hide(core.DialogHideReason.Method);
});
}
vue.watch(inputModel, () => {
if (!configuration.inputValidator) {
return;
}
const response = configuration.inputValidator(inputModel.value);
if (typeof response === "string" && response.length > 0) {
setValidationError(response);
emit("validation-error", response);
} else {
setValidationError(void 0);
}
});
const modalClasses = vue.computed(() => ({
overlay: configuration.classesList.overlay,
wrapper: configuration.classesList.wrapper,
modal: configuration.classesList.dialog,
body: configuration.classesList.body,
footer: configuration.classesList.buttons,
overlayEnterActiveClass: configuration.classesList.overlayEnterActiveClass,
overlayEnterFromClass: configuration.classesList.overlayEnterFromClass,
overlayEnterToClass: configuration.classesList.overlayEnterToClass,
overlayLeaveActiveClass: configuration.classesList.overlayLeaveActiveClass,
overlayLeaveFromClass: configuration.classesList.overlayLeaveFromClass,
overlayLeaveToClass: configuration.classesList.overlayLeaveToClass,
enterActiveClass: configuration.classesList.enterActiveClass,
enterFromClass: configuration.classesList.enterFromClass,
enterToClass: configuration.classesList.enterToClass,
leaveActiveClass: configuration.classesList.leaveActiveClass,
leaveFromClass: configuration.classesList.leaveFromClass,
leaveToClass: configuration.classesList.leaveToClass
}));
const showCancelButton = vue.computed(() => configuration.type !== core.DialogType.Alert);
return {
configuration,
attributes,
showModel,
modalClasses,
showCancelButton,
DialogHideReason: core.DialogHideReason,
inputModel,
busy,
show,
hide,
ok,
cancel,
onBeforeShow,
onBeforeHide,
onShown,
onHidden,
setInputValue,
setError,
setValidationError,
errorMessage,
validationErrorMessage,
inputWrapperRef,
modalRef
};
}
});
const _hoisted_1$b = ["disabled"];
const _hoisted_2$5 = ["variant", "type"];
const _hoisted_3$3 = ["aria-label", "disabled"];
const _hoisted_4 = ["aria-label", "disabled"];
function _sfc_render$r(_ctx, _cache, $props, $setup, $data, $opt