chore(ui,icons,ui-preset,toolbox): Move design system packages to monorepo (#5470)
This commit is contained in:
committed by
GitHub
parent
71853eafdd
commit
e4ce2f4e07
@@ -0,0 +1,52 @@
|
||||
import React from "react"
|
||||
import type { Meta, StoryObj } from "@storybook/react"
|
||||
|
||||
import { CodeBlock } from "./code-block"
|
||||
import { Label } from "../label"
|
||||
|
||||
const meta: Meta<typeof CodeBlock> = {
|
||||
title: "Components/CodeBlock",
|
||||
component: CodeBlock,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
},
|
||||
}
|
||||
|
||||
export default meta
|
||||
|
||||
type Story = StoryObj<typeof CodeBlock>
|
||||
|
||||
const snippets = [
|
||||
{
|
||||
label: "cURL",
|
||||
language: "markdown",
|
||||
code: `curl -H 'x-publishable-key: YOUR_API_KEY' 'http://localhost:9000/store/products/PRODUCT_ID'`,
|
||||
},
|
||||
{
|
||||
label: "Medusa JS Client",
|
||||
language: "jsx",
|
||||
code: `// Install the JS Client in your storefront project: @medusajs/medusa-js\n\nimport Medusa from "@medusajs/medusa-js"\n\nconst medusa = new Medusa({ publishableApiKey: "YOUR_API_KEY"})\nconst product = await medusa.products.retrieve("PRODUCT_ID")\nconsole.log(product.id)`,
|
||||
},
|
||||
{
|
||||
label: "Medusa React",
|
||||
language: "tsx",
|
||||
code: `// Install the React SDK and required dependencies in your storefront project:\n// medusa-react @tanstack/react-query @medusajs/medusa\n\nimport { useProduct } from "medusa-react"\n\nconst { product } = useProduct("PRODUCT_ID")\nconsole.log(product.id)`,
|
||||
},
|
||||
]
|
||||
|
||||
export const Default: Story = {
|
||||
render: () => {
|
||||
return (
|
||||
<div className="h-[300px] w-[700px]">
|
||||
<CodeBlock snippets={snippets}>
|
||||
<CodeBlock.Header>
|
||||
<CodeBlock.Header.Meta>
|
||||
<Label weight={"plus"}>/product-detail.js</Label>
|
||||
</CodeBlock.Header.Meta>
|
||||
</CodeBlock.Header>
|
||||
<CodeBlock.Body />
|
||||
</CodeBlock>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
"use client"
|
||||
import { Highlight, themes } from "prism-react-renderer"
|
||||
import * as React from "react"
|
||||
|
||||
import { Copy } from "@/components/copy"
|
||||
import { clx } from "@/utils/clx"
|
||||
|
||||
export type CodeSnippet = {
|
||||
label: string
|
||||
language: string
|
||||
code: string
|
||||
hideLineNumbers?: boolean
|
||||
}
|
||||
|
||||
type CodeBlockState = {
|
||||
snippets: CodeSnippet[]
|
||||
active: CodeSnippet
|
||||
setActive: (active: CodeSnippet) => void
|
||||
} | null
|
||||
|
||||
const CodeBlockContext = React.createContext<CodeBlockState>(null)
|
||||
|
||||
const useCodeBlockContext = () => {
|
||||
const context = React.useContext(CodeBlockContext)
|
||||
|
||||
if (context === null)
|
||||
throw new Error(
|
||||
"useCodeBlockContext can only be used within a CodeBlockContext"
|
||||
)
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
type RootProps = {
|
||||
snippets: CodeSnippet[]
|
||||
}
|
||||
|
||||
const Root = ({
|
||||
snippets,
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLDivElement> & RootProps) => {
|
||||
const [active, setActive] = React.useState(snippets[0])
|
||||
|
||||
return (
|
||||
<CodeBlockContext.Provider value={{ snippets, active, setActive }}>
|
||||
<div
|
||||
className={clx(
|
||||
"border-ui-code-border overflow-hidden rounded-lg border",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</CodeBlockContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
type HeaderProps = {
|
||||
hideLabels?: boolean
|
||||
}
|
||||
|
||||
const HeaderComponent = ({
|
||||
children,
|
||||
className,
|
||||
hideLabels = false,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLDivElement> & HeaderProps) => {
|
||||
const { snippets, active, setActive } = useCodeBlockContext()
|
||||
return (
|
||||
<div
|
||||
className={clx(
|
||||
"border-b-ui-code-border bg-ui-code-bg-header flex items-center gap-2 border-b px-4 py-3",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{!hideLabels &&
|
||||
snippets.map((snippet) => (
|
||||
<div
|
||||
className={clx(
|
||||
"text-ui-code-text-subtle txt-compact-small-plus cursor-pointer rounded-full border border-transparent px-3 py-2 transition-all",
|
||||
{
|
||||
"text-ui-code-text-base border-ui-code-border bg-ui-code-bg-base cursor-default":
|
||||
active.label === snippet.label,
|
||||
}
|
||||
)}
|
||||
key={snippet.label}
|
||||
onClick={() => setActive(snippet)}
|
||||
>
|
||||
{snippet.label}
|
||||
</div>
|
||||
))}
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const Meta = ({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLDivElement>) => {
|
||||
return (
|
||||
<div
|
||||
className={clx("text-ui-code-text-subtle ml-auto", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const Header = Object.assign(HeaderComponent, { Meta })
|
||||
|
||||
const Body = ({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLDivElement>) => {
|
||||
const { active } = useCodeBlockContext()
|
||||
return (
|
||||
<div
|
||||
className={clx("bg-ui-code-bg-base relative p-4", className)}
|
||||
{...props}
|
||||
>
|
||||
<Copy
|
||||
content={active.code}
|
||||
className="text-ui-code-icon absolute right-4 top-4"
|
||||
/>
|
||||
<div className="max-w-[90%]">
|
||||
<Highlight
|
||||
theme={{
|
||||
...themes.palenight,
|
||||
plain: {
|
||||
color: "rgba(249, 250, 251, 1)",
|
||||
backgroundColor: "#111827",
|
||||
},
|
||||
styles: [
|
||||
{
|
||||
types: ["keyword"],
|
||||
style: {
|
||||
color: "var(--fg-on-color)",
|
||||
},
|
||||
},
|
||||
{
|
||||
types: ["maybe-class-name"],
|
||||
style: {
|
||||
color: "rgb(255, 203, 107)",
|
||||
},
|
||||
},
|
||||
...themes.palenight.styles,
|
||||
],
|
||||
}}
|
||||
code={active.code}
|
||||
language={active.language}
|
||||
>
|
||||
{({ style, tokens, getLineProps, getTokenProps }) => (
|
||||
<pre
|
||||
className="txt-compact-small whitespace-pre-wrap bg-transparent font-mono"
|
||||
style={{
|
||||
...style,
|
||||
background: "transparent",
|
||||
}}
|
||||
>
|
||||
{tokens.map((line, i) => (
|
||||
<div key={i} {...getLineProps({ line })} className="flex">
|
||||
{!active.hideLineNumbers && (
|
||||
<span className="text-ui-code-text-subtle">{i + 1}</span>
|
||||
)}
|
||||
<div className="pl-4">
|
||||
{line.map((token, key) => (
|
||||
<span key={key} {...getTokenProps({ token })} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</pre>
|
||||
)}
|
||||
</Highlight>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const CodeBlock = Object.assign(Root, { Body, Header, Meta })
|
||||
|
||||
export { CodeBlock }
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./code-block"
|
||||
Reference in New Issue
Block a user