@wonderflow/react-components
Version:
UI components from Wonderflow's Wanda design system
41 lines (40 loc) • 3.4 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/*
* Copyright 2022-2023 Wonderflow Design Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useHover } from 'ahooks';
import clsx from 'clsx';
import { forwardRef, useCallback, useMemo, useRef, } from 'react';
import { useFocusEffect, useRovingTabIndex } from 'react-roving-tabindex';
import { Stack, Symbol, Text, Tooltip, } from '../../..';
import * as styles from './menu-item.module.css';
export const MenuItem = forwardRef(({ className, children, subtext, onClick, icon, dimension = 'regular', as: Wrapper = 'button', iconPosition = 'left', description, padding = true, disabled = false, autoFocus, decoration, value, ...otherProps }, forwardedRef) => {
const itemRef = useRef(forwardedRef);
const [tabIndex, isFocused, handleKeyDown, handleClick] = useRovingTabIndex(itemRef, disabled);
const isIconRight = iconPosition === 'right';
useFocusEffect(isFocused, itemRef);
const isHovering = useHover(itemRef);
const triggerClick = useCallback((e) => {
if (onClick) {
handleClick();
onClick(e, value);
}
}, [handleClick, onClick, value]);
const InnerContent = useMemo(() => (_jsxs(Stack, { direction: isIconRight ? 'row-reverse' : 'row', as: "span", fill: false, className: styles.ItemContent, hAlign: isIconRight ? 'space-between' : 'start', vAlign: "center", columnGap: 8, hPadding: 16, vPadding: 8, "data-menu-item-icon-right": isIconRight, "data-menu-item-has-icon": Boolean(icon), "data-menu-item-padding": padding, style: { inlineSize: '100%' }, children: [icon && (_jsx(Symbol, { className: styles.Icon, source: icon, dimension: dimension === 'small' ? 12 : 16 })), _jsxs(Stack, { className: styles.DecorationContent, columnGap: 16, fill: false, direction: "row", hAlign: "space-between", children: [_jsxs(Stack, { direction: "column", children: [children, subtext && _jsx(Text, { variant: dimension === 'small' ? 'body-3' : 'body-2', children: subtext })] }), decoration] })] })), [children, subtext, dimension, icon, isIconRight, decoration, padding]);
return (_jsx(Stack, { as: "li", role: "none", children: _jsx(Wrapper, { autoFocus: autoFocus, ref: itemRef, role: "menuitem", className: clsx(styles.MenuItem, className), onClick: disabled ? undefined : triggerClick, onKeyDown: disabled ? undefined : handleKeyDown, tabIndex: tabIndex, "aria-disabled": disabled, type: Wrapper === 'button' ? 'button' : undefined, "data-menu-item-dimension": dimension, "data-testid": "MenuItem", ...otherProps, children: description
? (_jsx(Tooltip, { fill: true, open: isFocused || isHovering, placement: "auto", interactive: true, ...otherProps, trigger: InnerContent, children: _jsx(Text, { variant: "body-2", children: description }) }))
: InnerContent }) }));
});
MenuItem.displayName = 'Menu.Item';