Skip to content

Commit

Permalink
💄 CopyButton: Justert padding, gap og animasjon (#2355)
Browse files Browse the repository at this point in the history
  • Loading branch information
HalvorHaugan authored Oct 11, 2023
1 parent d88a0c8 commit 70c5aff
Show file tree
Hide file tree
Showing 12 changed files with 162 additions and 113 deletions.
6 changes: 6 additions & 0 deletions .changeset/wild-coats-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@navikt/ds-react": patch
"@navikt/ds-css": patch
---

:lipstick: CopyButton: Justert padding, gap og animasjon
44 changes: 41 additions & 3 deletions @navikt/core/css/copybutton.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}

.navds-copybutton {
--__ac-copybutton-padding: var(--a-spacing-3) var(--a-spacing-5);
--__ac-copybutton-padding: var(--a-spacing-3) var(--a-spacing-5) var(--a-spacing-3) var(--a-spacing-4);

cursor: pointer;
margin: 0;
Expand All @@ -28,18 +28,30 @@
place-content: center;
}

.navds-copybutton--icon-right {
--__ac-copybutton-padding: var(--a-spacing-3) var(--a-spacing-4) var(--a-spacing-3) var(--a-spacing-5);
}

.navds-copybutton--small {
--__ac-copybutton-padding: var(--a-spacing-1) var(--a-spacing-3);
--__ac-copybutton-padding: var(--a-spacing-1) var(--a-spacing-3) var(--a-spacing-1) var(--a-spacing-2);

min-height: 2rem;
}

.navds-copybutton--small.navds-copybutton--icon-right {
--__ac-copybutton-padding: var(--a-spacing-1) var(--a-spacing-2) var(--a-spacing-1) var(--a-spacing-3);
}

.navds-copybutton--xsmall {
--__ac-copybutton-padding: var(--a-spacing-05) var(--a-spacing-2);
--__ac-copybutton-padding: var(--a-spacing-05) var(--a-spacing-2) var(--a-spacing-05) var(--a-spacing-1);

min-height: 1.5rem;
}

.navds-copybutton--xsmall.navds-copybutton--icon-right {
--__ac-copybutton-padding: var(--a-spacing-05) var(--a-spacing-1) var(--a-spacing-05) var(--a-spacing-2);
}

.navds-copybutton--icon-only {
--__ac-copybutton-padding: var(--a-spacing-3);
}
Expand Down Expand Up @@ -73,6 +85,28 @@
margin: 0;
}

.navds-copybutton--active .navds-copybutton__icon {
animation: akselCopyButtonIconAnimation 2s cubic-bezier(0.215, 0.61, 0.355, 1);
}

@keyframes akselCopyButtonIconAnimation {
8% {
transform: translateY(0);
}

17% {
transform: translateY(-10%);
}

25% {
transform: translateY(2%);
}

30% {
transform: translateY(0);
}
}

:where(.navds-copybutton--small, .navds-copybutton--xsmall):where(:not(:only-child)) {
margin: -0.125rem;
}
Expand Down Expand Up @@ -140,6 +174,10 @@
gap: var(--a-spacing-2);
}

.navds-copybutton--small > .navds-copybutton__content {
gap: 0.375rem;
}

.navds-copybutton--xsmall > .navds-copybutton__content {
gap: var(--a-spacing-1);
}
Expand Down
55 changes: 27 additions & 28 deletions @navikt/core/react/src/copybutton/CopyButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import Label from "../typography/Label";
export interface CopyButtonProps
extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
/**
* 'xsmall' should only be used in tables
* @default "medium"
* xsmall should only be used in tables/
*/
size?: "medium" | "small" | "xsmall";
/**
Expand All @@ -30,12 +30,12 @@ export interface CopyButtonProps
*/
text?: string;
/**
* Text shown when button is clicked
* Only set if used with 'text'-prop
* Text shown when button is clicked.
* Only set if used with `text`-prop.
*/
activeText?: string;
/**
* Callback when 'copied'-state is active
* Callback when 'copied'-state is active
*/
onActiveChange?: (state: boolean) => void;
/**
Expand All @@ -54,17 +54,17 @@ export interface CopyButtonProps
*/
activeDuration?: number;
/**
* * accessible label for icon (ignored if text is set)
* Accessible label for icon (ignored if text is set)
* @default 'Kopier'
*/
title?: string;
/**
* accessible label for icon in active-state (ignored if text is set)
* Accessible label for icon in active-state (ignored if text is set)
* @default 'Kopiert'
*/
activeTitle?: string;
/**
* Icon position in Button
* Icon position in button
* @default "left"
*/
iconPosition?: "left" | "right";
Expand Down Expand Up @@ -125,24 +125,23 @@ export const CopyButton = forwardRef<HTMLButtonElement, CopyButtonProps>(
}, activeDuration);
};

const CopyIcon = () => {
return active ? (
<span className="navds-copybutton__icon">
{activeIcon ?? (
<CheckmarkIcon
aria-hidden={!!text}
title={text ? undefined : activeTitle}
/>
)}
</span>
) : (
<span className="navds-copybutton__icon">
{icon ?? (
<FilesIcon aria-hidden={!!text} title={text ? undefined : title} />
)}
</span>
);
};
const copyIcon = (
<span className="navds-copybutton__icon">
{active
? activeIcon ?? (
<CheckmarkIcon
aria-hidden={!!text}
title={text ? undefined : activeTitle}
/>
)
: icon ?? (
<FilesIcon
aria-hidden={!!text}
title={text ? undefined : title}
/>
)}
</span>
);

