'use strict';

var React = require('react');
var ReactDOM = require('react-dom');
var framerMotion = require('framer-motion');
var jobberHooks = require('@jobber/hooks');
var classnames = require('classnames');
var design = require('@jobber/design');
var Heading = require('./Heading-cjs.js');
var Button = require('./Button-cjs.js');
var Flex = require('./Flex-cjs.js');

const SideDrawerContext = React.createContext({
    components: {
        backButton: false,
    },
    registerComponent: () => undefined,
    unRegisterComponent: () => undefined,
});
function useSideDrawerContext() {
    const context = React.useContext(SideDrawerContext);
    return context;
}

function SideDrawerActions({ children }) {
    const { actionPortal } = useSideDrawerContext();
    if (!actionPortal)
        return null;
    return ReactDOM.createPortal(React.createElement(React.Fragment, null, children), actionPortal);
}

function SideDrawerTitle({ children }) {
    const { titlePortal } = useSideDrawerContext();
    if (!titlePortal)
        return null;
    if (typeof children === "string") {
        return ReactDOM.createPortal(React.createElement(Heading.Heading, { level: 2 }, children), titlePortal);
    }
    return ReactDOM.createPortal(children, titlePortal);
}

function SideDrawerToolbar({ children }) {
    const { toolbarPortal } = useSideDrawerContext();
    if (!toolbarPortal)
        return null;
    return ReactDOM.createPortal(children, toolbarPortal);
}

var styles = {"drawer":"cCwRgRAz4qk-","inline":"ONUfsWMLKdo-","container":"XipkpXgyzyg-","header":"LuqC0RF-R1U-","content":"vArEcEUxGxQ-","footer":"_4HzuRZKD9u8-","subtle":"v5Db-FCF2kU-","heading":"Eti1JL3rghE-","hasShadow":"PtbV1GtWwzY-","headerActions":"YCdqkhcLHfI-","hideWhenEmpty":"ZH2Mp84HhX8-","overlay":"Ro-pE7hx0wY-","reverseScroll":"gSN5nWDwGm4-","headerShadowListener":"tMeBAjf4vEA-","footerShadowListener":"-lPSZVGIIAs-","backButton":"XOqA4Hw6S6g-","backButtonVisible":"b4VHPS-RG34-","spinning":"McL3-VWXVbs-"};

function SideDrawerBackButton({ onClick, }) {
    const { backPortal, registerComponent, unRegisterComponent } = useSideDrawerContext();
    React.useEffect(() => {
        registerComponent("backButton");
        return () => {
            unRegisterComponent("backButton");
        };
    }, []);
    if (!backPortal)
        return null;
    return ReactDOM.createPortal(React.createElement(Button.Button, { ariaLabel: "Back", icon: "longArrowLeft", variation: "subtle", type: "tertiary", onClick: onClick }), backPortal);
}

function SideDrawerFooter({ children }) {
    const { footerPortal } = useSideDrawerContext();
    if (!footerPortal)
        return null;
    return ReactDOM.createPortal(React.createElement(React.Fragment, null, children), footerPortal);
}

