UNPKG

wix-style-react

Version:
135 lines 6.39 kB
import React, { forwardRef, useImperativeHandle, useContext, useMemo, } from 'react'; import PropTypes from 'prop-types'; import { AddItemLarge, AddItemMedium, AddItemSmall, AddMedia, } from '@wix/wix-ui-icons-common/system'; import { Add } from '@wix/wix-ui-icons-common'; import { WixStyleReactContext } from '../WixStyleReactProvider/context'; import { useFocusRing } from '../providers/useFocusRing/useFocusRing'; import Tooltip from '../Tooltip'; import Text from '../Text'; import Image from '../Image'; import { dataHooks } from './constants'; import { st, classes } from './AddItem.st.css'; const AddItemButtonIcons = { tiny: ({ className }) => (React.createElement(Add, { "data-hook": dataHooks.defaultIcon, className: className, width: "24", height: "24" })), small: () => React.createElement(AddItemSmall, { "data-hook": dataHooks.defaultIcon }), medium: () => React.createElement(AddItemMedium, { "data-hook": dataHooks.defaultIcon }), large: () => React.createElement(AddItemLarge, { "data-hook": dataHooks.defaultIcon }), image: ({ className }) => (React.createElement(AddMedia, { "data-hook": dataHooks.defaultIcon, className: className, width: "31", height: "31" })), }; const illustrationDimensions = { tiny: { height: 24, width: 24 }, small: { height: 60, width: 60 }, medium: { height: 120, width: 120 }, large: { height: 120, width: 120 }, }; const tooltipPlacementByAlignment = { left: 'top-start', right: 'top-end', center: 'top', }; const AddItem = forwardRef(({ theme = 'dashes', size = 'tiny', alignItems = 'center', removePadding = false, borderRadius, disabled, className, onClick, ariaLabel, icon, children, subtitle, dataHook, tooltipProps, tooltipContent, showIcon = true, }, ref) => { const { newColorsBranding } = useContext(WixStyleReactContext); const buttonRef = React.useRef(null); useImperativeHandle(ref, () => ({ focus: () => { buttonRef.current?.focus(); }, blur: () => { buttonRef.current?.blur(); }, })); const iconElement = useMemo(() => { if (!showIcon) { return; } if (!icon) { const isImageIcon = theme === 'image'; const Icon = AddItemButtonIcons[isImageIcon ? 'image' : size]; return React.createElement(Icon, { className: classes.icon }); } if (typeof icon === 'string') { return (React.createElement(Image, { className: classes.illustration, fit: "contain", src: icon, ...illustrationDimensions[size] })); } return icon; }, [icon, size, theme, showIcon]); const textElement = useMemo(() => { if (!children || theme === 'image') { return; } const textSize = size === 'tiny' ? 'small' : 'medium'; return (React.createElement("div", { className: st(classes.textWrapper, { size }) }, typeof children === 'function' ? (children()) : (React.createElement(Text, { className: classes.textContent, weight: "thin", skin: "standard", size: textSize, dataHook: dataHooks.itemText, ellipsis: true }, children)))); }, [children, size, theme]); const subtitleElement = useMemo(() => { return (subtitle && (React.createElement(Text, { className: st(classes.subtitle, { size }), size: "small", dataHook: dataHooks.itemSubtitle }, subtitle))); }, [subtitle, size]); const commonButtonProps = { className, onClick, disabled, theme, size, ariaLabel, borderRadius, removePadding, newColorsBranding, alignItems, icon: iconElement, text: textElement, subtitle: subtitleElement, }; // TODO: remove this once we deprecate content usage thhrough tooltip // @ts-expect-error const tooltip = tooltipContent || tooltipProps?.content; return (React.createElement("div", { style: { width: '100%', height: '100%' }, "data-hook": dataHook }, tooltip && (React.createElement(Tooltip, { content: tooltip, className: classes.tooltip, flip: theme === 'image', moveBy: { y: theme === 'image' ? -12 : 0 }, dataHook: dataHooks.itemTooltip, placement: tooltipPlacementByAlignment[alignItems], ...tooltipProps }, React.createElement(AddItemButton, { ref: buttonRef, ...commonButtonProps }))), !tooltip && React.createElement(AddItemButton, { ref: buttonRef, ...commonButtonProps }))); }); const AddItemButton = forwardRef(({ className, onClick, disabled, size, ariaLabel, borderRadius, alignItems = 'center', newColorsBranding, removePadding, theme, icon, text, subtitle, }, ref) => { const { isFocusVisible, focusProps } = useFocusRing(); return (React.createElement("button", { ref: ref, "data-hook": dataHooks.addItem, className: st(classes.root, { theme, size, removePadding, borderRadius, disabled, alignItems, newColorsBranding, 'focus-visible': isFocusVisible, }, className), style: { borderRadius }, disabled: disabled, type: "button", onClick: onClick, "aria-label": ariaLabel, ...focusProps }, React.createElement("div", { className: st(classes.contentContainer, { theme, size, alignItems, disabled, }) }, React.createElement("div", { className: st(classes.content, { size }) }, icon, text), subtitle))); }); AddItem.displayName = 'AddItem'; AddItem.propTypes = { // @ts-ignore children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), disabled: PropTypes.bool, theme: PropTypes.oneOf(['dashes', 'plain', 'filled', 'image']), alignItems: PropTypes.oneOf(['center', 'right', 'left']), size: PropTypes.oneOf(['large', 'medium', 'small', 'tiny']), onClick: PropTypes.func, dataHook: PropTypes.string, className: PropTypes.string, // @ts-ignore tooltipContent: PropTypes.node, tooltipProps: PropTypes.object, showIcon: PropTypes.bool, removePadding: PropTypes.bool, borderRadius: PropTypes.string, ariaLabel: PropTypes.string, // @ts-ignore subtitle: PropTypes.node, // @ts-ignore icon: PropTypes.node, }; export default AddItem; //# sourceMappingURL=AddItem.js.map