From cafb7b4cddea8f2c2b1be8815ac6120c3c1f8e69 Mon Sep 17 00:00:00 2001 From: Ken Date: Thu, 11 May 2023 16:55:42 +0200 Subject: [PATCH 01/46] :sparkles: Boilerplate new component --- @navikt/core/css/copybutton.css | 3 ++ @navikt/core/css/index.css | 1 + .../core/react/src/copybutton/CopyButton.tsx | 28 +++++++++++++++++++ .../src/copybutton/copy-button.stories.tsx | 23 +++++++++++++++ @navikt/core/react/src/copybutton/index.ts | 1 + 5 files changed, 56 insertions(+) create mode 100644 @navikt/core/css/copybutton.css create mode 100644 @navikt/core/react/src/copybutton/CopyButton.tsx create mode 100644 @navikt/core/react/src/copybutton/copy-button.stories.tsx create mode 100644 @navikt/core/react/src/copybutton/index.ts diff --git a/@navikt/core/css/copybutton.css b/@navikt/core/css/copybutton.css new file mode 100644 index 0000000000..51653bb1eb --- /dev/null +++ b/@navikt/core/css/copybutton.css @@ -0,0 +1,3 @@ +.navds-copybutton { + background-color: red; +} diff --git a/@navikt/core/css/index.css b/@navikt/core/css/index.css index c261f2e980..ff592ee848 100644 --- a/@navikt/core/css/index.css +++ b/@navikt/core/css/index.css @@ -8,6 +8,7 @@ @import "content-container.css"; @import "chat.css"; @import "chips.css"; +@import "copybutton.css"; @import "expansioncard.css"; @import "guide-panel.css"; @import "form/index.css"; diff --git a/@navikt/core/react/src/copybutton/CopyButton.tsx b/@navikt/core/react/src/copybutton/CopyButton.tsx new file mode 100644 index 0000000000..61b5def11f --- /dev/null +++ b/@navikt/core/react/src/copybutton/CopyButton.tsx @@ -0,0 +1,28 @@ +import React, { ButtonHTMLAttributes, forwardRef } from "react"; +import cl from "clsx"; + +export interface CopyButtonProps + extends ButtonHTMLAttributes { + /** + * @default "medium" + */ + size?: "medium" | "small" | "xsmall"; +} + +export const CopyButton = forwardRef( + ({ className, size = "medium", ...rest }, ref) => { + return ( + ); } ); diff --git a/@navikt/core/react/src/util/copy.ts b/@navikt/core/react/src/util/copy.ts new file mode 100644 index 0000000000..029e1bae8e --- /dev/null +++ b/@navikt/core/react/src/util/copy.ts @@ -0,0 +1,60 @@ +// https://github.com/sudodoki/copy-to-clipboard/blob/main/index.js +function copy(text) { + let range: Range, mark: HTMLSpanElement | null; + + let selection: Selection | null; + + const debug = process.env.NODE_ENV !== "production"; + + try { + range = document.createRange(); + selection = document.getSelection(); + + mark = document.createElement("span"); + mark.textContent = text; + // avoid screen readers from reading out loud the text + mark.ariaHidden = "true"; + // reset user styles for span element + mark.style.all = "unset"; + // prevents scrolling to the end of the page + mark.style.position = "fixed"; + mark.style.top = "0"; + mark.style.clipPath = "rect(0, 0, 0, 0)"; + // used to preserve spaces and line breaks + mark.style.whiteSpace = "pre"; + // do not inherit user-select (it may be `none`) + (mark.style as any).webkitUserSelect = "text"; + (mark.style as any).MozUserSelect = "text"; + (mark.style as any).msUserSelect = "text"; + mark.style.userSelect = "text"; + mark.addEventListener("copy", function (e) { + e.stopPropagation(); + }); + + document.body.appendChild(mark); + + range.selectNodeContents(mark); + selection?.addRange(range); + + var successful = document.execCommand("copy"); + if (!successful) { + throw new Error("copy command was unsuccessful"); + } + + if (selection) { + if (typeof selection.removeRange == "function") { + selection.removeRange(range); + } else { + selection.removeAllRanges(); + } + } + + if (mark) { + document.body.removeChild(mark); + } + } catch (err) { + debug && console.error("unable to copy using execCommand: ", err); + } +} + +export default copy; From b3624f3e6c1d7c10f40a42ba3c08ad1c5cb9ddb1 Mon Sep 17 00:00:00 2001 From: Ken Date: Thu, 11 May 2023 17:50:48 +0200 Subject: [PATCH 03/46] :art: timeout functionality --- @navikt/core/css/copybutton.css | 4 +- .../core/react/src/copybutton/CopyButton.tsx | 50 +++++++++++++++---- .../src/copybutton/copy-button.stories.tsx | 9 ++++ 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/@navikt/core/css/copybutton.css b/@navikt/core/css/copybutton.css index 51653bb1eb..a77a2740aa 100644 --- a/@navikt/core/css/copybutton.css +++ b/@navikt/core/css/copybutton.css @@ -1,3 +1,3 @@ -.navds-copybutton { - background-color: red; +/* .navds-copybutton { } + */ diff --git a/@navikt/core/react/src/copybutton/CopyButton.tsx b/@navikt/core/react/src/copybutton/CopyButton.tsx index 66ed0c4bcd..dec5633567 100644 --- a/@navikt/core/react/src/copybutton/CopyButton.tsx +++ b/@navikt/core/react/src/copybutton/CopyButton.tsx @@ -1,6 +1,14 @@ -import React, { ButtonHTMLAttributes, forwardRef } from "react"; +import React, { + ButtonHTMLAttributes, + forwardRef, + useEffect, + useRef, + useState, +} from "react"; import cl from "clsx"; import copy from "../util/copy"; +import { Button } from "../button"; +import { CheckmarkIcon, FilesIcon } from "@navikt/aksel-icons"; export interface CopyButtonProps extends ButtonHTMLAttributes { @@ -8,12 +16,35 @@ export interface CopyButtonProps * @default "medium" */ size?: "medium" | "small"; + /** + * + */ + variant?: "tertiary" | "tertiary-neutral"; } export const CopyButton = forwardRef( - ({ className, size = "medium", ...rest }, ref) => { + ({ className, variant = "tertiary", size = "medium", ...rest }, ref) => { + const [active, setActive] = useState(false); + const timeoutRef = useRef(); + + useEffect(() => { + return () => { + timeoutRef.current && clearTimeout(timeoutRef.current); + }; + }, []); + + const handleClick = ( + event: React.MouseEvent + ) => { + copy("test"); + setActive(true); + rest.onClick?.(event); + + timeoutRef.current = window.setTimeout(() => setActive(false), 2000); + }; + return ( - + {active ? Kopiert! : Kopier!} + ); } ); diff --git a/@navikt/core/react/src/copybutton/copy-button.stories.tsx b/@navikt/core/react/src/copybutton/copy-button.stories.tsx index 411e416fce..628ace6085 100644 --- a/@navikt/core/react/src/copybutton/copy-button.stories.tsx +++ b/@navikt/core/react/src/copybutton/copy-button.stories.tsx @@ -21,3 +21,12 @@ export const Default = { size: "medium", }, }; + +export const Variants = { + render: () => ( +
+ + +
+ ), +}; From 6ad76c2031096aca0d27a6ea23daf20515ac669f Mon Sep 17 00:00:00 2001 From: Ken Date: Thu, 11 May 2023 21:26:28 +0200 Subject: [PATCH 04/46] :art: CopyButton API --- @navikt/core/css/copybutton.css | 124 +++++++++++++++++- .../core/react/src/copybutton/CopyButton.tsx | 96 ++++++++++++-- .../src/copybutton/copy-button.stories.tsx | 74 ++++++++++- 3 files changed, 271 insertions(+), 23 deletions(-) diff --git a/@navikt/core/css/copybutton.css b/@navikt/core/css/copybutton.css index a77a2740aa..86ac1a1571 100644 --- a/@navikt/core/css/copybutton.css +++ b/@navikt/core/css/copybutton.css @@ -1,3 +1,123 @@ -/* .navds-copybutton { +.navds-copybutton { + --__ac-button-padding: var(--a-spacing-3) var(--a-spacing-5); + + cursor: pointer; + margin: 0; + text-decoration: none; + border: none; + background: none; + border-radius: var(--ac-button-border-radius, var(--a-border-radius-medium)); + padding: var(--ac-button-padding, var(--__ac-button-padding)); + display: grid; + place-content: center; +} + +.navds-copybutton--small { + --__ac-button-padding: var(--a-spacing-1) var(--a-spacing-3); + + padding: var(--ac-button-padding-small, var(--__ac-button-padding)); + min-height: 2rem; +} + +.navds-copybutton--icon-only { + --__ac-button-padding: var(--a-spacing-3); + + padding: var(--ac-button-padding-icon-only, var(--__ac-button-padding)); +} + +.navds-copybutton--small.navds-copybutton--icon-only { + --__ac-button-padding: var(--a-spacing-1); + + padding: var(--ac-button-padding-icon-only-small, var(--__ac-button-padding)); +} + +.navds-copybutton__icon { + --ac-button-icon-margin: -4px; + + font-size: 1.5rem; + display: flex; +} + +.navds-copybutton__icon:first-child { + margin-left: var(--ac-button-icon-margin); +} + +.navds-copybutton__icon:only-child { + margin: 0; +} + +.navds-copybutton--tertiary { + color: var(--ac-button-tertiary-text, var(--a-text-action)); + background-color: var(--ac-button-tertiary-bg, var(--a-surface-transparent)); +} + +.navds-copybutton--tertiary:hover { + color: var(--ac-button-tertiary-hover-text, var(--a-text-action-on-action-subtle)); + background-color: var(--ac-button-tertiary-hover-bg, var(--a-surface-action-subtle-hover)); +} + +.navds-copybutton:focus-visible { + outline: none; + box-shadow: var(--a-shadow-focus); +} + +@supports not selector(:focus-visible) { + .navds-copybutton:focus { + outline: none; + box-shadow: var(--a-shadow-focus); + } +} + +.navds-copybutton--tertiary:where(:disabled, .navds-copybutton--disabled), +.navds-copybutton--tertiary:hover:where(:disabled, .navds-copybutton--disabled) { + color: var(--ac-button-tertiary-text, var(--a-text-action)); + background: none; + box-shadow: none; +} + +.navds-copybutton--tertiary-neutral { + color: var(--ac-button-tertiary-neutral-text, var(--a-text-default)); +} + +.navds-copybutton--tertiary-neutral:hover { + color: var(--ac-button-tertiary-neutral-hover-text, var(--a-text-default)); + background-color: var(--ac-button-tertiary-neutral-hover-bg, var(--a-surface-neutral-subtle-hover)); +} + +.navds-copybutton--tertiary-neutral:where(:disabled, .navds-copybutton--disabled), +.navds-copybutton--tertiary-neutral:hover:where(:disabled, .navds-copybutton--disabled) { + color: var(--ac-button-tertiary-neutral-text, var(--a-text-default)); + background: none; + box-shadow: none; +} + +.navds-copybutton--active.navds-copybutton--tertiary { + color: var(--a-surface-success); +} + +.navds-copybutton__content { + display: inline-flex; + align-items: center; + justify-content: center; + gap: var(--a-spacing-2); +} + +.navds-copybutton--active > .navds-copybutton__content { + animation: akselCopyButtonAnimation 0.5s ease; +} + +@keyframes akselCopyButtonAnimation { + 0% { + opacity: 0.7; + scale: 0.98; + } + + 80% { + scale: 1; + } + + 100% { + opacity: 1; + scale: 1; + } } - */ diff --git a/@navikt/core/react/src/copybutton/CopyButton.tsx b/@navikt/core/react/src/copybutton/CopyButton.tsx index dec5633567..c961065ac3 100644 --- a/@navikt/core/react/src/copybutton/CopyButton.tsx +++ b/@navikt/core/react/src/copybutton/CopyButton.tsx @@ -1,3 +1,5 @@ +import { CheckmarkIcon, FilesIcon } from "@navikt/aksel-icons"; +import cl from "clsx"; import React, { ButtonHTMLAttributes, forwardRef, @@ -5,10 +7,8 @@ import React, { useRef, useState, } from "react"; -import cl from "clsx"; import copy from "../util/copy"; -import { Button } from "../button"; -import { CheckmarkIcon, FilesIcon } from "@navikt/aksel-icons"; +import Label from "../typography/Label"; export interface CopyButtonProps extends ButtonHTMLAttributes { @@ -20,10 +20,43 @@ export interface CopyButtonProps * */ variant?: "tertiary" | "tertiary-neutral"; + /** + * + */ + clipboardText: string; + /** + * + */ + text?: string; + /** + * @default "Kopiert!" + */ + activeText?: string; + /** + * + */ + onActiveChange?: (state: boolean) => void; + /** + * + */ + icon?: React.ReactNode; } export const CopyButton = forwardRef( - ({ className, variant = "tertiary", size = "medium", ...rest }, ref) => { + ( + { + className, + clipboardText, + text, + activeText = "Kopiert!", + variant = "tertiary", + size = "medium", + onActiveChange, + icon, + ...rest + }, + ref + ) => { const [active, setActive] = useState(false); const timeoutRef = useRef(); @@ -36,30 +69,65 @@ export const CopyButton = forwardRef( const handleClick = ( event: React.MouseEvent ) => { - copy("test"); + timeoutRef.current && clearTimeout(timeoutRef.current); + copy(clipboardText); setActive(true); rest.onClick?.(event); + onActiveChange?.(true); - timeoutRef.current = window.setTimeout(() => setActive(false), 2000); + timeoutRef.current = window.setTimeout(() => { + setActive(false); + onActiveChange?.(false); + }, 2000); }; return ( - + + {active ? ( + + + + ) : ( + + {icon ?? } + + )} + + {text && + (active ? ( + + ) : ( + + ))} + + ); } ); diff --git a/@navikt/core/react/src/copybutton/copy-button.stories.tsx b/@navikt/core/react/src/copybutton/copy-button.stories.tsx index 628ace6085..ddf268de16 100644 --- a/@navikt/core/react/src/copybutton/copy-button.stories.tsx +++ b/@navikt/core/react/src/copybutton/copy-button.stories.tsx @@ -1,5 +1,7 @@ -import React from "react"; +import React, { useState } from "react"; import { CopyButton } from "."; +import { Tooltip } from "../tooltip"; +import { LinkIcon } from "@navikt/aksel-icons"; export default { title: "ds-react/CopyButton", @@ -23,10 +25,68 @@ export const Default = { }; export const Variants = { - render: () => ( -
- - -
- ), + render: () => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const [active, setActive] = useState(false); + return ( +
+
+ + + } + clipboardText="3.14" + variant="tertiary" + /> + } + clipboardText="3.14" + variant="tertiary-neutral" + /> +
+ +
+ + +
+
+ + +
+
+ {" "} + Kopier dette feltet +
+
+ + setActive(v)} + /> + +
+
+ ); + }, }; From 40e5dc1984dbde8287ce5eaae00fa95a82954284 Mon Sep 17 00:00:00 2001 From: Ken Date: Thu, 11 May 2023 21:52:00 +0200 Subject: [PATCH 05/46] :art: Prop for timeout length --- @navikt/core/css/copybutton.css | 10 ++-------- @navikt/core/react/src/copybutton/CopyButton.tsx | 10 ++++++++-- .../core/react/src/copybutton/copy-button.stories.tsx | 11 ++++------- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/@navikt/core/css/copybutton.css b/@navikt/core/css/copybutton.css index 86ac1a1571..63ace29635 100644 --- a/@navikt/core/css/copybutton.css +++ b/@navikt/core/css/copybutton.css @@ -103,21 +103,15 @@ } .navds-copybutton--active > .navds-copybutton__content { - animation: akselCopyButtonAnimation 0.5s ease; + animation: akselCopyButtonAnimation 0.4s linear; } @keyframes akselCopyButtonAnimation { 0% { - opacity: 0.7; - scale: 0.98; - } - - 80% { - scale: 1; + opacity: 0.4; } 100% { opacity: 1; - scale: 1; } } diff --git a/@navikt/core/react/src/copybutton/CopyButton.tsx b/@navikt/core/react/src/copybutton/CopyButton.tsx index c961065ac3..6de3e182a9 100644 --- a/@navikt/core/react/src/copybutton/CopyButton.tsx +++ b/@navikt/core/react/src/copybutton/CopyButton.tsx @@ -40,6 +40,11 @@ export interface CopyButtonProps * */ icon?: React.ReactNode; + /** + * Timeout duration in milliseconds + * @default 2000 + */ + activeDuration?: number; } export const CopyButton = forwardRef( @@ -49,10 +54,11 @@ export const CopyButton = forwardRef( clipboardText, text, activeText = "Kopiert!", - variant = "tertiary", + variant = "tertiary-neutral", size = "medium", onActiveChange, icon, + activeDuration = 2000, ...rest }, ref @@ -78,7 +84,7 @@ export const CopyButton = forwardRef( timeoutRef.current = window.setTimeout(() => { setActive(false); onActiveChange?.(false); - }, 2000); + }, activeDuration); }; return ( diff --git a/@navikt/core/react/src/copybutton/copy-button.stories.tsx b/@navikt/core/react/src/copybutton/copy-button.stories.tsx index ddf268de16..d168a759f8 100644 --- a/@navikt/core/react/src/copybutton/copy-button.stories.tsx +++ b/@navikt/core/react/src/copybutton/copy-button.stories.tsx @@ -68,12 +68,7 @@ export const Variants = { />
- {" "} - Kopier dette feltet + Kopier dette feltet
setActive(v)} />
+
+ +
); }, From a0418e89bb8534b0c69be90aa8a4ea5c2d875a94 Mon Sep 17 00:00:00 2001 From: Ken Date: Thu, 11 May 2023 23:42:33 +0200 Subject: [PATCH 06/46] :wheelchair: Dynamic aria-labels --- .../core/react/src/copybutton/CopyButton.tsx | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/@navikt/core/react/src/copybutton/CopyButton.tsx b/@navikt/core/react/src/copybutton/CopyButton.tsx index 6de3e182a9..851f144659 100644 --- a/@navikt/core/react/src/copybutton/CopyButton.tsx +++ b/@navikt/core/react/src/copybutton/CopyButton.tsx @@ -40,6 +40,10 @@ export interface CopyButtonProps * */ icon?: React.ReactNode; + /** + * + */ + activeIcon?: React.ReactNode; /** * Timeout duration in milliseconds * @default 2000 @@ -58,12 +62,14 @@ export const CopyButton = forwardRef( size = "medium", onActiveChange, icon, + activeIcon, activeDuration = 2000, ...rest }, ref ) => { const [active, setActive] = useState(false); + const [activated, setActivated] = useState(false); const timeoutRef = useRef(); useEffect(() => { @@ -80,8 +86,10 @@ export const CopyButton = forwardRef( setActive(true); rest.onClick?.(event); onActiveChange?.(true); + setActivated(false); timeoutRef.current = window.setTimeout(() => { + setActivated(true); setActive(false); onActiveChange?.(false); }, activeDuration); @@ -102,15 +110,27 @@ export const CopyButton = forwardRef( } )} onClick={handleClick} + aria-label={activated ? activeText : undefined} + onBlur={() => setActivated(false)} > {active ? ( - + {activeIcon ?? ( + + )} ) : ( - {icon ?? } + {icon ?? ( + + )} )} From 07645851870c86dfa4b1e351c226547124f463ab Mon Sep 17 00:00:00 2001 From: Ken Date: Thu, 11 May 2023 23:49:06 +0200 Subject: [PATCH 07/46] :memo: Docs --- .../core/react/src/copybutton/CopyButton.tsx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/@navikt/core/react/src/copybutton/CopyButton.tsx b/@navikt/core/react/src/copybutton/CopyButton.tsx index 851f144659..6185e0df3e 100644 --- a/@navikt/core/react/src/copybutton/CopyButton.tsx +++ b/@navikt/core/react/src/copybutton/CopyButton.tsx @@ -17,31 +17,34 @@ export interface CopyButtonProps */ size?: "medium" | "small"; /** - * + * @default "tertiary-neutral" */ variant?: "tertiary" | "tertiary-neutral"; /** - * + * Text to copy to clipboard */ clipboardText: string; /** - * + * Optional text in button */ text?: string; /** + * Text shown when button is clicked * @default "Kopiert!" */ activeText?: string; /** - * + * Callback when 'copied'-state is active */ onActiveChange?: (state: boolean) => void; /** - * + * Icon shown when button is not clicked + * @default */ icon?: React.ReactNode; /** - * + * Icon shown when button is clicked + * @default */ activeIcon?: React.ReactNode; /** @@ -70,7 +73,7 @@ export const CopyButton = forwardRef( ) => { const [active, setActive] = useState(false); const [activated, setActivated] = useState(false); - const timeoutRef = useRef(); + const timeoutRef = useRef(); useEffect(() => { return () => { From 62f631591f911e3752e952af5f990bc5ee2e1b92 Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 10:18:43 +0200 Subject: [PATCH 08/46] :recycle: Refactor stories --- .../src/copybutton/copy-button.stories.tsx | 180 ++++++++++++------ 1 file changed, 124 insertions(+), 56 deletions(-) diff --git a/@navikt/core/react/src/copybutton/copy-button.stories.tsx b/@navikt/core/react/src/copybutton/copy-button.stories.tsx index d168a759f8..662ed657f2 100644 --- a/@navikt/core/react/src/copybutton/copy-button.stories.tsx +++ b/@navikt/core/react/src/copybutton/copy-button.stories.tsx @@ -1,7 +1,7 @@ +import { LinkIcon, ThumbUpIcon } from "@navikt/aksel-icons"; import React, { useState } from "react"; import { CopyButton } from "."; import { Tooltip } from "../tooltip"; -import { LinkIcon } from "@navikt/aksel-icons"; export default { title: "ds-react/CopyButton", @@ -9,10 +9,13 @@ export default { argTypes: { size: { defaultValue: "medium", - control: { - type: "radio", - options: ["xsmall", "small", "medium"], - }, + control: { type: "radio" }, + options: ["small", "medium"], + }, + variant: { + defaultValue: undefined, + control: { type: "radio" }, + options: ["tertiary", "tertiary-neutral"], }, }, }; @@ -21,69 +24,134 @@ export const Default = { render: (args) => , args: { size: "medium", + duration: 2000, + clipboardText: "3.14", + text: "", + activeText: "", }, }; export const Variants = { + render: () => ( +
+ + +
+ ), +}; + +export const Sizes = { + render: () => ( +
+
+ + + + +
+
+ + + + +
+
+ ), +}; + +export const Texts = { + render: () => ( +
+
+ +
+
+ +
+
+ ), +}; + +export const Icons = { + render: () => ( +
+
+ } + activeIcon={} + /> +
+
+ } + activeIcon={} + /> +
+
+ ), +}; + +export const InlineDemo = { + render: () => ( +
+ Kopier dette feltet +
+ ), +}; + +export const WithTooltip = { render: () => { // eslint-disable-next-line react-hooks/rules-of-hooks const [active, setActive] = useState(false); return ( -
-
- - - } - clipboardText="3.14" - variant="tertiary" - /> - } - clipboardText="3.14" - variant="tertiary-neutral" - /> -
- -
- +
+ setActive(v)} /> -
-
- - -
-
- Kopier dette feltet -
-
- - setActive(v)} - /> - -
-
- -
+
); }, }; + +export const Duration = { + render: () => , +}; From 46f4428ea2d42a1b0b759ffb6a7ef8f868d8a514 Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 10:20:34 +0200 Subject: [PATCH 09/46] :lipstick: Disabled styles --- @navikt/core/css/copybutton.css | 5 +++++ .../core/react/src/copybutton/copy-button.stories.tsx | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/@navikt/core/css/copybutton.css b/@navikt/core/css/copybutton.css index 63ace29635..6d9ee37201 100644 --- a/@navikt/core/css/copybutton.css +++ b/@navikt/core/css/copybutton.css @@ -115,3 +115,8 @@ opacity: 1; } } + +.navds-copybutton:where(:disabled) { + cursor: not-allowed; + opacity: 0.3; +} diff --git a/@navikt/core/react/src/copybutton/copy-button.stories.tsx b/@navikt/core/react/src/copybutton/copy-button.stories.tsx index 662ed657f2..b02be9ecb4 100644 --- a/@navikt/core/react/src/copybutton/copy-button.stories.tsx +++ b/@navikt/core/react/src/copybutton/copy-button.stories.tsx @@ -155,3 +155,12 @@ export const WithTooltip = { export const Duration = { render: () => , }; + +export const Disabled = { + render: () => ( +
+ + +
+ ), +}; From d44d6bc9f193b158fb3b28c3b78afa54d6a016d7 Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 10:43:19 +0200 Subject: [PATCH 10/46] :art: Play-tests for storybook --- .storybook/main.cjs | 2 +- .../src/copybutton/copy-button.stories.tsx | 19 ++ package.json | 3 + yarn.lock | 279 ++++++++++++++++-- 4 files changed, 271 insertions(+), 32 deletions(-) diff --git a/.storybook/main.cjs b/.storybook/main.cjs index df335beea1..454af9e323 100644 --- a/.storybook/main.cjs +++ b/.storybook/main.cjs @@ -23,7 +23,7 @@ module.exports = { addons: [ "@storybook/addon-a11y", "@whitespace/storybook-addon-html", - + "@storybook/addon-interactions", { name: "@storybook/addon-storysource", options: { diff --git a/@navikt/core/react/src/copybutton/copy-button.stories.tsx b/@navikt/core/react/src/copybutton/copy-button.stories.tsx index b02be9ecb4..f6b91fab71 100644 --- a/@navikt/core/react/src/copybutton/copy-button.stories.tsx +++ b/@navikt/core/react/src/copybutton/copy-button.stories.tsx @@ -2,6 +2,7 @@ import { LinkIcon, ThumbUpIcon } from "@navikt/aksel-icons"; import React, { useState } from "react"; import { CopyButton } from "."; import { Tooltip } from "../tooltip"; +import { userEvent, within } from "@storybook/testing-library"; export default { title: "ds-react/CopyButton", @@ -31,6 +32,24 @@ export const Default = { }, }; +export const Interaction = { + render: () => ( + + ), + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + + const button = canvas.getByTestId("copy-button"); + + userEvent.click(button); + }, +}; + export const Variants = { render: () => (
diff --git a/package.json b/package.json index 71396480d6..e339131452 100644 --- a/package.json +++ b/package.json @@ -198,11 +198,14 @@ "@storybook/addon-a11y": "7.0.4", "@storybook/addon-actions": "7.0.4", "@storybook/addon-essentials": "7.0.4", + "@storybook/addon-interactions": "7.0.4", "@storybook/addon-storysource": "7.0.4", "@storybook/addons": "7.0.4", "@storybook/csf-tools": "7.0.4", + "@storybook/jest": "^0.1.0", "@storybook/react": "7.0.4", "@storybook/react-vite": "7.0.4", + "@storybook/testing-library": "^0.1.0", "@storybook/theming": "7.0.4", "@typescript-eslint/parser": "^5.41.0", "@whitespace/storybook-addon-html": "^5.0.3", diff --git a/yarn.lock b/yarn.lock index ef320f7af8..8ddf84a0da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3571,6 +3571,19 @@ __metadata: languageName: node linkType: hard +"@jest/types@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/types@npm:27.5.1" + dependencies: + "@types/istanbul-lib-coverage": ^2.0.0 + "@types/istanbul-reports": ^3.0.0 + "@types/node": "*" + "@types/yargs": ^16.0.0 + chalk: ^4.0.0 + checksum: d1f43cc946d87543ddd79d49547aab2399481d34025d5c5f2025d3d99c573e1d9832fa83cef25e9d9b07a8583500229d15bbb07b8e233d127d911d133e2f14b1 + languageName: node + linkType: hard + "@jest/types@npm:^29.4.1": version: 29.4.1 resolution: "@jest/types@npm:29.4.1" @@ -3885,7 +3898,7 @@ __metadata: languageName: node linkType: hard -"@navikt/aksel-icons@^3.0.1, @navikt/aksel-icons@workspace:@navikt/aksel-icons": +"@navikt/aksel-icons@^3.1.3, @navikt/aksel-icons@workspace:@navikt/aksel-icons": version: 0.0.0-use.local resolution: "@navikt/aksel-icons@workspace:@navikt/aksel-icons" dependencies: @@ -3912,7 +3925,7 @@ __metadata: version: 0.0.0-use.local resolution: "@navikt/aksel@workspace:@navikt/aksel" dependencies: - "@navikt/ds-css": 3.0.1 + "@navikt/ds-css": 3.1.3 "@types/inquirer": ^9.0.3 "@types/jest": ^29.0.0 axios: 1.3.6 @@ -3936,7 +3949,7 @@ __metadata: languageName: unknown linkType: soft -"@navikt/ds-codemod@^3.0.1, @navikt/ds-codemod@workspace:@navikt/codemod": +"@navikt/ds-codemod@^3.1.3, @navikt/ds-codemod@workspace:@navikt/codemod": version: 0.0.0-use.local resolution: "@navikt/ds-codemod@workspace:@navikt/codemod" dependencies: @@ -3963,7 +3976,7 @@ __metadata: languageName: unknown linkType: soft -"@navikt/ds-css-internal@^3.0.1, @navikt/ds-css-internal@workspace:@navikt/internal/css": +"@navikt/ds-css-internal@^3.1.3, @navikt/ds-css-internal@workspace:@navikt/internal/css": version: 0.0.0-use.local resolution: "@navikt/ds-css-internal@workspace:@navikt/internal/css" dependencies: @@ -3974,11 +3987,11 @@ __metadata: languageName: unknown linkType: soft -"@navikt/ds-css@3.0.1, @navikt/ds-css@^3.0.1, @navikt/ds-css@workspace:@navikt/core/css": +"@navikt/ds-css@3.1.3, @navikt/ds-css@^3.1.3, @navikt/ds-css@workspace:@navikt/core/css": version: 0.0.0-use.local resolution: "@navikt/ds-css@workspace:@navikt/core/css" dependencies: - "@navikt/ds-tokens": ^3.0.1 + "@navikt/ds-tokens": ^3.1.3 cssnano: 6.0.0 fast-glob: 3.2.11 lodash: 4.17.21 @@ -3991,7 +4004,7 @@ __metadata: languageName: unknown linkType: soft -"@navikt/ds-icons@^3.0.1, @navikt/ds-icons@workspace:@navikt/icons": +"@navikt/ds-icons@^3.1.3, @navikt/ds-icons@workspace:@navikt/icons": version: 0.0.0-use.local resolution: "@navikt/ds-icons@workspace:@navikt/icons" dependencies: @@ -4027,8 +4040,8 @@ __metadata: "@babel/preset-env": 7.19.4 "@babel/preset-react": 7.18.6 "@babel/preset-typescript": 7.18.6 - "@navikt/ds-icons": ^3.0.1 - "@navikt/ds-react": ^3.0.1 + "@navikt/ds-icons": ^3.1.3 + "@navikt/ds-react": ^3.1.3 "@rollup/plugin-babel": 6.0.2 "@rollup/plugin-commonjs": 23.0.2 "@rollup/plugin-node-resolve": ^15.0.1 @@ -4053,12 +4066,12 @@ __metadata: languageName: unknown linkType: soft -"@navikt/ds-react-internal@^3.0.1, @navikt/ds-react-internal@workspace:@navikt/internal/react": +"@navikt/ds-react-internal@^3.1.3, @navikt/ds-react-internal@workspace:@navikt/internal/react": version: 0.0.0-use.local resolution: "@navikt/ds-react-internal@workspace:@navikt/internal/react" dependencies: - "@navikt/aksel-icons": ^3.0.1 - "@navikt/ds-react": ^3.0.1 + "@navikt/aksel-icons": ^3.1.3 + "@navikt/ds-react": ^3.1.3 clsx: ^1.1.1 concurrently: 7.2.1 copy-to-clipboard: ^3.3.1 @@ -4074,12 +4087,12 @@ __metadata: languageName: unknown linkType: soft -"@navikt/ds-react@3.0.1, @navikt/ds-react@^3.0.1, @navikt/ds-react@workspace:@navikt/core/react": +"@navikt/ds-react@3.1.3, @navikt/ds-react@^3.1.3, @navikt/ds-react@workspace:@navikt/core/react": version: 0.0.0-use.local resolution: "@navikt/ds-react@workspace:@navikt/core/react" dependencies: "@floating-ui/react": 0.17.0 - "@navikt/aksel-icons": ^3.0.1 + "@navikt/aksel-icons": ^3.1.3 "@radix-ui/react-tabs": 1.0.0 "@radix-ui/react-toggle-group": 1.0.0 "@testing-library/dom": 8.13.0 @@ -4115,11 +4128,11 @@ __metadata: languageName: unknown linkType: soft -"@navikt/ds-tailwind@^3.0.1, @navikt/ds-tailwind@workspace:@navikt/core/tailwind": +"@navikt/ds-tailwind@^3.1.3, @navikt/ds-tailwind@workspace:@navikt/core/tailwind": version: 0.0.0-use.local resolution: "@navikt/ds-tailwind@workspace:@navikt/core/tailwind" dependencies: - "@navikt/ds-tokens": ^3.0.1 + "@navikt/ds-tokens": ^3.1.3 "@types/jest": ^29.0.0 color: 4.2.3 jest: ^29.0.0 @@ -4130,7 +4143,7 @@ __metadata: languageName: unknown linkType: soft -"@navikt/ds-tokens@^3.0.1, @navikt/ds-tokens@workspace:@navikt/core/tokens": +"@navikt/ds-tokens@^3.1.3, @navikt/ds-tokens@workspace:@navikt/core/tokens": version: 0.0.0-use.local resolution: "@navikt/ds-tokens@workspace:@navikt/core/tokens" dependencies: @@ -5552,6 +5565,35 @@ __metadata: languageName: node linkType: hard +"@storybook/addon-interactions@npm:7.0.4": + version: 7.0.4 + resolution: "@storybook/addon-interactions@npm:7.0.4" + dependencies: + "@storybook/client-logger": 7.0.4 + "@storybook/components": 7.0.4 + "@storybook/core-common": 7.0.4 + "@storybook/core-events": 7.0.4 + "@storybook/global": ^5.0.0 + "@storybook/instrumenter": 7.0.4 + "@storybook/manager-api": 7.0.4 + "@storybook/preview-api": 7.0.4 + "@storybook/theming": 7.0.4 + "@storybook/types": 7.0.4 + jest-mock: ^27.0.6 + polished: ^4.2.2 + ts-dedent: ^2.2.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + checksum: cce4e214d3f37e7ee4fc62f848aea80462965ab549a9cd626fb356b798ed5e11ac5cd84f2b8371f71f039350ce86ff0dfe81a1fa0a32c08cea6bb98410f40e96 + languageName: node + linkType: hard + "@storybook/addon-measure@npm:7.0.4": version: 7.0.4 resolution: "@storybook/addon-measure@npm:7.0.4" @@ -5782,6 +5824,20 @@ __metadata: languageName: node linkType: hard +"@storybook/channel-postmessage@npm:7.0.10": + version: 7.0.10 + resolution: "@storybook/channel-postmessage@npm:7.0.10" + dependencies: + "@storybook/channels": 7.0.10 + "@storybook/client-logger": 7.0.10 + "@storybook/core-events": 7.0.10 + "@storybook/global": ^5.0.0 + qs: ^6.10.0 + telejson: ^7.0.3 + checksum: 5fe13e6be29ca1a1ec67f2b0f838e837d5ed7b386dfc1a7007bef071822854b9e4fe7153da3b679de32a0644d66fb5f1b1c5e095140d24ed1457bb4b8deb8507 + languageName: node + linkType: hard + "@storybook/channel-postmessage@npm:7.0.4": version: 7.0.4 resolution: "@storybook/channel-postmessage@npm:7.0.4" @@ -5808,6 +5864,13 @@ __metadata: languageName: node linkType: hard +"@storybook/channels@npm:7.0.10": + version: 7.0.10 + resolution: "@storybook/channels@npm:7.0.10" + checksum: 6aed7cc0ef8ef3f398112c79ed4eb61c8b6ba4bbb7ac29125f9dd2e3ccf7f0d13cca0e91ca237c7464e32fffd6797ce1ac96dfe25ea8666dd0af612340ee7d2a + languageName: node + linkType: hard + "@storybook/channels@npm:7.0.4": version: 7.0.4 resolution: "@storybook/channels@npm:7.0.4" @@ -5864,6 +5927,15 @@ __metadata: languageName: node linkType: hard +"@storybook/client-logger@npm:7.0.10, @storybook/client-logger@npm:^7.0.0-beta.0 || ^7.0.0-rc.0 || ^7.0.0": + version: 7.0.10 + resolution: "@storybook/client-logger@npm:7.0.10" + dependencies: + "@storybook/global": ^5.0.0 + checksum: 6a1824476bc49304e0d6274c6f53c70a018e390430accfd942a5e288a1d13be7e4851c8e8a9cde5535bac711c42c6531739a6eb36d878b388e45fe498709f3ef + languageName: node + linkType: hard + "@storybook/client-logger@npm:7.0.4": version: 7.0.4 resolution: "@storybook/client-logger@npm:7.0.4" @@ -5950,6 +6022,13 @@ __metadata: languageName: node linkType: hard +"@storybook/core-events@npm:7.0.10": + version: 7.0.10 + resolution: "@storybook/core-events@npm:7.0.10" + checksum: 4bc6f35f763524aabc3d41307be427049dc93562cfb1ff79a0788fba8268c29b6438b1691e9bfecd17206a6f4e5705dad2f3b30ebf7d2f89376290139babc044 + languageName: node + linkType: hard + "@storybook/core-events@npm:7.0.4": version: 7.0.4 resolution: "@storybook/core-events@npm:7.0.4" @@ -6065,6 +6144,15 @@ __metadata: languageName: node linkType: hard +"@storybook/expect@npm:storybook-jest": + version: 27.5.2-0 + resolution: "@storybook/expect@npm:27.5.2-0" + dependencies: + "@types/jest": ">=26.0.0" + checksum: 09738a8f8e0b9d3d5a909c80ce0c101080cf376316ceca1f3820e88877d6b5ef92abd847b4c4a4e9687c43c2168a6e3e8cdd74947b6af622688797f74cf523df + languageName: node + linkType: hard + "@storybook/global@npm:^5.0.0": version: 5.0.0 resolution: "@storybook/global@npm:5.0.0" @@ -6072,6 +6160,44 @@ __metadata: languageName: node linkType: hard +"@storybook/instrumenter@npm:7.0.4": + version: 7.0.4 + resolution: "@storybook/instrumenter@npm:7.0.4" + dependencies: + "@storybook/channels": 7.0.4 + "@storybook/client-logger": 7.0.4 + "@storybook/core-events": 7.0.4 + "@storybook/global": ^5.0.0 + "@storybook/preview-api": 7.0.4 + checksum: d5f22fcea3efefd6bb0523c3164ffb7f0287c89a4f6485ac8165658d35b699d6665c964ba01fd3f0dff0938913e6c0b08341796acc9d3fe21e63ebd441147bd9 + languageName: node + linkType: hard + +"@storybook/instrumenter@npm:^7.0.0-beta.0 || ^7.0.0-rc.0 || ^7.0.0": + version: 7.0.10 + resolution: "@storybook/instrumenter@npm:7.0.10" + dependencies: + "@storybook/channels": 7.0.10 + "@storybook/client-logger": 7.0.10 + "@storybook/core-events": 7.0.10 + "@storybook/global": ^5.0.0 + "@storybook/preview-api": 7.0.10 + checksum: c4687c61e30bd3b16652f0ba09638f0ae0b39ffc6eeef629ec17bc0b66ce819c3fa5dedba0a0832d3ae79a1ab1bc1bc9d8dd807c69b3a0fb246592b5a4cffee0 + languageName: node + linkType: hard + +"@storybook/jest@npm:^0.1.0": + version: 0.1.0 + resolution: "@storybook/jest@npm:0.1.0" + dependencies: + "@storybook/expect": storybook-jest + "@storybook/instrumenter": ^7.0.0-beta.0 || ^7.0.0-rc.0 || ^7.0.0 + "@testing-library/jest-dom": ^5.16.2 + jest-mock: ^27.3.0 + checksum: 74a4b9dc0ce921f72c2f4fbba053e4a4c84a6a16d07406492a26733f55438229197e547364d0848ac3df38ab5ce9e20829029196d376a267033d8e75904ab611 + languageName: node + linkType: hard + "@storybook/manager-api@npm:7.0.4": version: 7.0.4 resolution: "@storybook/manager-api@npm:7.0.4" @@ -6131,6 +6257,29 @@ __metadata: languageName: node linkType: hard +"@storybook/preview-api@npm:7.0.10": + version: 7.0.10 + resolution: "@storybook/preview-api@npm:7.0.10" + dependencies: + "@storybook/channel-postmessage": 7.0.10 + "@storybook/channels": 7.0.10 + "@storybook/client-logger": 7.0.10 + "@storybook/core-events": 7.0.10 + "@storybook/csf": ^0.1.0 + "@storybook/global": ^5.0.0 + "@storybook/types": 7.0.10 + "@types/qs": ^6.9.5 + dequal: ^2.0.2 + lodash: ^4.17.21 + memoizerific: ^1.11.3 + qs: ^6.10.0 + synchronous-promise: ^2.0.15 + ts-dedent: ^2.0.0 + util-deprecate: ^1.0.2 + checksum: 04063b650ae4de687b368de0fbec62b1acddadcedddd70ce471b0dd7819bd574af965834985133a7b6a8409dbdf4196b1206d84ee71737ed4abc0c7c01ed1612 + languageName: node + linkType: hard + "@storybook/preview-api@npm:7.0.4": version: 7.0.4 resolution: "@storybook/preview-api@npm:7.0.4" @@ -6273,6 +6422,19 @@ __metadata: languageName: node linkType: hard +"@storybook/testing-library@npm:^0.1.0": + version: 0.1.0 + resolution: "@storybook/testing-library@npm:0.1.0" + dependencies: + "@storybook/client-logger": ^7.0.0-beta.0 || ^7.0.0-rc.0 || ^7.0.0 + "@storybook/instrumenter": ^7.0.0-beta.0 || ^7.0.0-rc.0 || ^7.0.0 + "@testing-library/dom": ^8.3.0 + "@testing-library/user-event": ^13.2.1 + ts-dedent: ^2.2.0 + checksum: a413110dafe80f8fe64da912fddb653bc3c695c94bd023b8cb918e519e9f94119bae559909bfb8ad229041a4f17a12b33425c61572270702c116d0b727b4d4ba + languageName: node + linkType: hard + "@storybook/theming@npm:7.0.4": version: 7.0.4 resolution: "@storybook/theming@npm:7.0.4" @@ -6288,6 +6450,18 @@ __metadata: languageName: node linkType: hard +"@storybook/types@npm:7.0.10": + version: 7.0.10 + resolution: "@storybook/types@npm:7.0.10" + dependencies: + "@storybook/channels": 7.0.10 + "@types/babel__core": ^7.0.0 + "@types/express": ^4.7.0 + file-system-cache: ^2.0.0 + checksum: c6ce373863c8c33f8a2e1409b6452934762f3e89b152952f558e1970e25c8b9dd32a5f71a239ca483736bd5ecc2b265bec413dada23349791dac6ace532dd11b + languageName: node + linkType: hard + "@storybook/types@npm:7.0.4": version: 7.0.4 resolution: "@storybook/types@npm:7.0.4" @@ -6658,7 +6832,7 @@ __metadata: languageName: node linkType: hard -"@testing-library/dom@npm:^8.5.0": +"@testing-library/dom@npm:^8.3.0, @testing-library/dom@npm:^8.5.0": version: 8.20.0 resolution: "@testing-library/dom@npm:8.20.0" dependencies: @@ -6674,7 +6848,7 @@ __metadata: languageName: node linkType: hard -"@testing-library/jest-dom@npm:^5.16.0": +"@testing-library/jest-dom@npm:^5.16.0, @testing-library/jest-dom@npm:^5.16.2": version: 5.16.5 resolution: "@testing-library/jest-dom@npm:5.16.5" dependencies: @@ -6705,6 +6879,17 @@ __metadata: languageName: node linkType: hard +"@testing-library/user-event@npm:^13.2.1": + version: 13.5.0 + resolution: "@testing-library/user-event@npm:13.5.0" + dependencies: + "@babel/runtime": ^7.12.5 + peerDependencies: + "@testing-library/dom": ">=7.21.4" + checksum: 16319de685fbb7008f1ba667928f458b2d08196918002daca56996de80ef35e6d9de26e9e1ece7d00a004692b95a597cf9142fff0dc53f2f51606a776584f549 + languageName: node + linkType: hard + "@testing-library/user-event@npm:^14.2.0": version: 14.4.3 resolution: "@testing-library/user-event@npm:14.4.3" @@ -7115,6 +7300,16 @@ __metadata: languageName: node linkType: hard +"@types/jest@npm:>=26.0.0": + version: 29.5.1 + resolution: "@types/jest@npm:29.5.1" + dependencies: + expect: ^29.0.0 + pretty-format: ^29.0.0 + checksum: 0a22491dec86333c0e92b897be2c809c922a7b2b0aa5604ac369810d6b2360908b4a3f2c6892e8a237a54fa1f10ecefe0e823ec5fcb7915195af4dfe88d2197e + languageName: node + linkType: hard + "@types/jscodeshift@npm:0.11.5": version: 0.11.5 resolution: "@types/jscodeshift@npm:0.11.5" @@ -7526,6 +7721,15 @@ __metadata: languageName: node linkType: hard +"@types/yargs@npm:^16.0.0": + version: 16.0.5 + resolution: "@types/yargs@npm:16.0.5" + dependencies: + "@types/yargs-parser": "*" + checksum: 22697f7cc8aa32dcc10981a87f035e183303a58351c537c81fb450270d5c494b1d918186210e445b0eb2e4a8b34a8bda2a595f346bdb1c9ed2b63d193cb00430 + languageName: node + linkType: hard + "@types/yargs@npm:^17.0.8": version: 17.0.22 resolution: "@types/yargs@npm:17.0.22" @@ -8093,15 +8297,15 @@ __metadata: version: 0.0.0-use.local resolution: "aksel.nav.no@workspace:aksel.nav.no" dependencies: - "@navikt/aksel-icons": ^3.0.1 - "@navikt/ds-codemod": ^3.0.1 - "@navikt/ds-css": ^3.0.1 - "@navikt/ds-css-internal": ^3.0.1 - "@navikt/ds-icons": ^3.0.1 - "@navikt/ds-react": ^3.0.1 - "@navikt/ds-react-internal": ^3.0.1 - "@navikt/ds-tailwind": ^3.0.1 - "@navikt/ds-tokens": ^3.0.1 + "@navikt/aksel-icons": ^3.1.3 + "@navikt/ds-codemod": ^3.1.3 + "@navikt/ds-css": ^3.1.3 + "@navikt/ds-css-internal": ^3.1.3 + "@navikt/ds-icons": ^3.1.3 + "@navikt/ds-react": ^3.1.3 + "@navikt/ds-react-internal": ^3.1.3 + "@navikt/ds-tailwind": ^3.1.3 + "@navikt/ds-tokens": ^3.1.3 prettier-plugin-tailwindcss: ^0.2.3 languageName: unknown linkType: soft @@ -8115,11 +8319,14 @@ __metadata: "@storybook/addon-a11y": 7.0.4 "@storybook/addon-actions": 7.0.4 "@storybook/addon-essentials": 7.0.4 + "@storybook/addon-interactions": 7.0.4 "@storybook/addon-storysource": 7.0.4 "@storybook/addons": 7.0.4 "@storybook/csf-tools": 7.0.4 + "@storybook/jest": ^0.1.0 "@storybook/react": 7.0.4 "@storybook/react-vite": 7.0.4 + "@storybook/testing-library": ^0.1.0 "@storybook/theming": 7.0.4 "@typescript-eslint/parser": ^5.41.0 "@whitespace/storybook-addon-html": ^5.0.3 @@ -16662,6 +16869,16 @@ __metadata: languageName: node linkType: hard +"jest-mock@npm:^27.0.6, jest-mock@npm:^27.3.0": + version: 27.5.1 + resolution: "jest-mock@npm:27.5.1" + dependencies: + "@jest/types": ^27.5.1 + "@types/node": "*" + checksum: f5b5904bb1741b4a1687a5f492535b7b1758dc26534c72a5423305f8711292e96a601dec966df81bb313269fb52d47227e29f9c2e08324d79529172f67311be0 + languageName: node + linkType: hard + "jest-mock@npm:^29.4.1": version: 29.4.1 resolution: "jest-mock@npm:29.4.1" @@ -23123,8 +23340,8 @@ __metadata: version: 0.0.0-use.local resolution: "shadow-dom@workspace:examples/shadow-dom" dependencies: - "@navikt/ds-css": 3.0.1 - "@navikt/ds-react": 3.0.1 + "@navikt/ds-css": 3.1.3 + "@navikt/ds-react": 3.1.3 "@types/react": ^18.0.0 "@types/react-dom": ^18.0.0 "@vitejs/plugin-react": ^2.1.0 @@ -24854,7 +25071,7 @@ __metadata: languageName: node linkType: hard -"ts-dedent@npm:^2.0.0": +"ts-dedent@npm:^2.0.0, ts-dedent@npm:^2.2.0": version: 2.2.0 resolution: "ts-dedent@npm:2.2.0" checksum: 93ed8f7878b6d5ed3c08d99b740010eede6bccfe64bce61c5a4da06a2c17d6ddbb80a8c49c2d15251de7594a4f93ffa21dd10e7be75ef66a4dc9951b4a94e2af From 2e07548d3d267b75964192c35255842362d0ef32 Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 11:02:47 +0200 Subject: [PATCH 11/46] :recycle: Refactor copy-function --- @navikt/core/react/src/util/copy.ts | 51 ++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/@navikt/core/react/src/util/copy.ts b/@navikt/core/react/src/util/copy.ts index 029e1bae8e..54adbda5dd 100644 --- a/@navikt/core/react/src/util/copy.ts +++ b/@navikt/core/react/src/util/copy.ts @@ -1,11 +1,20 @@ // https://github.com/sudodoki/copy-to-clipboard/blob/main/index.js -function copy(text) { - let range: Range, mark: HTMLSpanElement | null; - let selection: Selection | null; +const defaultMessage = "Kopier til utklippstavle: #{key}, Enter"; - const debug = process.env.NODE_ENV !== "production"; +function format(message) { + const copyKey = (/mac os x/i.test(navigator.userAgent) ? "⌘" : "Ctrl") + "+C"; + return message.replace(/#{\s*key\s*}/g, copyKey); +} +export default function copy(text) { + let debug, + message, + range, + selection, + mark, + success = false; + debug = process.env.NODE_ENV !== "production"; try { range = document.createRange(); selection = document.getSelection(); @@ -18,14 +27,14 @@ function copy(text) { mark.style.all = "unset"; // prevents scrolling to the end of the page mark.style.position = "fixed"; - mark.style.top = "0"; - mark.style.clipPath = "rect(0, 0, 0, 0)"; + mark.style.top = 0; + mark.style.clip = "rect(0, 0, 0, 0)"; // used to preserve spaces and line breaks mark.style.whiteSpace = "pre"; // do not inherit user-select (it may be `none`) - (mark.style as any).webkitUserSelect = "text"; - (mark.style as any).MozUserSelect = "text"; - (mark.style as any).msUserSelect = "text"; + mark.style.webkitUserSelect = "text"; + mark.style.MozUserSelect = "text"; + mark.style.msUserSelect = "text"; mark.style.userSelect = "text"; mark.addEventListener("copy", function (e) { e.stopPropagation(); @@ -34,13 +43,27 @@ function copy(text) { document.body.appendChild(mark); range.selectNodeContents(mark); - selection?.addRange(range); + selection.addRange(range); - var successful = document.execCommand("copy"); + const successful = document.execCommand("copy"); if (!successful) { throw new Error("copy command was unsuccessful"); } + success = true; + } catch (err) { + debug && console.error("unable to copy using execCommand: ", err); + debug && console.warn("trying IE specific stuff"); + try { + (window as any).clipboardData.setData("text", text); + success = true; + } catch (err) { + debug && console.error("unable to copy using clipboardData: ", err); + debug && console.error("falling back to prompt"); + message = format(defaultMessage); + window.prompt(message, text); + } + } finally { if (selection) { if (typeof selection.removeRange == "function") { selection.removeRange(range); @@ -52,9 +75,7 @@ function copy(text) { if (mark) { document.body.removeChild(mark); } - } catch (err) { - debug && console.error("unable to copy using execCommand: ", err); } -} -export default copy; + return success; +} From de9ce7ca546ff2940b704c7ab534a05aa6cdeb5c Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 11:05:22 +0200 Subject: [PATCH 12/46] :recycle: Rename to action,neutral --- @navikt/core/css/copybutton.css | 36 +++++++++---------- .../core/react/src/copybutton/CopyButton.tsx | 6 ++-- .../src/copybutton/copy-button.stories.tsx | 36 +++++++------------ 3 files changed, 33 insertions(+), 45 deletions(-) diff --git a/@navikt/core/css/copybutton.css b/@navikt/core/css/copybutton.css index 6d9ee37201..c2143c1820 100644 --- a/@navikt/core/css/copybutton.css +++ b/@navikt/core/css/copybutton.css @@ -46,14 +46,14 @@ margin: 0; } -.navds-copybutton--tertiary { - color: var(--ac-button-tertiary-text, var(--a-text-action)); - background-color: var(--ac-button-tertiary-bg, var(--a-surface-transparent)); +.navds-copybutton--action { + color: var(--ac-button-action-text, var(--a-text-action)); + background-color: var(--ac-button-action-bg, var(--a-surface-transparent)); } -.navds-copybutton--tertiary:hover { - color: var(--ac-button-tertiary-hover-text, var(--a-text-action-on-action-subtle)); - background-color: var(--ac-button-tertiary-hover-bg, var(--a-surface-action-subtle-hover)); +.navds-copybutton--action:hover { + color: var(--ac-button-action-hover-text, var(--a-text-action-on-action-subtle)); + background-color: var(--ac-button-action-hover-bg, var(--a-surface-action-subtle-hover)); } .navds-copybutton:focus-visible { @@ -68,30 +68,30 @@ } } -.navds-copybutton--tertiary:where(:disabled, .navds-copybutton--disabled), -.navds-copybutton--tertiary:hover:where(:disabled, .navds-copybutton--disabled) { - color: var(--ac-button-tertiary-text, var(--a-text-action)); +.navds-copybutton--action:where(:disabled, .navds-copybutton--disabled), +.navds-copybutton--action:hover:where(:disabled, .navds-copybutton--disabled) { + color: var(--ac-button-action-text, var(--a-text-action)); background: none; box-shadow: none; } -.navds-copybutton--tertiary-neutral { - color: var(--ac-button-tertiary-neutral-text, var(--a-text-default)); +.navds-copybutton--neutral { + color: var(--ac-button-neutral-text, var(--a-text-default)); } -.navds-copybutton--tertiary-neutral:hover { - color: var(--ac-button-tertiary-neutral-hover-text, var(--a-text-default)); - background-color: var(--ac-button-tertiary-neutral-hover-bg, var(--a-surface-neutral-subtle-hover)); +.navds-copybutton--neutral:hover { + color: var(--ac-button-neutral-hover-text, var(--a-text-default)); + background-color: var(--ac-button-neutral-hover-bg, var(--a-surface-neutral-subtle-hover)); } -.navds-copybutton--tertiary-neutral:where(:disabled, .navds-copybutton--disabled), -.navds-copybutton--tertiary-neutral:hover:where(:disabled, .navds-copybutton--disabled) { - color: var(--ac-button-tertiary-neutral-text, var(--a-text-default)); +.navds-copybutton--neutral:where(:disabled, .navds-copybutton--disabled), +.navds-copybutton--neutral:hover:where(:disabled, .navds-copybutton--disabled) { + color: var(--ac-button-neutral-text, var(--a-text-default)); background: none; box-shadow: none; } -.navds-copybutton--active.navds-copybutton--tertiary { +.navds-copybutton--active.navds-copybutton--action { color: var(--a-surface-success); } diff --git a/@navikt/core/react/src/copybutton/CopyButton.tsx b/@navikt/core/react/src/copybutton/CopyButton.tsx index 6185e0df3e..aa1155926e 100644 --- a/@navikt/core/react/src/copybutton/CopyButton.tsx +++ b/@navikt/core/react/src/copybutton/CopyButton.tsx @@ -17,9 +17,9 @@ export interface CopyButtonProps */ size?: "medium" | "small"; /** - * @default "tertiary-neutral" + * @default "neutral" */ - variant?: "tertiary" | "tertiary-neutral"; + variant?: "action" | "neutral"; /** * Text to copy to clipboard */ @@ -61,7 +61,7 @@ export const CopyButton = forwardRef( clipboardText, text, activeText = "Kopiert!", - variant = "tertiary-neutral", + variant = "neutral", size = "medium", onActiveChange, icon, diff --git a/@navikt/core/react/src/copybutton/copy-button.stories.tsx b/@navikt/core/react/src/copybutton/copy-button.stories.tsx index f6b91fab71..c4547b1224 100644 --- a/@navikt/core/react/src/copybutton/copy-button.stories.tsx +++ b/@navikt/core/react/src/copybutton/copy-button.stories.tsx @@ -16,7 +16,7 @@ export default { variant: { defaultValue: undefined, control: { type: "radio" }, - options: ["tertiary", "tertiary-neutral"], + options: ["neutral", "action"], }, }, }; @@ -36,7 +36,7 @@ export const Interaction = { render: () => ( @@ -53,12 +53,8 @@ export const Interaction = { export const Variants = { render: () => (
- - + +
), }; @@ -67,32 +63,24 @@ export const Sizes = { render: () => (
- - - - + + + +
- - + +
From 998e44d67d6f6620aaae7b76a40b6a6b3a402614 Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 11:53:04 +0200 Subject: [PATCH 13/46] :memo: Added component to mappings --- @navikt/core/css/config/_mappings.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/@navikt/core/css/config/_mappings.js b/@navikt/core/css/config/_mappings.js index 91a6f39311..4d059b1504 100644 --- a/@navikt/core/css/config/_mappings.js +++ b/@navikt/core/css/config/_mappings.js @@ -63,6 +63,11 @@ const StyleMappings = { component: "ContentContainer", main: "content-container.css", }, + { + component: "CopyButton", + main: "copybutton.css", + dependencies: [typoCss], + }, { component: "Detail", main: typoCss }, { component: "ErrorMessage", main: typoCss }, { component: "ErrorSummary", main: formCss, dependencies: [typoCss] }, From 43cb4e725966214135792d5d028e02f19af7b39b Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 11:54:11 +0200 Subject: [PATCH 14/46] :memo: Fallback tokens --- @navikt/core/css/copybutton.css | 40 ++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/@navikt/core/css/copybutton.css b/@navikt/core/css/copybutton.css index c2143c1820..aadc984049 100644 --- a/@navikt/core/css/copybutton.css +++ b/@navikt/core/css/copybutton.css @@ -1,45 +1,45 @@ .navds-copybutton { - --__ac-button-padding: var(--a-spacing-3) var(--a-spacing-5); + --__ac-copybutton-padding: var(--a-spacing-3) var(--a-spacing-5); cursor: pointer; margin: 0; text-decoration: none; border: none; background: none; - border-radius: var(--ac-button-border-radius, var(--a-border-radius-medium)); - padding: var(--ac-button-padding, var(--__ac-button-padding)); + border-radius: var(--ac-copybutton-border-radius, var(--a-border-radius-medium)); + padding: var(--ac-copybutton-padding, var(--__ac-copybutton-padding)); display: grid; place-content: center; } .navds-copybutton--small { - --__ac-button-padding: var(--a-spacing-1) var(--a-spacing-3); + --__ac-copybutton-padding: var(--a-spacing-1) var(--a-spacing-3); - padding: var(--ac-button-padding-small, var(--__ac-button-padding)); + padding: var(--ac-copybutton-padding-small, var(--__ac-copybutton-padding)); min-height: 2rem; } .navds-copybutton--icon-only { - --__ac-button-padding: var(--a-spacing-3); + --__ac-copybutton-padding: var(--a-spacing-3); - padding: var(--ac-button-padding-icon-only, var(--__ac-button-padding)); + padding: var(--ac-copybutton-padding-icon-only, var(--__ac-copybutton-padding)); } .navds-copybutton--small.navds-copybutton--icon-only { - --__ac-button-padding: var(--a-spacing-1); + --__ac-copybutton-padding: var(--a-spacing-1); - padding: var(--ac-button-padding-icon-only-small, var(--__ac-button-padding)); + padding: var(--ac-copybutton-padding-icon-only-small, var(--__ac-copybutton-padding)); } .navds-copybutton__icon { - --ac-button-icon-margin: -4px; + --ac-copybutton-icon-margin: -4px; font-size: 1.5rem; display: flex; } .navds-copybutton__icon:first-child { - margin-left: var(--ac-button-icon-margin); + margin-left: var(--ac-copybutton-icon-margin); } .navds-copybutton__icon:only-child { @@ -47,13 +47,13 @@ } .navds-copybutton--action { - color: var(--ac-button-action-text, var(--a-text-action)); - background-color: var(--ac-button-action-bg, var(--a-surface-transparent)); + color: var(--ac-copybutton-action-text, var(--a-text-action)); + background-color: var(--ac-copybutton-action-bg, var(--a-surface-transparent)); } .navds-copybutton--action:hover { - color: var(--ac-button-action-hover-text, var(--a-text-action-on-action-subtle)); - background-color: var(--ac-button-action-hover-bg, var(--a-surface-action-subtle-hover)); + color: var(--ac-copybutton-action-hover-text, var(--a-text-action-on-action-subtle)); + background-color: var(--ac-copybutton-action-hover-bg, var(--a-surface-action-subtle-hover)); } .navds-copybutton:focus-visible { @@ -70,23 +70,23 @@ .navds-copybutton--action:where(:disabled, .navds-copybutton--disabled), .navds-copybutton--action:hover:where(:disabled, .navds-copybutton--disabled) { - color: var(--ac-button-action-text, var(--a-text-action)); + color: var(--ac-copybutton-action-text, var(--a-text-action)); background: none; box-shadow: none; } .navds-copybutton--neutral { - color: var(--ac-button-neutral-text, var(--a-text-default)); + color: var(--ac-copybutton-neutral-text, var(--a-text-default)); } .navds-copybutton--neutral:hover { - color: var(--ac-button-neutral-hover-text, var(--a-text-default)); - background-color: var(--ac-button-neutral-hover-bg, var(--a-surface-neutral-subtle-hover)); + color: var(--ac-copybutton-neutral-hover-text, var(--a-text-default)); + background-color: var(--ac-copybutton-neutral-hover-bg, var(--a-surface-neutral-subtle-hover)); } .navds-copybutton--neutral:where(:disabled, .navds-copybutton--disabled), .navds-copybutton--neutral:hover:where(:disabled, .navds-copybutton--disabled) { - color: var(--ac-button-neutral-text, var(--a-text-default)); + color: var(--ac-copybutton-neutral-text, var(--a-text-default)); background: none; box-shadow: none; } From aa8e4fea0dd5c61c40331e5da8a775c2348b7a87 Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 12:06:54 +0200 Subject: [PATCH 15/46] :art: Tokens --- @navikt/core/css/copybutton.css | 58 ++++++++++++++++----------------- @navikt/core/css/tokens.json | 14 ++++++++ 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/@navikt/core/css/copybutton.css b/@navikt/core/css/copybutton.css index aadc984049..d60e1a5828 100644 --- a/@navikt/core/css/copybutton.css +++ b/@navikt/core/css/copybutton.css @@ -7,7 +7,7 @@ border: none; background: none; border-radius: var(--ac-copybutton-border-radius, var(--a-border-radius-medium)); - padding: var(--ac-copybutton-padding, var(--__ac-copybutton-padding)); + padding: var(--__ac-copybutton-padding); display: grid; place-content: center; } @@ -15,47 +15,27 @@ .navds-copybutton--small { --__ac-copybutton-padding: var(--a-spacing-1) var(--a-spacing-3); - padding: var(--ac-copybutton-padding-small, var(--__ac-copybutton-padding)); min-height: 2rem; } .navds-copybutton--icon-only { --__ac-copybutton-padding: var(--a-spacing-3); - - padding: var(--ac-copybutton-padding-icon-only, var(--__ac-copybutton-padding)); } .navds-copybutton--small.navds-copybutton--icon-only { --__ac-copybutton-padding: var(--a-spacing-1); - - padding: var(--ac-copybutton-padding-icon-only-small, var(--__ac-copybutton-padding)); } .navds-copybutton__icon { - --ac-copybutton-icon-margin: -4px; - font-size: 1.5rem; display: flex; -} - -.navds-copybutton__icon:first-child { - margin-left: var(--ac-copybutton-icon-margin); + margin-left: -4px; } .navds-copybutton__icon:only-child { margin: 0; } -.navds-copybutton--action { - color: var(--ac-copybutton-action-text, var(--a-text-action)); - background-color: var(--ac-copybutton-action-bg, var(--a-surface-transparent)); -} - -.navds-copybutton--action:hover { - color: var(--ac-copybutton-action-hover-text, var(--a-text-action-on-action-subtle)); - background-color: var(--ac-copybutton-action-hover-bg, var(--a-surface-action-subtle-hover)); -} - .navds-copybutton:focus-visible { outline: none; box-shadow: var(--a-shadow-focus); @@ -68,15 +48,32 @@ } } -.navds-copybutton--action:where(:disabled, .navds-copybutton--disabled), -.navds-copybutton--action:hover:where(:disabled, .navds-copybutton--disabled) { +/* Variant/action */ +.navds-copybutton--action { + color: var(--ac-copybutton-action-text, var(--a-text-action)); + background-color: var(--ac-copybutton-action-bg, var(--a-surface-transparent)); +} + +.navds-copybutton--action:hover { + color: var(--ac-copybutton-action-hover-text, var(--a-text-action-on-action-subtle)); + background-color: var(--ac-copybutton-action-hover-bg, var(--a-surface-action-subtle-hover)); +} + +.navds-copybutton--action:where(:disabled), +.navds-copybutton--action:hover:where(:disabled) { color: var(--ac-copybutton-action-text, var(--a-text-action)); - background: none; + background-color: var(--ac-copybutton-action-bg, var(--a-surface-transparent)); box-shadow: none; } +.navds-copybutton--active.navds-copybutton--action { + color: var(--ac-copybutton-action-active-text, var(--a-icon-success)); +} + +/* Variant/neutral */ .navds-copybutton--neutral { color: var(--ac-copybutton-neutral-text, var(--a-text-default)); + background-color: var(--ac-copybutton-neutral-bg, var(--a-surface-transparent)); } .navds-copybutton--neutral:hover { @@ -87,12 +84,12 @@ .navds-copybutton--neutral:where(:disabled, .navds-copybutton--disabled), .navds-copybutton--neutral:hover:where(:disabled, .navds-copybutton--disabled) { color: var(--ac-copybutton-neutral-text, var(--a-text-default)); - background: none; + background-color: var(--ac-copybutton-neutral-bg, var(--a-surface-transparent)); box-shadow: none; } -.navds-copybutton--active.navds-copybutton--action { - color: var(--a-surface-success); +.navds-copybutton--active.navds-copybutton--neutral { + color: var(--ac-copybutton-neutral-active-text, var(--a-text-default)); } .navds-copybutton__content { @@ -103,12 +100,12 @@ } .navds-copybutton--active > .navds-copybutton__content { - animation: akselCopyButtonAnimation 0.4s linear; + animation: var(--ac-copybutton-animation, akselCopyButtonAnimation 0.4s linear); } @keyframes akselCopyButtonAnimation { 0% { - opacity: 0.4; + opacity: 0.3; } 100% { @@ -116,6 +113,7 @@ } } +/* Disabled */ .navds-copybutton:where(:disabled) { cursor: not-allowed; opacity: 0.3; diff --git a/@navikt/core/css/tokens.json b/@navikt/core/css/tokens.json index 235fab1cb3..4de4ec62c5 100644 --- a/@navikt/core/css/tokens.json +++ b/@navikt/core/css/tokens.json @@ -104,6 +104,20 @@ "--ac-chip-removable-neutral-hover-bg": "--a-surface-neutral-subtle-hover", "--ac-chip-removable-neutral-hover-border": "--a-border-strong" }, + "copybutton": { + "--ac-copybutton-border-radius": "--a-border-radius-medium", + "--ac-copybutton-action-text": "--a-text-action", + "--ac-copybutton-action-bg": "--a-surface-transparent", + "--ac-copybutton-action-hover-text": "--a-text-action-on-action-subtle", + "--ac-copybutton-action-hover-bg": "--a-surface-action-subtle-hover", + "--ac-copybutton-action-active-text": "--a-icon-success", + "--ac-copybutton-neutral-text": "--a-text-default", + "--ac-copybutton-neutral-bg": "--a-surface-transparent", + "--ac-copybutton-neutral-hover-text": "--a-text-default", + "--ac-copybutton-neutral-hover-bg": "--a-surface-neutral-subtle-hover", + "--ac-copybutton-neutral-active-text": "--a-text-default", + "--ac-copybutton-animation": "akselCopyButtonAnimation 0.4s linear" + }, "date": { "--ac-date-middle-text": "--a-text-on-action", "--ac-date-middle-bg": "--a-surface-action-selected", From 6b79735afd7cd3f11cf7e5690c85053574dfe472 Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 12:09:01 +0200 Subject: [PATCH 16/46] :memo: Docs --- @navikt/core/react/src/copybutton/CopyButton.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/@navikt/core/react/src/copybutton/CopyButton.tsx b/@navikt/core/react/src/copybutton/CopyButton.tsx index aa1155926e..78f227738f 100644 --- a/@navikt/core/react/src/copybutton/CopyButton.tsx +++ b/@navikt/core/react/src/copybutton/CopyButton.tsx @@ -30,7 +30,7 @@ export interface CopyButtonProps text?: string; /** * Text shown when button is clicked - * @default "Kopiert!" + * Only set if used with 'text'-prop */ activeText?: string; /** @@ -43,7 +43,7 @@ export interface CopyButtonProps */ icon?: React.ReactNode; /** - * Icon shown when button is clicked + * Icon shown when active * @default */ activeIcon?: React.ReactNode; From cc53e12f823368f6dafd66176d8df34ad2bc9150 Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 12:10:07 +0200 Subject: [PATCH 17/46] :memo: Deprecation-test --- .../react/src/copy-to-clipboard/CopyToClipboard.tsx | 6 ++++++ @navikt/internal/react/src/copy-to-clipboard/index.ts | 3 +++ 2 files changed, 9 insertions(+) diff --git a/@navikt/internal/react/src/copy-to-clipboard/CopyToClipboard.tsx b/@navikt/internal/react/src/copy-to-clipboard/CopyToClipboard.tsx index b6bef4624d..c3991ca4e8 100644 --- a/@navikt/internal/react/src/copy-to-clipboard/CopyToClipboard.tsx +++ b/@navikt/internal/react/src/copy-to-clipboard/CopyToClipboard.tsx @@ -10,6 +10,9 @@ import { mergeRefs, } from "@navikt/ds-react"; +/** + * @deprecated Use import { CopyButton } from "@navikt/ds-react" instead + */ export interface CopyToClipboardProps extends Omit { /** @@ -57,6 +60,9 @@ export interface CopyToClipboardProps variant?: "tertiary"; } +/** + * @deprecated Use import { CopyButton } from "@navikt/ds-react" instead + */ export const CopyToClipboard = forwardRef< HTMLButtonElement, CopyToClipboardProps diff --git a/@navikt/internal/react/src/copy-to-clipboard/index.ts b/@navikt/internal/react/src/copy-to-clipboard/index.ts index fee9aa2cc8..806cc3a656 100644 --- a/@navikt/internal/react/src/copy-to-clipboard/index.ts +++ b/@navikt/internal/react/src/copy-to-clipboard/index.ts @@ -1,3 +1,6 @@ +/** + * @deprecated Use import { CopyButton } from "@navikt/ds-react" instead + */ export { type CopyToClipboardProps, default as CopyToClipboard, From ba442070c42fc90963fa821d8e8406fdfd4e1d47 Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 12:21:39 +0200 Subject: [PATCH 18/46] :memo: Oppdatert deprecation-text --- .../internal/react/src/copy-to-clipboard/CopyToClipboard.tsx | 2 +- @navikt/internal/react/src/copy-to-clipboard/index.ts | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/@navikt/internal/react/src/copy-to-clipboard/CopyToClipboard.tsx b/@navikt/internal/react/src/copy-to-clipboard/CopyToClipboard.tsx index c3991ca4e8..16f0c5fb9e 100644 --- a/@navikt/internal/react/src/copy-to-clipboard/CopyToClipboard.tsx +++ b/@navikt/internal/react/src/copy-to-clipboard/CopyToClipboard.tsx @@ -61,7 +61,7 @@ export interface CopyToClipboardProps } /** - * @deprecated Use import { CopyButton } from "@navikt/ds-react" instead + * @deprecated Use instead: import { CopyButton } from "@navikt/ds-react"; */ export const CopyToClipboard = forwardRef< HTMLButtonElement, diff --git a/@navikt/internal/react/src/copy-to-clipboard/index.ts b/@navikt/internal/react/src/copy-to-clipboard/index.ts index 806cc3a656..fee9aa2cc8 100644 --- a/@navikt/internal/react/src/copy-to-clipboard/index.ts +++ b/@navikt/internal/react/src/copy-to-clipboard/index.ts @@ -1,6 +1,3 @@ -/** - * @deprecated Use import { CopyButton } from "@navikt/ds-react" instead - */ export { type CopyToClipboardProps, default as CopyToClipboard, From 2ab6bfc3aaa3f34df2fd0a4a8a580d399b6dc11a Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 12:48:20 +0200 Subject: [PATCH 19/46] :art: CopyButton demoer --- @navikt/core/react/src/index.ts | 3 +- .../pages/eksempler/copybutton/action.tsx | 17 +++++++++++ .../eksempler/copybutton/active-icon.tsx | 24 +++++++++++++++ .../eksempler/copybutton/active-text.tsx | 23 ++++++++++++++ .../pages/eksempler/copybutton/icon.tsx | 20 +++++++++++++ .../pages/eksempler/copybutton/inline.tsx | 26 ++++++++++++++++ .../pages/eksempler/copybutton/neutral.tsx | 17 +++++++++++ .../pages/eksempler/copybutton/small.tsx | 22 ++++++++++++++ .../pages/eksempler/copybutton/text.tsx | 17 +++++++++++ .../pages/eksempler/copybutton/tooltip.tsx | 30 +++++++++++++++++++ 10 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 aksel.nav.no/website/pages/eksempler/copybutton/action.tsx create mode 100644 aksel.nav.no/website/pages/eksempler/copybutton/active-icon.tsx create mode 100644 aksel.nav.no/website/pages/eksempler/copybutton/active-text.tsx create mode 100644 aksel.nav.no/website/pages/eksempler/copybutton/icon.tsx create mode 100644 aksel.nav.no/website/pages/eksempler/copybutton/inline.tsx create mode 100644 aksel.nav.no/website/pages/eksempler/copybutton/neutral.tsx create mode 100644 aksel.nav.no/website/pages/eksempler/copybutton/small.tsx create mode 100644 aksel.nav.no/website/pages/eksempler/copybutton/text.tsx create mode 100644 aksel.nav.no/website/pages/eksempler/copybutton/tooltip.tsx diff --git a/@navikt/core/react/src/index.ts b/@navikt/core/react/src/index.ts index 5247be6035..fcddad6de2 100644 --- a/@navikt/core/react/src/index.ts +++ b/@navikt/core/react/src/index.ts @@ -3,9 +3,10 @@ export * from "./alert"; export * from "./button"; export * from "./chat"; export * from "./chips"; +export * from "./copybutton"; export * from "./date"; -export * from "./form"; export * from "./expansion-card"; +export * from "./form"; export * from "./grid"; export * from "./guide-panel"; export * from "./help-text"; diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/action.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/action.tsx new file mode 100644 index 0000000000..eff4402435 --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/copybutton/action.tsx @@ -0,0 +1,17 @@ +import { CopyButton } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ; +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 1, +}; diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/active-icon.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/active-icon.tsx new file mode 100644 index 0000000000..4c582c2d92 --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/copybutton/active-icon.tsx @@ -0,0 +1,24 @@ +import { LinkBrokenIcon, LinkIcon } from "@navikt/aksel-icons"; +import { CopyButton } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ( + } + activeIcon={} + /> + ); +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 6, +}; diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/active-text.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/active-text.tsx new file mode 100644 index 0000000000..a560fad560 --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/copybutton/active-text.tsx @@ -0,0 +1,23 @@ +import { CopyButton } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ( + + ); +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 4, +}; diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/icon.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/icon.tsx new file mode 100644 index 0000000000..e221c30c97 --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/copybutton/icon.tsx @@ -0,0 +1,20 @@ +import { LinkIcon } from "@navikt/aksel-icons"; +import { CopyButton } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ( + } /> + ); +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 5, +}; diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/inline.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/inline.tsx new file mode 100644 index 0000000000..b55a4b1a18 --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/copybutton/inline.tsx @@ -0,0 +1,26 @@ +import { CopyButton } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ( +
+ {" "} + Adresse: Maguer Gorge 14b, 56430 Tatooine +
+ ); +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 7, + desc: "CopyButton kan settes inline med tekst for å forenkle repetive oppgaver.", +}; diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/neutral.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/neutral.tsx new file mode 100644 index 0000000000..64427b1c6c --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/copybutton/neutral.tsx @@ -0,0 +1,17 @@ +import { CopyButton } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ; +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 0, +}; diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/small.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/small.tsx new file mode 100644 index 0000000000..93f5ee4d96 --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/copybutton/small.tsx @@ -0,0 +1,22 @@ +import { CopyButton } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ( +
+ + +
+ ); +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 2, +}; diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/text.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/text.tsx new file mode 100644 index 0000000000..3352fcb86b --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/copybutton/text.tsx @@ -0,0 +1,17 @@ +import { CopyButton } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ; +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 3, +}; diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/tooltip.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/tooltip.tsx new file mode 100644 index 0000000000..99dd80b958 --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/copybutton/tooltip.tsx @@ -0,0 +1,30 @@ +import { CopyButton, Tooltip } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; +import { useState } from "react"; + +const Example = () => { + const [active, setActive] = useState(false); + + return ( + + setActive(v)} + /> + + ); +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 8, + desc: "Man bruke Tooltip for å gi en mer beskrivende tekst til CopyButton. Dette er mest relevant når CopyButton er plassert utenfor context og med bare ikon.", +}; From bcb574139a3c343d7da2284b59a882ebe953b776 Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 12:52:57 +0200 Subject: [PATCH 20/46] :bug: CSS-versions ble duplisert i version-dir --- @navikt/core/css/config/bundle.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/@navikt/core/css/config/bundle.js b/@navikt/core/css/config/bundle.js index b2d8a4d07e..e9b35d70a1 100644 --- a/@navikt/core/css/config/bundle.js +++ b/@navikt/core/css/config/bundle.js @@ -146,7 +146,10 @@ async function bundleMinified() { } function copyToVersionFolder() { - const files = fastglob.sync("**/*.css", { cwd: `./${rootDir}` }); + const files = fastglob.sync("**/*.css", { + cwd: `./${rootDir}`, + ignore: "**/version/**", + }); for (let file of files) { const css = fs.readFileSync(`${rootDir}/${file}`, { encoding: "utf-8" }); From 7980bd0fa050ba9aa0292f75df00e6ecc4af2cc4 Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 13:56:58 +0200 Subject: [PATCH 21/46] :lipstick: Darkmode --- @navikt/core/css/copybutton.css | 19 ++++++++++++++----- @navikt/core/css/tokens.json | 8 ++++---- .../src/copybutton/copy-button.stories.tsx | 15 +++++---------- .../pages/eksempler/copybutton/tooltip.tsx | 12 ++---------- 4 files changed, 25 insertions(+), 29 deletions(-) diff --git a/@navikt/core/css/copybutton.css b/@navikt/core/css/copybutton.css index d60e1a5828..eaa617cc43 100644 --- a/@navikt/core/css/copybutton.css +++ b/@navikt/core/css/copybutton.css @@ -1,3 +1,12 @@ +[data-theme="dark"] .navds-copybutton, +[data-theme="dark"].navds-copybutton { + --a-text-action: var(--a-blue-300); + --a-surface-hover: rgb(214 231 255 /0.13); + --a-icon-success: rgb(51 170 95 /1); + --a-text-subtle: rgb(231 240 254 /0.69); + --a-text-default: rgb(251 252 254 /0.96); +} + .navds-copybutton { --__ac-copybutton-padding: var(--a-spacing-3) var(--a-spacing-5); @@ -55,8 +64,8 @@ } .navds-copybutton--action:hover { - color: var(--ac-copybutton-action-hover-text, var(--a-text-action-on-action-subtle)); - background-color: var(--ac-copybutton-action-hover-bg, var(--a-surface-action-subtle-hover)); + color: var(--ac-copybutton-action-hover-text, var(--a-text-action)); + background-color: var(--ac-copybutton-action-hover-bg, var(--a-surface-hover)); } .navds-copybutton--action:where(:disabled), @@ -72,13 +81,13 @@ /* Variant/neutral */ .navds-copybutton--neutral { - color: var(--ac-copybutton-neutral-text, var(--a-text-default)); + color: var(--ac-copybutton-neutral-text, var(--a-text-subtle)); background-color: var(--ac-copybutton-neutral-bg, var(--a-surface-transparent)); } .navds-copybutton--neutral:hover { color: var(--ac-copybutton-neutral-hover-text, var(--a-text-default)); - background-color: var(--ac-copybutton-neutral-hover-bg, var(--a-surface-neutral-subtle-hover)); + background-color: var(--ac-copybutton-neutral-hover-bg, var(--a-surface-hover)); } .navds-copybutton--neutral:where(:disabled, .navds-copybutton--disabled), @@ -105,7 +114,7 @@ @keyframes akselCopyButtonAnimation { 0% { - opacity: 0.3; + opacity: 0.4; } 100% { diff --git a/@navikt/core/css/tokens.json b/@navikt/core/css/tokens.json index 4de4ec62c5..3c8071d663 100644 --- a/@navikt/core/css/tokens.json +++ b/@navikt/core/css/tokens.json @@ -108,13 +108,13 @@ "--ac-copybutton-border-radius": "--a-border-radius-medium", "--ac-copybutton-action-text": "--a-text-action", "--ac-copybutton-action-bg": "--a-surface-transparent", - "--ac-copybutton-action-hover-text": "--a-text-action-on-action-subtle", - "--ac-copybutton-action-hover-bg": "--a-surface-action-subtle-hover", + "--ac-copybutton-action-hover-text": "--a-text-action", + "--ac-copybutton-action-hover-bg": "--a-surface-hover", "--ac-copybutton-action-active-text": "--a-icon-success", - "--ac-copybutton-neutral-text": "--a-text-default", + "--ac-copybutton-neutral-text": "--a-text-subtle", "--ac-copybutton-neutral-bg": "--a-surface-transparent", "--ac-copybutton-neutral-hover-text": "--a-text-default", - "--ac-copybutton-neutral-hover-bg": "--a-surface-neutral-subtle-hover", + "--ac-copybutton-neutral-hover-bg": "--a-surface-hover", "--ac-copybutton-neutral-active-text": "--a-text-default", "--ac-copybutton-animation": "akselCopyButtonAnimation 0.4s linear" }, diff --git a/@navikt/core/react/src/copybutton/copy-button.stories.tsx b/@navikt/core/react/src/copybutton/copy-button.stories.tsx index c4547b1224..f551b6cf5e 100644 --- a/@navikt/core/react/src/copybutton/copy-button.stories.tsx +++ b/@navikt/core/react/src/copybutton/copy-button.stories.tsx @@ -1,8 +1,8 @@ import { LinkIcon, ThumbUpIcon } from "@navikt/aksel-icons"; -import React, { useState } from "react"; +import { userEvent, within } from "@storybook/testing-library"; +import React from "react"; import { CopyButton } from "."; import { Tooltip } from "../tooltip"; -import { userEvent, within } from "@storybook/testing-library"; export default { title: "ds-react/CopyButton", @@ -143,16 +143,11 @@ export const InlineDemo = { export const WithTooltip = { render: () => { // eslint-disable-next-line react-hooks/rules-of-hooks - const [active, setActive] = useState(false); + return (
- - setActive(v)} - /> + +
); diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/tooltip.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/tooltip.tsx index 99dd80b958..044f48a62b 100644 --- a/aksel.nav.no/website/pages/eksempler/copybutton/tooltip.tsx +++ b/aksel.nav.no/website/pages/eksempler/copybutton/tooltip.tsx @@ -1,18 +1,10 @@ import { CopyButton, Tooltip } from "@navikt/ds-react"; import { withDsExample } from "components/website-modules/examples/withDsExample"; -import { useState } from "react"; const Example = () => { - const [active, setActive] = useState(false); - return ( - - setActive(v)} - /> + + ); }; From 099f4d3a5d880ef380dcb76352d71d24e210955d Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 14:46:27 +0200 Subject: [PATCH 22/46] :fire: Fjernet ubrukt comment --- @navikt/core/react/src/copybutton/copy-button.stories.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/@navikt/core/react/src/copybutton/copy-button.stories.tsx b/@navikt/core/react/src/copybutton/copy-button.stories.tsx index f551b6cf5e..27274ea2ff 100644 --- a/@navikt/core/react/src/copybutton/copy-button.stories.tsx +++ b/@navikt/core/react/src/copybutton/copy-button.stories.tsx @@ -142,8 +142,6 @@ export const InlineDemo = { export const WithTooltip = { render: () => { - // eslint-disable-next-line react-hooks/rules-of-hooks - return (
From f06260f50d6737e400e49db4a53024a97955d6b2 Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 15:44:18 +0200 Subject: [PATCH 23/46] :art: Aksel-eksempler for CopyButton --- .../src/copybutton/copy-button.stories.tsx | 70 +++++++++++++++++++ .../eksempler/copybutton/breadcrumbs.tsx | 28 ++++++++ .../pages/eksempler/copybutton/info.tsx | 41 +++++++++++ 3 files changed, 139 insertions(+) create mode 100644 aksel.nav.no/website/pages/eksempler/copybutton/breadcrumbs.tsx create mode 100644 aksel.nav.no/website/pages/eksempler/copybutton/info.tsx diff --git a/@navikt/core/react/src/copybutton/copy-button.stories.tsx b/@navikt/core/react/src/copybutton/copy-button.stories.tsx index 27274ea2ff..8b6f473946 100644 --- a/@navikt/core/react/src/copybutton/copy-button.stories.tsx +++ b/@navikt/core/react/src/copybutton/copy-button.stories.tsx @@ -164,3 +164,73 @@ export const Disabled = {
), }; + +const Hr = () => ( + +); + +const Row = ({ children, txt }: any) => ( + <> +
+ {txt} + {children} + +
+
+ +); + +export const Examples = { + render: () => ( +
+
+ Flere statsborgerskap: Norge, Danmark, Finland + / + Gift + / + + 17029645183 + +
+
+
+ Osloveien 99, 0111 Oslo + Bergenveien 99, 2233 Bergen + 4040404040 + nav@naversen.no +
+
+ ), +}; + +export const BreadCrumbs = { + render: () => ( +
+ Flere statsborgerskap: Norge, Danmark, Finland + / + Gift + / + + 17029645183 + +
+ ), +}; diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/breadcrumbs.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/breadcrumbs.tsx new file mode 100644 index 0000000000..b2e54cd8dc --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/copybutton/breadcrumbs.tsx @@ -0,0 +1,28 @@ +import { CopyButton } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ( +
+ Flere statsborgerskap: Norge, Danmark, Finland + / + + 17029645183 + + / + Gift +
+ ); +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 9, + desc: "CopyButton kan eksempelvis inlines i breadcrumbs for kopi av fødselsnummer.", +}; diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/info.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/info.tsx new file mode 100644 index 0000000000..8297a9861c --- /dev/null +++ b/aksel.nav.no/website/pages/eksempler/copybutton/info.tsx @@ -0,0 +1,41 @@ +import { CopyButton } from "@navikt/ds-react"; +import { withDsExample } from "components/website-modules/examples/withDsExample"; + +const Example = () => { + return ( +
+
+ Osloveien 99, 0111 Oslo + Bergenveien 99, 2233 Bergen + 4040404040 + nav@naversen.no +
+ ); +}; + +export default withDsExample(Example); + +/* Storybook story */ +export const Demo = { + render: Example, +}; + +export const args = { + index: 10, + desc: "Ved utlisting av mye relevant innhold, kan CopyButton brukes for å enklere kopiere informasjonen.", +}; + +const Hr = () => ( + +); + +const Row = ({ children, text }: any) => ( + <> +
+ {text} + {children} + +
+
+ +); From b0541fbd60dde4bed6b323f55352226595214764 Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 15:44:41 +0200 Subject: [PATCH 24/46] :fire: Fjernet ubrukte stories fra storybook --- .../src/copybutton/copy-button.stories.tsx | 70 ------------------- 1 file changed, 70 deletions(-) diff --git a/@navikt/core/react/src/copybutton/copy-button.stories.tsx b/@navikt/core/react/src/copybutton/copy-button.stories.tsx index 8b6f473946..27274ea2ff 100644 --- a/@navikt/core/react/src/copybutton/copy-button.stories.tsx +++ b/@navikt/core/react/src/copybutton/copy-button.stories.tsx @@ -164,73 +164,3 @@ export const Disabled = {
), }; - -const Hr = () => ( - -); - -const Row = ({ children, txt }: any) => ( - <> -
- {txt} - {children} - -
-
- -); - -export const Examples = { - render: () => ( -
-
- Flere statsborgerskap: Norge, Danmark, Finland - / - Gift - / - - 17029645183 - -
-
-
- Osloveien 99, 0111 Oslo - Bergenveien 99, 2233 Bergen - 4040404040 - nav@naversen.no -
-
- ), -}; - -export const BreadCrumbs = { - render: () => ( -
- Flere statsborgerskap: Norge, Danmark, Finland - / - Gift - / - - 17029645183 - -
- ), -}; From bd844461a740a186d7283ccce1e23373430c1b50 Mon Sep 17 00:00:00 2001 From: Ken Date: Fri, 12 May 2023 15:53:45 +0200 Subject: [PATCH 25/46] :memo: Changeset --- .changeset/green-trainers-guess.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .changeset/green-trainers-guess.md diff --git a/.changeset/green-trainers-guess.md b/.changeset/green-trainers-guess.md new file mode 100644 index 0000000000..d32921210a --- /dev/null +++ b/.changeset/green-trainers-guess.md @@ -0,0 +1,10 @@ +--- +"@navikt/ds-css": minor +"@navikt/ds-react": minor +"@navikt/ds-react-internal": minor +--- + +:sparkles: Ny komponent ``! + +- Erstatter `` fra `@navikt/ds-react-internal` +- CopyToClipboard er markert som deprecated. Den vil fortsatt fungere, men noen lintere vil kunne på den. From 1b44c5499412e0af8105a0c83639c7cfa626921e Mon Sep 17 00:00:00 2001 From: Ken Date: Mon, 15 May 2023 09:41:28 +0200 Subject: [PATCH 26/46] :memo: Endret clipboardText -> copyText --- .../core/react/src/copybutton/CopyButton.tsx | 8 ++-- .../src/copybutton/copy-button.stories.tsx | 42 +++++++++---------- .../pages/eksempler/copybutton/action.tsx | 2 +- .../eksempler/copybutton/active-icon.tsx | 2 +- .../eksempler/copybutton/active-text.tsx | 6 +-- .../eksempler/copybutton/breadcrumbs.tsx | 2 +- .../pages/eksempler/copybutton/icon.tsx | 2 +- .../pages/eksempler/copybutton/info.tsx | 2 +- .../pages/eksempler/copybutton/inline.tsx | 5 +-- .../pages/eksempler/copybutton/neutral.tsx | 2 +- .../pages/eksempler/copybutton/small.tsx | 4 +- .../pages/eksempler/copybutton/text.tsx | 2 +- .../pages/eksempler/copybutton/tooltip.tsx | 2 +- 13 files changed, 37 insertions(+), 44 deletions(-) diff --git a/@navikt/core/react/src/copybutton/CopyButton.tsx b/@navikt/core/react/src/copybutton/CopyButton.tsx index 78f227738f..4b7cd220b7 100644 --- a/@navikt/core/react/src/copybutton/CopyButton.tsx +++ b/@navikt/core/react/src/copybutton/CopyButton.tsx @@ -21,9 +21,9 @@ export interface CopyButtonProps */ variant?: "action" | "neutral"; /** - * Text to copy to clipboard + * Text to copy to clipboard */ - clipboardText: string; + copyText: string; /** * Optional text in button */ @@ -58,7 +58,7 @@ export const CopyButton = forwardRef( ( { className, - clipboardText, + copyText, text, activeText = "Kopiert!", variant = "neutral", @@ -85,7 +85,7 @@ export const CopyButton = forwardRef( event: React.MouseEvent ) => { timeoutRef.current && clearTimeout(timeoutRef.current); - copy(clipboardText); + copy(copyText); setActive(true); rest.onClick?.(event); onActiveChange?.(true); diff --git a/@navikt/core/react/src/copybutton/copy-button.stories.tsx b/@navikt/core/react/src/copybutton/copy-button.stories.tsx index 27274ea2ff..77dce357c1 100644 --- a/@navikt/core/react/src/copybutton/copy-button.stories.tsx +++ b/@navikt/core/react/src/copybutton/copy-button.stories.tsx @@ -26,7 +26,7 @@ export const Default = { args: { size: "medium", duration: 2000, - clipboardText: "3.14", + copyText: "3.14", text: "", activeText: "", }, @@ -35,7 +35,7 @@ export const Default = { export const Interaction = { render: () => ( (
- - + +
), }; @@ -63,23 +63,23 @@ export const Sizes = { render: () => (
- - - - + + + +
- - + + @@ -93,14 +93,14 @@ export const Texts = {
} activeIcon={} />
} activeIcon={} @@ -135,7 +135,7 @@ export const Icons = { export const InlineDemo = { render: () => (
- Kopier dette feltet + Kopier dette feltet
), }; @@ -145,7 +145,7 @@ export const WithTooltip = { return (
- +
); @@ -153,14 +153,14 @@ export const WithTooltip = { }; export const Duration = { - render: () => , + render: () => , }; export const Disabled = { render: () => (
- - + +
), }; diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/action.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/action.tsx index eff4402435..e21072ce89 100644 --- a/aksel.nav.no/website/pages/eksempler/copybutton/action.tsx +++ b/aksel.nav.no/website/pages/eksempler/copybutton/action.tsx @@ -2,7 +2,7 @@ import { CopyButton } from "@navikt/ds-react"; import { withDsExample } from "components/website-modules/examples/withDsExample"; const Example = () => { - return ; + return ; }; export default withDsExample(Example); diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/active-icon.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/active-icon.tsx index 4c582c2d92..6420ab819b 100644 --- a/aksel.nav.no/website/pages/eksempler/copybutton/active-icon.tsx +++ b/aksel.nav.no/website/pages/eksempler/copybutton/active-icon.tsx @@ -5,7 +5,7 @@ import { withDsExample } from "components/website-modules/examples/withDsExample const Example = () => { return ( } activeIcon={} /> diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/active-text.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/active-text.tsx index a560fad560..ec110c2591 100644 --- a/aksel.nav.no/website/pages/eksempler/copybutton/active-text.tsx +++ b/aksel.nav.no/website/pages/eksempler/copybutton/active-text.tsx @@ -3,11 +3,7 @@ import { withDsExample } from "components/website-modules/examples/withDsExample const Example = () => { return ( - + ); }; diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/breadcrumbs.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/breadcrumbs.tsx index b2e54cd8dc..002b2abc57 100644 --- a/aksel.nav.no/website/pages/eksempler/copybutton/breadcrumbs.tsx +++ b/aksel.nav.no/website/pages/eksempler/copybutton/breadcrumbs.tsx @@ -7,7 +7,7 @@ const Example = () => { Flere statsborgerskap: Norge, Danmark, Finland / - 17029645183 + 17029645183 / Gift diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/icon.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/icon.tsx index e221c30c97..ef710fa576 100644 --- a/aksel.nav.no/website/pages/eksempler/copybutton/icon.tsx +++ b/aksel.nav.no/website/pages/eksempler/copybutton/icon.tsx @@ -4,7 +4,7 @@ import { withDsExample } from "components/website-modules/examples/withDsExample const Example = () => { return ( - } /> + } /> ); }; diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/info.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/info.tsx index 8297a9861c..f2f87f1792 100644 --- a/aksel.nav.no/website/pages/eksempler/copybutton/info.tsx +++ b/aksel.nav.no/website/pages/eksempler/copybutton/info.tsx @@ -34,7 +34,7 @@ const Row = ({ children, text }: any) => (
{text} {children} - +

diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/inline.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/inline.tsx index b55a4b1a18..3dc2884bae 100644 --- a/aksel.nav.no/website/pages/eksempler/copybutton/inline.tsx +++ b/aksel.nav.no/website/pages/eksempler/copybutton/inline.tsx @@ -4,10 +4,7 @@ import { withDsExample } from "components/website-modules/examples/withDsExample const Example = () => { return (
- {" "} + {" "} Adresse: Maguer Gorge 14b, 56430 Tatooine
); diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/neutral.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/neutral.tsx index 64427b1c6c..58e2d044bc 100644 --- a/aksel.nav.no/website/pages/eksempler/copybutton/neutral.tsx +++ b/aksel.nav.no/website/pages/eksempler/copybutton/neutral.tsx @@ -2,7 +2,7 @@ import { CopyButton } from "@navikt/ds-react"; import { withDsExample } from "components/website-modules/examples/withDsExample"; const Example = () => { - return ; + return ; }; export default withDsExample(Example); diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/small.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/small.tsx index 93f5ee4d96..5cf56f4dc9 100644 --- a/aksel.nav.no/website/pages/eksempler/copybutton/small.tsx +++ b/aksel.nav.no/website/pages/eksempler/copybutton/small.tsx @@ -4,8 +4,8 @@ import { withDsExample } from "components/website-modules/examples/withDsExample const Example = () => { return (
- - + +
); }; diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/text.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/text.tsx index 3352fcb86b..8581087ab8 100644 --- a/aksel.nav.no/website/pages/eksempler/copybutton/text.tsx +++ b/aksel.nav.no/website/pages/eksempler/copybutton/text.tsx @@ -2,7 +2,7 @@ import { CopyButton } from "@navikt/ds-react"; import { withDsExample } from "components/website-modules/examples/withDsExample"; const Example = () => { - return ; + return ; }; export default withDsExample(Example); diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/tooltip.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/tooltip.tsx index 044f48a62b..ab0eb5b1fc 100644 --- a/aksel.nav.no/website/pages/eksempler/copybutton/tooltip.tsx +++ b/aksel.nav.no/website/pages/eksempler/copybutton/tooltip.tsx @@ -4,7 +4,7 @@ import { withDsExample } from "components/website-modules/examples/withDsExample const Example = () => { return ( - + ); }; From 5af5ca29c2f33a248575d4bb68cde54957c0f512 Mon Sep 17 00:00:00 2001 From: Ken Date: Mon, 15 May 2023 12:58:30 +0200 Subject: [PATCH 27/46] :memo: Skrivefeil --- aksel.nav.no/website/pages/eksempler/copybutton/tooltip.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/tooltip.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/tooltip.tsx index ab0eb5b1fc..a4ff4a9c8a 100644 --- a/aksel.nav.no/website/pages/eksempler/copybutton/tooltip.tsx +++ b/aksel.nav.no/website/pages/eksempler/copybutton/tooltip.tsx @@ -18,5 +18,5 @@ export const Demo = { export const args = { index: 8, - desc: "Man bruke Tooltip for å gi en mer beskrivende tekst til CopyButton. Dette er mest relevant når CopyButton er plassert utenfor context og med bare ikon.", + desc: "Man kan bruke Tooltip for å gi en mer beskrivende tekst til CopyButton. Dette er mest relevant når CopyButton er plassert utenfor context og med bare ikon.", }; From cc0deaf247ba9fa2545d3934457732fcdbdf2ccd Mon Sep 17 00:00:00 2001 From: Ken Date: Mon, 15 May 2023 12:59:42 +0200 Subject: [PATCH 28/46] :memo: rename breadcrumbs-demo --- .../copybutton/{breadcrumbs.tsx => breadcrumbs-demo.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename aksel.nav.no/website/pages/eksempler/copybutton/{breadcrumbs.tsx => breadcrumbs-demo.tsx} (100%) diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/breadcrumbs.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/breadcrumbs-demo.tsx similarity index 100% rename from aksel.nav.no/website/pages/eksempler/copybutton/breadcrumbs.tsx rename to aksel.nav.no/website/pages/eksempler/copybutton/breadcrumbs-demo.tsx From 5890336c3ba90014a8e0cac257ddc9cd5786113b Mon Sep 17 00:00:00 2001 From: Ken Date: Mon, 15 May 2023 13:04:23 +0200 Subject: [PATCH 29/46] :memo: rename breadcrumbs-demo --- .../copybutton/{breadcrumbs-demo.tsx => used-in-breadcrumbs.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename aksel.nav.no/website/pages/eksempler/copybutton/{breadcrumbs-demo.tsx => used-in-breadcrumbs.tsx} (100%) diff --git a/aksel.nav.no/website/pages/eksempler/copybutton/breadcrumbs-demo.tsx b/aksel.nav.no/website/pages/eksempler/copybutton/used-in-breadcrumbs.tsx similarity index 100% rename from aksel.nav.no/website/pages/eksempler/copybutton/breadcrumbs-demo.tsx rename to aksel.nav.no/website/pages/eksempler/copybutton/used-in-breadcrumbs.tsx From 3094d42991f953dcaca354c34baa725d3ef3fb2e Mon Sep 17 00:00:00 2001 From: Ken Date: Mon, 15 May 2023 13:24:19 +0200 Subject: [PATCH 30/46] :fire: Fjernet avansert aria-logikk, la inn title-props --- .../core/react/src/copybutton/CopyButton.tsx | 21 ++++++++++++------- .../src/copybutton/copy-button.stories.tsx | 10 +++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/@navikt/core/react/src/copybutton/CopyButton.tsx b/@navikt/core/react/src/copybutton/CopyButton.tsx index 4b7cd220b7..481c32cf50 100644 --- a/@navikt/core/react/src/copybutton/CopyButton.tsx +++ b/@navikt/core/react/src/copybutton/CopyButton.tsx @@ -52,6 +52,16 @@ export interface CopyButtonProps * @default 2000 */ activeDuration?: number; + /** + * * 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) + * @default 'Kopiert' + */ + activeTitle?: string; } export const CopyButton = forwardRef( @@ -67,12 +77,13 @@ export const CopyButton = forwardRef( icon, activeIcon, activeDuration = 2000, + title = "Kopier", + activeTitle = "Kopiert", ...rest }, ref ) => { const [active, setActive] = useState(false); - const [activated, setActivated] = useState(false); const timeoutRef = useRef(); useEffect(() => { @@ -89,10 +100,8 @@ export const CopyButton = forwardRef( setActive(true); rest.onClick?.(event); onActiveChange?.(true); - setActivated(false); timeoutRef.current = window.setTimeout(() => { - setActivated(true); setActive(false); onActiveChange?.(false); }, activeDuration); @@ -113,8 +122,6 @@ export const CopyButton = forwardRef( } )} onClick={handleClick} - aria-label={activated ? activeText : undefined} - onBlur={() => setActivated(false)} > {active ? ( @@ -122,7 +129,7 @@ export const CopyButton = forwardRef( {activeIcon ?? ( )} @@ -131,7 +138,7 @@ export const CopyButton = forwardRef( {icon ?? ( )} diff --git a/@navikt/core/react/src/copybutton/copy-button.stories.tsx b/@navikt/core/react/src/copybutton/copy-button.stories.tsx index 77dce357c1..8654ec1f87 100644 --- a/@navikt/core/react/src/copybutton/copy-button.stories.tsx +++ b/@navikt/core/react/src/copybutton/copy-button.stories.tsx @@ -53,7 +53,17 @@ export const Interaction = { export const Variants = { render: () => (
+

+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Quasi quo, a + optio veniam impedit totam possimus culpa ex nemo fuga, beatae, ipsa + dolorum ab ipsam perspiciatis sunt deserunt cum nulla! +

+

+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Quasi quo, a + optio veniam impedit totam possimus culpa ex nemo fuga, beatae, ipsa + dolorum ab ipsam perspiciatis sunt deserunt cum nulla! +

), From 54f9735caac27f08b19bf191ced3969ff26973ee Mon Sep 17 00:00:00 2001 From: Ken Date: Mon, 15 May 2023 13:28:08 +0200 Subject: [PATCH 31/46] :fire: Fikset story --- .../core/react/src/copybutton/copy-button.stories.tsx | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/@navikt/core/react/src/copybutton/copy-button.stories.tsx b/@navikt/core/react/src/copybutton/copy-button.stories.tsx index 8654ec1f87..2acdb4dce1 100644 --- a/@navikt/core/react/src/copybutton/copy-button.stories.tsx +++ b/@navikt/core/react/src/copybutton/copy-button.stories.tsx @@ -53,17 +53,8 @@ export const Interaction = { export const Variants = { render: () => (
-

- Lorem ipsum dolor sit amet consectetur adipisicing elit. Quasi quo, a - optio veniam impedit totam possimus culpa ex nemo fuga, beatae, ipsa - dolorum ab ipsam perspiciatis sunt deserunt cum nulla! -

-

- Lorem ipsum dolor sit amet consectetur adipisicing elit. Quasi quo, a - optio veniam impedit totam possimus culpa ex nemo fuga, beatae, ipsa - dolorum ab ipsam perspiciatis sunt deserunt cum nulla! -

+
), From 77dfb31e427a0edf47be5688b8051085127cb17d Mon Sep 17 00:00:00 2001 From: Ken <26967723+KenAJoh@users.noreply.github.com> Date: Mon, 15 May 2023 13:28:39 +0200 Subject: [PATCH 32/46] CopyButton-codemods (#1985) --- @navikt/aksel/src/codemod/migrations.ts | 23 +++- @navikt/aksel/src/codemod/run-codeshift.ts | 5 +- .../v3.0.0/copybutton/copybutton.ts | 89 ++++++++++++++++ .../v3.0.0/copybutton/tests/alias.input.js | 6 ++ .../v3.0.0/copybutton/tests/alias.output.js | 6 ++ .../v3.0.0/copybutton/tests/children.input.js | 16 +++ .../copybutton/tests/children.output.js | 10 ++ .../v3.0.0/copybutton/tests/cleanup.input.js | 6 ++ .../v3.0.0/copybutton/tests/cleanup.output.js | 6 ++ .../v3.0.0/copybutton/tests/complete.input.js | 16 +++ .../copybutton/tests/complete.output.js | 6 ++ .../copybutton/tests/copybutton.test.ts | 12 +++ .../copybutton/tests/idempotent.input.js | 6 ++ .../copybutton/tests/idempotent.output.js | 6 ++ .../v3.0.0/copybutton/tests/import.input.js | 7 ++ .../v3.0.0/copybutton/tests/import.output.js | 7 ++ .../src/codemod/utils/moveAndRenameImport.ts | 100 ++++++++++++++++++ .../aksel/src/codemod/utils/removeProps.ts | 25 +++++ @navikt/core/css/button.css | 2 +- .../core/react/src/copybutton/CopyButton.tsx | 2 +- aksel.nav.no/package.json | 1 + yarn.lock | 3 +- 22 files changed, 355 insertions(+), 5 deletions(-) create mode 100644 @navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/copybutton.ts create mode 100644 @navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/alias.input.js create mode 100644 @navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/alias.output.js create mode 100644 @navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/children.input.js create mode 100644 @navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/children.output.js create mode 100644 @navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/cleanup.input.js create mode 100644 @navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/cleanup.output.js create mode 100644 @navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/complete.input.js create mode 100644 @navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/complete.output.js create mode 100644 @navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/copybutton.test.ts create mode 100644 @navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/idempotent.input.js create mode 100644 @navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/idempotent.output.js create mode 100644 @navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/import.input.js create mode 100644 @navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/import.output.js create mode 100644 @navikt/aksel/src/codemod/utils/moveAndRenameImport.ts create mode 100644 @navikt/aksel/src/codemod/utils/removeProps.ts diff --git a/@navikt/aksel/src/codemod/migrations.ts b/@navikt/aksel/src/codemod/migrations.ts index 5c8be8a7c1..e220e56bf5 100644 --- a/@navikt/aksel/src/codemod/migrations.ts +++ b/@navikt/aksel/src/codemod/migrations.ts @@ -1,7 +1,12 @@ import chalk from "chalk"; export const migrations: { - [key: string]: { description: string; value: string; path: string }[]; + [key: string]: { + description: string; + value: string; + path: string; + warning?: string; + }[]; } = { "1.0.0": [ { @@ -48,6 +53,16 @@ export const migrations: { path: "v2.0.0/update-less-tokens/update-less-tokens", }, ], + "v3.0.0": [ + { + description: + "Replaces deprecated with ", + value: "v3-copybutton", + path: "v3.0.0/copybutton/copybutton", + warning: + "Remember to clean css-import from '@navikt/ds-css-internal' if no longer needed\nIf non-text was used as children, or different locales were handled, you need to manually fix this", + }, + ], }; export function getMigrationPath(str: string) { @@ -56,6 +71,12 @@ export function getMigrationPath(str: string) { .find((x) => x.value === str)?.path; } +export function getWarning(str: string) { + return Object.values(migrations) + .reduce((acc, val) => [...val, ...acc], []) + .find((x) => x.value === str)?.warning; +} + export function getMigrationNames() { return Object.values(migrations).reduce( (acc, val) => [...val.map((x) => x.value), ...acc], diff --git a/@navikt/aksel/src/codemod/run-codeshift.ts b/@navikt/aksel/src/codemod/run-codeshift.ts index 74e61e0e10..db8354c20b 100644 --- a/@navikt/aksel/src/codemod/run-codeshift.ts +++ b/@navikt/aksel/src/codemod/run-codeshift.ts @@ -2,7 +2,7 @@ import { Command } from "commander"; import fg from "fast-glob"; import * as jscodeshift from "jscodeshift/src/Runner"; import path from "path"; -import { getMigrationPath } from "./migrations"; +import { getMigrationPath, getWarning } from "./migrations"; import chalk from "chalk"; const ignoreNodeModules = [ @@ -32,6 +32,9 @@ export async function runCodeshift( options?.glob && console.log(`Using glob: ${chalk.green(options.glob)}\n`); + const warning = getWarning(input); + warning && console.log(`\n${chalk.yellow(warning)}\n`); + try { await jscodeshift.run(codemodPath, filepaths, { babel: true, diff --git a/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/copybutton.ts b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/copybutton.ts new file mode 100644 index 0000000000..e3685b7954 --- /dev/null +++ b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/copybutton.ts @@ -0,0 +1,89 @@ +import chalk from "chalk"; +import moveAndRenameImport from "../../../utils/moveAndRenameImport"; +import removePropsFromComponent from "../../../utils/removeProps"; + +/** + * @param {import('jscodeshift').FileInfo} file + * @param {import('jscodeshift').API} api + */ +export default function transformer(file, api, options, ...rest) { + const j = api.jscodeshift; + + let root: any; + try { + root = j(file.source); + } catch { + return file.source; + } + + const toName = "CopyButton"; + const localName = moveAndRenameImport(j, root, { + fromImport: "@navikt/ds-react-internal", + toImport: "@navikt/ds-react", + fromName: "CopyToClipboard", + toName, + }); + + if (localName === null) { + return root.toSource(options.printOptions); + } + + /* Finds and replaces import from CopyToClipboard -> CopyButton */ + + if (root.findJSXElements(localName)) { + removePropsFromComponent(j, root, localName, [ + "popoverText", + "popoverPlacement", + "iconPosition", + "variant", + ]); + + const component = root.findJSXElements(localName); + + component.forEach((node) => { + const children = node.node.children; + let flagged = false; + if ( + children.length > 0 && + !node.node.openingElement.attributes.some( + (attr) => attr.name.name === "text" + ) + ) { + if (children.length === 1 && children[0].type === "JSXText") { + node.node.openingElement.attributes.push( + j.jsxAttribute( + j.jsxIdentifier("text"), + j.literal(children[0].value.trim()) + ) + ); + } else { + flagged = true; + console.log( + chalk.yellow( + `\n\nWarning: Detected advanced children-type!\nCodemod can't convert into "text" prop so you will need to update this manually.` + ) + ); + } + } + + if (!flagged) { + node.node.children = []; + node.node.openingElement.selfClosing = true; + node.node.closingElement = null; + } + }); + + const compRoot = root.find(j.JSXElement, { + openingElement: { name: { name: localName } }, + }); + + compRoot.forEach((x) => { + x.node.openingElement.name.name = "CopyButton"; + if (x.node.children.length > 0) { + x.node.closingElement.name.name = "CopyButton"; + } + }); + } + + return root.toSource(options.printOptions); +} diff --git a/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/alias.input.js b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/alias.input.js new file mode 100644 index 0000000000..a839f877f8 --- /dev/null +++ b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/alias.input.js @@ -0,0 +1,6 @@ +import { CopyToClipboard as DsCpyButton } from "@navikt/ds-react-internal"; + +/* eslint-disable react/jsx-no-undef */ +export const Page = () => { + return ; +}; diff --git a/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/alias.output.js b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/alias.output.js new file mode 100644 index 0000000000..c3028b4532 --- /dev/null +++ b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/alias.output.js @@ -0,0 +1,6 @@ +import { CopyButton } from "@navikt/ds-react"; + +/* eslint-disable react/jsx-no-undef */ +export const Page = () => { + return ; +}; diff --git a/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/children.input.js b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/children.input.js new file mode 100644 index 0000000000..61b90bb748 --- /dev/null +++ b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/children.input.js @@ -0,0 +1,16 @@ +import { CopyToClipboard } from "@navikt/ds-react-internal"; + +/* eslint-disable react/jsx-no-undef */ +export const Page = () => { + return ( + + {text} + + ); +}; diff --git a/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/children.output.js b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/children.output.js new file mode 100644 index 0000000000..7121a40f03 --- /dev/null +++ b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/children.output.js @@ -0,0 +1,10 @@ +import { CopyButton } from "@navikt/ds-react"; + +/* eslint-disable react/jsx-no-undef */ +export const Page = () => { + return ( + + {text} + + ); +}; diff --git a/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/cleanup.input.js b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/cleanup.input.js new file mode 100644 index 0000000000..c8fcf7553d --- /dev/null +++ b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/cleanup.input.js @@ -0,0 +1,6 @@ +import { CopyToClipboard } from "@navikt/ds-react-internal"; + +/* eslint-disable react/jsx-no-undef */ +export const Page = () => { + return ; +}; diff --git a/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/cleanup.output.js b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/cleanup.output.js new file mode 100644 index 0000000000..c3028b4532 --- /dev/null +++ b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/cleanup.output.js @@ -0,0 +1,6 @@ +import { CopyButton } from "@navikt/ds-react"; + +/* eslint-disable react/jsx-no-undef */ +export const Page = () => { + return ; +}; diff --git a/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/complete.input.js b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/complete.input.js new file mode 100644 index 0000000000..63d86b2fbf --- /dev/null +++ b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/complete.input.js @@ -0,0 +1,16 @@ +import { CopyToClipboard } from "@navikt/ds-react-internal"; + +/* eslint-disable react/jsx-no-undef */ +export const Page = () => { + return ( + + text + + ); +}; diff --git a/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/complete.output.js b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/complete.output.js new file mode 100644 index 0000000000..c77d6d11b6 --- /dev/null +++ b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/complete.output.js @@ -0,0 +1,6 @@ +import { CopyButton } from "@navikt/ds-react"; + +/* eslint-disable react/jsx-no-undef */ +export const Page = () => { + return ; +}; diff --git a/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/copybutton.test.ts b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/copybutton.test.ts new file mode 100644 index 0000000000..e1d9687ce9 --- /dev/null +++ b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/copybutton.test.ts @@ -0,0 +1,12 @@ +import { check } from "../../../../utils/check"; + +const migration = "copybutton"; +const fixtures = ["complete", "idempotent", "alias", "cleanup", "import"]; + +for (const fixture of fixtures) { + check(__dirname, { + fixture, + migration, + extension: "js", + }); +} diff --git a/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/idempotent.input.js b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/idempotent.input.js new file mode 100644 index 0000000000..cc7df5aa8d --- /dev/null +++ b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/idempotent.input.js @@ -0,0 +1,6 @@ +import { CopyButton } from "@navikt/ds-react"; + +/* eslint-disable react/jsx-no-undef */ +export const Page = () => { + return ; +}; diff --git a/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/idempotent.output.js b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/idempotent.output.js new file mode 100644 index 0000000000..cc7df5aa8d --- /dev/null +++ b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/idempotent.output.js @@ -0,0 +1,6 @@ +import { CopyButton } from "@navikt/ds-react"; + +/* eslint-disable react/jsx-no-undef */ +export const Page = () => { + return ; +}; diff --git a/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/import.input.js b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/import.input.js new file mode 100644 index 0000000000..3e84f004c9 --- /dev/null +++ b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/import.input.js @@ -0,0 +1,7 @@ +import { CopyToClipboard, Dropdown } from "@navikt/ds-react-internal"; +import { Button } from "@navikt/ds-react"; + +/* eslint-disable react/jsx-no-undef */ +export const Page = () => { + return ; +}; diff --git a/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/import.output.js b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/import.output.js new file mode 100644 index 0000000000..0c27f5b312 --- /dev/null +++ b/@navikt/aksel/src/codemod/transforms/v3.0.0/copybutton/tests/import.output.js @@ -0,0 +1,7 @@ +import { Dropdown } from "@navikt/ds-react-internal"; +import { Button, CopyButton } from "@navikt/ds-react"; + +/* eslint-disable react/jsx-no-undef */ +export const Page = () => { + return ; +}; diff --git a/@navikt/aksel/src/codemod/utils/moveAndRenameImport.ts b/@navikt/aksel/src/codemod/utils/moveAndRenameImport.ts new file mode 100644 index 0000000000..4ae3c7e35e --- /dev/null +++ b/@navikt/aksel/src/codemod/utils/moveAndRenameImport.ts @@ -0,0 +1,100 @@ +import core, { Collection } from "jscodeshift"; + +export default function moveAndRenameImport( + j: core.JSCodeshift, + root: Collection, + { + fromImport, + toImport, + fromName, + toName, + }: { fromImport: string; toImport: string; fromName: string; toName: string } +) { + const existingFromImport = root.find(j.ImportDeclaration, { + source: { + value: fromImport, + }, + }); + + if (!existingFromImport.length) { + return null; + } + + let localname = fromName; + const existingFromImportSpecifier = existingFromImport?.find( + j.ImportSpecifier, + (node) => { + if (node.imported.name === fromName) { + localname = node.local.name; + } + return node.imported.name === fromName; + } + ); + + if (!existingFromImport.length || !existingFromImportSpecifier?.length) { + return null; + } + + if (existingFromImportSpecifier?.length > 0) { + existingFromImportSpecifier.remove(); + } + + if ( + !existingFromImport.get("specifiers").value?.length || + existingFromImport.get("specifiers").value?.length === 0 + ) { + existingFromImport.remove(); + } + + const existingImport = root.find(j.ImportDeclaration, { + source: { + value: toImport, + }, + }); + + const existingImportSpecifier = existingImport.find(j.ImportSpecifier, { + imported: { + name: toName, + }, + }); + + if (existingImportSpecifier.length <= 0) { + const newImportSpecifier = j.importSpecifier(j.identifier(toName)); + + if (existingImport.length > 0) { + existingImport.get("specifiers").push(newImportSpecifier); + } else { + const newImport = j.importDeclaration( + [newImportSpecifier], + j.stringLiteral(toImport) + ); + + const lastImport = root.find(j.ImportDeclaration).at(-1); + + if (lastImport.length > 0) { + lastImport.insertAfter(newImport); + } else { + root.get().node.program.body.unshift(newImport); + } + } + } + + return localname; +} + +/* root + .find(j.ImportDeclaration) + .filter((path) => path.node.source.value === "@navikt/ds-react-internal") + .forEach((imp) => { + imp.value.specifiers.forEach((x) => { + if (x.imported.name === "CopyToClipboard") { + if (x.local.name !== x.imported.name) { + localName = x.local.name; + x.imported.name = "CopyButton"; + } else { + x.imported.name = "CopyButton"; + x.local.name = "CopyButton"; + } + } + }); + }); */ diff --git a/@navikt/aksel/src/codemod/utils/removeProps.ts b/@navikt/aksel/src/codemod/utils/removeProps.ts new file mode 100644 index 0000000000..a7714b070b --- /dev/null +++ b/@navikt/aksel/src/codemod/utils/removeProps.ts @@ -0,0 +1,25 @@ +import core, { Collection } from "jscodeshift"; + +export default function removePropsFromComponent( + j: core.JSCodeshift, + root: Collection, + componentName: string, + propsToRemove: string[] +) { + const component = root.findJSXElements(componentName); + + component.forEach((node) => { + const attributes = node.node.openingElement.attributes; + + for (let i = attributes.length - 1; i >= 0; i--) { + const attribute = attributes[i]; + + if ( + attribute.type === "JSXAttribute" && + propsToRemove.includes(attribute.name.name.toString()) + ) { + attributes.splice(i, 1); + } + } + }); +} diff --git a/@navikt/core/css/button.css b/@navikt/core/css/button.css index 36c9d3694b..a10850bb6e 100644 --- a/@navikt/core/css/button.css +++ b/@navikt/core/css/button.css @@ -76,7 +76,7 @@ } .navds-button__icon { - --ac-button-icon-margin: -4px; + --__ac-button-icon-margin: var(--ac-button-icon-margin, -4px); font-size: 1.5rem; display: flex; diff --git a/@navikt/core/react/src/copybutton/CopyButton.tsx b/@navikt/core/react/src/copybutton/CopyButton.tsx index 481c32cf50..f749ebb3f2 100644 --- a/@navikt/core/react/src/copybutton/CopyButton.tsx +++ b/@navikt/core/react/src/copybutton/CopyButton.tsx @@ -11,7 +11,7 @@ import copy from "../util/copy"; import Label from "../typography/Label"; export interface CopyButtonProps - extends ButtonHTMLAttributes { + extends Omit, "children"> { /** * @default "medium" */ diff --git a/aksel.nav.no/package.json b/aksel.nav.no/package.json index 973c7f5be3..083b630413 100644 --- a/aksel.nav.no/package.json +++ b/aksel.nav.no/package.json @@ -15,6 +15,7 @@ "website" ], "dependencies": { + "@navikt/aksel": "*", "@navikt/aksel-icons": "^3.1.3", "@navikt/ds-codemod": "^3.1.3", "@navikt/ds-css": "^3.1.3", diff --git a/yarn.lock b/yarn.lock index 8ddf84a0da..d51f603ae0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3921,7 +3921,7 @@ __metadata: languageName: unknown linkType: soft -"@navikt/aksel@workspace:@navikt/aksel": +"@navikt/aksel@*, @navikt/aksel@workspace:@navikt/aksel": version: 0.0.0-use.local resolution: "@navikt/aksel@workspace:@navikt/aksel" dependencies: @@ -8297,6 +8297,7 @@ __metadata: version: 0.0.0-use.local resolution: "aksel.nav.no@workspace:aksel.nav.no" dependencies: + "@navikt/aksel": "*" "@navikt/aksel-icons": ^3.1.3 "@navikt/ds-codemod": ^3.1.3 "@navikt/ds-css": ^3.1.3 From 8a97099fa1a9e5371d37683a8bc556d948ef780e Mon Sep 17 00:00:00 2001 From: Ken Date: Mon, 15 May 2023 13:35:50 +0200 Subject: [PATCH 33/46] :memo: codemod docs --- @navikt/aksel/README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/@navikt/aksel/README.md b/@navikt/aksel/README.md index 421bdfc9be..079695d87a 100644 --- a/@navikt/aksel/README.md +++ b/@navikt/aksel/README.md @@ -22,6 +22,39 @@ To get started: npx @navikt/aksel codemod --help ``` +### v3 + +There is no general codemods for migrating from v2 -> v3. + +#### CopyButton + +`npx @navikt/aksel codemod v3-copybutton ...` + +`` has been renamed to `` and refactored. + +- Namechange +- removed props `popoverText`, `iconPosition`, `popoverPlacement` +- changed variants +- refactored CSS and React-code. ⚠️ Overwritten CSS will not be migrated! + +```diff +-import { CopyToClipboard } from "@navikt/ds-react-internal"; ++import { CopyButton } from "@navikt/ds-react"; + +- +- text ++ +- + +``` + ### v1 -> v2 [Documentation](https://aksel.nav.no/grunnleggende/kode/migrering#h76f47744d112) From e0005b5d133e6955360e4cfe92e5496f4a3cf256 Mon Sep 17 00:00:00 2001 From: Ken Date: Tue, 16 May 2023 11:24:26 +0200 Subject: [PATCH 34/46] =?UTF-8?q?:wheelchair:=20aria-polite=20for=20bedre?= =?UTF-8?q?=20jaws-st=C3=B8tte?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- @navikt/core/react/src/copybutton/CopyButton.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/@navikt/core/react/src/copybutton/CopyButton.tsx b/@navikt/core/react/src/copybutton/CopyButton.tsx index f749ebb3f2..7fb6d04d08 100644 --- a/@navikt/core/react/src/copybutton/CopyButton.tsx +++ b/@navikt/core/react/src/copybutton/CopyButton.tsx @@ -98,8 +98,8 @@ export const CopyButton = forwardRef( timeoutRef.current && clearTimeout(timeoutRef.current); copy(copyText); setActive(true); - rest.onClick?.(event); onActiveChange?.(true); + rest.onClick?.(event); timeoutRef.current = window.setTimeout(() => { setActive(false); @@ -111,6 +111,7 @@ export const CopyButton = forwardRef( - ); - } -); - -export default CopyButton; diff --git a/aksel.nav.no/website/components/sanity-modules/code/Snippet.tsx b/aksel.nav.no/website/components/sanity-modules/code/Snippet.tsx index bc4244ced5..ffd3dae6aa 100644 --- a/aksel.nav.no/website/components/sanity-modules/code/Snippet.tsx +++ b/aksel.nav.no/website/components/sanity-modules/code/Snippet.tsx @@ -2,8 +2,9 @@ import { withErrorBoundary } from "@/error-boundary"; import cl from "clsx"; import Highlight, { defaultProps, Language } from "prism-react-renderer"; import React from "react"; -import CopyButton from "./CopyButton"; import { CodeSnippetT } from "@/types"; +import { CopyButton } from "@navikt/ds-react"; +import style from "./index.module.css"; const CodeSnippet = ({ node: { code }, @@ -43,7 +44,11 @@ const CodeSnippet = ({ )} {...props} > - + {({ tokens, getLineProps, getTokenProps }) => ( -
+            
               {tokens.map((line, i) => (
                 
Date: Tue, 16 May 2023 12:50:39 +0200 Subject: [PATCH 45/46] :art: useclient-directive --- @navikt/core/react/src/copybutton/CopyButton.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/@navikt/core/react/src/copybutton/CopyButton.tsx b/@navikt/core/react/src/copybutton/CopyButton.tsx index 2a9cfcca05..5f691a5899 100644 --- a/@navikt/core/react/src/copybutton/CopyButton.tsx +++ b/@navikt/core/react/src/copybutton/CopyButton.tsx @@ -1,3 +1,4 @@ +"use client"; import { CheckmarkIcon, FilesIcon } from "@navikt/aksel-icons"; import cl from "clsx"; import React, { From 2b4a425c6d4307a50e0694a853d1834099f311ca Mon Sep 17 00:00:00 2001 From: Ken Date: Tue, 16 May 2023 12:55:27 +0200 Subject: [PATCH 46/46] :arrow_up: Yarn lock --- yarn.lock | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index d51f603ae0..8ddf84a0da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3921,7 +3921,7 @@ __metadata: languageName: unknown linkType: soft -"@navikt/aksel@*, @navikt/aksel@workspace:@navikt/aksel": +"@navikt/aksel@workspace:@navikt/aksel": version: 0.0.0-use.local resolution: "@navikt/aksel@workspace:@navikt/aksel" dependencies: @@ -8297,7 +8297,6 @@ __metadata: version: 0.0.0-use.local resolution: "aksel.nav.no@workspace:aksel.nav.no" dependencies: - "@navikt/aksel": "*" "@navikt/aksel-icons": ^3.1.3 "@navikt/ds-codemod": ^3.1.3 "@navikt/ds-css": ^3.1.3