├── .gitignore ├── .vscode └── settings.json ├── README.md ├── components ├── Callout.tsx ├── Features.tsx └── StackBlitz.tsx ├── custom.css ├── next-env.d.ts ├── next.config.js ├── package.json ├── pages ├── .DS_Store ├── _app.tsx ├── _document.tsx ├── index.tsx ├── meta.json └── patterns │ ├── design-patterns │ ├── factory-pattern.mdx │ ├── introduction.mdx │ ├── meta.json │ ├── module-pattern.mdx │ ├── observer-pattern.mdx │ ├── prototype-pattern.mdx │ ├── proxy-pattern.mdx │ └── singleton-pattern.mdx │ ├── index.mdx │ ├── meta.json │ ├── performance-patterns │ ├── browser-hints.mdx │ ├── dynamic-import.mdx │ ├── import-on-visibility.mdx │ ├── introduction.mdx │ ├── meta.json │ ├── route-based-splitting.mdx │ └── static-import.mdx │ ├── react-patterns │ ├── compound-pattern.mdx │ ├── conpres.mdx │ ├── higher-order-component.mdx │ ├── hooks-pattern.mdx │ ├── meta.json │ ├── provider-pattern.mdx │ └── render-props.mdx │ └── rendering-patterns │ ├── client-side-rendering.mdx │ ├── incremental-static-regeneration.mdx │ ├── introduction.mdx │ ├── meta.json │ ├── server-side-rendering.mdx │ ├── static-rendering.mdx │ └── streaming-ssr.mdx ├── postcss.config.js ├── public ├── .DS_Store ├── design-patterns │ ├── .DS_Store │ ├── module-pattern │ │ └── 1.png │ ├── prototype-pattern │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ └── 4.png │ ├── proxy-pattern │ │ └── 001.png │ └── singleton-pattern │ │ └── 1.png ├── fm-logo.png ├── javascript.svg ├── js.png ├── logo.svg ├── og-image2.png ├── ogimage.png ├── ogimage1.png ├── performance-patterns │ ├── .DS_Store │ ├── browser-hints │ │ ├── prefetch.png │ │ └── preload.png │ └── introduction │ │ ├── 1.png │ │ ├── 2.png │ │ └── 3.png ├── react-state-patterns │ ├── .DS_Store │ ├── compound-pattern │ │ └── 1.png │ ├── hoc-pattern │ │ └── 1.png │ ├── hooks-pattern │ │ ├── prescon.png │ │ └── prescon2.png │ ├── provider-pattern │ │ └── 1.png │ └── render-props-pattern │ │ └── 1.png ├── react.svg └── rendering-patterns │ ├── .DS_Store │ ├── client-side-rendering │ └── 1.png │ ├── server-side-rendering │ └── 1.png │ ├── static-rendering │ ├── .DS_Store │ ├── 1.png │ └── 2.png │ └── streaming-ssr │ └── 1.png ├── robots.txt ├── styles.css ├── tailwind.config.js ├── theme.config.js ├── tsconfig.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .vercel 2 | .next 3 | node_modules -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "grammarly.selectors": [ 3 | { 4 | "language": "mdx", 5 | "scheme": "file" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # JavaScript and React Patterns 3 | 4 | This repo includes the public source code for the [course website](https://javascriptpatterns.vercel.app/patterns) related to the [FrontendMasters workshop on JavaScript and React Patterns](https://frontendmasters.com/courses/tour-js-patterns/). Hope you enjoy the course :) 5 | -------------------------------------------------------------------------------- /components/Callout.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import LightBulbIcon from "@heroicons/react/solid/LightBulbIcon"; 3 | import WarningIcon from "@heroicons/react/solid/ExclamationIcon"; 4 | import ErrorIcon from "@heroicons/react/solid/ExclamationCircleIcon"; 5 | import InformationCircleIcon from "@heroicons/react/solid/InformationCircleIcon"; 6 | import { CheckCircleIcon } from "@heroicons/react/solid"; 7 | 8 | const themes = { 9 | info: { 10 | classes: 11 | "bg-blue-100 text-blue-800 dark:text-blue-300 dark:bg-blue-200 dark:bg-opacity-20", 12 | icon: , 13 | }, 14 | idea: { 15 | classes: 16 | "bg-gray-100 text-gray-800 dark:text-gray-300 dark:bg-gray-200 dark:bg-opacity-20", 17 | icon: , 18 | }, 19 | error: { 20 | classes: 21 | "bg-red-200 text-red-900 dark:text-red-200 dark:bg-red-600 dark:bg-opacity-30", 22 | icon: , 23 | }, 24 | default: { 25 | classes: 26 | "bg-orange-100 text-orange-800 dark:text-orange-300 dark:bg-orange-200 dark:bg-opacity-20", 27 | icon: , 28 | }, 29 | green: { 30 | classes: 31 | "bg-green-100 text-green-800 dark:text-green-300 dark:bg-green-200 dark:bg-opacity-20", 32 | icon: , 33 | }, 34 | }; 35 | 36 | export default function Callout({ children, type = "default", icon }) { 37 | const theme = themes[type] || themes.default; 38 | 39 | return ( 40 |
43 |
50 | {icon || theme.icon} 51 |
52 |
{children}
53 |
54 | ); 55 | } 56 | -------------------------------------------------------------------------------- /components/Features.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | LightningBoltIcon, 3 | PuzzleIcon, 4 | CogIcon, 5 | } from "@heroicons/react/outline"; 6 | 7 | const features = [ 8 | { 9 | name: "Design Patterns", 10 | icon: PuzzleIcon, 11 | }, 12 | { 13 | name: " React Patterns", 14 | icon: () => , 15 | }, 16 | { 17 | name: "Rendering Patterns", 18 | icon: CogIcon, 19 | }, 20 | { 21 | name: "Performance Patterns", 22 | icon: LightningBoltIcon, 23 | }, 24 | ]; 25 | 26 | function Features() { 27 | return ( 28 | <> 29 |
30 | {features.map(({ icon: Icon, ...feature }, i) => ( 31 |
35 |
36 |
42 |
43 |
44 | {feature.name} 45 |
46 |
47 |
48 | ))} 49 |
50 | 51 | ); 52 | } 53 | 54 | export default Features; 55 | -------------------------------------------------------------------------------- /components/StackBlitz.tsx: -------------------------------------------------------------------------------- 1 | export default function StackBlitz(props: { 2 | name: string; 3 | height?: number; 4 | view?: "preview" | "editor", 5 | openFile?: string; 6 | hideExplorer?: boolean; 7 | showDevtools?: boolean; 8 | }) { 9 | 10 | return ( 11 |