UNPKG

@wix/design-system

Version:

@wix/design-system

135 lines 6.43 kB
import React, { forwardRef, useImperativeHandle, useMemo, useEffect, } from 'react'; import { AddItemLarge, AddItemMedium, AddItemSmall, AddMedia, } from '@wix/wix-ui-icons-common/system'; import { Add } from '@wix/wix-ui-icons-common'; import { useFocusRing } from '../providers/useFocusRing/useFocusRing'; import { useId } from '../utils/useId'; import { useIcons } from '../WixDesignSystemIconThemeProvider'; import Tooltip from '../Tooltip'; import Text from '../Text'; import Image from '../Image'; import { dataHooks } from './constants'; import { st, classes } from './AddItem.st.css.js'; import deprecationLog from '../utils/deprecationLog'; 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', // TODO: add default skin size = 'tiny', alignItems = 'center', removePadding = false, borderRadius, disabled, className, onClick, ariaLabel, icon, children, subtitle, dataHook, tooltipProps, tooltipContent, showIcon = true, ...props }, ref) => { const icons = useIcons('AddItem', { Add, AddItemLarge, AddItemMedium, AddItemSmall, AddMedia, }); const skin = props.skin || theme; const buttonRef = React.useRef(null); useEffect(() => { if (theme) { deprecationLog('<AddItem/> - prop "theme" is deprecated and will be removed in next major release, please use "skin" property instead.'); } }, [theme]); useImperativeHandle(ref, () => ({ focus: () => { buttonRef.current?.focus(); }, blur: () => { buttonRef.current?.blur(); }, })); const iconElement = useMemo(() => { if (!showIcon) { return; } if (!icon) { const isImageIcon = skin === 'image'; if (isImageIcon) { return (React.createElement(icons.AddMedia, { "data-hook": dataHooks.defaultIcon, className: classes.icon, width: "31", height: "31" })); } if (size === 'tiny') { return (React.createElement(icons.Add, { "data-hook": dataHooks.defaultIcon, className: classes.icon, width: "24", height: "24" })); } if (size === 'small') { return React.createElement(icons.AddItemSmall, { "data-hook": dataHooks.defaultIcon }); } if (size === 'medium') { return React.createElement(icons.AddItemMedium, { "data-hook": dataHooks.defaultIcon }); } return React.createElement(icons.AddItemLarge, { "data-hook": dataHooks.defaultIcon }); } if (typeof icon === 'string') { return (React.createElement(Image, { className: classes.illustration, fit: "contain", src: icon, ...illustrationDimensions[size] })); } return icon; }, [icon, size, skin, showIcon, icons]); const textElement = useMemo(() => { if (!children || skin === '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, skin]); 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, skin, size, ariaLabel, borderRadius, removePadding, 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; const tooltipId = useId('additem-tooltip_'); return (React.createElement("div", { style: { width: '100%', height: '100%' }, "data-hook": dataHook }, tooltip && (React.createElement(Tooltip, { content: tooltip, className: classes.tooltip, flip: skin === 'image', moveBy: { y: skin === 'image' ? -12 : 0 }, dataHook: dataHooks.itemTooltip, placement: tooltipPlacementByAlignment[alignItems], "aria-describedby": tooltipId, ...tooltipProps }, ({ onFocus, onBlur }) => (React.createElement(AddItemButton, { ref: buttonRef, ariaDescribedBy: tooltipId, ...commonButtonProps, onFocus: onFocus, onBlur: onBlur })))), !tooltip && React.createElement(AddItemButton, { ref: buttonRef, ...commonButtonProps }))); }); const AddItemButton = forwardRef(({ className, onClick, disabled, size, ariaLabel, borderRadius, alignItems = 'center', removePadding, skin, icon, text, subtitle, ariaDescribedBy, onFocus, onBlur, }, ref) => { const { isFocusVisible, focusProps } = useFocusRing(); return (React.createElement("button", { ref: ref, "data-hook": dataHooks.addItem, className: st(classes.root, { skin, size, removePadding, borderRadius, disabled, alignItems, 'focus-visible': isFocusVisible, }, className), style: { borderRadius }, disabled: disabled, type: "button", onClick: onClick, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, ...focusProps, onFocus: e => { focusProps.onFocus?.(e); onFocus?.(e); }, onBlur: e => { focusProps.onBlur?.(e); onBlur?.(e); } }, React.createElement("div", { className: st(classes.contentContainer, { skin, size, alignItems, disabled, }) }, React.createElement("div", { className: st(classes.content, { size }) }, icon, text), subtitle))); }); AddItem.displayName = 'AddItem'; export default AddItem; //# sourceMappingURL=AddItem.js.map