@nex-ui/react
Version:
🎉 A beautiful, modern, and reliable React component library.
80 lines (77 loc) • 2.71 kB
JavaScript
"use client";
import { jsx } from 'react/jsx-runtime';
import { nex } from '@nex-ui/styled';
import { useFocusRing, useEvent } from '@nex-ui/hooks';
import { useMemo } from 'react';
import { isFunction } from '@nex-ui/utils';
import { buttonBaseRecipes } from '../../theme/recipes/buttonBase.mjs';
import { useSlotProps } from '../utils/useSlotProps.mjs';
const useAriaProps = (props)=>{
const { as, disabled, role, href, type = 'button', 'aria-disabled': ariaDisabled, tabIndex = 0 } = props;
return useMemo(()=>{
if (as !== 'button' && !isFunction(as)) {
return {
role: role ?? (as === 'a' && href ? undefined : 'button'),
tabIndex: disabled ? -1 : tabIndex,
'aria-disabled': ariaDisabled ?? (disabled || undefined)
};
}
return {
type,
disabled,
tabIndex: disabled ? -1 : tabIndex
};
}, [
as,
type,
disabled,
tabIndex,
role,
href,
ariaDisabled
]);
};
const ButtonBase = (inProps)=>{
const props = inProps;
const { as, children, disabled, ...remainingProps } = props;
const rootElement = as !== undefined ? as : typeof props.href === 'string' && props.href ? 'a' : 'button';
const { focusVisible, focusProps } = useFocusRing();
const handleKeyDown = useEvent((event)=>{
// Limit the repeated triggering of the click event when the Enter key is pressed.
if (focusVisible && event.key === 'Enter' && event.target === event.currentTarget && (event.currentTarget.tagName === 'BUTTON' || event.currentTarget.tagName === 'A')) {
event.preventDefault();
}
});
const handleKeyUp = useEvent((event)=>{
// Keyboard accessibility for non interactive elements
if (focusVisible && event.target === event.currentTarget && (event.key === 'Space' || event.key === 'Enter')) {
event.currentTarget.click();
}
});
const ariaProps = useAriaProps({
...props,
as: rootElement
});
const style = buttonBaseRecipes({
disabled
});
const rootProps = useSlotProps({
style,
a11y: ariaProps,
externalForwardedProps: remainingProps,
additionalProps: {
disabled,
onKeyUp: handleKeyUp,
onKeyDown: handleKeyDown,
'data-focus-visible': focusVisible || undefined,
...focusProps
}
});
return /*#__PURE__*/ jsx(nex.button, {
as: rootElement,
...rootProps,
children: children
});
};
ButtonBase.displayName = 'ButtonBase';
export { ButtonBase };