UNPKG

@wonderflow/react-components

Version:

UI components from Wonderflow's Wanda design system

41 lines (40 loc) 3.4 kB
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';