bootstrap-vue-next
Version:
Seamless integration of Vue 3, Bootstrap 5, and TypeScript for modern, type-safe UI development
126 lines (125 loc) • 3.93 kB
JavaScript
import { _ as orchestratorRegistryKey, x as showHideRegistryKey } from "../../../keys-BgLwJbLV.js";
import { buildController, getOrchestratorControllerId } from "../orchestratorShared/index.mjs";
import { t as BToast_default } from "../../../BToast-Di9HwBOV.js";
import { computed, inject, markRaw, onScopeDispose, ref } from "vue";
//#region src/composables/useToast/index.ts
var posDefault = "top-end";
var useToast = () => {
const orchestratorRegistry = inject(orchestratorRegistryKey, null);
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 showHideRegistry = inject(showHideRegistryKey, null);
/**
* @returns {ComponentController<typeof BToast, ToastOrchestratorParam>}
*/
function create(obj = {}) {
if (!_isOrchestratorInstalled.value) throw new Error("The BApp component must be mounted to use the toast composable");
const toastComp = markRaw(BToast_default);
const resolvedProps = ref(obj);
const toastStore = computed(() => store.value.toast);
const { htmlAttributeId, storeId } = getOrchestratorControllerId(resolvedProps.value.id);
const { resolve, controller } = buildController(storeId, toastStore);
const value = computed({
get: () => {
const { component = toastComp, options, slots, ...props } = resolvedProps.value;
return {
component,
options,
slots,
id: storeId,
fns: {
resolve,
setRef: (v) => {
controller.ref = v;
},
destroy: controller.destroy
},
props: {
...props,
id: htmlAttributeId,
position: props.position || posDefault
}
};
},
set: (v) => {
resolvedProps.value = {
...resolvedProps.value,
...v.props
};
}
});
toastStore.value.set(storeId, value);
onScopeDispose(async () => {
await controller[Symbol.asyncDispose]();
}, true);
return controller;
}
/**
* Hides a mounted BToast that registered itself under `id`. Going through the component, rather
* than through the store, is what lets the trigger flow through the regular hide cycle
*
* @returns whether a toast was found
*/
const hideRegisteredInstance = (id, trigger) => {
if (typeof id !== "string") return false;
const instances = showHideRegistry?.values.value.get(id)?.instances;
if (!instances) return false;
for (let i = instances.length - 1; i >= 0; i--) {
const instance = instances[i];
if (instance?.component.type !== BToast_default) continue;
instance.hide(trigger, true);
return true;
}
return false;
};
/**
* Hides a toast that lives in the orchestrator store. Prefers the mounted instance, falling back
* to the store entry itself, which also covers toasts that the orchestrator has yet to render
* and toasts rendered through a custom `component`
*/
const hideStoreItem = (item, trigger) => {
if (hideRegisteredInstance(item.value.props.id ?? item.value.id, trigger)) return;
item.value = {
...item.value,
props: {
...item.value.props,
modelValue: false
}
};
};
/**
* Hide all toasts
* @param trigger - The trigger to hide all toasts
*/
const hideAll = (trigger) => {
for (const item of store.value.toast.values()) hideStoreItem(item, trigger);
};
/**
* Hide a toast
* @param trigger - The trigger to hide the toast
* @param id - The id of the toast to hide, when omitted every toast is hidden
*/
const hide = (trigger, id) => {
if (id === void 0) {
hideAll(trigger);
return;
}
const item = store.value.toast.get(id);
if (item) {
hideStoreItem(item, trigger);
return;
}
hideRegisteredInstance(id, trigger);
};
return {
_isToastAppend,
_isOrchestratorInstalled,
store,
create,
hide,
hideAll
};
};
//#endregion
export { useToast };
//# sourceMappingURL=index.mjs.map