@navinc/base-react-components
Version:
Nav's Pattern Library
483 lines (477 loc) • 20.9 kB
JavaScript
;
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