@navinc/base-react-components
Version:
Nav's Pattern Library
249 lines (244 loc) • 11.4 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.InfoDrawer = exports.useInfoDrawer = exports.InfoDrawerProvider = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const styled_components_1 = __importStar(require("styled-components"));
const use_debounce_1 = require("use-debounce");
const header_js_1 = __importDefault(require("./header.js"));
const icon_js_1 = require("./icon.js");
const utils_1 = require("@navinc/utils");
const is_rebrand_js_1 = __importDefault(require("./is-rebrand.js"));
const moveOffScreen = (0, styled_components_1.keyframes) `
from { right: 0%; }
to { right: -100%; }
`;
const moveOnScreen = (0, styled_components_1.keyframes) `
from { right: -100%; }
to { right: 0%; }
`;
const suddenIn = (0, styled_components_1.keyframes) `
from { width: 100%; opacity: 0; }
to { width: 100%; opacity: 1; }
`;
const suddenOut = (0, styled_components_1.keyframes) `
0% { width: 100%; opacity: 1; }
99.9% { width: 100%; }
100% { width: 0%; opacity: 0; }
`;
const Backdrop = styled_components_1.default.div.withConfig({ displayName: "brc-sc-Backdrop", componentId: "brc-sc-1kxu7f1" }) `
align-items: flex-start;
animation: 0.2s ${({ theme }) => theme.materialTransitionTiming} both ${({ isOpen }) => isOpen ? suddenIn : suddenOut} ;
background-color: hsla(0, 0%, 0%, .2)};
box-sizing: border-box;
display: flex;
height: 100%;
justify-content: flex-end;
overflow: hidden;
pointer-events: ${({ isOpen }) => (isOpen ? 'initial' : 'none')};
position: fixed;
right: 0;
& * {
box-sizing: border-box;
}
`;
const drawerHeightVariations = (theme, type, mobileFullPage) => {
switch (type) {
case 'dynamic':
return `
border-bottom-left-radius: 4px;
border-top-left-radius: 4px;
height: ${mobileFullPage ? '100%' : 'auto'} ;
margin-top: ${mobileFullPage ? '0' : '100px'};
max-height: ${!mobileFullPage && 'calc(100vh - 100px)'};
min-height: 80px;
@media (${theme.forLargerThanPhone}) {
height: auto;
max-height: calc(100vh - 100px);
}
`;
case 'full':
return `
align-content: flex-start;
height: 100vh;
`;
default:
return null;
}
};
const contentHeightVariations = {
dynamic: 'max-height: calc(100vh - 160px);',
full: 'max-height: calc(100vh - 65px);',
};
const CloseButton = (0, styled_components_1.default)(icon_js_1.InteractiveIcon).attrs(() => ({ name: 'actions/close' })).withConfig({ displayName: "brc-sc-CloseButton", componentId: "brc-sc-krdogs" }) `
cursor: pointer;
`;
const Content = styled_components_1.default.div.withConfig({ displayName: "brc-sc-Content", componentId: "brc-sc-1soge9e" }) `
overflow: auto;
grid-column: 1 / -1;
font-family: ${({ theme }) => theme.fontPrimary}
${({ heightVariation }) => { var _a; return (_a = contentHeightVariations[heightVariation]) !== null && _a !== void 0 ? _a : contentHeightVariations.dynamic; }};
`;
const Drawer = styled_components_1.default.div.withConfig({ displayName: "brc-sc-Drawer", componentId: "brc-sc-50iogq" }) `
animation: 0.2s ${({ theme }) => theme.materialTransitionTiming} both
${({ isOpen }) => (isOpen ? moveOnScreen : moveOffScreen)};
background-color: ${({ variation = 'default', theme }) => {
var _a;
if ((0, is_rebrand_js_1.default)(theme))
return theme.navSecondary100;
const colorVariation = {
blue: theme.bubbleBlue100,
default: theme.white,
};
return (_a = colorVariation[variation]) !== null && _a !== void 0 ? _a : colorVariation.default;
}};
display: grid;
grid-template-columns: 1fr min-content;
grid-template-rows: ${({ mobileFullPage }) => mobileFullPage && 'auto 1fr'};
gap: 16px;
border-right: solid 1px ${({ theme }) => theme.border};
overflow: hidden;
padding: 16px;
// only use transition when not touching, otherwise dragging feels sluggish
transition: ${({ isTouching, theme }) => !isTouching && `transform 0.2s ${theme.materialTransitionTiming};`}
${({ theme, heightVariation, mobileFullPage }) => { var _a; return (_a = drawerHeightVariations(theme, heightVariation, mobileFullPage)) !== null && _a !== void 0 ? _a : drawerHeightVariations(theme, 'dynamic'); }}
width: 100%;
@media (${({ theme }) => theme.forLargerThanPhone}) {
position: ${({ orientBottom }) => orientBottom && `absolute`};
bottom: ${({ orientBottom }) => orientBottom && `0`};
width: ${({ orientBottom }) => (orientBottom ? `calc(100% - 260px)` : `485px`)};
padding: 24px 24px 32px;
max-width: calc(100vw - 55px);
}
`;
const InfoDrawerContext = (0, react_1.createContext)({
mobileFullPage: false,
orientBottom: false,
heightVariation: undefined,
setHeightVariation: utils_1.noop,
isOpen: false,
setIsOpen: utils_1.noop,
content: null,
title: null,
setInfoDrawer: utils_1.noop,
closeHandlersRef: { current: [] },
close: utils_1.noop,
});
const InfoDrawerProvider = ({ children }) => {
const [mobileFullPage, setMobileFullPage] = (0, react_1.useState)(false);
const [orientBottom, setOrientBottom] = (0, react_1.useState)(false);
const [content, setContent] = (0, react_1.useState)(null);
const [title, setTitle] = (0, react_1.useState)(null);
const [isOpen, setIsOpen] = (0, react_1.useState)(false);
const [heightVariation, setHeightVariation] = (0, react_1.useState)(undefined);
const closeHandlersRef = (0, react_1.useRef)([]);
const close = (0, react_1.useCallback)(() => {
setIsOpen(false);
closeHandlersRef.current.forEach((closeHandler) => closeHandler());
}, []);
const setInfoDrawer = (0, react_1.useCallback)((config = {}) => {
const cfg = Object.assign({
// in order to keep the value of orientBottom and mobileFullPage we need to check the config if the drawer is open to prevent flashing when orientBottom is true
mobileFullPage: config.isOpen ? false : mobileFullPage, orientBottom: config.isOpen ? false : orientBottom, title,
content,
isOpen }, config);
setMobileFullPage(cfg.mobileFullPage);
setOrientBottom(cfg.orientBottom);
if (isOpen && !config.isOpen) {
close();
}
else {
setIsOpen(cfg.isOpen);
}
setTitle(cfg.title);
setHeightVariation(cfg.heightVariation);
setContent(cfg.content);
}, [close, content, isOpen, title, orientBottom, mobileFullPage, heightVariation]);
return ((0, jsx_runtime_1.jsx)(InfoDrawerContext.Provider, Object.assign({ value: {
mobileFullPage,
orientBottom,
content,
isOpen,
setIsOpen,
title,
closeHandlersRef,
close,
setInfoDrawer,
setHeightVariation,
heightVariation: heightVariation,
} }, { children: children })));
};
exports.InfoDrawerProvider = InfoDrawerProvider;
const useInfoDrawer = ({ onClose } = {}) => {
const { mobileFullPage, orientBottom, content, title, setInfoDrawer, closeHandlersRef, isOpen, heightVariation } = (0, react_1.useContext)(InfoDrawerContext);
if (onClose && !closeHandlersRef.current.includes(onClose)) {
closeHandlersRef.current = closeHandlersRef.current.concat(onClose);
}
// When the component unmounts, we want to clean up our onClose handler.
(0, react_1.useEffect)(() => () => {
closeHandlersRef.current = closeHandlersRef.current.filter((closeHandler) => closeHandler !== onClose);
}, [closeHandlersRef, onClose]);
return {
mobileFullPage,
orientBottom,
content,
title,
isOpen,
setInfoDrawer,
heightVariation,
};
};
exports.useInfoDrawer = useInfoDrawer;
const InfoDrawer = ({ variation, heightVariation = 'dynamic', className, }) => {
const { mobileFullPage, orientBottom, content, title, isOpen, setInfoDrawer, heightVariation: heightVariationOverride, } = (0, exports.useInfoDrawer)();
const [moveStartX, setMoveStartX] = (0, react_1.useState)(0);
const [translateX, setTranslateX] = (0, react_1.useState)(0);
const onTouchMove = (0, use_debounce_1.useDebouncedCallback)((e) => {
onTouchMove.cancel();
e.persist();
setTranslateX(e.touches[0].clientX);
}, 2, { maxWait: 5 });
const configuredheightVariation = heightVariationOverride !== null && heightVariationOverride !== void 0 ? heightVariationOverride : heightVariation;
return ((0, jsx_runtime_1.jsx)(Backdrop, Object.assign({ isOpen: isOpen, className: className, "data-testid": "info-drawer:backdrop", onTouchStart: (e) => setMoveStartX(e.touches[0].clientX), onTouchMove: onTouchMove, onTouchEnd: () => {
onTouchMove.cancel();
translateX - moveStartX > 180 && setInfoDrawer({ isOpen: false });
setMoveStartX(0);
setTranslateX(0);
}, onClick: (e) => {
e.persist();
if ('dataset' in e.target && e.target.dataset.testid === 'info-drawer:backdrop') {
setInfoDrawer({ isOpen: false });
}
} }, { children: (0, jsx_runtime_1.jsxs)(Drawer, Object.assign({ mobileFullPage: mobileFullPage, orientBottom: orientBottom, style: {
transform: `translateX(${isOpen ? Math.max(translateX - moveStartX, 0) : 485}px)`,
}, isOpen: isOpen, isTouching: moveStartX !== 0, variation: variation, heightVariation: configuredheightVariation, "data-testid": "info-drawer:drawer" }, { children: [(0, jsx_runtime_1.jsx)(header_js_1.default, Object.assign({ size: "sm" }, { children: title })), (0, jsx_runtime_1.jsx)(CloseButton, { onClick: () => setInfoDrawer({ isOpen: false }), "data-testid": "info-drawer:close-button" }), (0, jsx_runtime_1.jsx)(Content, Object.assign({ heightVariation: configuredheightVariation }, { children: content }))] })) })));
};
exports.InfoDrawer = InfoDrawer;
exports.default = (0, styled_components_1.default)(exports.InfoDrawer).withConfig({ componentId: "brc-sc-ozwl0o" }) ``;
//# sourceMappingURL=info-drawer.js.map