Type checking improvements in V8
Reduce boilerplate and increase confidence with Base Web V8Changes in Base Web@v8
If you do not use flow, you can safely update to v8 from v7 with no issues. There has been no breaking change in functionality or javascript APIs.
Improved flow type API in base web styled
function
If you are migrating from v7 be sure to read the last section here for directions on how to update smoothly.
See here for a recap of what the styled
function
does and view the
v7 migration docs for
previous context. We've heard your feedback on the v7 styled
function and have improved its
usability when working with custom themes. Previously, developers using custom theme types must
import the type in each file using the function. This introduced additional boilerplate and
increased the barrier of entry to statically typing your code; doing so should be as simple as
possible. A new function called createThemedStyled
is now exported from the baseui
package.
This function will provide a custom type that you supply in the $theme
field in styled
's
callback. Take a look at the example below.
// @flowimport {styled, createThemedStyled} from 'baseui';type PropsT = {};// Uses baseui's default theme.function StyledA = styled<PropsT>('div', props => {return {backgroundColor: props.$theme.colors.primary400,};});// Supplying a custom theme.type CustomTheme = {customColor: string};const themedStyled = createThemedStyled<CustomTheme>();function StyledB = themedStyled<PropsT>('div', props => {return {backgroundColor: props.$theme.customColor,};});
Themed withStyle
function
A common use-case is to extend a baseui
styled component and maintain type-safety with your
custom theme. Previously, writing the code below would error on accessing $theme
in StyledB
.
Now we no longer need to perform additional type annotation simply to appease flow, and can focus
on the task at hand with all of the added benefits to type checking.
// @flowimport {styled, withStyle} from 'baseui';type PropsT = {};function StyledA = styled<PropsT>('div', props => {return {backgroundColor: props.$theme.colors.primary400,};});function StyledB = withStyle<typeof StyledA, PropsT>(StyledA, props => {return {color: props.$theme.colors.mono400,};});
Similar to how styled
has a related createThemedStyled
function, withStyle
has
createThemedWithStyle
.
// @flowimport {createThemedStyled, createThemedWithStyle} from 'baseui';type CustomTheme = {customColor: string};const themedStyled = createThemedStyled<CustomTheme>();const themedWithStyle = createThemedWithStyle<CustomTheme>();type PropsT = {};function StyledA = themedStyled<PropsT>('div', props => {return {backgroundColor: props.$theme.customColor,};});function StyledB = themedWithStyle<typeof StyledA, PropsT>(StyledA, props => {return {color: props.$theme.customColor,};});
One helpful tip when working with themed styled functions, is to isolate the 'create...' calls to a single file in your code base. From there, you can relatively import your themed styled functions to avoid duplicated import statements from baseui.
themed-styled.js
// @flowimport {createThemedStyled, createThemedWithStyle} from 'baseui';type CustomTheme = {customColor: string};export const styled = createThemedStyled<CustomTheme>();export const withStyle = createThemedWithStyle<CustomTheme>();
styled-components.js
// @flowimport {styled, withStyle} from './themed-styled.js';type PropsT = {};function StyledA = styled<PropsT>('div', props => {return {backgroundColor: props.$theme.customColor,};});function StyledB = withStyle<typeof StyledA, PropsT>(StyledA, props => {return {color: props.$theme.customColor,};});
Themed useStyletron
hook
Brand new to Base Web is a themed wrapper of styletron's
useStyletron hook. In addition to what the
styletron-react
version gives you, importing useStyletron
from baseui
will provide the theme.
Doing so removes the need to import ThemeContext
around and calling React.useContext
to read
values from the theme. See the example below for a consice method to style your elements.
// @flowimport {useStyletron} from 'baseui';function ComponentA() {const [css, theme] = useStyletron();return <div className={css({color: theme.colors.primary400})}>test</div>;}
As we've seen before, useStyletron
also has a related createThemedUseStyletron
function.
// @flowimport {createThemedUseStyletron} from 'baseui';type CustomTheme = {customColor: string};const themedUseStyletron = createThemedUseStyletron<CustomTheme>();function ComponentA() {const [css, theme] = themedUseStyletron();return <div className={css({color: theme.customColor})}>test</div>;}
Migrating themed styled
calls to v8
See below for an example of how v7 patterns map to v8.
A simple scenario:
-import {styled} from 'baseui';+import {createThemedStyled} from 'baseui';type CustomTheme = {customColor: string};type PropsT = {};+const themedStyled = createThemedStyled<CustomTheme>();-const StyledA = styled<PropsT, CustomTheme>('div', props => {+const StyledA = themedStyled<PropsT>('div', props => {return {color: props.$theme.customColor};});
A more complex scenario:
-import {styled} from 'baseui';+import {createThemedStyled} from 'baseui';type CustomTheme = {customColor: string};type PropsT = {};+const themedStyled = createThemedStyled<CustomTheme>();function ComponentA(props: {className: string}) {return <div className={props.className}>test</div>;}-const StyledB = styled<typeof ComponentA, PropsT, CustomTheme>(ComponentA, props => {+const StyledB = themedStyled<typeof ComponentA, PropsT>(ComponentA, props => {return {color: props.$theme.customColor};});
To make the migration process even simpler, you can run a codemod to shift from v7's generic API to this extracted pattern. The codemod operates somewhat naively, but will output running code. There may be some follow-up after running. Follow the instructions below to run the codemod locally.
npm install -g jscodeshiftjscodeshift -t node_modules/baseui/codemods/styled-v8-themedStyled.js <transform-path>
Use the -d option for a dry-run and use -p to print the output for comparison.