bootstrap-vue-next
Version:
BootstrapVueNext is an early and lovely component library for Vue 3 & Nuxt 3 based on Bootstrap 5 and Typescript.
401 lines (400 loc) • 17.1 kB
JavaScript
import { defineComponent, mergeModels, useSlots, useTemplateRef, useModel, computed, watchEffect, watch, createBlock, createCommentVNode, unref, openBlock, Transition, mergeProps, withCtx, withDirectives, createElementVNode, normalizeClass, createElementBlock, resolveDynamicComponent, renderSlot, normalizeProps, guardReactiveProps, toDisplayString, Fragment, withModifiers, createTextVNode, vShow, inject, toRef, toValue, markRaw, isRef, isReadonly, onScopeDispose } from "vue";
import { o as orchestratorRegistryKey } from "./keys-BLeKMItg.mjs";
import { b as buildPromise } from "./orchestratorShared-BTzXOM4N.mjs";
import "./BootstrapVueOptions-BTXqFG2e.mjs";
import "./ConditionalTeleport.vue_vue_type_script_lang-Cp-egLmm.mjs";
import "./ConditionalWrapper.vue_vue_type_script_lang-IX_NpHH-.mjs";
import "./useTransitions-BAT154ve.mjs";
import "./tableUtils-Jp7dzXjS.mjs";
import { _ as _sfc_main$2 } from "./BButton.vue_vue_type_script_setup_true_lang-CZakWNhr.mjs";
import { u as useBLinkHelper, _ as _sfc_main$1 } from "./BLink.vue_vue_type_script_setup_true_lang-Ct47WhzE.mjs";
import { _ as _sfc_main$3 } from "./BCloseButton.vue_vue_type_script_setup_true_lang-byZmQ_ot.mjs";
import { _ as _sfc_main$4 } from "./BProgress.vue_vue_type_script_setup_true_lang-DtvbiDvK.mjs";
import { u as useCountdown, a as useCountdownHover } from "./useCountdownHover-CLH01_XB.mjs";
import { u as useColorVariantClasses } from "./useColorVariantClasses-ZDE19TZw.mjs";
import { u as useDefaults } from "./useDefaults-DESCdb0p.mjs";
import { u as useId } from "./useId-t29UARy6.mjs";
import { u as useShowHide } from "./useShowHide-K2QIdPKK.mjs";
const _hoisted_1 = ["id", "role", "aria-live", "aria-atomic"];
const _hoisted_2 = {
key: 1,
class: "d-flex"
};
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "BToast",
props: /* @__PURE__ */ mergeModels({
body: { default: void 0 },
bodyClass: { default: void 0 },
closeClass: { default: void 0 },
closeContent: { default: void 0 },
closeLabel: { default: "Close" },
closeVariant: { default: "secondary" },
headerClass: { default: void 0 },
headerTag: { default: "div" },
id: { default: void 0 },
interval: { default: "requestAnimationFrame" },
isStatus: { type: Boolean, default: false },
noCloseButton: { type: Boolean, default: false },
noHoverPause: { type: Boolean, default: false },
noProgress: { type: Boolean, default: false },
noResumeOnHoverLeave: { type: Boolean, default: false },
progressProps: { default: void 0 },
showOnPause: { type: Boolean, default: true },
solid: { type: Boolean, default: false },
title: { default: void 0 },
toastClass: { default: void 0 },
variant: { default: void 0 },
bgVariant: { default: null },
textVariant: { default: null },
active: { type: Boolean, default: void 0 },
activeClass: { default: void 0 },
disabled: { type: Boolean, default: void 0 },
exactActiveClass: { default: void 0 },
href: { default: void 0 },
icon: { type: Boolean, default: void 0 },
noRel: { type: Boolean, default: void 0 },
opacity: { default: void 0 },
opacityHover: { default: void 0 },
prefetch: { type: Boolean },
prefetchOn: {},
noPrefetch: { type: Boolean },
prefetchedClass: {},
rel: { default: void 0 },
replace: { type: Boolean, default: void 0 },
routerComponentName: { default: void 0 },
stretched: { type: Boolean, default: false },
target: { default: void 0 },
to: { default: void 0 },
underlineOffset: { default: void 0 },
underlineOffsetHover: { default: void 0 },
underlineOpacity: { default: void 0 },
underlineOpacityHover: { default: void 0 },
underlineVariant: { default: void 0 },
initialAnimation: { type: Boolean, default: false },
noAnimation: { type: Boolean },
noFade: { type: Boolean, default: false },
lazy: { type: Boolean, default: false },
unmountLazy: { type: Boolean, default: false },
show: { type: Boolean, default: false },
transProps: { default: void 0 },
visible: { type: Boolean, default: false }
}, {
"modelValue": { type: [Boolean, Number], ...{ default: false } },
"modelModifiers": {}
}),
emits: /* @__PURE__ */ mergeModels(["close", "close-countdown", "hide", "hide-prevented", "hidden", "show", "show-prevented", "shown", "toggle", "toggle-prevented", "cancel", "ok"], ["update:modelValue"]),
setup(__props, { expose: __expose, emit: __emit }) {
const _props = __props;
const props = useDefaults(_props, "BToast");
const emit = __emit;
const slots = useSlots();
const element = useTemplateRef("_element");
const modelValue = useModel(__props, "modelValue");
const { computedLink, computedLinkProps } = useBLinkHelper(props);
const computedId = useId(() => props.id, "toast");
const {
showRef,
renderRef,
hide,
toggle,
show,
buildTriggerableEvent,
computedNoAnimation,
isVisible,
transitionProps,
contentShowing
} = useShowHide(modelValue, props, emit, element, computedId);
const countdownLength = computed(
() => typeof modelValue.value === "boolean" ? 0 : modelValue.value
);
const {
isActive,
pause,
restart,
resume,
stop,
isPaused,
value: remainingMs
} = useCountdown(countdownLength, props.interval, {
immediate: typeof modelValue.value === "number" && !!modelValue.value
});
useCountdownHover(
element,
{
noHoverPause: () => props.noHoverPause || typeof modelValue.value !== "number",
noResumeOnHoverLeave: () => props.noResumeOnHoverLeave || typeof modelValue.value !== "number",
modelValueIgnoresHover: () => typeof modelValue.value === "boolean"
},
{ pause, resume }
);
watchEffect(() => {
emit("close-countdown", remainingMs.value);
});
const computedTag = computed(() => computedLink.value ? _sfc_main$1 : "div");
const isToastVisible = computed(
() => showRef.value || isActive.value || props.showOnPause && isPaused.value
);
const colorClasses = useColorVariantClasses(props);
const computedClasses = computed(() => [
colorClasses.value,
{
show: isVisible.value,
fade: !computedNoAnimation.value
}
]);
watch(modelValue, (newValue, oldValue) => {
if (typeof newValue === "number" && newValue > 0) {
const event = buildTriggerableEvent("show", { cancelable: true, trigger: "model" });
emit("show", event);
if (event.defaultPrevented) {
emit("show-prevented", buildTriggerableEvent("show-prevented"));
} else {
restart();
}
}
if (typeof newValue === "number" && newValue === 0) {
stop();
}
if (newValue === false && typeof oldValue === "number" && oldValue > 0) {
stop();
}
});
watch(isActive, (newValue) => {
if (newValue === false && isPaused.value === false) {
hide();
modelValue.value = 0;
stop();
}
});
const sharedSlots = computed(() => ({
toggle,
show,
hide,
id: computedId.value,
visible: showRef.value,
active: isActive.value
}));
__expose({
show,
hide,
toggle,
pause,
restart,
resume,
stop
});
return (_ctx, _cache) => {
const _component_BButton = _sfc_main$2;
return unref(renderRef) || unref(contentShowing) ? (openBlock(), createBlock(Transition, mergeProps({ key: 0 }, unref(transitionProps), {
appear: !!modelValue.value || unref(props).visible
}), {
default: withCtx(() => [
withDirectives(createElementVNode("div", {
id: unref(props).id,
ref: "_element",
class: normalizeClass(["toast", [unref(props).toastClass, computedClasses.value]]),
tabindex: "0",
style: { "display": "block" },
role: !isToastVisible.value ? void 0 : unref(props).isStatus ? "status" : "alert",
"aria-live": !isToastVisible.value ? void 0 : unref(props).isStatus ? "polite" : "assertive",
"aria-atomic": !isToastVisible.value ? void 0 : true
}, [
unref(contentShowing) && (slots.title || unref(props).title) ? (openBlock(), createBlock(resolveDynamicComponent(unref(props).headerTag), {
key: 0,
class: normalizeClass(["toast-header", unref(props).headerClass])
}, {
default: withCtx(() => [
renderSlot(_ctx.$slots, "title", normalizeProps(guardReactiveProps(sharedSlots.value)), () => [
createElementVNode("strong", null, toDisplayString(unref(props).title), 1)
]),
!unref(props).noCloseButton ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
slots.close || unref(props).closeContent ? (openBlock(), createBlock(_component_BButton, {
key: 0,
class: normalizeClass([[unref(props).closeClass], "ms-auto"]),
variant: unref(props).closeVariant,
onClick: _cache[0] || (_cache[0] = withModifiers(($event) => unref(hide)("close"), ["stop", "prevent"]))
}, {
default: withCtx(() => [
renderSlot(_ctx.$slots, "close", normalizeProps(guardReactiveProps(sharedSlots.value)), () => [
createTextVNode(toDisplayString(unref(props).closeContent), 1)
])
]),
_: 3
}, 8, ["class", "variant"])) : (openBlock(), createBlock(_sfc_main$3, {
key: 1,
"aria-label": unref(props).closeLabel,
class: normalizeClass(["ms-auto", [unref(props).closeClass]]),
onClick: _cache[1] || (_cache[1] = withModifiers(($event) => unref(hide)("close"), ["stop", "prevent"]))
}, null, 8, ["aria-label", "class"]))
], 64)) : createCommentVNode("", true)
]),
_: 3
}, 8, ["class"])) : createCommentVNode("", true),
unref(contentShowing) && (slots.default || unref(props).body) ? (openBlock(), createElementBlock("div", _hoisted_2, [
(openBlock(), createBlock(resolveDynamicComponent(computedTag.value), mergeProps({
class: ["toast-body", unref(props).bodyClass]
}, unref(computedLinkProps), {
onClick: _cache[2] || (_cache[2] = ($event) => unref(computedLink) ? unref(hide)() : () => {
})
}), {
default: withCtx(() => [
renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(sharedSlots.value)), () => [
createTextVNode(toDisplayString(unref(props).body), 1)
])
]),
_: 3
}, 16, ["class"])),
!unref(props).noCloseButton && !(slots.title || unref(props).title) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
slots.close || unref(props).closeContent ? (openBlock(), createBlock(_component_BButton, {
key: 0,
class: normalizeClass([[unref(props).closeClass], "ms-auto btn-close-custom"]),
variant: unref(props).closeVariant,
onClick: _cache[3] || (_cache[3] = withModifiers(($event) => unref(hide)("close"), ["stop", "prevent"]))
}, {
default: withCtx(() => [
renderSlot(_ctx.$slots, "close", normalizeProps(guardReactiveProps(sharedSlots.value)), () => [
createTextVNode(toDisplayString(unref(props).closeContent), 1)
])
]),
_: 3
}, 8, ["class", "variant"])) : (openBlock(), createBlock(_sfc_main$3, {
key: 1,
"aria-label": unref(props).closeLabel,
class: normalizeClass(["ms-auto btn-close-custom", [unref(props).closeClass]]),
onClick: _cache[4] || (_cache[4] = withModifiers(($event) => unref(hide)("close"), ["stop", "prevent"]))
}, null, 8, ["aria-label", "class"]))
], 64)) : createCommentVNode("", true)
])) : createCommentVNode("", true),
typeof modelValue.value === "number" && !unref(props).noProgress ? (openBlock(), createBlock(_sfc_main$4, {
key: 2,
animated: unref(props).progressProps?.animated,
precision: unref(props).progressProps?.precision,
"show-progress": unref(props).progressProps?.showProgress,
"show-value": unref(props).progressProps?.showValue,
striped: unref(props).progressProps?.striped,
variant: unref(props).progressProps?.variant,
max: modelValue.value,
value: unref(remainingMs),
height: "4px"
}, null, 8, ["animated", "precision", "show-progress", "show-value", "striped", "variant", "max", "value"])) : createCommentVNode("", true)
], 10, _hoisted_1), [
[vShow, isToastVisible.value]
])
]),
_: 3
}, 16, ["appear"])) : createCommentVNode("", true);
};
}
});
const posDefault = "top-end";
const useToast = () => {
const orchestratorRegistry = inject(orchestratorRegistryKey);
if (!orchestratorRegistry) {
throw new Error(
"useToast() must be called within setup(), and BApp, useRegistry or plugin must be installed/provided."
);
}
const { store, _isToastAppend, _isOrchestratorInstalled } = orchestratorRegistry;
const create = (obj = {}, options = {}) => {
if (!_isOrchestratorInstalled.value) {
throw new Error(
"The BApp or BOrchestrator component must be mounted to use the toast composable"
);
}
const resolvedProps = toRef(obj);
const _self = resolvedProps.value?.id || Symbol("Toast controller");
const promise = buildPromise(_self, store);
promise.stop = watch(
resolvedProps,
(_newValue) => {
const newValue = { ...toValue(_newValue) };
const previousIndex = store.value.findIndex((el) => el._self === _self);
const previous = previousIndex === -1 ? { _component: markRaw(_sfc_main) } : store.value[previousIndex];
const v = {
...previous,
type: "toast",
_self,
promise,
options
};
if (newValue.props) {
Object.assign(v, newValue.props);
newValue.props = void 0;
}
if (newValue.pos) {
v.position = newValue.pos;
newValue.pos = void 0;
}
for (const key in newValue) {
if (key.startsWith("on")) {
v[key] = newValue[key];
} else if (key === "component" && newValue.component) {
v._component = markRaw(newValue.component);
} else if (key === "slots" && newValue.slots) {
v.slots = markRaw(newValue.slots);
} else {
v[key] = toValue(
newValue[key]
);
}
}
v.position = v.position || posDefault;
v.modelValue = v.modelValue ?? 5e3;
v["onUpdate:modelValue"] = (val) => {
newValue["onUpdate:modelValue"]?.(val);
const { modelValue } = toValue(obj);
if (isRef(obj) && !isRef(modelValue)) obj.value.modelValue = val;
if (isRef(modelValue) && !isReadonly(modelValue)) {
modelValue.value = val;
}
if (v.modelValue !== val) {
const toast = store.value.find((el) => el._self === _self);
if (toast) {
toast.modelValue = val;
}
}
};
if (previousIndex === -1) {
if (resolvedProps.value?.appendToast !== void 0 ? resolvedProps.value.appendToast : _isToastAppend.value) {
store.value.push(v);
} else {
store.value.unshift(v);
}
} else {
store.value.splice(previousIndex, 1, v);
}
},
{
deep: true,
immediate: true
}
);
onScopeDispose(() => {
const toast = store.value.find((el) => el._self === _self);
if (toast) {
toast.promise.value.destroy?.();
}
}, true);
return promise.value;
};
const show = (obj = {}) => {
console.warn(
"[BootstrapVueNext] useToast: The `show` method is deprecated. Use the `create` method instead."
);
return create(obj);
};
return {
_isToastAppend,
_isOrchestratorInstalled,
store,
create,
show
};
};
const useToastController = useToast;
export {
_sfc_main as _,
useToastController as a,
useToast as u
};
//# sourceMappingURL=index-C-NV_5Mj.mjs.map