wix-style-react
Version:
wix-style-react
135 lines • 6.39 kB
JavaScript
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