phx-react
Version:
PHX REACT
103 lines • 12.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PHXButton = void 0;
const tslib_1 = require("tslib");
const react_1 = tslib_1.__importStar(require("react"));
const SolidIcons = tslib_1.__importStar(require("@heroicons/react/24/solid"));
const OutlineIcons = tslib_1.__importStar(require("@heroicons/react/24/outline"));
const IconLoading_1 = require("../../commons/IconLoading");
const types_1 = require("../types");
const use_disable_interaction_1 = require("../../utils/use-disable-interaction");
const react_2 = require("@headlessui/react");
// ánh xạ typeIcon -> tên icon
const typeIconMap = {
calendar: 'CalendarDaysIcon',
// download: 'ArrowDownTrayIcon',
};
const PHXButton = ({ primary, secondary, danger, danger2, plain, tertiary, plainCritical, primaryCritical, split, options, soft, soft2, deleted, deletedButton = true, rounded, submit, size = 'medium', children, icon, iconClassName, iconOutline = false, iconPosition = 'before', disabled = false, loading = false, id, onClick, className, style, typeIcon, squareSize, noPadding, }) => {
let Icon;
if (icon) {
// nếu truyền thẳng tên icon
Icon = iconOutline ? OutlineIcons[icon] : SolidIcons[icon];
}
else if (typeIcon) {
// lấy tên icon theo typeIcon
const iconName = typeIconMap[typeIcon];
if (iconName) {
Icon = iconOutline ? OutlineIcons[iconName] : SolidIcons[iconName];
}
}
const commonProps = {
id,
onClick,
};
const interactiveProps = {
...commonProps,
};
const handleClick = (0, use_disable_interaction_1.useDisableClick)(disabled, onClick);
const isNew = !plain && !plainCritical;
const isTextOnly = plain || tertiary || plainCritical;
const binClassNames = (0, types_1.classNames)(primary &&
`primary bg-[#303030] font-normal text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 ${!disabled
? 'hover:bg-[#1A1A1A] !shadow-[inset_0_-1px_0_1px_rgba(0,0,0,0.8),inset_0_0_0_1px_rgba(48,48,48,1),inset_0_0.5px_0_1.5px_rgba(255,255,255,0.25)] hover:text-gray-200 active:!shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset] active:bg-[#1A1A1A]'
: ''}`, split &&
`bg-indigo-800 font-normal text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 ${!disabled
? 'hover:bg-indigo-900 hover:text-gray-200 active:text-gray-400 active:shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset] active:bg-indigo-900'
: ''}`, secondary &&
`bg-white font-normal text-gray-950 shadow-sm border border-gray-300 ${!disabled
? 'hover:border-gray-400 active:bg-gray-200 active:border-b-gray-300 active:shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset]'
: ''}`, primaryCritical &&
`bg-[#d80b0b] font-normal text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 ${!disabled
? 'hover:bg-[#a91212] hover:text-gray-200 active:shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset] active:bg-[#8d0606]'
: ''}`, plain && `shadow-none active:text-link-600 hover:text-link-600 hover:underline text-link-500`, tertiary && `shadow-none hover:bg-gray-100 active:bg-gray-200 `, plainCritical && 'shadow-none active:text-[#9e5b5b] hover:text-[#900d0d] hover:underline text-red-700', danger &&
`bg-[#C70A24] font-normal text-white danger ${!disabled
? 'hover:bg-red-700 active:bg-[#8E0B21] active:!shadow-[inset_0_1.5px_0_#080808,0_3px_6px_rgba(0,0,0,0.35)] !shadow-[inset_0_-1px_0_1px_rgba(142,11,33,0.8),inset_0_0_0_1px_rgba(163,10,36,0.8),inset_0_0.5px_0_1.5px_rgba(247,128,134,0.64)]'
: ''}`, danger2 &&
`font-normal text-red-700 shadow-sm ring-1 ring-inset ring-red-700 ${!disabled ? 'hover:bg-red-100 active:bg-red-200 active:shadow-[0rem_0.125rem_0rem_0rem_#e73737_inset]' : ''}`, deleted &&
`bg-indigo-50 font-normal text-red-700 shadow-sm ${!disabled ? 'hover:bg-indigo-100 active:shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset]' : ''}`, rounded && 'rounded-full', soft &&
`bg-indigo-50 font-normal text-gray-700 shadow-sm ${!disabled ? 'hover:bg-indigo-100 active:shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset]' : ''}`, soft2 &&
`bg-gray-100 font-normal text-gray-700 shadow-sm ${!disabled ? 'hover:bg-gray-200 active:shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset]' : ''}`, size === 'micro' && isNew && `px-2 py-1 text-xs ${!disabled ? 'active:pt-[0.3rem] active:pb-[0.2rem]' : ''}`, size === 'small' &&
isNew &&
`px-2.5 ${!secondary ? 'py-[5px]' : 'py-[4px]'} text-xxs ${!disabled
? `${!secondary ? 'active:pt-[0.37rem] active:pb-[0.27rem]' : 'active:pt-[0.3rem] active:pb-[0.2rem]'}`
: ''}`, size === 'medium' && isNew && `px-2.5 py-1.5 text-sm ${!disabled ? 'active:pt-[0.45rem] active:pb-[0.3rem]' : ''}`, size === 'large' && isNew && `px-3 py-2 text-sm ${!disabled ? 'active:pt-[0.55rem] active:pb-[0.45rem]' : ''}`, size === 'extra-large' &&
isNew &&
`px-3.5 py-2.5 text-sm ${!disabled ? 'active:pt-[0.7rem] active:pb-[0.55rem]' : ''}`, size === 'micro' && `px-2 py-1 text-xxs`, size === 'small' && `px-3 text-xxs`, size === 'extra-micro' && `px-1.5 py-1 text-xxs`, size === 'medium' && `px-3 py-1.5 text-sm`, size === 'large' && `px-3 py-2 text-sm `, size === 'extra-large' && `px-3.5 py-2.5 text-sm`, (icon || typeIcon) && (size === 'medium' || size === 'large') && 'items-center', (icon || typeIcon) && size === 'extra-large' && 'items-center', loading && 'opacity-30', 'relative', disabled && 'opacity-30 cursor-default', squareSize && 'flex items-center justify-center !p-0 aspect-square shrink-0', squareSize && `w-${squareSize} h-${squareSize}`, noPadding && '!p-0', className);
const iconClass = (0, types_1.classNames)((icon || typeIcon) && iconPosition === 'before' && size !== 'extra-micro' && 'h-5 w-5', (icon || typeIcon) && iconPosition === 'after' && size !== 'extra-micro' && 'h-5 w-5', (icon || typeIcon) && iconPosition === 'before' && size === 'extra-micro' && 'h-4 w-4', (icon || typeIcon) && iconPosition === 'after' && size === 'extra-micro' && 'h-4 w-4', iconClassName);
// Icon markup
const iconMarkup = Icon && react_1.default.createElement(Icon, { className: iconClass });
// Loading markup
const loadingMarkup = loading ? (react_1.default.createElement("span", { className: 'w-3 absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2' },
react_1.default.createElement(IconLoading_1.IconLoading, { color: primary ? 'text-white' : danger ? 'text-red-50' : 'bg-transparent' }))) : (react_1.default.createElement(react_1.default.Fragment, null));
const buttonMarkup = (react_1.default.createElement(react_1.default.Fragment, null,
react_1.default.createElement("button", { style: style, ...interactiveProps, type: submit ? 'submit' : 'button', onClick: handleClick, className: (0, types_1.classNames)(`hover:before:opacity-100 ${binClassNames}`, `${isTextOnly
? ''
: `group relative isolate flex items-center justify-center overflow-hidden rounded-md transition duration-300 ease-[cubic-bezier(0.4,0.36,0,1)] shadow-[inset_0_1px_theme(colors.white/0.07),0_0.12px_0_theme(colors.gray.900/${deleted || soft ? 0.1 : 0.5})]
`}`, '!rounded-[8px]'), disabled: loading ? true : disabled },
react_1.default.createElement("div", { className: `${(icon || typeIcon) && children ? 'flex space-x-1 justify-between items-center' : ''}` },
loadingMarkup,
iconPosition === 'before' ? iconMarkup : react_1.default.createElement(react_1.default.Fragment, null),
react_1.default.createElement("span", { className: (0, types_1.classNames)(loading ? 'invisible' : '', deleted ? 'flex items-center' : '') },
deleted && (react_1.default.createElement(react_1.default.Fragment, null, deletedButton ? (react_1.default.createElement("svg", { xmlns: 'http://www.w3.org/2000/svg', fill: 'none', viewBox: '0 0 24 24', strokeWidth: '2.5', stroke: 'currentColor', className: 'w-3.5 h-3.5 mr-1' },
react_1.default.createElement("path", { strokeLinecap: 'round', strokeLinejoin: 'round', d: 'M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0' }))) : (react_1.default.createElement(react_1.default.Fragment, null)))),
react_1.default.createElement("span", { className: '[--button-height:calc((theme(spacing.3)+theme(fontSize.base[1].lineHeight))*-1)] flex w-full items-center justify-center gap-1 whitespace-nowrap text-[--button-color-text] drop-shadow-[--button-text-shadow] transition' }, children)),
iconPosition === 'after' ? iconMarkup : react_1.default.createElement(react_1.default.Fragment, null)))));
const styleBtnSplit = (0, types_1.classNames)(size === 'small' && 'px-2.5 py-1.5 text-xs', size === 'micro' && 'px-2 py-1 text-xs', size === 'medium' && 'px-2.5 py-1.5 text-sm', size === 'extra-large' && 'px-3.5 py-2.5 text-sm', size === 'large' && 'px-3 py-2 text-sm', 'flex items-center border font-normal shadow-sm ', primary &&
'hover:bg-indigo-800 text-white border-gray-800 hover:text-gray-200 active:text-gray-400 bg-indigo-700 active:shadow-[0rem_0.125rem_0.1rem_0rem_#a3a3a344_inset]', !primary && 'bg-white hover:bg-slate-50 text-gray-900 active:shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset]');
const sizeIcon = (0, types_1.classNames)(size === 'small' && 'px-2.5 py-[7px]', size === 'micro' && 'px-2 py-1.5', size === 'medium' && 'px-2.5 py-2', size === 'extra-large' && 'px-3.5 py-3', size === 'large' && 'px-3 py-2.5');
const buttonSplit = (react_1.default.createElement(react_1.default.Fragment, null,
react_1.default.createElement("div", { className: `flex ${className}` },
react_1.default.createElement("button", { ...interactiveProps, type: submit ? 'submit' : 'button', onClick: handleClick, className: `${styleBtnSplit} rounded-l-[4px]` }, children),
react_1.default.createElement(react_2.Menu, { as: 'div' },
react_1.default.createElement(react_2.Menu.Button, null,
react_1.default.createElement("button", { className: `${styleBtnSplit} ${sizeIcon} rounded-r-[4px] border-l-0` },
react_1.default.createElement("svg", { xmlns: 'http://www.w3.org/2000/svg', fill: 'none', viewBox: '0 0 24 24', strokeWidth: '1.5', stroke: 'currentColor', className: 'w-4 h-4' },
react_1.default.createElement("path", { strokeLinecap: 'round', strokeLinejoin: 'round', d: 'm19.5 8.25-7.5 7.5-7.5-7.5' })))),
react_1.default.createElement(react_2.Transition, { as: react_1.Fragment, enter: 'transition ease-out duration-100', enterFrom: 'transform opacity-0 scale-95', enterTo: 'transform opacity-100 scale-100', leave: 'transition ease-in duration-75', leaveFrom: 'transform opacity-100 scale-100', leaveTo: 'transform opacity-0 scale-95' },
react_1.default.createElement(react_2.Menu.Items, { className: (0, types_1.classNames)('whitespace-nowrap border px-1 absolute z-10 max-h-96 overflow-y-auto mt-1.5 min-w-[5.2rem] rounded-lg bg-white focus:outline-none shadow-[0rem_0.25rem_0.375rem_-0.125rem_rgba(26,26,26,.2)]') },
react_1.default.createElement(react_1.default.Fragment, null,
react_1.default.createElement("div", { className: 'py-1' }, options === null || options === void 0 ? void 0 : options.map((item) => (react_1.default.createElement(react_2.Menu.Item, { key: item.content }, ({ active }) => (react_1.default.createElement("div", { className: (0, types_1.classNames)(active ? 'bg-gray-100 text-gray-900 rounded-lg cursor-pointer' : 'text-gray-700', 'block px-2 py-1.5 text-xs'), onClick: item.onClick }, item.name)))))))))))));
return react_1.default.createElement(react_1.default.Fragment, null, split ? buttonSplit : buttonMarkup);
};
exports.PHXButton = PHXButton;
//# sourceMappingURL=Button.js.map