UNPKG

vcc-ui

Version:

A React library for building user interfaces at Volvo Cars

357 lines (356 loc) 10.7 kB
import * as CSS from 'csstype'; import { IRenderer } from 'fela'; import { ComponentType, ReactNode } from 'react'; import { IconColor, IconType } from '../components/icon'; import { ThreeElements } from './three-element-types'; export type ValueOf<T> = T[keyof T]; /** * CSS object where values can be strings or numbers. */ export type CSSPropertiesBase = CSS.Properties<string | number>; export type CSSCustomPropertyType = `${string}var(--${string})${string}`; export type CSSCalcType = `${string}calc(${string})${string}`; export type CSSPropertiesDefault = { [key in keyof CSSPropertiesBase]: CSSPropertiesBase[key] | CSSCustomPropertyType | CSSCalcType; }; /** * CSS object with pseudo selectors. */ export type CSSPseudos<Theme> = { [K in CSS.Pseudos]?: ExtendCSSObject<Theme>; }; export interface CustomCSSProperties { /** * #### `foreground.primary` * &nbsp;&nbsp; Use for primary text and icons. * * > ⚪: `#141414` | ⚫: `#ffffff` * * * #### `foreground.secondary` * &nbsp;&nbsp; Use for secondary text and icons. * * > ⚪: `#707070` | ⚫: `#a3a3a3` * * * #### `foreground.inverted` * &nbsp;&nbsp; Use for inverted text and icons. * * > ⚪: `#ffffff` | ⚫: `#000000` * * * #### `foreground.alert` * &nbsp;&nbsp; Use for highlighting errors, invalid data, and destructive actions. * * > ⚪: `#bf2012` | ⚫: `#ea2c1a` * * * #### `foreground.action` * &nbsp;&nbsp; Use for links and other interactive elements. * * > ⚪: `#1c6bba` | ⚫: `#1c6bba` * **/ color?: `foreground.${keyof DesignSystemColors['foreground']}` | Omit<string, ''>; /** * #### `background.primary` * &nbsp;&nbsp; Primary background * * > ⚪: `#ffffff` | ⚫: `#0a0a0a` * * * #### `background.secondary` * &nbsp;&nbsp; Secondary background * * > ⚪: `#fafafa` | ⚫: `#141414` * **/ backgroundColor?: `background.${keyof DesignSystemColors['background']}` | Omit<string, ''>; } export type CSSProperties = CSSPropertiesDefault & CustomCSSProperties; export type ExtendPropValue<Theme, Props = {}> = ExtendCSSObject<Theme, Props> | ((args: { theme: Theme; } & Props) => ExtendCSSObject<Theme, Props>) | ExtendPropValue<Theme, Props>[] | FelaExtend<Theme> | undefined; export interface FelaExtend<Theme> { extend?: { condition?: boolean; style: ExtendCSSObject<Theme>; } | { condition?: boolean; style: ExtendCSSObject<Theme>; }[]; } /** * CSS object with properties, breakpoints, child selectors and pseudo selectors. */ export interface ExtendCSSObject<Theme, Props = {}> extends FelaExtend<Theme>, CSSProperties, CSSPseudos<Theme> { [key: string]: ExtendCSSObject<Theme, Props> | ExtendPropValue<Theme, Props> | string | boolean | number | undefined; } export type ResponsiveProp<T> = T | [T] | [T, T] | [T, T, T] | [T, T, T, T] | Record<ThemeBreakpointName | 'default', T> | { [mediaQuery: string]: T; }; export type TypeVariants = /** * * Amundsen (action text) - 14px */ 'amundsen' /** * * Bates - 12px */ | 'bates' /** * * Columbus (default) - 16px */ | 'columbus' /** * * Cook - 32px / 36px / 40px */ | 'cook' /** * * Hillary - 20px */ | 'hillary' /** * * Ootah - 24px / 28px / 32px */ | 'ootah' /** * * Peary - 48px / 52px / 56px */ | 'peary' /** * * Yang (brand statement) - 40px / 72px / 72px */ | 'yang' /** * * Kelly - 14px */ | 'kelly' /** * * Meir - 8px */ | 'meir'; export interface DesignSystemColors { brand: { /** * The primary brand color, used sparingly to create brand associated UI components. * * * Light Theme: #284e80 * * Dark Theme: #284e80 */ primary: string; }; foreground: { /** * Use for primary text and icons. * * * Light Theme: #141414 * * Dark Theme: #ffffff */ primary: string; /** * Use for secondary text and icons. * * * Light Theme: #707070 * * Dark Theme: #a3a3a3 */ secondary: string; /** * Use for inverted text and icons. * * * Light Theme: #ffffff * * Dark Theme: #000000 */ inverted: string; /** * Use to highlight positive actions or events. * * * Light Theme: #058A22 * * Dark Theme: #08B42E */ positive: string; /** * Use to highlight destructive actions. * * * Light Theme: #bf2012 * * Dark Theme: #ea2c1a */ alert: string; /** * Use for links and other interactive elements. * * * Light Theme: #1c6bba * * Dark Theme: #1c6bba */ action: string; }; background: { /** * Primary background. * * * Light Theme: #ffffff * * Dark Theme: #0a0a0a */ primary: string; /** * Secondary background. * * * Light Theme: #fafafa * * Dark Theme: #141414 * */ secondary: string; }; ornament: { /** * Use to visually group or separate UI elements. * * * Light Theme: #d5d5d5 * * Dark Theme: #707070 */ border: string; /** * Use to visually group or separate UI elements. * * * Light Theme: #ebebeb * * Dark Theme: #292929 */ divider: string; /** * Use to highlight selected and focus states. * * * Light Theme: #1c6bba * * Dark Theme: #1c6bba */ highlight: string; /** * Use to highlight successful states. * * * Light Theme: #058A22 * * Dark Theme: #08B42E */ positive: string; /** * Use to highlight errors and invalid states. * * * Light Theme: #bf2012 * * Dark Theme: #ea2c1a */ alert: string; }; primitive: { black: string; white: string; blue: string; accentBlue: string; greenPositive: string; red: string; grey100: string; grey200: string; grey300: string; grey400: string; grey500: string; }; } export interface ThemeBreakpoints { /** \< 480 (identical to untilM) */ onlyS: '@media (max-width: 479px)'; /** \< 480 */ untilM: '@media (max-width: 479px)'; /** \> 480 */ fromM: '@media (min-width: 480px)'; /** \>= 480 && < 1024 */ onlyM: '@media (min-width: 480px) and (max-width: 1023px)'; /** \< 1024 */ untilL: '@media (max-width: 1023px)'; /** \>= 1024 */ fromL: '@media (min-width: 1024px)'; /** \>= 1024 && < 1600 */ onlyL: '@media (min-width: 1024px) and (max-width: 1599px)'; /** \< 1600 */ untilXL: '@media (max-width: 1599px)'; /** \>= 1600 */ fromXL: '@media (min-width: 1600px)'; /** \>= 1600 (identical to fromXL) */ onlyXL: '@media (min-width: 1600px)'; } export type ThemeBreakpointName = keyof ThemeBreakpoints; export type Direction = 'ltr' | 'rtl'; /** Volvo Theme */ export interface CurrentTheme { name: 'volvo' | 'volvo-dark' | 'light' | 'dark'; color: DesignSystemColors; direction: Direction; baselineGrid: 8; baselineSubGrid: 4; breakpoints: ThemeBreakpoints; icons: readonly ('account' | 'email' | 'facebook' | 'globe' | 'instagram' | 'linkedin' | 'pinterest' | 'search' | 'twitter' | 'vkontakte' | 'wechat' | 'weibo' | 'youku' | 'youtube')[]; getIcon(type: IconType, color?: IconColor): string; fonts: any; font: { family: { 'volvo-novum': 'Volvo Novum, sans-serif'; 'volvo-serif': 'Volvo Serif Pro, serif'; 'volvo-broad': 'Volvo Broad Pro, sans-serif'; }; weight: { 'semi-light': 300; regular: 400; medium: 500; }; }; fontsPath: string; fontTypes: any; iconsPath: string; tokens: { [key: string]: any; }; logoImagesPath: string; typeScale: Record<TypeVariants, any>; states: { focus: { outlineOffset: number; outlineWidth: number; outlineColor: string; outlineStyle: string; }; }; } export type Extendable<Props = {}> = { /** A CSS object or a function returning a CSS object, or an array of them */ extend?: ExtendPropValue<CurrentTheme, Props>; }; /** All intrinsic elements except react-three-fiber related ones */ export type OmittedIntrinsicElements = Omit<JSX.IntrinsicElements, ThreeElements>; /** A React component, or a string specifying a name for an HTML element */ export type AsProp = keyof OmittedIntrinsicElements | ComponentType<any>; export type PropsWithExtend<Props> = Props & Extendable<Props>; export type ExtendCSS<Props = {}> = ExtendPropValue<CurrentTheme, Props>; type As<Props = any> = Exclude<React.ElementType<Props>, ThreeElements>; export type PropsWithAs<Props = {}, Type extends As = As, ExtendedRefType = undefined> = Props & Omit<React.ComponentProps<Type>, 'as' | keyof Props | 'ref'> & { as?: Type; ref?: React.ComponentProps<Type>['ref'] | ExtendedRefType; }; export type ComponentWithAs<Props, DefaultType extends As, ExtendedRefType = undefined> = { <Type extends As>(props: PropsWithAs<Props, Type, ExtendedRefType> & { as: Type; }): JSX.Element; (props: PropsWithAs<Props, DefaultType, ExtendedRefType>): JSX.Element; }; /** Changes the rendered element from `<button>` to `<a>`, * and based on that change the allowed props */ type HrefProp = any; export type PropsWithHref<Props = {}, Href extends HrefProp = undefined, NoHrefElementType extends 'button' | 'div' = 'button'> = Props & React.ComponentProps<Href extends undefined ? NoHrefElementType : 'a'> & { href?: Href; }; export type ComponentWithHref<Props, DefaultHref extends HrefProp, NoHrefElementType extends 'button' | 'div' = 'button'> = { <Href extends HrefProp>(props: PropsWithHref<Props, Href, NoHrefElementType> & { href: Href; }): JSX.Element; (props: PropsWithHref<Props, DefaultHref, NoHrefElementType>): JSX.Element; }; export type Theme = ComponentType<{ children: (theme: CurrentTheme) => ReactNode; }>; export type renderStyles = (renderer: IRenderer) => React.DetailedReactHTMLElement<any, HTMLElement>[]; export {};