Skip to content

Commit

Permalink
chore(doc): refactor copyButton
Browse files Browse the repository at this point in the history
  • Loading branch information
Franck Gaudin committed Dec 15, 2023
1 parent ad5705b commit 7921433
Show file tree
Hide file tree
Showing 15 changed files with 124 additions and 180 deletions.
25 changes: 15 additions & 10 deletions apps/docs/components/copyButton/CopyButton.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useState } from "react";
import type { Meta, StoryObj } from "@storybook/react";

import CopyButton from "./CopyButton";
Expand All @@ -13,15 +12,21 @@ type Story = StoryObj<typeof CopyButton>;

export const Default: Story = {
args: {
text: "this text can be copied in 1 click",
text: "this text can be copied in 1 click",
children: "this text can be copied in 1 click"
},
render: (args) => {
const [isCopied, setIsCopied] = useState(false);
return (
<CopyButton {...args} isCopied={isCopied} setIsCopied={setIsCopied} >
{isCopied ? <span >Copied!</span> : args.children}
</CopyButton>
)
}
};

export const Inline: Story = {
args: {
...Default.args,
variant: "inline"
},
};

export const Ghost: Story = {
args: {
...Default.args,
variant: "ghost"
},
};
42 changes: 33 additions & 9 deletions apps/docs/components/copyButton/CopyButton.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,61 @@
"use client";

import React from "react";
import clsx from "clsx";
import React, { type ReactNode } from "react";

import { Button } from "react-aria-components";

import "./copyButton.css";

interface CopyButtonProps {
variant?: "default" | "inline" | "ghost";
text: string;
className?: string;
children?: ReactNode;
onCopy?: () => void;
isCopied: boolean;
setIsCopied: React.Dispatch<React.SetStateAction<boolean>>;
copyMessage?: string;
}

