UNPKG

@navinc/base-react-components

Version:
483 lines (477 loc) 20.9 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 = exports.StyledButton = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); const styled_components_1 = __importDefault(require("styled-components")); const button_link_icon_js_1 = require("./button-link-icon.js"); const is_rebrand_js_1 = __importDefault(require("./is-rebrand.js")); const link_js_1 = __importDefault(require("./link.js")); const loading_dots_js_1 = __importDefault(require("./loading-dots.js")); const sizeVariants = { 'nav-blue': { small: { padding: '0.5em 1.33em', fontSize: '12px', borderRadius: '12px', lineHeight: '1', }, medium: { padding: '0.64em 1.71em', fontSize: '14px', borderRadius: '12px', lineHeight: '1', }, mediumFull: { padding: '0.64em 1.71em', fontSize: '14px', borderRadius: '12px', lineHeight: '1', }, large: { padding: '0.75em 2em', fontSize: '16px', borderRadius: '12px', lineHeight: '1', }, largeFull: { padding: '0.75em 2em', fontSize: '16px', borderRadius: '12px', lineHeight: '1', }, extraLarge: { padding: '0.9em 1.6em', fontSize: '20px', borderRadius: '16px', lineHeight: '1', }, cardButton: { padding: '8px', fontSize: '16px', borderRadius: '12px', lineHeight: '1', }, }, 'nav-purple': { small: { padding: '0.5em 1.33em', fontSize: '12px', borderRadius: '8px', lineHeight: '1', }, medium: { padding: '6px 16px 6px 16px', fontSize: '14px', borderRadius: '8px', lineHeight: '1', }, mediumFull: { padding: '12px 24px', fontSize: '16px', borderRadius: '8px', lineHeight: '1.5', width: '100%', }, large: { padding: '8px 24px 8px 24px', fontSize: '16px', borderRadius: '8px', lineHeight: '1', }, largeFull: { padding: '20px 24px', fontSize: '16px', borderRadius: '8px', lineHeight: '1.5', width: '100%', }, extraLarge: { padding: '16px 32px 16px 32px', fontSize: '20px', borderRadius: '8px', lineHeight: '1', }, cardButton: { padding: '8px', fontSize: '16px', borderRadius: '12px', lineHeight: '1', }, }, }; const getSize = ({ size = 'medium', themeName = 'nav-blue' }) => { var _a; return (_a = sizeVariants[themeName][size]) !== null && _a !== void 0 ? _a : sizeVariants[themeName].medium; }; const getVariation = ({ variation = 'main', theme, size = 'medium', iconPosition }) => { var _a, _b, _c; const lineHeightMap = { small: '18px', medium: '20px', mediumFull: '20px', large: '24px', largeFull: '24px', extraLarge: '28px', }; const buttonLink = { borderColor: 'transparent', backgroundColor: theme.transparentWhite, color: theme.navPrimary400, padding: 0, lineHeight: (_a = lineHeightMap[size]) !== null && _a !== void 0 ? _a : lineHeightMap.medium, hover: { color: (0, is_rebrand_js_1.default)(theme) ? theme.navPrimary500 : theme.oceanBoat, }, focus: Object.assign({}, ((0, is_rebrand_js_1.default)(theme) ? { outline: 'none', boxShadow: `0 0 0 4px ${theme.navStatusPositive500}`, borderRadius: '2px', } : { borderColor: 'transparent', color: theme.oceanBoat, })), active: { color: (0, is_rebrand_js_1.default)(theme) ? theme.navPrimary500 : theme.oceanBoat, }, }; const styleVariation = { main: { borderColor: 'transparent', backgroundColor: theme.navPrimary, /* 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.navPrimary200} radial-gradient(circle, transparent 1%, ${theme.navPrimary700} 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.navNeutralLight, hover: { backgroundColor: (0, is_rebrand_js_1.default)(theme) ? theme.navPrimary500 : theme.navStatusPositive500, color: theme.navNeutralLight, }, focus: Object.assign({ backgroundColor: (0, is_rebrand_js_1.default)(theme) ? theme.navPrimary : theme.navStatusPositive500 }, ((0, is_rebrand_js_1.default)(theme) ? { outline: 'none', boxShadow: (0, is_rebrand_js_1.default)(theme) ? `0 0 0 4px ${theme.navStatusPositive500}` : `0 0 0 1px ${theme.azure}`, } : {})), active: Object.assign(Object.assign({}, ((0, is_rebrand_js_1.default)(theme) ? { backgroundColor: theme.navPrimary700 } : {})), { backgroundSize: '100%', transition: 'background 0s' }), }, outline: { borderColor: theme.navPrimary, backgroundColor: 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.navPrimary200} radial-gradient(circle, transparent 1%, ${theme.navPrimary300} 1%) center/15000%`, color: theme.navPrimary, hover: { backgroundColor: theme.navPrimary200, }, focus: { backgroundColor: (0, is_rebrand_js_1.default)(theme) ? theme.transparentWhite : theme.bubbleBlue100, outline: 'none', boxShadow: (0, is_rebrand_js_1.default)(theme) ? `0 0 0 4px ${theme.navStatusPositive500}` : `0 0 0 1px ${theme.azure}`, }, active: { backgroundColor: theme.navPrimary300, /* Tied to the background property, these will create the click impression effect */ backgroundSize: '100%', transition: 'background 0s', }, }, shade: { borderColor: 'transparent', backgroundColor: theme.navPrimary200, /* 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.navPrimary200} radial-gradient(circle, transparent 1%, ${theme.navPrimary300} 1%) center/15000%`, color: theme.navPrimary, hover: { backgroundColor: theme.navPrimary100, }, focus: { outline: 'none', boxShadow: (0, is_rebrand_js_1.default)(theme) ? `0 0 0 4px ${theme.navStatusPositive500}` : `0 0 0 1px ${theme.azure}`, }, active: { backgroundColor: theme.navPrimary300, /* Tied to the background property, these will create the click impression effect */ backgroundSize: '100%', transition: 'background 0s', }, }, white: { borderColor: 'transparent', backgroundColor: theme.navNeutralLight, /* 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.navPrimary200} radial-gradient(circle, transparent 1%, ${theme.navPrimary300} 1%) center/15000%`, color: theme.navPrimary, hover: { backgroundColor: theme.navPrimary200, }, focus: { outline: 'none', boxShadow: (0, is_rebrand_js_1.default)(theme) ? `0 0 0 4px ${theme.navStatusPositive500}` : `0 0 0 1px ${theme.azure}`, }, active: { backgroundColor: theme.navPrimary300, /* Tied to the background property, these will create the click impression effect */ backgroundSize: '100%', transition: 'background 0s', }, }, tan: { borderColor: 'transparent', backgroundColor: theme.navSecondary, /* 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.navSecondary} radial-gradient(circle, transparent 1%, ${theme.navSecondary300} 1%) center/15000%`, color: theme.navPrimary400, hover: { backgroundColor: theme.navSecondary100, color: theme.navPrimary500, }, focus: { outline: 'none', boxShadow: (0, is_rebrand_js_1.default)(theme) ? `0 0 0 4px ${theme.navStatusPositive500}` : `0 0 0 1px ${theme.azure}`, }, active: { backgroundColor: theme.navSecondary300, color: theme.navPrimary500, /* Tied to the background property, these will create the click impression effect */ backgroundSize: '100%', transition: 'background 0s', }, }, destructive: { borderColor: 'transparent', backgroundColor: theme.navStatusNegative, /* 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.navStatusNegative} radial-gradient(circle, transparent 1%, ${theme.navStatusNegative700} 1%) center/15000%`, color: theme.navNeutralLight, hover: { backgroundColor: theme.navStatusNegative500, }, focus: { outline: 'none', boxShadow: (0, is_rebrand_js_1.default)(theme) ? `0 0 0 4px ${theme.navStatusPositive500}` : `0 0 0 1px ${theme.azure}`, }, active: { backgroundColor: theme.navStatusNegative700, /* Tied to the background property, these will create the click impression effect */ backgroundSize: '100%', transition: 'background 0s', }, }, accent: { borderColor: 'transparent', backgroundColor: theme.navStatusPositive, /* 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.navStatusPositive} radial-gradient(circle, transparent 1%, ${theme.navStatusPositive700} 1%) center/15000%`, color: theme.navNeutralLight, hover: { backgroundColor: theme.navStatusPositive500, }, focus: { outline: 'none', boxShadow: (0, is_rebrand_js_1.default)(theme) ? `0 0 0 4px ${theme.navStatusPositive500}` : `0 0 0 1px ${theme.azure}`, }, active: { backgroundColor: theme.navStatusPositive700, /* Tied to the background property, these will create the click impression effect */ backgroundSize: '100%', transition: 'background 0s', }, }, buttonLink, buttonLinkIcon: Object.assign(Object.assign({}, buttonLink), { padding: !iconPosition ? 0 : iconPosition === 'left' ? '0 2px 0 0' : '0 0 0 2px' }), buttonAction: { borderColor: 'transparent', backgroundColor: theme.transparentWhite, color: theme.navNeutral400, padding: 0, lineHeight: (_b = lineHeightMap[size]) !== null && _b !== void 0 ? _b : lineHeightMap.medium, }, noOutline: { borderColor: 'transparent', backgroundColor: theme.transparentWhite, color: theme.navPrimary400, hover: Object.assign({}, ((0, is_rebrand_js_1.default)(theme) ? { color: theme.navPrimary500 } : { borderColor: theme.navStatusPositive500 })), focus: Object.assign({ borderColor: theme.navStatusPositive500 }, ((0, is_rebrand_js_1.default)(theme) ? { outline: 'none', boxShadow: `0 0 0 4px ${theme.navStatusPositive500}` } : {})), active: Object.assign({}, ((0, is_rebrand_js_1.default)(theme) ? { color: theme.navPrimary500 } : { backgroundColor: theme.navPrimary300, borderColor: 'transparent' })), }, whiteOutline: { borderColor: theme.white, backgroundColor: theme.transparentWhite, color: theme.white, hover: { backgroundColor: theme.navPrimary200, color: theme.navPrimary, }, focus: { backgroundColor: theme.navPrimary200, color: theme.navPrimary, }, active: { backgroundColor: theme.navPrimary300, color: theme.navPrimary, borderColor: 'transparent', }, }, neutral: { borderColor: 'transparent', backgroundColor: theme.navNeutral100, background: `${theme.navPrimary200} radial-gradient(circle, transparent 1%, ${theme.navPrimary200} 1%) center/15000%`, color: theme.navPrimary400, hover: { backgroundColor: theme.navPrimary200, }, focus: { outline: 'none', boxShadow: `0 0 0 4px ${(0, is_rebrand_js_1.default)(theme) ? theme.navStatusPositive500 : theme.navPrimary700}`, }, active: { backgroundColor: theme.navPrimary300, backgroundSize: '100%', transition: 'background 0s', borderColor: 'transparent', }, }, }; return (_c = styleVariation[variation]) !== null && _c !== void 0 ? _c : styleVariation.main; }; const getRule = (rulePath) => ({ size, variation, theme, iconPosition }) => { const rules = Object.assign(Object.assign({}, getSize({ size, themeName: theme.name })), getVariation({ variation, theme, size, iconPosition })); 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 'buttonLink': case 'noOutline': return ''; case 'outline': return (0, is_rebrand_js_1.default)(theme) ? '' : `border-color: ${theme.neutral300};`; default: return `background-color: ${theme.neutral200};`; } }; exports.StyledButton = styled_components_1.default.button.withConfig({ displayName: "brc-sc-StyledButton", componentId: "brc-sc-bkuhcf" }) ` display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; font-family: ${({ theme }) => theme.fontPrimary}; width: ${getRule('width')}; 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: ${getRule('lineHeight')}; 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')}; outline: ${getRule('focus.outline')}; box-shadow: ${getRule('focus.boxShadow')}; border-radius: ${getRule('focus.borderRadius')}; } &:focus:active { outline: none; box-shadow: none; } &[disabled] { ${({ $isLoading, variation = 'main', theme, size }) => $isLoading ? '' : ` ${getDisabledStyleByVariation({ variation, theme })} ${(0, is_rebrand_js_1.default)(theme) ? `opacity: 38%;` : `color: ${theme.neutral400};`} ${(0, is_rebrand_js_1.default)(theme) ? `background: ${getRule('backgroundColor')({ size, variation, theme })} !important;` : ''} cursor: not-allowed; `} } &:active { background-color: ${getRule('active.backgroundColor')}; background-size: ${getRule('active.backgroundSize')}; transition: ${getRule('active.transition')}; } `; const ButtonBase = (_a) => { var { children, $isLoading, onClick = () => { }, iconFilename = 'tech/filter', iconPosition, variation } = _a, props = __rest(_a, ["children", "$isLoading", "onClick", "iconFilename", "iconPosition", "variation"]); let dotColor = 'purple'; switch (variation) { case 'main': case 'destructive': case 'accent': case undefined: dotColor = 'white'; break; default: break; } return ((0, jsx_runtime_1.jsx)(exports.StyledButton, Object.assign({ disabled: $isLoading, onClick: (event) => { event.persist(); onClick(event); } }, Object.assign(Object.assign({}, props), { variation, iconPosition }), { children: $isLoading ? ((0, jsx_runtime_1.jsx)(loading_dots_js_1.default, { dotColor: dotColor, "data-testid": "button-loading-dots" })) : ((0, jsx_runtime_1.jsx)(button_link_icon_js_1.ButtonLinkIcon, Object.assign({}, { name: iconFilename, iconPosition, variation }, { children: children }))) }))); }; ButtonBase.displayName = 'ButtonBase'; const ButtonLink = (0, styled_components_1.default)(exports.StyledButton).attrs(() => ({ as: link_js_1.default })) ` text-decoration: none; `; ButtonLink.displayName = 'ButtonLink'; const ButtonAnchor = (0, styled_components_1.default)(exports.StyledButton).attrs(() => ({ as: 'a' })).withConfig({ displayName: "brc-sc-ButtonAnchor", componentId: "brc-sc-1uee4oc" }) ` text-decoration: none; `; ButtonAnchor.displayName = 'ButtonAnchor'; const Button = (_a) => { var { href, asAnchor, isLoading } = _a, props = __rest(_a, ["href", "asAnchor", "isLoading"]); if (!href) { return (0, jsx_runtime_1.jsx)(ButtonBase, Object.assign({ "$isLoading": isLoading }, props)); } if (asAnchor) { return (0, jsx_runtime_1.jsx)(ButtonAnchor, Object.assign({ "$isLoading": isLoading, href: href }, props)); } return (0, jsx_runtime_1.jsx)(ButtonLink, Object.assign({ "$isLoading": isLoading, href: href }, props)); }; exports.Button = Button; exports.Button.displayName = 'Button'; const StyledButtonExp = (0, styled_components_1.default)(exports.Button).withConfig({ displayName: "brc-sc-StyledButtonExp", componentId: "brc-sc-1jq7psv" }) ``; exports.default = StyledButtonExp; //# sourceMappingURL=button.js.map