const variants = {
    initial: { x: "100%" },
    visible: { x: 0, transitionEnd: { x: 0 } },
    hidden: { x: "100%" },
};
const inlineVariants = {
    initial: { x: "25%", opacity: 0 },
    visible: { x: 0, opacity: 1, transitionEnd: { x: 0 } },
    hidden: { x: "25%", opacity: 0 },
};
const useSideDrawerState = (open) => {
    const [ref, setRef] = React.useState(null);
    const [components, setComponents] = React.useState({
        backButton: false,
    });
    const { toolbar, title, actions, backButton, footer } = useSlotIDs();
    jobberHooks.useRefocusOnActivator(open);
    const sideDrawerRef = jobberHooks.useFocusTrap(open);
    const [headerShadowRef, noHeaderShadow] = jobberHooks.useInView();
    const [footerShadowRef, noFooterShadow] = jobberHooks.useInView();
    return {
        ref,
        setRef,
        components,
        setComponents,
        slots: { toolbar, title, actions, backButton, footer },
        sideDrawerRef,
        headerShadowRef,
        noHeaderShadow,
        footerShadowRef,
        noFooterShadow,
    };
};
function SideDrawer({ children, onRequestClose, open, variation = "base", scrollDirection, inline = false, UNSAFE_className, UNSAFE_style, }) {
    var _a;
    const { ref, setRef, components, setComponents, slots, sideDrawerRef, headerShadowRef, noHeaderShadow, footerShadowRef, noFooterShadow, } = useSideDrawerState(open);
    jobberHooks.useRefocusOnActivator(open);
    const container = ((_a = globalThis.document) === null || _a === void 0 ? void 0 : _a.body) || null;
    const isMounted = jobberHooks.useIsMounted();
    if (!isMounted.current && !container)
        return null;
    const SideDrawerRender = (React.createElement(SideDrawerContext.Provider, { value: {
            actionPortal: ref === null || ref === void 0 ? void 0 : ref.querySelector(slots.actions.selector),
            titlePortal: ref === null || ref === void 0 ? void 0 : ref.querySelector(slots.title.selector),
            toolbarPortal: ref === null || ref === void 0 ? void 0 : ref.querySelector(slots.toolbar.selector),
            backPortal: ref === null || ref === void 0 ? void 0 : ref.querySelector(slots.backButton.selector),
            footerPortal: ref === null || ref === void 0 ? void 0 : ref.querySelector(slots.footer.selector),
            components,
            registerComponent: key => setComponents(prev => (Object.assign(Object.assign({}, prev), { [key]: true }))),
            unRegisterComponent: key => setComponents(prev => (Object.assign(Object.assign({}, prev), { [key]: false }))),
        } },
        open && !inline && (React.createElement("button", { className: styles.overlay, "aria-label": "Close", onClick: onRequestClose, type: "button" })),
        React.createElement(framerMotion.AnimatePresence, { initial: false }, open && (React.createElement(framerMotion.motion.div, { className: classnames(styles.drawer, {
                [styles.reverseScroll]: scrollDirection === "reverse",
                [styles.inline]: inline,
            }, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.container), ref: setRef, "data-elevation": "elevated", variants: inline ? inlineVariants : variants, initial: "initial", animate: "visible", exit: "hidden", transition: {
                duration: design.tokens["timing-base"] / 1000,
            }, style: UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.container },
            React.createElement("div", { ref: sideDrawerRef, role: "dialog", className: classnames(styles.container, styles.hasShadow, {
                    [styles.subtle]: variation === "subtle",
                }), tabIndex: 0, onKeyDown: handleKeyDown },
                React.createElement("div", { className: classnames(styles.header, {
                        [styles.hasShadow]: headerShadowRef.current && !noHeaderShadow,
                    }) },
                    React.createElement(Flex.Flex, { template: ["grow", "shrink"], align: "start" },
                        React.createElement(Flex.Flex, { template: ["shrink", "grow"], align: "start", gap: "none" },
                            React.createElement("div", Object.assign({ className: classnames(styles.backButton, {
                                    [styles.backButtonVisible]: components.backButton,
                                }) }, slots.backButton.attr)),
                            React.createElement("div", Object.assign({ className: classnames(styles.heading) }, slots.title.attr))),
                        React.createElement("div", { className: styles.headerActions },
                            React.createElement("div", Object.assign({ className: styles.hideWhenEmpty }, slots.actions.attr)),
                            React.createElement(Button.Button, { ariaLabel: "Close", icon: "cross", onClick: onRequestClose, type: "tertiary", variation: "subtle" }))),
                    React.createElement("div", Object.assign({ className: styles.hideWhenEmpty }, slots.toolbar.attr))),
                React.createElement("div", { className: styles.content },
                    React.createElement("div", { className: styles.headerShadowListener, ref: headerShadowRef }),
                    children,
                    React.createElement("div", { className: styles.footerShadowListener, ref: footerShadowRef })),
                React.createElement("div", Object.assign({ className: classnames(styles.footer, styles.hideWhenEmpty, {
                        [styles.hasShadow]: footerShadowRef.current && !noFooterShadow,
                    }) }, slots.footer.attr))))))));
    if (inline) {
        return SideDrawerRender;
    }
    return ReactDOM.createPortal(SideDrawerRender, container);
    function handleKeyDown(event) {
        if (event.key === "Escape") {
            event.stopPropagation();
            onRequestClose();
        }
    }
}
function useSlotIDs() {
    const toolbar = useSlotID();
    const title = useSlotID("title");
    const actions = useSlotID();
    const backButton = useSlotID("back");
    const footer = useSlotID();
    return { toolbar, title, actions, backButton, footer };
}
function useSlotID(prefix) {
    const id = React.useId();
    const prefixedId = prefix ? `${prefix}-${id}` : id;
    const attrKey = "data-side-drawer-slot";
    const selector = `[${attrKey}="${prefixedId}"]`;
    const attr = { [attrKey]: prefixedId };
    return { id: prefixedId, selector, attr };
}
SideDrawer.Title = SideDrawerTitle;
SideDrawer.Toolbar = SideDrawerToolbar;
SideDrawer.Actions = SideDrawerActions;
SideDrawer.BackButton = SideDrawerBackButton;
SideDrawer.Footer = SideDrawerFooter;

exports.SideDrawer = SideDrawer;