const CopyButton = ({ text, className, children, onCopy, isCopied, setIsCopied }: CopyButtonProps) => {
const classes = clsx("hd-copy-button", className);
const CopiedSvg = <svg width="24" height="24" className="hd-copy-button__icon" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="m5 11.75 5 5 9-9.5" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"></path></svg>;
// eslint-disable-next-line max-len
const CopySvg = <svg width="16" height="16" className="hd-copy-button__icon" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M13.3333 6H7.33333C6.59695 6 6 6.59695 6 7.33333V13.3333C6 14.0697 6.59695 14.6667 7.33333 14.6667H13.3333C14.0697 14.6667 14.6667 14.0697 14.6667 13.3333V7.33333C14.6667 6.59695 14.0697 6 13.3333 6Z" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" /><path d="M3.33337 9.99992H2.66671C2.31309 9.99992 1.97395 9.85944 1.7239 9.60939C1.47385 9.35935 1.33337 9.02021 1.33337 8.66659V2.66659C1.33337 2.31296 1.47385 1.97382 1.7239 1.72378C1.97395 1.47373 2.31309 1.33325 2.66671 1.33325H8.66671C9.02033 1.33325 9.35947 1.47373 9.60952 1.72378C9.85956 1.97382 10 2.31296 10 2.66659V3.33325" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" /></svg>;

const CopyButton = (
{ text, className, children, onCopy, variant = "default", copyMessage = "Copied!", ...rest }: React.PropsWithChildren<CopyButtonProps>) => {
const [isCopied, setIsCopied] = React.useState(false);

const classes = clsx("hd-copy-button", {
[`hd-copy-button--${variant}`]: variant !== "default",
}, className);

const copy = async () => {
await navigator.clipboard.writeText(text);
setIsCopied(true);
onCopy?.();

setTimeout(() => {
const timer = setTimeout(() => {
setIsCopied(false);
}, 5000);

return () => {
clearTimeout(timer);
};
};

const status = (
variant === "ghost"
? <span className="hd-copy-button__status">{copyMessage}</span>
: CopiedSvg
);

const content = (
variant === "ghost"
? children
: CopySvg
);

return (
<Button isDisabled={isCopied} onPress={copy} className={classes} aria-label="Copy">
{children}
<Button isDisabled={isCopied} onPress={copy} className={classes} aria-label="Copy" {...rest}>
{isCopied ? status : content}
</Button>
);
};
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

29 changes: 26 additions & 3 deletions apps/docs/components/copyButton/copyButton.css
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
.hd-copy-button {
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
background-color: transparent;
border: none;
border-radius: var(--hd-space-1);
cursor: pointer;
aspect-ratio: 1/1;
border-radius: var(--hd-space-05);
width: var(--hd-space-4);
background-color: transparent;
}

.hd-copy-button:not([disabled]):hover {
background-color: var(--hd-color-neutral-surface-weak);
}

.hd-copy-button__icon {
stroke: currentcolor;
}

.hd-copy-button[disabled]:hover {
cursor: not-allowed;
}

.hd-copy-button--inline {
width: var(--hd-space-3);
}

.hd-copy-button--ghost {
aspect-ratio: unset;
width: auto;
}

.hd-copy-button--ghost:not([disabled]):hover {
background-color: transparent;
}

This file was deleted.

This file was deleted.

This file was deleted.

15 changes: 6 additions & 9 deletions apps/docs/components/iconTable/IconItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ function toKebabCase(str: string) {
}

const IconItem: React.FC<IconItemProps> = ({ name, type, size }) => {
const [isCopied, setIsCopied] = React.useState(false);

const getIconNumericSize = (iconSize: IconItemProps["size"]) => {
switch (iconSize) {
Expand Down Expand Up @@ -45,14 +44,12 @@ const IconItem: React.FC<IconItemProps> = ({ name, type, size }) => {
<>
<div className="hd-icon-item">
<div className="hd-icon-item-content">
<CopyButton className="hd-icon-item-copy" text={copyString} isCopied={isCopied} setIsCopied={setIsCopied}>
{isCopied ? <span className="hd-icon-item__copy-status">Copied!</span> :
<span className="hd-icon-item__icon">
<Component size={size} />
</span>
}
</CopyButton>
<div className="hd-icon-item__title">
<span className="hd-icon-item__icon">
<CopyButton className="hd-icon-item-copy" text={copyString} variant="ghost">
<Component size={size}/>
</CopyButton>
</span>
<div className="hd-icon-item__title">
{formattedName}
</div>
</div>
Expand Down
17 changes: 5 additions & 12 deletions apps/docs/components/iconTable/iconItem.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,18 @@
flex-direction: column;
}

.hd-icon-item__icon {
align-items: center;
border-radius: var(--hd-space-1);
display: flex;
height: 3rem;
justify-content: center;
transition: opacity 0.2s ease-in-out;
.hd-icon-item__icon,
.hd-icon-item-copy {
aspect-ratio: 1;
width: 3rem;
}

.hd-icon-item__copy-status {
.hd-icon-item__icon {
align-items: center;
color: var(--hd-color-accent-text);
border-radius: var(--hd-space-1);
display: flex;
font-size: 0.875rem;
height: 3rem;
justify-content: center;
transition: opacity 0.2s ease-in-out;
width: 3rem;
}

.hd-icon-item-copy:not([disabled]):hover {
Expand Down
5 changes: 3 additions & 2 deletions apps/docs/components/ui/code/Code.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from "react";
import InlineCopyButton from "@/components/copyButton/inlineCopyButton/InlineCopyButton";
import CopyButton from "@/components/copyButton/CopyButton";

import "./code.css";

interface CodeProps {
Expand All @@ -11,7 +12,7 @@ const Code: React.FC<CodeProps> = ({ children, value }) => {
return (
<div className="hd-code__wrapper">
<code className="hd-code">{children}</code>
<InlineCopyButton text={value} className="hd-code__copy" />
<CopyButton text={value} variant="inline" className="hd-code__copy" />
</div>
);
};
Expand Down
8 changes: 8 additions & 0 deletions apps/docs/components/ui/pre/Pre.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,11 @@ export const Default: Story = {
children: <code>const foo = 'bar';</code>
}
}

export const WithoutTitle: Story = {
args: {
raw: "const foo = 'bar';",
"data-language": "tsx",
children: <code>const foo = 'bar';</code>
}
}
Loading

0 comments on commit 7921433

Please sign in to comment.