Repository: zeit-ui/react
Pull request #207 (2020-05-15 13:32:20)

build: supprot esm bundle
## PR Checklist

- [x] Fix linting errors
- [x] Label has been added


## Change information

  - Add `esm` modules to adapt to tree-shaking.
  - Rename some modules to  make sure tree-shaking works.
  - Change the export paths for some modules.

After PR merged, I will add some examples for tree-shaking.

**Before:**

<img width="705" alt="esm-1" src="https://user-images.githubusercontent.com/11304944/82067556-77deaf00-9703-11ea-966f-220d74812b9b.png">

**After:**

<img width="431" alt="esm-2" src="https://user-images.githubusercontent.com/11304944/82067574-7dd49000-9703-11ea-8f25-56f26ba97b0c.png">



codecov[bot]: # [Codecov](https://codecov.io/gh/zeit-ui/react/pull/207?src=pr&el=h1) Report
> Merging [#207](https://codecov.io/gh/zeit-ui/react/pull/207?src=pr&el=desc) into [master](https://codecov.io/gh/zeit-ui/react/commit/5bf35735315ad718f4048e61af2f92f117a3b41f&el=desc) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/zeit-ui/react/pull/207/graphs/tree.svg?width=650&height=150&src=pr&token=209SV0GGAX)](https://codecov.io/gh/zeit-ui/react/pull/207?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master     #207   +/-   ##
=======================================
  Coverage   99.90%   99.90%           
=======================================
  Files         171      171           
  Lines        2138     2138           
  Branches      501      484   -17     
=======================================
  Hits         2136     2136           
  Misses          2        2           
```



------

[Continue to review full report at Codecov](https://codecov.io/gh/zeit-ui/react/pull/207?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/zeit-ui/react/pull/207?src=pr&el=footer). Last update [5bf3573...d5c8f1b](https://codecov.io/gh/zeit-ui/react/pull/207?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/.eslintignore b/.eslintignore
index 6ddc99c..547c236 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -2,6 +2,7 @@
 .next/*
 examples/*
 dist/*
+esm/*
 public/*
 scripts/*
 tests/*
diff --git a/.gitignore b/.gitignore
index ce3447d..7945eaf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,3 +26,4 @@ yarn-error.log*
 
 .now
 dist
+esm
diff --git a/.nowignore b/.nowignore
index 411ea2b..c1434a6 100644
--- a/.nowignore
+++ b/.nowignore
@@ -3,4 +3,7 @@
 .DS_Store
 .env
 examples
+esm
+dist
+coverage
 .circleci
diff --git a/.prettierignore b/.prettierignore
index fe59788..1f0f8b3 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -5,6 +5,7 @@
 dist
 coverage
 public
+esm
 *.mdx
 *.md
 *.json
diff --git a/components/css-baseline-deprecated/index.ts b/components/css-baseline-deprecated/index.ts
new file mode 100644
index 0000000..8cf79db
--- /dev/null
+++ b/components/css-baseline-deprecated/index.ts
@@ -0,0 +1,6 @@
+import CssBaseline from '../css-baseline'
+import useWarning from '../utils/use-warning'
+
+useWarning('Module "CSSBaseline" is deprecated. Use `CssBaseline` instead of it.', 'CSSBaseline')
+
+export default CssBaseline
diff --git a/components/styles/css-baseline/css-baseline.tsx b/components/css-baseline/css-baseline.tsx
similarity index 96%
rename from components/styles/css-baseline/css-baseline.tsx
rename to components/css-baseline/css-baseline.tsx
index 4deeda9..3eeadfb 100644
--- a/components/styles/css-baseline/css-baseline.tsx
+++ b/components/css-baseline/css-baseline.tsx
@@ -1,9 +1,9 @@
 import React from 'react'
-import useTheme from '../use-theme'
+import useTheme from '../styles/use-theme'
 import flush from 'styled-jsx/server'
 import flushToReact from 'styled-jsx/server'
 
-const CSSBaseline: React.FC<React.PropsWithChildren<{}>> = ({ children }) => {
+const CssBaseline: React.FC<React.PropsWithChildren<{}>> = ({ children }) => {
   const theme = useTheme()
 
   return (
@@ -305,9 +305,9 @@ type MemoCssBaselineComponent<P = {}> = React.NamedExoticComponent<P> & {
   flush: typeof flushToReact
 }
 
-const MemoCSSBaseline = React.memo(CSSBaseline) as MemoCssBaselineComponent<
+const MemoCssBaseline = React.memo(CssBaseline) as MemoCssBaselineComponent<
   React.PropsWithChildren<{}>
 >
-MemoCSSBaseline.flush = flush
+MemoCssBaseline.flush = flush
 
-export default MemoCSSBaseline
+export default MemoCssBaseline
diff --git a/components/styles/css-baseline/index.tsx b/components/css-baseline/index.ts
similarity index 100%
rename from components/styles/css-baseline/index.tsx
rename to components/css-baseline/index.ts
diff --git a/components/index.ts b/components/index.ts
index d721655..4194409 100644
--- a/components/index.ts
+++ b/components/index.ts
@@ -1,14 +1,21 @@
 /// <reference types="styled-jsx" />
 
 export * from './styles/themes'
-export { default as Utils } from './utils-shared/index'
+export { default as Utils } from './utils-shared-deprecated/index'
 export { default as useTheme } from './styles/use-theme'
-export { default as ZEITUIProvider } from './providers/zeit-ui-provider'
-export { default as useToasts } from './toast'
+export { default as ZEITUIProvider } from './zeit-provider-deprecated'
+export { default as ZeitProvider } from './zeit-provider'
+export { default as CSSBaseline } from './css-baseline-deprecated'
+export { default as CssBaseline } from './css-baseline'
+export { default as useToasts } from './use-toasts'
 export { default as useInput } from './input/use-input'
 export { default as useModal } from './modal/use-modal'
 export { default as useTabs } from './tabs/use-tabs'
-export { default as CSSBaseline } from './styles/css-baseline'
+export { default as useBodyScroll } from './use-body-scroll'
+export { default as useClickAway } from './use-click-away'
+export { default as useClipboard } from './use-clipboard'
+export { default as useCurrentState } from './use-current-state'
+export { default as useMediaQuery } from './use-media-query'
 export { default as Avatar } from './avatar'
 export { default as Text } from './text'
 export { default as Note } from './note'
@@ -37,7 +44,7 @@ export { default as Radio } from './radio'
 export { default as Select } from './select'
 export { default as Tabs } from './tabs'
 export { default as Progress } from './progress'
-export { default as Tree } from './file-tree'
+export { default as Tree } from './tree'
 export { default as Badge } from './badge'
 export { default as AutoComplete } from './auto-complete'
 export { default as Collapse } from './collapse'
diff --git a/components/snippet/snippet.tsx b/components/snippet/snippet.tsx
index f4e6095..b7dda7b 100644
--- a/components/snippet/snippet.tsx
+++ b/components/snippet/snippet.tsx
@@ -5,7 +5,7 @@ import { SnippetTypes, CopyTypes } from '../utils/prop-types'
 import { getStyles } from './styles'
 import SnippetIcon from './snippet-icon'
 import useClipboard from '../utils/use-clipboard'
-import useToasts from '../toast/use-toast'
+import useToasts from '../use-toasts'
 
 interface Props {
   text?: string | string[]
diff --git a/components/file-tree/index.ts b/components/tree/index.ts
similarity index 100%
rename from components/file-tree/index.ts
rename to components/tree/index.ts
diff --git a/components/file-tree/tree-context.ts b/components/tree/tree-context.ts
similarity index 100%
rename from components/file-tree/tree-context.ts
rename to components/tree/tree-context.ts
diff --git a/components/file-tree/tree-file-icon.tsx b/components/tree/tree-file-icon.tsx
similarity index 100%
rename from components/file-tree/tree-file-icon.tsx
rename to components/tree/tree-file-icon.tsx
diff --git a/components/file-tree/tree-file.tsx b/components/tree/tree-file.tsx
similarity index 100%
rename from components/file-tree/tree-file.tsx
rename to components/tree/tree-file.tsx
diff --git a/components/file-tree/tree-folder-icon.tsx b/components/tree/tree-folder-icon.tsx
similarity index 100%
rename from components/file-tree/tree-folder-icon.tsx
rename to components/tree/tree-folder-icon.tsx
diff --git a/components/file-tree/tree-folder.tsx b/components/tree/tree-folder.tsx
similarity index 100%
rename from components/file-tree/tree-folder.tsx
rename to components/tree/tree-folder.tsx
diff --git a/components/file-tree/tree-help.ts b/components/tree/tree-help.ts
similarity index 100%
rename from components/file-tree/tree-help.ts
rename to components/tree/tree-help.ts
diff --git a/components/file-tree/tree-indents.tsx b/components/tree/tree-indents.tsx
similarity index 100%
rename from components/file-tree/tree-indents.tsx
rename to components/tree/tree-indents.tsx
diff --git a/components/file-tree/tree-status-icon.tsx b/components/tree/tree-status-icon.tsx
similarity index 100%
rename from components/file-tree/tree-status-icon.tsx
rename to components/tree/tree-status-icon.tsx
diff --git a/components/file-tree/tree.tsx b/components/tree/tree.tsx
similarity index 97%
rename from components/file-tree/tree.tsx
rename to components/tree/tree.tsx
index e339459..eecf68d 100644
--- a/components/file-tree/tree.tsx
+++ b/components/tree/tree.tsx
@@ -3,7 +3,7 @@ import TreeFile from './tree-file'
 import TreeFolder from './tree-folder'
 import { TreeContext } from './tree-context'
 import { tuple } from '../utils/prop-types'
-import { sortChildren } from '../file-tree/tree-help'
+import { sortChildren } from './/tree-help'
 
 const FileTreeValueType = tuple('directory', 'file')
 
diff --git a/components/use-body-scroll/index.ts b/components/use-body-scroll/index.ts
new file mode 100644
index 0000000..f65551d
--- /dev/null
+++ b/components/use-body-scroll/index.ts
@@ -0,0 +1,3 @@
+import useBodyScroll from './use-body-scroll'
+
+export default useBodyScroll
diff --git a/components/use-click-away/index.ts b/components/use-click-away/index.ts
new file mode 100644
index 0000000..83cf129
--- /dev/null
+++ b/components/use-click-away/index.ts
@@ -0,0 +1,3 @@
+import useClickAway from './use-click-away'
+
+export default useClickAway
diff --git a/components/use-clipboard/index.ts b/components/use-clipboard/index.ts
new file mode 100644
index 0000000..3c09962
--- /dev/null
+++ b/components/use-clipboard/index.ts
@@ -0,0 +1,3 @@
+import useClipboard from './use-clipboard'
+
+export default useClipboard
diff --git a/components/use-current-state/index.ts b/components/use-current-state/index.ts
new file mode 100644
index 0000000..b563a37
--- /dev/null
+++ b/components/use-current-state/index.ts
@@ -0,0 +1,3 @@
+import useCurrentState from './use-current-state'
+
+export default useCurrentState
diff --git a/components/use-media-query/index.ts b/components/use-media-query/index.ts
new file mode 100644
index 0000000..0a6879a
--- /dev/null
+++ b/components/use-media-query/index.ts
@@ -0,0 +1,3 @@
+import useMediaQuery from './use-media-query'
+
+export default useMediaQuery
diff --git a/components/toast/index.ts b/components/use-toasts/index.ts
similarity index 100%
rename from components/toast/index.ts
rename to components/use-toasts/index.ts
diff --git a/components/toast/toast-container.tsx b/components/use-toasts/toast-container.tsx
similarity index 100%
rename from components/toast/toast-container.tsx
rename to components/use-toasts/toast-container.tsx
diff --git a/components/toast/toast-item.tsx b/components/use-toasts/toast-item.tsx
similarity index 100%
rename from components/toast/toast-item.tsx
rename to components/use-toasts/toast-item.tsx
diff --git a/components/toast/use-toast.tsx b/components/use-toasts/use-toast.tsx
similarity index 100%
rename from components/toast/use-toast.tsx
rename to components/use-toasts/use-toast.tsx
diff --git a/components/utils-shared-deprecated/index.ts b/components/utils-shared-deprecated/index.ts
new file mode 100644
index 0000000..1862cea
--- /dev/null
+++ b/components/utils-shared-deprecated/index.ts
@@ -0,0 +1,19 @@
+import useBodyScroll from '../use-body-scroll'
+import useClipboard from '../use-clipboard'
+import useCurrentState from '../use-current-state'
+import useClickAway from '../use-click-away'
+import useMediaQuery from '../use-media-query'
+import useWarning from '../utils/use-warning'
+
+useWarning(
+  'Module "Utils" is deprecated. All hooks are now exported directly from the main module.',
+  'Utils',
+)
+
+export default {
+  useBodyScroll,
+  useClipboard,
+  useCurrentState,
+  useClickAway,
+  useMediaQuery,
+}
diff --git a/components/utils-shared/index.ts b/components/utils-shared/index.ts
deleted file mode 100644
index 0fe42ee..0000000
--- a/components/utils-shared/index.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { default as useBodyScroll } from './use-body-scroll'
-import { default as useClipboard } from './use-clipboard'
-import { default as useCurrentState } from './use-current-state'
-import { default as useClickAway } from './use-click-away'
-import { default as useMediaQuery } from './use-media-query'
-
-export default {
-  useBodyScroll,
-  useClipboard,
-  useCurrentState,
-  useClickAway,
-  useMediaQuery,
-}
diff --git a/components/utils/use-body-scroll.ts b/components/utils/use-body-scroll.ts
index c6a70aa..083bdcd 100644
--- a/components/utils/use-body-scroll.ts
+++ b/components/utils/use-body-scroll.ts
@@ -1,3 +1,3 @@
-import useBodyScroll from '../utils-shared/use-body-scroll'
+import useBodyScroll from '../use-body-scroll'
 
 export default useBodyScroll
diff --git a/components/utils/use-click-away.ts b/components/utils/use-click-away.ts
index cf1e7b1..3f652b3 100644
--- a/components/utils/use-click-away.ts
+++ b/components/utils/use-click-away.ts
@@ -1,3 +1,3 @@
-import { default as useClickAway } from '../utils-shared/use-click-away'
+import { default as useClickAway } from '../use-click-away'
 
 export default useClickAway
diff --git a/components/utils/use-clipboard.ts b/components/utils/use-clipboard.ts
index 360793f..6324fdb 100644
--- a/components/utils/use-clipboard.ts
+++ b/components/utils/use-clipboard.ts
@@ -1,3 +1,3 @@
-import useClipboard from '../utils-shared/use-clipboard'
+import useClipboard from '../use-clipboard'
 
 export default useClipboard
diff --git a/components/utils/use-current-state.ts b/components/utils/use-current-state.ts
index f606510..834f217 100644
--- a/components/utils/use-current-state.ts
+++ b/components/utils/use-current-state.ts
@@ -1,3 +1,3 @@
-import useCurrentState from '../utils-shared/use-current-state'
+import useCurrentState from '../use-current-state'
 
 export default useCurrentState
diff --git a/components/utils/use-zeit-ui-context.ts b/components/utils/use-zeit-ui-context.ts
index a8e5bea..d761cf2 100644
--- a/components/utils/use-zeit-ui-context.ts
+++ b/components/utils/use-zeit-ui-context.ts
@@ -1,5 +1,5 @@
 import React from 'react'
-import { ToastWithID } from '../toast/toast-container'
+import { ToastWithID } from '../use-toasts/toast-container'
 
 export type UpdateToastsFunction<T> = (fn: (toasts: Array<T>) => Array<T>) => any
 
diff --git a/components/zeit-provider-deprecated/index.ts b/components/zeit-provider-deprecated/index.ts
new file mode 100644
index 0000000..0e8b3d9
--- /dev/null
+++ b/components/zeit-provider-deprecated/index.ts
@@ -0,0 +1,9 @@
+import ZeitProvider from '../zeit-provider'
+import useWarning from '../utils/use-warning'
+
+useWarning(
+  'Module "ZEITUIProvider" is deprecated. Use `ZeitProvider` instead of it.',
+  'ZEITUIProvider',
+)
+
+export default ZeitProvider
diff --git a/components/zeit-provider/index.ts b/components/zeit-provider/index.ts
new file mode 100644
index 0000000..cfc46cf
--- /dev/null
+++ b/components/zeit-provider/index.ts
@@ -0,0 +1,3 @@
+import ZeitProvider from './zeit-provider'
+
+export default ZeitProvider
diff --git a/components/providers/zeit-ui-provider.tsx b/components/zeit-provider/zeit-provider.tsx
similarity index 87%
rename from components/providers/zeit-ui-provider.tsx
rename to components/zeit-provider/zeit-provider.tsx
index d46741d..fd63281 100644
--- a/components/providers/zeit-ui-provider.tsx
+++ b/components/zeit-provider/zeit-provider.tsx
@@ -7,13 +7,13 @@ import {
 import ThemeProvider from '../styles/theme-provider'
 import { ThemeParam } from '../styles/theme-provider/theme-provider'
 import useCurrentState from '../utils/use-current-state'
-import ToastContainer, { ToastWithID } from '../toast/toast-container'
+import ToastContainer, { ToastWithID } from '../use-toasts/toast-container'
 
 export interface Props {
   theme?: ThemeParam
 }
 
-const ZEITUIProvider: React.FC<PropsWithChildren<Props>> = ({ theme, children }) => {
+const ZeitProvider: React.FC<PropsWithChildren<Props>> = ({ theme, children }) => {
   const [toasts, setToasts, toastsRef] = useCurrentState<Array<ToastWithID>>([])
   const [toastHovering, setToastHovering] = useState<boolean>(false)
   const updateToasts: UpdateToastsFunction<ToastWithID> = (
@@ -48,4 +48,4 @@ const ZEITUIProvider: React.FC<PropsWithChildren<Props>> = ({ theme, children })
   )
 }
 
-export default ZEITUIProvider
+export default ZeitProvider
diff --git a/package.json b/package.json
index 141d3bd..97ee9a8 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "name": "@zeit-ui/react",
   "version": "1.4.2",
   "main": "dist/index.js",
-  "module": "dist/index.js",
+  "module": "esm/index.js",
   "types": "dist/index.d.ts",
   "unpkg": "dist/index.min.js",
   "license": "MIT",
@@ -31,22 +31,28 @@
     "docs-start": "next start",
     "docs-collect": "node scripts/collect-meta.js",
     "contributor-collect": "node scripts/collect-contributors.js",
-    "clear": "rm -rf dist",
+    "clear": "rm -rf ./dist ./esm",
     "lint": "eslint \"{components,lib}/**/*.{js,ts,tsx}\"",
     "prettier": "prettier --write .",
     "test": "jest --config .jest.config.js --no-cache",
     "test-update": "jest --config .jest.config.js --no-cache --update-snapshot",
     "coverage": "yarn test --coverage",
     "now-build": "yarn run docs-build",
-    "build": "yarn run clear && webpack --config scripts/webpack.config.js && tsc -p ./scripts",
-    "release": "yarn run build && yarn publish --access public --non-interactive"
+    "build:esm": "babel --config-file ./scripts/babel.config.js --extensions \".js,.ts,.tsx\" ./components --out-dir ./esm --ignore \"**/__tests__/**/*,**/*.d.ts\"",
+    "build:webpack": "webpack --config scripts/webpack.config.js",
+    "build:types": "tsc -p ./scripts",
+    "build": "yarn clear && yarn build:esm && yarn build:webpack && yarn build:types",
+    "release": "yarn build && yarn publish --access public --non-interactive"
   },
   "files": [
-    "/dist"
+    "/dist",
+    "/esm"
   ],
   "devDependencies": {
+    "@babel/cli": "^7.8.4",
     "@babel/plugin-transform-runtime": "^7.9.0",
     "@babel/preset-typescript": "^7.8.3",
+    "@babel/runtime": "^7.9.6",
     "@mapbox/rehype-prism": "^0.4.0",
     "@mdx-js/loader": "^1.5.7",
     "@next/mdx": "^9.4.0",
diff --git a/scripts/babel.config.js b/scripts/babel.config.js
new file mode 100644
index 0000000..1c3a952
--- /dev/null
+++ b/scripts/babel.config.js
@@ -0,0 +1,19 @@
+module.exports = {
+  presets: [
+    [
+      '@babel/preset-env',
+      {
+        bugfixes: true,
+        modules: false,
+      },
+    ],
+    '@babel/preset-react',
+    '@babel/preset-typescript',
+  ],
+  plugins: [
+    'styled-jsx/babel',
+    ['@babel/plugin-proposal-object-rest-spread', { loose: true }],
+    ['@babel/plugin-transform-runtime', { useESModules: true }],
+  ],
+  ignore: [/@babel[\\|/]runtime/],
+}
diff --git a/yarn.lock b/yarn.lock
index 763d8f9..0f9a01b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -45,6 +45,22 @@
   dependencies:
     cross-fetch "3.0.4"
 
+"@babel/cli@^7.8.4":
+  version "7.8.4"
+  resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.8.4.tgz#505fb053721a98777b2b175323ea4f090b7d3c1c"
+  integrity sha512-XXLgAm6LBbaNxaGhMAznXXaxtCWfuv6PIDJ9Alsy9JYTOh+j2jJz+L/162kkfU1j/pTSxK1xGmlwI4pdIMkoag==
+  dependencies:
+    commander "^4.0.1"
+    convert-source-map "^1.1.0"
+    fs-readdir-recursive "^1.1.0"
+    glob "^7.0.0"
+    lodash "^4.17.13"
+    make-dir "^2.1.0"
+    slash "^2.0.0"
+    source-map "^0.5.0"
+  optionalDependencies:
+    chokidar "^2.1.8"
+
 "@babel/code-frame@7.8.3", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3":
   version "7.8.3"
   resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e"
@@ -974,7 +990,7 @@
     core-js-pure "^3.0.0"
     regenerator-runtime "^0.13.4"
 
-"@babel/runtime@7.9.6", "@babel/runtime@^7.5.4", "@babel/runtime@^7.8.4":
+"@babel/runtime@7.9.6", "@babel/runtime@^7.5.4", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.6":
   version "7.9.6"
   resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.6.tgz#a9102eb5cadedf3f31d08a9ecf294af7827ea29f"
   integrity sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==
@@ -2881,6 +2897,11 @@ commander@^2.19.0, commander@^2.20.0:
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
   integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
 
+commander@^4.0.1:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
+  integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
+
 commondir@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
@@ -4335,6 +4356,11 @@ fs-minipass@^2.0.0:
   dependencies:
     minipass "^3.0.0"
 
+fs-readdir-recursive@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27"
+  integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==
+
 fs-write-stream-atomic@^1.0.8:
   version "1.0.10"
   resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9"
@@ -4448,7 +4474,7 @@ glob-to-regexp@^0.4.1:
   resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
   integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
 
-glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
+glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
   version "7.1.6"
   resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
   integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
@@ -6063,7 +6089,7 @@ magic-string@^0.25.1:
   dependencies:
     sourcemap-codec "^1.4.4"
 
-make-dir@^2.0.0:
+make-dir@^2.0.0, make-dir@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
   integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==
@@ -8484,6 +8510,11 @@ sisteransi@^1.0.4:
   resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed"
   integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==
 
+slash@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44"
+  integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==
+
 slash@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"


Test patch:
diff --git a/components/styles/__tests__/__snapshots__/baseline.test.tsx.snap b/components/css-baseline/__tests__/__snapshots__/baseline.test.tsx.snap
similarity index 100%
rename from components/styles/__tests__/__snapshots__/baseline.test.tsx.snap
rename to components/css-baseline/__tests__/__snapshots__/baseline.test.tsx.snap
diff --git a/components/styles/__tests__/baseline.test.tsx b/components/css-baseline/__tests__/baseline.test.tsx
similarity index 60%
rename from components/styles/__tests__/baseline.test.tsx
rename to components/css-baseline/__tests__/baseline.test.tsx
index f13afc0..a7ae002 100644
--- a/components/styles/__tests__/baseline.test.tsx
+++ b/components/css-baseline/__tests__/baseline.test.tsx
@@ -1,22 +1,22 @@
 import React from 'react'
 import { render } from 'enzyme'
-import { CSSBaseline, ZEITUIProvider } from 'components'
+import { CssBaseline, ZeitProvider } from 'components'
 
 describe('CSSBaseline', () => {
   it('should render correctly', () => {
     const wrapper = render(
-      <ZEITUIProvider>
-        <CSSBaseline />
-      </ZEITUIProvider>,
+      <ZeitProvider>
+        <CssBaseline />
+      </ZeitProvider>,
     )
     expect(wrapper).toMatchSnapshot()
   })
 
   it('should render dark mode correctly', () => {
     const wrapper = render(
-      <ZEITUIProvider theme={{ type: 'dark' }}>
-        <CSSBaseline />
-      </ZEITUIProvider>,
+      <ZeitProvider theme={{ type: 'dark' }}>
+        <CssBaseline />
+      </ZeitProvider>,
     )
     expect(wrapper).toMatchSnapshot()
   })
diff --git a/components/page/__tests__/index.test.tsx b/components/page/__tests__/index.test.tsx
index d48eafa..cd686bb 100644
--- a/components/page/__tests__/index.test.tsx
+++ b/components/page/__tests__/index.test.tsx
@@ -1,7 +1,7 @@
 import React from 'react'
 import ReactDom from 'react-dom/server'
 import { mount } from 'enzyme'
-import { Page, ZEITUIProvider } from 'components'
+import { Page, ZeitProvider } from 'components'
 
 describe('Page', () => {
   it('should render correctly', () => {
@@ -48,9 +48,9 @@ describe('Page', () => {
 
   it('should disable dot style when in dark mode', () => {
     const wrapper = mount(
-      <ZEITUIProvider theme={{ type: 'dark' }}>
+      <ZeitProvider theme={{ type: 'dark' }}>
         <Page dotBackdrop />
-      </ZEITUIProvider>,
+      </ZeitProvider>,
     )
     expect(wrapper.html()).not.toContain('global(body)')
   })
diff --git a/components/styles/__tests__/theme-provider.test.tsx b/components/styles/__tests__/theme-provider.test.tsx
index 7c65045..c3bf711 100644
--- a/components/styles/__tests__/theme-provider.test.tsx
+++ b/components/styles/__tests__/theme-provider.test.tsx
@@ -2,7 +2,7 @@ import React from 'react'
 import { render, mount } from 'enzyme'
 import { deepMergeObject } from '../theme-provider/theme-provider'
 import DefaultThemes from '../themes/default'
-import { ZEITUIProvider, ZeitUIThemes, Text } from 'components'
+import { ZeitProvider, ZeitUIThemes, Text } from 'components'
 import { DeepPartial } from 'components/utils/types'
 
 describe('ThemeProvider', () => {
@@ -51,9 +51,9 @@ describe('ThemeProvider', () => {
       }
     }
     const wrapper = render(
-      <ZEITUIProvider theme={customFunc}>
+      <ZeitProvider theme={customFunc}>
         <Text type="success">hello</Text>
-      </ZEITUIProvider>,
+      </ZeitProvider>,
     )
     expect(wrapper).toMatchSnapshot()
   })
@@ -62,9 +62,9 @@ describe('ThemeProvider', () => {
     const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {})
     const customFunc = () => 0 as DeepPartial<ZeitUIThemes>
     const wrapper = mount(
-      <ZEITUIProvider theme={customFunc}>
+      <ZeitProvider theme={customFunc}>
         <p>test</p>
-      </ZEITUIProvider>,
+      </ZeitProvider>,
     )
 
     expect(errorSpy).toHaveBeenCalled()
diff --git a/components/tooltip/__test__/index.test.tsx b/components/tooltip/__test__/index.test.tsx
index 8018932..d6018fd 100644
--- a/components/tooltip/__test__/index.test.tsx
+++ b/components/tooltip/__test__/index.test.tsx
@@ -1,6 +1,6 @@
 import React from 'react'
 import { mount, ReactWrapper } from 'enzyme'
-import { Button, Tooltip, ZEITUIProvider } from 'components'
+import { Button, Tooltip, ZeitProvider } from 'components'
 import { nativeEvent, updateWrapper } from 'tests/utils'
 import { act } from 'react-dom/test-utils'
 
@@ -15,9 +15,9 @@ const expectTooltipIsHidden = (wrapper: ReactWrapper) => {
 describe('Tooltip', () => {
   it('should render correctly', async () => {
     const wrapper = mount(
-      <ZEITUIProvider theme={{ type: 'dark' }}>
+      <ZeitProvider theme={{ type: 'dark' }}>
         <Tooltip text={<p id="test">custom-content</p>}>some tips</Tooltip>
-      </ZEITUIProvider>,
+      </ZeitProvider>,
     )
 
     expectTooltipIsHidden(wrapper)
diff --git a/components/file-tree/__tests__/__snapshots__/index.test.tsx.snap b/components/tree/__tests__/__snapshots__/index.test.tsx.snap
similarity index 100%
rename from components/file-tree/__tests__/__snapshots__/index.test.tsx.snap
rename to components/tree/__tests__/__snapshots__/index.test.tsx.snap
diff --git a/components/file-tree/__tests__/index.test.tsx b/components/tree/__tests__/index.test.tsx
similarity index 97%
rename from components/file-tree/__tests__/index.test.tsx
rename to components/tree/__tests__/index.test.tsx
index f213c64..cde7557 100644
--- a/components/file-tree/__tests__/index.test.tsx
+++ b/components/tree/__tests__/index.test.tsx
@@ -2,7 +2,7 @@ import React from 'react'
 import { mount } from 'enzyme'
 import { Tree } from 'components'
 import { nativeEvent } from 'tests/utils'
-import { FileTreeValue } from 'components/file-tree/tree'
+import { FileTreeValue } from 'components/tree/tree'
 
 const mockFiles: Array<FileTreeValue> = [
   {
diff --git a/components/utils-shared/__tests__/body-scroll.test.tsx b/components/use-body-scroll/__tests__/body-scroll.test.tsx
similarity index 99%
rename from components/utils-shared/__tests__/body-scroll.test.tsx
rename to components/use-body-scroll/__tests__/body-scroll.test.tsx
index dfdb7ac..988e9c0 100644
--- a/components/utils-shared/__tests__/body-scroll.test.tsx
+++ b/components/use-body-scroll/__tests__/body-scroll.test.tsx
@@ -1,5 +1,5 @@
 import React, { RefObject } from 'react'
-import useBodyScroll from '../use-body-scroll'
+import { useBodyScroll } from 'components'
 import { act, renderHook } from '@testing-library/react-hooks'
 
 describe('UseBodyScroll', () => {
diff --git a/components/utils-shared/use-body-scroll.ts b/components/use-body-scroll/use-body-scroll.ts
similarity index 100%
rename from components/utils-shared/use-body-scroll.ts
rename to components/use-body-scroll/use-body-scroll.ts
diff --git a/components/utils-shared/__tests__/click-away.test.tsx b/components/use-click-away/__tests__/click-away.test.tsx
similarity index 95%
rename from components/utils-shared/__tests__/click-away.test.tsx
rename to components/use-click-away/__tests__/click-away.test.tsx
index c8f38ad..ef9661f 100644
--- a/components/utils-shared/__tests__/click-away.test.tsx
+++ b/components/use-click-away/__tests__/click-away.test.tsx
@@ -1,6 +1,6 @@
 import React from 'react'
 import { renderHook } from '@testing-library/react-hooks'
-import useClickAway from '../use-click-away'
+import { useClickAway } from 'components'
 
 const simulateNativeClick = (el: Element) => {
   el.dispatchEvent(
diff --git a/components/utils-shared/use-click-away.ts b/components/use-click-away/use-click-away.ts
similarity index 100%
rename from components/utils-shared/use-click-away.ts
rename to components/use-click-away/use-click-away.ts
diff --git a/components/utils-shared/__tests__/clipboard.test.tsx b/components/use-clipboard/__tests__/clipboard.test.tsx
similarity index 97%
rename from components/utils-shared/__tests__/clipboard.test.tsx
rename to components/use-clipboard/__tests__/clipboard.test.tsx
index e5484b5..720f1aa 100644
--- a/components/utils-shared/__tests__/clipboard.test.tsx
+++ b/components/use-clipboard/__tests__/clipboard.test.tsx
@@ -1,4 +1,4 @@
-import useClipboard from '../use-clipboard'
+import { useClipboard } from 'components'
 import { renderHook } from '@testing-library/react-hooks'
 
 describe('UseClipboard', () => {
diff --git a/components/utils-shared/use-clipboard.ts b/components/use-clipboard/use-clipboard.ts
similarity index 100%
rename from components/utils-shared/use-clipboard.ts
rename to components/use-clipboard/use-clipboard.ts
diff --git a/components/utils-shared/__tests__/current-state.test.tsx b/components/use-current-state/__tests__/current-state.test.tsx
similarity index 96%
rename from components/utils-shared/__tests__/current-state.test.tsx
rename to components/use-current-state/__tests__/current-state.test.tsx
index 2114150..8f90c12 100644
--- a/components/utils-shared/__tests__/current-state.test.tsx
+++ b/components/use-current-state/__tests__/current-state.test.tsx
@@ -1,6 +1,6 @@
 import React, { useEffect } from 'react'
 import { mount } from 'enzyme'
-import useCurrentState from '../use-current-state'
+import { useCurrentState } from 'components'
 import { renderHook, act } from '@testing-library/react-hooks'
 
 describe('UseCurrentState', () => {
diff --git a/components/utils-shared/use-current-state.ts b/components/use-current-state/use-current-state.ts
similarity index 100%
rename from components/utils-shared/use-current-state.ts
rename to components/use-current-state/use-current-state.ts
diff --git a/components/utils-shared/__tests__/media-query.test.tsx b/components/use-media-query/__tests__/media-query.test.tsx
similarity index 96%
rename from components/utils-shared/__tests__/media-query.test.tsx
rename to components/use-media-query/__tests__/media-query.test.tsx
index 25a574d..e46fe6a 100644
--- a/components/utils-shared/__tests__/media-query.test.tsx
+++ b/components/use-media-query/__tests__/media-query.test.tsx
@@ -1,8 +1,7 @@
-import { Utils } from 'components'
+import { useMediaQuery } from 'components'
 import { renderHook } from '@testing-library/react-hooks'
 // @ts-ignore
 import mediaQuery from 'css-mediaquery'
-const { useMediaQuery } = Utils
 
 const mediaListMock = (width: number) => {
   ;(window as any).listeners = [] as Array<Function>
diff --git a/components/utils-shared/use-media-query.ts b/components/use-media-query/use-media-query.ts
similarity index 100%
rename from components/utils-shared/use-media-query.ts
rename to components/use-media-query/use-media-query.ts
diff --git a/components/toast/__tests__/__snapshots__/index.test.tsx.snap b/components/use-toasts/__tests__/__snapshots__/index.test.tsx.snap
similarity index 100%
rename from components/toast/__tests__/__snapshots__/index.test.tsx.snap
rename to components/use-toasts/__tests__/__snapshots__/index.test.tsx.snap
diff --git a/components/toast/__tests__/index.test.tsx b/components/use-toasts/__tests__/index.test.tsx
similarity index 92%
rename from components/toast/__tests__/index.test.tsx
rename to components/use-toasts/__tests__/index.test.tsx
index 778f8e5..db32b67 100644
--- a/components/toast/__tests__/index.test.tsx
+++ b/components/use-toasts/__tests__/index.test.tsx
@@ -1,6 +1,6 @@
 import React from 'react'
 import { mount, ReactWrapper } from 'enzyme'
-import { useToasts, ZEITUIProvider } from 'components'
+import { useToasts, ZeitProvider } from 'components'
 import { nativeEvent, updateWrapper } from 'tests/utils'
 
 const MockToast: React.FC<{}> = () => {
@@ -41,9 +41,9 @@ const expectToastIsHidden = (wrapper: ReactWrapper) => {
 describe('UseToast', () => {
   it('should render correctly', async () => {
     const wrapper = mount(
-      <ZEITUIProvider>
+      <ZeitProvider>
         <MockToast />
-      </ZEITUIProvider>,
+      </ZeitProvider>,
     )
 
     expectToastIsHidden(wrapper)
@@ -54,9 +54,9 @@ describe('UseToast', () => {
 
   it('should work with different types', async () => {
     const wrapper = mount(
-      <ZEITUIProvider>
+      <ZeitProvider>
         <MockToast />
-      </ZEITUIProvider>,
+      </ZeitProvider>,
     )
 
     expectToastIsHidden(wrapper)
@@ -68,9 +68,9 @@ describe('UseToast', () => {
 
   it('should close toast', async () => {
     const wrapper = mount(
-      <ZEITUIProvider>
+      <ZeitProvider>
         <MockToast />
-      </ZEITUIProvider>,
+      </ZeitProvider>,
     )
 
     expectToastIsHidden(wrapper)
@@ -85,9 +85,9 @@ describe('UseToast', () => {
 
   it('the removeal should be delayed when hover is triggerd', async () => {
     const wrapper = mount(
-      <ZEITUIProvider>
+      <ZeitProvider>
         <MockToast />
-      </ZEITUIProvider>,
+      </ZeitProvider>,
     )
 
     expectToastIsHidden(wrapper)
@@ -111,9 +111,9 @@ describe('UseToast', () => {
 
   it('should render different actions', async () => {
     const wrapper = mount(
-      <ZEITUIProvider>
+      <ZeitProvider>
         <MockToast />
-      </ZEITUIProvider>,
+      </ZeitProvider>,
     )
     const actions = [
       {
@@ -135,9 +135,9 @@ describe('UseToast', () => {
 
   it('should close toast when action triggered', async () => {
     const wrapper = mount(
-      <ZEITUIProvider>
+      <ZeitProvider>
         <MockToast />
-      </ZEITUIProvider>,
+      </ZeitProvider>,
     )
     const actions = [
       {
@@ -160,9 +160,9 @@ describe('UseToast', () => {
 
   it('should work with multiple toasts', async () => {
     const wrapper = mount(
-      <ZEITUIProvider>
+      <ZeitProvider>
         <MockToast />
-      </ZEITUIProvider>,
+      </ZeitProvider>,
     )
 
     expectToastIsHidden(wrapper)