UNPKG

@devseed-ui/theme-provider

Version:
191 lines (162 loc) 4.1 kB
import React from 'react'; import { createGlobalStyle, css, ThemeProvider } from 'styled-components'; import { themeVal } from './utils'; import { theme } from './theme'; import { unscrollableY, unscrollableX } from './helpers'; // Global styles for these components are included here for performance reasons. // This way they're only rendered when absolutely needed. const baseStyles = css` /** * Based on * https://hankchizljaw.com/wrote/a-modern-css-reset/ */ /* Box sizing rules */ *, *::before, *::after { box-sizing: border-box; } /* Set core root defaults */ html:focus-within { scroll-behavior: smooth; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } /* Set default line-height */ * { line-height: ${themeVal('type.base.line')}; } /* Remove default margin */ body, h1, h2, h3, h4, h5, h6, p, ul, ol, li, figure, blockquote, dl, dd { margin: 0; } /* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */ ul[role='list'], ol[role='list'] { list-style: none; padding: 0; } /* Set core <body> defaults */ body { background-color: ${themeVal('color.background')}; color: ${themeVal('type.base.color')}; font-size: ${themeVal('type.base.size')}; /* stylelint-disable-next-line font-family-no-missing-generic-family-keyword */ font-family: ${themeVal('type.base.family')}; text-transform: ${themeVal('type.base.case')}; font-weight: ${themeVal('type.base.weight')}; font-style: ${themeVal('type.base.style')}; font-variation-settings: ${themeVal('type.base.settings')}; min-width: ${themeVal('layout.min')}; min-height: 100vh; text-rendering: optimizeSpeed; ${({ theme }) => theme.type.base.antialiasing && css` -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; `} } /* Apply some default styles to <a> elements without a class */ a:not([class]) { cursor: pointer; color: ${themeVal('color.link')}; text-decoration: none; transition: opacity 0.24s ease 0s; &:visited { color: ${themeVal('color.link')}; } &:hover { opacity: 0.64; } &:active { transform: translate(0, 1px); } } /* Make images easier to work with */ img, picture { max-width: 100%; display: block; } /* Inherit fonts for <input> and <button> */ input, button, textarea, select { font: inherit; } /* Text-level semantics */ b, strong { font-weight: ${themeVal('type.base.bold')}; } /* Remove all animations and transitions for people that prefer not to see them */ @media (prefers-reduced-motion: reduce) { html:focus-within { scroll-behavior: auto; } *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } } /* Misc */ ::selection { background-color: ${themeVal('color.base-400a')}; color: ${themeVal('color.surface')}; } .tether-element { z-index: 1000; } .unscrollable-y { ${unscrollableY()} } .unscrollable-x { ${unscrollableX()} } `; const GlobalStyles = createGlobalStyle` ${baseStyles} `; /* eslint-disable react/prop-types */ const DevseedUiThemeProvider = ({ children, theme: providedTheme, ...rest }) => { // If the user provided a function, pass the ui library theme to allow // overrides. The resulting theme will be the used one. const newTheme = typeof providedTheme === 'function' ? providedTheme(theme.main) : // If it's not a function, the provided theme is used, // defaulting to the ui-library. providedTheme || theme.main; return ( <ThemeProvider theme={newTheme} {...rest}> <GlobalStyles /> {children} </ThemeProvider> ); }; /* eslint-enable react/prop-types */ export { GlobalStyles, DevseedUiThemeProvider };