@navinc/base-react-components
Version:
Nav's Pattern Library
272 lines (266 loc) • 10.5 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 = 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