UNPKG

@reusable-ui/hamburger-menu-button

Version:

A toggleable hamburger button for showing/hiding menu in Navbar.

90 lines (89 loc) 3.66 kB
// react: import { // react: default as React, } from 'react'; // cssfn: import { // checks if a certain css feature is supported by the running browser: supportsHasPseudoClass, } from '@cssfn/core'; // writes css in javascript import { // style sheets: dynamicStyleSheet, } from '@cssfn/cssfn-react'; // writes css in react hook // reusable-ui core: import { // react helper hooks: useEvent, useMergeEvents, useMergeClasses, useUncontrollableActivatable, } from '@reusable-ui/core'; // a set of reusable-ui packages which are responsible for building any component // reusable-ui components: import { ToggleButton, } from '@reusable-ui/toggle-button'; // a base component // internals: import { // states: useHamburgerable, } from './states/hamburgerable.js'; // styles: export const useHamburgerMenuButtonStyleSheet = dynamicStyleSheet(() => import(/* webpackPrefetch: true */ './styles/styles.js'), { id: '5sj70x1zsf', lazyCsr: supportsHasPseudoClass(), // dealing with browsers that don't support the :has() selector }); const HamburgerMenuButton = (props) => { // styles: const styleSheet = useHamburgerMenuButtonStyleSheet(); // states: const [isActive, , toggleActive] = useUncontrollableActivatable(props); const hamburgerableState = useHamburgerable(isActive); // rest props: const { // components: toggleButtonComponent = React.createElement(ToggleButton, null), ...restToggleButtonProps } = props; // classes: const stateClasses = useMergeClasses( // preserves the original `stateClasses` from `toggleButtonComponent`: toggleButtonComponent.props.stateClasses, // preserves the original `stateClasses` from `props`: props.stateClasses, // states: hamburgerableState.class); // handlers: const handleClickInternal = useEvent((event) => { // conditions: if (event.defaultPrevented) return; // the event was already handled by user => nothing to do // actions: toggleActive(); // handle click as toggle [active] event.preventDefault(); // handled }); const handleClick = useMergeEvents( // preserves the original `onClick` from `toggleButtonComponent`: toggleButtonComponent.props.onClick, // preserves the original `onClick` from `props`: props.onClick, // actions: handleClickInternal); // fn props: const activeFn = (toggleButtonComponent.props.active ?? isActive); // jsx: /* <ToggleButton> */ return React.cloneElement(toggleButtonComponent, // props: { // other props: ...restToggleButtonProps, ...toggleButtonComponent.props, // accessibilities: label: toggleButtonComponent.props.label ?? props.label ?? 'Toggle navigation', // classes: mainClass: toggleButtonComponent.props.mainClass ?? props.mainClass ?? styleSheet.main, stateClasses, // states: active: activeFn, // handlers: onClick: handleClick, }, // children: toggleButtonComponent.props.children ?? (React.createElement("svg", { viewBox: '0 0 24 24' }, React.createElement("polyline", { points: '3,4 21,4', // handlers: onAnimationStart: hamburgerableState.handleAnimationStart, onAnimationEnd: hamburgerableState.handleAnimationEnd }), React.createElement("polyline", { points: '3,12 21,12' }), React.createElement("polyline", { points: '3,20 21,20' })))); }; export { HamburgerMenuButton, HamburgerMenuButton as default, };