UNPKG

phx-react

Version:

PHX REACT

103 lines 12.7 kB
"use strict"; 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