Skip to content

Commit affcab1

Browse files
authored
✨ Copybutton-komponent (#1982)
1 parent d51b023 commit affcab1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1479
-125
lines changed

.changeset/green-trainers-guess.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
"@navikt/ds-css": minor
3+
"@navikt/ds-react": minor
4+
"@navikt/ds-react-internal": minor
5+
---
6+
7+
:sparkles: Ny komponent `<CopyButton />`!
8+
9+
- Erstatter `<CopyToClipboard />` fra `@navikt/ds-react-internal`
10+
- CopyToClipboard er markert som deprecated. Den vil fortsatt fungere, men noen lintere vil kunne ende opp med å klage på den.

.storybook/main.cjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ module.exports = {
2323
addons: [
2424
"@storybook/addon-a11y",
2525
"@whitespace/storybook-addon-html",
26-
26+
"@storybook/addon-interactions",
2727
{
2828
name: "@storybook/addon-storysource",
2929
options: {

@navikt/aksel/README.md

+33
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,39 @@ To get started:
2222
npx @navikt/aksel codemod --help
2323
```
2424

25+
### v3
26+
27+
There is no general codemods for migrating from v2 -> v3.
28+
29+
#### CopyButton
30+
31+
`npx @navikt/aksel codemod v3-copybutton ...`
32+
33+
`<CopyToClipboard />` has been renamed to `<CopyButton />` and refactored.
34+
35+
- Namechange
36+
- removed props `popoverText`, `iconPosition`, `popoverPlacement`
37+
- changed variants
38+
- refactored CSS and React-code. ⚠️ Overwritten CSS will not be migrated!
39+
40+
```diff
41+
-import { CopyToClipboard } from "@navikt/ds-react-internal";
42+
+import { CopyButton } from "@navikt/ds-react";
43+
44+
-<CopyToClipboard
45+
+<CopyButton
46+
- popoverText="popoverText"
47+
- iconPosition="left"
48+
- popoverPlacement="bottom-end"
49+
copyText="Text to copy"
50+
size="medium"
51+
>
52+
- text
53+
+</CopyButton>
54+
-</CopyToClipboard>
55+
56+
```
57+
2558
### v1 -> v2
2659

2760
[Documentation](https://aksel.nav.no/grunnleggende/kode/migrering#h76f47744d112)

@navikt/aksel/src/codemod/migrations.ts

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import chalk from "chalk";
22

33
export const migrations: {
4-
[key: string]: { description: string; value: string; path: string }[];
4+
[key: string]: {
5+
description: string;
6+
value: string;
7+
path: string;
8+
warning?: string;
9+
}[];
510
} = {
611
"1.0.0": [
712
{
@@ -48,6 +53,16 @@ export const migrations: {
4853
path: "v2.0.0/update-less-tokens/update-less-tokens",
4954
},
5055
],
56+
"v3.0.0": [
57+
{
58+
description:
59+
"Replaces deprecated <CopyToClipboard /> with <CopyButton />",
60+
value: "v3-copybutton",
61+
path: "v3.0.0/copybutton/copybutton",
62+
warning:
63+
"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",
64+
},
65+
],
5166
};
5267

5368
export function getMigrationPath(str: string) {
@@ -56,6 +71,12 @@ export function getMigrationPath(str: string) {
5671
.find((x) => x.value === str)?.path;
5772
}
5873

74+
export function getWarning(str: string) {
75+
return Object.values(migrations)
76+
.reduce((acc, val) => [...val, ...acc], [])
77+
.find((x) => x.value === str)?.warning;
78+
}
79+
5980
export function getMigrationNames() {
6081
return Object.values(migrations).reduce(
6182
(acc, val) => [...val.map((x) => x.value), ...acc],

@navikt/aksel/src/codemod/run-codeshift.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Command } from "commander";
22
import fg from "fast-glob";
33
import * as jscodeshift from "jscodeshift/src/Runner";
44
import path from "path";
5-
import { getMigrationPath } from "./migrations";
5+
import { getMigrationPath, getWarning } from "./migrations";
66
import chalk from "chalk";
77

88
const ignoreNodeModules = [
@@ -32,6 +32,8 @@ export async function runCodeshift(
3232

3333
options?.glob && console.log(`Using glob: ${chalk.green(options.glob)}\n`);
3434

35+
const warning = getWarning(input);
36+
3537
try {
3638
await jscodeshift.run(codemodPath, filepaths, {
3739
babel: true,
@@ -46,6 +48,8 @@ export async function runCodeshift(
4648
force: options?.force,
4749
print: options?.print,
4850
});
51+
52+
warning && console.log(`\n${chalk.yellow(warning)}\n`);
4953
} catch (error) {
5054
program.error(chalk.red("Error:", error.message));
5155
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import chalk from "chalk";
2+
import moveAndRenameImport from "../../../utils/moveAndRenameImport";
3+
import removePropsFromComponent from "../../../utils/removeProps";
4+
5+
/**
6+
* @param {import('jscodeshift').FileInfo} file
7+
* @param {import('jscodeshift').API} api
8+
*/
9+
export default function transformer(file, api, options, ...rest) {
10+
const j = api.jscodeshift;
11+
12+
let root: any;
13+
try {
14+
root = j(file.source);
15+
} catch {
16+
return file.source;
17+
}
18+
19+
const toName = "CopyButton";
20+
const localName = moveAndRenameImport(j, root, {
21+
fromImport: "@navikt/ds-react-internal",
22+
toImport: "@navikt/ds-react",
23+
fromName: "CopyToClipboard",
24+
toName,
25+
});
26+
27+
if (localName === null) {
28+
return root.toSource(options.printOptions);
29+
}
30+
31+
/* Finds and replaces import from CopyToClipboard -> CopyButton */
32+
33+
if (root.findJSXElements(localName)) {
34+
removePropsFromComponent(j, root, localName, [
35+
"popoverText",
36+
"popoverPlacement",
37+
"iconPosition",
38+
"variant",
39+
]);
40+
41+
const component = root.findJSXElements(localName);
42+
43+
component.forEach((node) => {
44+
const children = node.node.children;
45+
let flagged = false;
46+
if (
47+
children.length > 0 &&
48+
!node.node.openingElement.attributes.some(
49+
(attr) => attr.name.name === "text"
50+
)
51+
) {
52+
if (children.length === 1 && children[0].type === "JSXText") {
53+
node.node.openingElement.attributes.push(
54+
j.jsxAttribute(
55+
j.jsxIdentifier("text"),
56+
j.literal(children[0].value.trim())
57+
)
58+
);
59+
} else {
60+
flagged = true;
61+
console.log(
62+
chalk.yellow(
63+
`\n\nWarning: Detected advanced children-type!\nCodemod can't convert into "text" prop so you will need to update this manually.`
64+
)
65+
);
66+
}
67+
}
68+
69+
if (!flagged) {
70+
node.node.children = [];
71+
node.node.openingElement.selfClosing = true;
72+
node.node.closingElement = null;
73+
}
74+
});
75+
76+
const compRoot = root.find(j.JSXElement, {
77+
openingElement: { name: { name: localName } },
78+
});
79+
80+
compRoot.forEach((x) => {
81+
x.node.openingElement.name.name = "CopyButton";
82+
if (x.node.children.length > 0) {
83+
x.node.closingElement.name.name = "CopyButton";
84+
}
85+
});
86+
}
87+
88+
return root.toSource(options.printOptions);
89+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { CopyToClipboard as DsCpyButton } from "@navikt/ds-react-internal";
2+
3+
/* eslint-disable react/jsx-no-undef */
4+
export const Page = () => {
5+
return <DsCpyButton></DsCpyButton>;
6+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { CopyButton } from "@navikt/ds-react";
2+
3+
/* eslint-disable react/jsx-no-undef */
4+
export const Page = () => {
5+
return <CopyButton />;
6+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { CopyToClipboard } from "@navikt/ds-react-internal";
2+
3+
/* eslint-disable react/jsx-no-undef */
4+
export const Page = () => {
5+
return (
6+
<CopyToClipboard
7+
popoverText="popoverText"
8+
copyText="Text to copy"
9+
iconPosition="left"
10+
size="medium"
11+
popoverPlacement="bottom-end"
12+
>
13+
{text}
14+
</CopyToClipboard>
15+
);
16+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { CopyButton } from "@navikt/ds-react";
2+
3+
/* eslint-disable react/jsx-no-undef */
4+
export const Page = () => {
5+
return (
6+
<CopyButton copyText="Text to copy" size="medium" text="text">
7+
{text}
8+
</CopyButton>
9+
);
10+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { CopyToClipboard } from "@navikt/ds-react-internal";
2+
3+
/* eslint-disable react/jsx-no-undef */
4+
export const Page = () => {
5+
return <CopyToClipboard></CopyToClipboard>;
6+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { CopyButton } from "@navikt/ds-react";
2+
3+
/* eslint-disable react/jsx-no-undef */
4+
export const Page = () => {
5+
return <CopyButton />;
6+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { CopyToClipboard } from "@navikt/ds-react-internal";
2+
3+
/* eslint-disable react/jsx-no-undef */
4+
export const Page = () => {
5+
return (
6+
<CopyToClipboard
7+
popoverText="popoverText"
8+
copyText="Text to copy"
9+
iconPosition="left"
10+
size="medium"
11+
popoverPlacement="bottom-end"
12+
>
13+
text
14+
</CopyToClipboard>
15+
);
16+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { CopyButton } from "@navikt/ds-react";
2+
3+
/* eslint-disable react/jsx-no-undef */
4+
export const Page = () => {
5+
return <CopyButton copyText="Text to copy" size="medium" text="text" />;
6+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { check } from "../../../../utils/check";
2+
3+
const migration = "copybutton";
4+
const fixtures = ["complete", "idempotent", "alias", "cleanup", "import"];
5+
6+
for (const fixture of fixtures) {
7+
check(__dirname, {
8+
fixture,
9+
migration,
10+
extension: "js",
11+
});
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { CopyButton } from "@navikt/ds-react";
2+
3+
/* eslint-disable react/jsx-no-undef */
4+
export const Page = () => {
5+
return <CopyButton copyText="Text to copy" size="medium" text={props.text} />;
6+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { CopyButton } from "@navikt/ds-react";
2+
3+
/* eslint-disable react/jsx-no-undef */
4+
export const Page = () => {
5+
return <CopyButton copyText="Text to copy" size="medium" text={props.text} />;
6+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { CopyToClipboard, Dropdown } from "@navikt/ds-react-internal";
2+
import { Button } from "@navikt/ds-react";
3+
4+
/* eslint-disable react/jsx-no-undef */
5+
export const Page = () => {
6+
return <CopyToClipboard></CopyToClipboard>;
7+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Dropdown } from "@navikt/ds-react-internal";
2+
import { Button, CopyButton } from "@navikt/ds-react";
3+
4+
/* eslint-disable react/jsx-no-undef */
5+
export const Page = () => {
6+
return <CopyButton />;
7+
};

0 commit comments

Comments
 (0)