diff --git a/examples/gatsby-plugin/gatsby-config.js b/examples/gatsby-plugin/gatsby-config.js index d972cd592..024b75057 100644 --- a/examples/gatsby-plugin/gatsby-config.js +++ b/examples/gatsby-plugin/gatsby-config.js @@ -1,3 +1,4 @@ +/** @type {import('gatsby').GatsbyConfig} */ module.exports = { plugins: ['gatsby-plugin-mdx', 'gatsby-plugin-theme-ui'], } diff --git a/examples/gatsby-plugin/package.json b/examples/gatsby-plugin/package.json index 807601d82..402de71d8 100644 --- a/examples/gatsby-plugin/package.json +++ b/examples/gatsby-plugin/package.json @@ -6,25 +6,21 @@ "author": "Brent Jackson ", "license": "MIT", "scripts": { + "develop": "gatsby develop", "start": "gatsby develop", "clean": "gatsby clean", "build": "gatsby build" }, "dependencies": { + "@emotion/react": "^11.8.1", + "@emotion/styled": "^11.8.1", "@mdx-js/mdx": "^1.6.22", "@mdx-js/react": "^1.6.22", - "gatsby": "^2.6.3", - "gatsby-plugin-mdx": "^1.6.0", + "gatsby": "^4.7.2", + "gatsby-plugin-mdx": "^3.7.1", "gatsby-plugin-theme-ui": "latest", - "react": "^16.14.0", - "react-dom": "^16.14.0", + "react": "^17.0.2", + "react-dom": "^17.0.2", "theme-ui": "latest" - }, - "devDependencies": { - "@testing-library/react": "^9.1.3", - "husky": ">=4.0.7", - "jest": "^24.8.0", - "lint-staged": "10", - "react-test-renderer": "^17.0.1" } } diff --git a/examples/gatsby-plugin/src/gatsby-plugin-theme-ui/index.js b/examples/gatsby-plugin/src/gatsby-plugin-theme-ui/index.js index 4109ca827..76ba1f9e6 100755 --- a/examples/gatsby-plugin/src/gatsby-plugin-theme-ui/index.js +++ b/examples/gatsby-plugin/src/gatsby-plugin-theme-ui/index.js @@ -1,6 +1,7 @@ const theme = { - useCustomProperties: true, - initialColorMode: 'light', + config: { + initialColorModeName: 'light', + }, colors: { text: '#000', background: '#fff', @@ -26,6 +27,8 @@ const theme = { fontFamily: 'body', fontWeight: 'body', lineHeight: 'body', + py: 2, + px: 4, }, a: { color: 'primary', diff --git a/examples/gatsby/gatsby-config.js b/examples/gatsby/gatsby-config.js index ae6d7b259..fbcac1807 100644 --- a/examples/gatsby/gatsby-config.js +++ b/examples/gatsby/gatsby-config.js @@ -1,3 +1,4 @@ +/** @type {import('gatsby').GatsbyConfig} */ module.exports = { plugins: ['gatsby-plugin-mdx'], } diff --git a/examples/gatsby/package.json b/examples/gatsby/package.json index 4aa05fc7f..79ee38802 100644 --- a/examples/gatsby/package.json +++ b/examples/gatsby/package.json @@ -6,21 +6,24 @@ "author": "Brent Jackson ", "license": "MIT", "scripts": { + "develop": "gatsby develop", "start": "gatsby develop", "clean": "gatsby clean", "build": "gatsby build" }, "dependencies": { + "@emotion/react": "^11.8.1", + "@emotion/styled": "^11.8.1", "@mdx-js/mdx": "^1.6.22", "@mdx-js/react": "^1.6.22", - "gatsby": "^2.6.3", - "gatsby-plugin-mdx": "^1.6.0", - "react": "^16.14.0", - "react-dom": "^16.14.0", + "gatsby": "^4.7.2", + "gatsby-plugin-mdx": "^3.7.1", + "react": "^17.0.2", + "react-dom": "^17.0.2", "theme-ui": "latest" }, "devDependencies": { - "@types/react": "^16.9.55", - "typescript": "^4.4.3" + "@types/react": "^17.0.39", + "typescript": "^4.5.5" } } diff --git a/examples/gatsby/src/layout.tsx b/examples/gatsby/src/layout.tsx index e6790a49c..2c5159cbd 100644 --- a/examples/gatsby/src/layout.tsx +++ b/examples/gatsby/src/layout.tsx @@ -1,11 +1,8 @@ /** @jsx jsx */ import { FC } from 'react' -import { jsx, Box, Container } from 'theme-ui' -import { useBreakpointIndex } from '@theme-ui/match-media' +import { Box, Container } from 'theme-ui' export const Layout: FC = ({ children }) => { - const index = useBreakpointIndex({ defaultIndex: 2 }) - console.log('breakpoint index', index) return ( diff --git a/examples/gatsby/src/pages/index.mdx b/examples/gatsby/src/pages/index.mdx index 33e9fdf08..8d3b77cd2 100644 --- a/examples/gatsby/src/pages/index.mdx +++ b/examples/gatsby/src/pages/index.mdx @@ -6,5 +6,5 @@ export default Layout This page is written in [MDX][] and styled with [Theme UI][]. -[theme ui]: https://theme-ui.now.sh +[theme ui]: https://theme-ui.com/ [mdx]: https://mdxjs.com diff --git a/examples/gatsby/src/theme.ts b/examples/gatsby/src/theme.ts index 2d294ccf7..e1ae920c4 100644 --- a/examples/gatsby/src/theme.ts +++ b/examples/gatsby/src/theme.ts @@ -1,6 +1,9 @@ -import { Theme } from 'theme-ui' +import type { Theme } from 'theme-ui' const theme: Theme = { + config: { + initialColorModeName: 'light', + }, colors: { text: '#000', background: '#fff', diff --git a/examples/next/package.json b/examples/next/package.json index a2b992c0c..7a7281a91 100644 --- a/examples/next/package.json +++ b/examples/next/package.json @@ -16,7 +16,7 @@ "@mdx-js/loader": "^1.6.22", "@mdx-js/react": "^1.6.22", "@next/mdx": "^12.0.7", - "next": "^12.0.9", + "next": "^12.1.0", "react": "^17.0.2", "react-dom": "^17.0.2", "theme-ui": "latest" diff --git a/examples/next/yarn.lock b/examples/next/yarn.lock index d65dbaeae..5eeb4e1fb 100644 --- a/examples/next/yarn.lock +++ b/examples/next/yarn.lock @@ -377,70 +377,70 @@ resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b" integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== -"@next/env@12.0.9": - version "12.0.9" - resolved "https://registry.yarnpkg.com/@next/env/-/env-12.0.9.tgz#4c9e9eef00226145d9629a846b8cc31878e1328c" - integrity sha512-oBlkyDop0Stf7MPIzETGv5r0YT/G/weBrknoPOUTaa5qwOeGjuy6gsOVc/SBtrBkOoBmRpD+fFhQJPvmo1mS+g== +"@next/env@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/env/-/env-12.1.0.tgz#73713399399b34aa5a01771fb73272b55b22c314" + integrity sha512-nrIgY6t17FQ9xxwH3jj0a6EOiQ/WDHUos35Hghtr+SWN/ntHIQ7UpuvSi0vaLzZVHQWaDupKI+liO5vANcDeTQ== "@next/mdx@^12.0.7": version "12.0.7" resolved "https://registry.yarnpkg.com/@next/mdx/-/mdx-12.0.7.tgz#5095198e85a0fe6d3687db9813aa373f185dece8" integrity sha512-yudu/ZxkFznvcQtVKKWkLYVja4kCah/yz09x5tpphr5g+xmaJNA6RylheaORIY8qdgdKRqVXt3hMnpfdH9bBtw== -"@next/swc-android-arm64@12.0.9": - version "12.0.9" - resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.0.9.tgz#2cdbcc1814471044ea0e057b475090d25654833c" - integrity sha512-aVqgsEn5plmUH2X58sjzhHsH/6majucWTMaaBEs7hHO2+GCwCZc7zaLH4XCBMKPES9Yaja8/pYUbvZQE9DqgFw== - -"@next/swc-darwin-arm64@12.0.9": - version "12.0.9" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.0.9.tgz#ea200929d7116de12c6f3b13ff75f9522c2153e3" - integrity sha512-uAgRKm4a2nVdyBiPPJokvmDD1saugOvxljz9ld2ih0CCg5S9vBhqaj3kPGCQBj9hSu3q+Lng2CHnQqG3ga1jzA== - -"@next/swc-darwin-x64@12.0.9": - version "12.0.9" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.0.9.tgz#32800a7a9aff4bfd2038b0bce3657ece8708a87b" - integrity sha512-fDOs2lZIyrAdU18IxMA5orBPn9qLbOdu55gXSTNZOhyRJ8ugtbUAejsK7OL0boJy0CCHPAdVRXm01Mwk8tZ9RQ== - -"@next/swc-linux-arm-gnueabihf@12.0.9": - version "12.0.9" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.0.9.tgz#da012dfb69ad2abc3d4045395581b650048bdd7c" - integrity sha512-/ni0p9DBvATUML9RQ1ycQuf05uOYKdzA6iI8+eRsARjpGbFVUFbge7XPzlj9g2Q9YWgoN8CSjFGnKRlyky5uHA== - -"@next/swc-linux-arm64-gnu@12.0.9": - version "12.0.9" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.0.9.tgz#fe704c0a1cb048ef19d4a24b2c990574c96c933b" - integrity sha512-AphxilJDf95rUxJDHgM9Ww1DaYXZWqTvoKwXeej/0SgSvICcRZrLaFDrkojdXz0Rxr4igX2OdYR1S4/Hj1jWOQ== - -"@next/swc-linux-arm64-musl@12.0.9": - version "12.0.9" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.0.9.tgz#b2bb68940903cd64f7875979ed9907e946dc4f3e" - integrity sha512-K5jbvNNzF3mRjWmPdxP5Bg87i7FHivfBj/L0KJlxpkLSC8sffBJDmB6jtMnI7wiPj9J6vmLkbGtSosln78xAlQ== - -"@next/swc-linux-x64-gnu@12.0.9": - version "12.0.9" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.0.9.tgz#b700ba095551d4f6e830b92d4593a3b6e73bba82" - integrity sha512-bJZ9bkMkQzsY+UyWezEZ77GWQ4TzwKeXdayX3U3+aEkL8k5C6eKBXlidWdrhu0teLmaUXIyWerWrLnJzwGXdfw== - -"@next/swc-linux-x64-musl@12.0.9": - version "12.0.9" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.0.9.tgz#678460266f544b52f1190ef0c3494e436608591e" - integrity sha512-SR9p0R+v1T32DTXPVAXZw31pmJAkSDotC6Afy+mfC0xrEL3pp95R8sGXYAAUCEPkQp0MEeUOVy2LrToe92X7hQ== - -"@next/swc-win32-arm64-msvc@12.0.9": - version "12.0.9" - resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.0.9.tgz#f70e5bd0821ca168aeef117e51ab870265ceeeb1" - integrity sha512-mzQ1A8vfHhJrvEy5KJZGZWEByXthyKfWofvFaf+oo/5nJl/0Bz1ODP2ajSmbLG++77Eo2AROgbm9pkW1ucvG2A== - -"@next/swc-win32-ia32-msvc@12.0.9": - version "12.0.9" - resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.0.9.tgz#0b853793754642cde9f9099087d4a86b6a99a24d" - integrity sha512-MpD2vj1zjo1u3J3wiz3pEKse19Etz+P0GL6XfQkB/9a84vJQ1JWMaWBjmIdivzZv718Il2pRSSx8hymwPfguYQ== - -"@next/swc-win32-x64-msvc@12.0.9": - version "12.0.9" - resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.0.9.tgz#f7d3b59000082cf65c84fdc61930b708aa5446e5" - integrity sha512-1c/sxp/4Qz4F6rCxiYqAnrmghCOFt5hHZ9Kd+rXFW5Mqev4C4XDOUMHdBH55HgnJZqngYhOE0r/XNkCtsIojig== +"@next/swc-android-arm64@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.1.0.tgz#865ba3a9afc204ff2bdeea49dd64d58705007a39" + integrity sha512-/280MLdZe0W03stA69iL+v6I+J1ascrQ6FrXBlXGCsGzrfMaGr7fskMa0T5AhQIVQD4nA/46QQWxG//DYuFBcA== + +"@next/swc-darwin-arm64@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.0.tgz#08e8b411b8accd095009ed12efbc2f1d4d547135" + integrity sha512-R8vcXE2/iONJ1Unf5Ptqjk6LRW3bggH+8drNkkzH4FLEQkHtELhvcmJwkXcuipyQCsIakldAXhRbZmm3YN1vXg== + +"@next/swc-darwin-x64@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.0.tgz#fcd684497a76e8feaca88db3c394480ff0b007cd" + integrity sha512-ieAz0/J0PhmbZBB8+EA/JGdhRHBogF8BWaeqR7hwveb6SYEIJaDNQy0I+ZN8gF8hLj63bEDxJAs/cEhdnTq+ug== + +"@next/swc-linux-arm-gnueabihf@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.0.tgz#9ec6380a27938a5799aaa6035c205b3c478468a7" + integrity sha512-njUd9hpl6o6A5d08dC0cKAgXKCzm5fFtgGe6i0eko8IAdtAPbtHxtpre3VeSxdZvuGFh+hb0REySQP9T1ttkog== + +"@next/swc-linux-arm64-gnu@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.0.tgz#7f4196dff1049cea479607c75b81033ae2dbd093" + integrity sha512-OqangJLkRxVxMhDtcb7Qn1xjzFA3s50EIxY7mljbSCLybU+sByPaWAHY4px97ieOlr2y4S0xdPKkQ3BCAwyo6Q== + +"@next/swc-linux-arm64-musl@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.0.tgz#b445f767569cdc2dddee785ca495e1a88c025566" + integrity sha512-hB8cLSt4GdmOpcwRe2UzI5UWn6HHO/vLkr5OTuNvCJ5xGDwpPXelVkYW/0+C3g5axbDW2Tym4S+MQCkkH9QfWA== + +"@next/swc-linux-x64-gnu@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.0.tgz#67610e9be4fbc987de7535f1bcb17e45fe12f90e" + integrity sha512-OKO4R/digvrVuweSw/uBM4nSdyzsBV5EwkUeeG4KVpkIZEe64ZwRpnFB65bC6hGwxIBnTv5NMSnJ+0K/WmG78A== + +"@next/swc-linux-x64-musl@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.0.tgz#ea19a23db08a9f2e34ac30401f774cf7d1669d31" + integrity sha512-JohhgAHZvOD3rQY7tlp7NlmvtvYHBYgY0x5ZCecUT6eCCcl9lv6iV3nfu82ErkxNk1H893fqH0FUpznZ/H3pSw== + +"@next/swc-win32-arm64-msvc@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.0.tgz#eadf054fc412085659b98e145435bbba200b5283" + integrity sha512-T/3gIE6QEfKIJ4dmJk75v9hhNiYZhQYAoYm4iVo1TgcsuaKLFa+zMPh4056AHiG6n9tn2UQ1CFE8EoybEsqsSw== + +"@next/swc-win32-ia32-msvc@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.0.tgz#68faeae10c89f698bf9d28759172b74c9c21bda1" + integrity sha512-iwnKgHJdqhIW19H9PRPM9j55V6RdcOo6rX+5imx832BCWzkDbyomWnlzBfr6ByUYfhohb8QuH4hSGEikpPqI0Q== + +"@next/swc-win32-x64-msvc@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.1.0.tgz#d27e7e76c87a460a4da99c5bfdb1618dcd6cd064" + integrity sha512-aBvcbMwuanDH4EMrL2TthNJy+4nP59Bimn8egqv6GHMVj0a44cU6Au4PjOhLNqEh9l+IpRGBqMTzec94UdC5xg== "@styled-system/background@^5.1.2": version "5.1.2" @@ -1124,28 +1124,28 @@ nanoid@^3.1.30: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== -next@^12.0.9: - version "12.0.9" - resolved "https://registry.yarnpkg.com/next/-/next-12.0.9.tgz#4eb3006b63bb866f5c2918ca0003e98f4259e063" - integrity sha512-omfYqoR/DvbdOIJ6SS1unKJ4mGIxUPs0RPa7wr/Mft22OCKgJhuG+aI9KFYi5ZJBwoFQk1vqaMKpWz5qr+dN0Q== +next@^12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/next/-/next-12.1.0.tgz#c33d753b644be92fc58e06e5a214f143da61dd5d" + integrity sha512-s885kWvnIlxsUFHq9UGyIyLiuD0G3BUC/xrH0CEnH5lHEWkwQcHOORgbDF0hbrW9vr/7am4ETfX4A7M6DjrE7Q== dependencies: - "@next/env" "12.0.9" + "@next/env" "12.1.0" caniuse-lite "^1.0.30001283" postcss "8.4.5" styled-jsx "5.0.0" use-subscription "1.5.1" optionalDependencies: - "@next/swc-android-arm64" "12.0.9" - "@next/swc-darwin-arm64" "12.0.9" - "@next/swc-darwin-x64" "12.0.9" - "@next/swc-linux-arm-gnueabihf" "12.0.9" - "@next/swc-linux-arm64-gnu" "12.0.9" - "@next/swc-linux-arm64-musl" "12.0.9" - "@next/swc-linux-x64-gnu" "12.0.9" - "@next/swc-linux-x64-musl" "12.0.9" - "@next/swc-win32-arm64-msvc" "12.0.9" - "@next/swc-win32-ia32-msvc" "12.0.9" - "@next/swc-win32-x64-msvc" "12.0.9" + "@next/swc-android-arm64" "12.1.0" + "@next/swc-darwin-arm64" "12.1.0" + "@next/swc-darwin-x64" "12.1.0" + "@next/swc-linux-arm-gnueabihf" "12.1.0" + "@next/swc-linux-arm64-gnu" "12.1.0" + "@next/swc-linux-arm64-musl" "12.1.0" + "@next/swc-linux-x64-gnu" "12.1.0" + "@next/swc-linux-x64-musl" "12.1.0" + "@next/swc-win32-arm64-msvc" "12.1.0" + "@next/swc-win32-ia32-msvc" "12.1.0" + "@next/swc-win32-x64-msvc" "12.1.0" object-assign@^4.1.1: version "4.1.1" diff --git a/package.json b/package.json index 9b67836a4..3859e6777 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "jest-canvas-mock": "^2.3.1", "jest-mock-console": "^1.0.1", "lerna": "^4.0.0", - "lint-staged": "12.1.2", + "lint-staged": "12.3.2", "postinstall-postinstall": "^2.1.0", "prettier": "^2.2.1", "react-test-renderer": "^17.0.2", diff --git a/packages/color-modes/src/index.tsx b/packages/color-modes/src/index.tsx index 7600f85a6..59873c6a9 100644 --- a/packages/color-modes/src/index.tsx +++ b/packages/color-modes/src/index.tsx @@ -164,6 +164,24 @@ const TopLevelColorModeProvider = ({ ' and cannot reference a key in `theme.colors.modes`.' ) } + const allColorKeys: Array = [] + const flattenKeys = (obj: Record) => { + Object.keys(obj).forEach((key) => { + allColorKeys.push(key) + if (typeof obj[key] === 'object') { + flattenKeys(obj[key]) + } + }) + return allColorKeys + } + flattenKeys(outerTheme.colors ?? {}).forEach((color) => { + if (color !== color.trim()) { + console.warn( + `[theme-ui] Key \`${color}\` in theme.colors contains leading/trailing ` + + 'whitespace, which can cause bugs in your project.' + ) + } + }) } const newTheme = useThemeWithAppliedColorMode({ colorMode, outerTheme }) diff --git a/packages/color-modes/test/index.tsx b/packages/color-modes/test/index.tsx index 6a46aacc5..91e9852ca 100644 --- a/packages/color-modes/test/index.tsx +++ b/packages/color-modes/test/index.tsx @@ -541,6 +541,30 @@ test('warns when initialColorModeName matches a key in theme.colors.modes', () = restore() }) +test('warns when a key in theme.colors.modes has leading/trailing whitespace', () => { + const restore = mockConsole() + render( + + + + ) + expect(console.warn).toBeCalled() + restore() +}) + test('does not warn in production', () => { const restore = mockConsole() const init = process.env.NODE_ENV @@ -557,7 +581,7 @@ test('does not warn in production', () => { modes: { dark: { text: '#fff', - background: '#000', + ' background': '#000', }, }, }, diff --git a/packages/custom-properties/src/index.ts b/packages/custom-properties/src/index.ts index 1f40b6b7f..a5bafe1d0 100644 --- a/packages/custom-properties/src/index.ts +++ b/packages/custom-properties/src/index.ts @@ -1,6 +1,10 @@ import pluralize from 'pluralize' import { Theme } from '@theme-ui/css' +// Simplified validator based on spec https://www.w3.org/TR/CSS22/syndata.html#value-def-identifier +// Does not check for "cannot start with a digit, two hyphens, or a hyphen followed by a digit" +const keyValidator = /^[A-z0-9][\w-]*$/ + interface CustomProperties { [key: string]: string | number } @@ -12,6 +16,16 @@ export default function makeCustomProperties(theme: Theme, prefix?: string) { Object.entries(object).forEach(([key, value]) => { let formattedKey = pluralize(key, 1) + if ( + process.env.NODE_ENV !== 'production' && + !keyValidator.test(formattedKey) + ) { + console.warn( + `[theme-ui] Theme key "${value}" found will produce an invalid CSS custom property. ` + + 'Keys must only contain the following: A-Z, a-z, 0-9, hyphen, underscore.' + ) + } + if (prefix && !previousKey) { formattedKey = `${prefix}-${formattedKey}` } diff --git a/packages/custom-properties/test/test.js b/packages/custom-properties/test/test.js index 392a29c51..5f3523257 100644 --- a/packages/custom-properties/test/test.js +++ b/packages/custom-properties/test/test.js @@ -1,4 +1,5 @@ import toCustomProperties from '../src' +import mockConsole from 'jest-mock-console' const theme = { colors: { @@ -18,8 +19,7 @@ const theme = { }, }, fonts: { - body: - 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif', + body: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif', heading: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif', monospace: 'Menlo, monospace', @@ -35,9 +35,11 @@ const theme = { } it('transforms a theme config to CSS custom properties', () => { + mockConsole() const result = toCustomProperties(theme) expect(result).toMatchSnapshot() + expect(console.warn).toHaveBeenCalledTimes(0) }) it('transforms a theme config to CSS custom properties with prefix', () => { @@ -45,3 +47,13 @@ it('transforms a theme config to CSS custom properties with prefix', () => { expect(result).toMatchSnapshot() }) + +it('warns on invalid CSS custom property key', () => { + mockConsole() + toCustomProperties({ sizes: { '1/4': 1 / 4, '1/2': 1 / 2 } }) + + expect(console.warn).toHaveBeenCalledTimes(2) + expect(console.warn).toHaveBeenLastCalledWith( + '[theme-ui] Theme key "0.5" found will produce an invalid CSS custom property. Keys must only contain the following: A-Z, a-z, 0-9, hyphen, underscore.' + ) +}) diff --git a/packages/docs/package.json b/packages/docs/package.json index 74ab20b6b..1d5d68874 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -92,6 +92,6 @@ "@babel/register": "^7.8.6" }, "resolutions": { - "@emotion/react": "11.7.1" + "@emotion/react": "11.8.1" } } diff --git a/packages/docs/src/components/components.mdx b/packages/docs/src/components/components.mdx new file mode 100644 index 000000000..07e6900f5 --- /dev/null +++ b/packages/docs/src/components/components.mdx @@ -0,0 +1,232 @@ + + +import { useTheme } from '@emotion/react' +import { + Message, + NavLink, + Divider, + Container, + Box, + Button, + Card, + Text, + Paragraph, + Image, + Slider, + Label, + Flex, + Checkbox, + Select, + Textarea, + Radio, + Input, + Link, + Progress, + Badge, + Alert, +} from 'theme-ui' + +export const Radii = () => { + const theme = useTheme() + if (typeof theme.radii === 'object') { + return ( + + +

Borders

+ + {Object.keys(theme.radii).map((key) => ( + + {key} + + ))} + +
+ ) + } + return null +} + +# Example components + + + +export const Buttons = () => { + const theme = useTheme() + if (typeof theme.buttons === 'object') { + return ( + + +

Buttons

+ + {Object.keys(theme.buttons).map((key) => ( + + ))} + +
+ ) + } + return null +} + + + +--- + +## Form elements + + e.preventDefault()} + sx={{ width: '100%', maxWidth: '500px' }}> + + + + + + + + + + +