docs: redesign notes (#8661)
* docs: redesign notes * fix color for warning notes * allow optional links * show links in a note * allow line code in notes
This commit is contained in:
@@ -1,60 +1,111 @@
|
||||
import React from "react"
|
||||
import React, { useMemo } from "react"
|
||||
import { NoteProps } from ".."
|
||||
import clsx from "clsx"
|
||||
import { MarkdownContent } from "../../.."
|
||||
|
||||
type NoteLayoutProps = NoteProps & {
|
||||
icon: React.ReactNode
|
||||
type StringInfo = {
|
||||
allStringChildren: boolean
|
||||
stringChildren: string[]
|
||||
}
|
||||
|
||||
export const NoteLayout = ({
|
||||
type,
|
||||
title,
|
||||
children,
|
||||
icon,
|
||||
}: NoteLayoutProps) => {
|
||||
const isDefaultStyle =
|
||||
type === "default" ||
|
||||
type === "success" ||
|
||||
type === "error" ||
|
||||
type === "check"
|
||||
const isWarningStyle = type === "warning"
|
||||
const isSoonStyle = type === "soon"
|
||||
type NoteLayoutProps = NoteProps
|
||||
|
||||
export const NoteLayout = ({ type, title, children }: NoteLayoutProps) => {
|
||||
const getStringInfoFromChildren = (nodes: React.ReactNode): StringInfo => {
|
||||
let allStringChildren = true
|
||||
const stringChildren: string[] = []
|
||||
|
||||
React.Children.forEach(nodes, (child) => {
|
||||
if (!allStringChildren) {
|
||||
return
|
||||
} else if (["string", "number"].includes(typeof child)) {
|
||||
stringChildren.push(`${child}`)
|
||||
} else if (Array.isArray(child)) {
|
||||
const childInfo = getStringInfoFromChildren(child)
|
||||
allStringChildren = childInfo.allStringChildren
|
||||
stringChildren.push(...childInfo.stringChildren)
|
||||
} else if (
|
||||
React.isValidElement(child) &&
|
||||
typeof child.props === "object" &&
|
||||
child.props &&
|
||||
"children" in child.props &&
|
||||
child.props.children
|
||||
) {
|
||||
const typeStr = child.type.toString()
|
||||
if (typeStr.includes(`"li"`)) {
|
||||
allStringChildren = false
|
||||
return
|
||||
} else if (
|
||||
"href" in child.props &&
|
||||
typeof child.props.children === "string"
|
||||
) {
|
||||
stringChildren.push(`[${child.props.children}](${child.props.href})`)
|
||||
return
|
||||
} else if (
|
||||
typeStr.includes("InlineCode") &&
|
||||
typeof child.props.children === "string"
|
||||
) {
|
||||
stringChildren.push(`\`${child.props.children}\``)
|
||||
return
|
||||
}
|
||||
|
||||
const childInfo = getStringInfoFromChildren(
|
||||
child.props.children as React.ReactNode
|
||||
)
|
||||
allStringChildren = childInfo.allStringChildren
|
||||
stringChildren.push(...childInfo.stringChildren)
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
allStringChildren,
|
||||
stringChildren,
|
||||
}
|
||||
}
|
||||
const { allStringChildren, stringChildren } = useMemo(() => {
|
||||
const { allStringChildren, stringChildren } =
|
||||
getStringInfoFromChildren(children)
|
||||
|
||||
return {
|
||||
allStringChildren,
|
||||
stringChildren: stringChildren.join(" "),
|
||||
}
|
||||
}, [children])
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"p-docs_0.75 border border-solid rounded shadow-none",
|
||||
isDefaultStyle && "bg-medusa-bg-component border-medusa-border-base",
|
||||
isWarningStyle && "bg-medusa-tag-red-bg border-medusa-tag-red-border",
|
||||
isSoonStyle && "bg-medusa-tag-blue-bg border-medusa-tag-blue-border",
|
||||
"[&_a]:no-underline [&_a]:text-medusa-fg-interactive hover:[&_a]:text-medusa-fg-interactive-hover",
|
||||
"mb-docs_2"
|
||||
"py-[10px] px-docs_0.75 my-docs_0.5",
|
||||
"flex gap-docs_0.75 rounded-docs_DEFAULT items-stretch",
|
||||
"bg-medusa-bg-component border border-medusa-border-base"
|
||||
)}
|
||||
>
|
||||
<div className={clsx("flex gap-docs_0.5")}>
|
||||
{icon}
|
||||
<div
|
||||
className={clsx(
|
||||
isDefaultStyle && "text-medusa-fg-subtle",
|
||||
isWarningStyle && "text-medusa-tag-red-text",
|
||||
isSoonStyle && "text-medusa-tag-blue-text",
|
||||
"text-medium flex-1 [&>*:last-child]:mb-0",
|
||||
"[&>p>code]:px-docs_0.5 [&>p>code]:text-code-label"
|
||||
)}
|
||||
>
|
||||
{title && (
|
||||
<span
|
||||
className={clsx(
|
||||
"text-compact-medium-plus block mb-docs_0.125",
|
||||
isDefaultStyle && "text-medusa-fg-base",
|
||||
isWarningStyle && "text-medusa-tag-red-text",
|
||||
isSoonStyle && "text-medusa-tag-blue-text"
|
||||
)}
|
||||
<span
|
||||
className={clsx(
|
||||
"rounded-full w-docs_0.25",
|
||||
// TODO remove once we use the new prerequisites component across docs
|
||||
(type === "default" || type === "check") &&
|
||||
"bg-medusa-tag-neutral-icon",
|
||||
(type === "error" || type === "warning") && "bg-medusa-tag-red-icon",
|
||||
type === "success" && "bg-medusa-tag-green-icon",
|
||||
// TODO remove once all soon components are removed
|
||||
type === "soon" && "bg-medusa-tag-blue-icon"
|
||||
)}
|
||||
></span>
|
||||
<div className="flex-1">
|
||||
<div className="text-small text-medusa-fg-subtle [&_ol]:!mb-0 [&_ul]:!mb-0">
|
||||
<span className={clsx("text-small-plus text-medusa-fg-base")}>
|
||||
{title}:
|
||||
</span>
|
||||
{allStringChildren && (
|
||||
<MarkdownContent
|
||||
allowedElements={["a", "code"]}
|
||||
unwrapDisallowed={true}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
{stringChildren}
|
||||
</MarkdownContent>
|
||||
)}
|
||||
{children}
|
||||
{!allStringChildren && children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,27 +1,7 @@
|
||||
import React from "react"
|
||||
import { NoteProps } from ".."
|
||||
import { NoteLayout } from "../Layout"
|
||||
import { CheckCircleSolid } from "@medusajs/icons"
|
||||
import clsx from "clsx"
|
||||
|
||||
export const CheckNote = ({
|
||||
title = "Prerequisites",
|
||||
icon,
|
||||
...props
|
||||
}: NoteProps) => {
|
||||
return (
|
||||
<NoteLayout
|
||||
title={title}
|
||||
icon={
|
||||
icon || (
|
||||
<CheckCircleSolid
|
||||
className={clsx(
|
||||
"inline-block mr-docs_0.125 text-medusa-tag-neutral-icon"
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
export const CheckNote = ({ title = "Prerequisites", ...props }: NoteProps) => {
|
||||
return <NoteLayout title={title} {...props} />
|
||||
}
|
||||
|
||||
@@ -1,23 +1,7 @@
|
||||
import React from "react"
|
||||
import { NoteProps } from ".."
|
||||
import { NoteLayout } from "../Layout"
|
||||
import { InformationCircleSolid } from "@medusajs/icons"
|
||||
import clsx from "clsx"
|
||||
|
||||
export const DefaultNote = ({ title = "Note", icon, ...props }: NoteProps) => {
|
||||
return (
|
||||
<NoteLayout
|
||||
title={title}
|
||||
icon={
|
||||
icon || (
|
||||
<InformationCircleSolid
|
||||
className={clsx(
|
||||
"inline-block mr-docs_0.125 text-medusa-tag-neutral-icon"
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
export const DefaultNote = ({ title = "Note", ...props }: NoteProps) => {
|
||||
return <NoteLayout title={title} {...props} />
|
||||
}
|
||||
|
||||
@@ -1,23 +1,7 @@
|
||||
import React from "react"
|
||||
import { NoteProps } from ".."
|
||||
import { NoteLayout } from "../Layout"
|
||||
import { XMark } from "@medusajs/icons"
|
||||
import clsx from "clsx"
|
||||
|
||||
export const ErrorNote = ({ title = "Error", icon, ...props }: NoteProps) => {
|
||||
return (
|
||||
<NoteLayout
|
||||
title={title}
|
||||
icon={
|
||||
icon || (
|
||||
<XMark
|
||||
className={clsx(
|
||||
"inline-block mr-docs_0.125 text-medusa-tag-red-icon"
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
export const ErrorNote = ({ title = "Error", ...props }: NoteProps) => {
|
||||
return <NoteLayout title={title} {...props} />
|
||||
}
|
||||
|
||||
@@ -1,27 +1,7 @@
|
||||
import React from "react"
|
||||
import { NoteProps } from ".."
|
||||
import { NoteLayout } from "../Layout"
|
||||
import { LightBulb } from "@medusajs/icons"
|
||||
import clsx from "clsx"
|
||||
|
||||
export const SoonNote = ({
|
||||
title = "Coming soon",
|
||||
icon,
|
||||
...props
|
||||
}: NoteProps) => {
|
||||
return (
|
||||
<NoteLayout
|
||||
title={title}
|
||||
icon={
|
||||
icon || (
|
||||
<LightBulb
|
||||
className={clsx(
|
||||
"inline-block mr-docs_0.125 text-medusa-tag-blue-icon"
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
export const SoonNote = ({ title = "Coming soon", ...props }: NoteProps) => {
|
||||
return <NoteLayout title={title} {...props} />
|
||||
}
|
||||
|
||||
@@ -1,27 +1,7 @@
|
||||
import React from "react"
|
||||
import { NoteProps } from ".."
|
||||
import { NoteLayout } from "../Layout"
|
||||
import { Check } from "@medusajs/icons"
|
||||
import clsx from "clsx"
|
||||
|
||||
export const SuccessNote = ({
|
||||
title = "Sucess",
|
||||
icon,
|
||||
...props
|
||||
}: NoteProps) => {
|
||||
return (
|
||||
<NoteLayout
|
||||
title={title}
|
||||
icon={
|
||||
icon || (
|
||||
<Check
|
||||
className={clsx(
|
||||
"inline-block mr-docs_0.125 text-medusa-tag-green-icon"
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
export const SuccessNote = ({ title = "Sucess", ...props }: NoteProps) => {
|
||||
return <NoteLayout title={title} {...props} />
|
||||
}
|
||||
|
||||
@@ -1,27 +1,7 @@
|
||||
import React from "react"
|
||||
import { NoteProps } from ".."
|
||||
import { NoteLayout } from "../Layout"
|
||||
import { ExclamationCircleSolid } from "@medusajs/icons"
|
||||
import clsx from "clsx"
|
||||
|
||||
export const WarningNote = ({
|
||||
title = "Warning",
|
||||
icon,
|
||||
...props
|
||||
}: NoteProps) => {
|
||||
return (
|
||||
<NoteLayout
|
||||
title={title}
|
||||
icon={
|
||||
icon || (
|
||||
<ExclamationCircleSolid
|
||||
className={clsx(
|
||||
"inline-block mr-docs_0.125 text-medusa-tag-red-icon"
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
export const WarningNote = ({ title = "Warning", ...props }: NoteProps) => {
|
||||
return <NoteLayout title={title} {...props} />
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ export type NoteProps = {
|
||||
type?: "default" | "warning" | "success" | "error" | "check" | "soon"
|
||||
title?: string
|
||||
children?: React.ReactNode
|
||||
icon?: React.ReactNode
|
||||
}
|
||||
|
||||
export const Note = ({ type = "default", ...props }: NoteProps) => {
|
||||
@@ -21,6 +20,7 @@ export const Note = ({ type = "default", ...props }: NoteProps) => {
|
||||
return <SuccessNote type={type} {...props} />
|
||||
case "error":
|
||||
return <ErrorNote type={type} {...props} />
|
||||
// TODO remove both once we've removed all notes using them
|
||||
case "check":
|
||||
return <CheckNote type={type} {...props} />
|
||||
case "soon":
|
||||
|
||||
Reference in New Issue
Block a user