diff --git a/.eslintignore b/.eslintignore index 3bbaf943..9b34f21a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -5,5 +5,4 @@ __fixtures_build__/ coverage/ examples/ svgr.now.sh/ -/website/.cache/ -/website/public/ \ No newline at end of file +/website/ \ No newline at end of file diff --git a/resources/svgr-logo.sketch b/resources/svgr-logo.sketch index f88f84a3..03a99385 100644 Binary files a/resources/svgr-logo.sketch and b/resources/svgr-logo.sketch differ diff --git a/website/.eslintrc.js b/website/.eslintrc.js new file mode 100644 index 00000000..2778802c --- /dev/null +++ b/website/.eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + globals: { + __PATH_PREFIX__: true, + }, + extends: `react-app`, +} diff --git a/website/.eslintrc.json b/website/.eslintrc.json deleted file mode 100644 index 81b15e86..00000000 --- a/website/.eslintrc.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "env": { - "browser": true - }, - "rules": { - "import/no-unresolved": "off" - } -} diff --git a/website/.nvmrc b/website/.nvmrc new file mode 100644 index 00000000..da2d3988 --- /dev/null +++ b/website/.nvmrc @@ -0,0 +1 @@ +14 \ No newline at end of file diff --git a/website/gatsby-config.js b/website/gatsby-config.js index 94936e16..8de30bc8 100644 --- a/website/gatsby-config.js +++ b/website/gatsby-config.js @@ -1,27 +1,34 @@ +const path = require('path') + module.exports = { plugins: [ { resolve: 'smooth-doc', options: { name: 'SVGR', - slug: 'svgr', author: 'Greg Bergé', description: 'Transforms SVG into React Components.', siteUrl: 'https://react-svgr.com', - github: 'https://github.com/gregberge/svgr', - menu: ['About', 'Usage', 'Configuring SVGR', 'Advanced'], - nav: [ + githubRepositoryURL: 'https://github.com/gregberge/svgr', + baseDirectory: path.resolve(__dirname, '..'), + navItems: [ { title: 'Playground', url: '/playground/' }, - { title: 'Usage', url: '/docs/getting-started/' }, + { title: 'Docs', url: '/docs/' }, ], - carbonAdUrl: + sections: ['About', 'Usage', 'Configuring SVGR', 'Advanced'], + carbonAdsURL: '//cdn.carbonads.com/carbon.js?serve=CE7I5K3N&placement=react-svgrcom', - googleAnalytics: 'UA-154496255-2', - algoliaDocSearch: { + docSearch: { apiKey: '0c7343afd83c189413499c62c1df6853', indexName: 'smooth-code-svgr', }, }, }, + { + resolve: `gatsby-plugin-google-analytics`, + options: { + trackingId: 'UA-154496255-2', + }, + }, ], } diff --git a/website/gatsby-node.js b/website/gatsby-node.js deleted file mode 100644 index 0fb056b8..00000000 --- a/website/gatsby-node.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports.createPages = ({ actions }) => { - actions.createRedirect({ - fromPath: `/docs/`, - toPath: `/docs/getting-started/`, - redirectInBrowser: true, - }) -} diff --git a/website/src/images/home-logo-dark.png b/website/images/home-logo-dark.png similarity index 100% rename from website/src/images/home-logo-dark.png rename to website/images/home-logo-dark.png diff --git a/website/src/images/home-logo.png b/website/images/home-logo.png similarity index 100% rename from website/src/images/home-logo.png rename to website/images/home-logo.png diff --git a/website/images/logo-manifest.png b/website/images/logo-manifest.png new file mode 100644 index 00000000..72d62a3f Binary files /dev/null and b/website/images/logo-manifest.png differ diff --git a/website/images/logo-nav-dark.svg b/website/images/logo-nav-dark.svg new file mode 100644 index 00000000..f9744cfe --- /dev/null +++ b/website/images/logo-nav-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/images/logo-nav-light.svg b/website/images/logo-nav-light.svg new file mode 100644 index 00000000..94780d60 --- /dev/null +++ b/website/images/logo-nav-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/src/images/social.jpg b/website/images/social.jpg similarity index 100% rename from website/src/images/social.jpg rename to website/images/social.jpg diff --git a/website/package.json b/website/package.json index 77e53aad..de106c40 100644 --- a/website/package.json +++ b/website/package.json @@ -1,29 +1,26 @@ { "private": true, "dependencies": { - "@smooth-ui/core-sc": "^11.1.5", - "@xstyled/styled-components": "^1.17.1", + "@xstyled/styled-components": "^3.0.3", "brace": "^0.11.1", - "final-form": "^4.20.1", - "gatsby": "^2.24.2", - "history": "^5.0.0", - "isomorphic-fetch": "^2.2.1", - "polished": "^3.6.5", - "prismjs": "^1.20.0", - "prop-types": "^15.7.2", - "react": "^16.13.1", - "react-ace": "^9.1.1", - "react-dom": "^16.13.1", - "react-final-form": "^6.5.0", - "react-helmet": "^6.1.0", - "react-icons": "^3.10.0", - "reakit": "^1.0.0-beta.14", - "smooth-doc": "^4.0.3", - "styled-components": "^5.1.1" + "final-form": "^4.20.2", + "gatsby": "^3.13.0", + "gatsby-plugin-google-analytics": "^3.13.0", + "history": "^5.0.1", + "isomorphic-fetch": "^3.0.0", + "react": "^17.0.2", + "react-ace": "^9.4.3", + "react-dom": "^17.0.2", + "react-final-form": "^6.5.3", + "react-icons": "^4.2.0", + "smooth-doc": "^8.0.0" }, "scripts": { "build": "gatsby build && cp _redirects public/", "dev": "gatsby develop", "serve": "gatsby serve" + }, + "devDependencies": { + "eslint-config-react-app": "^6.0.0" } } diff --git a/website/src/pages/docs/cli.mdx b/website/pages/docs/cli.mdx similarity index 98% rename from website/src/pages/docs/cli.mdx rename to website/pages/docs/cli.mdx index 28d592ca..91989559 100644 --- a/website/src/pages/docs/cli.mdx +++ b/website/pages/docs/cli.mdx @@ -1,5 +1,5 @@ --- -menu: Usage +section: Usage title: CLI order: 10 --- @@ -8,6 +8,8 @@ order: 10 SVGR can be run from the CLI. Run it without argument to see the [options](/docs/options). + + ## Install ```bash diff --git a/website/src/pages/docs/configuration-files.mdx b/website/pages/docs/configuration-files.mdx similarity index 97% rename from website/src/pages/docs/configuration-files.mdx rename to website/pages/docs/configuration-files.mdx index 9651e37a..d0450e0f 100644 --- a/website/src/pages/docs/configuration-files.mdx +++ b/website/pages/docs/configuration-files.mdx @@ -1,5 +1,5 @@ --- -menu: Configuring SVGR +section: Configuring SVGR title: Configuration Files order: 20 --- @@ -8,6 +8,8 @@ order: 20 SVGR supports project configuration files for SVGR, SVGO and Prettier. + + ## SVGR SVGR uses [cosmiconfig](https://github.com/davidtheclark/cosmiconfig) for configuration file support. This means you can configure SVGR via: diff --git a/website/src/pages/docs/custom-templates.mdx b/website/pages/docs/custom-templates.mdx similarity index 97% rename from website/src/pages/docs/custom-templates.mdx rename to website/pages/docs/custom-templates.mdx index 14607ef7..f0e16809 100644 --- a/website/src/pages/docs/custom-templates.mdx +++ b/website/pages/docs/custom-templates.mdx @@ -1,5 +1,5 @@ --- -menu: Advanced +section: Advanced title: Custom Templates order: 6 --- @@ -8,6 +8,8 @@ order: 6 Custom templates give you the opportunity to personalize the final generated component by SVGR. In most of case you don't need it, only advanced use-cases require templates. + + ## Custom Component template A custom template takes place in a file that exports a "template function". @@ -116,7 +118,7 @@ The customization is the same, a file that exports a function: const path = require('path') function defaultIndexTemplate(filePaths) { - const exportEntries = filePaths.map(filePath => { + const exportEntries = filePaths.map((filePath) => { const basename = path.basename(filePath, path.extname(filePath)) const exportName = /^\d/.test(basename) ? `Svg${basename}` : basename return `export { default as ${exportName} } from './${basename}'` diff --git a/website/src/pages/docs/custom-transformations.mdx b/website/pages/docs/custom-transformations.mdx similarity index 98% rename from website/src/pages/docs/custom-transformations.mdx rename to website/pages/docs/custom-transformations.mdx index 1f858bec..94c7692d 100644 --- a/website/src/pages/docs/custom-transformations.mdx +++ b/website/pages/docs/custom-transformations.mdx @@ -1,5 +1,5 @@ --- -menu: Advanced +section: Advanced title: Custom transformations order: 10 --- @@ -8,6 +8,8 @@ order: 10 SVGR exposes a simple API but it is extendable, you can extend it to create complex SVG transformations. + + ## Install ```bash diff --git a/website/src/pages/docs/ecosystem.mdx b/website/pages/docs/ecosystem.mdx similarity index 98% rename from website/src/pages/docs/ecosystem.mdx rename to website/pages/docs/ecosystem.mdx index 80732b47..7ede9c6e 100644 --- a/website/src/pages/docs/ecosystem.mdx +++ b/website/pages/docs/ecosystem.mdx @@ -1,5 +1,5 @@ --- -menu: About +section: About title: Ecosystem order: 30 --- @@ -8,6 +8,8 @@ order: 30 This is an incomplete list of awesome things built with svgr. If you have something to share, please submit a PR on [GitHub project](https://github.com/gregberge/svgr). + + ## SVGR inside ✨ - [Create React App](https://facebook.github.io/create-react-app/) diff --git a/website/src/pages/docs/getting-started.mdx b/website/pages/docs/getting-started.mdx similarity index 95% rename from website/src/pages/docs/getting-started.mdx rename to website/pages/docs/getting-started.mdx index 1dfbcefa..9f6e515e 100644 --- a/website/src/pages/docs/getting-started.mdx +++ b/website/pages/docs/getting-started.mdx @@ -1,5 +1,5 @@ --- -menu: Usage +section: Usage title: Getting Started order: 5 --- @@ -8,6 +8,8 @@ order: 5 Follow these steps to start with SVGR. + + **Take an icon.svg**: ```html @@ -55,7 +57,7 @@ npx @svgr/cli --icon --replace-attr-values "#063855=currentColor" icon.svg ```js import * as React from 'react' -const SvgComponent = props => ( +const SvgComponent = (props) => ( diff --git a/website/pages/docs/index.mdx b/website/pages/docs/index.mdx new file mode 100644 index 00000000..585476fe --- /dev/null +++ b/website/pages/docs/index.mdx @@ -0,0 +1,4 @@ +--- +slug: /docs/ +redirect: /docs/getting-started/ +--- diff --git a/website/src/pages/docs/jest.mdx b/website/pages/docs/jest.mdx similarity index 96% rename from website/src/pages/docs/jest.mdx rename to website/pages/docs/jest.mdx index f43ae25f..c5b580e8 100644 --- a/website/src/pages/docs/jest.mdx +++ b/website/pages/docs/jest.mdx @@ -1,5 +1,5 @@ --- -menu: Advanced +section: Advanced title: Testing with Jest order: 4 --- @@ -8,6 +8,8 @@ order: 4 Create a simple mock for the svgr loader and map this in the jest config: + + ## 1. Create a mock file Create a mock file `__mocks__/svgrMock.js`: @@ -20,13 +22,13 @@ export const ReactComponent = 'div' ``` The above mock would support the following import syntaxes: + ```js import logoURL from '../assets/logo.svg' // and import { ReactComponent as Logo } from '../assets/logo.svg' ``` - ## 2. Configure Jest In your `package.json` @@ -46,7 +48,7 @@ module.exports = { moduleNameMapper: { '\\.svg$': '/__mocks__/svgrMock.js', }, -}; +} ``` Your snapshots will include all properties on the icon components, so they will be tested. diff --git a/website/src/pages/docs/motivation.mdx b/website/pages/docs/motivation.mdx similarity index 95% rename from website/src/pages/docs/motivation.mdx rename to website/pages/docs/motivation.mdx index 1206a60d..33cbb1b8 100644 --- a/website/src/pages/docs/motivation.mdx +++ b/website/pages/docs/motivation.mdx @@ -1,5 +1,5 @@ --- -menu: About +section: About title: Motivation order: 10 --- @@ -10,6 +10,8 @@ React supports SVG out of the box, it's simpler, easier and much more powerful to have components instead of SVG files. Wrapped in a React component, your SVG is inlined in the page and you can style it using CSS. + + SVGR differs from other library by its solid architecture. It uses [svg-parser](https://github.com/Rich-Harris/svg-parser) + [Babel](https://babeljs.io) to transform SVG code into JavaScript code. SVGR is included in [create-react-app v2](https://github.com/facebook/create-react-app) and gives you the power to [import SVG directly as a React component](https://facebook.github.io/create-react-app/docs/adding-images-fonts-and-files#adding-svgs). diff --git a/website/src/pages/docs/node-api.mdx b/website/pages/docs/node-api.mdx similarity index 89% rename from website/src/pages/docs/node-api.mdx rename to website/pages/docs/node-api.mdx index 296a596e..86b4a6b4 100644 --- a/website/src/pages/docs/node-api.mdx +++ b/website/pages/docs/node-api.mdx @@ -1,5 +1,5 @@ --- -menu: Usage +section: Usage title: Node API order: 20 --- @@ -8,6 +8,8 @@ order: 20 SVGR exposes a Node API, you can create a custom script or build another tool based on SVGR. + + ## Install ```bash @@ -29,9 +31,11 @@ const svgCode = ` ` -svgr(svgCode, { icon: true }, { componentName: 'MyComponent' }).then(jsCode => { - console.log(jsCode) -}) +svgr(svgCode, { icon: true }, { componentName: 'MyComponent' }).then( + (jsCode) => { + console.log(jsCode) + }, +) ``` Use `svgr.sync(code, config, state)` if you would like to use sync version. @@ -43,7 +47,7 @@ By default `@svgr/core` doesn't include `svgo` and `prettier` plugins, if you wa ```js svgr(svgCode, { plugins: ['@svgr/plugin-svgo', '@svgr/plugin-jsx', '@svgr/plugin-prettier'], -}).then(jsCode => { +}).then((jsCode) => { console.log(jsCode) }) ``` diff --git a/website/src/pages/docs/options.mdx b/website/pages/docs/options.mdx similarity index 99% rename from website/src/pages/docs/options.mdx rename to website/pages/docs/options.mdx index 5f83b311..d9e36b60 100644 --- a/website/src/pages/docs/options.mdx +++ b/website/pages/docs/options.mdx @@ -1,5 +1,5 @@ --- -menu: Configuring SVGR +section: Configuring SVGR title: Options order: 10 --- @@ -9,6 +9,8 @@ order: 10 SVGR ships with a handful of customizable options, usable in both the CLI and API. + + ## Config file Specify a custom config file. diff --git a/website/src/pages/docs/parcel.mdx b/website/pages/docs/parcel.mdx similarity index 93% rename from website/src/pages/docs/parcel.mdx rename to website/pages/docs/parcel.mdx index 1c335a2d..8a63fcbc 100644 --- a/website/src/pages/docs/parcel.mdx +++ b/website/pages/docs/parcel.mdx @@ -1,5 +1,5 @@ --- -menu: Usage +section: Usage title: Parcel order: 45 --- @@ -8,6 +8,8 @@ order: 45 SVGR can be used as a [parcel](https://parceljs.org/) plugin, this way you can import your SVG directly as a React Component. + + ## Install ```bash diff --git a/website/src/pages/docs/rollup.mdx b/website/pages/docs/rollup.mdx similarity index 98% rename from website/src/pages/docs/rollup.mdx rename to website/pages/docs/rollup.mdx index d81c40bd..7c7b8d77 100644 --- a/website/src/pages/docs/rollup.mdx +++ b/website/pages/docs/rollup.mdx @@ -1,5 +1,5 @@ --- -menu: Usage +section: Usage title: Rollup order: 40 --- @@ -8,6 +8,8 @@ order: 40 SVGR can be used as a [rollup](https://rollupjs.org) plugin, this way you can import your SVG directly as a React Component. + + ## Install ```bash diff --git a/website/src/pages/docs/support.mdx b/website/pages/docs/support.mdx similarity index 95% rename from website/src/pages/docs/support.mdx rename to website/pages/docs/support.mdx index 334b3317..583770fd 100644 --- a/website/src/pages/docs/support.mdx +++ b/website/pages/docs/support.mdx @@ -1,5 +1,5 @@ --- -menu: About +section: About title: Support order: 20 --- @@ -10,6 +10,8 @@ order: 20 SVGR is a MIT-licensed open source project. It's an independent project with ongoing development made possible thanks to the support of these awesome [backers](/BACKERS.md). If you'd like to join them, please consider: + + - [Become a backer or sponsor on OpenCollective](https://opencollective.com/svgr). ## Gold Sponsors diff --git a/website/src/pages/docs/testing.mdx b/website/pages/docs/testing.mdx similarity index 92% rename from website/src/pages/docs/testing.mdx rename to website/pages/docs/testing.mdx index 8da252ff..f44c1fef 100644 --- a/website/src/pages/docs/testing.mdx +++ b/website/pages/docs/testing.mdx @@ -1,5 +1,5 @@ --- -menu: Configuring SVGR +section: Configuring SVGR title: Testing order: 30 --- @@ -8,6 +8,8 @@ order: 30 This section helps you to integrate SVGR with your test framework. + + ## Use with Jest Create a mock file: diff --git a/website/src/pages/docs/webpack.mdx b/website/pages/docs/webpack.mdx similarity index 96% rename from website/src/pages/docs/webpack.mdx rename to website/pages/docs/webpack.mdx index c9c97ef3..3ead1d3c 100644 --- a/website/src/pages/docs/webpack.mdx +++ b/website/pages/docs/webpack.mdx @@ -1,5 +1,5 @@ --- -menu: Usage +section: Usage title: Webpack order: 30 --- @@ -8,6 +8,8 @@ order: 30 SVGR can be used as a [webpack](https://webpack.js.org/) loader, this way you can import your SVG directly as a React Component. + + ## Install ```bash @@ -115,15 +117,15 @@ By default, `@svgr/webpack` includes a `babel-loader` with [an optimized configu It is possible to detect the module that requires your SVG using [`Rule.issuer`](https://webpack.js.org/configuration/module/#ruleissuer) in Webpack 5. Using it you can specify two different configurations for JavaScript and the rest of your files. ```js -[ +;[ { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, issuer: /\.[jt]sx?$/, - use: ['babel-loader', '@svgr/webpack', 'url-loader'] + use: ['babel-loader', '@svgr/webpack', 'url-loader'], }, { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, - loader: 'url-loader' + loader: 'url-loader', }, ] ``` diff --git a/website/pages/index.mdx b/website/pages/index.mdx new file mode 100644 index 00000000..4b825411 --- /dev/null +++ b/website/pages/index.mdx @@ -0,0 +1,7 @@ +--- +title: SVGR - Transforms SVG into React Components. +--- + +import { Home } from '../src/components/Home' + + diff --git a/website/pages/playground.mdx b/website/pages/playground.mdx new file mode 100644 index 00000000..852c76c6 --- /dev/null +++ b/website/pages/playground.mdx @@ -0,0 +1,7 @@ +--- +title: SVGR Playground +--- + +import { Playground } from '../src/components/playground/Playground' + + diff --git a/website/src/components/Home.js b/website/src/components/Home.js new file mode 100644 index 00000000..de06c8ae --- /dev/null +++ b/website/src/components/Home.js @@ -0,0 +1,85 @@ +import * as React from 'react' +import { Link } from 'gatsby' +import { + Button, + Hero, + HeroBody, + HeroSection, + HeroTitle, + HeroTeaser, + ScreenContainer, + HeroActionList, + HeroAction, + FeatureSection, + FeatureList, + Feature, + FeatureTitle, + FeatureText, +} from 'smooth-doc/components' +import heroBackgroundURL from './images/hero-bg.png' + +export const Home = () => ( + <> + + + + + Transform SVGs into React components + + A complete tool box to take advantage of using SVGs in your React + applications. + + + + + + + + + + + + + + + + + Powerful + + SVGR handles all type of SVG and transforms it into a React + component. + + + + Universal + + SVGR is everywhere. Available online, in CLI, Node.js, as a webpack + plugin... The list is long. + + + + Customizable + + SVGR is entirely configurable. Use built-in settings or create your + own plugin for advanced use-cases. + + + + Used by everyone + + SVGR is literally everywhere. WordPress, Next.js, Create React App. + You probably already use SVGR in your project. + + + + + +) diff --git a/website/src/components/images/hero-bg.png b/website/src/components/images/hero-bg.png new file mode 100644 index 00000000..cebde6fe Binary files /dev/null and b/website/src/components/images/hero-bg.png differ diff --git a/website/src/components/playground/CheckGroup.js b/website/src/components/playground/CheckGroup.js new file mode 100644 index 00000000..0d9f94b7 --- /dev/null +++ b/website/src/components/playground/CheckGroup.js @@ -0,0 +1,8 @@ +import styled from '@xstyled/styled-components' + +export const CheckGroup = styled.div` + display: grid; + grid-template-columns: min-content 1fr; + align-items: center; + gap: 2; +` diff --git a/website/src/components/playground/DropArea.js b/website/src/components/playground/DropArea.js index d8fad8ef..04dc2444 100644 --- a/website/src/components/playground/DropArea.js +++ b/website/src/components/playground/DropArea.js @@ -1,4 +1,5 @@ import * as React from 'react' +import { useState } from 'react' import styled from '@xstyled/styled-components' const FullWidth = styled.div` @@ -10,7 +11,7 @@ const ChildWrapper = styled(FullWidth)` transition: base; opacity: 1; - &[data-dragging='true'] { + &[data-dragging] { opacity: 0.1; } ` @@ -19,7 +20,7 @@ const Area = styled(FullWidth)` position: relative; ` -const DragHelp = styled(FullWidth)` +const Help = styled(FullWidth)` position: absolute; z-index: 20; pointer-events: none; @@ -31,13 +32,13 @@ const DragHelp = styled(FullWidth)` border-color: light800; ` -function prevent(event) { +const prevent = (event) => { event.preventDefault() event.stopPropagation() } -export function DropArea({ onChange, children }) { - const [dragging, setDragging] = React.useState(false) +export const DropArea = ({ onChange, children }) => { + const [dragging, setDragging] = useState(false) return ( {dragging && ( - -

- - 📄 - {' '} - Drop .svg file here. -

-
+ +

📄 Drop .svg file here.

+
)} - {children} + + {children} + ) } diff --git a/website/src/components/playground/Editor.js b/website/src/components/playground/Editor.js index 381c7487..b4406318 100644 --- a/website/src/components/playground/Editor.js +++ b/website/src/components/playground/Editor.js @@ -9,19 +9,19 @@ import 'brace/theme/tomorrow_night' import 'brace/theme/github' const editorProps = { $blockScrolling: true } +const scrollMargin = [8, 0, 0, 0] export default function Editor(props) { const [colorMode] = useColorMode() const theme = colorMode === 'dark' ? 'tomorrow_night' : 'github' return ( diff --git a/website/src/components/playground/Loading.js b/website/src/components/playground/Loading.js index b4b410e4..4787a2a7 100644 --- a/website/src/components/playground/Loading.js +++ b/website/src/components/playground/Loading.js @@ -1,10 +1,10 @@ import * as React from 'react' -import styled, { keyframes } from 'styled-components' +import styled, { keyframes } from '@xstyled/styled-components' import { graphql, StaticQuery } from 'gatsby' const QUERY = graphql` query Loading { - logo: file(relativePath: { eq: "logo.png" }) { + logo: file(relativePath: { eq: "home-logo.png" }) { childImageSharp { fluid(maxWidth: 800, maxHeight: 800) { ...GatsbyImageSharpFluid @@ -22,16 +22,19 @@ const fadeIn = keyframes` const Loader = styled.div` flex: 1; animation: ${fadeIn} 1000ms ease-in infinite alternate; - background: url(${(p) => p.backgroundImage}) center no-repeat; + background-repeat: no-repeat; + background-position: center; background-size: 30%; ` -export function Loading() { +export const Loading = () => { return ( ( - + )} /> ) diff --git a/website/src/components/playground/Playground.js b/website/src/components/playground/Playground.js index a1badc0d..52bcca36 100644 --- a/website/src/components/playground/Playground.js +++ b/website/src/components/playground/Playground.js @@ -1,20 +1,14 @@ /* eslint-disable jsx-a11y/accessible-emoji */ import * as React from 'react' -import styled, { - Box, - createGlobalStyle, - up, - down, - css, -} from '@xstyled/styled-components' +import { useState, useEffect, lazy, useRef, Suspense } from 'react' +import styled, { x, createGlobalStyle } from '@xstyled/styled-components' import { useDialogState, Dialog as ReakitDialog, DialogBackdrop as ReakitDialogBackdrop, } from 'reakit/Dialog' -import { CarbonAd } from 'smooth-doc/components' +import { CarbonAd } from 'smooth-doc/src/components/CarbonAd' import { lighten } from 'polished' -import { Button } from '@smooth-ui/core-sc' import { Settings } from './Settings' import { svgr } from './modules/svgr' import defaultSvg from './defaultSVG' @@ -24,53 +18,51 @@ import { settings, getInitialState, stateToSettings } from './config/settings' import { useQuery } from './Query' const GlobalStyle = createGlobalStyle` + :root { + color-scheme: light; + } + + .xstyled-color-mode-dark { + color-scheme: dark; + } + .loading { transition: opacity 300ms; opacity: 0.5; } .ace_gutter { - ${down( - 'sm', - css` - width: 5px !important; - `, - )} + @media(max-width: sm) { + width: 5px !important; + } } ` -const PlaygroundContainer = styled.box` - display: flex; - flex-direction: column; - background-color: lighter; - height: calc(100vh - 67px); - - ${up( - 'md', - css` - flex-direction: row; - `, - )} +const Container = styled.div` + display: grid; + grid-template-columns: min-content 1fr; + height: calc(100vh - 50px); + background-color: background; ` -const PlaygroundEditors = styled(Box)` - display: flex; - flex: 1; - flex-direction: row; - background-color: lighter; - height: 50%; +const Editors = styled.div` + display: grid; + grid-template-columns: 1fr 1fr; + + > :first-child { + border-right: 1px solid; + border-color: layout-border; + } +` - ${up( - 'md', - css` - height: 100%; +const EditorContainer = styled.div` + display: grid; + grid-template-rows: min-content 1fr; + transition: opacity 300ms; - > :first-child { - border-right: 1px solid; - border-color: light400; - } - `, - )} + &[data-loading] { + opacity: 0.5; + } ` const FloatingAd = styled.div` @@ -78,37 +70,33 @@ const FloatingAd = styled.div` bottom: 16; right: 16; z-index: 500; - background-color: black !important; - ${down( - 'md', - css` - display: none; - `, - )} + width: 400; ` -const EditorTitle = styled.div` - background-color: light100; - color: light900; - padding: 4 8; +const EditorTitle = styled.h3` + padding: 0 2; font-size: 12; + height: 28; + display: flex; + align-items: center; text-transform: uppercase; font-weight: bold; - border-bottom: 1px solid; - border-color: light400; + border-bottom: 1; + border-color: layout-border; + color: on-background-light; ` const InnerDialog = styled.div` - background-color: light900; - color: lighter; + background-color: background-light; + color: on-background; position: fixed; top: 20%; left: 50%; max-width: 90%; - min-width: 500; + min-width: 600; transform: translateX(-50%); border-radius: 10; - padding: 8; + padding: 5; outline: 0; z-index: 999; box-shadow: 5px 5px rgba(50, 50, 50, 0.4), 10px 10px rgba(50, 50, 50, 0.3), @@ -122,7 +110,7 @@ const InnerBackdrop = styled.div` right: 0; bottom: 0; left: 0; - background-color: light800; + background-color: on-background; opacity: 0.4; z-index: 899; ` @@ -130,30 +118,37 @@ const InnerBackdrop = styled.div` const ThankBody = styled.div` text-align: center; - a { - color: lighter; - text-decoration: underline; - - &:hover { - text-decoration: none; - } - } - h2 { font-size: 18; font-weight: 500; + margin: 2; } ` -const SponsorButton = styled(Button)` +const Link = styled.a` + display: inline-block; + color: inherit; + transition: base; + + &:hover { + text-decoration: none; + transform: translateY(-2px); + } +` + +const SponsorLink = styled.aBox` + display: inline-block; font-weight: 500; - color: white !important; + color: white; text-shadow: 0 0 1px rgba(0, 0, 0, 0.4), 0 0 3px rgba(0, 0, 0, 0.2); min-width: 300; text-decoration: none !important; + padding: 2; + border-radius: 3; + transition: base; &:hover { - color: white !important; + color: white; transform: scale(1.08); } ` @@ -179,82 +174,79 @@ function CopyFeedback(props) {

SVGR is made with ❤️ by{' '} - Greg Bergé - +

Glad it helps!
A few ways to say thank you 👇

- - + ❤️ Sponsor me on GitHub - - - - + + + 💸 Donate on OpenCollective - - - - + + + 😉 Follow me on Twitter - - + +
) } -const Editor = React.lazy(() => import('components/playground/Editor')) +const Editor = lazy(() => import('./Editor')) -function ClientOnly({ children }) { - const [visible, setVisible] = React.useState(false) - React.useEffect(() => { +const ClientOnly = ({ children }) => { + const [visible, setVisible] = useState(false) + useEffect(() => { setVisible(true) - }) - return visible && children + }, []) + return visible ? children : null } export function Playground() { - const [input, setInput] = React.useState(defaultSvg) - const [output, setOutput] = React.useState('') - const [loading, setLoading] = React.useState(false) + const [input, setInput] = useState(defaultSvg) + const [output, setOutput] = useState('') + const [loading, setLoading] = useState(false) const [state, setState] = useQuery(getInitialState) const dialog = useDialogState({ visible: false }) - const [dialogDisplayed, setDialogDisplayed] = React.useState(false) + const dialogDisplayedRef = useRef(false) - const transformIdRef = React.useRef(0) + const transformIdRef = useRef(0) - React.useEffect(() => { + useEffect(() => { async function transform() { if (input.trim() === '') { setOutput('') @@ -291,64 +283,48 @@ export function Playground() { <> - + - }> - - + }> + + SVG input - - - - - - - + + + + { + if (dialogDisplayedRef.current) return + // Detect copy + if ((event.metaKey || event.ctrlKey) && event.key === 'c') { + setTimeout(() => { + dialog.show() + dialogDisplayedRef.current = true + }, 50) + } + }} > JSX output - { - // Detect copy - if ( - (event.metaKey || event.ctrlKey) && - event.key === 'c' - ) { - setTimeout(() => { - dialog.show() - setDialogDisplayed(true) - }, 50) - } - } - } - > - - - - - + + + + - + ) diff --git a/website/src/components/playground/Query.js b/website/src/components/playground/Query.js index 56be40ad..da29bd3b 100644 --- a/website/src/components/playground/Query.js +++ b/website/src/components/playground/Query.js @@ -40,7 +40,10 @@ function useHistory() { function useLocation() { const history = useHistory() const [location, setLocation] = React.useState(getLocation) - React.useEffect(() => history.listen((location) => setLocation(location)), []) + React.useEffect( + () => history.listen((location) => setLocation(location)), + [history], + ) return location } diff --git a/website/src/components/playground/Settings.js b/website/src/components/playground/Settings.js index 7e20391c..4dc8a0f4 100644 --- a/website/src/components/playground/Settings.js +++ b/website/src/components/playground/Settings.js @@ -1,5 +1,5 @@ import * as React from 'react' -import styled, { up, css } from '@xstyled/styled-components' +import styled from '@xstyled/styled-components' import { Form, FormSpy } from 'react-final-form' import { SettingsFieldBoolean } from './SettingsFieldBoolean' import { SettingsGroup } from './SettingsGroup' @@ -7,23 +7,14 @@ import { SettingsFieldString } from './SettingsFieldString' import { SettingsFieldEnum } from './SettingsFieldEnum' import { SettingsFieldInteger } from './SettingsFieldInteger' -const SettingsContainer = styled.div` - width: 100%; +const Container = styled.div` font-size: 14; - background-color: light100; - color: light800; + color: on-background-light; user-select: none; + width: 200; overflow: auto; - max-height: 50%; - - ${up( - 'md', - css` - width: 200px; - height: 100%; - max-height: 100%; - `, - )} + border-right: 1; + border-color: layout-border; ` const getGroupSettings = (group, settings) => @@ -44,7 +35,7 @@ const renderSetting = (setting) => { const noop = () => {} -export function Settings({ settings, initialValues, onChange }) { +export const Settings = ({ settings, initialValues, onChange }) => { return (
{() => ( @@ -53,7 +44,7 @@ export function Settings({ settings, initialValues, onChange }) { subscription={{ values: true }} onChange={({ values }) => onChange(values)} /> - + {getGroupSettings('global', settings).map(renderSetting)} @@ -63,7 +54,7 @@ export function Settings({ settings, initialValues, onChange }) { {getGroupSettings('prettier', settings).map(renderSetting)} - + )}
diff --git a/website/src/components/playground/SettingsFieldBoolean.js b/website/src/components/playground/SettingsFieldBoolean.js index 2bf6657d..af51cb23 100644 --- a/website/src/components/playground/SettingsFieldBoolean.js +++ b/website/src/components/playground/SettingsFieldBoolean.js @@ -1,19 +1,12 @@ import * as React from 'react' -import { Box } from '@xstyled/styled-components' -import { FormCheck, FormCheckLabel } from '@smooth-ui/core-sc' +import { CheckGroup } from './CheckGroup' import { CheckboxControl } from './controls/CheckboxControl' export function SettingsFieldBoolean({ setting }) { return ( - - - - {setting.label} - - + + + + ) } diff --git a/website/src/components/playground/SettingsFieldEnum.js b/website/src/components/playground/SettingsFieldEnum.js index 6fa7a259..a137e059 100644 --- a/website/src/components/playground/SettingsFieldEnum.js +++ b/website/src/components/playground/SettingsFieldEnum.js @@ -1,28 +1,22 @@ import * as React from 'react' -import { Box } from '@xstyled/styled-components' -import { FormField, FormCheck, FormCheckLabel } from '@smooth-ui/core-sc' -import { RadioControl } from 'components/playground/controls/RadioControl' +import { RadioControl } from './controls/RadioControl' import { SmallLabel } from './SmallLabel' +import { CheckGroup } from './CheckGroup' export function SettingsFieldEnum({ setting }) { return ( - - - {setting.label} - {setting.values.map((value) => ( - - - - {value} - - - ))} - - +
+ {setting.label} + {setting.values.map((value) => ( + + + + + ))} +
) } diff --git a/website/src/components/playground/SettingsFieldInteger.js b/website/src/components/playground/SettingsFieldInteger.js index 807c8798..b8206b8a 100644 --- a/website/src/components/playground/SettingsFieldInteger.js +++ b/website/src/components/playground/SettingsFieldInteger.js @@ -1,21 +1,12 @@ import * as React from 'react' -import { Box } from '@xstyled/styled-components' -import { FormField } from '@smooth-ui/core-sc' import { InputControl } from './controls/InputControl' import { SmallLabel } from './SmallLabel' export function SettingsFieldInteger({ setting }) { return ( - - - {setting.label} - - - +
+ {setting.label} + +
) } diff --git a/website/src/components/playground/SettingsFieldString.js b/website/src/components/playground/SettingsFieldString.js index 8f3ba06a..69c022ef 100644 --- a/website/src/components/playground/SettingsFieldString.js +++ b/website/src/components/playground/SettingsFieldString.js @@ -1,21 +1,16 @@ import * as React from 'react' -import { Box } from '@xstyled/styled-components' -import { FormField } from '@smooth-ui/core-sc' -import { TextareaControl } from 'components/playground/controls/TextareaControl' +import { TextareaControl } from './controls/TextareaControl' import { SmallLabel } from './SmallLabel' export function SettingsFieldString({ setting }) { return ( - - - {setting.label} - - - +
+ {setting.label} + +
) } diff --git a/website/src/components/playground/SettingsGroup.js b/website/src/components/playground/SettingsGroup.js index 6cd751b1..498b75eb 100644 --- a/website/src/components/playground/SettingsGroup.js +++ b/website/src/components/playground/SettingsGroup.js @@ -1,21 +1,17 @@ import * as React from 'react' -import styled, { up, css, Box } from '@xstyled/styled-components' +import styled, { up, css } from '@xstyled/styled-components' import { useDisclosureState, DisclosureContent, Disclosure, } from 'reakit/Disclosure' -import { ChevronLeft } from 'components/playground/icons/ChevronLeft' +import { IoChevronBack } from 'react-icons/io5' -const Container = styled.div` - border-right: 1px solid; - border-color: light400; -` - -const Marker = styled(ChevronLeft)` +const Marker = styled(IoChevronBack)` width: 18; height: 18; transition: base; + transition-property: transform; transform: rotate(90deg); ${up( @@ -26,22 +22,24 @@ const Marker = styled(ChevronLeft)` )} ` -const Button = styled.buttonBox` +const Button = styled.button` font-size: 15; - font-weight: bold; - padding: 8 16; + height: 28; + font-weight: 500; background-color: transparent; border: none; color: inherit; cursor: pointer; - transition: base; border: 0; - border-bottom: 1px solid; - border-color: light400; + border-bottom: 1; + border-color: layout-border; appearance: none; margin: 0; - width: 100%; text-align: left; + display: grid; + grid-template-columns: 1fr min-content; + align-items: center; + width: 100%; &[aria-expanded='true'] { ${Marker} { @@ -57,27 +55,27 @@ const Button = styled.buttonBox` ` const Content = styled.div` - border-bottom: 1px solid; - border-color: light400; + display: grid; + gap: 1; + padding: 2; + border-bottom: 1; + border-color: layout-border; ` export function SettingsGroup({ title, children }) { const disclosure = useDisclosureState({ visible: true }) return ( - +
{(DisclosureProps) => ( - )} {children} - +
) } diff --git a/website/src/components/playground/SmallLabel.js b/website/src/components/playground/SmallLabel.js index 0fb45511..79608164 100644 --- a/website/src/components/playground/SmallLabel.js +++ b/website/src/components/playground/SmallLabel.js @@ -1,8 +1,9 @@ -import { FormFieldLabel } from '@smooth-ui/core-sc' import styled from '@xstyled/styled-components' -export const SmallLabel = styled(FormFieldLabel)` +export const SmallLabel = styled.labelBox` text-transform: uppercase; - font-size: 11px; + font-size: 11; font-weight: bold; + display: block; + margin: 2 0; ` diff --git a/website/src/components/playground/config/settings.js b/website/src/components/playground/config/settings.js index e902b45a..75f3f39a 100644 --- a/website/src/components/playground/config/settings.js +++ b/website/src/components/playground/config/settings.js @@ -9,6 +9,21 @@ const parseObject = (value) => const parseJson = (value) => value && JSON.parse(value) +const initialSvgoConfig = JSON.stringify( + { + plugins: [ + { + name: 'preset-default', + params: { overrides: { removeTitle: false } }, + }, + ], + }, + null, + 2, +) + +const initialPrettierConfig = JSON.stringify({ semi: false }, null, 2) + export const settings = [ { label: 'Icon', @@ -89,12 +104,10 @@ export const settings = [ { label: 'Config', name: 'svgoConfig', - placeholder: - '{"plugins":[{"name":"preset-default","params":{"overrides":{"removeTitle":false}}}]}', + placeholder: initialSvgoConfig, type: 'string', group: 'svgo', - default: - '{"plugins":[{"name":"preset-default","params":{"overrides":{"removeTitle":false}}}]}', + default: initialSvgoConfig, transform: parseJson, }, { @@ -107,10 +120,10 @@ export const settings = [ { label: 'Config', name: 'prettierConfig', - placeholder: '{ "semi": false }', + placeholder: initialPrettierConfig, type: 'string', group: 'prettier', - default: '{ "semi": false }', + default: initialPrettierConfig, transform: parseJson, }, ] diff --git a/website/src/components/playground/controls/CheckboxControl.js b/website/src/components/playground/controls/CheckboxControl.js index 9f4c7284..5dfa9c4c 100644 --- a/website/src/components/playground/controls/CheckboxControl.js +++ b/website/src/components/playground/controls/CheckboxControl.js @@ -1,15 +1,7 @@ import * as React from 'react' -import { Field } from 'react-final-form' -import { Checkbox } from '@smooth-ui/core-sc' +import { useField } from 'react-final-form' -export function CheckboxControl(props) { - return ( - ( - - )} - {...props} - /> - ) +export const CheckboxControl = ({ name, value, ...props }) => { + const field = useField(name, { type: 'checkbox', value }) + return } diff --git a/website/src/components/playground/controls/InputControl.js b/website/src/components/playground/controls/InputControl.js index 45ec9272..2795192f 100644 --- a/website/src/components/playground/controls/InputControl.js +++ b/website/src/components/playground/controls/InputControl.js @@ -1,12 +1,7 @@ import * as React from 'react' -import { Field } from 'react-final-form' -import { Input } from '@smooth-ui/core-sc' +import { useField } from 'react-final-form' -export function InputControl(props) { - return ( - } - {...props} - /> - ) +export const InputControl = ({ name, ...props }) => { + const field = useField(name) + return } diff --git a/website/src/components/playground/controls/RadioControl.js b/website/src/components/playground/controls/RadioControl.js index baef9cef..5efcc338 100644 --- a/website/src/components/playground/controls/RadioControl.js +++ b/website/src/components/playground/controls/RadioControl.js @@ -1,13 +1,7 @@ import * as React from 'react' -import { Field } from 'react-final-form' -import { Radio } from '@smooth-ui/core-sc' +import { useField } from 'react-final-form' -export function RadioControl(props) { - return ( - } - {...props} - /> - ) +export const RadioControl = ({ name, value, ...props }) => { + const field = useField(name, { type: 'radio', value }) + return } diff --git a/website/src/components/playground/controls/TextareaControl.js b/website/src/components/playground/controls/TextareaControl.js index cc422028..6f0dbf74 100644 --- a/website/src/components/playground/controls/TextareaControl.js +++ b/website/src/components/playground/controls/TextareaControl.js @@ -1,14 +1,16 @@ import * as React from 'react' -import { Field } from 'react-final-form' -import { Textarea } from '@smooth-ui/core-sc' +import styled from '@xstyled/styled-components' +import { useField } from 'react-final-form' -export function TextareaControl(props) { - return ( - ( -