import * as Vue from 'vue';
import { renderInNonRouteComponentContext } from './nonRouteComponentContext';
const VueErrorBoundary = Vue.defineComponent({
    name: 'VueErrorBoundary',
    props: {
        onError: Function,
        resetKey: [String, Number, Object],
        children: null,
        errorComponent: null,
    },
    setup(props) {
        const error = 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;
            if (props.onError) {
                props.onError(err);
            }
            return false;
        });
        return () => {
            if (!error.value) {
                return props.children;
            }
            const errorComponent = props.errorComponent ?? ErrorComponent;
            const errorProps = {
                error: error.value,
                reset,
            };
            return process.env.NODE_ENV !== 'production'
                ? renderInNonRouteComponentContext(errorComponent, errorProps, 'errorComponent')
                : Vue.h(errorComponent, errorProps);
        };
    },
});
export function CatchBoundary(props) {
    return Vue.h(VueErrorBoundary, {
        resetKey: props.getResetKey(),
        onError: props.onCatch,
        children: props.children,
        errorComponent: props.errorComponent,
    });
}
CatchBoundary.inheritAttrs = false;
CatchBoundary.props = ['getResetKey', 'children', 'errorComponent', 'onCatch'];
export const 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,
        ]);
    },
});
//# sourceMappingURL=CatchBoundary.jsx.map