UNPKG

@reusable-ui/nav-button

Version:

A clickable button for navigation.

78 lines (77 loc) 3.01 kB
// react: import { // react: default as React, } from 'react'; // reusable-ui core: import { // react helper hooks: useMergeRefs, // an accessibility management system: usePropActive, ElementWithAutoActive, } from '@reusable-ui/core'; // a set of reusable-ui packages which are responsible for building any component // reusable-ui components: import { Button, } from '@reusable-ui/button'; // a base component const NavButton = (props) => { // rest props: const { // navigations: caseSensitive, end, // components: buttonComponent = React.createElement(Button, null), ...restButtonProps } = props; // refs: const mergedElmRef = useMergeRefs( // preserves the original `elmRef` from `buttonComponent`: buttonComponent.props.elmRef, // preserves the original `elmRef` from `props`: props.elmRef); const mergedOuterRef = useMergeRefs( // preserves the original `outerRef` from `buttonComponent`: buttonComponent.props.outerRef, // preserves the original `outerRef` from `props`: props.outerRef); // fn props: const propActive = usePropActive(props, null); const activeSt = (buttonComponent.props.active ?? propActive) /*controllable*/; const isControllableActive = activeSt !== null; // jsx: /* <Button> */ const navButton = React.cloneElement(buttonComponent, // props: { // other props: ...restButtonProps, ...buttonComponent.props, // refs: elmRef: mergedElmRef, outerRef: mergedOuterRef, // semantics: 'aria-current': buttonComponent.props['aria-current'] ?? props['aria-current'] ?? 'page', }, // children: buttonComponent.props.children ?? props.children); if (isControllableActive) return React.cloneElement(navButton, // props: { // states: active: activeSt, }); const navButtonProps = navButton.props; return (React.createElement(ElementWithAutoActive // other props: , { ...navButtonProps, // navigations: caseSensitive: caseSensitive, end: end, // components: elementComponent: // the underlying `<Element>` to be `<Link>`-ed and manipulated of `[active]` & `[aria-current]` props, based on the current page url // clone navButton element with (almost) blank props: React.createElement(navButton.type // identifiers: , { // identifiers: key: navButton.key, ...{ ...(('caseSensitive' in navButtonProps) ? { caseSensitive: navButtonProps.caseSensitive } : undefined), ...(('end' in navButtonProps) ? { end: navButtonProps.end } : undefined), ...(('elementComponent' in navButtonProps) ? { elementComponent: navButtonProps.elementComponent } : undefined), } }) })); }; export { NavButton, NavButton as default, };