import Layout from "../../../components/layout";
import { BlogImage, Demo, Meta } from "../../../components/blog";
import metadata from "./metadata.json";

export default Layout;

<Meta data={metadata} />

# Changes in Base Web@v8

_If you do not use [flow](https://flow.org/), 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](https://baseweb.design/components/styled/) for a recap of what the `styled` function
does and view the
[v7 migration docs](https://github.com/uber/baseweb/blob/master/docs/migrations/01207.md) 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.

```js
import {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.

```js
import {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`.

```js
import {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

```js
import {
  createThemedStyled,
  createThemedWithStyle,
} from "baseui";

type CustomTheme = { customColor: string };
export const styled = createThemedStyled<CustomTheme>();
export const withStyle =
  createThemedWithStyle<CustomTheme>();
```

styled-components.js

```js
import {styled, withStyle} from './themed-styled.jsx';

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](https://www.styletron.org/react/#usestyletron-hook) 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 concise method to style your elements.

```js
import { 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.

```js
import { 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:

```diff
-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:

```diff
-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.

```
npx @uber-web-ui/baseui-codemods --mod=v8Types --dir=<path_to_code>
```

Use the -d option for a dry-run and use -p to print the output for comparison.
