diff --git a/.all-contributorsrc b/.all-contributorsrc index 64e7fe6bdf7..8f3a49ee524 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -555,6 +555,15 @@ "contributions": [ "doc" ] + }, + { + "login": "raj17ce", + "name": "Raj Patel", + "avatar_url": "https://avatars.githubusercontent.com/u/116947399?v=4", + "profile": "https://github.com/raj17ce", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/.github/workflows/if-nodejs-pr-testing.yml b/.github/workflows/if-nodejs-pr-testing.yml index 2154143339c..c50814a4a17 100644 --- a/.github/workflows/if-nodejs-pr-testing.yml +++ b/.github/workflows/if-nodejs-pr-testing.yml @@ -60,6 +60,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: "${{ steps.nodeversion.outputs.version }}" + - name: Install dependencies run: npm ci - if: steps.packagejson.outputs.exists == 'true' @@ -72,3 +73,12 @@ jobs: name: Run release assets generation to make sure PR does not break it shell: bash run: npm run generate:assets --if-present + + - if: steps.packagejson.outputs.exists == 'true' + name: Upload Coverage to Codecov + uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 + with: + fail_ci_if_error: true + files: ./coverage/lcov.info + token: ${{ secrets.CODECOV_TOKEN }} + verbose: true diff --git a/.github/workflows/netlify-edge-functions-test.yml b/.github/workflows/netlify-edge-functions-test.yml new file mode 100644 index 00000000000..adc110d68dd --- /dev/null +++ b/.github/workflows/netlify-edge-functions-test.yml @@ -0,0 +1,21 @@ +name: Run tests for netlify edge-functions + +on: + pull_request: + types: [opened, reopened, synchronize, ready_for_review] + +jobs: + netlify-tests: + strategy: + matrix: + deno-version: [1.46.0] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup Deno + uses: denoland/setup-deno@3a041055d2e2068f6e2c59904ee0ec2dfa9d9665 + with: + deno-version: ${{ matrix.deno-version }} + - name: Test with Deno + run: deno test --allow-env --trace-ops netlify/**/*.test.ts + diff --git a/.gitignore b/.gitignore index 210beb93f6a..0a69d4de26c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ cypress/videos *storybook.log /storybook-static/ coverage +deno.lock diff --git a/.storybook/AsyncAPIStorybookTheme.ts b/.storybook/AsyncAPIStorybookTheme.ts new file mode 100644 index 00000000000..9213d73cd95 --- /dev/null +++ b/.storybook/AsyncAPIStorybookTheme.ts @@ -0,0 +1,42 @@ +import { create } from '@storybook/theming/create'; + +export default create({ + // Brand Information + brandTitle: 'AsyncAPI Initiative', + brandUrl: 'https://www.asyncapi.com/', + brandImage: 'img/logos/asyncapi-horizontal-white-logo.svg', + brandTarget: '_blank', + + // Typography + fontBase: '"Work Sans", sans-serif', + fontCode: 'monospace', + + + // Themes + base: 'dark', + + /* -- FULL THEME IS NOT BEING USED DUE TO LACK OF STORYBOOK SUPPORT FOR CUSTOMIZING THE SETTINGS & ACTIONS BAR BG/TEXTCOLOR INDEPENDENTLY. -- + colorPrimary: '#47BCEE', + colorSecondary: '#8851FB', + + // UI + appBg: '#1b1130', + appContentBg: '#ffffff', + appPreviewBg: '#ffffff', + appBorderColor: '#dfe6ea', + appBorderRadius: 4, + + // Text colors + textColor: '#ffffff', + textInverseColor: '#ffffff', + textMutedColor: '#5c6870', + inputTextColor: '#2e3438', + + // Toolbar + barTextColor: '#9E9E9E', + + // Toolbar default and active colors + booleanBg: '#dfe6ea', + booleanSelectedBg: '#8851FB' + */ +}); diff --git a/.storybook/manager.ts b/.storybook/manager.ts new file mode 100644 index 00000000000..cc32cf0e2e4 --- /dev/null +++ b/.storybook/manager.ts @@ -0,0 +1,6 @@ +import { addons } from '@storybook/manager-api'; +import AsyncAPIStorybookTheme from './AsyncAPIStorybookTheme'; + +addons.setConfig({ + theme: AsyncAPIStorybookTheme, +}); diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index c8e7c3b7f91..29ac0d62998 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -1,6 +1,7 @@ import React from "react"; import "../styles/globals.css"; import type { Preview } from "@storybook/react"; +import { themes } from '@storybook/theming'; import { Title, Subtitle, @@ -20,6 +21,7 @@ const preview: Preview = { }, }, docs: { + theme: themes.light, toc: { title: 'Table of contents', }, diff --git a/CODEOWNERS b/CODEOWNERS index e33f9f4e706..ac1c2868806 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -15,4 +15,4 @@ markdown/community/*.md @thulieblack @quetzalliwrites README.md @quetzalliwrites @derberg @akshatnema @magicmatatjahu @mayaleeeee @asyncapi-bot-eve #docTriagers: TRohit20 BhaswatiRoy VaishnaviNandakumar J0SAL -#codeTriagers: sambhavgupta0705 +#codeTriagers: sambhavgupta0705 devilkiller-ag diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1334921c281..6a20e1c3395 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,13 +1,20 @@ -# Contributing to AsyncAPI -We love your input! We want to make contributing to this project as easy and transparent as possible. +# Welcome to AsyncAPI -## Contribution recogniton +Welcome to our open-source project! We're excited to have you join our community and contribute to making our project better. Please follow this guide to ensure a smooth contribution process and maintain the quality of our codebase and documentation. -We use [All Contributors](https://allcontributors.org/docs/en/specification) specification to handle recognitions. For more details read [this](https://github.com/asyncapi/community/blob/master/recognize-contributors.md) document. +We encourage all contributors to familiarize themselves with these guidelines and actively participate in the project's growth. If you have any questions or need assistance, don't hesitate to contact the project maintainers or community members. -## Summary of the contribution flow +## Code of Conduct + +AsyncAPI has adopted a Code of Conduct (CoC) that we expect project participants to adhere to. Please [read the full CoC text](./CODE_OF_CONDUCT.md) to understand the expected behavior. + +## Our Development Process + +We use Github to host code, track issues, feature requests, and accept pull requests. + +## Contribution flow -The following is a summary of the ideal contribution flow. Please, note that Pull Requests can also be rejected by the maintainers when appropriate. +The following is a summary of the ideal contribution flow. ``` ┌───────────────────────┐ @@ -36,44 +43,70 @@ The following is a summary of the ideal contribution flow. Please, note that Pul └───────────────────────┘ ``` -## Code of Conduct -AsyncAPI has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full text](./CODE_OF_CONDUCT.md) so that you can understand what sort of behaviour is expected. +Issues and pull requests without activity from the creator within 14 days will be automatically closed by a triager or committer. However, closure does not mean rejection. If you wish to revisit a closed issue or pull a request, open a new one referencing the closed item. -## Our Development Process -We use Github to host code, to track issues and feature requests, as well as accept pull requests. +Issues and pull requests without activity from the triager or committer within 14 days may occur for many reasons. The creator may use the `/ptal` comment in the pull request to call out maintainers. -## Issues -[Open an issue](https://github.com/asyncapi/asyncapi/issues/new) **only** if you want to report a bug or a feature. Don't open issues for questions or support, instead join our [Slack workspace](https://www.asyncapi.com/slack-invite) and ask there. Don't forget to follow our [Slack Etiquette](https://github.com/asyncapi/community/blob/master/slack-etiquette.md) while interacting with community members! It's more likely you'll get help, and much faster! +### Issues -## Bug Reports and Feature Requests +[Open an issue](https://github.com/asyncapi/asyncapi/issues/new) **only** if you want to report a bug or a feature. Don't open issues for questions or support; join our [AsyncAPI Slack workspace](https://www.asyncapi.com/slack-invite) and post your queries on the relevant channels. Don't forget to follow our [Slack Etiquette](https://github.com/asyncapi/community/blob/master/slack-etiquette.md) while interacting with community members! It's more likely you'll get help, and much faster! -Please use our issues templates that provide you with hints on what information we need from you to help you out. +### Bug Reports and Feature Requests -## Pull Requests +Please use our issues templates, which provide hints on what information we need from you to help you out. -**Please, make sure you open an issue before starting with a Pull Request, unless it's a typo or a really obvious error.** Pull requests are the best way to propose changes to the specification. Get familiar with our document that explains [Git workflow](https://github.com/asyncapi/community/blob/master/git-workflow.md) used in our repositories. +### Pull Requests -## Conventional commits +**Please open an issue before starting a Pull Request unless it's a typo or a really obvious error.** Pull requests are the best way to propose changes to the specification. It may be rejected if no issue was created first to discuss the need for a pull request. -Our repositories follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#summary) specification. Releasing to GitHub and NPM is done with the support of [semantic-release](https://semantic-release.gitbook.io/semantic-release/). +Get familiar with our document that explains the [Git workflow](https://github.com/asyncapi/community/blob/master/git-workflow.md) used in our repositories. -Pull requests should have a title that follows the specification, otherwise, merging is blocked. If you are not familiar with the specification simply ask maintainers to modify. You can also use this cheatsheet if you want: +## Conventional commits + +Our repositories follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#summary) specification. -- `fix: ` prefix in the title indicates that PR is a bug fix and PATCH release must be triggered. -- `feat: ` prefix in the title indicates that PR is a feature and MINOR release must be triggered. -- `docs: ` prefix in the title indicates that PR is only related to the documentation and there is no need to trigger release. -- `chore: ` prefix in the title indicates that PR is only related to cleanup in the project and there is no need to trigger release. -- `test: ` prefix in the title indicates that PR is only related to tests and there is no need to trigger release. -- `refactor: ` prefix in the title indicates that PR is only related to refactoring and there is no need to trigger release. +Pull requests should have a title that follows the specification; otherwise, merging is blocked. If you are unfamiliar with the specification, ask maintainers to modify it. You can also use this cheatsheet if you want: -What about MAJOR release? just add `!` to the prefix, like `fix!: ` or `refactor!: ` +- `fix: ` prefix in the title indicates that the PR is a bug fix. +- `feat: ` prefix in the title indicates that the PR is a feature. +- `docs: ` prefix in the title indicates that the PR only relates to the documentation. +- `chore: ` prefix in the title indicates that the PR is only related to cleanup in the project. +- `test: ` prefix in the title indicates that the PR is only related to tests. +- `refactor: ` prefix in the title indicates that the PR is only related to refactoring. -Prefix that follows specification is not enough though. Remember that the title must be clear and descriptive with usage of [imperative mood](https://chris.beams.io/posts/git-commit/#imperative). +A prefix that follows specification is not enough. Remember that the title must be clear and descriptive, using the [imperative mood](https://chris.beams.io/posts/git-commit/#imperative). -Happy contributing :heart: +Happy contributing! :heart: ## License + When you submit changes, your submissions are understood to be under the same [Apache 2.0 License](https://github.com/asyncapi/asyncapi/blob/master/LICENSE) that covers the project. Feel free to [contact the maintainers](https://www.asyncapi.com/slack-invite) if that's a concern. -## References -This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/master/CONTRIBUTING.md). \ No newline at end of file +## Contribution recognition + +We use the [All Contributors](https://allcontributors.org/docs/en/specification) specification to handle recognitions. Read the [`recognize contributors` document](https://github.com/asyncapi/community/blob/master/recognize-contributors.md). + +## Maintainers setup + +To streamline project management and facilitate onboarding, the maintainer's setup includes two roles: `triager` and `committer`. + +There are also two separate areas of responsibility: docs and code. A committer can be responsible for code only, and a triager can be responsible for docs only. A maintainer can hold all roles and participate in different areas. + +We recognize that because of the project's size and complexity, areas of responsibility can also become more granular. For example, a committer can be responsible for docs, but only community docs or a committer can be responsible only for project design. Project maintainers assess and approve these exceptions. + +### Triager + +Triagers are responsible for labeling, commenting, and managing issues and pull requests. + +- Triagers assess newly-opened issues and pull requests. +Responsibilities include labeling issues and pull requests, commenting, closing, and reopening items as needed, as well as assisting users and novice contributors. +- Triagers are crucial in enforcing the contributor guide and maintaining a clean backlog. +If a triager plans to become a committer, they should consult existing committers to gradually gain more rights. It's crucial to earn the trust of existing committers so they feel confident in your ability to merge PRs. A triager should consistently demonstrate dedication by regularly fulfilling their duties and actively reviewing PRs, providing code/docs suggestions and recommendations. This shows the committers that the triager is knowledgeable about the docs/codebase and committed to maintaining its quality. + +### Committer + +Committers are responsible for technical oversight, pull request approval, and onboarding of new maintainers. + +- Committers approve pull requests and oversee the technical direction of the project. +- They are responsible for reviewing and approving pull requests for merging. +- Committers also play a role in onboarding new maintainers and triagers. diff --git a/README.md b/README.md index 5eab72063aa..2422bd1b2ae 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,24 @@ After cloning repository to your local, perform the following steps from the roo Now you're running AsyncAPI website in a development mode. Container is mapped with your local copy of the website. Whenever you make changes to the code, the website will refresh and changes visible in localhost:3000. +## Use shared Markdown fragments + +To minimize the duplication of content and make it easier to maintain, there are shared fragments you can use when working with Markdown files. These fragments are stored in the `/assets/docs/fragments` directory. + +To include a fragment in a Markdown file: + +1. Import the fragment at the top of the file (but below the frontmatter) using the following syntax: + + ```md + import DesiredFragmentName from '@/assets/docs/fragments/fragmentYouWantToImport.md'; + ``` + +1. Add the imported fragment to the desired location in the Markdown file using the following syntax: + + ```md + + ``` + ## Lint the code To lint the code, run the following command: ``` @@ -377,6 +395,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Neutron
Neutron

💻 Sagar Kori
Sagar Kori

📖 + + Raj Patel
Raj Patel

💻 + diff --git a/assets/docs/fragments/bindings-overview.md b/assets/docs/fragments/bindings-overview.md new file mode 100644 index 00000000000..5f92b0ca380 --- /dev/null +++ b/assets/docs/fragments/bindings-overview.md @@ -0,0 +1 @@ +Bindings in AsyncAPI provide a way to add protocol-specific information to the AsyncAPI documentation. They can be added to different document parts, such as servers, channels, or messages; they specify standard details specific to a particular protocol. The purpose of bindings is to enhance the API's understanding and usage by providing additional context and configuration options for different protocols. diff --git a/assets/docs/fragments/contribution-notes.md b/assets/docs/fragments/contribution-notes.md new file mode 100644 index 00000000000..5c10d80c480 --- /dev/null +++ b/assets/docs/fragments/contribution-notes.md @@ -0,0 +1,14 @@ +Code isn't the only way to contribute to OSS; Dev Docs are a **huge** help that benefit the entire OSS ecosystem. At AsyncAPI, we value Doc contributions as much as every other type of contribution. ❤️ + +To get started as a Docs contributor: + +1. Familiarize yourself with our [project's Contribution Guide](https://github.com/asyncapi/community/blob/master/CONTRIBUTING.md) and our [Code of Conduct](https://github.com/asyncapi/.github/blob/master/CODE_OF_CONDUCT.md). +2. Head over to our [AsyncAPI Docs Board](https://github.com/orgs/asyncapi/projects/12). +3. Pick an issue you would like to contribute to and leave a comment introducing yourself. This is also the perfect place to leave any questions you may have on how to get started. +4. If there is no work done in that Docs issue yet, feel free to open a PR and get started! + +### Docs contributor questions + +Do you have a documentation contributor question and you're wondering how to tag me into a GitHub discussion or PR? Never fear! + +Tag me in your AsyncAPI Doc PRs or [GitHub Discussions](https://github.com/asyncapi/community/discussions/categories/docs) via my GitHub handle, [`alequetzalli`](https://github.com/alequetzalli) 🐙. diff --git a/assets/docs/fragments/how-to-contribute.md b/assets/docs/fragments/how-to-contribute.md index 932347021a1..1f3711096e3 100644 --- a/assets/docs/fragments/how-to-contribute.md +++ b/assets/docs/fragments/how-to-contribute.md @@ -1,23 +1,10 @@ -## How to contribute to AsyncAPI Docs - -Did you know that you can contribute Docs to AsyncAPI as well? Code isn't the only way to contribute to OSS; Dev Docs are a **huge** help that benefit the entire OSS ecosystem. At AsyncAPI, we value Doc contributions as much as every other type of contribution. ❤️ - -To get started as a Docs contributor: - -1. Familiarize yourself with our [project's Contribution Guide](https://github.com/asyncapi/community/blob/master/CONTRIBUTING.md) and our [Code of Conduct](https://github.com/asyncapi/.github/blob/master/CODE_OF_CONDUCT.md). - -2. Head over to our Docs GH Board [here](https://github.com/orgs/asyncapi/projects/12). +import ContributionNotes from '@/assets/docs/fragments/contribution-notes.md'; +import TalkToMe from '@/assets/docs/fragments/talk-to-me.md'; -3. Pick an issue you would like to contribute to and leave a comment introducing yourself. This is also the perfect place to leave any questions you may have on how to get started. - -4. If there is no work done in that Docs issue yet, feel free to open a PR and get started! - -### Tag me in your AsyncAPI Doc PRs - -Do you have a documentation contributor question and you're wondering how to tag me into a GitHub discussion or PR? Never fear! +## How to contribute to AsyncAPI Docs -Tag me in your AsyncAPI Doc PRs or [GitHub Discussions](https://github.com/asyncapi/community/discussions/categories/docs) via my GitHub handle, [`/alequetzalli`](https://github.com/alequetzalli) 🐙. +Did you know that you can contribute Docs to AsyncAPI as well? + ### Talk to me - -I want and need to listen 👂🏽 to all of your perspectives and ideas. Please don't be shy to express to me what you think needs to be documented first or what is missing. 📝 There's a lot of good work ahead, but **you** determine _our content roadmap_ because the OSS community needs should always come first.✨ \ No newline at end of file + \ No newline at end of file diff --git a/assets/docs/fragments/talk-to-me.md b/assets/docs/fragments/talk-to-me.md new file mode 100644 index 00000000000..c1066a563f1 --- /dev/null +++ b/assets/docs/fragments/talk-to-me.md @@ -0,0 +1 @@ +I want and need to listen 👂🏽 to all of your perspectives and ideas. Please don't be shy to express to me what you think needs to be documented first or what is missing. 📝 There's a lot of good work ahead, but **you** determine _our content roadmap_ because the OSS community needs should always come first.✨ diff --git a/components/Accordion/Accordion.stories.tsx b/components/Accordion/Accordion.stories.tsx new file mode 100644 index 00000000000..95bbed4b5ed --- /dev/null +++ b/components/Accordion/Accordion.stories.tsx @@ -0,0 +1,35 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import type { AccordionItemType } from '@/types/components/AccordionItemType'; + +import Accordion from './Accordion'; + +const meta: Meta = { + title: 'Components/Accordion', + component: Accordion +}; + +export default meta; + +type Story = StoryObj; + +const sampleAccordionItemList: AccordionItemType[] = [ + { + title: 'Accordion Item 1', + content: 'This is the content of accordion item 1.' + }, + { + title: 'Accordion Item 2', + content: 'This is the content of accordion item 2.' + }, + { + title: 'Accordion Item 3', + content: 'This is the content of accordion item 3.' + } +]; + +export const SampleAccordion: Story = { + args: { + accordionItems: sampleAccordionItemList + } +}; diff --git a/components/Accordion/Accordion.tsx b/components/Accordion/Accordion.tsx new file mode 100644 index 00000000000..aa5fbf536fb --- /dev/null +++ b/components/Accordion/Accordion.tsx @@ -0,0 +1,34 @@ +import React from 'react'; + +import type { AccordionItemType } from '@/types/components/AccordionItemType'; + +import AccordionItem from './AccordionItem'; + +export interface AccordionProps { + // eslint-disable-next-line prettier/prettier + + /** List of accordian items objects each containing title and content. */ + accordionItems: AccordionItemType[]; +} + +/** + * This is the Accordion component. It displays a list of items that can be expanded or collapsed. + */ +export default function Accordion({ accordionItems = [] }: AccordionProps) { + const [activeIndex, setActiveIndex] = React.useState(null); + + return ( +
+ {accordionItems.map(({ title, content }, index) => ( + + ))} +
+ ); +} diff --git a/components/Accordion/AccordionItem.tsx b/components/Accordion/AccordionItem.tsx new file mode 100644 index 00000000000..b7c1f61d829 --- /dev/null +++ b/components/Accordion/AccordionItem.tsx @@ -0,0 +1,67 @@ +import React from 'react'; + +export interface AccordionItemProps { + // eslint-disable-next-line prettier/prettier + + /** Index of the accordion item. */ + itemIndex: number; + + /** Title of the accordion item. */ + title: string; + + /** Content of the accordion item. */ + content: React.ReactNode; + + /** Whether the accordion item is active(open) or not. */ + isActive: boolean; + + /** Function to set the active index of the accordion item. */ + setActiveIndex: (index: number | null) => void; +} + +/** + * This is the AccordionItem component. It displays a single item that can be expanded or collapsed. + */ +export default function AccordionItem({ itemIndex, title, content, isActive, setActiveIndex }: AccordionItemProps) { + const handleClick = () => { + const nextIndex = isActive ? null : itemIndex; + + setActiveIndex(nextIndex); + }; + + return ( +
+ + {isActive && ( +
+ {content} +
+ )} +
+ ); +} diff --git a/components/AlgoliaSearch.tsx b/components/AlgoliaSearch.tsx index 43b3cc7ce6b..a7d3604fafb 100644 --- a/components/AlgoliaSearch.tsx +++ b/components/AlgoliaSearch.tsx @@ -5,7 +5,7 @@ import clsx from 'clsx'; import Head from 'next/head'; import Link from 'next/link'; import { useRouter } from 'next/router'; -import { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react'; +import React, { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; export const INDEX_NAME = 'asyncapi'; @@ -283,6 +283,7 @@ export default function AlgoliaSearch({ children }: { children: React.ReactNode */ export function SearchButton({ children, indexName = INDEX_NAME, ...props }: ISearchButtonProps) { const { onOpen, onInput } = useContext(SearchContext); + const [Children, setChildren] = useState(''); const searchButtonRef = useRef(null); const actionKey = getActionKey(); @@ -308,6 +309,12 @@ export function SearchButton({ children, indexName = INDEX_NAME, ...props }: ISe }; }, [onInput, searchButtonRef]); + useEffect(() => { + if (typeof children === 'function') { + setChildren(children({ actionKey })); + } + }, []); + return ( ); } diff --git a/components/Avatar.tsx b/components/Avatar.tsx index b8bb1e55715..d889cafb9d7 100644 --- a/components/Avatar.tsx +++ b/components/Avatar.tsx @@ -32,9 +32,17 @@ export default function Avatar({ name, photo, link, className }: AvatarProps) { ); return link ? ( - + ) : ( {avatar} ); diff --git a/components/Calendar.tsx b/components/Calendar.tsx index 2805abf2f7c..767f2964880 100644 --- a/components/Calendar.tsx +++ b/components/Calendar.tsx @@ -1,4 +1,5 @@ import moment from 'moment'; +import React from 'react'; import { twMerge } from 'tailwind-merge'; import type { IEvent } from '@/types/event'; diff --git a/components/CaseStudyCard.tsx b/components/CaseStudyCard.tsx index 241e9b5aa84..7b6bad8dadb 100644 --- a/components/CaseStudyCard.tsx +++ b/components/CaseStudyCard.tsx @@ -1,3 +1,5 @@ +import React from 'react'; + import type { ICaseStudies } from '@/types/post'; import { ParagraphTypeStyle } from '@/types/typography/Paragraph'; diff --git a/components/CaseTOC.tsx b/components/CaseTOC.tsx index 6008a6ea156..e242c6af579 100644 --- a/components/CaseTOC.tsx +++ b/components/CaseTOC.tsx @@ -1,4 +1,4 @@ -import { useMemo, useState } from 'react'; +import React, { useMemo, useState } from 'react'; import { twMerge } from 'tailwind-merge'; import { useHeadingsObserver } from './helpers/useHeadingsObserver'; diff --git a/components/ClickableLogo.tsx b/components/ClickableLogo.tsx index 0ce7f081e4f..98836011e1f 100644 --- a/components/ClickableLogo.tsx +++ b/components/ClickableLogo.tsx @@ -1,6 +1,7 @@ import Link from 'next/link'; +import React from 'react'; -import AsyncAPILogo from './AsyncAPILogo'; +import AsyncAPILogo from './logos/AsyncAPILogo'; interface IClickableLogoProps { href?: string; diff --git a/components/DemoAnimation.tsx b/components/DemoAnimation.tsx index 0e8affd7628..1748d0c6ca2 100644 --- a/components/DemoAnimation.tsx +++ b/components/DemoAnimation.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import Typing from 'react-typist-component'; import { HeadingLevel, HeadingTypeStyle } from '@/types/typography/Heading'; diff --git a/components/Feedback.tsx b/components/Feedback.tsx index 6fad56ecb20..104e21107f0 100644 --- a/components/Feedback.tsx +++ b/components/Feedback.tsx @@ -1,5 +1,5 @@ import { useRouter } from 'next/router'; -import { useEffect, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import GitHubIssue from './buttons/GitHubIssue'; diff --git a/components/Figure.tsx b/components/Figure.tsx index 878258ce775..c20a92884c3 100644 --- a/components/Figure.tsx +++ b/components/Figure.tsx @@ -1,3 +1,5 @@ +import React from 'react'; + import { Float } from '@/types/components/FigurePropsType'; import Caption from './Caption'; diff --git a/components/FinancialSummary/AsyncAPISummary.tsx b/components/FinancialSummary/AsyncAPISummary.tsx index 280a24b476f..7ee80d54dbf 100644 --- a/components/FinancialSummary/AsyncAPISummary.tsx +++ b/components/FinancialSummary/AsyncAPISummary.tsx @@ -1,3 +1,5 @@ +import React from 'react'; + import { HeadingLevel, HeadingTypeStyle } from '@/types/typography/Heading'; import { ParagraphTypeStyle } from '@/types/typography/Paragraph'; diff --git a/components/FinancialSummary/BarChartComponent.tsx b/components/FinancialSummary/BarChartComponent.tsx index 55bf51c5b04..019927672cb 100644 --- a/components/FinancialSummary/BarChartComponent.tsx +++ b/components/FinancialSummary/BarChartComponent.tsx @@ -3,8 +3,8 @@ import { Bar, BarChart, CartesianGrid, Legend, Tooltip, YAxis } from 'recharts'; import type { ExpenseItem, ExpensesLinkItem } from '@/types/FinancialSummary/BarChartComponent'; -import ExpensesData from '../../config/finance/json-data/2024/Expenses.json'; -import ExpensesLinkData from '../../config/finance/json-data/2024/ExpensesLink.json'; +import ExpensesData from '../../config/finance/json-data/Expenses.json'; +import ExpensesLinkData from '../../config/finance/json-data/ExpensesLink.json'; import { getUniqueCategories } from '../../utils/getUniqueCategories'; import CustomTooltip from './CustomTooltip'; import ExpensesCard from './ExpensesCard'; diff --git a/components/FinancialSummary/Card.tsx b/components/FinancialSummary/Card.tsx index 2433fbd52cb..44c9a00ca55 100644 --- a/components/FinancialSummary/Card.tsx +++ b/components/FinancialSummary/Card.tsx @@ -1,6 +1,8 @@ +import React from 'react'; + import type { ExpenseItem, Expenses } from '@/types/FinancialSummary/BarChartComponent'; -import ExpensesLinkData from '../../config/finance/json-data/2024/ExpensesLink.json'; +import ExpensesLinkData from '../../config/finance/json-data/ExpensesLink.json'; /** * @description Card component displays expense details for a specific month. diff --git a/components/FinancialSummary/ContactUs.tsx b/components/FinancialSummary/ContactUs.tsx index 738631f8e8f..1e0dd9560d3 100644 --- a/components/FinancialSummary/ContactUs.tsx +++ b/components/FinancialSummary/ContactUs.tsx @@ -1,3 +1,5 @@ +import React from 'react'; + import { HeadingLevel, HeadingTypeStyle } from '@/types/typography/Heading'; import { ParagraphTypeStyle } from '@/types/typography/Paragraph'; diff --git a/components/FinancialSummary/CustomTooltip.tsx b/components/FinancialSummary/CustomTooltip.tsx index fa23aa5e69e..f4ae6afe117 100644 --- a/components/FinancialSummary/CustomTooltip.tsx +++ b/components/FinancialSummary/CustomTooltip.tsx @@ -1,3 +1,5 @@ +import React from 'react'; + import type { CustomTooltipProps } from '@/types/FinancialSummary/BarChartComponent'; /** diff --git a/components/FinancialSummary/ExpenseBreakdown.tsx b/components/FinancialSummary/ExpenseBreakdown.tsx index 89ceaff56f7..d0566968820 100644 --- a/components/FinancialSummary/ExpenseBreakdown.tsx +++ b/components/FinancialSummary/ExpenseBreakdown.tsx @@ -1,3 +1,5 @@ +import React from 'react'; + import { ParagraphTypeStyle } from '@/types/typography/Paragraph'; import { expenseData } from '../data/ExpenseBreakdownData'; diff --git a/components/FinancialSummary/ExpensesCard.tsx b/components/FinancialSummary/ExpensesCard.tsx index fb747ce3a89..5bf593f9642 100644 --- a/components/FinancialSummary/ExpensesCard.tsx +++ b/components/FinancialSummary/ExpensesCard.tsx @@ -1,6 +1,8 @@ +import React from 'react'; + import type { Expenses } from '@/types/FinancialSummary/BarChartComponent'; -import ExpensesData from '../../config/finance/json-data/2024/Expenses.json'; +import ExpensesData from '../../config/finance/json-data/Expenses.json'; import Card from './Card'; /** diff --git a/components/FinancialSummary/OtherFormsComponent.tsx b/components/FinancialSummary/OtherFormsComponent.tsx index d3132dc931a..2c52e7775fc 100644 --- a/components/FinancialSummary/OtherFormsComponent.tsx +++ b/components/FinancialSummary/OtherFormsComponent.tsx @@ -1,3 +1,5 @@ +import React from 'react'; + import { ParagraphTypeStyle } from '@/types/typography/Paragraph'; import { otherFormsData } from '../data/otherFormsData'; diff --git a/components/FinancialSummary/SponsorshipTiers.tsx b/components/FinancialSummary/SponsorshipTiers.tsx index 42464c7f9e6..082fc22e5a3 100644 --- a/components/FinancialSummary/SponsorshipTiers.tsx +++ b/components/FinancialSummary/SponsorshipTiers.tsx @@ -1,3 +1,5 @@ +import React from 'react'; + import { HeadingLevel, HeadingTypeStyle } from '@/types/typography/Heading'; import { ParagraphTypeStyle } from '@/types/typography/Paragraph'; diff --git a/components/FinancialSummary/SuccessStories.tsx b/components/FinancialSummary/SuccessStories.tsx index 487be9fd1a3..2ffdd960b00 100644 --- a/components/FinancialSummary/SuccessStories.tsx +++ b/components/FinancialSummary/SuccessStories.tsx @@ -1,3 +1,5 @@ +import React from 'react'; + import { successStories } from '../data/successStoriesData'; /** diff --git a/components/GeneratorInstallation.tsx b/components/GeneratorInstallation.tsx index d280a2199e4..bf4d937f802 100644 --- a/components/GeneratorInstallation.tsx +++ b/components/GeneratorInstallation.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import React, { useState } from 'react'; import { ParagraphTypeStyle } from '@/types/typography/Paragraph'; @@ -62,7 +62,7 @@ asyncapi generate fromTemplate ${specPath} ${template} ${params}`; * @returns {string} The Docker command. */ function getDockerCode(): string { - return `docker run --rm -it -v \${PWD}/example:/app/example -v \${PWD}/output:/app/output \\ + return `docker run --rm -it --user=root -v \${PWD}/example:/app/example -v \${PWD}/output:/app/output \\ asyncapi/cli generate fromTemplate ${specPath} ${template} ${params}`; } diff --git a/components/Head.tsx b/components/Head.tsx index e44f4cfac19..5681a6bb5c5 100644 --- a/components/Head.tsx +++ b/components/Head.tsx @@ -30,7 +30,7 @@ export default function HeadComponent({ rssTitle = 'RSS Feed for AsyncAPI Initiative Blog', rssLink = '/rss.xml' }: IHeadProps) { - const url = process.env.DEPLOY_PRIME_URL || process.env.DEPLOY_URL || 'http://localhost:3000'; + const url = process.env.NEXT_PUBLIC_DEPLOY_PRIME_URL || process.env.NEXT_PUBLIC_DEPLOY_URL || 'http://localhost:3000'; const appContext = useContext(AppContext); const { path = '' } = appContext || {}; let currImage = image; diff --git a/components/Hero.tsx b/components/Hero.tsx index 6ce5289e085..c0609e83756 100644 --- a/components/Hero.tsx +++ b/components/Hero.tsx @@ -1,3 +1,5 @@ +import React from 'react'; + import { HeadingLevel, HeadingTypeStyle } from '@/types/typography/Heading'; import { ParagraphTypeStyle } from '@/types/typography/Paragraph'; diff --git a/components/InlineHelp.tsx b/components/InlineHelp.tsx index ec8d039da2a..0db3fd87f44 100644 --- a/components/InlineHelp.tsx +++ b/components/InlineHelp.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { registerClickAway } from './helpers/click-away'; import QuestionMark from './icons/QuestionMark'; diff --git a/components/InputBox.stories.tsx b/components/InputBox.stories.tsx index f30247a7b83..78edb891d6f 100644 --- a/components/InputBox.stories.tsx +++ b/components/InputBox.stories.tsx @@ -1,5 +1,6 @@ import { useArgs } from '@storybook/preview-api'; import type { Meta, StoryObj } from '@storybook/react'; +import React from 'react'; import type { InputBoxProps } from '@/types/components/InputBoxPropsType'; import { InputTypes } from '@/types/components/InputBoxPropsType'; diff --git a/components/Loader.stories.tsx b/components/Loader.stories.tsx new file mode 100644 index 00000000000..563f1ed81e7 --- /dev/null +++ b/components/Loader.stories.tsx @@ -0,0 +1,116 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import React from 'react'; + +import AsyncAPIColorIcon from '@/components/icons/AsyncAPIColorIcon'; +import IconCircularLoader from '@/components/icons/CircularLoader'; + +import Loader from './Loader'; + +const meta: Meta = { + title: 'Components/Loader', + component: Loader +}; + +export default meta; + +type Story = StoryObj; + +const DarkBackgroundDecorator = (Story: any) => ( +
+ +
+); + +export const TextLoader: Story = { + args: { + loaderText: 'Loading...' + } +}; + +export const TextLoaderInDark: Story = { + decorators: [DarkBackgroundDecorator], + args: { + loaderText: 'Loading...', + dark: true + } +}; + +export const PulsatingTextLoader: Story = { + args: { + loaderText: 'Loading...', + pulsating: true + } +}; + +export const PulsatingTextLoaderInDark: Story = { + decorators: [DarkBackgroundDecorator], + args: { + loaderText: 'Loading...', + dark: true, + pulsating: true + } +}; + +export const CircularAnimationLoader: Story = { + args: { + loaderIcon: + } +}; + +export const CircularAnimationLoaderInDark: Story = { + decorators: [DarkBackgroundDecorator], + args: { + loaderIcon: , + dark: true + } +}; + +export const PulsatingIconLoader: Story = { + args: { + loaderIcon: , + pulsating: true + } +}; + +export const PulsatingIconLoaderInDark: Story = { + decorators: [DarkBackgroundDecorator], + args: { + loaderIcon: , + dark: true, + pulsating: true + } +}; + +export const CircularAnimationTextLoader: Story = { + args: { + loaderIcon: , + loaderText: 'Loading...' + } +}; + +export const CircularAnimationTextLoaderInDark: Story = { + decorators: [DarkBackgroundDecorator], + args: { + loaderIcon: , + loaderText: 'Loading...', + dark: true + } +}; + +export const PulsatingIconTextLoader: Story = { + args: { + loaderIcon: , + loaderText: 'Loading...', + pulsating: true + } +}; + +export const PulsatingIconTextLoaderInDark: Story = { + decorators: [DarkBackgroundDecorator], + args: { + loaderIcon: , + loaderText: 'Loading...', + dark: true, + pulsating: true + } +}; diff --git a/components/Loader.tsx b/components/Loader.tsx index 09324174ec2..b0be9da3475 100644 --- a/components/Loader.tsx +++ b/components/Loader.tsx @@ -1,24 +1,41 @@ +import React from 'react'; import { twMerge } from 'tailwind-merge'; +import AsyncAPIColorIcon from './icons/AsyncAPIColorIcon'; + interface LoaderProps { + // eslint-disable-next-line prettier/prettier + + /** The text to be displayed along with the loading animation. */ + loaderText?: string; + + /** The icon to be displayed along with the loading animation. */ + loaderIcon?: React.ReactElement | null; + + /** Additional classes for the loader. */ className?: string; + + /** Whether the loader should be in dark mode. */ dark?: boolean; + + /** Whether the loader should be pulsating. */ + pulsating?: boolean; } /** * This component displays a loader. - * @param {LoaderProps} props - The props for the Loader component - * @param {string} props.className - Additional classes for the loader - * @param {boolean} props.dark - Whether the loader should be in dark mode */ -export default function Loader({ className = '', dark = false }: LoaderProps) { +export default function Loader({ + loaderText = '', + loaderIcon = , + className = '', + dark = false, + pulsating = false +}: LoaderProps) { return ( -
- -
Waiting for response...
+
+ {loaderIcon} +
{loaderText}
); } diff --git a/components/MDX/MDX.tsx b/components/MDX/MDX.tsx index 36cddf7aa6a..32bdb94f978 100644 --- a/components/MDX/MDX.tsx +++ b/components/MDX/MDX.tsx @@ -1,7 +1,7 @@ import { MDXProvider as CoreMDXProvider } from '@mdx-js/react'; import mermaid from 'mermaid'; import Link from 'next/link'; -import { useLayoutEffect, useState } from 'react'; +import React, { useLayoutEffect, useState } from 'react'; import { TwitterDMButton, TwitterFollowButton, @@ -29,6 +29,7 @@ import Caption from '../Caption'; import DocsCards from '../docs/DocsCards'; import Visualizer from '../docs/Visualizer'; import CodeBlock from '../editor/CodeBlock'; +import FAQ from '../faq/FAQ'; import Figure from '../Figure'; import GeneratorInstallation from '../GeneratorInstallation'; import Column from '../layout/Column'; @@ -38,7 +39,7 @@ import Profiles from '../Profiles'; import Remember from '../Remember'; import Sponsors from '../sponsors/Sponsors'; import Warning from '../Warning'; -import { Table, TableCell, TableHeader, TableRow } from './MDXTable'; +import { Table, TableBody, TableCell, TableHeader, TableRow, Thead } from './MDXTable'; let mermaidInitialized = false; @@ -174,163 +175,161 @@ function Text({ content = '', className = '' }) { /** * @description This function returns MDX components. */ -export function getMDXComponents() { - return { - h1: (props: React.HTMLProps) => ( -

- ), - h2: (props: React.HTMLProps) => ( -

- ), - h3: (props: React.HTMLProps) => ( -

- ), - h4: (props: React.HTMLProps) => ( -

- ), - h5: (props: React.HTMLProps) => ( -
- ), - h6: (props: React.HTMLProps) => ( -
- ), - blockquote: (props: React.HTMLProps) => ( -
- ), - p: (props: React.HTMLProps) => ( -

- ), - strong: (props: React.HTMLProps) => ( - - ), - a: (props: React.HTMLProps) => ( - - ), - ul: (props: React.HTMLProps) => ( -