Skip to content

Commit

Permalink
Merge branch 'migrate-ts' into lib-mig
Browse files Browse the repository at this point in the history
  • Loading branch information
akshatnema authored Feb 29, 2024
2 parents a27b42d + b2d9496 commit 1727256
Show file tree
Hide file tree
Showing 78 changed files with 2,436 additions and 1 deletion.
19 changes: 19 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
"eslint:recommended",
"plugin:prettier/recommended"
],
"env": {
"browser": true,
"es2021": true,
"node": true
},
"plugins": [
"react",
"jsx-a11y"
Expand All @@ -16,8 +21,22 @@
"singleQuote": true,
"endOfLine": "auto"
}
],
"max-len": [
"error",
{
"code": 120,
"ignoreUrls": true,
"ignorePattern": "*className=([\\s\\S]*?)*" // Ignore classnames
}
]
},
"globals": {
"React": true,
"expect": true,
"jsdom": true,
"JSX": true
},
"overrides": [
// Configuration for TypeScript files
{
Expand Down
3 changes: 2 additions & 1 deletion .prettierrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
"singleQuote": true,
"jsxSingleQuote": true,
"arrowParens": "always",
"trailingComma": "es5"
"trailingComma": "es5",
"printWidth": 120
}
93 changes: 93 additions & 0 deletions components/buttons/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import Link from 'next/link';
import { twMerge } from 'tailwind-merge';

type IButtonProps = {
text: string;
icon?: React.ReactNode;
iconPosition?: 'left' | 'right';
target?: string;
bgClassName?: string;
textClassName?: string;
buttonSize?: 'small' | 'default';
type?: 'submit' | 'reset' | 'button';
} & (
| ({
href: string;
} & React.AnchorHTMLAttributes<HTMLAnchorElement>)
| ({
href?: undefined | null;
} & React.ButtonHTMLAttributes<HTMLButtonElement>)
);

/**
* @name Button
* @param {string} props.text - The text to be displayed on the button.
* @param {string} props.type - The type of the button. Defaults to 'button'.
* @param {string} props.target - The target attribute for the anchor tag. Defaults to '_self'.
* @param {React.ReactNode} props.icon - The icon to be displayed on the button.
* @param {string} props.iconPosition - The position of the icon. Defaults to 'right'.
* @param {string} props.className - The class name to be applied to the button.
* @param {string} props.bgClassName - The class name to be applied to the button's background.
* @param {string} props.textClassName - The class name to be applied to the button's text.
* @param {string} props.buttonSize - The size of the button. Defaults to 'default'.
* @param {string} props.href - The href attribute for the anchor tag.
* @description The Button component is a reusable button component that can be used to render a button or an anchor tag
* @description The component accepts button or anchor tag props based on the presence of the href prop.
* @description If the href prop is present, the component will render an anchor tag,
* otherwise it will render a button tag.
*/
export default function Button({
text,
type = 'button',
target = '_self',
icon,
iconPosition = 'right',
className,
bgClassName = twMerge('bg-primary-500 hover:bg-primary-400'),
textClassName = twMerge('text-white'),
buttonSize,
...props
}: IButtonProps): React.ReactElement {
const smallButtonClasses = twMerge(`${bgClassName} ${textClassName} transition-all duration-500
ease-in-out rounded-md px-3 py-2 text-sm font-medium tracking-heading ${className || ''}`);
const classNames = twMerge(`${bgClassName} ${textClassName} transition-all duration-500 ease-in-out
rounded-md px-4 py-3 text-md font-semibold tracking-heading ${className || ''}`);

if (!props.href) {
return (
<button
{...(props as React.ButtonHTMLAttributes<HTMLButtonElement>)}
type={type}
className={buttonSize === 'small' ? smallButtonClasses : classNames}
data-testid='Button-main'
>
{icon && iconPosition === 'left' && (
<span className='mr-2 inline-block' data-testid='Button-icon-left'>
{icon}
</span>
)}
<span className='inline-block'>{text}</span>
{icon && iconPosition === 'right' && (
<span className='ml-2 inline-block' data-testid='Button-icon-right'>
{icon}
</span>
)}
</button>
);
}

return (
<Link
passHref
{...props}
target={target}
rel='noopener noreferrer'
className={buttonSize === 'small' ? smallButtonClasses : classNames}
data-testid='Button-link'
>
{icon && iconPosition === 'left' && <span className='mr-2 inline-block'>{icon}</span>}
<span className='inline-block'>{text}</span>
{icon && iconPosition === 'right' && <span className='ml-2 inline-block'>{icon}</span>}
</Link>
);
}
52 changes: 52 additions & 0 deletions components/buttons/ChapterSuggestion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import Link from 'next/link';
import type { HTMLAttributeAnchorTarget } from 'react';
import type { Url } from 'url';

import IconArrowRight from '../icons/ArrowRight';

export interface IChapterSuggestionProps {
href: string | Url;
target?: HTMLAttributeAnchorTarget;
title: string;
description: string;
linkText: string;
className?: string;
}

/**
*
* @param {Object} props - The props of the component
* @param {string} props.href - The URL of the chapter
* @param {string} props.target - The target of the link
* @param {string} props.title - The title of the chapter
* @param {string} props.description - The description of the chapter
* @param {string} props.linkText - The text of the link
* @param {string} props.className - The class name of the component
*/
export default function ChapterSuggestion({
href = '/',
target = '_self',
title,
description,
linkText,
className
}: IChapterSuggestionProps) {
return (
<Link
href={href}
target={target}
rel='noopener noreferrer'
title={description}
className={`${className} mt-4 flex max-w-lg flex-col rounded border border-gray-200 p-6
text-gray-900 shadow-md transition-all duration-300 ease-in-out hover:border-gray-300 hover:shadow-lg`}
data-testid='ChapterSuggestion-link'
>
<h5 className='mb-2 font-sans text-lg font-medium antialiased'>{title}</h5>
<p className='font-normal mb-2 flex-1 font-sans text-gray-600 antialiased'>{description}</p>
<p className='font-sans font-medium text-primary-500 antialiased'>
{linkText}
<IconArrowRight className='inline-block h-4' />
</p>
</Link>
);
}
30 changes: 30 additions & 0 deletions components/buttons/ChapterSuggestions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { IChapterSuggestionProps } from './ChapterSuggestion';
import ChapterSuggestion from './ChapterSuggestion';

interface IChapterSuggestionsProps {
suggestions: IChapterSuggestionProps[];
className?: string;
}

/**
*
* @param {Object} props - The props of the component
* @param {Array} props.suggestions - The suggestions of the chapter
* @param {string} props.className - The class name of the component
*/
export default function ChapterSuggestions({ suggestions = [], className = '' }: IChapterSuggestionsProps) {
return (
<div className={`${className} grid grid-cols-1 gap-4 sm:grid-cols-2`}>
{suggestions.map((suggestion, index) => (
<ChapterSuggestion
key={index}
href={suggestion.href}
title={suggestion.title}
description={suggestion.description}
linkText={suggestion.linkText}
className={suggestion.className}
/>
))}
</div>
);
}
80 changes: 80 additions & 0 deletions components/buttons/DocsButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import Link from 'next/link';

import type { IDocs } from '@/types/post';

export interface IDocsButtonProps {
post: IDocs[number];
className?: string;
}

/**
* @description The DocsButton component is a button that links to the previous and next pages of the documentation.
* @param {Object} props - The props of the component
* @param {IPost} props.post - The post object
* @param {string} props.className - The class name of the component
* @returns {JSX.Element} The DocsButton component
*/
export default function DocsButton({ post, className = '' }: IDocsButtonProps) {
return (
<div className={`mb-4 flex h-full flex-row gap-4 ${className}`}>
<div className='h-auto w-1/2'>
{post?.prevPage && (
<Link href={post.prevPage.href} passHref>
<div className={`cursor-pointer rounded border border-gray-200 p-4 text-center shadow-md transition-all
duration-300 ease-in-out hover:border-gray-300 hover:shadow-lg lg:text-left`}>
<div className='text-secondary-500' data-testid='DocsButton-Prevdiv'>
<svg
xmlns='http://www.w3.org/2000/svg'
className='mr-1 inline size-6'
fill='none'
viewBox='0 0 24 24'
stroke='currentColor'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth={2}
d='M11 15l-3-3m0 0l3-3m-3 3h8M3 12a9 9 0 1118 0 9 9 0 01-18 0z'
/>
</svg>
<div className='my-auto inline text-sm font-bold uppercase'>Go Back</div>
</div>
<div className='my-2 text-base font-medium' data-testid='DocsButton-PrevPage'>
{post.prevPage.title}
</div>
</div>
</Link>
)}
</div>
<div className='h-auto w-1/2'>
{post?.nextPage && (
<Link href={post.nextPage.href} className='h-auto' passHref>
<div className={`h-full cursor-pointer rounded border border-gray-200 p-4 text-center shadow-md
transition-all duration-300 ease-in-out hover:border-gray-300 hover:shadow-lg lg:text-right`}>
<div className='text-secondary-500' data-testid='DocsButton-Nextdiv'>
<div className='my-auto inline text-sm font-bold uppercase'>Up Next</div>
<svg
xmlns='http://www.w3.org/2000/svg'
className='ml-1 inline size-6'
fill='none'
viewBox='0 0 24 24'
stroke='currentColor'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth={2}
d='M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z'
/>
</svg>
</div>
<div className='my-2 text-base font-medium' data-testid='DocsButton-NextPage'>
{post.nextPage.title}
</div>
</div>
</Link>
)}
</div>
</div>
);
}
21 changes: 21 additions & 0 deletions components/buttons/GitHubIssue.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';

/**
* @description The GitHubIssue component is a button that links to the GitHub issue creation page.
* @param {string} props.className - The class name to be applied to the button.
*/
export default function GitHubIssue({ className = '' }) {
return (
<a
className={`flex flex-row justify-center rounded bg-black py-2 text-white
shadow-md transition-all duration-500 ease-in-out hover:shadow-lg lg:w-6/12 ${className}`}
href='https://github.com/asyncapi/website/issues/new/choose'
target='_blank'
rel='noopener noreferrer'
data-testid='GithubIssue-Link'
>
<img src='/img/logos/github-fill.svg' className='mr-2' alt='Github:AsyncAPI' />
Create Issue on GitHub
</a>
);
}
45 changes: 45 additions & 0 deletions components/buttons/GithubButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import IconGithub from '../icons/Github';
import Button from './Button';
import type { IButtonDefaultProps } from './types';
// TODO: add this again when we have i18n
// import { useTranslation } from '../../lib/i18n'

interface IGithubButtonProps extends IButtonDefaultProps {
inNav?: boolean;
}

/**
* @description The GithubButton component is a button that links to the AsyncAPI GitHub repository.
* @param {string} props.text - The text to display on the button.
* @param {string} props.href - The href attribute for the anchor tag.
* @param {string} props.target - The target attribute for the anchor tag.
* @param {string} props.iconPosition - The position of the icon in the button.
* @param {string} props.className - The class name to be applied to the button.
*/
export default function GithubButton({
text = 'githubButton',
href = 'https://github.com/asyncapi',
target = '_blank',
iconPosition = 'left',
className,
inNav
}: IGithubButtonProps) {
// TODO: add this again when we have i18n
// const { t } = useTranslation("common");

return (
<Button
// TODO: add this again when we have i18n
// text={t(text)}
text={text}
icon={<IconGithub className='-mt-1 inline-block size-6' />}
href={href}
iconPosition={iconPosition}
target={target}
className={className}
data-testid='Github-button'
bgClassName='bg-gray-800 hover:bg-gray-700'
buttonSize={inNav ? 'small' : 'default'}
/>
);
}
Loading

0 comments on commit 1727256

Please sign in to comment.