Skip to content

Commit

Permalink
chore(website): Add migration guides for react-md major versions
Browse files Browse the repository at this point in the history
  • Loading branch information
mlaursen committed Jan 18, 2022
1 parent b7264d3 commit 78b7396
Show file tree
Hide file tree
Showing 9 changed files with 370 additions and 7 deletions.
2 changes: 1 addition & 1 deletion packages/dev-utils/src/indexer/generate.ts
Expand Up @@ -25,7 +25,7 @@ function pluralize(s: string): string {
}

function getMarkdownForRoute(route: string): string | null {
const simpleReadmeMatch = route.match(/^\/(blog|guides)\//);
const simpleReadmeMatch = route.match(/^\/(blog|guides|migration-guides)\//);
const packageMarkdownMatch = route.match(/\/(installation|changelog)$/);

let path = "";
Expand Down
4 changes: 4 additions & 0 deletions packages/dev-utils/src/indexer/getRoutes.ts
Expand Up @@ -6,6 +6,7 @@ import { getPackages, glob } from "../utils";

interface GetRoutesOptions {
guides: readonly string[];
migrations: readonly string[];
changelogs: readonly string[];
blogs: readonly string[];
}
Expand All @@ -15,6 +16,7 @@ const replaceIds = (pathname: string, values: readonly string[]): string[] =>

export async function getRoutes({
guides,
migrations,
changelogs,
blogs,
}: GetRoutesOptions): Promise<string[]> {
Expand Down Expand Up @@ -46,6 +48,8 @@ export async function getRoutes({
return "";
case "/guides/[id]":
return replaceIds(pathname, guides);
case "/migration-guides/[id]":
return replaceIds(pathname, migrations);
case "/blog/[id]":
return replaceIds(pathname, blogs);
case "/packages/[id]/api":
Expand Down
3 changes: 3 additions & 0 deletions packages/dev-utils/src/indexer/index.ts
Expand Up @@ -12,13 +12,16 @@ export async function indexer(): Promise<void> {

const guidesFolder = join(documentationRoot, src, "guides");
const guides = await glob("*.md", { cwd: guidesFolder });
const migrationsFolder = join(documentationRoot, src, "migration-guides");
const migrations = await glob("*.md", { cwd: migrationsFolder });
const changelogsFolder = join(documentationRoot, src, "changelogs");
const changelogs = await glob("*.md", { cwd: changelogsFolder });
const blogsFolder = join(documentationRoot, src, "blogs");
const blogs = await glob("*.md", { cwd: blogsFolder, ignore: ["index.md"] });

const routes = await getRoutes({
guides,
migrations,
changelogs,
blogs,
});
Expand Down
3 changes: 2 additions & 1 deletion packages/dev-utils/src/indexer/parseMarkdown.ts
Expand Up @@ -17,6 +17,7 @@ export function parseMarkdown(markdown: string): MarkdownResult {
const joinedNames = getPackages().join("|");
const anchors: TOCAnchor[] = [];
const renderer = new Renderer({ gfm: true, sanitize: false });
const forceAllHeadings = markdown.startsWith("# Migrate from v");
renderer.heading = (text, _level, _raw, slugger) => {
// if it is over 60 characters, it is probably not really a title
const isNoMargin = text.includes("<!-- no-margin -->");
Expand All @@ -25,7 +26,7 @@ export function parseMarkdown(markdown: string): MarkdownResult {
text = text.replace(/<!-- ([A-z]+(-[A-z]+)*) -->/g, "");

const isValidHeading =
isForcedHeading || (text.length <= 60 && !isNoMargin);
forceAllHeadings || isForcedHeading || (text.length <= 60 && !isNoMargin);

if (
!isValidHeading ||
Expand Down
3 changes: 3 additions & 0 deletions packages/dev-utils/src/utils/titles.ts
Expand Up @@ -58,6 +58,9 @@ export function toBreadcrumbPageTitle(
default:
title = "Server error";
}
} else if (/v\d+-to-v\d+$/.test(pathname)) {
const [migration] = pathname.split("/").reverse();
title = `Migration Guides - ${migration.replace(/-/g, " ")}`;
} else {
const parts = pathname.split("/").filter((p) => !!p && !/packages/.test(p));
title = parts.map((p) => toTitle(p)).join(" - ");
Expand Down
29 changes: 24 additions & 5 deletions packages/documentation/src/constants/navItems.tsx
@@ -1,3 +1,4 @@
import { snakeCase } from "lodash";
import { LayoutNavigationTree } from "@react-md/layout";
import {
BuildSVGIcon,
Expand All @@ -7,21 +8,21 @@ import {
HomeSVGIcon,
InfoOutlineSVGIcon,
LibraryBooksSVGIcon,
TrendingUpSVGIcon,
} from "@react-md/material-icons";

import MaterialDesignSVGIcon from "icons/MaterialDesignSVGIcon";
import ReactSVGIcon from "icons/ReactSVGIcon";
import createIdGenerator from "utils/createIdGenerator";
import { toTitle } from "utils/toTitle";

import { PACKAGE_NAMES, SCSS_PACKAGES, TYPESCRIPT_PACKAGES } from "./packages";
import {
RouteNavItem,
NavItem,
DividerNavItem,
NavItem,
RouteNavItem,
SubheaderNavItem,
} from "./meta/types";
import { snakeCase } from "lodash";
import { PACKAGE_NAMES, SCSS_PACKAGES, TYPESCRIPT_PACKAGES } from "./packages";

const uuid = createIdGenerator("nav");
const TSDOCS_PREFIX = "/tsdocs/modules/_react_md_";
Expand Down Expand Up @@ -128,6 +129,21 @@ const routes: readonly NavItem[] = [
},
],
},
{
href: "/migration-guides",
children: "Migration Guides",
leftAddon: <TrendingUpSVGIcon />,
routes: [
{
href: "/v3-to-v4",
children: "v3 to v4",
},
{
href: "/v2-to-v3",
children: "v2 to v3",
},
],
},
{
href: "/colors-and-theming",
children: "Colors and Theming",
Expand Down Expand Up @@ -238,7 +254,10 @@ function createNavItem(
}

const { href: currentItemId, routes = [], ...item } = navItem;
const itemId = `${parentHref || ""}${currentItemId}`;
const itemId = `${(parentHref || "").replace(
/\/migration$/,
""
)}${currentItemId}`;
const lastSlashIndex = itemId.lastIndexOf("/");

let href: string | undefined = itemId;
Expand Down
161 changes: 161 additions & 0 deletions packages/documentation/src/migration-guides/v2-to-v3.md
@@ -0,0 +1,161 @@
# Migrate from v2 to v3

#### Change node-sass to sass

Since
[node-sass has been deprecated](https://github.com/sass/node-sass#node-sass) and
[a new module system has been introduced](https://sass-lang.com/blog/the-module-system-is-launched)
users must switch from `node-sass` to `sass` to use the latest features within
`react-md`.

```sh
npm update react-md
npm uninstall node-sass
npm install sass
```

or with `yarn`

```sh
yarn add react-md
yarn remove node-sass
yarn add sass
```

#### Rename InteractionModeListener to UserInteractionModeListener

The `InteractionModeListener` was an alias for `UserInteractionModeListener` and
has been removed.

#### Remove ResizeObserver

The `ResizeObserver` component has been removed in favor of using the
`useResizeObserver` hook.

#### Update useResizeObserver to use the new API

```diff
-const ref = useRef()
-useResizeObserver({
- target: ref,
- onResize({ height, width, scrollHeight, scrollWidth, element }) {
- // Do something
- }
- disableHeight: true,
- disableWidth: true
-});
+const [ref] = useResizeObserver((resizeEvent) => {
+ const { height, width, scrollHeight, scrollWidth, element } = resizeEvent
+ // do something
+}, { disableHeight: true, disableWidth: true });

return (
<div ref={ref}>
{children}
</div>
);
```

#### Remove deprecated props from Tooltipped component

Since the `Tooltip` components now use the `HoverModeProvider`, the following
props should be removed from the `Tooltipped` component:

- `onHide`
- `onShow`
- `tooltipId`
- `hoverDelay`
- `focusDelay`
- `touchTimeout`
- `positionThreshold`

#### Remove TooltipHoverModeConfig

This component has been removed since the `Tooltip` uses the
`HoverModeProvider`.

#### Update useIndeterminateChecked to use an object as the second argument

```diff
const {
getProps,
rootProps,
// checkedValues,
// setCheckedValues,
-} = useIndeterminateChecked(condiments, ["Sprouts"], customOnChange);
+} = useIndeterminateChecked(condiments, {
+ onChange: customOnChange,
+ defaultCheckedValues: ["Sprouts"],
});
```

#### Improve build performance by using the new react-md sass file

Part of the v3.0.0 release was to create a
[new Sass import](https://github.com/mlaursen/react-md/blob/a9995e084480006a77f9123b95ce7275998fb406/packages/react-md/package.json#L9)
that
[merges all the .scss files into one](https://github.com/mlaursen/react-md/blob/3e738b4ab14fd7b4aab4f104b0d4120d226b7747/packages/dev-utils/src/utils/styles/combineAllFiles.ts#L105-L109)
for two reasons:

1. This simplifies importing things from react-md into a single `@use` statement
instead of multiple lines
2. Drastically improves build performance in large projects because only one
`.scss` file needs to be resolved.

`sass-loader` with `webpack` does not maintain context of other `.scss` files in
your app so each time you `import './path/to/my.scss';` or
`import styles from './path/to/my.module.scss';`, `sass-loader` will need to
resolve every `@import` or `@use` statement found in that file recursively. The
IO required for this is the whole reason build times can get slow in larger
projects since there are about 200 `.scss` files within react-md that would need
to be resolved. Combining all the files as a build step within react-md removes
this issue and drastically increases build performance.

To get started, update your main `.scss` file that imports all the packages
within `react-md` and generates the styles:

```diff
-@import '~@react-md/alert/dist/mixins';
-@import '~@react-md/app-bar/dist/mixins';
-@import '~@react-md/avatar/dist/mixins';
-@import '~@react-md/badge/dist/mixins';
-@import '~@react-md/button/dist/mixins';
-@import '~@react-md/card/dist/mixins';
-@import '~@react-md/chip/dist/mixins';
-@import '~@react-md/dialog/dist/mixins';
-@import '~@react-md/divider/dist/mixins';
-@import '~@react-md/elevation/dist/mixins';
-@import '~@react-md/expansion-panel/dist/mixins';
-@import '~@react-md/form/dist/mixins';
-@import '~@react-md/icon/dist/mixins';
-@import '~@react-md/layout/dist/mixins';
-@import '~@react-md/link/dist/mixins';
-@import '~@react-md/list/dist/mixins';
-@import '~@react-md/media/dist/mixins';
-@import '~@react-md/menu/dist/mixins';
-@import '~@react-md/overlay/dist/mixins';
-@import '~@react-md/progress/dist/mixins';
-@import '~@react-md/sheet/dist/mixins';
-@import '~@react-md/states/dist/mixins';
-@import '~@react-md/table/dist/mixins';
-@import '~@react-md/tabs/dist/mixins';
-@import '~@react-md/theme/dist/mixins';
-@import '~@react-md/tooltip/dist/mixins';
-@import '~@react-md/transition/dist/mixins';
-@import '~@react-md/tree/dist/mixins';
-@import '~@react-md/typography/dist/mixins';
-@import '~@react-md/utils/dist/mixins';
+@use 'react-md' as *;

@include react-md-utils;
```

Once the main styles have been generated, update the remaining `.scss` files in
your app replacing `@import` statements of `react-md` packages to be
`@use 'react-md' as *;`.

#### Overriding react-md Sass variables with the new module system

Check out the new #customizing-your-theme documentation to see how you can
override `react-md` Sass variables with the new module system and a recommended
setup.

0 comments on commit 78b7396

Please sign in to comment.