diff --git a/examples/with-storybook-styled-jsx-scss/.babelrc b/examples/with-storybook-styled-jsx-scss/.babelrc new file mode 100644 index 0000000000000..3eaec7a8b8557 --- /dev/null +++ b/examples/with-storybook-styled-jsx-scss/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + [ + "next/babel", + { + "styled-jsx": { + "plugins": ["styled-jsx-plugin-sass"] + } + } + ] + ] +} diff --git a/examples/with-storybook-styled-jsx-scss/.gitignore b/examples/with-storybook-styled-jsx-scss/.gitignore new file mode 100644 index 0000000000000..a423604f97788 --- /dev/null +++ b/examples/with-storybook-styled-jsx-scss/.gitignore @@ -0,0 +1,37 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local + +# vercel +.vercel + +# Storybook +/storybook-static \ No newline at end of file diff --git a/examples/with-storybook-styled-jsx-scss/.storybook/main.js b/examples/with-storybook-styled-jsx-scss/.storybook/main.js new file mode 100644 index 0000000000000..f041eb8c96a17 --- /dev/null +++ b/examples/with-storybook-styled-jsx-scss/.storybook/main.js @@ -0,0 +1,7 @@ +module.exports = { + stories: [ + '../stories/**/*.stories.mdx', + '../stories/**/*.stories.@(js|jsx|ts|tsx)', + ], + addons: ['@storybook/addon-links', '@storybook/addon-essentials'], +} diff --git a/examples/with-storybook-styled-jsx-scss/.storybook/preview.js b/examples/with-storybook-styled-jsx-scss/.storybook/preview.js new file mode 100644 index 0000000000000..6dd87694930ad --- /dev/null +++ b/examples/with-storybook-styled-jsx-scss/.storybook/preview.js @@ -0,0 +1,3 @@ +export const parameters = { + actions: { argTypesRegex: '^on[A-Z].*' }, +} diff --git a/examples/with-storybook-styled-jsx-scss/README.md b/examples/with-storybook-styled-jsx-scss/README.md new file mode 100644 index 0000000000000..c35210600ec7e --- /dev/null +++ b/examples/with-storybook-styled-jsx-scss/README.md @@ -0,0 +1,45 @@ +# Example app with Storybook setup for SCSS in Styled-jsx + +This example shows Styled-jsx (with SCSS) working for components written in TypeScript rendered both inside and outside of Storybook. + +## Deploy your own + +Deploy the example using [Vercel](https://vercel.com): + +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/vercel/next.js/tree/canary/examples/with-storybook-styled-jsx-scss) + +## How to use + +Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: + +```bash +npx create-next-app --example with-storybook-styled-jsx-scss with-storybook-styled-jsx-scss-app +# or +yarn create next-app --example with-storybook-styled-jsx-scss with-storybook-styled-jsx-scss-app +``` + +### Run Storybook + +```bash +npm run storybook +# or +yarn storybook +``` + +### Build Static Storybook + +```bash +npm run build-storybook +# or +yarn build-storybook +``` + +You can use [Vercel](https://vercel.com/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) to deploy Storybook. Specify `storybook-static` as the output directory. + +## Notes + +This example combines the following examples, with some required extra config added: + +- [with-storybook](https://github.com/vercel/next.js/tree/canary/examples/with-storybook) +- [with-styled-jsx-scss](https://github.com/vercel/next.js/tree/canary/examples/with-styled-jsx-scss) +- [with-typescript](https://github.com/vercel/next.js/tree/canary/examples/with-typescript) diff --git a/examples/with-storybook-styled-jsx-scss/components/Button.tsx b/examples/with-storybook-styled-jsx-scss/components/Button.tsx new file mode 100644 index 0000000000000..87c29a5084834 --- /dev/null +++ b/examples/with-storybook-styled-jsx-scss/components/Button.tsx @@ -0,0 +1,86 @@ +import React from 'react' + +export interface ButtonProps { + /** + * Is this the principal call to action on the page? + */ + primary?: boolean + /** + * What background color to use + */ + backgroundColor?: string + /** + * How large should the button be? + */ + size?: 'small' | 'medium' | 'large' + /** + * Button contents + */ + label: string + /** + * Optional click handler + */ + onClick?: () => void +} + +/** + * Primary UI component for user interaction + */ +export const Button: React.FC = ({ + primary = false, + size = 'medium', + backgroundColor, + label, + ...props +}) => { + const mode = primary + ? 'storybook-button--primary' + : 'storybook-button--secondary' + return ( + <> + + + + ) +} diff --git a/examples/with-storybook-styled-jsx-scss/components/Header.tsx b/examples/with-storybook-styled-jsx-scss/components/Header.tsx new file mode 100644 index 0000000000000..467d84061da7c --- /dev/null +++ b/examples/with-storybook-styled-jsx-scss/components/Header.tsx @@ -0,0 +1,89 @@ +import React from 'react' + +import { Button } from './Button' + +export interface HeaderProps { + user?: {} + onLogin: () => void + onLogout: () => void + onCreateAccount: () => void +} + +export const Header: React.FC = ({ + user, + onLogin, + onLogout, + onCreateAccount, +}) => ( + <> +
+
+
+ + + + + + + +

