vcc-ui
Version:
VCC UI is a collection of React UI Components that can be used for developing front-end applications at Volvo Car Corporation.
293 lines (268 loc) • 10 kB
JavaScript
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import React, { createContext, useState, useRef } from 'react';
import { useFela } from 'react-fela';
import PropTypes from 'prop-types';
import { Block } from '../block';
import { Click } from '../click';
import { Arrow } from '../arrow';
import { Inline } from '../inline';
import { Flex } from '../flex';
import { getThemeStyle } from '../../get-theme-style';
import { deprecate } from '../../deprecate';
export var TabNavContext = createContext({});
var styles = {
nav: function nav(_ref) {
var theme = _ref.theme,
reverseOut = _ref.reverseOut;
return {
flexDirection: 'row',
overflow: 'hidden',
borderBottomStyle: 'solid',
borderBottomWidth: 1,
borderBottomColor: reverseOut ? theme.color.primitive.grey200 : theme.color.ornament.divider,
backgroundColor: reverseOut ? theme.color.primitive.grey200 : theme.color.background.secondary
};
},
scrollContainer: {
flex: '0 1 auto',
overflowY: 'hidden',
overflowX: 'auto',
msOverflowY: 'hidden',
msOverflowX: 'auto',
msOverflowStyle: 'none',
'::-webkit-scrollbar': {
display: 'none'
}
},
itemContainer: {
flexDirection: 'row',
padding: '0 0 0 19px'
},
stickyLeft: function stickyLeft(_ref2) {
var isCentered = _ref2.isCentered;
return {
flexShrink: 0,
flexBasis: 0,
flexGrow: isCentered ? 1 : 0,
msFlex: '1 0 auto',
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'center'
};
},
stickyRight: {
flexShrink: 0,
flexBasis: 0,
flexGrow: 1,
msFlex: '1 0 auto',
alignItems: 'center',
justifyContent: 'flex-end',
flexDirection: 'row'
},
border: function border(_ref3) {
var reverseOut = _ref3.reverseOut,
animatedMargin = _ref3.animatedMargin,
duration = _ref3.duration,
theme = _ref3.theme;
return {
width: 0,
height: duration === 0 ? 0 : 3,
marginRight: '0 !important',
backgroundColor: reverseOut ? theme.color.primitive.white : theme.color.ornament.highlight,
transitionProperty: "margin-".concat(animatedMargin, ", width"),
transitionTimingFunction: 'ease-out',
transitionDuration: duration + 'ms'
};
},
backButton: function backButton(_ref4) {
var _ref5;
var reverseOut = _ref4.reverseOut,
_ref4$showBackButtonO = _ref4.showBackButtonOn,
showBackButtonOn = _ref4$showBackButtonO === void 0 ? [] : _ref4$showBackButtonO,
theme = _ref4.theme;
return _ref5 = {
fontSize: 15,
padding: '16px 10px 19px',
verticalAlign: 'middle',
fontWeight: 200,
whiteSpace: 'nowrap',
flexShrink: '0',
color: reverseOut ? theme.color.primitive.white : theme.color.foreground.primary,
display: showBackButtonOn.some(function (size) {
return size === 's';
}) ? 'inline' : 'none',
'> svg': {
marginRight: 8
},
':hover > svg': {
transform: 'translateX(-5px)'
}
}, _defineProperty(_ref5, theme.breakpoints.onlyM, {
display: showBackButtonOn.some(function (size) {
return size === 'm';
}) ? 'inline' : 'none'
}), _defineProperty(_ref5, theme.breakpoints.fromL, {
display: showBackButtonOn.some(function (size) {
return size === 'l';
}) ? 'inline' : 'none'
}), _ref5;
},
backButtonText: function backButtonText(_ref6) {
var theme = _ref6.theme;
return _defineProperty({}, theme.breakpoints.onlyS, {
display: 'none'
});
}
};
function BackButton(_ref8) {
var _ref8$backButtonConfi = _ref8.backButtonConfig,
backButtonConfig = _ref8$backButtonConfi === void 0 ? {} : _ref8$backButtonConfi,
showBackButtonOn = _ref8.showBackButtonOn,
reverseOut = _ref8.reverseOut;
var _useFela = useFela(),
theme = _useFela.theme;
var href = backButtonConfig.href,
_backButtonConfig$cli = backButtonConfig.clickHandler,
clickHandler = _backButtonConfig$cli === void 0 ? function () {} : _backButtonConfig$cli,
text = backButtonConfig.text;
var styleProps = {
theme: theme,
reverseOut: reverseOut,
showBackButtonOn: showBackButtonOn
};
return React.createElement(Click, {
onClick: clickHandler,
href: href,
extend: [styles.backButton(styleProps), getThemeStyle('tabNavBackButton', theme, styleProps)]
}, React.createElement(Arrow, {
direction: "left",
size: 10,
color: reverseOut ? theme.color.primitive.white : theme.color.ornament.highlight
}), React.createElement(Inline, {
extend: styles.backButtonText
}, text || ''));
}
function TabNavBorder() {
var _React$useContext = React.useContext(TabNavContext),
borderRef = _React$useContext.borderRef,
reverseOut = _React$useContext.reverseOut,
duration = _React$useContext.duration;
var _useFela2 = useFela(),
theme = _useFela2.theme;
var animatedMargin = theme.direction === 'rtl' ? 'right' : 'left';
return React.createElement(Block, {
ref: borderRef,
extend: styles.border({
animatedMargin: animatedMargin,
duration: duration,
reverseOut: reverseOut,
theme: theme
})
});
}
export var TabNav = React.forwardRef(function (_ref9, ref) {
var children = _ref9.children,
_ref9$duration = _ref9.duration,
duration = _ref9$duration === void 0 ? 160 : _ref9$duration,
_ref9$enableLineTrans = _ref9.enableLineTransition,
enableLineTransition = _ref9$enableLineTrans === void 0 ? false : _ref9$enableLineTrans,
_ref9$textAlign = _ref9.textAlign,
textAlign = _ref9$textAlign === void 0 ? 'center' : _ref9$textAlign,
variant = _ref9.variant,
_ref9$stickyChildrenL = _ref9.stickyChildrenLeft,
stickyChildrenLeft = _ref9$stickyChildrenL === void 0 ? null : _ref9$stickyChildrenL,
_ref9$stickyChildrenR = _ref9.stickyChildrenRight,
stickyChildrenRight = _ref9$stickyChildrenR === void 0 ? null : _ref9$stickyChildrenR,
_ref9$showBackButtonO = _ref9.showBackButtonOn,
showBackButtonOn = _ref9$showBackButtonO === void 0 ? ['s', 'm', 'l'] : _ref9$showBackButtonO,
_ref9$backButton = _ref9.backButton,
backButtonConfig = _ref9$backButton === void 0 ? {} : _ref9$backButton;
var _useState = useState(null),
_useState2 = _slicedToArray(_useState, 2),
active = _useState2[0],
setActive = _useState2[1];
var scrollRef = useRef();
var borderRef = useRef();
var _useFela3 = useFela(),
theme = _useFela3.theme; // TODO: remove in 2.x
deprecate('Variant for TabNav is deprecated, please use the volvo dark theme instead', variant);
var reverseOut = variant === 'dark';
var isCentered = textAlign === 'center';
var backButtonVisible = !!(backButtonConfig.clickHandler || backButtonConfig.href);
var styleProps = {
theme: theme,
reverseOut: reverseOut,
isCentered: isCentered
};
var context = {
active: active,
setActive: setActive,
scrollRef: scrollRef,
borderRef: borderRef,
reverseOut: reverseOut,
duration: enableLineTransition ? duration : 0
};
return React.createElement(Flex, {
as: "nav",
ref: ref,
extend: [styles.nav(styleProps), getThemeStyle('tabNav', theme, styleProps)]
}, React.createElement(Flex, {
extend: styles.stickyLeft(styleProps)
}, backButtonVisible ? React.createElement(BackButton, {
backButtonConfig: backButtonConfig,
showBackButtonOn: showBackButtonOn,
reverseOut: reverseOut
}) : null, React.createElement(TabNavContext.Provider, {
value: {
reverseOut: reverseOut
}
}, stickyChildrenLeft)), React.createElement(TabNavContext.Provider, {
value: context
}, React.createElement(Flex, {
ref: scrollRef,
extend: styles.scrollContainer
}, React.createElement(Flex, {
extend: styles.itemContainer
}, React.createElement(Flex, {
extend: {
paddingRight: 1
}
}), children, React.createElement(Flex, {
extend: {
paddingRight: 1
}
})), React.createElement(TabNavBorder, null))), React.createElement(Flex, {
extend: styles.stickyRight
}, React.createElement(TabNavContext.Provider, {
value: {
reverseOut: reverseOut
}
}, stickyChildrenRight)));
});
TabNav.displayName = 'TabNav';
TabNav.propTypes = {
/** Text-align: left or center */
textAlign: PropTypes.oneOf(['center', 'left']),
/** Back button text, href, click handler */
backButton: PropTypes.shape({
text: PropTypes.string,
href: PropTypes.string,
clickHandler: PropTypes.func
}),
/** A JSX node */
children: PropTypes.node,
/** A JSX node sticky to the left */
stickyChildrenLeft: PropTypes.node,
/** A JSX node sticky to the right */
stickyChildrenRight: PropTypes.node,
/** Which viewports to show the back button on */
showBackButtonOn: PropTypes.arrayOf(PropTypes.oneOf(['s', 'm', 'l'])),
/** Enable fancy transition when changing active tabs */
enableLineTransition: PropTypes.bool,
/** Set duration of lineTransition animation */
duration: PropTypes.number
};