return (
<button
Expand All @@ -157,14 +156,14 @@ export const CopyButton = forwardRef<HTMLButtonElement, CopyButtonProps>(
`navds-copybutton--${variant}`,
{
"navds-copybutton--icon-only": !text,
"navds-copybutton--icon-right": iconPosition === "right",
"navds-copybutton--active": active,
}
)}
onClick={handleClick}
>
<span className="navds-copybutton__content">
{iconPosition === "left" && <CopyIcon />}

{iconPosition === "left" && copyIcon}
{text &&
(active ? (
<Label
Expand All @@ -183,7 +182,7 @@ export const CopyButton = forwardRef<HTMLButtonElement, CopyButtonProps>(
{text}
</Label>
))}
{iconPosition === "right" && <CopyIcon />}
{iconPosition === "right" && copyIcon}
</span>
</button>
);
Expand Down
46 changes: 24 additions & 22 deletions @navikt/core/react/src/copybutton/copy-button.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,40 @@
import { LinkIcon, ThumbUpIcon } from "@navikt/aksel-icons";
import { userEvent, within } from "@storybook/testing-library";
import React from "react";
import { CopyButton } from ".";
import { userEvent, within } from "@storybook/testing-library";
import { Meta, StoryObj } from "@storybook/react";
import { LinkIcon, ThumbUpIcon } from "@navikt/aksel-icons";
import { Tooltip } from "../tooltip";
import { CopyButton } from ".";

export default {
const meta: Meta<typeof CopyButton> = {
title: "ds-react/CopyButton",
component: CopyButton,
};
export default meta;

type Story = StoryObj<typeof CopyButton>;

export const Default: Story = {
render: (props) => <CopyButton {...props} />,
argTypes: {
size: {
defaultValue: "medium",
control: { type: "radio" },
options: ["small", "medium", "xsmall"],
options: ["medium", "small", "xsmall"],
},
variant: {
defaultValue: undefined,
control: { type: "radio" },
options: ["neutral", "action"],
},
},
};

export const Default = {
render: (args) => <CopyButton {...args} />,
args: {
size: "medium",
duration: 2000,
activeDuration: 2000,
copyText: "3.14",
text: "",
activeText: "",
},
};

export const Interaction = {
export const Interaction: Story = {
render: () => (
<CopyButton
copyText="3.14"
Expand All @@ -50,7 +52,7 @@ export const Interaction = {
},
};

export const Variants = {
export const Variants: Story = {
render: () => (
<div className="colgap">
<CopyButton copyText="3.14" variant="action" text="Kopier" />
Expand All @@ -60,7 +62,7 @@ export const Variants = {
),
};

export const IconPosition = {
export const IconPosition: Story = {
render: () => (
<div className="colgap">
<CopyButton copyText="3.14" iconPosition="left" text="Kopier" />
Expand All @@ -70,7 +72,7 @@ export const IconPosition = {
),
};

export const Sizes = {
export const Sizes: Story = {
render: () => (
<div className="colgap">
<div className="rowgap">
Expand Down Expand Up @@ -115,7 +117,7 @@ export const Sizes = {
),
};

export const Texts = {
export const Texts: Story = {
render: () => (
<div className="colgap">
<div>
Expand Down Expand Up @@ -145,7 +147,7 @@ export const Texts = {
),
};

export const Icons = {
export const Icons: Story = {
render: () => (
<div className="rowgap">
<div>
Expand Down Expand Up @@ -175,15 +177,15 @@ export const Icons = {
),
};

export const InlineDemo = {
export const InlineDemo: Story = {
render: () => (
<div style={{ display: "flex", gap: "0.5rem", alignItems: "center" }}>
<CopyButton size="small" copyText="3.14" /> Kopier dette feltet
</div>
),
};

export const WithTooltip = {
export const WithTooltip: Story = {
render: () => {
return (
<div>
Expand All @@ -195,11 +197,11 @@ export const WithTooltip = {
},
};

export const Duration = {
export const Duration: Story = {
render: () => <CopyButton copyText="3.14" activeDuration={300} />,
};

export const Disabled = {
export const Disabled: Story = {
render: () => (
<div className="colgap">
<CopyButton copyText="3.14" disabled />
Expand Down
11 changes: 7 additions & 4 deletions aksel.nav.no/website/pages/eksempler/copybutton/active-icon.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { LinkBrokenIcon, LinkIcon } from "@navikt/aksel-icons";
import { LinkIcon, ThumbUpIcon } from "@navikt/aksel-icons";
import { CopyButton } from "@navikt/ds-react";
import { withDsExample } from "components/website-modules/examples/withDsExample";

const Example = () => {
return (
<CopyButton
copyText="3.14"
icon={<LinkIcon title="Kopier lenke" />}
activeIcon={<LinkBrokenIcon title="Kopierte lenke" />}
copyText="https://aksel.nav.no/"
text="Kopier lenke"
activeText="Lenken er kopiert"
icon={<LinkIcon aria-hidden />}
activeIcon={<ThumbUpIcon aria-hidden />}
/>
);
};
Expand All @@ -21,4 +23,5 @@ export const Demo = {

export const args = {
index: 6,
desc: "ActiveIcon-propen lar deg endre ikon i active state",
};
8 changes: 7 additions & 1 deletion aksel.nav.no/website/pages/eksempler/copybutton/icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import { withDsExample } from "components/website-modules/examples/withDsExample

const Example = () => {
return (
<CopyButton copyText="3.14" icon={<LinkIcon title="Kopier lenke" />} />
<CopyButton
copyText="https://aksel.nav.no/"
text="Kopier lenke"
activeText="Lenken er kopiert"
icon={<LinkIcon aria-hidden />}
/>
);
};

Expand All @@ -17,4 +22,5 @@ export const Demo = {

export const args = {
index: 5,
desc: "Icon-propen lar deg bytte ikon i default state",
};
Loading

0 comments on commit 70c5aff

Please sign in to comment.