Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions apps/docs/components/copy-button.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import {FC} from "react";
import {Button, ButtonProps} from "@nextui-org/react";
import {useClipboard} from "@nextui-org/use-clipboard";
import {clsx} from "@nextui-org/shared-utils";

import {CheckLinearIcon, CopyLinearIcon} from "@/components/icons";

export interface CopyButtonProps extends ButtonProps {
value?: string;
}

export const CopyButton: FC<CopyButtonProps> = ({value, ...buttonProps}) => {
export const CopyButton: FC<CopyButtonProps> = ({value, className, ...buttonProps}) => {
const {copy, copied} = useClipboard();

const handleCopy = () => {
Expand All @@ -18,19 +19,22 @@ export const CopyButton: FC<CopyButtonProps> = ({value, ...buttonProps}) => {
return (
<Button
isIconOnly
className="absolute z-50 right-3 top-8 border-1 border-transparent bg-transparent before:bg-white/10 before:content-[''] before:block before:z-[-1] before:absolute before:inset-0 before:backdrop-blur-md before:backdrop-saturate-100 before:rounded-lg"
className={clsx(
"absolute z-50 right-3 text-zinc-300 top-8 border-1 border-transparent bg-transparent before:bg-white/10 before:content-[''] before:block before:z-[-1] before:absolute before:inset-0 before:backdrop-blur-md before:backdrop-saturate-100 before:rounded-lg",
className,
)}
size="sm"
variant="bordered"
onPress={handleCopy}
{...buttonProps}
>
<CheckLinearIcon
className="absolute opacity-0 scale-50 text-zinc-300 data-[visible=true]:opacity-100 data-[visible=true]:scale-100 transition-transform-opacity"
className="absolute opacity-0 scale-50 data-[visible=true]:opacity-100 data-[visible=true]:scale-100 transition-transform-opacity"
data-visible={copied}
size={16}
/>
<CopyLinearIcon
className="absolute opacity-0 scale-50 text-zinc-300 data-[visible=true]:opacity-100 data-[visible=true]:scale-100 transition-transform-opacity"
className="absolute opacity-0 scale-50 data-[visible=true]:opacity-100 data-[visible=true]:scale-100 transition-transform-opacity"
data-visible={!copied}
size={16}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export const CodeDemo: React.FC<CodeDemoProps> = ({
<DynamicReactLiveDemo
className={className}
code={code}
files={files}
gradientColor={gradientColor}
height={previewHeight}
isCentered={isPreviewCentered}
Expand Down
10 changes: 10 additions & 0 deletions apps/docs/components/docs/components/code-demo/react-live-demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import * as reactHookForm from "react-hook-form";

import {BgGridContainer} from "@/components/bg-grid-container";
import {GradientBox, GradientBoxProps} from "@/components/gradient-box";
import {CopyButton} from "@/components/copy-button";

export interface ReactLiveDemoProps {
code: string;
files: string[];
noInline?: boolean;
height?: string | number;
isCentered?: boolean;
Expand All @@ -27,8 +29,11 @@ export const scope = {
...reactHookForm,
} as Record<string, unknown>;

const DEFAULT_FILE = "/App.jsx";

export const ReactLiveDemo: React.FC<ReactLiveDemoProps> = ({
code,
files,
isGradientBox,
gradientColor = "orange",
isCentered = false,
Expand All @@ -38,6 +43,11 @@ export const ReactLiveDemo: React.FC<ReactLiveDemoProps> = ({
}) => {
const content = (
<>
{files?.[DEFAULT_FILE] && (
<div className="absolute top-[-24px] right-[-8px]">
<CopyButton className="text-zinc-400" value={files?.[DEFAULT_FILE]} />
</div>
)}
<LivePreview
className={clsx("live-preview flex h-full w-full not-prose", {
"justify-center items-center": isCentered,
Expand Down
33 changes: 33 additions & 0 deletions apps/docs/components/icons/info-circle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from "react";

export const InfoCircle = ({
size = 24,
width,
height,
...props
}: {
size?: number;
width?: number;
height?: number;
[key: string]: any;
}) => (
<svg
fill="none"
height={size || height}
viewBox="0 0 24 24"
width={size || width}
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z"
stroke="currentColor"
strokeWidth="1.5"
/>
<path d="M12 17V11" stroke="currentColor" strokeLinecap="round" strokeWidth="1.5" />
<path
d="M12 7C12.5523 7 13 7.44772 13 8C13 8.55228 12.5523 9 12 9C11.4477 9 11 8.55228 11 8C11 7.44772 11.4477 7 12 7Z"
fill="currentColor"
/>
</svg>
);
102 changes: 100 additions & 2 deletions apps/docs/components/mdx-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,23 @@ import NextImage from "next/image";
import {usePostHog} from "posthog-js/react";

import {ThemeSwitch} from "./theme-switch";
import {InfoCircle} from "./icons/info-circle";

import {Sandpack} from "@/components/sandpack";
import {CarbonAd} from "@/components/ads/carbon-ad";
import * as DocsComponents from "@/components/docs/components";
import * as BlogComponents from "@/components/blog/components";
import {Codeblock} from "@/components/docs/components";
import {VirtualAnchor, virtualAnchorEncode} from "@/components/virtual-anchor";
import {
Table as StaticTable,
TableHeader,
TableBody,
TableRow,
TableCell,
TableColumnHeader,
TableRoot,
} from "@/components/static-table";

const Table: React.FC<{children?: React.ReactNode}> = ({children}) => {
return (
Expand Down Expand Up @@ -103,9 +113,14 @@ const List: React.FC<{children?: React.ReactNode}> = ({children}) => {
);
};

const InlineCode = ({children}: {children?: React.ReactNode}) => {
const InlineCode = ({children, className}: {children?: React.ReactNode; className?: string}) => {
return (
<Components.Code className="font-normal text-default-700 bg-default-200/50 dark:bg-default-100/60 px-2 py-0.5">
<Components.Code
className={clsx(
"font-mono text-tiny rounded-md text-default-500 bg-default-100 dark:bg-default-100/80 px-1.5 py-0.5",
className,
)}
>
{children}
</Components.Code>
);
Expand Down Expand Up @@ -187,6 +202,88 @@ const Link = ({href, children}: {href?: string; children?: React.ReactNode}) =>
);
};

interface APITableProps {
data: {
attribute: string;
type: string;
description: string;
default?: string;
}[];
}

export const APITable: React.FC<APITableProps> = ({data}) => {
return (
<TableRoot className="overflow-x-auto overflow-y-hidden">
<StaticTable aria-label="API table" className="w-full" layout="auto">
<TableHeader>
<TableRow>
<TableColumnHeader>Prop</TableColumnHeader>
<TableColumnHeader>Type</TableColumnHeader>
<TableColumnHeader>Default</TableColumnHeader>
</TableRow>
</TableHeader>
<TableBody>
{data.map((item, index) => (
<TableRow key={index} className="[&>td]:px-2 [&>td]:py-1.5 [&>td]:first:pt-4">
<TableCell className="flex items-center gap-1 font-mono text-small whitespace-nowrap">
<InlineCode className="text-default-700 bg-default-100 dark:bg-default-100/80">
{item.attribute}
</InlineCode>
{item.description && (
<Components.Tooltip
classNames={{
content: "max-w-[240px]",
}}
content={item.description}
delay={0}
placement="top"
>
<div className="flex items-center gap-1 cursor-help">
<InfoCircle className="text-default-400" size={16} />
</div>
</Components.Tooltip>
)}
</TableCell>
<TableCell className="font-mono text-small whitespace-nowrap text-primary">
<InlineCode>
<div className="flex max-w-[300px] flex-wrap text-wrap">{item.type}</div>
</InlineCode>
</TableCell>
<TableCell className="font-mono text-small whitespace-nowrap">
{item.default && item.default !== "-" ? (
<InlineCode>
{item.default !== "true" && item.default !== "false"
? `"${item.default}"`
: item.default}
</InlineCode>
) : (
<svg
aria-hidden="true"
className="text-default-400"
fill="none"
focusable="false"
height="15"
viewBox="0 0 15 15"
width="15"
xmlns="http://www.w3.org/2000/svg"
>
<path
clipRule="evenodd"
d="M2 7.5C2 7.22386 2.22386 7 2.5 7H12.5C12.7761 7 13 7.22386 13 7.5C13 7.77614 12.7761 8 12.5 8H2.5C2.22386 8 2 7.77614 2 7.5Z"
fill="currentColor"
fillRule="evenodd"
/>
</svg>
)}
</TableCell>
</TableRow>
))}
</TableBody>
</StaticTable>
</TableRoot>
);
};

export const MDXComponents = {
/**
* Next.js components
Expand Down Expand Up @@ -239,5 +336,6 @@ export const MDXComponents = {
{...props}
/>
),
APITable,
// Block,
} as unknown as Record<string, React.ReactNode>;
4 changes: 2 additions & 2 deletions apps/docs/components/sandpack/copy-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import {useClipboard} from "@nextui-org/use-clipboard";

import {CopyLinearIcon} from "@/components/icons";

export const CopyButton = () => {
export const CopyButton = ({code: codeProp}: {code?: string}) => {
const {copy, copied} = useClipboard();

const {sandpack} = useSandpack();

const copyHandler = () => {
const code = sandpack.files[sandpack.activeFile].code;
const code = codeProp ?? sandpack.files[sandpack.activeFile].code;

copy(code);
};
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/components/sandpack/language-selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const LanguageSelector: React.FC<LanguageSelectorProps> = ({template, onC
aria-label="Language selector"
classNames={{
base: "absolute z-10 right-3 bottom-4",
cursor: "bg-zinc-400 dark:bg-zinc-700",
cursor: "bg-default-600 dark:bg-default-300",
tabList:
"bg-transparent relative before:bg-white/5 before:w-full before:rounded-lg before:h-full before:content-[''] before:block before:z-1 before:absolute before:inset-0 before:backdrop-blur-md before:backdrop-saturate-100",
}}
Expand Down
73 changes: 73 additions & 0 deletions apps/docs/components/static-table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import type {ComponentProps, FC} from "react";

import {cn, table} from "@nextui-org/theme";

const tableSlots = table();

export const TableRoot: FC<ComponentProps<"div">> = ({children, className, ...props}) => {
return (
<div {...props} className={tableSlots.base({className})}>
{children}
</div>
);
};

export const Table: FC<
ComponentProps<"table"> & {
layout?: "fixed" | "auto";
}
> = ({children, className, layout = "auto", ...props}) => {
return (
<table {...props} className={tableSlots.table({className, layout})}>
{children}
</table>
);
};

export const TableHeader: FC<ComponentProps<"thead">> = ({children, className, ...props}) => {
return (
<thead {...props} className={tableSlots.thead({className})}>
{children}
</thead>
);
};

export const TableBody: FC<ComponentProps<"tbody">> = ({children, className, ...props}) => {
return (
<tbody {...props} className={tableSlots.tbody({className})}>
{children}
</tbody>
);
};

export const TableRow: FC<ComponentProps<"tr">> = ({children, className, ...props}) => {
return (
<tr {...props} className={tableSlots.tr({className})}>
{children}
</tr>
);
};

export const TableColumnHeader: FC<ComponentProps<"th">> = ({children, className, ...props}) => {
return (
<td {...props} className={tableSlots.th({className})}>
{children}
</td>
);
};

export const TableCell: FC<ComponentProps<"td">> = ({children, className, ...props}) => {
return (
<td {...props} className={tableSlots.td({class: cn("p-0", className)})}>
{children}
</td>
);
};

export const TableColumn: FC<ComponentProps<"th">> = ({children, className, ...props}) => {
return (
<th {...props} className={tableSlots.th({class: cn("p-0", className)})}>
{children}
</th>
);
};
Loading