import { JsxChildren, JsxProps } from 'dom-renderer'; import { observable } from 'mobx'; import { FC, WebCell, WebCellProps, attribute, component, observer } from 'web-cell'; import { delegate, uniqueID } from 'web-utility'; import { Container, ContainerProps } from '../Layout/Grid'; import { Offcanvas, OffcanvasBody, OffcanvasBoxProps, OffcanvasHeader, OffcanvasTitle } from '../Layout/Offcanvas'; import { BackgroundColor, PositionY, Size } from '../type'; export type NavbarBrandProps = JsxProps; export const NavbarBrand: FC = ({ className = '', children, ...props }) => ( {children} ); export type NavbarToggleProps = JsxProps; export const NavbarToggle: FC = ({ className = '', type, children, ...props }) => ( ); export interface NavbarProps extends WebCellProps { variant?: 'light' | 'dark'; bg?: BackgroundColor; expand?: boolean | Size; fixed?: PositionY; sticky?: PositionY; } export const Navbar: FC = ({ variant = 'light', bg = 'body-tertiary', fixed, sticky, expand, children }) => ( ); export interface OffcanvasNavbarProps extends OffcanvasBoxProps, NavbarProps, ContainerProps { brand?: JsxChildren; } export interface OffcanvasNavbar extends WebCell {} @component({ tagName: 'offcanvas-navbar', mode: 'open' }) @observer export class OffcanvasNavbar extends HTMLElement implements WebCell { declare props: OffcanvasNavbarProps; @attribute @observable accessor variant: OffcanvasNavbarProps['variant']; @attribute @observable accessor bg: OffcanvasNavbarProps['bg']; @attribute @observable accessor expand: OffcanvasNavbarProps['expand']; @attribute @observable accessor fixed: OffcanvasNavbarProps['fixed']; @attribute @observable accessor sticky: OffcanvasNavbarProps['sticky']; @attribute @observable accessor fluid: ContainerProps['fluid']; @attribute @observable accessor title: string; titleId = uniqueID(); @observable accessor brand: OffcanvasNavbarProps['brand']; offcanvasId = uniqueID(); @attribute @observable accessor open = false; @attribute @observable accessor closeButton = true; connectedCallback() { globalThis.addEventListener?.('keyup', this.close, true); this.addEventListener('click', this.handleLink); } disconnectedCallback() { globalThis.removeEventListener?.('keyup', this.close, true); this.addEventListener('click', this.handleLink); } close = (event?: KeyboardEvent | MouseEvent) => { if ( event instanceof KeyboardEvent && !['Escape', 'Enter'].includes(event.key) ) return; this.open = false; }; handleLink = delegate('a[href].nav-link', this.close); renderContent() { const { variant, bg, expand, fixed, sticky, fluid, brand } = this, { title, titleId, offcanvasId, open, closeButton } = this; return ( {brand || title} (this.open = true)} /> (this.open = false)} > {brand || title} ); } render() { return ( <> {this.renderContent()} ); } }