import {children, mergeProps, splitProps, useContext} from "solid-js"; import classNames from "./classnames"; import { Modal as BaseModal, ModalProps as BaseModalProps, RenderModalBackdropProps, RenderModalDialogProps, } from "solid-bootstrap-core"; import Fade from "./Fade"; import OffcanvasBody from "./OffcanvasBody"; import OffcanvasToggling from "./OffcanvasToggling"; import ModalContext from "./ModalContext"; import NavbarContext from "./NavbarContext"; import OffcanvasHeader from "./OffcanvasHeader"; import OffcanvasTitle from "./OffcanvasTitle"; import {BsPrefixRefForwardingComponent} from "./helpers"; import {useBootstrapPrefix} from "./ThemeProvider"; import {BootstrapModalManager, getSharedManager} from "./BootstrapModalManager"; export type OffcanvasPlacement = "start" | "end" | "top" | "bottom"; export interface OffcanvasProps extends Omit< BaseModalProps, "role" | "renderBackdrop" | "renderDialog" | "transition" | "backdrop" | "backdropTransition" > { bsPrefix?: string; backdropClass?: string; scroll?: boolean; placement?: OffcanvasPlacement; } const defaultProps: Partial = { show: false, backdrop: true, keyboard: true, scroll: false, autoFocus: true, enforceFocus: true, restoreFocus: true, placement: "start", }; function DialogTransition(props: any) { return ; } function BackdropTransition(props: any) { return ; } const Offcanvas: BsPrefixRefForwardingComponent<"div", OffcanvasProps> = (p: OffcanvasProps) => { const [local, props] = splitProps(mergeProps(defaultProps, p), [ "bsPrefix", "class", "children", "aria-labelledby", "placement", /*BaseModal props */ "show", "backdrop", "keyboard", "scroll", "onEscapeKeyDown", "onShow", "onHide", "container", "autoFocus", "enforceFocus", "restoreFocus", "restoreFocusOptions", "onEntered", "onExit", "onExiting", "onEnter", "onEntering", "onExited", "backdropClass", "manager", "ref", ]); let modalManager: BootstrapModalManager; const bsPrefix = useBootstrapPrefix(local.bsPrefix, "offcanvas"); const navbarContext = useContext(NavbarContext); const handleHide = () => { navbarContext?.onToggle?.(); local.onHide?.(); }; const modalContext = { get onHide() { return handleHide; }, }; function getModalManager() { if (local.manager) return local.manager; if (local.scroll) { // Have to use a different modal manager since the shared // one handles overflow. if (!modalManager) modalManager = new BootstrapModalManager({ handleContainerOverflow: false, }); return modalManager; } return getSharedManager(); } const handleEnter = (node: any, ...args: any[]) => { if (node) node.style.visibility = "visible"; local.onEnter?.(node, ...args); }; const handleExited = (node: any, ...args: any[]) => { if (node) node.style.visibility = ""; local.onExited?.(...args); }; const renderBackdrop = (backdropProps: RenderModalBackdropProps) => (
{/* {props.children} */}
); let child: ReturnType; const renderDialog = (dialogProps: RenderModalDialogProps) => { if (!child) child = children(() => local.children); return ( ); }; return ( ); }; export default Object.assign(Offcanvas, { Body: OffcanvasBody, Header: OffcanvasHeader, Title: OffcanvasTitle, });