Acme

+
+
+ {user ? ( +
+
+
+ + +) diff --git a/examples/with-storybook-styled-jsx-scss/components/Page.tsx b/examples/with-storybook-styled-jsx-scss/components/Page.tsx new file mode 100644 index 0000000000000..d99229dc66ddb --- /dev/null +++ b/examples/with-storybook-styled-jsx-scss/components/Page.tsx @@ -0,0 +1,211 @@ +import React from 'react' +import Link from 'next/link' +import { Header } from './Header' + +export interface PageProps { + user?: {} + onLogin: () => void + onLogout: () => void + onCreateAccount: () => void +} + +export const Page: React.FC = ({ + user, + onLogin, + onLogout, + onCreateAccount, +}) => ( + <> +
+
+
+

Example app with Storybook setup for SCSS in Styled-jsx

+

+ This example shows Styled-jsx (with SCSS) working for components + rendered both inside and outside of Storybook. +

+

This example combines the following other examples:

+ +

+ Additionally, the Storybook demo components are moved into the + components directory and their css is refactored into component level + Styled JSX + SCSS. +

+

+ Story files live in their own directory and refer to the components + within /components. +

+

+ The /styles directory contains styles, both global and for the + index.js file. +

+

+ You might also want to check out the{' '} + + Styled JSX documentation + +

+

+ + Improvements welcome! + +

+
+
+

Pages in Storybook

+

+ (From the storybook demo setup) +

+

+ We recommend building UIs with a{' '} + + component-driven + {' '} + process starting with atomic components and ending with pages. +

+

+ Render pages with mock data. This makes it easy to build and review + page states without needing to navigate to them in your app. Here are + some handy patterns for managing page data in Storybook: +

+
    +
  • + Use a higher-level connected component. Storybook helps you compose + such data from the "args" of child component stories +
  • +
  • + Assemble data in the page component from your services. You can mock + these services out using Storybook. +
  • +
+

+ Get a guided tutorial on component-driven development at{' '} + + Learn Storybook + + . Read more in the{' '} + + docs + + . +

+
+ Tip Adjust the width of the canvas with + the{' '} + + + + + + Viewports addon in the toolbar (when viewed in Storybook) +
+
+
+ + +) diff --git a/examples/with-storybook-styled-jsx-scss/next-env.d.ts b/examples/with-storybook-styled-jsx-scss/next-env.d.ts new file mode 100644 index 0000000000000..7b7aa2c7727d8 --- /dev/null +++ b/examples/with-storybook-styled-jsx-scss/next-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/examples/with-storybook-styled-jsx-scss/package.json b/examples/with-storybook-styled-jsx-scss/package.json new file mode 100644 index 0000000000000..0a85565d4b3ce --- /dev/null +++ b/examples/with-storybook-styled-jsx-scss/package.json @@ -0,0 +1,33 @@ +{ + "name": "with-storybook-styled-jsx-scss", + "version": "0.1.0", + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "type-check": "tsc", + "storybook": "start-storybook -p 6006 --no-dll", + "build-storybook": "build-storybook --no-dll" + }, + "dependencies": { + "next": "^10.0.0", + "node-sass": "^4.14.1", + "react": "17.0.1", + "react-dom": "17.0.1", + "styled-jsx-plugin-sass": "^1.0.0" + }, + "license": "MIT", + "devDependencies": { + "@babel/core": "^7.12.3", + "@storybook/addon-actions": "^6.1.11", + "@storybook/addon-essentials": "^6.1.11", + "@storybook/addon-links": "^6.1.11", + "@storybook/react": "^6.1.11", + "@types/node": "^14.14.2", + "@types/react": "^16.9.53", + "@types/react-dom": "^16.9.8", + "babel-loader": "^8.1.0", + "react-is": "^17.0.1", + "typescript": "^4.0.3" + } +} diff --git a/examples/with-storybook-styled-jsx-scss/pages/_app.tsx b/examples/with-storybook-styled-jsx-scss/pages/_app.tsx new file mode 100644 index 0000000000000..27cd5bfc2166f --- /dev/null +++ b/examples/with-storybook-styled-jsx-scss/pages/_app.tsx @@ -0,0 +1,8 @@ +import { AppProps } from 'next/app' +import '../styles/globals.css' + +function MyApp({ Component, pageProps }: AppProps) { + return +} + +export default MyApp diff --git a/examples/with-storybook-styled-jsx-scss/pages/index.tsx b/examples/with-storybook-styled-jsx-scss/pages/index.tsx new file mode 100644 index 0000000000000..cb3bcd9323e9b --- /dev/null +++ b/examples/with-storybook-styled-jsx-scss/pages/index.tsx @@ -0,0 +1,35 @@ +import Head from 'next/head' +import styles from '../styles/Home.module.css' +import { Page } from '../components/Page' + +const demoProps = { + user: {}, + onLogin: () => {}, + onLogout: () => {}, + onCreateAccount: () => {}, +} + +export default function Home() { + return ( +
+ + Create Next App + + + + {/* Including demo props here for example */} + + + +
+ ) +} diff --git a/examples/with-storybook-styled-jsx-scss/public/favicon.ico b/examples/with-storybook-styled-jsx-scss/public/favicon.ico new file mode 100644 index 0000000000000..4965832f2c9b0 Binary files /dev/null and b/examples/with-storybook-styled-jsx-scss/public/favicon.ico differ diff --git a/examples/with-storybook-styled-jsx-scss/public/vercel.svg b/examples/with-storybook-styled-jsx-scss/public/vercel.svg new file mode 100644 index 0000000000000..fbf0e25a651c2 --- /dev/null +++ b/examples/with-storybook-styled-jsx-scss/public/vercel.svg @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/examples/with-storybook-styled-jsx-scss/stories/Button.stories.tsx b/examples/with-storybook-styled-jsx-scss/stories/Button.stories.tsx new file mode 100644 index 0000000000000..3a6504b17d2cb --- /dev/null +++ b/examples/with-storybook-styled-jsx-scss/stories/Button.stories.tsx @@ -0,0 +1,38 @@ +import React from 'react' +// also exported from '@storybook/react' if you can deal with breaking changes in 6.1 +import { Story, Meta } from '@storybook/react/types-6-0' + +import { Button, ButtonProps } from '../components/Button' + +export default { + title: 'Example/Button', + component: Button, + argTypes: { + backgroundColor: { control: 'color' }, + }, +} as Meta + +const Template: Story = (args) =>