UNPKG

@navinc/base-react-components

Version:
272 lines (266 loc) 10.5 kB
"use strict"; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Button = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); const styled_components_1 = __importDefault(require("styled-components")); const prop_types_1 = __importDefault(require("prop-types")); const link_js_1 = __importDefault(require("./link.js")); const loading_dots_js_1 = __importDefault(require("./loading-dots.js")); const sizeVariants = { small: { padding: '0.5em 1.33em', fontSize: '12px', borderRadius: '12px', }, medium: { padding: '0.64em 1.71em', fontSize: '14px', borderRadius: '12px', }, large: { padding: '0.75em 2em', fontSize: '16px', borderRadius: '12px', }, extraLarge: { padding: '0.9em 1.6em', fontSize: '20px', borderRadius: '16px', }, cardButton: { padding: '8px', fontSize: '16px', borderRadius: '12px', }, }; const getSize = ({ size = 'medium' }) => { var _a; return (_a = sizeVariants[size]) !== null && _a !== void 0 ? _a : sizeVariants.medium; }; const styleVariation = { main: { borderColor: 'transparent', backgroundColor: ({ theme }) => theme.azure, /* Imposes a background radial gradient too small to detect, that upon activation will expand 100% of the container like a ripple from the click */ background: ({ theme }) => `${theme.bubbleBlue400} radial-gradient(circle, transparent 1%, ${theme.bubbleBlue300} 1%) center/15000%`, /* Despite remaining the same, the font color must be defined for both hover/focus so as to override nested link styling */ color: ({ theme }) => theme.white, hover: { backgroundColor: ({ theme }) => theme.bubbleBlue400, color: ({ theme }) => theme.white, }, focus: { backgroundColor: ({ theme }) => theme.bubbleBlue400, color: ({ theme }) => theme.white, }, active: { /* Tied to the background property, these will create the click impression effect */ backgroundSize: '100%', transition: 'background 0s', }, }, outline: { borderColor: ({ theme }) => theme.azure, backgroundColor: ({ theme }) => theme.transparentWhite, /* Imposes a background radial gradient too small to detect, that upon activation will expand 100% of the container like a ripple from the click */ background: ({ theme }) => `${theme.bubbleBlue100} radial-gradient(circle, transparent 1%, ${theme.bubbleBlue200} 1%) center/15000%`, color: ({ theme }) => theme.azure, hover: { backgroundColor: ({ theme }) => theme.bubbleBlue100, }, focus: { backgroundColor: ({ theme }) => theme.bubbleBlue100, }, active: { backgroundColor: ({ theme }) => theme.bubbleBlue200, /* Tied to the background property, these will create the click impression effect */ backgroundSize: '100%', transition: 'background 0s', }, }, buttonLink: { borderColor: 'transparent', backgroundColor: ({ theme }) => theme.transparentWhite, color: ({ theme }) => theme.azure, padding: 0, hover: { borderColor: 'transparent', color: ({ theme }) => theme.oceanBoat, }, focus: { borderColor: 'transparent', color: ({ theme }) => theme.oceanBoat, }, active: { borderColor: 'transparent', color: ({ theme }) => theme.oceanBoat, }, }, noOutline: { borderColor: 'transparent', backgroundColor: ({ theme }) => theme.transparentWhite, color: ({ theme }) => theme.bubbleBlue500, hover: { borderColor: ({ theme }) => theme.bubbleBlue400, }, focus: { borderColor: ({ theme }) => theme.bubbleBlue400, }, active: { backgroundColor: ({ theme }) => theme.bubbleBlue200, borderColor: 'transparent', }, }, whiteOutline: { borderColor: ({ theme }) => theme.white, backgroundColor: ({ theme }) => theme.transparentWhite, color: ({ theme }) => theme.white, hover: { backgroundColor: ({ theme }) => theme.bubbleBlue100, color: ({ theme }) => theme.azure, }, focus: { backgroundColor: ({ theme }) => theme.bubbleBlue100, color: ({ theme }) => theme.azure, }, active: { backgroundColor: ({ theme }) => theme.bubbleBlue200, color: ({ theme }) => theme.azure, borderColor: 'transparent', }, }, }; const getVariation = ({ variation = 'main' }) => { var _a; return (_a = styleVariation[variation]) !== null && _a !== void 0 ? _a : styleVariation.main; }; const getRule = (rulePath) => ({ size, variation, theme, }) => { const rules = Object.assign(Object.assign({}, getSize({ size })), getVariation({ variation })); const rule = rulePath.split('.').reduce((rules, pathPart) => { var _a; return (_a = rules[pathPart]) !== null && _a !== void 0 ? _a : ''; }, rules); return typeof rule === 'function' ? rule({ theme }) : rule; }; const getDisabledStyleByVariation = ({ variation, theme }) => { switch (variation) { case 'noOutline': return ''; case 'outline': return `border-color: ${theme.neutral300};`; default: return `background-color: ${theme.neutral200};`; } }; const StyledButton = (0, styled_components_1.default)('button') ` display: inline-flex; align-items: center; box-sizing: border-box; font-family: postgrotesk, Roboto, Helvetica, sans-serif; padding: ${getRule('padding')}; border: 1px solid ${getRule('borderColor')}; border-radius: ${getRule('borderRadius')}; background: ${getRule('background')}; background-color: ${getRule('backgroundColor')}; color: ${getRule('color')}; font-size: ${getRule('fontSize')}; line-height: 1; text-align: center; white-space: ${({ wrap }) => (wrap ? 'normal' : 'nowrap')}; cursor: pointer; outline: none; font-weight: 700; transition: ease-out background 0.4s; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; &:hover:not([disabled]) { background-color: ${getRule('hover.backgroundColor')}; color: ${getRule('hover.color')}; border-color: ${getRule('hover.borderColor')}; } /* Override hover styles, b/c when pressed the hover event is also active */ &:hover:active { background-color: ${getRule('active.backgroundColor')}; color: ${getRule('active.color')}; border-color: ${getRule('active.borderColor')}; } &:focus { background-color: ${getRule('focus.backgroundColor')}; color: ${getRule('focus.color')}; border-color: ${getRule('focus.borderColor')}; } &[disabled] { ${({ isLoading, variation = 'main', theme }) => isLoading ? '' : ` ${getDisabledStyleByVariation({ variation, theme })} color: ${theme.neutral400}; cursor: not-allowed; `} } &:active { background-color: ${getRule('active.backgroundColor')}; background-size: ${getRule('active.backgroundSize')}; transition: ${getRule('active.transition')}; } & ${loading_dots_js_1.default} { color: ${({ variation = 'main', theme }) => (variation === 'main' ? theme.white : theme.azure)}; } `; const ButtonBase = (_a) => { var { children, isLoading, onClick = () => { } } = _a, _b = _a.trackingContext, _c = _b === void 0 ? {} : _b, { type, category, options } = _c, payload = __rest(_c, ["type", "category", "options"]), props = __rest(_a, ["children", "isLoading", "onClick", "trackingContext"]); return ((0, jsx_runtime_1.jsx)(StyledButton, Object.assign({ disabled: isLoading, onClick: (event) => { event.persist(); onClick(event); } }, props, { children: isLoading ? (0, jsx_runtime_1.jsx)(loading_dots_js_1.default, { "data-testid": "button-loading-dots" }, void 0) : children }), void 0)); }; ButtonBase.propTypes = { trackingContext: prop_types_1.default.shape({ type: prop_types_1.default.string, context: prop_types_1.default.string, category: prop_types_1.default.string, payload: prop_types_1.default.shape({ category: prop_types_1.default.string, label: prop_types_1.default.string, name: prop_types_1.default.string, }), options: prop_types_1.default.shape({ integrations: prop_types_1.default.shape({ Salesforce: prop_types_1.default.bool, }), }), }), }; ButtonBase.displayName = 'ButtonBase'; const ButtonLink = (0, styled_components_1.default)(StyledButton).attrs(() => ({ as: link_js_1.default })) ` text-decoration: none; `; ButtonLink.displayName = 'ButtonLink'; const ButtonAnchor = (0, styled_components_1.default)(StyledButton).attrs(() => ({ as: 'a' })) ` text-decoration: none; `; ButtonAnchor.displayName = 'ButtonAnchor'; const Button = (_a) => { var { isLoading } = _a, props = __rest(_a, ["isLoading"]); return props.href ? (props.asAnchor ? ((0, jsx_runtime_1.jsx)(ButtonAnchor, Object.assign({}, props), void 0)) : ((0, jsx_runtime_1.jsx)(ButtonLink, Object.assign({}, props), void 0))) : ((0, jsx_runtime_1.jsx)(ButtonBase, Object.assign({ isLoading: isLoading }, props), void 0)); }; exports.Button = Button; exports.Button.displayName = 'Button'; const StyledButtonExp = (0, styled_components_1.default)(exports.Button) ``; exports.default = StyledButtonExp; //# sourceMappingURL=button.js.map