diff --git a/.eslintrc b/.eslintrc
index 5f2ddb01b1eb..ddab7e016ee3 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -3,7 +3,8 @@
"airbnb-base",
"next/core-web-vitals",
"eslint:recommended",
- "plugin:prettier/recommended"
+ "plugin:prettier/recommended",
+ "plugin:storybook/recommended"
],
"env": {
"browser": true,
@@ -52,7 +53,11 @@
"overrides": [
// Configuration for TypeScript files
{
- "files": ["**/*.ts", "**/*.tsx", "netlify/*.ts"],
+ "files": [
+ "**/*.ts",
+ "**/*.tsx",
+ "netlify/*.ts"
+ ],
"plugins": [
"@typescript-eslint",
"tailwindcss",
@@ -63,7 +68,8 @@
"plugin:tailwindcss/recommended",
"airbnb-typescript",
"next/core-web-vitals",
- "plugin:prettier/recommended"
+ "plugin:prettier/recommended",
+ "plugin:storybook/recommended"
],
"parserOptions": {
"project": "./tsconfig.json"
@@ -93,7 +99,9 @@
"unused-imports/no-unused-imports": "error",
"unused-imports/no-unused-vars": [
"error",
- { "argsIgnorePattern": "^_" }
+ {
+ "argsIgnorePattern": "^_"
+ }
],
// Variables
"init-declarations": "off",
@@ -192,7 +200,10 @@
"ignoreChainWithDepth": 4
}
],
- "newline-after-var": ["error", "always"],
+ "newline-after-var": [
+ "error",
+ "always"
+ ],
"no-array-constructor": "error",
"no-lonely-if": "error",
"no-mixed-operators": "off",
@@ -294,10 +305,12 @@
}
},
{
- "files": ["components/logos/*"],
+ "files": [
+ "components/logos/*"
+ ],
"rules": {
"max-len": "off"
}
}
]
-}
+}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 1aa4c1d8c8aa..210beb93f6a7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,4 +17,7 @@ meetings.json
cypress/screenshots
cypress/videos
/config/finance/json-data/*
-*.mdx
+/pages/**/*.mdx
+*storybook.log
+/storybook-static/
+coverage
diff --git a/.storybook/main.ts b/.storybook/main.ts
new file mode 100644
index 000000000000..2580c94306b0
--- /dev/null
+++ b/.storybook/main.ts
@@ -0,0 +1,23 @@
+import type { StorybookConfig } from "@storybook/nextjs";
+
+const config: StorybookConfig = {
+ stories: [
+ "../components/**/*.mdx",
+ "../components/**/*.stories.@(js|jsx|mjs|ts|tsx)",
+ ],
+ addons: [
+ "@storybook/addon-onboarding",
+ "@storybook/addon-links",
+ "@storybook/addon-essentials",
+ "@storybook/addon-interactions",
+ ],
+ docs: {
+ defaultName: 'Documentation',
+ },
+ framework: {
+ name: "@storybook/nextjs",
+ options: {},
+ },
+ staticDirs: ["../public"],
+};
+export default config;
diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx
new file mode 100644
index 000000000000..c8e7c3b7f91b
--- /dev/null
+++ b/.storybook/preview.tsx
@@ -0,0 +1,40 @@
+import React from "react";
+import "../styles/globals.css";
+import type { Preview } from "@storybook/react";
+import {
+ Title,
+ Subtitle,
+ Description,
+ Primary,
+ Controls,
+ Stories,
+} from '@storybook/blocks';
+
+const preview: Preview = {
+ tags: ['autodocs'],
+ parameters: {
+ controls: {
+ matchers: {
+ color: /(background|color)$/i,
+ date: /Date$/i,
+ },
+ },
+ docs: {
+ toc: {
+ title: 'Table of contents',
+ },
+ page: () => (
+ <>
+
+
+
+
+
+
+ >
+ )
+ }
+ }
+};
+
+export default preview;
diff --git a/CODEOWNERS b/CODEOWNERS
index c72167304497..e33f9f4e706b 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -8,11 +8,11 @@
* @derberg @akshatnema @magicmatatjahu @anshgoyalevil @mayaleeeee @asyncapi-bot-eve
# All .md files
-*.md @alequetzalli @asyncapi-bot-eve
+*.md @quetzalliwrites @asyncapi-bot-eve
-markdown/blog/*.md @thulieblack @alequetzalli
-markdown/community/*.md @thulieblack @alequetzalli
+markdown/blog/*.md @thulieblack @quetzalliwrites
+markdown/community/*.md @thulieblack @quetzalliwrites
-README.md @alequetzalli @derberg @akshatnema @magicmatatjahu @mayaleeeee @asyncapi-bot-eve
+README.md @quetzalliwrites @derberg @akshatnema @magicmatatjahu @mayaleeeee @asyncapi-bot-eve
#docTriagers: TRohit20 BhaswatiRoy VaishnaviNandakumar J0SAL
#codeTriagers: sambhavgupta0705
diff --git a/README.md b/README.md
index f394899ca9a3..67479c6f7a58 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,8 @@ This repository contains the sources of AsyncAPI website:
- It's powered by [Next.js](https://nextjs.org/),
- It uses [Tailwind](https://tailwindcss.com/) CSS framework,
-- It's build and deployed with [Netlify](https://www.netlify.com/).
+- It's build and deployed with [Netlify](https://www.netlify.com/),
+- It uses [Storybook](https://storybook.js.org/) as a frontend workshop and for dociuenting UI components.
## Requirements
@@ -69,6 +70,14 @@ Use the following tools to set up the project:
7. Access the live development server at [localhost:3000](http://localhost:3000).
+8. To run the storybook locally:
+
+```bash
+ npm run dev:storybook
+```
+
+9. Access the live storybook development server at [localhost:6006](http://localhost:6006).
+
## Compose new blog post
@@ -88,7 +97,7 @@ To spin up a Gitpod codespace, go to http://gitpod.io/#https://github.com/asynca
### Build
-To build a production-ready website, run the following command:
+1. To build a production-ready website, run the following command:
```bash
npm run build
@@ -96,6 +105,14 @@ npm run build
Generated files of the website go to the `.next` folder.
+2. To build the production-ready storybook, run the following command:
+
+```bash
+npm run build:storybook
+```
+
+Generated files of the storybook go to the `storybook-static` folder.
+
### Run locally using Docker
#### Prerequisites:
diff --git a/components/AuthorAvatars.tsx b/components/AuthorAvatars.tsx
index 03bf39dcb447..39928ba2a535 100644
--- a/components/AuthorAvatars.tsx
+++ b/components/AuthorAvatars.tsx
@@ -1,5 +1,7 @@
import React from 'react';
+import Avatar from './Avatar';
+
interface Author {
name: string;
photo: string;
@@ -18,29 +20,14 @@ interface AuthorAvatarsProps {
export default function AuthorAvatars({ authors = [] }: AuthorAvatarsProps) {
return (
<>
- {authors.map((author, index) => {
- const avatar = (
- 0 ? `left- absolute${index * 7} top-0` : `mr- relative${(authors.length - 1) * 7}`}
- z-${(authors.length - 1 - index) * 10} size-10 rounded-full border-2
- border-white object-cover hover:z-50`}
- src={author.photo}
- loading='lazy'
- data-testid='AuthorAvatars-img'
- alt={author.name} // Added alt attribute here
- />
- );
-
- return author.link ? (
-
- {avatar}
-
- ) : (
- {avatar}
- );
- })}
+ {authors.map((author, index) => (
+ 0 ? `left- absolute${index * 7} top-0` : `mr- relative${(authors.length - 1) * 7}`}
+ z-${(authors.length - 1 - index) * 10}`}
+ />
+ ))}
>
);
}
diff --git a/components/Avatar.stories.tsx b/components/Avatar.stories.tsx
new file mode 100644
index 000000000000..71af6ee2d21d
--- /dev/null
+++ b/components/Avatar.stories.tsx
@@ -0,0 +1,20 @@
+import type { Meta, StoryObj } from '@storybook/react';
+
+import Avatar from './Avatar';
+
+const meta: Meta = {
+ title: 'Components/Avatar',
+ component: Avatar
+};
+
+export default meta;
+
+type Story = StoryObj;
+
+export const DefaultAvatar: Story = {
+ args: {
+ name: 'Avatar',
+ link: 'https://www.asyncapi.com/',
+ photo: '/favicon-32x32.png'
+ }
+};
diff --git a/components/Avatar.tsx b/components/Avatar.tsx
new file mode 100644
index 000000000000..b8bb1e557153
--- /dev/null
+++ b/components/Avatar.tsx
@@ -0,0 +1,41 @@
+import React from 'react';
+
+interface AvatarProps {
+ // eslint-disable-next-line prettier/prettier
+
+ /** The name of the avatar. */
+ name: string;
+
+ /** The photo of the avatar. */
+ photo: string;
+
+ /** The link of the avatar. */
+ link?: string;
+
+ /** The class name to be applied to the avatar. */
+ className: string;
+}
+
+/**
+ * This component renders avatar.
+ */
+export default function Avatar({ name, photo, link, className }: AvatarProps) {
+ const avatar = (
+
+ );
+
+ return link ? (
+
+ {avatar}
+
+ ) : (
+ {avatar}
+ );
+}
diff --git a/components/Colors.mdx b/components/Colors.mdx
new file mode 100644
index 000000000000..3fddc2d54521
--- /dev/null
+++ b/components/Colors.mdx
@@ -0,0 +1,220 @@
+import { Meta, ColorPalette, ColorItem } from '@storybook/blocks';
+
+
+
+# Colors
+
+
+
+
+{' '}
+
+
+
+{' '}
+
+
+
+{' '}
+
+
+
+{' '}
+
+
+
+{' '}
+
+
+
+{' '}
+
+
+
+{' '}
+
+
+
+{' '}
+
+
+
+{' '}
+
+
+
+{' '}
+
+
+
+
+
diff --git a/components/MDX/MDX.tsx b/components/MDX/MDX.tsx
index ebdf43a9514a..36cddf7aa6a0 100644
--- a/components/MDX/MDX.tsx
+++ b/components/MDX/MDX.tsx
@@ -27,6 +27,7 @@ import Button from '../buttons/Button';
import ChapterSuggestions from '../buttons/ChapterSuggestions';
import Caption from '../Caption';
import DocsCards from '../docs/DocsCards';
+import Visualizer from '../docs/Visualizer';
import CodeBlock from '../editor/CodeBlock';
import Figure from '../Figure';
import GeneratorInstallation from '../GeneratorInstallation';
@@ -324,7 +325,8 @@ export function getMDXComponents() {
TwitterDMButton,
TwitterVideoEmbed,
TwitterOnAirButton,
- Profiles
+ Profiles,
+ Visualizer
};
}
diff --git a/components/Testimonial.tsx b/components/Testimonial.tsx
index a1dae1c6a28b..5d25a769fc05 100644
--- a/components/Testimonial.tsx
+++ b/components/Testimonial.tsx
@@ -1,4 +1,4 @@
-import Quote from './icons/Quote';
+import IconQuote from './icons/Quote';
import Paragraph from './typography/Paragraph';
interface TestimonialProps {
@@ -30,7 +30,7 @@ export default function Testimonial({