Skip to content

Commit

Permalink
feat(LabeledValue): Introduce component
Browse files Browse the repository at this point in the history
  • Loading branch information
Lisa18289 authored Jan 30, 2024
1 parent e5bdd22 commit 4f1cb09
Show file tree
Hide file tree
Showing 19 changed files with 280 additions and 19 deletions.
22 changes: 22 additions & 0 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions packages/components/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ import React from "react";

const preview: Preview = {
decorators: [
(Story) => (
<div className="flow">
<Story />
</div>
),
(Story) => {
document.body.classList.add("flow");
return <Story />;
},
],
globalTypes: {
rtlDirection: {},
Expand Down
3 changes: 3 additions & 0 deletions packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
"./Button": "./dist/Button.js",
"./Checkbox": "./dist/Checkbox.js",
"./Content": "./dist/Content.js",
"./CopyButton": "./dist/CopyButton.js",
"./FieldDescription": "./dist/FieldDescription.js",
"./FieldError": "./dist/FieldError.js",
"./Heading": "./dist/Heading.js",
"./Icon": "./dist/Icon.js",
"./Image": "./dist/Image.js",
"./Initials": "./dist/Initials.js",
"./Label": "./dist/Label.js",
"./LabeledValue": "./dist/LabeledValue.js",
"./Link": "./dist/Link.js",
"./Navigation": "./dist/Navigation.js",
"./Note": "./dist/Note.js",
Expand Down Expand Up @@ -48,6 +50,7 @@
"@react-aria/utils": "^3.23.0",
"@react-types/shared": "^3.22.0",
"clsx": "^2.1.0",
"copy-to-clipboard": "^3.3.3",
"html-react-parser": "^5.1.1",
"react-aria": "^3.31.1",
"react-aria-components": "^1.0.1",
Expand Down
42 changes: 42 additions & 0 deletions packages/components/src/components/CopyButton/CopyButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { FC } from "react";
import copy from "copy-to-clipboard";
import { Button } from "@/components/Button";
import { Icon } from "@/components/Icon";
import { faCopy } from "@fortawesome/free-regular-svg-icons/faCopy";
import locales from "./locales/*.locale.json";
import { useLocalizedStringFormatter } from "react-aria";
import { Tooltip, TooltipTrigger } from "@/components/Tooltip";

export interface CopyButtonProps {
value: string;
className?: string;
}

export const CopyButton: FC<CopyButtonProps> = (props) => {
const { value, className } = props;

const stringFormatter = useLocalizedStringFormatter(locales);

const tooltip = stringFormatter.format("copyButton.copy");

const copyValue = () => {
copy(value);
};

return (
<TooltipTrigger>
<Button
className={className}
onPress={copyValue}
aria-label={tooltip}
variant="plain"
small
>
<Icon faIcon={faCopy} />
</Button>
<Tooltip>{tooltip}</Tooltip>
</TooltipTrigger>
);
};

export default CopyButton;
3 changes: 3 additions & 0 deletions packages/components/src/components/CopyButton/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { CopyButton } from "./CopyButton";
export { type CopyButtonProps, CopyButton } from "./CopyButton";
export default CopyButton;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"copyButton.copy": "Kopieren"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"copyButton.copy": "Copy"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Meta, StoryObj } from "@storybook/react";
import React from "react";
import { CopyButton } from "../CopyButton";

const meta: Meta<typeof CopyButton> = {
title: "Buttons/CopyButton",
component: CopyButton,
render: (props) => <CopyButton {...props} value="Copied content" />,
parameters: {
controls: { exclude: ["value", "className"] },
},
};
export default meta;

type Story = StoryObj<typeof CopyButton>;

export const Default: Story = {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
@import "@/styles";

.labeledValue {
display: grid;
grid-template-areas:
"label"
"value";
row-gap: var(--labeled-value--label-to-value-spacing);
column-gap: var(--labeled-value--value-to-button-spacing);
grid-template-columns: auto 1fr;

&:has(.button) {
grid-template-areas:
"label label"
"value button";
}
}

.label {
grid-area: label;
}

.content {
grid-area: value;
}

.button {
grid-area: button;
justify-self: start;
}
36 changes: 36 additions & 0 deletions packages/components/src/components/LabeledValue/LabeledValue.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React, { FC, PropsWithChildren } from "react";
import styles from "./LabeledValue.module.scss";
import clsx from "clsx";
import { PropsContext, PropsContextProvider } from "@/lib/propsContext";

export interface LabeledValueProps extends PropsWithChildren {
className?: string;
}

export const LabeledValue: FC<LabeledValueProps> = (props) => {
const { children, className } = props;

const rootClassName = clsx(styles.labeledValue, className);

const propsContext: PropsContext = {
Label: {
className: styles.label,
},
Content: {
className: styles.content,
},
Button: {
className: styles.button,
},
};

return (
<div className={rootClassName}>
<PropsContextProvider props={propsContext}>
{children}
</PropsContextProvider>
</div>
);
};

export default LabeledValue;
3 changes: 3 additions & 0 deletions packages/components/src/components/LabeledValue/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { LabeledValue } from "./LabeledValue";
export { type LabeledValueProps, LabeledValue } from "./LabeledValue";
export default LabeledValue;
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { Meta, StoryObj } from "@storybook/react";
import LabeledValue from "../LabeledValue";
import React from "react";
import { Label } from "@/components/Label";
import { Content } from "@/components/Content";
import { CopyButton } from "@/components/CopyButton";

const meta: Meta<typeof LabeledValue> = {
title: "Content/Labeled Value",
component: LabeledValue,
parameters: {
controls: { exclude: ["className"] },
},
render: (props) => (
<LabeledValue {...props}>
<Label>Project</Label>
<Content>My proSpace</Content>
</LabeledValue>
),
};
export default meta;

type Story = StoryObj<typeof LabeledValue>;

export const Default: Story = {};

export const WithCopyButton: Story = {
render: (props) => (
<LabeledValue {...props}>
<Label>Project</Label>
<Content>My proSpace</Content>
<CopyButton value="My proSpace" />
</LabeledValue>
),
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { Meta, StoryObj } from "@storybook/react";
import LabeledValue from "../LabeledValue";
import defaultMeta from "./Default.stories";
import { dummyText } from "@/lib/dev/dummyText";
import { Label } from "@/components/Label";
import { Content } from "@/components/Content";
import React from "react";
import { CopyButton } from "@/components/CopyButton";

const meta: Meta<typeof LabeledValue> = {
title: "Content/Labeled Value/Edge Cases",
...defaultMeta,
};
export default meta;

type Story = StoryObj<typeof LabeledValue>;

export const LongLabel: Story = {
render: (props) => (
<LabeledValue {...props}>
<Label>{dummyText.medium}</Label>
<Content>{dummyText.short}</Content>
<CopyButton value={dummyText.short} />
</LabeledValue>
),
};
export const LongContent: Story = {
render: (props) => (
<LabeledValue {...props}>
<Label>{dummyText.medium}</Label>
<Content>{dummyText.long}</Content>
<CopyButton value={dummyText.long} />
</LabeledValue>
),
};
6 changes: 3 additions & 3 deletions packages/components/src/components/StatusIcon/StatusIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ export interface StatusIconProps extends StatusVariantProps {
export const StatusIcon: FC<StatusIconProps> = (props) => {
const { variant = "info", ...rest } = props;

const ariaLabel = useLocalizedStringFormatter(locales).format(
`statusIcon.${variant}`,
);
const stringFormatter = useLocalizedStringFormatter(locales);

const ariaLabel = stringFormatter.format(`statusIcon.${variant}`);

const icon =
variant === "info"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@ import React from "react";
import { Text } from "@/components/Text";
import { Button } from "@/components/Button";
import { Icon } from "@/components/Icon";
import { faCopy } from "@fortawesome/free-regular-svg-icons/faCopy";
import { faSave } from "@fortawesome/free-regular-svg-icons/faSave";

const meta: Meta<typeof Tooltip> = {
title: "Overlays/Tooltip",
component: Tooltip,
render: () => (
<TooltipTrigger>
<Button aria-label="copy">
<Icon faIcon={faCopy} />
args: {
defaultOpen: true,
},
render: (props) => (
<TooltipTrigger {...props}>
<Button aria-label="save">
<Icon faIcon={faSave} />
</Button>
<Tooltip>Copy</Tooltip>
<Tooltip>Save</Tooltip>
</TooltipTrigger>
),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@ import React from "react";
import { Text } from "@/components/Text";
import { Button } from "@/components/Button";
import { Icon } from "@/components/Icon";
import { faCopy } from "@fortawesome/free-regular-svg-icons/faCopy";
import defaultMeta from "./Default.stories";
import { dummyText } from "@/lib/dev/dummyText";
import { faSave } from "@fortawesome/free-regular-svg-icons/faSave";

const meta: Meta<typeof Tooltip> = {
...defaultMeta,
title: "Overlays/Tooltip/Edge Cases",
render: () => (
<TooltipTrigger>
<Button aria-label="copy">
<Icon faIcon={faCopy} />
args: {
defaultOpen: true,
},
render: (props) => (
<TooltipTrigger {...props}>
<Button aria-label="save">
<Icon faIcon={faSave} />
</Button>
<Tooltip>{dummyText.medium}</Tooltip>
</TooltipTrigger>
Expand Down
2 changes: 2 additions & 0 deletions packages/components/vite.build.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ export default defineConfig(
Button: "./src/components/Button/index.ts",
Checkbox: "./src/components/Checkbox/index.ts",
Content: "./src/components/Content/index.ts",
CopyButton: "./src/components/CopyButton/index.ts",
FieldDescription: "./src/components/FieldDescription/index.ts",
FieldError: "./src/components/FieldError/index.ts",
Heading: "./src/components/Heading/index.ts",
Icon: "./src/components/Icon/index.ts",
Image: "./src/components/Image/index.ts",
Initials: "./src/components/Initials/index.ts",
Label: "./src/components/Label/index.ts",
LabeledValue: "./src/components/LabeledValue/index.ts",
Link: "./src/components/Link/index.ts",
Navigation: "./src/components/Navigation/index.ts",
Note: "./src/components/Note/index.ts",
Expand Down
Loading

1 comment on commit 4f1cb09

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage report for ./packages/components/

St.
Category Percentage Covered / Total
🟢 Statements 98.04% 100/102
🟢 Branches 93.75% 30/32
🟢 Functions 100% 27/27
🟢 Lines 98.04% 100/102

Test suite run success

51 tests passing in 9 suites.

Report generated by 🧪jest coverage report action from 4f1cb09

Please sign in to comment.