Skip to content

Commit

Permalink
Merge pull request #134 from dolthub/taylor/field
Browse files Browse the repository at this point in the history
components: Add FieldWithButton, up storybook
  • Loading branch information
tbantle22 committed Jun 10, 2024
2 parents 0ff095a + 952c063 commit e6757e1
Show file tree
Hide file tree
Showing 8 changed files with 1,753 additions and 1,107 deletions.
20 changes: 10 additions & 10 deletions packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"name": "DoltHub"
},
"description": "A collection of React components for common tasks",
"version": "0.2.2",
"version": "0.2.3",
"repository": {
"type": "git",
"url": "git+https://github.com/dolthub/react-library.git"
Expand Down Expand Up @@ -75,16 +75,16 @@
"@rollup/plugin-commonjs": "^25.0.8",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-typescript": "^11.1.5",
"@storybook/addon-essentials": "^8.0.9",
"@storybook/addon-interactions": "^8.1.5",
"@storybook/addon-links": "^8.0.9",
"@storybook/addon-essentials": "^8.1.6",
"@storybook/addon-interactions": "^8.1.6",
"@storybook/addon-links": "^8.1.6",
"@storybook/addon-styling-webpack": "^1.0.0",
"@storybook/addon-viewport": "^8.0.6",
"@storybook/addon-viewport": "^8.1.6",
"@storybook/addon-webpack5-compiler-swc": "^1.0.3",
"@storybook/blocks": "^8.1.5",
"@storybook/react": "^8.0.6",
"@storybook/react-webpack5": "^8.0.9",
"@storybook/test": "^8.0.6",
"@storybook/blocks": "^8.1.6",
"@storybook/react": "^8.1.6",
"@storybook/react-webpack5": "^8.1.6",
"@storybook/test": "^8.1.6",
"@testing-library/jest-dom": "^6.4.5",
"@testing-library/react": "^15.0.6",
"@testing-library/react-hooks": "^8.0.1",
Expand Down Expand Up @@ -126,7 +126,7 @@
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-terser": "^7.0.2",
"storybook": "^8.0.6",
"storybook": "^8.1.6",
"storybook-css-modules": "^1.0.8",
"stylelint": "^16.2.1",
"stylelint-config-recommended": "^14.0.0",
Expand Down
49 changes: 0 additions & 49 deletions packages/components/src/CopyableField/index.module.css
Original file line number Diff line number Diff line change
@@ -1,52 +1,3 @@
.field {
@apply md:flex items-center my-2;
}

.label {
@apply font-semibold min-w-[6rem] md:w-32;
}

.verticalField {
@apply flex-col items-start mb-3;

.label {
@apply mb-1.5 md:w-60;
}
}

.valueWrapper {
@apply flex items-center;
}

.valContainer {
@apply relative;
}

.value {
@apply bg-white px-3 text-acc-1 rounded-md border font-mono text-sm flex items-center lg:whitespace-nowrap;

span {
@apply overflow-x-auto py-2 break-words;
}
}

.blueValue {
@apply text-primary;
}

.smallValue {
@apply text-xs;

span {
@apply py-2.5;
}
}

.blurValue {
@apply text-transparent;
text-shadow: 0 0 5px rgba(var(--color-acc-1), 0.3);
}

.clipboard {
@apply p-1 rounded ml-4 text-button-1;

Expand Down
81 changes: 17 additions & 64 deletions packages/components/src/CopyableField/index.tsx
Original file line number Diff line number Diff line change
@@ -1,74 +1,27 @@
import { useDelay } from "@dolthub/react-hooks";
import { FaRegClone } from "@react-icons/all-files/fa/FaRegClone";
import cx from "classnames";
import React, { ReactNode } from "react";
import React from "react";
import CopyToClipboard from "react-copy-to-clipboard";
import Btn from "../Btn";
import FieldWithButton, { CommonProps } from "../FieldWithButton";
import css from "./index.module.css";

type Props = {
label?: string;
value: string;
hideValue?: boolean;
children?: ReactNode;
blue?: boolean;
help?: ReactNode;
blur?: boolean;
labelClassName?: string;
className?: string;
smallValue?: boolean;
vertical?: boolean;
valueForHidden?: string;
};

export default function CopyableField(props: Props) {
export default function CopyableField(props: CommonProps) {
const copySuccess = useDelay();

return (
<div
className={cx(
css.field,
{ [css.verticalField]: !!props.vertical },
props.className,
)}
data-cy={`copyable-field-${
props.label ? props.label.toLowerCase() : "item"
}`}
>
<div className={cx(css.label, props.labelClassName)}>
{props.label}
{props.label ? ":" : ""}
</div>
<div className={css.valueWrapper}>
{props.hideValue || !props.value ? (
props.valueForHidden ?? ""
) : (
<div className={css.valContainer}>
{props.help}
<div
className={cx(css.value, {
[css.blueValue]: !!props.blue,
[css.smallValue]: !!props.smallValue,
})}
>
<span
className={cx({
[css.blurValue]: !!props.blur && !copySuccess.active,
})}
>
{copySuccess.active ? "Copied to clipboard" : props.value}
</span>
{typeof props.value === "string" && (
<CopyToClipboard text={props.value} onCopy={copySuccess.start}>
<Btn className={css.clipboard} aria-label="copy value">
<FaRegClone />
</Btn>
</CopyToClipboard>
)}
</div>
</div>
)}
{(!props.hideValue || props.valueForHidden) && props.children}
</div>
</div>
<FieldWithButton
{...props}
buttonActive={copySuccess.active}
button={
typeof props.value === "string" ? (
<CopyToClipboard text={props.value} onCopy={copySuccess.start}>
<Btn className={css.clipboard} aria-label="copy value">
<FaRegClone />
</Btn>
</CopyToClipboard>
) : undefined
}
/>
);
}
48 changes: 48 additions & 0 deletions packages/components/src/FieldWithButton/index.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
.field {
@apply md:flex items-center my-2;
}

.label {
@apply font-semibold min-w-[6rem] md:w-32;
}

.verticalField {
@apply flex-col items-start mb-3;

.label {
@apply mb-1.5 md:w-60;
}
}

.valueWrapper {
@apply flex items-center;
}

.valContainer {
@apply relative;
}

.value {
@apply bg-white px-3 text-acc-1 rounded-md border font-mono text-sm flex items-center lg:whitespace-nowrap;

span {
@apply overflow-x-auto py-2 break-words;
}
}

.blueValue {
@apply text-primary;
}

.smallValue {
@apply text-xs;

span {
@apply py-2.5;
}
}

.blurValue {
@apply text-transparent;
text-shadow: 0 0 5px rgba(var(--color-acc-1), 0.3);
}
68 changes: 68 additions & 0 deletions packages/components/src/FieldWithButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import cx from "classnames";
import React, { ReactNode } from "react";
import css from "./index.module.css";

export type CommonProps = {
label?: string;
value: string;
hideValue?: boolean;
children?: ReactNode;
blue?: boolean;
help?: ReactNode;
blur?: boolean;
labelClassName?: string;
className?: string;
smallValue?: boolean;
vertical?: boolean;
valueForHidden?: string;
};

type Props = CommonProps & {
buttonActive?: boolean;
button?: ReactNode;
};

export default function FieldWithButton(props: Props) {
return (
<div
className={cx(
css.field,
{ [css.verticalField]: !!props.vertical },
props.className,
)}
data-cy={`copyable-field-${
props.label ? props.label.toLowerCase() : "item"
}`}
>
<div className={cx(css.label, props.labelClassName)}>
{props.label}
{props.label ? ":" : ""}
</div>
<div className={css.valueWrapper}>
{props.hideValue || !props.value ? (
props.valueForHidden ?? ""
) : (
<div className={css.valContainer}>
{props.help}
<div
className={cx(css.value, {
[css.blueValue]: !!props.blue,
[css.smallValue]: !!props.smallValue,
})}
>
<span
className={cx({
[css.blurValue]: !!props.blur && !props.buttonActive,
})}
>
{props.buttonActive ? "Copied to clipboard" : props.value}
</span>
{props.button}
</div>
</div>
)}
{(!props.hideValue || props.valueForHidden) && props.children}
</div>
</div>
);
}
91 changes: 91 additions & 0 deletions packages/components/src/__stories__/FieldWithButton.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { FaGithub } from "@react-icons/all-files/fa/FaGithub";
import { FaPencilAlt } from "@react-icons/all-files/fa/FaPencilAlt";
import type { Meta, StoryObj } from "@storybook/react";
import React from "react";
import Button from "../Button";
import FieldWithButton from "../FieldWithButton";

const meta: Meta<typeof FieldWithButton> = {
title: "FieldWithButton",
component: FieldWithButton,
tags: ["autodocs"],
};

export default meta;

type Story = StoryObj<typeof FieldWithButton>;

export const Default: Story = {
args: {
value: "value",
},
};

export const WithLabel: Story = {
args: {
...Default.args,
label: "Label",
},
};

export const HideValue: Story = {
args: {
...WithLabel.args,
hideValue: true,
},
};

export const WithChildren: Story = {
args: {
...WithLabel.args,
children: <FaGithub />,
},
};

export const WithHelp: Story = {
args: {
...WithLabel.args,
help: <span className="absolute -left-4 top-1">?</span>,
},
};

export const Blue: Story = {
args: {
...WithLabel.args,
children: <FaGithub />,
blue: true,
},
};

export const SmallValue: Story = {
args: {
...WithLabel.args,
smallValue: true,
},
};

export const Vertical: Story = {
args: {
...WithLabel.args,
vertical: true,
},
};

export const Blur: Story = {
args: {
label: "Password",
value: "blur me",
blur: true,
},
};

export const WithButton: Story = {
args: {
...WithLabel.args,
button: (
<Button.Link>
<FaPencilAlt />
</Button.Link>
),
},
};
Loading

0 comments on commit e6757e1

Please sign in to comment.