UNPKG

@tanstack/vue-router

Version:

Modern and scalable routing for Vue applications

118 lines (117 loc) 3.11 kB
import * as Vue from "vue"; //#region src/CatchBoundary.tsx var VueErrorBoundary = Vue.defineComponent({ name: "VueErrorBoundary", props: { onError: Function, resetKey: [String, Number] }, emits: ["catch"], setup(props, { slots }) { const error = Vue.ref(null); const resetFn = Vue.ref(null); const reset = () => { error.value = null; }; Vue.watch(() => props.resetKey, (newKey, oldKey) => { if (newKey !== oldKey && error.value) reset(); }); Vue.onErrorCaptured((err) => { if (err instanceof Promise || err && typeof err.then === "function") return false; error.value = err; resetFn.value = reset; if (props.onError) props.onError(err); return false; }); return () => { if (error.value && slots.fallback) { const fallbackContent = slots.fallback({ error: error.value, reset }); return Array.isArray(fallbackContent) && fallbackContent.length === 1 ? fallbackContent[0] : fallbackContent; } const defaultContent = slots.default && slots.default(); return Array.isArray(defaultContent) && defaultContent.length === 1 ? defaultContent[0] : defaultContent; }; } }); var CatchBoundaryWrapper = Vue.defineComponent({ name: "CatchBoundary", inheritAttrs: false, props: [ "getResetKey", "children", "errorComponent", "onCatch" ], setup(props) { const resetKey = Vue.computed(() => props.getResetKey()); return () => { return Vue.h(VueErrorBoundary, { resetKey: resetKey.value, onError: props.onCatch }, { default: () => props.children, fallback: ({ error, reset }) => { if (props.errorComponent) return Vue.h(props.errorComponent, { error, reset }); return Vue.h(ErrorComponent, { error, reset }); } }); }; } }); function CatchBoundary(props) { return Vue.h(CatchBoundaryWrapper, props); } var ErrorComponent = Vue.defineComponent({ name: "ErrorComponent", props: { error: Object, reset: Function }, setup(props) { const show = Vue.ref(process.env.NODE_ENV !== "production"); const toggleShow = () => { show.value = !show.value; }; return () => Vue.h("div", { style: { padding: ".5rem", maxWidth: "100%" } }, [ Vue.h("div", { style: { display: "flex", alignItems: "center", gap: ".5rem" } }, [Vue.h("strong", { style: { fontSize: "1rem" } }, "Something went wrong!"), Vue.h("button", { style: { appearance: "none", fontSize: ".6em", border: "1px solid currentColor", padding: ".1rem .2rem", fontWeight: "bold", borderRadius: ".25rem" }, onClick: toggleShow }, show.value ? "Hide Error" : "Show Error")]), Vue.h("div", { style: { height: ".25rem" } }), show.value ? Vue.h("div", {}, [Vue.h("pre", { style: { fontSize: ".7em", border: "1px solid red", borderRadius: ".25rem", padding: ".3rem", color: "red", overflow: "auto" } }, [props.error?.message ? Vue.h("code", {}, props.error.message) : null])]) : null ]); } }); //#endregion export { CatchBoundary, ErrorComponent }; //# sourceMappingURL=CatchBoundary.js.map