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.
669 lines (586 loc) • 14.4 kB
JavaScript
import { sizeToRem } from '../size-to-rem';
import { buildTypeScale } from '../build-type-scale';
import designTokens from '../../design-tokens/build/web/volvo/tokens.json';
import { deprecate } from '../deprecate';
/* New colors */
const { color } = designTokens;
/* Old colors, deprecated */
const colorWarn = color => {
deprecate(
color +
' in theme.colors is deprecated, please use theme.color decisions instead',
true
);
return color;
};
const colors = {
black: () => color.primitive.black, // pending removal in 3.x
white: () => color.primtive.white, // pending removal in 3.x
primary: () => color.primitive.accentBlue, // pending removal in 3.x
destructive: () => color.primitive.red, // pending removal in 3.x
grey1: () => colorWarn('rgb(30, 30, 30)'), // pending removal in 3.x
grey2: () => colorWarn('rgb(65, 65, 65)'),
grey3: () => colorWarn('rgb(100, 100,100)'),
grey4: () => colorWarn('rgb(135, 135, 135)'),
grey5: () => colorWarn('rgb(165, 165, 165)'),
grey6: () => colorWarn('rgb(195, 195, 195)'),
grey7: () => colorWarn('rgb(225, 225, 225)'),
grey8: () => colorWarn('rgb(240, 240, 240)'),
primaryLight: () => colorWarn('#008ae6'),
secondary: () => colorWarn('#000000'),
secondaryLight: () => colorWarn('#161618'),
destructiveLight: () => colorWarn('#db0f4f'),
};
const tokens = {
buttonPaddingVertical: 18,
buttonPaddingHorizontal: 48,
buttonPrimaryColor: color.primitive.accentBlue,
buttonPrimaryForeground: color.foreground.inverted,
buttonSecondaryColor: color.primitive.black,
buttonSecondaryForeground: color.foreground.inverted,
buttonDestructiveColor: color.foreground.alert,
buttonDestructiveForeground: color.foreground.inverted,
buttonPrimaryLightColor: color.primitive.white, // deprecated
buttonPrimaryLightForeground: color.primitive.black, // deprecated
buttonPrimaryLightActiveBackground: color.primitive.white, // deprecated
inputPaddingVertical: 16,
inputPaddingHorizontal: 24,
inputForeground: color.foreground.primary,
inputDisabledForeground: color.primitive.grey300,
inputDisabledControl: color.primitive.grey400, // should be decision?
inputDisabledBorder: color.primitive.grey400,
inputBackground: color.background.primary,
inputBorder: color.ornament.border,
inputBorderFocus: color.ornament.highlight,
inputPlaceholder: color.foreground.secondary,
inputControl: color.primitive.accentBlue,
card: {
background: color.background.primary,
shadow: 'rgba(0, 0, 0, 0.2) 0px 4px 12px',
},
};
const breakpointSizes = {
m: 480,
l: 1024,
xl: 1600,
};
// there is no fromS as that'd be the default styles and we do not want
// those to be part of a min-width: 0px media queries due to CSS performance
const breakpoints = {
// duplicate of untilM
// > 0 && < 480
get onlyS() {
return this.untilM;
},
// < 480
untilM: '@media (max-width: ' + (breakpointSizes.m - 1) + 'px)',
// >= 480
fromM: '@media (min-width: ' + breakpointSizes.m + 'px)',
// >= 480 && < 1024
get onlyM() {
return this.fromM + ' and ' + this.untilL.substring(7);
},
// < 1024
untilL: '@media (max-width: ' + (breakpointSizes.l - 1) + 'px)',
// >= 1024
fromL: '@media (min-width: ' + breakpointSizes.l + 'px)',
// >= 1024 && < 1600
get onlyL() {
return this.fromL + ' and ' + this.untilXL.substring(7);
},
// < 1600
untilXL: '@media (max-width: ' + (breakpointSizes.xl - 1) + 'px)',
// >= 1600
fromXL: '@media (min-width: ' + breakpointSizes.xl + 'px)',
// duplicate of fromXL
// >= 1600
get onlyXL() {
return this.fromXL;
},
};
const icons = [
'account',
'email',
'search',
'globe',
'facebook',
'twitter',
'youtube',
'linkedin',
'instagram',
'pinterest',
'youku',
'vkontakte',
'wechat',
'weibo',
];
const DEFAULT_FONT_DISPLAY = 'swap';
export const FONT_WEIGHTS = {
semiLight: 300,
regular: 400,
medium: 500,
bold: 700,
};
const fonts = [
{
fontFamily: 'Volvo Broad',
fontDisplay: DEFAULT_FONT_DISPLAY,
src: ['volvo-broad/volvo-broad.woff'],
},
{
fontFamily: 'Volvo Novum',
fontDisplay: DEFAULT_FONT_DISPLAY,
fontWeight: 200,
src: [
'volvo-novum/volvo-novum-light.woff2',
'volvo-novum/volvo-novum-light.woff',
],
},
{
fontFamily: 'Volvo Novum',
fontDisplay: DEFAULT_FONT_DISPLAY,
fontWeight: 200,
fontStyle: 'italic',
src: [
'volvo-novum/volvo-novum-light-italic.woff2',
'volvo-novum/volvo-novum-light-italic.woff',
],
},
{
fontFamily: 'Volvo Novum',
fontDisplay: DEFAULT_FONT_DISPLAY,
fontWeight: 300,
src: [
'volvo-novum/volvo-novum-semi-light.woff2',
'volvo-novum/volvo-novum-semi-light.woff',
],
},
{
fontFamily: 'Volvo Novum',
fontDisplay: DEFAULT_FONT_DISPLAY,
fontWeight: 300,
fontStyle: 'italic',
src: [
'volvo-novum/volvo-novum-semi-light-italic.woff2',
'volvo-novum/volvo-novum-semi-light-italic.woff',
],
},
{
fontFamily: 'Volvo Novum',
fontDisplay: DEFAULT_FONT_DISPLAY,
fontWeight: 400,
src: [
'volvo-novum/volvo-novum-regular.woff2',
'volvo-novum/volvo-novum-regular.woff',
],
},
{
fontFamily: 'Volvo Novum',
fontDisplay: DEFAULT_FONT_DISPLAY,
fontWeight: 400,
fontStyle: 'italic',
src: [
'volvo-novum/volvo-novum-italic.woff2',
'volvo-novum/volvo-novum-italic.woff',
],
},
{
fontFamily: 'Volvo Novum',
fontDisplay: DEFAULT_FONT_DISPLAY,
fontWeight: 500,
src: [
'volvo-novum/volvo-novum-medium.woff2',
'volvo-novum/volvo-novum-medium.woff',
],
},
{
fontFamily: 'Volvo Novum',
fontDisplay: DEFAULT_FONT_DISPLAY,
fontWeight: 500,
fontStyle: 'italic',
src: [
'volvo-novum/volvo-novum-medium-italic.woff2',
'volvo-novum/volvo-novum-medium-italic.woff',
],
},
{
fontFamily: 'Volvo Novum',
fontDisplay: DEFAULT_FONT_DISPLAY,
fontWeight: 700,
src: [
'volvo-novum/volvo-novum-bold.woff2',
'volvo-novum/volvo-novum-bold.woff',
],
},
{
fontFamily: 'Volvo Novum',
fontDisplay: DEFAULT_FONT_DISPLAY,
fontWeight: 700,
fontStyle: 'italic',
src: [
'volvo-novum/volvo-novum-bold-italic.woff2',
'volvo-novum/volvo-novum-bold-italic.woff',
],
},
{
fontFamily: 'Volvo Serif',
fontDisplay: DEFAULT_FONT_DISPLAY,
fontWeight: 400,
src: ['volvo-serif/volvo-serif-regular.woff'],
},
{
fontFamily: 'Volvo Serif',
fontDisplay: DEFAULT_FONT_DISPLAY,
fontWeight: 400,
fontStyle: 'italic',
src: ['volvo-serif/volvo-serif-italic.woff'],
},
{
fontFamily: 'Volvo Serif',
fontDisplay: DEFAULT_FONT_DISPLAY,
fontWeight: 700,
src: ['volvo-serif/volvo-serif-bold.woff'],
},
{
fontFamily: 'Volvo Serif',
fontDisplay: DEFAULT_FONT_DISPLAY,
fontWeight: 700,
fontStyle: 'italic',
src: ['volvo-serif/volvo-serif-bold-italic.woff'],
},
];
const fontTypes = {
BROAD: 'Volvo Broad, Arial Black, sans-serif',
NOVUM: 'Volvo Novum, Arial, sans-serif',
SERIF: 'Volvo Serif, serif',
};
const logoImages = {
square: 'volvo-logo.png',
square2x: 'volvo-logo-2x.png',
wordmark: 'volvo-wordmark.svg', // deprecated, remove in 2.x
'wordmark-black': 'volvo-wordmark-black.svg', // deprecated 2.x
spreadmark: 'volvo-wordmark-black.svg',
};
// it automatically picks up 2x pictures if found as a prefix to the actual names
const logoTypes = {
SQUARE: 'square',
WORDMARK: 'wordmark', // deprecated, remove in 2.x
WORDMARK_BLACK: 'wordmark-black', //deprecated, remove in 2.x
SPREADMARK: 'spreadmark',
};
const typeScale = {
/**
Headings
*/
peary: {
standard: {
element: 'h1',
styles: {
fontFamily: fontTypes.NOVUM,
fontSize: sizeToRem(6),
fontWeight: FONT_WEIGHTS.medium,
lineHeight: 52 / 48,
letterSpacing: 0,
[breakpoints.fromM]: {
fontSize: sizeToRem(6.5),
lineHeight: 56 / 52,
},
[breakpoints.fromL]: {
fontSize: sizeToRem(7),
lineHeight: 60 / 56,
},
},
baselineAdjustments: {
top: 0,
bottom: 0,
[breakpoints.fromL]: {
top: 1,
bottom: 3,
},
},
},
},
cook: {
standard: {
element: 'h1',
styles: {
fontFamily: fontTypes.NOVUM,
fontSize: sizeToRem(4),
fontWeight: FONT_WEIGHTS.medium,
lineHeight: 36 / 32,
letterSpacing: 0,
[breakpoints.fromM]: {
fontSize: sizeToRem(4.5),
lineHeight: 40 / 36,
},
[breakpoints.fromL]: {
fontSize: sizeToRem(5),
lineHeight: 44 / 40,
},
},
baselineAdjustments: {
top: 2,
bottom: 2,
[breakpoints.fromM]: {
top: 3,
bottom: 1,
},
},
},
},
ootah: {
standard: {
element: 'h1',
styles: {
fontFamily: fontTypes.NOVUM,
fontSize: sizeToRem(3),
fontWeight: FONT_WEIGHTS.medium,
lineHeight: 28 / 24,
letterSpacing: 0,
[breakpoints.fromM]: {
fontSize: sizeToRem(3.5),
lineHeight: 32 / 28,
},
[breakpoints.fromL]: {
fontSize: sizeToRem(4),
lineHeight: 36 / 32,
},
},
baselineAdjustments: {
top: 1,
bottom: 3,
[breakpoints.fromM]: {
top: 2,
bottom: 2,
},
},
},
},
/**
Sub-Headings
*/
hillary: {
standard: {
element: 'p',
styles: {
fontFamily: fontTypes.NOVUM,
fontSize: sizeToRem(2.5),
fontWeight: FONT_WEIGHTS.semiLight,
textDecoration: 'none',
lineHeight: 24 / 20,
letterSpacing: 0,
},
baselineAdjustments: {
top: 0,
bottom: 0,
},
},
'inline-link': {
element: 'a',
styles: {
color: tokens.buttonPrimaryColor,
'&:hover': {
textDecoration: 'underline',
},
},
},
emphasis: {
element: 'em',
styles: {
fontStyle: 'normal',
fontWeight: FONT_WEIGHTS.medium,
},
},
},
/**
Body
*/
columbus: {
standard: {
element: 'p',
styles: {
fontFamily: fontTypes.NOVUM,
fontSize: sizeToRem(2),
lineHeight: 24 / 16,
letterSpacing: 0,
fontWeight: FONT_WEIGHTS.semiLight,
},
baselineAdjustments: {
top: 2,
bottom: 2,
},
},
'inline-link': {
element: 'a',
styles: {
color: tokens.buttonPrimaryColor,
textDecoration: 'none',
'&:hover': {
textDecoration: 'underline',
},
},
},
emphasis: {
element: 'em',
styles: {
fontStyle: 'normal',
fontWeight: FONT_WEIGHTS.medium,
},
},
},
/**
Micro
*/
bates: {
standard: {
element: 'small',
styles: {
fontFamily: fontTypes.NOVUM,
fontSize: sizeToRem(1.5),
lineHeight: 20 / 12,
letterSpacing: '0.02em',
fontWeight: FONT_WEIGHTS.semiLight,
},
baselineAdjustments: {
top: 2,
bottom: 2,
},
},
'inline-link': {
element: 'a',
styles: {
color: tokens.buttonPrimaryColor,
textDecoration: 'none',
'&:hover': {
textDecoration: 'underline',
},
},
},
emphasis: {
element: 'em',
styles: {
fontStyle: 'normal',
fontWeight: FONT_WEIGHTS.medium,
},
},
},
/**
Button
*/
amundsen: {
standard: {
element: 'span',
styles: {
fontFamily: fontTypes.NOVUM,
fontSize: sizeToRem(2),
lineHeight: 24 / 16,
letterSpacing: '0.04em',
fontWeight: FONT_WEIGHTS.medium,
},
baselineAdjustments: {
top: 2,
bottom: 2,
},
},
},
/**
Outliers
*/
armstrong: {
standard: {
element: 'p',
styles: {
fontFamily: fontTypes.SERIF,
fontWeight: FONT_WEIGHTS.regular,
fontSize: sizeToRem(4),
lineHeight: 36 / 32,
[breakpoints.fromM]: {
fontSize: sizeToRem(4.5),
lineHeight: 40 / 36,
},
[breakpoints.fromL]: {
fontSize: sizeToRem(5),
lineHeight: 44 / 40,
},
},
baselineAdjustments: {
top: 3,
bottom: 1,
[breakpoints.fromM]: {
top: 0,
bottom: 0,
},
},
},
},
jemison: {
standard: {
element: 'p',
styles: {
fontFamily: fontTypes.SERIF,
fontWeight: FONT_WEIGHTS.regular,
fontSize: sizeToRem(2.5),
lineHeight: 24 / 20,
},
baselineAdjustments: {
top: 1,
bottom: 3,
},
},
},
ride: {
standard: {
element: 'p',
styles: {
fontFamily: fontTypes.SERIF,
fontWeight: FONT_WEIGHTS.regular,
fontSize: sizeToRem(2),
lineHeight: 24 / 16,
},
baselineAdjustments: {
top: 3,
bottom: 1,
},
},
},
};
export default {
name: 'volvo',
// this is the default text direction
// rtl needs to be set via ThemeProvider explicitly
direction: 'ltr',
baselineGrid: 8,
baselineSubGrid: 4,
breakpoints,
colors,
tokens,
icons,
fonts,
fontsPath: '/',
fontTypes,
logoImages,
logoImagesPath: '/',
logoTypes,
typeScale: buildTypeScale(typeScale),
// placeholder for custom brand styles
styles: {
button: ({ theme }) => ({
fontFamily: theme.fontTypes.NOVUM,
}),
link: () => typeScale.columbus.standard.styles,
navItem: ({ theme }) => ({
fontFamily: theme.fontTypes.NOVUM,
}),
tabNavItem: ({ theme }) => ({
fontFamily: theme.fontTypes.NOVUM,
}),
tabNavBackButton: ({ theme }) => ({
fontFamily: theme.fontTypes.NOVUM,
}),
textInput: () => typeScale.columbus.standard.styles,
selectInput: () => typeScale.columbus.standard.styles,
textArea: () => typeScale.columbus.standard.styles,
},
// New Design Tokens
...designTokens,
};