docs: refactor to use TypeScript, ESLint, and Tailwind CSS (#4136)
* docs(refactoring): configured eslint and typescript (#3511) * docs: configured eslint and typescript * fixed yarn.lock * docs(refactoring): migrate components directory to typescript (#3517) * docs: migrate components directory to typescript * removed vscode settings * fix following merge * docs: refactored QueryNote component (#3576) * docs: refactored first batch of theme components (#3579) * docs: refactored second batch of theme components (#3580) * added missing badge styles * fix after merge * docs(refactoring): migrated remaining component to TypeScript (#3770) * docs(refactoring): configured eslint and typescript (#3511) * docs: configured eslint and typescript * fixed yarn.lock * docs(refactoring): migrate components directory to typescript (#3517) * docs: migrate components directory to typescript * removed vscode settings * fix following merge * docs: refactored QueryNote component (#3576) * docs: refactored first batch of theme components (#3579) * docs: refactored second batch of theme components (#3580) * added missing badge styles * docs: refactoring second batch of theme components * fix after merge * refactored icons and other components * docs: refactored all components * docs(refactoring): set up and configured Tailwind Css (#3841) * docs: added tailwind config * docs: added more tailwind configurations * add includes option * added more tailwind configurations * fix to configurations * docs(refactoring): use tailwind css (#4134) * docs: added tailwind config * docs: added more tailwind configurations * add includes option * added more tailwind configurations * fix to configurations * docs(refactoring): refactored all styles to use tailwind css (#4132) * refactored Badge component to use tailwind css * refactored Bordered component to use tailwind css * updated to latest docusaurus * refactored BorderedIcon component to use tailwind css * refactored Feedback component to use tailwind css * refactored icons and footersociallinks to tailwind css * start refactoring of large card * refactored large card styling * refactored until admonitions * refactored until codeblock * refactored until Tabs * refactored Tabs (without testing * finished refactoring styles to tailwind css * upgraded to version 2.4.1 * general fixes * adjusted eslint configurations * fixed ignore files * fixes to large card * fix search styling * fix npx command * updated tabs to use isCodeTabs prop * fixed os tabs * removed os-tabs class in favor of general styling * improvements to buttons * fix for searchbar * fixed redocly download button * chore: added eslint code action (#4135) * small change in commerce modules page
This commit is contained in:
@@ -1,146 +0,0 @@
|
||||
import {
|
||||
findFirstCategoryLink,
|
||||
useDocById,
|
||||
} from '@docusaurus/theme-common/internal';
|
||||
|
||||
import Link from '@docusaurus/Link';
|
||||
import React from 'react';
|
||||
import clsx from 'clsx';
|
||||
import isInternalUrl from '@docusaurus/isInternalUrl';
|
||||
import styles from './styles.module.css';
|
||||
import {translate} from '@docusaurus/Translate';
|
||||
import BorderedIcon from '../../components/BorderedIcon';
|
||||
import Badge from '../../components/Badge';
|
||||
import Icons from '../Icon';
|
||||
|
||||
function CardContainer({href, children, className}) {
|
||||
return (
|
||||
<article className={`card-wrapper margin-bottom--lg`}>
|
||||
<Link
|
||||
href={href}
|
||||
className={clsx('card', styles.cardContainer, className)}>
|
||||
{children}
|
||||
</Link>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
|
||||
function CardLayout({href, icon, title, description, html, containerClassName, isSoon = false, badge}) {
|
||||
return (
|
||||
<CardContainer href={href} className={clsx(containerClassName, isSoon && styles.cardSoon)}>
|
||||
<div className={clsx(styles.cardIconContainer)}>
|
||||
{icon}
|
||||
{isSoon && <Badge variant={'purple'}>Guide coming soon</Badge>}
|
||||
{badge && <Badge {...badge} />}
|
||||
</div>
|
||||
<div className={clsx(styles.contentContainer)}>
|
||||
<span className={clsx(styles.cardTitle)} title={title}>
|
||||
{title}
|
||||
</span>
|
||||
{description && (
|
||||
<p
|
||||
className={clsx(styles.cardDescription)}
|
||||
title={description}>
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
{html && (
|
||||
<p
|
||||
className={clsx(styles.cardDescription)}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: html
|
||||
}}
|
||||
></p>
|
||||
)}
|
||||
</div>
|
||||
</CardContainer>
|
||||
);
|
||||
}
|
||||
|
||||
function getCardIcon (item) {
|
||||
if (item.customProps?.themedImage) {
|
||||
return (
|
||||
<BorderedIcon icon={{
|
||||
light: item.customProps.themedImage.light,
|
||||
dark: item.customProps.themedImage.dark
|
||||
}} wrapperClassName='card-icon-wrapper' iconClassName={'card-icon'} />
|
||||
)
|
||||
} else if (item.customProps?.image) {
|
||||
return (
|
||||
<BorderedIcon icon={{
|
||||
light: item.customProps.image
|
||||
}} wrapperClassName='card-icon-wrapper' iconClassName={'card-icon'} />
|
||||
);
|
||||
} else if (item.customProps?.icon) {
|
||||
return <BorderedIcon
|
||||
IconComponent={item.customProps.icon}
|
||||
wrapperClassName='card-icon-wrapper' iconClassName={'card-icon'} />;
|
||||
} else if (item.customProps?.iconName && Icons.hasOwnProperty(item.customProps?.iconName)) {
|
||||
return <BorderedIcon
|
||||
IconComponent={Icons[item.customProps?.iconName]}
|
||||
wrapperClassName='card-icon-wrapper' iconClassName={'card-icon'} />;
|
||||
} else {
|
||||
return (
|
||||
<div className={clsx('card-icon-wrapper', 'no-zoom-img')}>
|
||||
{isInternalUrl(item.href) ? '📄️' : '🔗'}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function CardCategory({item}) {
|
||||
const href = findFirstCategoryLink(item);
|
||||
const icon = getCardIcon(item);
|
||||
// Unexpected: categories that don't have a link have been filtered upfront
|
||||
if (!href) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<CardLayout
|
||||
href={href}
|
||||
icon={icon}
|
||||
title={item.label}
|
||||
description={translate(
|
||||
{
|
||||
message: item.customProps?.description || '{count} items',
|
||||
id: 'theme.docs.DocCard.categoryDescription',
|
||||
description:
|
||||
'The default description for a category card in the generated index about how many items this category includes',
|
||||
},
|
||||
{count: item.items.length},
|
||||
)}
|
||||
containerClassName={item.customProps?.className}
|
||||
isSoon={item.customProps?.isSoon}
|
||||
badge={item.customProps?.badge}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function CardLink({item}) {
|
||||
const icon = getCardIcon(item);
|
||||
const doc = useDocById(item.docId ?? undefined);
|
||||
|
||||
return (
|
||||
<CardLayout
|
||||
href={item.href}
|
||||
icon={icon}
|
||||
title={item.label}
|
||||
description={item.customProps?.description || doc?.description}
|
||||
html={item.customProps?.html}
|
||||
containerClassName={item.customProps?.className}
|
||||
isSoon={item.customProps?.isSoon}
|
||||
badge={item.customProps?.badge}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default function DocCard({item}) {
|
||||
switch (item.type) {
|
||||
case 'link':
|
||||
return <CardLink item={item} />;
|
||||
case 'category':
|
||||
return <CardCategory item={item} />;
|
||||
default:
|
||||
throw new Error(`unknown item type ${JSON.stringify(item)}`);
|
||||
}
|
||||
}
|
||||
287
www/docs/src/theme/DocCard/index.tsx
Normal file
287
www/docs/src/theme/DocCard/index.tsx
Normal file
@@ -0,0 +1,287 @@
|
||||
import React, { type ReactNode } from "react"
|
||||
import clsx from "clsx"
|
||||
import Link from "@docusaurus/Link"
|
||||
import {
|
||||
findFirstCategoryLink,
|
||||
useDocById,
|
||||
} from "@docusaurus/theme-common/internal"
|
||||
import isInternalUrl from "@docusaurus/isInternalUrl"
|
||||
import { translate } from "@docusaurus/Translate"
|
||||
import BorderedIcon from "@site/src/components/BorderedIcon"
|
||||
import Badge, { BadgeProps } from "@site/src/components/Badge"
|
||||
import Icons from "@site/src/theme/Icon"
|
||||
import {
|
||||
ModifiedPropSidebarItemCategory,
|
||||
ModifiedPropSidebarItemLink,
|
||||
ModifiedSidebarItem,
|
||||
} from "@medusajs/docs"
|
||||
|
||||
type ModifiedProps = {
|
||||
item: ModifiedSidebarItem
|
||||
}
|
||||
|
||||
function CardContainer({
|
||||
href,
|
||||
children,
|
||||
className,
|
||||
}: {
|
||||
href: string
|
||||
children: ReactNode
|
||||
className?: string
|
||||
}): JSX.Element {
|
||||
return (
|
||||
<article className={`card-wrapper margin-bottom--lg`}>
|
||||
<Link
|
||||
href={href}
|
||||
className={clsx(
|
||||
"card",
|
||||
"tw-bg-medusa-bg-subtle dark:tw-bg-medusa-bg-base-dark",
|
||||
"tw-rounded tw-border tw-border-solid tw-border-medusa-bg-subtle-hover dark:tw-border-medusa-bg-base-hover-dark",
|
||||
"tw-shadow-none tw-transition-all tw-duration-200 tw-ease-ease",
|
||||
"tw-flex tw-p-1 tw-h-full",
|
||||
className
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
|
||||
function CardLayout({
|
||||
href,
|
||||
icon,
|
||||
title,
|
||||
description,
|
||||
html,
|
||||
containerClassName,
|
||||
isSoon = false,
|
||||
badge,
|
||||
}: {
|
||||
href: string
|
||||
icon: ReactNode
|
||||
title: string
|
||||
description?: string
|
||||
html?: string
|
||||
containerClassName?: string
|
||||
isSoon?: boolean
|
||||
badge?: BadgeProps
|
||||
}): JSX.Element {
|
||||
const isHighlighted = containerClassName?.includes("card-highlighted")
|
||||
return (
|
||||
<CardContainer
|
||||
href={href}
|
||||
className={clsx(
|
||||
containerClassName,
|
||||
!isSoon &&
|
||||
"hover:tw-bg-medusa-bg-subtle-hover dark:hover:tw-bg-medusa-bg-base-hover-dark",
|
||||
isSoon && "tw-pointer-events-none",
|
||||
isHighlighted &&
|
||||
"md:before:tw-content-[''] md:before:tw-absolute md:before:tw-top-0 before:tw-right-0 md:before:tw-w-1/2 md:before:tw-h-full md:before:tw-bg-no-repeat md:before:tw-bg-cover md:before:tw-bg-card-highlighted dark:md:before:tw-bg-card-highlighted-dark"
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx("tw-mb-1 tw-flex tw-justify-between tw-items-center")}
|
||||
>
|
||||
{icon}
|
||||
{isSoon && <Badge variant={"purple"}>Guide coming soon</Badge>}
|
||||
{badge && <Badge {...badge} />}
|
||||
</div>
|
||||
<div className={clsx("tw-w-[calc(100%-20px)] [&>*:last-child]:tw-mb-0")}>
|
||||
<span
|
||||
className={clsx(
|
||||
"tw-text-label-regular-plus tw-text-medusa-text-base dark:tw-text-medusa-text-base-dark",
|
||||
"tw-mb-0.5 tw-block",
|
||||
"tw-transition-all tw-duration-200 tw-ease-ease",
|
||||
isSoon &&
|
||||
"group-hover:tw-text-medusa-text-disabled dark:group-hover:tw-text-medusa-text-disabled-dark"
|
||||
)}
|
||||
title={title}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
{description && (
|
||||
<p
|
||||
className={clsx(
|
||||
"tw-text-label-regular tw-text-medusa-text-subtle dark:tw-text-medusa-text-subtle-dark",
|
||||
"tw-transition-all tw-duration-200 tw-ease-ease",
|
||||
isSoon &&
|
||||
"group-hover:tw-text-medusa-text-disabled dark:group-hover:tw-text-medusa-text-disabled-dark",
|
||||
isHighlighted && "md:tw-w-1/2"
|
||||
)}
|
||||
title={description}
|
||||
>
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
{html && (
|
||||
<p
|
||||
className={clsx(
|
||||
"tw-text-label-regular tw-text-medusa-text-subtle dark:tw-text-medusa-text-subtle-dark",
|
||||
"tw-transition-all tw-duration-200 tw-ease-ease",
|
||||
isSoon &&
|
||||
"group-hover:tw-text-medusa-text-disabled dark:group-hover:tw-text-medusa-text-disabled-dark",
|
||||
isHighlighted && "md:tw-w-1/2"
|
||||
)}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: html,
|
||||
}}
|
||||
></p>
|
||||
)}
|
||||
</div>
|
||||
</CardContainer>
|
||||
)
|
||||
}
|
||||
|
||||
function getCardIcon(item: ModifiedSidebarItem): JSX.Element {
|
||||
if (item.customProps?.themedImage) {
|
||||
return (
|
||||
<BorderedIcon
|
||||
icon={{
|
||||
light: item.customProps.themedImage.light,
|
||||
dark: item.customProps.themedImage.dark,
|
||||
}}
|
||||
wrapperClassName={
|
||||
clsx()
|
||||
// "card-icon-wrapper",
|
||||
}
|
||||
iconWrapperClassName={clsx(
|
||||
item.customProps?.className?.includes("card-highlighted") &&
|
||||
"tw-p-[6px]"
|
||||
)}
|
||||
iconClassName={clsx("tw-h-[20px] tw-w-[20px]")}
|
||||
/>
|
||||
)
|
||||
} else if (item.customProps?.image) {
|
||||
return (
|
||||
<BorderedIcon
|
||||
icon={{
|
||||
light: item.customProps.image,
|
||||
}}
|
||||
wrapperClassName={
|
||||
clsx()
|
||||
// "card-icon-wrapper",
|
||||
}
|
||||
iconWrapperClassName={clsx(
|
||||
item.customProps?.className?.includes("card-highlighted") &&
|
||||
"tw-p-[6px]"
|
||||
)}
|
||||
iconClassName={clsx("tw-h-[20px] tw-w-[20px]")}
|
||||
/>
|
||||
)
|
||||
} else if (item.customProps?.icon) {
|
||||
return (
|
||||
<BorderedIcon
|
||||
IconComponent={item.customProps.icon}
|
||||
wrapperClassName={
|
||||
clsx()
|
||||
// "card-icon-wrapper",
|
||||
}
|
||||
iconWrapperClassName={clsx(
|
||||
item.customProps?.className?.includes("card-highlighted") &&
|
||||
"tw-p-[6px]"
|
||||
)}
|
||||
iconClassName={clsx("tw-h-[20px] tw-w-[20px]")}
|
||||
/>
|
||||
)
|
||||
} else if (
|
||||
item.customProps?.iconName &&
|
||||
Object.hasOwn(Icons, item.customProps?.iconName)
|
||||
) {
|
||||
return (
|
||||
<BorderedIcon
|
||||
IconComponent={Icons[item.customProps?.iconName]}
|
||||
wrapperClassName={
|
||||
clsx()
|
||||
// "card-icon-wrapper",
|
||||
}
|
||||
iconWrapperClassName={clsx(
|
||||
item.customProps?.className?.includes("card-highlighted") &&
|
||||
"tw-p-[6px]"
|
||||
)}
|
||||
iconClassName={clsx("tw-h-[20px] tw-w-[20px]")}
|
||||
/>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
// "card-icon-wrapper",
|
||||
"no-zoom-img"
|
||||
)}
|
||||
>
|
||||
{isInternalUrl(
|
||||
"href" in item ? item.href : "value" in item ? item.value : "#"
|
||||
)
|
||||
? "📄️"
|
||||
: "🔗"}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function CardCategory({
|
||||
item,
|
||||
}: {
|
||||
item: ModifiedPropSidebarItemCategory
|
||||
}): JSX.Element | null {
|
||||
const href = findFirstCategoryLink(item)
|
||||
const icon = getCardIcon(item)
|
||||
// Unexpected: categories that don't have a link have been filtered upfront
|
||||
if (!href) {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<CardLayout
|
||||
href={href}
|
||||
icon={icon}
|
||||
title={item.label}
|
||||
// eslint-disable-next-line @docusaurus/string-literal-i18n-messages
|
||||
description={translate(
|
||||
{
|
||||
message: item.customProps?.description || "{count} items",
|
||||
id: "theme.docs.DocCard.categoryDescription",
|
||||
description:
|
||||
"The default description for a category card in the generated index about how many items this category includes",
|
||||
},
|
||||
{ count: item.items.length }
|
||||
)}
|
||||
containerClassName={item.customProps?.className}
|
||||
isSoon={item.customProps?.isSoon}
|
||||
badge={item.customProps?.badge}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function CardLink({
|
||||
item,
|
||||
}: {
|
||||
item: ModifiedPropSidebarItemLink
|
||||
}): JSX.Element {
|
||||
const icon = getCardIcon(item)
|
||||
const doc = useDocById(item.docId ?? undefined)
|
||||
|
||||
return (
|
||||
<CardLayout
|
||||
href={item.href}
|
||||
icon={icon}
|
||||
title={item.label}
|
||||
description={item.customProps?.description || doc?.description}
|
||||
html={item.customProps?.html}
|
||||
containerClassName={item.customProps?.className}
|
||||
isSoon={item.customProps?.isSoon}
|
||||
badge={item.customProps?.badge}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default function DocCard({ item }: ModifiedProps): JSX.Element {
|
||||
switch (item.type) {
|
||||
case "link":
|
||||
return <CardLink item={item} />
|
||||
case "category":
|
||||
return <CardCategory item={item} />
|
||||
default:
|
||||
throw new Error(`unknown item type ${JSON.stringify(item)}`)
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
.cardContainer {
|
||||
box-shadow: none !important;
|
||||
transition: all var(--ifm-transition-fast) ease;
|
||||
display: flex;
|
||||
padding: var(--ifm-base-spacing);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.cardContainer *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.cardContainer:not(.cardSoon):hover {
|
||||
background-color: var(--ifm-card-bg-hover);
|
||||
}
|
||||
|
||||
.cardIconContainer {
|
||||
margin-bottom: calc(var(--ifm-base-margin-vertical) / 2);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.cardTitle {
|
||||
font-size: var(--medusa-label-regular-plus-size);
|
||||
line-height: var(--medusa-label-regular-plus-line-height);
|
||||
font-weight: var(--medusa-label-regular-plus-font-weight);
|
||||
color: var(--ifm-color-primary);
|
||||
margin-bottom: calc(var(--ifm-base-margin-vertical) / 4);
|
||||
display: block;
|
||||
}
|
||||
|
||||
.cardDescription {
|
||||
font-size: var(--medusa-label-regular-size);
|
||||
line-height: var(--medusa-label-regular-line-height);
|
||||
font-weight: var(--medusa-label-regular-font-weight);
|
||||
color: var(--ifm-color-content);
|
||||
}
|
||||
|
||||
.cardTitle,
|
||||
.cardDescription {
|
||||
transition: all var(--ifm-transition-fast) ease;
|
||||
}
|
||||
|
||||
.contentContainer {
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
|
||||
.cardSoon {
|
||||
pointer-events: none;
|
||||
}
|
||||
Reference in New Issue
Block a user