Compare commits

...
Author SHA1 Message Date
github-actions[bot]andgithub-actions[bot] 9a98f0eae4 Version Packages (#1988)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-16 13:13:56 +02:00
Ken affcab14c3 ✨ Copybutton-komponent (#1982) 2023-05-16 12:56:16 +02:00
Ken d51b0238d5 💄 Oppdatert ToggleGroup-bruk på ikonsider 2023-05-12 12:58:22 +02:00
github-actions[bot]andgithub-actions[bot] c818a92355 Version Packages (#1977)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-11 15:57:52 +02:00
Ken e8ecf309a9 💄 Oppdatert ToggleGroup (#1976) 2023-05-11 15:55:30 +02:00
Ken 060d4f3c7c 📝 Bedre props-dokumentasjon for ExpansionCard 2023-05-11 12:35:10 +02:00
github-actions[bot]andgithub-actions[bot] 1871038837 Version Packages (#1974)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-10 22:19:00 +02:00
Ken 5e79234eff 🐛 Timeline pin var ikke riktig alignet 2023-05-10 16:03:09 +02:00
github-actions[bot]andgithub-actions[bot] b8bebace11 Version Packages (#1971)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-10 14:10:55 +02:00
Ken 14379a02c3 🐛 Timeline håndterte ikke SVG-ikoner riktig 2023-05-10 13:56:20 +02:00
github-actions[bot]andgithub-actions[bot] d716ebbc40 Version Packages (#1970)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-10 13:33:21 +02:00
Ken f1c4c46ebb 💄 Focus-visible (#1966) 2023-05-10 13:04:29 +02:00
Ken 9d2cd9e7ff 💄 Oppdatert label/description for skjemakomponenter (#1967) 2023-05-10 12:54:29 +02:00
113 changed files with 2394 additions and 393 deletions

No files matched your search

+1 -1
View File
@@ -23,7 +23,7 @@ module.exports = {
addons: [
"@storybook/addon-a11y",
"@whitespace/storybook-addon-html",
"@storybook/addon-interactions",
{
name: "@storybook/addon-storysource",
options: {
+10
View File
@@ -1,5 +1,15 @@
# @navikt/aksel-icons
## 3.2.0
## 3.1.3
## 3.1.2
## 3.1.1
## 3.1.0
## 3.0.1
## 3.0.0
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/aksel-icons",
"version": "3.0.1",
"version": "3.2.0",
"author": "Aksel | NAV",
"homepage": "https://aksel.nav.no/ikoner",
"repository": {
+35
View File
@@ -1,5 +1,40 @@
# @navikt/aksel
## 3.2.0
### Patch Changes
- Updated dependencies [[`affcab14c`](https://github.com/navikt/aksel/commit/affcab14c3d536929dfa64a36f5b43f9d0e8c3b7)]:
- @navikt/ds-css@3.2.0
## 3.1.3
### Patch Changes
- Updated dependencies [[`e8ecf309a`](https://github.com/navikt/aksel/commit/e8ecf309a910e47fd3cea6c54cd993ab1196910f)]:
- @navikt/ds-css@3.1.3
## 3.1.2
### Patch Changes
- Updated dependencies []:
- @navikt/ds-css@3.1.2
## 3.1.1
### Patch Changes
- Updated dependencies []:
- @navikt/ds-css@3.1.1
## 3.1.0
### Patch Changes
- Updated dependencies [[`9d2cd9e7f`](https://github.com/navikt/aksel/commit/9d2cd9e7fffb3cf6310c88229ee39ea85db19bca), [`f1c4c46eb`](https://github.com/navikt/aksel/commit/f1c4c46ebb0522561483f18e3b86b190cf9cc372)]:
- @navikt/ds-css@3.1.0
## 3.0.1
### Patch Changes
+33
View File
@@ -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 ...`
`<CopyToClipboard />` has been renamed to `<CopyButton />` 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";
-<CopyToClipboard
+<CopyButton
- popoverText="popoverText"
- iconPosition="left"
- popoverPlacement="bottom-end"
copyText="Text to copy"
size="medium"
>
- text
+</CopyButton>
-</CopyToClipboard>
```
### v1 -> v2
[Documentation](https://aksel.nav.no/grunnleggende/kode/migrering#h76f47744d112)
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/aksel",
"version": "3.0.1",
"version": "3.2.0",
"description": "Aksel command line interface. Handles css-imports, codemods and more",
"author": "Aksel | NAV designsystem team",
"license": "MIT",
@@ -29,7 +29,7 @@
},
"homepage": "https://aksel.nav.no/grunnleggende/kode/kommandolinje",
"dependencies": {
"@navikt/ds-css": "3.0.1",
"@navikt/ds-css": "3.2.0",
"axios": "1.3.6",
"chalk": "4.1.0",
"clipboardy": "^2.3.0",
+22 -1
View File
@@ -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 <CopyToClipboard /> with <CopyButton />",
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],
+5 -1
View File
@@ -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,8 @@ export async function runCodeshift(
options?.glob && console.log(`Using glob: ${chalk.green(options.glob)}\n`);
const warning = getWarning(input);
try {
await jscodeshift.run(codemodPath, filepaths, {
babel: true,
@@ -46,6 +48,8 @@ export async function runCodeshift(
force: options?.force,
print: options?.print,
});
warning && console.log(`\n${chalk.yellow(warning)}\n`);
} catch (error) {
program.error(chalk.red("Error:", error.message));
}
@@ -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);
}
@@ -0,0 +1,6 @@
import { CopyToClipboard as DsCpyButton } from "@navikt/ds-react-internal";
/* eslint-disable react/jsx-no-undef */
export const Page = () => {
return <DsCpyButton></DsCpyButton>;
};
@@ -0,0 +1,6 @@
import { CopyButton } from "@navikt/ds-react";
/* eslint-disable react/jsx-no-undef */
export const Page = () => {
return <CopyButton />;
};
@@ -0,0 +1,16 @@
import { CopyToClipboard } from "@navikt/ds-react-internal";
/* eslint-disable react/jsx-no-undef */
export const Page = () => {
return (
<CopyToClipboard
popoverText="popoverText"
copyText="Text to copy"
iconPosition="left"
size="medium"
popoverPlacement="bottom-end"
>
{text}
</CopyToClipboard>
);
};
@@ -0,0 +1,10 @@
import { CopyButton } from "@navikt/ds-react";
/* eslint-disable react/jsx-no-undef */
export const Page = () => {
return (
<CopyButton copyText="Text to copy" size="medium" text="text">
{text}
</CopyButton>
);
};
@@ -0,0 +1,6 @@
import { CopyToClipboard } from "@navikt/ds-react-internal";
/* eslint-disable react/jsx-no-undef */
export const Page = () => {
return <CopyToClipboard></CopyToClipboard>;
};
@@ -0,0 +1,6 @@
import { CopyButton } from "@navikt/ds-react";
/* eslint-disable react/jsx-no-undef */
export const Page = () => {
return <CopyButton />;
};
@@ -0,0 +1,16 @@
import { CopyToClipboard } from "@navikt/ds-react-internal";
/* eslint-disable react/jsx-no-undef */
export const Page = () => {
return (
<CopyToClipboard
popoverText="popoverText"
copyText="Text to copy"
iconPosition="left"
size="medium"
popoverPlacement="bottom-end"
>
text
</CopyToClipboard>
);
};
@@ -0,0 +1,6 @@
import { CopyButton } from "@navikt/ds-react";
/* eslint-disable react/jsx-no-undef */
export const Page = () => {
return <CopyButton copyText="Text to copy" size="medium" text="text" />;
};
@@ -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",
});
}
@@ -0,0 +1,6 @@
import { CopyButton } from "@navikt/ds-react";
/* eslint-disable react/jsx-no-undef */
export const Page = () => {
return <CopyButton copyText="Text to copy" size="medium" text={props.text} />;
};
@@ -0,0 +1,6 @@
import { CopyButton } from "@navikt/ds-react";
/* eslint-disable react/jsx-no-undef */
export const Page = () => {
return <CopyButton copyText="Text to copy" size="medium" text={props.text} />;
};
@@ -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 <CopyToClipboard></CopyToClipboard>;
};
@@ -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 <CopyButton />;
};
@@ -0,0 +1,83 @@
import core, { Collection } from "jscodeshift";
export default function moveAndRenameImport(
j: core.JSCodeshift,
root: Collection<any>,
{
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;
}
@@ -0,0 +1,25 @@
import core, { Collection } from "jscodeshift";
export default function removePropsFromComponent(
j: core.JSCodeshift,
root: Collection<any>,
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);
}
}
});
}
+10
View File
@@ -1,5 +1,15 @@
# @navikt/ds-codemod
## 3.2.0
## 3.1.3
## 3.1.2
## 3.1.1
## 3.1.0
## 3.0.1
## 3.0.0
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-codemod",
"version": "3.0.1",
"version": "3.2.0",
"description": "Aksel codemods for NAVs designsystem",
"author": "Aksel | NAV designsystem team",
"license": "MIT",
+2 -2
View File
@@ -40,8 +40,8 @@
"build-pict": "svgr --silent --index-template index-template.js --out-dir src/pictograms pictograms"
},
"dependencies": {
"@navikt/ds-icons": "^3.0.1",
"@navikt/ds-react": "^3.0.1",
"@navikt/ds-icons": "^3.2.0",
"@navikt/ds-react": "^3.2.0",
"clsx": "^1.1.1"
},
"devDependencies": {
+33
View File
@@ -1,5 +1,38 @@
# @navikt/ds-css
## 3.2.0
### Minor Changes
- [#1982](https://github.com/navikt/aksel/pull/1982) [`affcab14c`](https://github.com/navikt/aksel/commit/affcab14c3d536929dfa64a36f5b43f9d0e8c3b7) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :sparkles: Ny komponent `<CopyButton />`!
- Erstatter `<CopyToClipboard />` fra `@navikt/ds-react-internal`
- CopyToClipboard er markert som deprecated. Den vil fortsatt fungere, men noen lintere vil kunne ende opp med å klage på den.
## 3.1.3
### Patch Changes
- [#1976](https://github.com/navikt/aksel/pull/1976) [`e8ecf309a`](https://github.com/navikt/aksel/commit/e8ecf309a910e47fd3cea6c54cd993ab1196910f) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :lipstick: Oppdatert utseende for ToggleGroup
- Medium og Small er begge 10px lavere
- Mindre border-radius
## 3.1.2
## 3.1.1
## 3.1.0
### Minor Changes
- [#1966](https://github.com/navikt/aksel/pull/1966) [`f1c4c46eb`](https://github.com/navikt/aksel/commit/f1c4c46ebb0522561483f18e3b86b190cf9cc372) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :lipstick: Alle komponenter bruker nå default `:focus-visible` for fokusmarkering.
(Alle komponenter som bruker `:focus-visible` har også en fallback for `:focus`)
### Patch Changes
- [#1967](https://github.com/navikt/aksel/pull/1967) [`9d2cd9e7f`](https://github.com/navikt/aksel/commit/9d2cd9e7fffb3cf6310c88229ee39ea85db19bca) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :lipstick: Oppdatert Label og Description spacing for skjemakomponenter
## 3.0.1
## 3.0.0
+87 -12
View File
@@ -63,11 +63,18 @@
padding: var(--ac-button-padding-icon-only-xsmall, var(--__ac-button-padding));
}
.navds-button:focus {
.navds-button:focus-visible {
outline: none;
box-shadow: var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-button:focus {
outline: none;
box-shadow: var(--a-shadow-focus);
}
}
.navds-button__icon {
--ac-button-icon-margin: -4px;
@@ -114,10 +121,16 @@
background-color: var(--ac-button-primary-active-bg, var(--a-surface-action-active));
}
.navds-button--primary:focus {
.navds-button--primary:focus-visible {
box-shadow: inset 0 0 0 1px var(--ac-button-primary-focus-border, var(--a-surface-default)), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-button--primary:focus {
box-shadow: inset 0 0 0 1px var(--ac-button-primary-focus-border, var(--a-surface-default)), var(--a-shadow-focus);
}
}
.navds-button--primary:hover:where(:disabled, .navds-button--disabled),
.navds-button--primary:active:where(:disabled, .navds-button--disabled) {
background-color: var(--ac-button-primary-bg, var(--a-surface-action));
@@ -140,10 +153,16 @@
background-color: var(--ac-button-primary-neutral-active-bg, var(--a-surface-neutral-active));
}
.navds-button--primary-neutral:focus {
.navds-button--primary-neutral:focus-visible {
box-shadow: inset 0 0 0 1px var(--ac-button-primary-neutral-focus-border, var(--a-surface-default)), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-button--primary-neutral:focus {
box-shadow: inset 0 0 0 1px var(--ac-button-primary-neutral-focus-border, var(--a-surface-default)), var(--a-shadow-focus);
}
}
.navds-button--primary-neutral:hover:where(:disabled, .navds-button--disabled),
.navds-button--primary-neutral:active:where(:disabled, .navds-button--disabled) {
background-color: var(--ac-button-primary-neutral-bg, var(--a-surface-neutral));
@@ -164,20 +183,32 @@
background-color: var(--ac-button-secondary-hover-bg, var(--a-surface-action-subtle-hover));
}
.navds-button--secondary:focus {
.navds-button--secondary:focus-visible {
box-shadow: inset 0 0 0 2px var(--ac-button-secondary-focus-border, var(--a-border-action)), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-button--secondary:focus {
box-shadow: inset 0 0 0 2px var(--ac-button-secondary-focus-border, var(--a-border-action)), var(--a-shadow-focus);
}
}
.navds-button--secondary:active {
color: var(--ac-button-secondary-active-text, var(--a-text-on-action));
background-color: var(--ac-button-secondary-active-bg, var(--a-surface-action-active));
box-shadow: none;
}
.navds-button--secondary:focus:active {
.navds-button--secondary:focus-visible:active {
box-shadow: inset 0 0 0 1px var(--ac-button-secondary-active-focus-border, var(--a-surface-default)), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-button--secondary:focus:active {
box-shadow: inset 0 0 0 1px var(--ac-button-secondary-active-focus-border, var(--a-surface-default)), var(--a-shadow-focus);
}
}
.navds-button--secondary:where(:disabled, .navds-button--disabled),
.navds-button--secondary:hover:where(:disabled, .navds-button--disabled) {
color: var(--ac-button-secondary-text, var(--a-text-action));
@@ -199,22 +230,36 @@
background-color: var(--ac-button-secondary-neutral-hover-bg, var(--a-surface-neutral-subtle-hover));
}
.navds-button--secondary-neutral:focus {
.navds-button--secondary-neutral:focus-visible {
color: var(--ac-button-secondary-neutral-text, var(--a-text-default));
box-shadow: inset 0 0 0 2px var(--ac-button-secondary-neutral-focus-border, var(--a-border-strong)), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-button--secondary-neutral:focus {
color: var(--ac-button-secondary-neutral-text, var(--a-text-default));
box-shadow: inset 0 0 0 2px var(--ac-button-secondary-neutral-focus-border, var(--a-border-strong)), var(--a-shadow-focus);
}
}
.navds-button--secondary-neutral:active {
color: var(--ac-button-secondary-neutral-active-text, var(--a-text-on-neutral));
background-color: var(--ac-button-secondary-neutral-active-bg, var(--a-surface-neutral-active));
box-shadow: none;
}
.navds-button--secondary-neutral:focus:active {
.navds-button--secondary-neutral:focus-visible:active {
box-shadow: inset 0 0 0 1px var(--ac-button-secondary-neutral-active-focus-border, var(--a-surface-default)),
var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-button--secondary-neutral:focus:active {
box-shadow: inset 0 0 0 1px var(--ac-button-secondary-neutral-active-focus-border, var(--a-surface-default)),
var(--a-shadow-focus);
}
}
.navds-button--secondary-neutral:where(:disabled, .navds-button--disabled),
.navds-button--secondary-neutral:hover:where(:disabled, .navds-button--disabled) {
color: var(--ac-button-secondary-neutral-text, var(--a-text-default));
@@ -236,10 +281,16 @@
background-color: var(--ac-button-tertiary-hover-bg, var(--a-surface-action-subtle-hover));
}
.navds-button--tertiary:focus {
.navds-button--tertiary:focus-visible {
box-shadow: inset 0 0 0 2px var(--ac-button-tertiary-focus-border, var(--a-border-action)), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-button--tertiary:focus {
box-shadow: inset 0 0 0 2px var(--ac-button-tertiary-focus-border, var(--a-border-action)), var(--a-shadow-focus);
}
}
.navds-button--tertiary:active {
color: var(--ac-button-tertiary-active-text, var(--a-text-on-action));
background-color: var(--ac-button-tertiary-active-bg, var(--a-surface-action-active));
@@ -250,10 +301,16 @@
background-color: var(--ac-button-tertiary-active-hover-bg, var(--a-surface-action-active));
}
.navds-button--tertiary:active:focus {
.navds-button--tertiary:focus-visible:active {
box-shadow: inset 0 0 0 1px var(--a-surface-default), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-button--tertiary:focus:active {
box-shadow: inset 0 0 0 1px var(--a-surface-default), var(--a-shadow-focus);
}
}
.navds-button--tertiary:where(:disabled, .navds-button--disabled),
.navds-button--tertiary:hover:where(:disabled, .navds-button--disabled),
.navds-button--tertiary:active:where(:disabled, .navds-button--disabled),
@@ -276,10 +333,16 @@
background-color: var(--ac-button-tertiary-neutral-hover-bg, var(--a-surface-neutral-subtle-hover));
}
.navds-button--tertiary-neutral:focus {
.navds-button--tertiary-neutral:focus-visible {
box-shadow: inset 0 0 0 2px var(--ac-button-tertiary-neutral-focus-border, var(--a-border-strong)), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-button--tertiary-neutral:focus {
box-shadow: inset 0 0 0 2px var(--ac-button-tertiary-neutral-focus-border, var(--a-border-strong)), var(--a-shadow-focus);
}
}
.navds-button--tertiary-neutral:active {
color: var(--ac-button-tertiary-neutral-active-text, var(--a-text-on-neutral));
background-color: var(--ac-button-tertiary-neutral-active-bg, var(--a-surface-neutral-active));
@@ -290,10 +353,16 @@
background-color: var(--ac-button-tertiary-neutral-active-hover-bg, var(--a-surface-neutral-active));
}
.navds-button--tertiary-neutral:active:focus {
.navds-button--tertiary-neutral:focus-visible:active {
box-shadow: inset 0 0 0 1px var(--a-surface-default), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-button--tertiary-neutral:focus:active {
box-shadow: inset 0 0 0 1px var(--a-surface-default), var(--a-shadow-focus);
}
}
.navds-button--tertiary-neutral:where(:disabled, .navds-button--disabled),
.navds-button--tertiary-neutral:hover:where(:disabled, .navds-button--disabled),
.navds-button--tertiary-neutral:active:where(:disabled, .navds-button--disabled),
@@ -320,10 +389,16 @@
background-color: var(--ac-button-danger-active-bg, var(--a-surface-danger-active));
}
.navds-button--danger:focus {
.navds-button--danger:focus-visible {
box-shadow: inset 0 0 0 1px var(--a-surface-default), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-button--danger:focus {
box-shadow: inset 0 0 0 1px var(--a-surface-default), var(--a-shadow-focus);
}
}
.navds-button--danger:active:where(:disabled, .navds-button--disabled),
.navds-button--danger:hover:where(:disabled, .navds-button--disabled) {
background-color: var(--ac-button-danger-bg, var(--a-surface-danger));
-5
View File
@@ -56,11 +56,6 @@
gap: var(--a-spacing-2);
}
.navds-chat__bubble:focus {
box-shadow: var(--a-shadow-focus);
outline: none;
}
.navds-chat--right .navds-chat__bubble {
border-radius: var(--a-border-radius-xlarge);
border-bottom-right-radius: 2px;
+24
View File
@@ -63,6 +63,18 @@
box-shadow: inset 0 0 0 1px var(--a-surface-default), 0 0 0 2px var(--ac-chip-toggle-focus, var(--a-border-focus));
}
@supports not selector(:focus-visible) {
.navds-chips__toggle:focus {
outline: none;
box-shadow: 0 0 0 2px var(--ac-chip-toggle-focus, var(--a-border-focus));
}
.navds-chips__toggle[aria-pressed="true"]:focus,
.navds-chips__toggle:active:focus {
box-shadow: inset 0 0 0 1px var(--a-surface-default), 0 0 0 2px var(--ac-chip-toggle-focus, var(--a-border-focus));
}
}
.navds-chips__removable {
gap: 0;
}
@@ -117,6 +129,18 @@
box-shadow: 0 0 0 2px var(--a-border-focus);
}
@supports not selector(:focus-visible) {
.navds-chips__removable--action:focus {
outline: none;
box-shadow: inset 0 0 0 1px var(--a-surface-default), 0 0 0 2px var(--a-border-focus);
}
.navds-chips__removable--neutral:focus {
outline: none;
box-shadow: 0 0 0 2px var(--a-border-focus);
}
}
.navds-chips__removable--action:hover {
background-color: var(--ac-chip-removable-action-hover-bg, var(--a-surface-action-selected-hover));
}
+5
View File
@@ -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] },
+4 -1
View File
@@ -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" });
+129
View File
@@ -0,0 +1,129 @@
[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);
cursor: pointer;
margin: 0;
text-decoration: none;
border: none;
background: none;
border-radius: var(--ac-copybutton-border-radius, var(--a-border-radius-medium));
padding: var(--__ac-copybutton-padding);
display: grid;
place-content: center;
}
.navds-copybutton--small {
--__ac-copybutton-padding: var(--a-spacing-1) var(--a-spacing-3);
min-height: 2rem;
}
.navds-copybutton--icon-only {
--__ac-copybutton-padding: var(--a-spacing-3);
}
.navds-copybutton--small.navds-copybutton--icon-only {
--__ac-copybutton-padding: var(--a-spacing-1);
}
.navds-copybutton__icon {
font-size: 1.5rem;
display: flex;
margin-left: -4px;
}
.navds-copybutton__icon:only-child {
margin: 0;
}
.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);
}
}
/* 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));
background-color: var(--ac-copybutton-action-hover-bg, var(--a-surface-hover));
}
.navds-copybutton--action:where(:disabled),
.navds-copybutton--action:hover:where(:disabled) {
color: var(--ac-copybutton-action-text, var(--a-text-action));
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-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-hover));
}
.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-color: var(--ac-copybutton-neutral-bg, var(--a-surface-transparent));
box-shadow: none;
}
.navds-copybutton--active.navds-copybutton--neutral {
color: var(--ac-copybutton-neutral-active-text, var(--a-text-default));
}
.navds-copybutton__content {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--a-spacing-2);
}
.navds-copybutton--active > .navds-copybutton__content {
animation: var(--ac-copybutton-animation, akselCopyButtonAnimation 0.4s linear);
}
@keyframes akselCopyButtonAnimation {
0% {
opacity: 0.4;
}
100% {
opacity: 1;
}
}
/* Disabled */
.navds-copybutton:where(:disabled) {
cursor: not-allowed;
opacity: 0.3;
}
+42 -8
View File
@@ -73,16 +73,30 @@
border-radius: var(--a-border-radius-xlarge);
}
.navds-date .rdp-button:not(.rdp-day_selected):not([disabled]):focus,
.navds-date .navds-date__month-button:not(.rdp-day_selected):not([disabled]):focus {
.navds-date .rdp-button:not(.rdp-day_selected):not([disabled]):focus-visible,
.navds-date .navds-date__month-button:not(.rdp-day_selected):not([disabled]):focus-visible {
box-shadow: var(--a-shadow-focus);
}
.navds-date .rdp-button.rdp-day_selected:not([disabled]):focus,
.navds-date .navds-date__month-button.rdp-day_selected:not([disabled]):focus {
@supports not selector(:focus-visible) {
.navds-date .rdp-button:not(.rdp-day_selected):not([disabled]):focus,
.navds-date .navds-date__month-button:not(.rdp-day_selected):not([disabled]):focus {
box-shadow: var(--a-shadow-focus);
}
}
.navds-date .rdp-button.rdp-day_selected:not([disabled]):focus-visible,
.navds-date .navds-date__month-button.rdp-day_selected:not([disabled]):focus-visible {
box-shadow: inset 0 0 0 1px var(--a-surface-default), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-date .rdp-button.rdp-day_selected:not([disabled]):focus,
.navds-date .navds-date__month-button.rdp-day_selected:not([disabled]):focus {
box-shadow: inset 0 0 0 1px var(--a-surface-default), var(--a-shadow-focus);
}
}
/* Monthpicker */
.navds-date__month-button {
all: unset;
@@ -94,12 +108,20 @@
cursor: pointer;
}
.navds-date__month-button:focus,
.navds-monthpicker__caption-button:focus {
.navds-date__month-button:focus-visible,
.navds-monthpicker__caption-button:focus-visible {
box-shadow: var(--a-shadow-focus);
z-index: 1;
}
@supports not selector(:focus-visible) {
.navds-date__month-button:focus,
.navds-monthpicker__caption-button:focus {
box-shadow: var(--a-shadow-focus);
z-index: 1;
}
}
.navds-date__year-label {
display: flex;
align-items: center;
@@ -126,11 +148,17 @@
}
/* Focus layering */
.navds-date__field-input:focus,
.navds-date__field-input:focus-visible,
.navds-date__field-button {
z-index: 1;
}
@supports not selector(:focus-visible) {
.navds-date__field-input:focus {
z-index: 1;
}
}
.navds-date .rdp-day_selected,
.navds-monthpicker__month--selected {
color: var(--ac-date-selected-text, var(--a-text-on-action));
@@ -183,10 +211,16 @@
box-shadow: inset 0 0 0 1px var(--ac-date-input-error-border, var(--a-border-danger));
}
.navds-date__field--error .navds-date__field-input:focus:not(:hover):not(:disabled) {
.navds-date__field--error .navds-date__field-input:focus-visible:not(:hover):not(:disabled) {
box-shadow: inset 0 0 0 1px var(--ac-date-input-error-border, var(--a-border-danger)), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-date__field--error .navds-date__field-input:focus:not(:hover):not(:disabled) {
box-shadow: inset 0 0 0 1px var(--ac-date-input-error-border, var(--a-border-danger)), var(--a-shadow-focus);
}
}
.navds-date__field-button {
position: absolute;
right: var(--a-spacing-2);
+7 -3
View File
@@ -123,12 +123,16 @@
transform: translateY(1px);
}
.navds-expansioncard__header-button:focus {
.navds-expansioncard__header-button:focus-visible {
outline: none;
box-shadow: var(--a-shadow-focus);
}
.navds-expansioncard__header-button:focus-visible {
box-shadow: var(--a-shadow-focus);
@supports not selector(:focus-visible) {
.navds-expansioncard__header-button:focus {
outline: none;
box-shadow: var(--a-shadow-focus);
}
}
.navds-expansioncard--open :where(.navds-expansioncard__header-button):hover :where(.navds-expansioncard__header-chevron) {
+8 -1
View File
@@ -8,11 +8,18 @@
padding: var(--a-spacing-3);
}
.navds-error-summary:focus {
.navds-error-summary:focus-visible {
box-shadow: var(--a-shadow-focus);
outline: none;
}
@supports not selector(:focus-visible) {
.navds-error-summary:focus {
box-shadow: var(--a-shadow-focus);
outline: none;
}
}
.navds-error-summary__list {
margin: var(--a-spacing-3) 0;
display: flex;
+1 -1
View File
@@ -10,7 +10,7 @@
}
.navds-fieldset > .navds-fieldset__description:not(:empty) {
margin-top: var(--a-spacing-1);
margin-top: 0.125rem;
}
/* Applied when hideLegend is applied to fieldset */
+5 -1
View File
@@ -5,7 +5,7 @@
}
.navds-form-field__description {
margin-top: -4px;
margin-top: -6px;
}
.navds-form-field .navds-error-message,
@@ -27,3 +27,7 @@
.navds-form-field__error:empty {
display: none;
}
.navds-form-field__subdescription {
color: var(--ac-form-subdescription, var(--a-text-subtle));
}
+79 -16
View File
@@ -43,7 +43,7 @@
.navds-radio__content {
display: flex;
flex-direction: column;
gap: var(--a-spacing-1);
gap: 0.125rem;
}
.navds-checkbox--small > .navds-checkbox__input,
@@ -65,16 +65,30 @@
height: 1.25rem;
}
.navds-checkbox__input:focus + .navds-checkbox__label::before,
.navds-radio__input:focus + .navds-radio__label::before {
.navds-checkbox__input:focus-visible + .navds-checkbox__label::before,
.navds-radio__input:focus-visible + .navds-radio__label::before {
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-border, var(--a-border-default)), var(--a-shadow-focus);
}
.navds-checkbox__input:hover:focus + .navds-checkbox__label::before,
.navds-radio__input:hover:focus + .navds-radio__label::before {
@supports not selector(:focus-visible) {
.navds-checkbox__input:focus + .navds-checkbox__label::before,
.navds-radio__input:focus + .navds-radio__label::before {
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-border, var(--a-border-default)), var(--a-shadow-focus);
}
}
.navds-checkbox__input:hover:focus-visible + .navds-checkbox__label::before,
.navds-radio__input:hover:focus-visible + .navds-radio__label::before {
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-action, var(--a-surface-action)), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-checkbox__input:hover:focus + .navds-checkbox__label::before,
.navds-radio__input:hover:focus + .navds-radio__label::before {
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-action, var(--a-surface-action)), var(--a-shadow-focus);
}
}
.navds-checkbox__input:indeterminate + .navds-checkbox__label::before {
box-shadow: none;
background-color: var(--ac-radio-checkbox-action, var(--a-surface-action));
@@ -109,32 +123,54 @@
background-position: 4px center;
}
.navds-checkbox__input:indeterminate:focus + .navds-checkbox__label::before,
.navds-checkbox__input:checked:focus + .navds-checkbox__label::before {
.navds-checkbox__input:indeterminate:focus-visible + .navds-checkbox__label::before,
.navds-checkbox__input:checked:focus-visible + .navds-checkbox__label::before {
box-shadow: inset 0 0 0 1px var(--ac-radio-checkbox-bg, var(--a-surface-default)), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-checkbox__input:indeterminate:focus + .navds-checkbox__label::before,
.navds-checkbox__input:checked:focus + .navds-checkbox__label::before {
box-shadow: inset 0 0 0 1px var(--ac-radio-checkbox-bg, var(--a-surface-default)), var(--a-shadow-focus);
}
}
.navds-radio__input:checked + .navds-radio__label::before {
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-action, var(--a-surface-action)),
inset 0 0 0 4px var(--ac-radio-checkbox-bg, var(--a-surface-default));
background-color: var(--ac-radio-checkbox-action, var(--a-surface-action));
}
.navds-radio__input:checked:focus + .navds-radio__label::before {
.navds-radio__input:checked:focus-visible + .navds-radio__label::before {
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-action, var(--a-surface-action)),
inset 0 0 0 4px var(--ac-radio-checkbox-bg, var(--a-surface-default)), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-radio__input:checked:focus + .navds-radio__label::before {
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-action, var(--a-surface-action)),
inset 0 0 0 4px var(--ac-radio-checkbox-bg, var(--a-surface-default)), var(--a-shadow-focus);
}
}
.navds-checkbox__input:hover:not(:disabled) + .navds-checkbox__label,
.navds-radio__input:hover:not(:disabled) + .navds-radio__label {
color: var(--ac-radio-checkbox-action, var(--a-surface-action));
}
.navds-checkbox__input:hover:not(:disabled):not(:checked):not(:indeterminate):not(:focus) + .navds-checkbox__label::before,
.navds-radio__input:hover:not(:disabled):not(:checked):not(:focus) + .navds-radio__label::before {
.navds-checkbox__input:hover:not(:disabled):not(:checked):not(:indeterminate):not(:focus-visible)
+ .navds-checkbox__label::before,
.navds-radio__input:hover:not(:disabled):not(:checked):not(:focus-visible) + .navds-radio__label::before {
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-action, var(--a-surface-action));
}
@supports not selector(:focus-visible) {
.navds-checkbox__input:hover:not(:disabled):not(:checked):not(:indeterminate):not(:focus) + .navds-checkbox__label::before,
.navds-radio__input:hover:not(:disabled):not(:checked):not(:focus) + .navds-radio__label::before {
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-action, var(--a-surface-action));
}
}
.navds-checkbox__input:hover:not(:disabled):not(:checked):not(:indeterminate) + .navds-checkbox__label::before,
.navds-radio__input:hover:not(:disabled):not(:checked) + .navds-radio__label::before {
background-color: var(--ac-radio-checkbox-action-hover-bg, var(--a-surface-action-subtle));
@@ -148,28 +184,55 @@
}
.navds-checkbox--error
> .navds-checkbox__input:focus:not(:hover):not(:disabled):not(:checked):not(:indeterminate)
> .navds-checkbox__input:focus-visible:not(:hover):not(:disabled):not(:checked):not(:indeterminate)
+ .navds-checkbox__label::before,
.navds-radio--error > .navds-radio__input:focus:not(:hover):not(:disabled):not(:checked) + .navds-radio__label::before {
.navds-radio--error > .navds-radio__input:focus-visible:not(:hover):not(:disabled):not(:checked) + .navds-radio__label::before {
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-error-border, var(--a-border-danger)), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-checkbox--error
> .navds-checkbox__input:focus:not(:hover):not(:disabled):not(:checked):not(:indeterminate)
+ .navds-checkbox__label::before,
.navds-radio--error > .navds-radio__input:focus:not(:hover):not(:disabled):not(:checked) + .navds-radio__label::before {
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-error-border, var(--a-border-danger)), var(--a-shadow-focus);
}
}
.navds-checkbox--error
> .navds-checkbox__input:hover:not(:disabled):not(:checked):not(:indeterminate):not(:focus)
> .navds-checkbox__input:hover:not(:disabled):not(:checked):not(:indeterminate):not(:focus-visible)
+ .navds-checkbox__label::before,
.navds-radio--error > .navds-radio__input:hover:not(:disabled):not(:checked):not(:focus) + .navds-radio__label::before {
.navds-radio--error > .navds-radio__input:hover:not(:disabled):not(:checked):not(:focus-visible) + .navds-radio__label::before {
background-color: var(--ac-radio-checkbox-error-hover-bg, var(--a-surface-danger-subtle));
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-error-border, var(--a-border-danger));
}
.navds-checkbox--error
> .navds-checkbox__input:focus:hover:not(:disabled):not(:checked):not(:indeterminate)
> .navds-checkbox__input:focus-visible:hover:not(:disabled):not(:checked):not(:indeterminate)
+ .navds-checkbox__label::before,
.navds-radio--error > .navds-radio__input:focus:hover:not(:disabled):not(:checked) + .navds-radio__label::before {
.navds-radio--error > .navds-radio__input:focus-visible:hover:not(:disabled):not(:checked) + .navds-radio__label::before {
background-color: var(--ac-radio-checkbox-error-hover-bg, var(--a-surface-danger-subtle));
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-error-border, var(--a-border-danger)), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-checkbox--error
> .navds-checkbox__input:hover:not(:disabled):not(:checked):not(:indeterminate):not(:focus)
+ .navds-checkbox__label::before,
.navds-radio--error > .navds-radio__input:hover:not(:disabled):not(:checked):not(:focus) + .navds-radio__label::before {
background-color: var(--ac-radio-checkbox-error-hover-bg, var(--a-surface-danger-subtle));
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-error-border, var(--a-border-danger));
}
.navds-checkbox--error
> .navds-checkbox__input:focus:hover:not(:disabled):not(:checked):not(:indeterminate)
+ .navds-checkbox__label::before,
.navds-radio--error > .navds-radio__input:focus:hover:not(:disabled):not(:checked) + .navds-radio__label::before {
background-color: var(--ac-radio-checkbox-error-hover-bg, var(--a-surface-danger-subtle));
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-error-border, var(--a-border-danger)), var(--a-shadow-focus);
}
}
.navds-checkbox--disabled,
.navds-radio--disabled {
opacity: 0.3;
+39 -7
View File
@@ -86,11 +86,18 @@
color: var(--ac-search-clear-icon-hover, var(--a-text-action));
}
.navds-search__button-clear:focus {
.navds-search__button-clear:focus-visible {
box-shadow: var(--a-shadow-focus);
outline: none;
}
@supports not selector(:focus-visible) {
.navds-search__button-clear:focus {
box-shadow: var(--a-shadow-focus);
outline: none;
}
}
.navds-search__button-search {
flex-shrink: 0;
min-width: 64px;
@@ -126,31 +133,56 @@
z-index: auto;
}
.navds-search__button-search.navds-button--secondary:focus {
.navds-search__button-search.navds-button--secondary:focus-visible {
box-shadow: 0 0 0 1px var(--ac-search-button-border, var(--a-border-default)) inset, var(--a-shadow-focus);
}
.navds-search__button-search.navds-button--secondary:focus:hover {
.navds-search__button-search.navds-button--secondary:focus-visible:hover {
box-shadow: 0 0 0 1px var(--ac-search-button-border-hover, var(--a-border-action)) inset, var(--a-shadow-focus);
}
.navds-search__button-search.navds-button--secondary:focus:active {
.navds-search__button-search.navds-button--secondary:focus-visible:active {
box-shadow: 0 0 0 1px var(--ac-search-button-focus-active-border, var(--a-surface-default)) inset, var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-search__button-search.navds-button--secondary:focus {
box-shadow: 0 0 0 1px var(--ac-search-button-border, var(--a-border-default)) inset, var(--a-shadow-focus);
}
.navds-search__button-search.navds-button--secondary:focus:hover {
box-shadow: 0 0 0 1px var(--ac-search-button-border-hover, var(--a-border-action)) inset, var(--a-shadow-focus);
}
.navds-search__button-search.navds-button--secondary:focus:active {
box-shadow: 0 0 0 1px var(--ac-search-button-focus-active-border, var(--a-surface-default)) inset, var(--a-shadow-focus);
}
}
/* Error-handling */
.navds-search--error .navds-search__input:not(:hover):not(:disabled) {
border-color: var(--ac-search-error-border, var(--a-border-danger));
box-shadow: inset 0 0 0 1px var(--ac-search-error-border, var(--a-border-danger));
}
.navds-search--error .navds-search__input:focus:not(:hover):not(:disabled) {
.navds-search--error .navds-search__input:focus-visible:not(:hover):not(:disabled) {
box-shadow: inset 0 0 0 1px var(--ac-search-error-border, var(--a-border-danger)), var(--a-shadow-focus);
}
/* Focus layering */
.navds-search__input:focus,
.navds-search__input:focus-visible,
.navds-search__button-clear,
.navds-search__button-search:focus {
.navds-search__button-search:focus-visible {
z-index: 1;
}
@supports not selector(:focus-visible) {
.navds-search--error .navds-search__input:focus:not(:hover):not(:disabled) {
box-shadow: inset 0 0 0 1px var(--ac-search-error-border, var(--a-border-danger)), var(--a-shadow-focus);
}
.navds-search__input:focus,
.navds-search__button-search:focus {
z-index: 1;
}
}
+8 -1
View File
@@ -17,11 +17,18 @@
border-color: var(--ac-select-hover-bg, var(--a-border-action));
}
.navds-select__input:focus {
.navds-select__input:focus-visible {
outline: none;
box-shadow: var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-select__input:focus {
outline: none;
box-shadow: var(--a-shadow-focus);
}
}
.navds-select__container {
position: relative;
display: flex;
+8 -2
View File
@@ -38,7 +38,7 @@
.navds-switch__content {
display: flex;
flex-direction: column;
gap: var(--a-spacing-1);
gap: 0.125rem;
padding: 0.75rem 0 0.75rem 3.25rem;
}
@@ -110,10 +110,16 @@
background-color: var(--ac-switch-checked-bg, var(--a-border-success));
}
.navds-switch__input:focus ~ .navds-switch__track {
.navds-switch__input:focus-visible ~ .navds-switch__track {
box-shadow: 0 0 0 1px var(--a-surface-default), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-switch__input:focus ~ .navds-switch__track {
box-shadow: 0 0 0 1px var(--a-surface-default), var(--a-shadow-focus);
}
}
/* Thumb */
.navds-switch__thumb {
background-color: var(--ac-switch-thumb-bg, var(--a-surface-default));
+15 -2
View File
@@ -35,11 +35,18 @@
border-color: var(--ac-textfield-hover-border, var(--a-border-action));
}
.navds-text-field__input:focus {
.navds-text-field__input:focus-visible {
outline: none;
box-shadow: var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-text-field__input:focus {
outline: none;
box-shadow: var(--a-shadow-focus);
}
}
/**
Error handling
*/
@@ -48,10 +55,16 @@
box-shadow: 0 0 0 1px var(--ac-textfield-error-border, var(--a-border-danger));
}
.navds-text-field--error > .navds-text-field__input:focus:not(:hover):not(:disabled) {
.navds-text-field--error > .navds-text-field__input:focus-visible:not(:hover):not(:disabled) {
box-shadow: 0 0 0 1px var(--a-border-danger), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-text-field--error > .navds-text-field__input:focus:not(:hover):not(:disabled) {
box-shadow: 0 0 0 1px var(--a-border-danger), var(--a-shadow-focus);
}
}
/* Disabled handling */
.navds-text-field__input:disabled {
background-color: var(--ac-textfield-bg, var(--a-surface-default));
+16 -2
View File
@@ -38,11 +38,18 @@
border-color: var(--ac-textarea-hover-border, var(--a-border-action));
}
.navds-textarea__input:focus {
.navds-textarea__input:focus-visible {
outline: none;
box-shadow: var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-textarea__input:focus {
outline: none;
box-shadow: var(--a-shadow-focus);
}
}
.navds-form-field--small .navds-textarea__input {
padding: 6px;
}
@@ -73,11 +80,18 @@
/**
Error handling
*/
.navds-textarea--error .navds-textarea__input:not(:hover):not(:focus):not(:disabled) {
.navds-textarea--error .navds-textarea__input:not(:hover):not(:focus-visible):not(:disabled) {
box-shadow: 0 0 0 1px var(--ac-textarea-error-border, var(--a-border-danger));
border-color: var(--ac-textarea-error-border, var(--a-border-danger));
}
@supports not selector(:focus-visible) {
.navds-textarea--error .navds-textarea__input:not(:hover):not(:focus):not(:disabled) {
box-shadow: 0 0 0 1px var(--ac-textarea-error-border, var(--a-border-danger));
border-color: var(--ac-textarea-error-border, var(--a-border-danger));
}
}
.navds-textarea__input:disabled {
background-color: var(--ac-textarea-bg, var(--a-surface-default));
border-color: var(--ac-textarea-border, var(--a-border-default));
+20 -4
View File
@@ -12,11 +12,17 @@
font-size: 1.5rem;
}
.navds-help-text__button:focus {
outline: none;
.navds-help-text__button:focus-visible {
box-shadow: 0 0 0 1px var(--a-surface-default), 0 0 0 4px var(--a-border-focus);
}
@supports not selector(:focus-visible) {
.navds-help-text__button:focus {
outline: none;
box-shadow: 0 0 0 1px var(--a-surface-default), 0 0 0 4px var(--a-border-focus);
}
}
.navds-help-text__icon {
border-radius: var(--a-border-radius-full);
}
@@ -36,10 +42,20 @@
display: none;
}
.navds-help-text__button:where(:hover, :focus, [aria-expanded="true"]) > .navds-help-text__icon {
.navds-help-text__button:where(:hover, :focus-visible, [aria-expanded="true"]) > .navds-help-text__icon {
display: none;
}
.navds-help-text__button:where(:hover, :focus, [aria-expanded="true"]) > .navds-help-text__icon--filled {
.navds-help-text__button:where(:hover, :focus-visible, [aria-expanded="true"]) > .navds-help-text__icon--filled {
display: inherit;
}
@supports not selector(:focus-visible) {
.navds-help-text__button:where(:focus) > .navds-help-text__icon {
display: none;
}
.navds-help-text__button:where(:focus) > .navds-help-text__icon--filled {
display: inherit;
}
}
+1
View File
@@ -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";
+8 -1
View File
@@ -17,11 +17,18 @@
border-color: var(--ac-link-panel-hover-border, var(--a-border-action));
}
.navds-link-panel:focus {
.navds-link-panel:focus-visible {
box-shadow: var(--a-shadow-focus);
outline: none;
}
@supports not selector(:focus-visible) {
.navds-link-panel:focus {
box-shadow: var(--a-shadow-focus);
outline: none;
}
}
.navds-link-panel__chevron {
flex-shrink: 0;
font-size: 1.5rem;
+11 -1
View File
@@ -15,7 +15,7 @@
text-decoration: none;
}
.navds-link:focus {
.navds-link:focus-visible {
outline: none;
color: var(--ac-link-focus-text, var(--a-text-on-action));
text-decoration: none;
@@ -23,6 +23,16 @@
box-shadow: 0 0 0 2px var(--ac-link-focus-border, var(--a-border-focus));
}
@supports not selector(:focus-visible) {
.navds-link:focus {
outline: none;
color: var(--ac-link-focus-text, var(--a-text-on-action));
text-decoration: none;
background-color: var(--ac-link-focus-bg, var(--a-border-focus));
box-shadow: 0 0 0 2px var(--ac-link-focus-border, var(--a-border-focus));
}
}
.navds-link:active {
outline: none;
color: var(--ac-link-active-text, var(--a-text-on-action));
+9 -1
View File
@@ -15,12 +15,20 @@
padding: var(--a-spacing-4);
}
.navds-modal:focus,
.navds-modal:focus-visible,
.navds-modal--focus {
box-shadow: var(--a-shadow-focus);
outline: none;
}
@supports not selector(:focus-visible) {
.navds-modal:focus,
.navds-modal--focus {
box-shadow: var(--a-shadow-focus);
outline: none;
}
}
.navds-modal__overlay {
position: fixed;
z-index: var(--a-z-index-modal);
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-css",
"version": "3.0.1",
"version": "3.2.0",
"description": "CSS for NAV Designsystem",
"author": "Aksel | NAV designsystem team",
"keywords": [
@@ -27,7 +27,7 @@
"css:get-version": "node config/get-version.js"
},
"devDependencies": {
"@navikt/ds-tokens": "^3.0.1",
"@navikt/ds-tokens": "^3.2.0",
"cssnano": "6.0.0",
"fast-glob": "3.2.11",
"lodash": "4.17.21",
+7 -1
View File
@@ -35,10 +35,16 @@
color: var(--ac-pagination-selected-text, var(--a-text-on-action));
}
.navds-pagination__item[aria-current="true"]:focus {
.navds-pagination__item[aria-current="true"]:focus-visible {
box-shadow: inset 0 0 0 1px var(--a-surface-default), var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-pagination__item[aria-current="true"]:focus {
box-shadow: inset 0 0 0 1px var(--a-surface-default), var(--a-shadow-focus);
}
}
.navds-pagination__prev-next {
display: flex;
align-items: center;
+8 -1
View File
@@ -15,11 +15,18 @@
display: none;
}
.navds-popover:focus {
.navds-popover:focus-visible {
outline: none;
box-shadow: var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-popover:focus {
outline: none;
box-shadow: var(--a-shadow-focus);
}
}
.navds-popover__arrow {
position: absolute;
z-index: -1;
+8 -1
View File
@@ -24,11 +24,18 @@
background-color: var(--ac-read-more-active-bg, var(--a-surface-active));
}
.navds-read-more__button:focus {
.navds-read-more__button:focus-visible {
outline: none;
box-shadow: var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-read-more__button:focus {
outline: none;
box-shadow: var(--a-shadow-focus);
}
}
.navds-read-more__content {
margin-top: var(--a-spacing-1);
border-left: 2px solid var(--ac-read-more-line, var(--a-border-divider));
+9 -1
View File
@@ -80,12 +80,20 @@ button.navds-stepper__step {
cursor: default;
}
:where(.navds-stepper__step):focus {
:where(.navds-stepper__step):focus-visible {
outline: none;
box-shadow: var(--a-shadow-focus);
isolation: isolate;
}
@supports not selector(:focus-visible) {
.navds-stepper__step:focus {
outline: none;
box-shadow: var(--a-shadow-focus);
isolation: isolate;
}
}
.navds-stepper__circle {
grid-column: circle;
display: inline-grid;
+15 -2
View File
@@ -119,11 +119,18 @@
background-color: var(--ac-table-sort-button-hover-bg, var(--a-bg-subtle));
}
.navds-table__sort-button:focus {
.navds-table__sort-button:focus-visible {
outline: none;
box-shadow: inset 0 0 0 2px var(--a-border-focus);
}
@supports not selector(:focus-visible) {
.navds-table__sort-button:focus {
outline: none;
box-shadow: inset 0 0 0 2px var(--a-border-focus);
}
}
.navds-table__header-cell[aria-sort="ascending"] .navds-table__sort-button,
.navds-table__header-cell[aria-sort="descending"] .navds-table__sort-button {
background-color: var(--ac-table-sort-button-sorted-bg, var(--a-surface-selected));
@@ -181,10 +188,16 @@
padding: var(--a-spacing-2);
}
.navds-table__toggle-expand-button:focus {
.navds-table__toggle-expand-button:focus-visible {
box-shadow: inset var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-table__toggle-expand-button:focus {
box-shadow: inset var(--a-shadow-focus);
}
}
.navds-table__expandable-icon {
font-size: 1.5rem;
}
+16 -1
View File
@@ -62,12 +62,20 @@
color: var(--ac-tabs-selected-text, var(--a-text-default));
}
.navds-tabs__tab:focus {
.navds-tabs__tab:focus-visible {
outline: none;
box-shadow: inset var(--a-shadow-focus);
color: var(--ac-tabs-focus-text, var(--a-text-default));
}
@supports not selector(:focus-visible) {
.navds-tabs__tab:focus {
outline: none;
box-shadow: inset var(--a-shadow-focus);
color: var(--ac-tabs-focus-text, var(--a-text-default));
}
}
.navds-tabs__tab-inner {
display: flex;
align-items: center;
@@ -112,3 +120,10 @@
outline: none;
box-shadow: inset 0 0 0 2px var(--a-border-focus);
}
@supports not selector(:focus-visible) {
.navds-tabs__tabpanel:focus {
outline: none;
box-shadow: inset 0 0 0 2px var(--a-border-focus);
}
}
+47 -10
View File
@@ -5,7 +5,7 @@
}
.navds-toggle-group {
border-radius: 9px;
border-radius: var(--a-border-radius-medium);
background-color: var(--ac-toggle-group-bg, var(--a-surface-transparent));
box-shadow: inset 0 0 0 1px var(--ac-toggle-group-border, var(--a-border-default));
padding: calc(var(--a-spacing-1) + 1px);
@@ -15,6 +15,10 @@
grid-auto-columns: 1fr;
}
.navds-toggle-group--small {
padding: calc(var(--a-spacing-05) + 1px);
}
.navds-toggle-group--neutral {
background-color: var(--ac-toggle-group-neutral-bg, var(--a-surface-transparent));
box-shadow: inset 0 0 0 1px var(--ac-toggle-group-neutral-border, var(--a-border-default));
@@ -24,14 +28,25 @@
display: inline-flex;
align-items: center;
justify-content: center;
padding: var(--a-spacing-3);
min-height: 48px;
padding: var(--a-spacing-1) var(--a-spacing-3);
min-height: 38px;
border: none;
cursor: pointer;
background-color: var(--ac-toggle-group-button-bg, var(--a-surface-transparent));
color: var(--ac-toggle-group-button-text, var(--a-text-default));
border-radius: var(--a-border-radius-medium);
border-radius: 2px;
min-width: fit-content;
font-weight: var(--a-font-weight-regular);
}
.navds-toggle-group--medium > :where(.navds-toggle-group__button:first-of-type:focus-visible) {
border-start-start-radius: 1px;
border-end-start-radius: 1px;
}
.navds-toggle-group--medium > :where(.navds-toggle-group__button:last-of-type:focus-visible) {
border-start-end-radius: 1px;
border-end-end-radius: 1px;
}
.navds-toggle-group--neutral > .navds-toggle-group__button {
@@ -41,7 +56,7 @@
.navds-toggle-group__button:hover {
background-color: var(--ac-toggle-group-button-hover-bg, var(--a-surface-action-subtle));
color: var(--ac-toggle-group-button-hover-text, var(--a-text-action-on-action-subtle));
color: var(--ac-toggle-group-button-hover-text, var(--a-text-default));
}
.navds-toggle-group--neutral > .navds-toggle-group__button:hover {
@@ -49,24 +64,45 @@
color: var(--ac-toggle-group-button-neutral-hover-text, var(--a-text-default));
}
.navds-toggle-group__button:focus {
.navds-toggle-group__button:focus-visible {
outline: none;
box-shadow: 0 0 0 1px var(--a-surface-default), 0 0 0 4px var(--a-border-focus);
}
.navds-toggle-group__button:focus:hover[aria-pressed="false"] {
@supports not selector(:focus-visible) {
.navds-toggle-group__button:focus {
outline: none;
box-shadow: 0 0 0 1px var(--a-surface-default), 0 0 0 4px var(--a-border-focus);
}
}
.navds-toggle-group__button:focus-visible:hover[aria-pressed="false"] {
box-shadow: 0 0 0 1px var(--ac-toggle-group-button-hover-bg, var(--a-surface-action-subtle)), 0 0 0 4px var(--a-border-focus);
}
@supports not selector(:focus-visible) {
.navds-toggle-group__button:focus:hover[aria-pressed="false"] {
box-shadow: 0 0 0 1px var(--ac-toggle-group-button-hover-bg, var(--a-surface-action-subtle)), 0 0 0 4px var(--a-border-focus);
}
}
.navds-toggle-group--neutral > .navds-toggle-group__button:focus:hover[aria-pressed="false"] {
box-shadow: 0 0 0 1px var(--ac-toggle-group-button-neutral-hover-bg, var(--a-surface-neutral-subtle-hover)),
0 0 0 4px var(--a-border-focus);
}
@supports not selector(:focus-visible) {
.navds-toggle-group--neutral > .navds-toggle-group__button:focus-visible:hover[aria-pressed="false"] {
box-shadow: 0 0 0 1px var(--ac-toggle-group-button-neutral-hover-bg, var(--a-surface-neutral-subtle-hover)),
0 0 0 4px var(--a-border-focus);
}
}
.navds-toggle-group__button-inner {
display: flex;
align-items: center;
gap: var(--a-spacing-2);
font-weight: inherit;
}
.navds-toggle-group__button-inner > * {
@@ -77,17 +113,18 @@
.navds-toggle-group__button[aria-checked="true"] {
background-color: var(--ac-toggle-group-selected-bg, var(--a-surface-action-selected));
color: var(--ac-toggle-group-selected-text, var(--a-text-on-action));
font-weight: var(--a-font-weight-bold);
}
.navds-toggle-group--neutral > .navds-toggle-group__button[aria-pressed="true"],
.navds-toggle-group--neutral > .navds-toggle-group__button[aria-checked="true"] {
background-color: var(--ac-toggle-group-neutral-selected-bg, var(--a-surface-neutral));
background-color: var(--ac-toggle-group-neutral-selected-bg, var(--a-surface-neutral-selected));
color: var(--ac-toggle-group-neutral-selected-text, var(--a-text-on-neutral));
}
.navds-toggle-group--small > .navds-toggle-group__button {
padding: 0.375rem;
min-height: 32px;
padding: var(--a-spacing-05) var(--a-spacing-3);
min-height: 26px;
min-width: fit-content;
}
+16 -2
View File
@@ -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",
"--ac-copybutton-action-hover-bg": "--a-surface-hover",
"--ac-copybutton-action-active-text": "--a-icon-success",
"--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-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",
@@ -277,14 +291,14 @@
"--ac-toggle-group-button-bg": "--a-surface-transparent",
"--ac-toggle-group-button-text": "--a-text-default",
"--ac-toggle-group-button-hover-bg": "--a-surface-action-subtle",
"--ac-toggle-group-button-hover-text": "--a-text-action-on-action-subtle",
"--ac-toggle-group-button-hover-text": "--a-text-default",
"--ac-toggle-group-selected-bg": "--a-surface-action-selected",
"--ac-toggle-group-selected-text": "--a-text-on-action",
"--ac-toggle-group-button-neutral-bg": "--a-surface-transparent",
"--ac-toggle-group-button-neutral-text": "--a-text-default",
"--ac-toggle-group-button-neutral-hover-bg": "--a-surface-neutral-subtle-hover",
"--ac-toggle-group-button-neutral-hover-text": "--a-text-default",
"--ac-toggle-group-neutral-selected-bg": "--a-surface-neutral",
"--ac-toggle-group-neutral-selected-bg": "--a-surface-neutral-selected",
"--ac-toggle-group-neutral-selected-text": "--a-text-on-neutral"
},
"tooltip": {
+49
View File
@@ -1,5 +1,54 @@
# @navikt/ds-react
## 3.2.0
### Minor Changes
- [#1982](https://github.com/navikt/aksel/pull/1982) [`affcab14c`](https://github.com/navikt/aksel/commit/affcab14c3d536929dfa64a36f5b43f9d0e8c3b7) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :sparkles: Ny komponent `<CopyButton />`!
- Erstatter `<CopyToClipboard />` fra `@navikt/ds-react-internal`
- CopyToClipboard er markert som deprecated. Den vil fortsatt fungere, men noen lintere vil kunne ende opp med å klage på den.
### Patch Changes
- Updated dependencies []:
- @navikt/aksel-icons@3.2.0
## 3.1.3
### Patch Changes
- [#1976](https://github.com/navikt/aksel/pull/1976) [`e8ecf309a`](https://github.com/navikt/aksel/commit/e8ecf309a910e47fd3cea6c54cd993ab1196910f) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :lipstick: Oppdatert utseende for ToggleGroup
- Medium og Small er begge 10px lavere
- Mindre border-radius
- Updated dependencies []:
- @navikt/aksel-icons@3.1.3
## 3.1.2
### Patch Changes
- Updated dependencies []:
- @navikt/aksel-icons@3.1.2
## 3.1.1
### Patch Changes
- Updated dependencies []:
- @navikt/aksel-icons@3.1.1
## 3.1.0
### Patch Changes
- [#1967](https://github.com/navikt/aksel/pull/1967) [`9d2cd9e7f`](https://github.com/navikt/aksel/commit/9d2cd9e7fffb3cf6310c88229ee39ea85db19bca) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :lipstick: Oppdatert Label og Description spacing for skjemakomponenter
- Updated dependencies []:
- @navikt/aksel-icons@3.1.0
## 3.0.1
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-react",
"version": "3.0.1",
"version": "3.2.0",
"description": "Aksel react-components for NAV designsystem",
"author": "Aksel | NAV designsystem team",
"license": "MIT",
@@ -38,7 +38,7 @@
},
"dependencies": {
"@floating-ui/react": "0.17.0",
"@navikt/aksel-icons": "^3.0.1",
"@navikt/aksel-icons": "^3.2.0",
"@radix-ui/react-tabs": "1.0.0",
"@radix-ui/react-toggle-group": "1.0.0",
"clsx": "^1.2.1",
@@ -0,0 +1,174 @@
"use client";
import { CheckmarkIcon, FilesIcon } from "@navikt/aksel-icons";
import cl from "clsx";
import React, {
ButtonHTMLAttributes,
forwardRef,
useEffect,
useRef,
useState,
} from "react";
import copy from "../util/copy";
import Label from "../typography/Label";
export interface CopyButtonProps
extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
/**
* @default "medium"
*/
size?: "medium" | "small";
/**
* @default "neutral"
*/
variant?: "action" | "neutral";
/**
* Text to copy to clipboard
*/
copyText: string;
/**
* Optional text in button
*/
text?: string;
/**
* Text shown when button is clicked
* Only set if used with 'text'-prop
*/
activeText?: string;
/**
* Callback when 'copied'-state is active
*/
onActiveChange?: (state: boolean) => void;
/**
* Icon shown when button is not clicked
* @default <FilesIcon />
*/
icon?: React.ReactNode;
/**
* Icon shown when active
* @default <CheckmarkIcon />
*/
activeIcon?: React.ReactNode;
/**
* Timeout duration in milliseconds
* @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<HTMLButtonElement, CopyButtonProps>(
(
{
className,
copyText,
text,
activeText = "Kopiert!",
variant = "neutral",
size = "medium",
onActiveChange,
icon,
activeIcon,
activeDuration = 2000,
title = "Kopier",
activeTitle = "Kopiert",
...rest
},
ref
) => {
const [active, setActive] = useState(false);
const timeoutRef = useRef<number>();
useEffect(() => {
return () => {
timeoutRef.current && clearTimeout(timeoutRef.current);
};
}, []);
const handleClick = (
event: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
timeoutRef.current && clearTimeout(timeoutRef.current);
copy(copyText);
setActive(true);
onActiveChange?.(true);
rest.onClick?.(event);
timeoutRef.current = window.setTimeout(() => {
setActive(false);
onActiveChange?.(false);
}, activeDuration);
};
return (
<button
ref={ref}
type="button"
{...rest}
aria-live="polite"
className={cl(
"navds-copybutton",
className,
`navds-copybutton--${size}`,
`navds-copybutton--${variant}`,
{
"navds-copybutton--icon-only": !text,
"navds-copybutton--active": active,
}
)}
onClick={handleClick}
>
<span className="navds-copybutton__content">
{active ? (
<span className="navds-copybutton__icon">
{activeIcon ?? (
<CheckmarkIcon
aria-hidden={!!text}
title={text ? undefined : activeTitle}
/>
)}
</span>
) : (
<span className="navds-copybutton__icon">
{icon ?? (
<FilesIcon
aria-hidden={!!text}
title={text ? undefined : title}
/>
)}
</span>
)}
{text &&
(active ? (
<Label
as="span"
size={size === "medium" ? "medium" : "small"}
aria-live="polite"
>
{activeText}
</Label>
) : (
<Label
as="span"
size={size === "medium" ? "medium" : "small"}
aria-live="polite"
>
{text}
</Label>
))}
</span>
</button>
);
}
);
export default CopyButton;
@@ -0,0 +1,168 @@
import { LinkIcon, ThumbUpIcon } from "@navikt/aksel-icons";
import { userEvent, within } from "@storybook/testing-library";
import React from "react";
import { CopyButton } from ".";
import { Tooltip } from "../tooltip";
export default {
title: "ds-react/CopyButton",
component: CopyButton,
argTypes: {
size: {
defaultValue: "medium",
control: { type: "radio" },
options: ["small", "medium"],
},
variant: {
defaultValue: undefined,
control: { type: "radio" },
options: ["neutral", "action"],
},
},
};
export const Default = {
render: (args) => <CopyButton {...args} />,
args: {
size: "medium",
duration: 2000,
copyText: "3.14",
text: "",
activeText: "",
},
};
export const Interaction = {
render: () => (
<CopyButton
copyText="3.14"
variant="action"
text="Kopier"
data-testid="copy-button"
/>
),
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const button = canvas.getByTestId("copy-button");
userEvent.click(button);
},
};
export const Variants = {
render: () => (
<div className="colgap">
<CopyButton copyText="3.14" variant="action" text="Kopier" />
<CopyButton copyText="3.14" variant="neutral" text="Kopier" />
</div>
),
};
export const Sizes = {
render: () => (
<div className="colgap">
<div className="rowgap">
<CopyButton copyText="3.14" variant="action" />
<CopyButton copyText="3.14" variant="neutral" />
<CopyButton copyText="3.14" variant="action" text="Kopier" />
<CopyButton copyText="3.14" variant="neutral" text="Kopier" />
</div>
<div className="rowgap">
<CopyButton size="small" copyText="3.14" variant="action" />
<CopyButton size="small" copyText="3.14" variant="neutral" />
<CopyButton
size="small"
copyText="3.14"
variant="action"
text="Kopier"
/>
<CopyButton
size="small"
copyText="3.14"
variant="neutral"
text="Kopier"
/>
</div>
</div>
),
};
export const Texts = {
render: () => (
<div className="colgap">
<div>
<CopyButton
copyText="3.14"
text="Kopier XYZ"
activeText="Kopierte XYZ"
/>
</div>
<div>
<CopyButton
copyText="3.14"
size="small"
text="Kopier XYZ"
activeText="Kopierte XYZ"
/>
</div>
</div>
),
};
export const Icons = {
render: () => (
<div className="rowgap">
<div>
<CopyButton
copyText="3.14"
icon={<LinkIcon title="Kopier" />}
activeIcon={<ThumbUpIcon title="Kopiert" />}
/>
</div>
<div>
<CopyButton
copyText="3.14"
size="small"
icon={<LinkIcon title="Kopier" />}
activeIcon={<ThumbUpIcon title="Kopiert" />}
/>
</div>
</div>
),
};
export const InlineDemo = {
render: () => (
<div style={{ display: "flex", gap: "0.5rem", alignItems: "center" }}>
<CopyButton size="small" copyText="3.14" /> Kopier dette feltet
</div>
),
};
export const WithTooltip = {
render: () => {
return (
<div>
<Tooltip content="Kopier fødselsnummer">
<CopyButton copyText="3.14" />
</Tooltip>
</div>
);
},
};
export const Duration = {
render: () => <CopyButton copyText="3.14" activeDuration={300} />,
};
export const Disabled = {
render: () => (
<div className="colgap">
<CopyButton copyText="3.14" disabled />
<CopyButton copyText="3.14" size="small" disabled />
<CopyButton copyText="3.14" disabled variant="action" />
</div>
),
};
@@ -0,0 +1 @@
export { default as CopyButton, type CopyButtonProps } from "./CopyButton";
@@ -46,17 +46,20 @@ interface ExpansionCardCommonProps
* @default "medium"
*/
size?: "medium" | "small";
/**
* Since ExpansionCard is a section-element, accessible name is required.
*/
}
type ExpansionCardConditionalProps =
| {
["aria-label"]: string;
/**
* Should be set if not using 'aria-labelledby'
*/
"aria-label": string;
}
| {
["aria-labelledby"]: string;
/**
* Should be set if not using 'aria-label'
*/
"aria-labelledby": string;
};
export type ExpansionCardContextProps = {
@@ -1,6 +1,6 @@
import cl from "clsx";
import React, { FieldsetHTMLAttributes, forwardRef, useContext } from "react";
import { BodyLong, Detail, Label, ErrorMessage, omit } from "../..";
import { BodyShort, ErrorMessage, Label, omit } from "../..";
import { FormFieldProps } from "../useFormField";
import { useFieldset } from "./useFieldset";
@@ -104,30 +104,18 @@ export const Fieldset = forwardRef<HTMLFieldSetElement, FieldsetProps>(
>
{legend}
</Label>
{!!description &&
(size === "medium" ? (
<BodyLong
className={cl("navds-fieldset__description", {
"navds-sr-only": !!hideLegend,
})}
id={inputDescriptionId}
size="small"
as="div"
>
{props.description}
</BodyLong>
) : (
<Detail
className={cl("navds-fieldset__description", {
"navds-sr-only": !!hideLegend,
})}
id={inputDescriptionId}
size="small"
as="div"
>
{props.description}
</Detail>
))}
{!!description && (
<BodyShort
className={cl("navds-fieldset__description", {
"navds-sr-only": !!hideLegend,
})}
id={inputDescriptionId}
size={size ?? "medium"}
as="div"
>
{props.description}
</BodyShort>
)}
{children}
<div
id={errorId}
+12 -27
View File
@@ -1,8 +1,8 @@
import React, { forwardRef, SelectHTMLAttributes } from "react";
import cl from "clsx";
import React, { forwardRef, SelectHTMLAttributes } from "react";
import { ChevronDownIcon } from "@navikt/aksel-icons";
import { BodyLong, Label, ErrorMessage, omit, Detail } from "..";
import { BodyShort, ErrorMessage, Label, omit } from "..";
import { FormFieldProps, useFormField } from "./useFormField";
export interface SelectProps
@@ -74,31 +74,16 @@ export const Select = forwardRef<HTMLSelectElement, SelectProps>(
{label}
</Label>
{!!description && (
<>
{size === "medium" ? (
<BodyLong
className={cl("navds-form-field__description", {
"navds-sr-only": hideLabel,
})}
id={inputDescriptionId}
size="small"
as="div"
>
{description}
</BodyLong>
) : (
<Detail
className={cl("navds-form-field__description", {
"navds-sr-only": hideLabel,
})}
id={inputDescriptionId}
size="small"
as="div"
>
{description}
</Detail>
)}
</>
<BodyShort
className={cl("navds-form-field__description", {
"navds-sr-only": hideLabel,
})}
id={inputDescriptionId}
size={size}
as="div"
>
{description}
</BodyShort>
)}
<div className="navds-select__container" style={style}>
<select
+5 -7
View File
@@ -5,7 +5,7 @@ import React, {
useEffect,
useState,
} from "react";
import { BodyShort, Detail, Loader, omit } from "..";
import { BodyShort, Loader, omit } from "..";
import { FormFieldProps, useFormField } from "./useFormField";
const SelectedIcon = () => (
@@ -71,8 +71,6 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
...rest
} = props;
const Description = size === "medium" ? BodyShort : Detail;
const [checked, setChecked] = useState(
defaultChecked ?? checkedProp ?? false
);
@@ -130,13 +128,13 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
{children}
</BodyShort>
{description && (
<Description
<BodyShort
size={size}
as="div"
size="small"
className="navds-switch__description"
className="navds-form-field__subdescription navds-switch__description"
>
{description}
</Description>
</BodyShort>
)}
</div>
</label>
+12 -27
View File
@@ -1,6 +1,6 @@
import React, { forwardRef, InputHTMLAttributes } from "react";
import cl from "clsx";
import { BodyLong, Detail, Label, ErrorMessage, omit } from "..";
import React, { forwardRef, InputHTMLAttributes } from "react";
import { BodyShort, ErrorMessage, Label, omit } from "..";
import { FormFieldProps, useFormField } from "./useFormField";
export interface TextFieldProps
@@ -78,31 +78,16 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
</Label>
{!!description && (
<>
{size === "medium" ? (
<BodyLong
className={cl("navds-form-field__description", {
"navds-sr-only": hideLabel,
})}
id={inputDescriptionId}
size="small"
as="div"
>
{description}
</BodyLong>
) : (
<Detail
className={cl("navds-form-field__description", {
"navds-sr-only": hideLabel,
})}
id={inputDescriptionId}
size="small"
as="div"
>
{description}
</Detail>
)}
</>
<BodyShort
className={cl("navds-form-field__description", {
"navds-sr-only": hideLabel,
})}
id={inputDescriptionId}
size={size}
as="div"
>
{description}
</BodyShort>
)}
<input
{...omit(rest, ["error", "errorId", "size"])}
+13 -29
View File
@@ -1,9 +1,8 @@
import React, { forwardRef, useState } from "react";
import cl from "clsx";
import { BodyShort, BodyLong, Label, ErrorMessage, omit, Detail } from "..";
import { FormFieldProps, useFormField } from "./useFormField";
import { useId } from "..";
import React, { forwardRef, useState } from "react";
import { BodyShort, ErrorMessage, Label, omit, useId } from "..";
import TextareaAutosize from "../util/TextareaAutoSize";
import { FormFieldProps, useFormField } from "./useFormField";
/**
* TODO: Mulighet for lokalisering av sr-only/counter text
@@ -120,31 +119,16 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
{label}
</Label>
{!!description && (
<>
{size === "medium" ? (
<BodyLong
className={cl("navds-form-field__description", {
"navds-sr-only": hideLabel,
})}
id={inputDescriptionId}
size="small"
as="div"
>
{description}
</BodyLong>
) : (
<Detail
className={cl("navds-form-field__description", {
"navds-sr-only": hideLabel,
})}
id={inputDescriptionId}
size="small"
as="div"
>
{description}
</Detail>
)}
</>
<BodyShort
className={cl("navds-form-field__description", {
"navds-sr-only": hideLabel,
})}
id={inputDescriptionId}
size={size}
as="div"
>
{description}
</BodyShort>
)}
<div className="navds-textarea__wrapper">
<TextareaAutosize
@@ -1,6 +1,6 @@
import cl from "clsx";
import React, { forwardRef, InputHTMLAttributes } from "react";
import { BodyLong, BodyShort, Detail } from "../../typography";
import { BodyShort } from "../../typography";
import { omit } from "../../util";
import { FormFieldProps } from "../useFormField";
import useCheckbox from "./useCheckbox";
@@ -44,8 +44,6 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
(props, ref) => {
const { inputProps, hasError, size } = useCheckbox(props);
const Description = size === "medium" ? BodyLong : Detail;
return (
<div
className={cl(
@@ -94,9 +92,13 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
{props.children}
</BodyShort>
{props.description && (
<Description as="span" className="navds-checkbox__description">
<BodyShort
as="span"
size={size}
className="navds-form-field__subdescription navds-checkbox__description"
>
{props.description}
</Description>
</BodyShort>
)}
</span>
</label>
+7 -5
View File
@@ -1,6 +1,6 @@
import cl from "clsx";
import React, { forwardRef, InputHTMLAttributes } from "react";
import { BodyLong, BodyShort, Detail } from "../../typography";
import { BodyShort } from "../../typography";
import { omit } from "../../util";
import { FormFieldProps } from "../useFormField";
import { useRadio } from "./useRadio";
@@ -25,8 +25,6 @@ export interface RadioProps
export const Radio = forwardRef<HTMLInputElement, RadioProps>((props, ref) => {
const { inputProps, size, hasError } = useRadio(props);
const Description = size === "medium" ? BodyLong : Detail;
return (
<div
className={cl(props.className, "navds-radio", `navds-radio--${size}`, {
@@ -46,9 +44,13 @@ export const Radio = forwardRef<HTMLInputElement, RadioProps>((props, ref) => {
{props.children}
</BodyShort>
{props.description && (
<Description as="span" className="navds-radio__description">
<BodyShort
as="span"
size={size}
className="navds-form-field__subdescription navds-radio__description"
>
{props.description}
</Description>
</BodyShort>
)}
</span>
</label>
@@ -86,7 +86,9 @@ export const GroupDescription = () => (
defaultValue="tekst2"
description="Group description"
>
<Radio value="tekst">Radiotekst</Radio>
<Radio value="tekst" description="textdesc">
Radiotekst
</Radio>
<Radio value="tekst2">Radiotekst</Radio>
</RadioGroup>
);
@@ -181,12 +181,12 @@ export const Search = forwardRef<HTMLInputElement, SearchProps>(
</Label>
{!!description && (
<BodyShort
as="div"
className={cl("navds-form-field__description", {
"navds-sr-only": hideLabel,
})}
id={inputDescriptionId}
size={size}
as="div"
>
{description}
</BodyShort>
+2 -1
View File
@@ -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";
@@ -1,6 +1,6 @@
import React, { forwardRef, useContext } from "react";
import cl from "clsx";
import { Label } from "..";
import { BodyShort } from "../typography/BodyShort";
import * as RadixToggleGroup from "@radix-ui/react-toggle-group";
import { ToggleGroupContext } from "./ToggleGroup";
@@ -30,13 +30,13 @@ const ToggleItem = forwardRef<HTMLButtonElement, ToggleItemProps>(
ref={ref}
className={cl("navds-toggle-group__button", className)}
>
<Label
<BodyShort
as="span"
className="navds-toggle-group__button-inner"
size={context?.size}
>
{children}
</Label>
</BodyShort>
</RadixToggleGroup.Item>
);
}
+81
View File
@@ -0,0 +1,81 @@
// https://github.com/sudodoki/copy-to-clipboard/blob/main/index.js
const defaultMessage = "Kopier til utklippstavle: #{key}, Enter";
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();
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.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.webkitUserSelect = "text";
mark.style.MozUserSelect = "text";
mark.style.msUserSelect = "text";
mark.style.userSelect = "text";
mark.addEventListener("copy", function (e) {
e.stopPropagation();
});
document.body.appendChild(mark);
range.selectNodeContents(mark);
selection.addRange(range);
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);
} else {
selection.removeAllRanges();
}
}
if (mark) {
document.body.removeChild(mark);
}
}
return success;
}
+10
View File
@@ -1,5 +1,15 @@
# @navikt/ds-tailwind
## 3.2.0
## 3.1.3
## 3.1.2
## 3.1.1
## 3.1.0
## 3.0.1
## 3.0.0
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-tailwind",
"version": "3.0.1",
"version": "3.2.0",
"description": "Tailwind config based on @navikt/ds-tokens",
"author": "Aksel | NAV designsystem team",
"keywords": [
@@ -22,7 +22,7 @@
"directory": "@navikt/core/tailwind"
},
"devDependencies": {
"@navikt/ds-tokens": "^3.0.1",
"@navikt/ds-tokens": "^3.2.0",
"@types/jest": "^29.0.0",
"color": "4.2.3",
"jest": "^29.0.0",
+10
View File
@@ -1,5 +1,15 @@
# @navikt/ds-tokens
## 3.2.0
## 3.1.3
## 3.1.2
## 3.1.1
## 3.1.0
## 3.0.1
## 3.0.0
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-tokens",
"version": "3.0.1",
"version": "3.2.0",
"description": "Design-tokens for NAV designsystem",
"author": "Aksel | NAV designsystem team",
"keywords": [
+10
View File
@@ -1,5 +1,15 @@
# @navikt/ds-icons
## 3.2.0
## 3.1.3
## 3.1.2
## 3.1.1
## 3.1.0
## 3.0.1
## 3.0.0
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-icons",
"version": "3.0.1",
"version": "3.2.0",
"description": "Aksel icons for NAV",
"author": "Aksel | NAV designsystem team",
"repository": {
+23
View File
@@ -1,5 +1,28 @@
# @navikt/ds-css-internal
## 3.2.0
## 3.1.3
## 3.1.2
### Patch Changes
- [`5e79234ef`](https://github.com/navikt/aksel/commit/5e79234effb8c8fc73c9bb0c34737e99fab1510b) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Fikset pin alignment for Timeline
## 3.1.1
### Patch Changes
- [`14379a02c`](https://github.com/navikt/aksel/commit/14379a02c3d32091a8c33061464160d7de9f3f2e) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Timeline håndterte ikke SVG ikoner riktig
## 3.1.0
### Minor Changes
- [#1966](https://github.com/navikt/aksel/pull/1966) [`f1c4c46eb`](https://github.com/navikt/aksel/commit/f1c4c46ebb0522561483f18e3b86b190cf9cc372) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :lipstick: Alle komponenter bruker nå default `:focus-visible` for fokusmarkering.
(Alle komponenter som bruker `:focus-visible` har også en fallback for `:focus`)
## 3.0.1
## 3.0.0
+7
View File
@@ -63,6 +63,13 @@
box-shadow: inset 0 0 0 2px var(--a-border-focus);
}
@supports not selector(:focus-visible) {
.navdsi-dropdown__item:focus {
outline: none;
box-shadow: inset 0 0 0 2px var(--a-border-focus);
}
}
.navdsi-dropdown__item:disabled {
color: var(--ac-dropdown-item-text, var(--a-text-action));
opacity: 0.3;
+10 -2
View File
@@ -59,12 +59,20 @@ button.navdsi-header__title:hover,
background-color: var(--ac-header-hover-bg, var(--a-surface-inverted-hover));
}
.navdsi-header__title:focus,
.navdsi-header__button:focus {
.navdsi-header__title:focus-visible,
.navdsi-header__button:focus-visible {
box-shadow: var(--navdsi-header-focus);
outline: none;
}
@supports not selector(:focus-visible) {
.navdsi-header__title:focus,
.navdsi-header__button:focus {
box-shadow: var(--navdsi-header-focus);
outline: none;
}
}
a.navdsi-header__title:active,
button.navdsi-header__title:active,
.navdsi-header__button:active {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-css-internal",
"version": "3.0.1",
"version": "3.2.0",
"description": "CSS for NAV internal Designsystem-components",
"author": "Aksel | NAV designsystem team",
"keywords": [
+49 -8
View File
@@ -12,7 +12,6 @@
height: 1rem;
box-sizing: content-box;
grid-column: 2;
margin-left: var(--a-spacing-8);
}
.navdsi-timeline__row-label {
@@ -40,7 +39,6 @@
display: flex;
background: var(--ac-timeline-row-bg, var(--a-surface-subtle));
margin: var(--a-spacing-4) 0;
padding-left: var(--a-spacing-8);
grid-column: 2;
}
@@ -85,6 +83,10 @@
align-items: center;
}
.navdsi-timeline__period--inner svg {
flex-shrink: 0;
}
.navdsi-timeline__period--clickable {
cursor: pointer;
}
@@ -190,7 +192,7 @@
top: calc(-12.5px + 3.5px);
}
.navdsi-timeline__pin-button:focus {
.navdsi-timeline__pin-button:focus-visible {
box-shadow: inset 0 0 0 1px var(--ac-timeline-pin-bg, var(--a-surface-danger)),
0 0 0 3px var(--ac-timeline-pin-bg, var(--a-surface-danger)), 0 0 0 4px var(--a-surface-default),
0 0 0 6px var(--a-border-focus);
@@ -202,12 +204,27 @@
0 0 0 4px var(--ac-timeline-pin-bg-hover, var(--a-surface-danger-hover)), 0 0 0 5px var(--a-surface-default);
}
.navdsi-timeline__pin-button:hover:focus {
.navdsi-timeline__pin-button:hover:focus-visible {
box-shadow: inset 0 0 0 1px var(--ac-timeline-pin-bg-hover, var(--a-surface-danger-hover)),
0 0 0 3px var(--ac-timeline-pin-bg-hover, var(--a-surface-danger-hover)), 0 0 0 4px var(--a-surface-default),
0 0 0 6px var(--a-border-focus);
}
@supports not selector(:focus-visible) {
.navdsi-timeline__pin-button:focus {
box-shadow: inset 0 0 0 1px var(--ac-timeline-pin-bg, var(--a-surface-danger)),
0 0 0 3px var(--ac-timeline-pin-bg, var(--a-surface-danger)), 0 0 0 4px var(--a-surface-default),
0 0 0 6px var(--a-border-focus);
outline: none;
}
.navdsi-timeline__pin-button:hover:focus {
box-shadow: inset 0 0 0 1px var(--ac-timeline-pin-bg-hover, var(--a-surface-danger-hover)),
0 0 0 3px var(--ac-timeline-pin-bg-hover, var(--a-surface-danger-hover)), 0 0 0 4px var(--a-surface-default),
0 0 0 6px var(--a-border-focus);
}
}
.navdsi-timeline__pin-wrapper::before {
content: "";
top: var(--navdsc-timeline-pin-size);
@@ -255,13 +272,13 @@
color: var(--ac-timeline-zoom-selected-text, var(--a-text-on-inverted));
}
.navdsi-timeline__period:focus {
.navdsi-timeline__period:focus-visible {
outline: none;
z-index: 4;
box-shadow: 0 0 0 2px var(--a-border-focus);
}
.navdsi-timeline__period--selected:focus {
.navdsi-timeline__period--selected:focus-visible {
box-shadow: inset 0 0 0 2px var(--ac-timeline-period-selected-border, var(--a-border-action-selected)),
0 0 0 2px var(--a-border-focus);
z-index: 3;
@@ -271,12 +288,36 @@
z-index: var(--a-z-index-focus);
}
.navdsi-timeline__zoom-button:focus {
.navdsi-timeline__zoom-button:focus-visible {
box-shadow: 0 0 0 1px var(--a-surface-default), 0 0 0 3px var(--a-border-focus);
border-width: 1px;
}
.navdsi-timeline__zoom li:not(:last-child) .navdsi-timeline__zoom-button:focus {
.navdsi-timeline__zoom li:not(:last-child) .navdsi-timeline__zoom-button:focus-visible {
margin-right: 2px;
padding-right: 6px;
}
@supports not selector(:focus-visible) {
.navdsi-timeline__period:focus {
outline: none;
z-index: 4;
box-shadow: 0 0 0 2px var(--a-border-focus);
}
.navdsi-timeline__period--selected:focus {
box-shadow: inset 0 0 0 2px var(--ac-timeline-period-selected-border, var(--a-border-action-selected)),
0 0 0 2px var(--a-border-focus);
z-index: 3;
}
.navdsi-timeline__zoom-button:focus {
box-shadow: 0 0 0 1px var(--a-surface-default), 0 0 0 3px var(--a-border-focus);
border-width: 1px;
}
.navdsi-timeline__zoom li:not(:last-child) .navdsi-timeline__zoom-button:focus {
margin-right: 2px;
padding-right: 6px;
}
}
+49
View File
@@ -1,5 +1,54 @@
# @navikt/ds-react-internal
## 3.2.0
### Minor Changes
- [#1982](https://github.com/navikt/aksel/pull/1982) [`affcab14c`](https://github.com/navikt/aksel/commit/affcab14c3d536929dfa64a36f5b43f9d0e8c3b7) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :sparkles: Ny komponent `<CopyButton />`!
- Erstatter `<CopyToClipboard />` fra `@navikt/ds-react-internal`
- CopyToClipboard er markert som deprecated. Den vil fortsatt fungere, men noen lintere vil kunne ende opp med å klage på den.
### Patch Changes
- Updated dependencies [[`affcab14c`](https://github.com/navikt/aksel/commit/affcab14c3d536929dfa64a36f5b43f9d0e8c3b7)]:
- @navikt/ds-react@3.2.0
- @navikt/aksel-icons@3.2.0
## 3.1.3
### Patch Changes
- Updated dependencies [[`e8ecf309a`](https://github.com/navikt/aksel/commit/e8ecf309a910e47fd3cea6c54cd993ab1196910f)]:
- @navikt/ds-react@3.1.3
- @navikt/aksel-icons@3.1.3
## 3.1.2
### Patch Changes
- Updated dependencies []:
- @navikt/ds-react@3.1.2
- @navikt/aksel-icons@3.1.2
## 3.1.1
### Patch Changes
- [`14379a02c`](https://github.com/navikt/aksel/commit/14379a02c3d32091a8c33061464160d7de9f3f2e) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Timeline håndterte ikke SVG ikoner riktig
- Updated dependencies []:
- @navikt/ds-react@3.1.1
- @navikt/aksel-icons@3.1.1
## 3.1.0
### Patch Changes
- Updated dependencies [[`9d2cd9e7f`](https://github.com/navikt/aksel/commit/9d2cd9e7fffb3cf6310c88229ee39ea85db19bca)]:
- @navikt/ds-react@3.1.0
- @navikt/aksel-icons@3.1.0
## 3.0.1
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-react-internal",
"version": "3.0.1",
"version": "3.2.0",
"description": "Aksel react components for internal UIs in NAV",
"author": "Aksel | NAV designsystem team",
"license": "MIT",
@@ -36,8 +36,8 @@
"watch": "tsc --watch -p tsconfig.esm.json"
},
"dependencies": {
"@navikt/aksel-icons": "^3.0.1",
"@navikt/ds-react": "^3.0.1",
"@navikt/aksel-icons": "^3.2.0",
"@navikt/ds-react": "^3.2.0",
"clsx": "^1.1.1",
"copy-to-clipboard": "^3.3.1"
},
@@ -10,6 +10,9 @@ import {
mergeRefs,
} from "@navikt/ds-react";
/**
* @deprecated Use import { CopyButton } from "@navikt/ds-react" instead
*/
export interface CopyToClipboardProps
extends Omit<ButtonProps, "children" | "onClick" | "variant" | "loading"> {
/**
@@ -57,6 +60,9 @@ export interface CopyToClipboardProps
variant?: "tertiary";
}
/**
* @deprecated Use <CopyButton /> instead: import { CopyButton } from "@navikt/ds-react";
*/
export const CopyToClipboard = forwardRef<
HTMLButtonElement,
CopyToClipboardProps
@@ -72,7 +72,7 @@ const ClickablePeriod = React.memo(
initiate(index);
}}
>
<div className="navdsi-timeline__period--inner">{icon}</div>
<span className="navdsi-timeline__period--inner">{icon}</span>
</button>
{children && (
<Popover
@@ -33,10 +33,12 @@ const NonClickablePeriod = ({
[direction]: `${left}%`,
}}
>
<div className="navdsi-timeline__period--inner">
<span className="navdsi-timeline__period--inner">
{icon}
<p className="sr-only">{ariaLabel(start, end, status, statusLabel)}</p>
</div>
<span className="sr-only">
{ariaLabel(start, end, status, statusLabel)}
</span>
</span>
</div>
);
};
+3 -3
View File
@@ -32,12 +32,12 @@
├── internal/react # @navikt/ds-react-internal, komponenter interne flater
├── internal/css # @navikt/ds-css-internal, css interne flater
├── aksel-icons # @navikt/aksel-icons, ikonpakke
├── icons # @navikt/ds-icons (ikke lengre i bruk)
└── codemod # @navikt/ds-codemod, migrerings-scripts
└── aksel # @navikt/aksel, kommandolinje-verktøy
aksel.nav.no/
├── website # NEXT.JS app (v13)
├── website # NEXT.JS app (v13)
└── website/sanity # Sanity CMS-app (v3)
```
## Commands
+9 -9
View File
@@ -15,15 +15,15 @@
"website"
],
"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.2.0",
"@navikt/ds-codemod": "^3.2.0",
"@navikt/ds-css": "^3.2.0",
"@navikt/ds-css-internal": "^3.2.0",
"@navikt/ds-icons": "^3.2.0",
"@navikt/ds-react": "^3.2.0",
"@navikt/ds-react-internal": "^3.2.0",
"@navikt/ds-tailwind": "^3.2.0",
"@navikt/ds-tokens": "^3.2.0"
},
"devDependencies": {
"prettier-plugin-tailwindcss": "^0.2.3"
@@ -3,9 +3,8 @@ import { TokenTableT } from "@/types";
import { ChevronDownCircleIcon } from "@navikt/aksel-icons";
import internal from "@navikt/ds-css-internal/tokens.json";
import core from "@navikt/ds-css/tokens.json";
import { BodyLong, Label, Link } from "@navikt/ds-react";
import { BodyLong, CopyButton, Label, Link } from "@navikt/ds-react";
import cl from "classnames";
import CopyButton from "components/sanity-modules/code/CopyButton";
import NextLink from "next/link";
import { useState } from "react";
@@ -53,10 +52,9 @@ const TokenTable = ({ node }: { node: TokenTableT }) => {
</tbody>
</table>
{(open || !showMore) && (
<div className="border-border-divider bg-surface-neutral-subtle relative w-full rounded-b border border-t-0 p-2">
<div className="border-border-divider bg-surface-neutral-subtle relative w-full rounded-b border border-t-0 p-2 pr-14">
<CopyButton
variant="tokentable"
content={Object.entries(tokens).reduce(
copyText={Object.entries(tokens).reduce(
(prev, cur) =>
prev +
`${cur[0]}: ${
@@ -64,6 +62,7 @@ const TokenTable = ({ node }: { node: TokenTableT }) => {
};\n`,
""
)}
className="absolute top-2 right-2 z-10"
/>
<Label size="small" as="span" spacing>
Hva er dette?
@@ -1,78 +0,0 @@
import { useRef, useState, useEffect } from "react";
import copy from "copy-to-clipboard";
import React from "react";
import cl from "clsx";
import style from "./index.module.css";
import { CheckmarkIcon, ClipboardIcon } from "@navikt/aksel-icons";
const copyCode = (content: string) =>
copy(content, {
format: "text/plain",
});
interface CopyButtonProps {
content: string;
variant?: "tokentable" | "codeblock";
}
const CopyButton = React.forwardRef<HTMLButtonElement, CopyButtonProps>(
({ content, variant = "codeblock" }, ref) => {
const [active, setActive] = useState(false);
const timeoutRef = useRef<NodeJS.Timeout>();
useEffect(() => {
return () => timeoutRef.current && clearTimeout(timeoutRef.current);
}, []);
const handleCopy = () => {
copyCode(content);
setActive(true);
timeoutRef.current && clearTimeout(timeoutRef.current);
timeoutRef.current = setTimeout(() => setActive(false), 1000);
};
return (
<button
ref={ref}
aria-live={active ? "polite" : "off"}
role={active ? "alert" : undefined}
className={cl(
style.copybutton,
"navds-body-short group/button absolute top-2 right-2 z-10 flex h-10 w-10 items-center justify-center overflow-hidden rounded backdrop-blur transition duration-75 focus:outline-none",
{
"hover:text-text-on-inverted focus-visible:shadow-focus-inverted text-3xl text-gray-100 hover:bg-white/20 ":
variant === "codeblock",
"hover:text-deepblue-800 focus-visible:shadow-focus text-text-subtle hover:bg-surface-hover text-2xl":
variant === "tokentable",
}
)}
onClick={handleCopy}
>
<span
aria-hidden={!active}
className={cl(
"absolute inset-0 grid place-content-center transition duration-300",
{
"pointer-events-none translate-y-1.5 opacity-0": !active,
}
)}
>
<CheckmarkIcon title="Kopierte kodesnutt" />
</span>
<span
aria-hidden={active}
className={cl("flex items-center transition duration-300", {
"pointer-events-none -translate-y-1.5 opacity-0": active,
"group-hover/button:opacity-100": !active,
})}
>
<ClipboardIcon title="Kopier kodesnutt" />
</span>
</button>
);
}
);
export default CopyButton;
@@ -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}
>
<CopyButton content={code.code} />
<CopyButton
data-theme="dark"
copyText={code.code}
className={cl(style.copybutton, "absolute top-2 right-2 z-10")}
/>
<Highlight
code={code.code}
language={language}
@@ -51,7 +56,7 @@ const CodeSnippet = ({
theme={undefined}
>
{({ tokens, getLineProps, getTokenProps }) => (
<pre className="text-text-on-inverted relative m-0 overflow-x-auto overflow-y-auto rounded-lg bg-[#0f172a] p-4 pr-16 font-mono">
<pre className="text-text-on-inverted relative m-0 mr-16 overflow-x-auto overflow-y-auto rounded-lg bg-[#0f172a] p-4 font-mono">
{tokens.map((line, i) => (
<div
key={i}
@@ -126,11 +126,11 @@ export const IconPage = ({ name }: { name: string }) => {
onSubmit={(e) => e.preventDefault()}
className="flex h-fit w-full items-center gap-4 py-2 px-4"
>
<div className="min-w-fit">
<div className="min-w-40">
<ToggleGroup
size="small"
value={toggle}
onChange={(v) => setToggle(v as any)}
variant="neutral"
>
<ToggleGroup.Item value="stroke">Stroke</ToggleGroup.Item>
<ToggleGroup.Item value="fill">Fill</ToggleGroup.Item>
@@ -0,0 +1,17 @@
import { CopyButton } from "@navikt/ds-react";
import { withDsExample } from "components/website-modules/examples/withDsExample";
const Example = () => {
return <CopyButton copyText="3.14" variant="action" />;
};
export default withDsExample(Example);
/* Storybook story */
export const Demo = {
render: Example,
};
export const args = {
index: 1,
};
Loaded 100 of 113 files, more files were not shown because too many files have changed in this diff. Show more