UNPKG

@reusable-ui/action-control

Version:

A base clickable (button) UI of Reusable-UI components.

100 lines (99 loc) 4.09 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: useMergeEvents, useMergeClasses, // an accessibility management system: usePropEnabled, // a set of client-side functions: ElementWithMaybeLink, useClickable, } from '@reusable-ui/core'; // a set of reusable-ui packages which are responsible for building any component // reusable-ui components: import { Control, } from '@reusable-ui/control'; // a base component // defaults: const _defaultSemanticTag = [null, 'button', 'a']; // no corresponding semantic tag => defaults to <div>, fallbacks to <button>, <a> const _defaultSemanticRole = ['button', 'link']; // uses [role="button"] as the default semantic role , fallbacks to [role="link"] const _defaultClickableOptions = { handleActionCtrlEvents: true, // needs to handle [space] key as onClick handleKeyEnterEvents: true, // needs to handle [enter] key as onClick }; // styles: export const useActionControlStyleSheet = dynamicStyleSheet(() => import(/* webpackPrefetch: true */ './styles/styles.js'), { id: '5u3j6wjzxd', // a unique salt for SSR support, ensures the server-side & client-side have the same generated class names lazyCsr: supportsHasPseudoClass(), // dealing with browsers that don't support the :has() selector }); const ActionControl = (props) => { // styles: const styleSheet = useActionControlStyleSheet(); // states: const clickableState = useClickable(props, _defaultClickableOptions); // fn props: const propEnabled = usePropEnabled(props); // rest props: const { // states: pressed: _pressed, // remove // behaviors: actionMouses: _actionMouses, // remove actionTouches: _actionTouches, // remove actionKeys: _actionKeys, // remove releaseDelay: _releaseDelay, // remove // handlers: onClick: _onClick, // remove ...restControlProps } = props; // classes: const stateClasses = useMergeClasses( // preserves the original `stateClasses`: props.stateClasses, // states: clickableState.class); // handlers: const handleMouseDown = useMergeEvents( // preserves the original `onMouseDown`: props.onMouseDown, // states: clickableState.handleMouseDown); const handleTouchStart = useMergeEvents( // preserves the original `onTouchStart`: props.onTouchStart, // states: clickableState.handleTouchStart); const handleKeyDown = useMergeEvents( // preserves the original `onKeyDown`: props.onKeyDown, // states: clickableState.handleKeyDown); const handleClick = clickableState.handleClick; const handleAnimationStart = useMergeEvents( // preserves the original `onAnimationStart`: props.onAnimationStart, // states: clickableState.handleAnimationStart); const handleAnimationEnd = useMergeEvents( // preserves the original `onAnimationEnd`: props.onAnimationEnd, // states: clickableState.handleAnimationEnd); // jsx: return (React.createElement(ElementWithMaybeLink // components: , { // components: elementComponent: React.createElement(Control, { ...restControlProps, // semantics: semanticTag: props.semanticTag ?? _defaultSemanticTag, semanticRole: props.semanticRole ?? _defaultSemanticRole, // classes: mainClass: props.mainClass ?? styleSheet.main, stateClasses: stateClasses, ...(!propEnabled ? { href: undefined } : null), // handlers: onMouseDown: handleMouseDown, onTouchStart: handleTouchStart, onKeyDown: handleKeyDown, onClick: handleClick, onAnimationStart: handleAnimationStart, onAnimationEnd: handleAnimationEnd }) })); }; export { ActionControl, ActionControl as default, };