UNPKG

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.

128 lines (115 loc) 2.97 kB
import React, { useContext, useEffect, useRef } from "react"; import PropTypes from "prop-types"; import { useFela } from "react-fela"; import { Click } from "../click"; import { LineTransitionContext } from "../tab-nav"; import { getThemeStyle } from "../../get-theme-style"; const styles = ({ isActive, reverseOut, hasLineTransition, theme: { colors: { grey1, primary, white } } }) => ({ display: "inline-flex", alignItems: "center", color: reverseOut ? white : grey1, fontSize: 15, height: 55, textAlign: "left", fontWeight: 200, letterSpacing: 0.3, margin: "0 20px 0 0", backgroundColor: reverseOut ? grey1 : "none", ":last-child": { margin: 0 }, transition: "color 200ms ease-out", ":hover": { color: reverseOut ? white : primary }, ":focus": { outline: "none", color: reverseOut ? white : primary }, extend: [ { condition: isActive, style: { color: reverseOut ? white : primary } }, { condition: !hasLineTransition, style: { borderBottom: "3px solid transparent", ":hover": { borderBottom: `3px solid ${reverseOut ? white : primary}` }, ":focus": { borderBottom: `3px solid ${reverseOut ? white : primary}` } } }, { condition: !hasLineTransition && isActive, style: { borderBottom: `3px solid ${reverseOut ? white : primary}` } } ] }); export function TabNavItem({ children, index, isActive, variant, ...props }) { const { theme } = useFela(); const reverseOut = variant === "dark"; const { updateDimensions } = useContext(LineTransitionContext); const ref = useRef(); useEffect(() => { if (updateDimensions && ref.current) { const { width } = ref.current ? ref.current.getBoundingClientRect() : { width: 0 }; const x = ref.current ? ref.current.offsetLeft : 0; updateDimensions(index, { width, x }); } }, []); const styleProps = { isActive, reverseOut, hasLineTransition: !!updateDimensions, theme }; if (styleProps.hasLineTransition && typeof index !== "number") { // Index property is passed down only to direct descendants of <TabNav> and is required for line transitions to work as intended. // If <TabNavItem>s are not direct descendants of <TabNav> an index will need to be passed down manually. // eslint-disable-next-line no-console console.warn( "TabNavItem is not a direct descendant of TabNav. Please provide an index to each TabNavItem to enable line transitions." ); return null; } return ( <Click extend={{ ...styles(styleProps), ...getThemeStyle("tabNavItem", theme, styleProps) }} {...props} innerRef={ref} > {children} </Click> ); } TabNavItem.propTypes = { children: PropTypes.node, /** Indicate if the TabNavItem is in an active state */ isActive: PropTypes.bool, /** Dark text on light background, or vice versa */ variant: PropTypes.oneOf(["light", "dark"]) }; TabNavItem.defaultProps = { isActive: false, variant: "light" };