mirror of
https://github.com/navikt/aksel.git
synced 2026-10-18 11:42:02 +00:00
Compare commits
33
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea19081b71 | ||
|
|
b9da4fd716 | ||
|
|
858849d743 | ||
|
|
ae9e6235db | ||
|
|
f895555ab2 | ||
|
|
372a14b225 | ||
|
|
a82126b893 | ||
|
|
06193ae300 | ||
|
|
b6db2c4ce5 | ||
|
|
d4ee3afb12 | ||
|
|
6d6900c08b | ||
|
|
3b43ad51f9 | ||
|
|
fe4ad00462 | ||
|
|
2ea0876e50 | ||
|
|
460c9c3dbd | ||
|
|
88dc43bd50 | ||
|
|
2e476ef559 | ||
|
|
f3542d50d4 | ||
|
|
1f9a343afc | ||
|
|
f026817dd3 | ||
|
|
36190f7657 | ||
|
|
f12070842a | ||
|
|
601e1569f8 | ||
|
|
f7452d5d0d | ||
|
|
04e65c701c | ||
|
|
878ee68e5c | ||
|
|
ade48469dd | ||
|
|
cbea73abda | ||
|
|
fd2e65e790 | ||
|
|
f720562908 | ||
|
|
5dedfa104a | ||
|
|
0189bd7b4a | ||
|
|
119d699ff2 |
No files matched your search
@@ -42,7 +42,7 @@ jobs:
|
||||
yarn boot
|
||||
yarn workspace aksel.nav.no build:next
|
||||
|
||||
- name: Upload static files to NAV CDN
|
||||
- name: Upload static files to Nav CDN
|
||||
uses: nais/deploy/actions/cdn-upload/v2@master
|
||||
with:
|
||||
team: designsystem
|
||||
|
||||
@@ -74,7 +74,7 @@ jobs:
|
||||
SANITY_READ_NO_DRAFTS: ${{ secrets.SANITY_READ_NO_DRAFTS }}
|
||||
run: yarn workspace aksel.nav.no build:next
|
||||
|
||||
- name: Upload static files to NAV CDN
|
||||
- name: Upload static files to Nav CDN
|
||||
uses: nais/deploy/actions/cdn-upload/v2@master
|
||||
with:
|
||||
team: designsystem
|
||||
|
||||
@@ -78,7 +78,7 @@ jobs:
|
||||
if: steps.changesets.outputs.published == 'true'
|
||||
run: yarn zip:icons
|
||||
|
||||
- name: Upload updated icon.zip to NAV CDN
|
||||
- name: Upload updated icon.zip to Nav CDN
|
||||
if: steps.changesets.outputs.published == 'true'
|
||||
uses: nais/deploy/actions/cdn-upload/v2@master
|
||||
with:
|
||||
@@ -94,7 +94,7 @@ jobs:
|
||||
echo "version=$VERSION" >> $GITHUB_ENV
|
||||
echo "Version of @navikt/ds-css: ${{ env.version }}"
|
||||
|
||||
- name: Upload CSS to NAV CDN
|
||||
- name: Upload CSS to Nav CDN
|
||||
if: steps.changesets.outputs.published == 'true'
|
||||
uses: nais/deploy/actions/cdn-upload/v2@master
|
||||
with:
|
||||
|
||||
@@ -11,7 +11,7 @@ import Setup from "./assets/setup.png";
|
||||
|
||||
# Getting started
|
||||
|
||||
Aksel is the toolbox for product development <a href="https://aksel.nav.no"target="_blank">@NAV</a> (Norwegian Labour and Welfare Administration)
|
||||
Aksel is the toolbox for product development <a href="https://aksel.nav.no"target="_blank">@Nav</a> (Norwegian Labour and Welfare Administration)
|
||||
|
||||
This includes a designsystem, best practices for product-development, principles for user-experience and a blog. <a href="https://aksel.nav.no/god-praksis/artikler/om-aksel" target="_blank">
|
||||
Read more about Aksel.</a>
|
||||
@@ -30,7 +30,7 @@ import Setup from "./assets/setup.png";
|
||||
target="_blank"
|
||||
className="sb-link"
|
||||
>Website</a></h3>
|
||||
<p className="sb-section-item-paragraph">Includes everything you need to get started building and developing digital products for NAV today.</p>
|
||||
<p className="sb-section-item-paragraph">Includes everything you need to get started building and developing digital products for Nav today.</p>
|
||||
|
||||
</div>
|
||||
<div className="sb-section-item">
|
||||
|
||||
@@ -2,11 +2,13 @@ import { withThemeByClassName } from "@storybook/addon-themes";
|
||||
import { Preview } from "@storybook/react";
|
||||
import React, { useLayoutEffect } from "react";
|
||||
// @ts-expect-error - Temporary
|
||||
import darksideCss from "@navikt/ds-css/darkside/index.css?inline";
|
||||
import darksideCss from "../@navikt/core/css/darkside/index.css?inline";
|
||||
// @ts-expect-error - Temporary
|
||||
import defaultCss from "@navikt/ds-css/index.css?inline";
|
||||
import { UNSAFE_AkselTheme } from "../@navikt/core/react/src/provider";
|
||||
import UNSAFE_AkselLanguageProvider from "../@navikt/core/react/src/provider/i18n/LanguageProvider";
|
||||
import defaultCss from "../@navikt/core/css/index.css?inline";
|
||||
import {
|
||||
Provider,
|
||||
UNSAFE_AkselTheme,
|
||||
} from "../@navikt/core/react/src/provider";
|
||||
import en from "../@navikt/core/react/src/util/i18n/locales/en";
|
||||
import nb from "../@navikt/core/react/src/util/i18n/locales/nb";
|
||||
import nn from "../@navikt/core/react/src/util/i18n/locales/nn";
|
||||
@@ -46,9 +48,7 @@ const translations = {
|
||||
const LanguageDecorator = ({ children, language }) => {
|
||||
if (language) {
|
||||
return (
|
||||
<UNSAFE_AkselLanguageProvider translations={translations[language]}>
|
||||
{children}
|
||||
</UNSAFE_AkselLanguageProvider>
|
||||
<Provider translations={translations[language]}>{children}</Provider>
|
||||
);
|
||||
}
|
||||
return children;
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# @navikt/aksel-icons
|
||||
|
||||
## 7.8.1
|
||||
|
||||
## 7.8.0
|
||||
|
||||
## 7.7.0
|
||||
|
||||
## 7.6.0
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@navikt/aksel-icons",
|
||||
"version": "7.7.0",
|
||||
"author": "Aksel | NAV",
|
||||
"version": "7.8.1",
|
||||
"author": "Aksel | Nav",
|
||||
"homepage": "https://aksel.nav.no/ikoner",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -10,7 +10,7 @@
|
||||
},
|
||||
"keywords": [
|
||||
"Icons",
|
||||
"NAV",
|
||||
"Nav",
|
||||
"Aksel",
|
||||
"designsystem",
|
||||
"react",
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @navikt/aksel-stylelint
|
||||
|
||||
## 7.8.1
|
||||
|
||||
## 7.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Combobox: Removed clear button, removed tokens staring with `--ac-combobox-clear`, deprecated props `clearButton`/`clearButtonLabel`. ([#3433](https://github.com/navikt/aksel/pull/3433))
|
||||
|
||||
## 7.7.0
|
||||
|
||||
## 7.6.0
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@navikt/aksel-stylelint",
|
||||
"version": "7.7.0",
|
||||
"author": "Aksel | NAV",
|
||||
"version": "7.8.1",
|
||||
"author": "Aksel | Nav",
|
||||
"homepage": "https://aksel.nav.no/grunnleggende/kode/stylelint",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -35,8 +35,8 @@
|
||||
"dev": "yarn watch:lint"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@navikt/ds-css": "^7.7.0",
|
||||
"@navikt/ds-tokens": "^7.7.0",
|
||||
"@navikt/ds-css": "^7.8.1",
|
||||
"@navikt/ds-tokens": "^7.8.1",
|
||||
"concurrently": "9.0.1",
|
||||
"postcss-selector-parser": "^6.0.13",
|
||||
"postcss-value-parser": "^4.2.0",
|
||||
|
||||
@@ -72,4 +72,8 @@ export const deprecations: DeprecatedList = [
|
||||
classes: ["navds-list--nested", "navds-list__item-content"],
|
||||
message: "Removed in v7.1.1",
|
||||
},
|
||||
{
|
||||
classes: ["navds-combobox__button-clear"],
|
||||
message: "Removed in v7.8.0",
|
||||
},
|
||||
];
|
||||
@@ -1,5 +1,19 @@
|
||||
# @navikt/aksel
|
||||
|
||||
## 7.8.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`06193ae`](https://github.com/navikt/aksel/commit/06193ae3001cee4b1f411a75d51ab54391483dd7), [`a82126b`](https://github.com/navikt/aksel/commit/a82126b893490b9786d31cb74ba31695b90f8c60)]:
|
||||
- @navikt/ds-css@7.8.1
|
||||
|
||||
## 7.8.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f720562`](https://github.com/navikt/aksel/commit/f720562908ccb0c7c62cabd386920d0c1fdcdaf9), [`5dedfa1`](https://github.com/navikt/aksel/commit/5dedfa104a187d23e3028ffa2b4a85e44e206b31)]:
|
||||
- @navikt/ds-css@7.8.0
|
||||
|
||||
## 7.7.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "@navikt/aksel",
|
||||
"version": "7.7.0",
|
||||
"version": "7.8.1",
|
||||
"description": "Aksel command line interface. Handles css-imports, codemods and more",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"author": "Aksel | Nav designsystem team",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"Commandline",
|
||||
@@ -29,7 +29,7 @@
|
||||
},
|
||||
"homepage": "https://aksel.nav.no/grunnleggende/kode/kommandolinje",
|
||||
"dependencies": {
|
||||
"@navikt/ds-css": "7.7.0",
|
||||
"@navikt/ds-css": "7.8.1",
|
||||
"axios": "1.7.4",
|
||||
"chalk": "4.1.0",
|
||||
"clipboardy": "^2.3.0",
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# @navikt/ds-css
|
||||
|
||||
## 7.8.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Alert: Link-components used within Alert variant='inline' now preserves default coloring ([#3461](https://github.com/navikt/aksel/pull/3461))
|
||||
|
||||
- Table: :fire: Removed cursor 'pointer' when 'ExpandableRow' is disabled. ([#3462](https://github.com/navikt/aksel/pull/3462))
|
||||
|
||||
## 7.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Combobox: Removed clear button, removed tokens staring with `--ac-combobox-clear`, deprecated props `clearButton`/`clearButtonLabel`. ([#3433](https://github.com/navikt/aksel/pull/3433))
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- CSS: Resolved regression where the complete stylesheet was included in scoped 'components.css' file. ([#3427](https://github.com/navikt/aksel/pull/3427))
|
||||
|
||||
## 7.7.0
|
||||
|
||||
## 7.6.0
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
import browserslist from "browserslist";
|
||||
import CleanCss from "clean-css";
|
||||
import fastglob from "fast-glob";
|
||||
import fs from "fs";
|
||||
import { Features, browserslistToTargets, bundleAsync } from "lightningcss";
|
||||
import path from "path";
|
||||
import {
|
||||
StyleMappings,
|
||||
componentsCss,
|
||||
formCss,
|
||||
primitivesCss,
|
||||
} from "../config/_mappings";
|
||||
import packageJSON from "../package.json";
|
||||
|
||||
bundleDarkside();
|
||||
|
||||
async function bundleDarkside() {
|
||||
const buildDir = path.join(__dirname, "..", "dist/darkside");
|
||||
const darksideDir = path.join(__dirname, "..", "darkside");
|
||||
|
||||
/* Make sure every dir is created to make node happy */
|
||||
[buildDir, `${buildDir}/global`, `${buildDir}/component`].forEach((dir) => {
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Bundles the ./index.css file with LightningCSS.
|
||||
* @param rootParser: Custom parsers that allows for editing the index.css file before bundling it. This allows removing unwanted CSS from being bundled.
|
||||
* @returns Parsed CSS file output. Must be valid CSS.
|
||||
*/
|
||||
async function bundleCSS(rootParser?: (rootFile: string) => string) {
|
||||
const { code } = await bundleAsync({
|
||||
filename: `${darksideDir}/index.css`,
|
||||
minify: false,
|
||||
include:
|
||||
Features.Nesting | Features.MediaRangeSyntax | Features.HexAlphaColors,
|
||||
|
||||
drafts: {
|
||||
customMedia: false,
|
||||
},
|
||||
targets: browserslistToTargets(
|
||||
browserslist(">= 0.5% in NO, safari >= 15.4, iOS >= 15.4, not dead"),
|
||||
),
|
||||
resolver: {
|
||||
read(filePath) {
|
||||
const file = fs.readFileSync(filePath, "utf8");
|
||||
if (filePath === `${darksideDir}/index.css` && rootParser) {
|
||||
return rootParser(file);
|
||||
}
|
||||
|
||||
return file;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
let codeString = code.toString();
|
||||
|
||||
/**
|
||||
* LightningCSS adds these tokens to the bundle that we want removed:
|
||||
* --lightningcss-light: initial;
|
||||
* --lightningcss-dark: ;
|
||||
*/
|
||||
codeString = codeString
|
||||
.split("\n")
|
||||
.filter((line) => !line.includes("--lightningcss-"))
|
||||
.join("\n");
|
||||
|
||||
return codeString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the CSS file to the build directory. Includes a minified version with the .min.css suffix.
|
||||
* @param file: CSS file content
|
||||
* @param filePath: Path to the file in the build directory
|
||||
*/
|
||||
function writeFile({ file, filePath }: { file: string; filePath: string }) {
|
||||
fs.writeFileSync(`${buildDir}/${filePath}`, file);
|
||||
|
||||
/**
|
||||
* We use CleanCss package here since we only want it to optimize filesize, not transform any CSS like LightningCSS minifier does.
|
||||
* This is because we want to keep the CSS as close to the original as possible.
|
||||
* Since CleanCSS is not part of the PostCSS ecosystem, we use it in replacement for cssnano.
|
||||
*/
|
||||
const minifiedCss = new CleanCss({}).minify(file);
|
||||
|
||||
if (minifiedCss.errors.length > 0) {
|
||||
throw new Error(
|
||||
`Errors found when minifying for ${filePath} CSS. Stopped bundling\n${minifiedCss.errors}`,
|
||||
);
|
||||
}
|
||||
|
||||
fs.writeFileSync(
|
||||
`${buildDir}/${filePath.replace(".css", ".min.css")}`,
|
||||
minifiedCss.styles,
|
||||
);
|
||||
}
|
||||
|
||||
/* ----------------------------- index.css build ---------------------------- */
|
||||
await bundleCSS().then((file) => {
|
||||
writeFile({
|
||||
file,
|
||||
filePath: "index.css",
|
||||
});
|
||||
});
|
||||
|
||||
/* --------------------------- component.css build -------------------------- */
|
||||
function rootComponentsParser(rootString: string) {
|
||||
let parsed = rootString
|
||||
.split("\n")
|
||||
.filter((line) => {
|
||||
/* We assume that all components is added under the layer components or layout */
|
||||
return (
|
||||
line.endsWith("layer(aksel.components);") ||
|
||||
line.endsWith("layer(aksel.layout);")
|
||||
);
|
||||
})
|
||||
.join("\n");
|
||||
|
||||
/* If one imports this file standalone, we would like to make sure the layering order is included. */
|
||||
const layerDefinition = rootString
|
||||
.split("\n")
|
||||
.find((line) => line.startsWith("@layer"));
|
||||
|
||||
if (!layerDefinition) {
|
||||
throw new Error(
|
||||
"No layer definition found in index.css. Stopped bundling",
|
||||
);
|
||||
}
|
||||
|
||||
parsed = layerDefinition + "\n" + parsed;
|
||||
|
||||
return parsed;
|
||||
}
|
||||
|
||||
await bundleCSS(rootComponentsParser).then((file) => {
|
||||
writeFile({
|
||||
file,
|
||||
filePath: componentsCss,
|
||||
});
|
||||
});
|
||||
|
||||
/* ------------------------------ /global build ----------------------------- */
|
||||
for (const style of StyleMappings.baseline) {
|
||||
// eslint-disable-next-line no-inner-declarations
|
||||
function parser(input: string) {
|
||||
return input
|
||||
.split("\n")
|
||||
.filter((line) => line.startsWith("@import"))
|
||||
.filter((line) =>
|
||||
line.replace(".darkside.css", ".css").includes(style.main),
|
||||
)
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
await bundleCSS(parser).then((file) => {
|
||||
writeFile({
|
||||
file,
|
||||
filePath: `global/${style.main}`,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* ------------------------------ form build ----------------------------- */
|
||||
function rootFormParser(input: string) {
|
||||
return input
|
||||
.split("\n")
|
||||
.filter((line) => line.startsWith("@import"))
|
||||
.filter((line) => line.includes("form/index.css"))
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
await bundleCSS(rootFormParser).then((file) => {
|
||||
writeFile({
|
||||
file,
|
||||
filePath: `component/${formCss}`,
|
||||
});
|
||||
});
|
||||
|
||||
/* ------------------------------ Primitives build ----------------------------- */
|
||||
function rootPrimitivesParser(input: string) {
|
||||
return input
|
||||
.split("\n")
|
||||
.filter((line) => line.startsWith("@import"))
|
||||
.filter((line) => line.includes("primitives/index.css"))
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
await bundleCSS(rootPrimitivesParser).then((file) => {
|
||||
writeFile({
|
||||
file,
|
||||
filePath: `component/${primitivesCss}`,
|
||||
});
|
||||
});
|
||||
|
||||
/* ---------------------------- /component build ---------------------------- */
|
||||
|
||||
function componentFiles(): string[] {
|
||||
const indexFile = fs.readFileSync(`${darksideDir}/index.css`, "utf8");
|
||||
|
||||
/* Since forms and primitives is under the same layers, but diffferent files we filter them out to avoid duplicates */
|
||||
const formLine = rootFormParser(indexFile);
|
||||
const primitivesLine = rootPrimitivesParser(indexFile);
|
||||
|
||||
return indexFile
|
||||
.split("\n")
|
||||
.filter((line) => line.startsWith("@import"))
|
||||
.filter((line) => !formLine.includes(line))
|
||||
.filter((line) => !primitivesLine.includes(line))
|
||||
.filter((line) => line.endsWith("layer(aksel.components);"));
|
||||
}
|
||||
|
||||
for (const componentLine of componentFiles()) {
|
||||
// eslint-disable-next-line no-inner-declarations
|
||||
function parser(input: string) {
|
||||
return input
|
||||
.split("\n")
|
||||
.filter((line) => line === componentLine)
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
await bundleCSS(parser).then((file) => {
|
||||
const componentName = componentLine
|
||||
/* Matches everything between " */
|
||||
.match(/".*"/gm)?.[0]
|
||||
/* Replaces every " with nothing */
|
||||
.replace(/"/gm, "")
|
||||
/* Removes start of import-string */
|
||||
.replace("./", "")
|
||||
.replace(".darkside.css", ".css");
|
||||
|
||||
if (!componentName) {
|
||||
throw new Error(
|
||||
`Could not find component name for line: ${componentLine}`,
|
||||
);
|
||||
}
|
||||
|
||||
const sanitizedName = componentName
|
||||
/*
|
||||
* https://regex101.com/r/MAj58n/1
|
||||
* Removes every - and space
|
||||
*/
|
||||
.replace(/[\s-]/g, "")
|
||||
.replace(".css", "")
|
||||
.toLowerCase();
|
||||
|
||||
writeFile({
|
||||
file,
|
||||
filePath: `component/${sanitizedName}.css`,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const version = packageJSON.version;
|
||||
|
||||
const files = fastglob.sync("**/*.css", {
|
||||
cwd: buildDir,
|
||||
ignore: ["**/version/**"],
|
||||
});
|
||||
|
||||
for (const file of files) {
|
||||
const css = fs.readFileSync(`${buildDir}/${file}`, "utf-8");
|
||||
|
||||
const filename = `${buildDir}/version/${version}/${file}`;
|
||||
fs.mkdirSync(path.dirname(filename), { recursive: true });
|
||||
|
||||
fs.writeFileSync(filename, css);
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,13 @@ async function bundleComponents() {
|
||||
const css = fs.readFileSync(indexSrc);
|
||||
|
||||
/* Remove @charset, baseline */
|
||||
const cssString = css.toString().split("\n").slice(2).join("\n");
|
||||
const cssString = css
|
||||
.toString()
|
||||
.split("\n")
|
||||
.filter((line) => {
|
||||
return line.startsWith("@import") && !line.includes("baseline");
|
||||
})
|
||||
.join("\n");
|
||||
|
||||
const result = await postcss([cssImports, combineSelectors]).process(
|
||||
cssString,
|
||||
@@ -102,6 +108,7 @@ function buildFragmentFiles() {
|
||||
const files = fastglob
|
||||
.sync("*.css", { cwd: ".", ignore: "**/*.min.css" })
|
||||
.map((fileN) => path.basename(fileN))
|
||||
.filter((fileName) => !fileName.includes("index.css"))
|
||||
.map((x) => ({
|
||||
input: path.resolve(__dirname, `../${x}`),
|
||||
output: path.resolve(
|
||||
@@ -154,7 +161,7 @@ async function bundleMinified() {
|
||||
function copyToVersionFolder() {
|
||||
const files = fastglob.sync("**/*.css", {
|
||||
cwd: `./${rootDir}`,
|
||||
ignore: "**/version/**",
|
||||
ignore: ["**/version/**", "**/darkside/**"],
|
||||
});
|
||||
|
||||
for (let file of files) {
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import fastglob from "fast-glob";
|
||||
import path from "path";
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
/**
|
||||
* Darkside config might have some new files added. We can skip these when checking for equality.
|
||||
*/
|
||||
const newFiles = ["theme"];
|
||||
|
||||
describe("Check that old and new (darkside) bundle matches", () => {
|
||||
test("Darkside includes the same files as old bundle", () => {
|
||||
const oldBundleDir = path.join(__dirname, "../../dist");
|
||||
const darksideDir = path.join(__dirname, "../../dist/darkside");
|
||||
|
||||
const oldFiles = fastglob.sync("**/*.css", {
|
||||
cwd: oldBundleDir,
|
||||
ignore: ["**/version/**", "**/darkside/**"],
|
||||
});
|
||||
|
||||
const darksideFiles = fastglob.sync("**/*.css", {
|
||||
cwd: darksideDir,
|
||||
ignore: ["**/version/**"],
|
||||
});
|
||||
|
||||
expect(oldFiles.length).toBeGreaterThan(0);
|
||||
expect(darksideFiles.length).toBeGreaterThan(0);
|
||||
|
||||
// Compare file names
|
||||
oldFiles.forEach((file) => {
|
||||
expect(darksideFiles).toContain(file);
|
||||
});
|
||||
|
||||
darksideFiles.forEach((file) => {
|
||||
if (newFiles.find((newFile) => file.includes(newFile))) {
|
||||
return;
|
||||
}
|
||||
expect(oldFiles).toContain(file);
|
||||
});
|
||||
|
||||
/**
|
||||
* Check that darkside has the same amount of files as old bundle
|
||||
* (minus the new files * 2 since .min.css is also included)
|
||||
*/
|
||||
expect(darksideFiles.length - newFiles.length * 2).toBe(oldFiles.length);
|
||||
});
|
||||
});
|
||||
+9
@@ -1,3 +1,12 @@
|
||||
/* ------------------------- Global typo-definitions ------------------------ */
|
||||
body,
|
||||
:host {
|
||||
font-family: var(--ax-font-family, "Source Sans 3", "Source Sans Pro", Arial, sans-serif);
|
||||
line-height: 1.333;
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
|
||||
/* ---------------------------- Inline utilities ---------------------------- */
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
@import "../../../tokens/dist/darkside/tokens.css";
|
||||
@@ -260,7 +260,7 @@
|
||||
}
|
||||
|
||||
.navds-button:not(.navds-button--loading):where(:disabled, .navds-button--disabled) {
|
||||
opacity: 0.3;
|
||||
opacity: var(--ax-opacity-disabled);
|
||||
}
|
||||
|
||||
/* Loader overrides */
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.3;
|
||||
opacity: var(--ax-opacity-disabled);
|
||||
}
|
||||
|
||||
&:disabled:hover {
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
|
||||
.navds-dropdown__item:disabled {
|
||||
color: var(--ac-dropdown-item-text, var(--a-text-action));
|
||||
opacity: 0.3;
|
||||
opacity: var(--ax-opacity-disabled);
|
||||
background: transparent;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
}
|
||||
|
||||
.navds-combobox--disabled {
|
||||
opacity: 0.3;
|
||||
opacity: var(--ax-opacity-disabled);
|
||||
|
||||
& .navds-combobox__wrapper {
|
||||
& *:hover {
|
||||
@@ -69,7 +69,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.navds-combobox__button-clear svg,
|
||||
.navds-combobox__button-toggle-list svg,
|
||||
.navds-combobox__list svg {
|
||||
width: var(--__axc-combobox-icon-size);
|
||||
@@ -203,19 +202,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.navds-combobox__button-clear {
|
||||
border-radius: var(--ax-border-radius-medium);
|
||||
color: var(--ax-text-subtle);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 1rem;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.navds-combobox__input::-webkit-search-cancel-button {
|
||||
display: none;
|
||||
}
|
||||
@@ -231,10 +217,7 @@
|
||||
border: none;
|
||||
font-size: 1rem;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.navds-combobox__button-clear,
|
||||
.navds-combobox__button-toggle-list {
|
||||
&:hover {
|
||||
color: var(--ax-text-accent);
|
||||
|
||||
@@ -405,10 +388,6 @@
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.navds-combobox__button-clear:hover {
|
||||
color: highlight;
|
||||
}
|
||||
|
||||
.navds-combobox__wrapper-inner:has(.navds-combobox__input:focus-visible) {
|
||||
outline-color: highlight;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
.navds-fieldset:disabled > .navds-fieldset__legend,
|
||||
.navds-fieldset:disabled > .navds-fieldset__description {
|
||||
opacity: 0.3;
|
||||
opacity: var(--ax-opacity-disabled);
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
}
|
||||
|
||||
.navds-form-field--disabled {
|
||||
opacity: 0.3;
|
||||
opacity: var(--ax-opacity-disabled);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
.navds-form-field__readonly-icon {
|
||||
margin-top: var(--ax-spacing-05);
|
||||
margin-right: var(--ax-spacing-2);
|
||||
margin-right: var(--ax-spacing-1);
|
||||
flex-shrink: 0;
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@
|
||||
|
||||
.navds-checkbox--disabled,
|
||||
.navds-radio--disabled {
|
||||
opacity: 0.3;
|
||||
opacity: var(--ax-opacity-disabled);
|
||||
}
|
||||
|
||||
.navds-checkbox--disabled > .navds-checkbox__input,
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
font-size: 1.5rem;
|
||||
|
||||
.navds-search--disabled & {
|
||||
opacity: 0.3;
|
||||
opacity: var(--ax-opacity-disabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +105,10 @@
|
||||
--__axc-button-border-width: 1px;
|
||||
--__axc-button-border-color: var(--ax-border-default);
|
||||
|
||||
&:not(:hover, :active) {
|
||||
background-color: var(--ax-bg-input);
|
||||
}
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
--__axc-button-border-color: var(--ax-border-accent-strong);
|
||||
}
|
||||
@@ -144,7 +148,7 @@
|
||||
/* We can't re-use disabled-state for form-fields since opacity multiplies on search-button */
|
||||
.navds-search--disabled {
|
||||
.navds-search__input {
|
||||
opacity: 0.3;
|
||||
opacity: var(--ax-opacity-disabled);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
@@ -169,7 +169,7 @@
|
||||
}
|
||||
|
||||
.navds-switch--disabled:not(.navds-switch--loading) {
|
||||
opacity: 0.3;
|
||||
opacity: var(--ax-opacity-disabled);
|
||||
}
|
||||
|
||||
.navds-switch__input:disabled,
|
||||
|
||||
@@ -1,20 +1,41 @@
|
||||
.navds-guide-panel {
|
||||
--__ac-guide-panel-guide-size: 4rem;
|
||||
--__axc-guide-panel-guide-size: 3.75rem;
|
||||
|
||||
position: relative;
|
||||
padding-top: calc(var(--__ac-guide-panel-guide-size) / 2);
|
||||
display: flex;
|
||||
width: fit-content;
|
||||
|
||||
&[data-poster="true"],
|
||||
&[data-responsive="true"] {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&[data-poster="false"] {
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
@media (min-width: 480px) {
|
||||
& {
|
||||
--__axc-guide-panel-guide-size: 5rem;
|
||||
}
|
||||
|
||||
&[data-responsive="true"] {
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.navds-guide {
|
||||
background: var(--ac-guide-panel-illustration-bg, var(--a-surface-alt-3-subtle));
|
||||
border: 2px solid var(--ac-guide-panel-border, var(--a-border-alt-3));
|
||||
border-radius: var(--a-border-radius-full);
|
||||
box-sizing: border-box;
|
||||
border: 2px solid var(--ax-border-info);
|
||||
border-radius: var(--ax-border-radius-full);
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
width: var(--__ac-guide-panel-guide-size);
|
||||
height: var(--__ac-guide-panel-guide-size);
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: var(--__axc-guide-panel-guide-size);
|
||||
height: var(--__axc-guide-panel-guide-size);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.navds-guide svg,
|
||||
@@ -24,73 +45,70 @@
|
||||
}
|
||||
|
||||
.navds-guide-panel__content {
|
||||
background-color: var(--ac-guide-panel-bg, var(--a-surface-default));
|
||||
border: 2px solid var(--ac-guide-panel-border, var(--a-border-alt-3));
|
||||
border-radius: var(--a-border-radius-large);
|
||||
padding: var(--a-spacing-4);
|
||||
padding-top: var(--a-spacing-12);
|
||||
}
|
||||
background-color: var(--ax-bg-raised);
|
||||
border: 2px solid var(--ax-border-info);
|
||||
border-radius: var(--ax-border-radius-xlarge);
|
||||
position: relative;
|
||||
|
||||
@media (min-width: 480px) {
|
||||
.navds-guide-panel {
|
||||
--__ac-guide-panel-guide-size: 6.25rem;
|
||||
.navds-guide-panel:is([data-poster="true"], [data-responsive="true"]) > & {
|
||||
margin-top: var(--ax-spacing-5);
|
||||
}
|
||||
|
||||
.navds-guide-panel__content {
|
||||
padding: var(--a-spacing-8);
|
||||
padding-top: 4.25rem;
|
||||
.navds-guide-panel[data-poster="false"] > & {
|
||||
margin-left: var(--ax-spacing-5);
|
||||
}
|
||||
|
||||
@media (min-width: 480px) {
|
||||
.navds-guide-panel[data-responsive="true"] > & {
|
||||
margin-top: 0;
|
||||
margin-left: var(--ax-spacing-5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* not-poster */
|
||||
.navds-guide-panel__content-inner {
|
||||
padding: var(--ax-spacing-3) var(--ax-spacing-4);
|
||||
border-radius: var(--ax-border-radius-xlarge);
|
||||
background-color: var(--ax-bg-raised);
|
||||
position: relative;
|
||||
height: 100%;
|
||||
|
||||
.navds-guide-panel--not-poster {
|
||||
padding-top: 0;
|
||||
padding-left: calc(var(--__ac-guide-panel-guide-size) / 2);
|
||||
}
|
||||
|
||||
.navds-guide-panel--not-poster .navds-guide {
|
||||
left: 0;
|
||||
top: var(--a-spacing-5);
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.navds-guide-panel--not-poster .navds-guide-panel__content {
|
||||
padding: var(--a-spacing-4);
|
||||
padding-left: var(--a-spacing-10);
|
||||
min-height: calc(var(--__ac-guide-panel-guide-size) + var(--a-spacing-5) + var(--a-spacing-5));
|
||||
}
|
||||
|
||||
@media (min-width: 480px) {
|
||||
.navds-guide-panel--not-poster {
|
||||
--__ac-guide-panel-guide-size: 5rem;
|
||||
.navds-guide-panel[data-poster="false"] & {
|
||||
min-height: var(--__axc-guide-panel-guide-size);
|
||||
}
|
||||
|
||||
.navds-guide-panel--not-poster .navds-guide-panel__content {
|
||||
padding: var(--a-spacing-6);
|
||||
padding-left: var(--a-spacing-14);
|
||||
@media (min-width: 480px) {
|
||||
& {
|
||||
padding: var(--ax-spacing-4) var(--ax-spacing-5);
|
||||
}
|
||||
|
||||
.navds-guide-panel[data-responsive="true"] & {
|
||||
min-height: var(--__axc-guide-panel-guide-size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* responsive-poster (on desktop) */
|
||||
.navds-guide-panel__tail {
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
|
||||
@media (min-width: 480px) {
|
||||
.navds-guide-panel--responsive-poster {
|
||||
--__ac-guide-panel-guide-size: 5rem;
|
||||
|
||||
padding-top: 0;
|
||||
padding-left: calc(var(--__ac-guide-panel-guide-size) / 2);
|
||||
.navds-guide-panel:is([data-poster="true"], [data-responsive="true"]) & {
|
||||
left: 50%;
|
||||
top: calc(var(--ax-spacing-4) * -1 - 2px);
|
||||
transform: translateX(-48%);
|
||||
}
|
||||
|
||||
.navds-guide-panel--responsive-poster .navds-guide {
|
||||
left: 0;
|
||||
top: var(--a-spacing-5);
|
||||
transform: none;
|
||||
.navds-guide-panel[data-poster="false"] & {
|
||||
top: calc(var(--__axc-guide-panel-guide-size) / 2);
|
||||
left: calc(var(--ax-spacing-5) * -1 - 2px);
|
||||
transform: translateY(-48%) rotateZ(-90deg) scaleX(-1);
|
||||
}
|
||||
|
||||
.navds-guide-panel--responsive-poster .navds-guide-panel__content {
|
||||
padding: var(--a-spacing-6);
|
||||
padding-left: var(--a-spacing-14);
|
||||
min-height: calc(var(--__ac-guide-panel-guide-size) + var(--a-spacing-5) + var(--a-spacing-5));
|
||||
@media (min-width: 480px) {
|
||||
.navds-guide-panel[data-responsive="true"] & {
|
||||
top: calc(var(--__axc-guide-panel-guide-size) / 2);
|
||||
left: calc(var(--ax-spacing-5) * -1 - 2px);
|
||||
transform: translateY(-48%) rotateZ(-90deg) scaleX(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
@import "baseline/index.css";
|
||||
@import "typography.css";
|
||||
@import "accordion.css";
|
||||
@import "alert.css";
|
||||
@import "button.css";
|
||||
@import "chat.css";
|
||||
@import "chips.css";
|
||||
@import "copybutton.css";
|
||||
@import "dropdown.css";
|
||||
@import "action-menu.css";
|
||||
@import "expansioncard.css";
|
||||
@import "guide-panel.css";
|
||||
@import "form/index.css";
|
||||
@import "help-text.css";
|
||||
@import "internalheader.css";
|
||||
@import "link.css";
|
||||
@import "loader.css";
|
||||
@import "modal.css";
|
||||
@import "pagination.css";
|
||||
@import "popover.css";
|
||||
@import "date.css";
|
||||
@import "tag.css";
|
||||
@import "timeline.css";
|
||||
@import "tooltip.css";
|
||||
@import "toggle-group.css";
|
||||
@import "panel.css";
|
||||
@import "link-panel.css";
|
||||
@import "read-more.css";
|
||||
@import "progress-bar.css";
|
||||
@import "skeleton.css";
|
||||
@import "stepper.css";
|
||||
@import "table.css";
|
||||
@import "tabs.css";
|
||||
@import "list.css";
|
||||
@import "primitives/index.css";
|
||||
@@ -1,23 +1,23 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/* CSS is ordered by specificity, so that browsers without layers fall backs to good defaults */
|
||||
@layer aksel.reset, aksel.typography, aksel.theme, aksel.components, aksel.layout, aksel.utilities;
|
||||
@layer aksel.reset, aksel.theming, aksel.baseline, aksel.print, aksel.typography, aksel.components, aksel.layout;
|
||||
|
||||
/* ----------------------------- CSS foundations ---------------------------- */
|
||||
@import "./baseline/reset.darkside.css" layer(aksel.reset);
|
||||
@import "./baseline/print.darkside.css" layer(aksel.reset);
|
||||
@import "./baseline/fonts.darkside.css" layer(aksel.typography);
|
||||
@import "./typography.darkside.css" layer(aksel.typography);
|
||||
|
||||
/* --------------------------------- Theming -------------------------------- */
|
||||
@import "@navikt/ds-tokens/dist/darkside/tokens.css" layer(aksel.theme);
|
||||
@import "./baseline/theme.darkside.css" layer(aksel.theme);
|
||||
@import "./baseline/reset.darkside.css" layer(aksel.reset);
|
||||
@import "./baseline/tokens.darkside.css" layer(aksel.theming);
|
||||
@import "./baseline/baseline.darkside.css" layer(aksel.baseline);
|
||||
@import "./baseline/print.darkside.css" layer(aksel.print);
|
||||
|
||||
/* ------------------------------- Components ------------------------------- */
|
||||
@import "./typography.darkside.css" layer(aksel.components);
|
||||
@import "./button.darkside.css" layer(aksel.components);
|
||||
@import "./chips.darkside.css" layer(aksel.components);
|
||||
|
||||
/**
|
||||
* Most components depend on typo-styles, so we import them first.
|
||||
*
|
||||
* `./form/index.css` edits the following components:
|
||||
* - Button
|
||||
* - Chips
|
||||
@@ -53,9 +53,7 @@
|
||||
@import "./table.darkside.css" layer(aksel.components);
|
||||
@import "./tabs.darkside.css" layer(aksel.components);
|
||||
@import "./list.darkside.css" layer(aksel.components);
|
||||
@import "./theme.darkside.css" layer(aksel.components);
|
||||
|
||||
/* --------------------------------- Layout --------------------------------- */
|
||||
@import "./primitives/index.css" layer(aksel.layout);
|
||||
|
||||
/* --------------------------------- Utility -------------------------------- */
|
||||
@import "./baseline/utilities.darkside.css" layer(aksel.utilities);
|
||||
@@ -2,7 +2,7 @@
|
||||
color: var(--ax-text-accent);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--ax-spacing-1);
|
||||
gap: var(--ax-spacing-05);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 0.1em;
|
||||
text-decoration-thickness: 0.05em;
|
||||
@@ -43,7 +43,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.navds-alert,
|
||||
.navds-alert:not(.navds-alert--inline),
|
||||
.navds-confirmation-panel {
|
||||
& .navds-link {
|
||||
color: var(--ax-text-default);
|
||||
|
||||
@@ -10,43 +10,44 @@
|
||||
|
||||
.navds-table__body {
|
||||
display: table-row-group;
|
||||
|
||||
& .navds-table__row--shade-on-hover:not(.navds-table__expandable-row--expansion-disabled):hover {
|
||||
background-color: var(--ax-bg-neutral-hoverA);
|
||||
transition: background-color 70ms cubic-bezier(0.2, 0, 0, 1);
|
||||
}
|
||||
|
||||
& .navds-table__row--shade-on-hover.navds-table__row--selected:hover {
|
||||
background-color: var(--ax-bg-accent-hoverA);
|
||||
}
|
||||
}
|
||||
|
||||
.navds-table__row {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.navds-table__body .navds-table__row--shade-on-hover:not(.navds-table__expandable-row--expansion-disabled):hover {
|
||||
background-color: var(--ac-table-row-hover, var(--a-bg-subtle));
|
||||
}
|
||||
|
||||
.navds-table__row--selected {
|
||||
background-color: var(--ac-table-row-selected, var(--a-surface-action-subtle));
|
||||
background-color: var(--ax-bg-accent);
|
||||
}
|
||||
|
||||
.navds-table__body .navds-table__row--shade-on-hover.navds-table__row--selected:hover {
|
||||
background-color: var(--ac-table-row-selected-hover, var(--a-surface-action-subtle-hover));
|
||||
}
|
||||
.navds-table--zebra-stripes {
|
||||
& .navds-table__body :where(.navds-table__row:nth-child(odd):not(.navds-table__row--selected)) {
|
||||
background-color: var(--ax-bg-neutral);
|
||||
}
|
||||
|
||||
.navds-table--zebra-stripes .navds-table__body :where(.navds-table__row:nth-child(odd):not(.navds-table__row--selected)) {
|
||||
background-color: var(--ac-table-row-zebra, var(--a-surface-subtle));
|
||||
}
|
||||
|
||||
.navds-table--zebra-stripes
|
||||
.navds-table__body
|
||||
:where(.navds-table__expandable-row:nth-child(4n + 1):not(.navds-table__row--selected)) {
|
||||
background-color: transparent;
|
||||
& .navds-table__body :where(.navds-table__expandable-row:nth-child(4n + 1):not(.navds-table__row--selected)) {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.navds-table--zebra-stripes .navds-table__body .navds-table__expanded-row:nth-child(4n) {
|
||||
background-color: var(--ac-table-row-zebra, var(--a-surface-subtle));
|
||||
background-color: var(--ax-bg-neutral);
|
||||
}
|
||||
|
||||
.navds-table__header-cell,
|
||||
.navds-table__data-cell {
|
||||
display: table-cell;
|
||||
padding: var(--a-spacing-3) var(--a-spacing-2);
|
||||
border-bottom: 1px solid var(--ac-table-row-border, var(--a-border-default));
|
||||
padding: var(--ax-spacing-3) var(--ax-spacing-2);
|
||||
border-bottom: 1px solid var(--ax-border-default);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@@ -67,7 +68,7 @@
|
||||
|
||||
:where(.navds-table__body .navds-table__row--shade-on-hover:hover) .navds-table__header-cell,
|
||||
:where(.navds-table__body .navds-table__row--shade-on-hover:hover) .navds-table__data-cell {
|
||||
border-color: var(--ac-table-cell-hover-border, var(--a-border-strong));
|
||||
border-color: var(--ax-border-strong);
|
||||
}
|
||||
|
||||
:where(.navds-table__expandable-row--open:hover) .navds-table__data-cell {
|
||||
@@ -76,12 +77,12 @@
|
||||
|
||||
.navds-table--large .navds-table__header-cell,
|
||||
.navds-table--large .navds-table__data-cell {
|
||||
padding: var(--a-spacing-4) var(--a-spacing-2);
|
||||
padding: var(--ax-spacing-4) var(--ax-spacing-2);
|
||||
}
|
||||
|
||||
.navds-table--small .navds-table__header-cell,
|
||||
.navds-table--small .navds-table__data-cell {
|
||||
padding: var(--a-spacing-1) var(--a-spacing-2);
|
||||
padding: var(--ax-spacing-1) var(--ax-spacing-2);
|
||||
}
|
||||
|
||||
.navds-table :not(.navds-checkboxes) > .navds-checkbox .navds-checkbox__input {
|
||||
@@ -103,43 +104,36 @@
|
||||
.navds-table__sort-button {
|
||||
appearance: none;
|
||||
background: none;
|
||||
color: var(--ac-table-sort-button-text, var(--a-text-action));
|
||||
color: var(--ax-text-accent);
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
padding: var(--a-spacing-4) var(--a-spacing-3);
|
||||
padding: var(--ax-spacing-4) var(--ax-spacing-3);
|
||||
width: 100%;
|
||||
display: flex;
|
||||
gap: var(--a-spacing-2);
|
||||
gap: var(--ax-spacing-2);
|
||||
align-items: center;
|
||||
line-height: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
.navds-table--small .navds-table__sort-button {
|
||||
padding: var(--a-spacing-2) var(--a-spacing-3);
|
||||
padding: var(--ax-spacing-2) var(--ax-spacing-3);
|
||||
}
|
||||
|
||||
.navds-table__sort-button:hover {
|
||||
background-color: var(--ac-table-sort-button-hover-bg, var(--a-bg-subtle));
|
||||
background-color: var(--ax-bg-neutral-hoverA);
|
||||
}
|
||||
|
||||
.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);
|
||||
}
|
||||
outline: 2px solid var(--ax-border-focus);
|
||||
outline-offset: -4px;
|
||||
}
|
||||
|
||||
.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));
|
||||
color: var(--ac-table-sort-button-sorted-text, var(--a-table-sort-button-sorted-text, var(--a-text-action-on-action-subtle)));
|
||||
background-color: var(--ax-bg-accent-moderate);
|
||||
color: var(--ax-text-accent-strong);
|
||||
}
|
||||
|
||||
.navds-table__header-cell--align-right .navds-table__sort-button {
|
||||
@@ -156,7 +150,7 @@
|
||||
}
|
||||
|
||||
.navds-table__expandable-row:not(.navds-table__expandable-row--open) .navds-table__data-cell {
|
||||
transition: border-bottom-color 190ms cubic-bezier(0.6, 0.04, 0.98, 0.335);
|
||||
transition: border-bottom-color 150ms cubic-bezier(0.95, 0.05, 0.8, 0.04);
|
||||
}
|
||||
|
||||
.navds-table__expandable-row.navds-table__expandable-row--clickable:not(.navds-table__expandable-row--expansion-disabled):hover {
|
||||
@@ -168,7 +162,7 @@
|
||||
}
|
||||
|
||||
.navds-table__expandable-row--open .navds-table__header-cell {
|
||||
border-color: var(--ac-table-row-border, var(--a-border-default));
|
||||
border-color: var(--ax-border-default);
|
||||
}
|
||||
|
||||
.navds-table__expandable-row--open .navds-table__toggle-expand-cell--open {
|
||||
@@ -181,11 +175,11 @@
|
||||
}
|
||||
|
||||
.navds-table--large .navds-table__toggle-expand-cell {
|
||||
padding: 0 var(--a-spacing-2);
|
||||
padding: 0 var(--ax-spacing-2);
|
||||
}
|
||||
|
||||
.navds-table--small .navds-table__toggle-expand-cell {
|
||||
padding: var(--a-spacing-1) var(--a-spacing-2);
|
||||
padding: var(--ax-spacing-1) var(--ax-spacing-2);
|
||||
}
|
||||
|
||||
.navds-table__toggle-expand-button {
|
||||
@@ -194,93 +188,54 @@
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: var(--a-border-radius-medium);
|
||||
border-radius: var(--ax-border-radius-medium);
|
||||
height: 2rem;
|
||||
width: 2rem;
|
||||
font-size: 1.5rem;
|
||||
margin: 0 auto;
|
||||
transition: background-color 70ms cubic-bezier(0.2, 0, 0, 1);
|
||||
}
|
||||
|
||||
.navds-table__expandable-icon {
|
||||
transition: transform 150ms ease-in-out;
|
||||
transition: transform 250ms cubic-bezier(0.2, 0, 0, 1);
|
||||
}
|
||||
|
||||
.navds-table__toggle-expand-cell:hover {
|
||||
.navds-table__expandable-row:not(.navds-table__expandable-row--expansion-disabled) .navds-table__toggle-expand-cell:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.navds-table__toggle-expand-button:hover,
|
||||
.navds-table__toggle-expand-cell:hover > .navds-table__toggle-expand-button,
|
||||
.navds-table__expandable-row--clickable:hover .navds-table__toggle-expand-button {
|
||||
background-color: var(--a-surface-hover);
|
||||
background-color: var(--ax-bg-neutral-hoverA);
|
||||
}
|
||||
|
||||
.navds-table__toggle-expand-cell--open > :where(.navds-table__toggle-expand-button) :where(.navds-table__expandable-icon) {
|
||||
transform: translateY(0) rotate(180deg);
|
||||
}
|
||||
|
||||
.navds-table__toggle-expand-button:hover > :where(.navds-table__expandable-icon) {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
.navds-table__toggle-expand-cell--open > .navds-table__toggle-expand-button:hover > :where(.navds-table__expandable-icon) {
|
||||
transform: translateY(-1px) rotate(180deg);
|
||||
transform: rotateX(180deg);
|
||||
}
|
||||
|
||||
.navds-table__toggle-expand-button:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: var(--a-shadow-focus);
|
||||
}
|
||||
|
||||
@supports not selector(:focus-visible) {
|
||||
.navds-table__toggle-expand-button:focus {
|
||||
outline: none;
|
||||
box-shadow: var(--a-shadow-focus);
|
||||
}
|
||||
outline: 2px solid var(--ax-border-focus);
|
||||
}
|
||||
|
||||
.navds-table__expanded-row-cell {
|
||||
padding: 0;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.navds-table__expanded-row-cell:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navds-table__expanded-row-collapse:not([style*="height: 0px;"]) {
|
||||
border-bottom: 1px solid var(--ac-table-row-border, var(--a-border-default));
|
||||
/* -------------------------- Table ExpandableRow -------------------------- */
|
||||
.navds-table__expanded-row-collapse:not([style*="height: 0px;"]),
|
||||
.navds-table__expanded-row-collapse[style*="transition:"] {
|
||||
border-bottom: 1px solid var(--ax-border-default);
|
||||
}
|
||||
|
||||
.navds-table__expanded-row-content {
|
||||
padding: var(--a-spacing-4) calc(var(--a-spacing-2) + 3rem);
|
||||
padding: var(--ax-spacing-4) calc(var(--ax-spacing-2) + 3rem);
|
||||
}
|
||||
|
||||
.navds-table--small .navds-table__expanded-row-content {
|
||||
padding: var(--a-spacing-2) calc(var(--a-spacing-2) + 3rem);
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.navds-date.navds-date button.rdp-day_selected {
|
||||
forced-color-adjust: none;
|
||||
background-color: highlight;
|
||||
color: highlighttext;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.navds-date.navds-date button {
|
||||
color: buttontext;
|
||||
forced-color-adjust: none;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.navds-date button:focus-visible {
|
||||
color: buttontext;
|
||||
forced-color-adjust: none;
|
||||
outline: 2px solid highlight;
|
||||
}
|
||||
|
||||
.navds-date.navds-date button.rdp-day_disabled {
|
||||
color: GrayText;
|
||||
}
|
||||
padding: var(--ax-spacing-2) calc(var(--ax-spacing-2) + 3rem);
|
||||
}
|
||||
@@ -1,194 +1,132 @@
|
||||
.navds-tag {
|
||||
--__ac-tag-icon-size: 1.5rem;
|
||||
--__ac-tag-icon-margin: -2px;
|
||||
--__axc-tag-icon-size: 1.5rem;
|
||||
--__axc-tag-icon-margin: -2px;
|
||||
--__axc-tag-border: ;
|
||||
--__axc-tag-bg: ;
|
||||
--__axc-tag-bg-strong: ;
|
||||
--__axc-tag-text: ;
|
||||
--__axc-tag-text-strong: ;
|
||||
|
||||
border: 1px solid;
|
||||
border-radius: var(--a-border-radius-small);
|
||||
border-radius: var(--ax-border-radius-medium);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--a-spacing-05) var(--a-spacing-2);
|
||||
padding: var(--ax-spacing-05) var(--ax-spacing-2);
|
||||
min-height: 2rem;
|
||||
line-height: 1;
|
||||
|
||||
&:has(.navds-tag__icon--left) {
|
||||
gap: var(--ax-spacing-05);
|
||||
}
|
||||
}
|
||||
|
||||
.navds-tag--info,
|
||||
.navds-tag--alt3 {
|
||||
--__axc-tag-border: var(--ax-border-info);
|
||||
--__axc-tag-bg: var(--ax-bg-info-moderateA);
|
||||
--__axc-tag-bg-strong: var(--ax-bg-info-strong);
|
||||
--__axc-tag-text: var(--ax-text-info-strong);
|
||||
--__axc-tag-text-strong: var(--ax-text-info-contrast);
|
||||
}
|
||||
|
||||
.navds-tag--success {
|
||||
--__axc-tag-border: var(--ax-border-success);
|
||||
--__axc-tag-bg: var(--ax-bg-success-moderateA);
|
||||
--__axc-tag-bg-strong: var(--ax-bg-success-strong);
|
||||
--__axc-tag-text: var(--ax-text-success-strong);
|
||||
--__axc-tag-text-strong: var(--ax-text-success-contrast);
|
||||
}
|
||||
|
||||
.navds-tag--warning {
|
||||
--__axc-tag-border: var(--ax-border-warning);
|
||||
--__axc-tag-bg: var(--ax-bg-warning-moderateA);
|
||||
--__axc-tag-bg-strong: var(--ax-bg-warning-strong);
|
||||
--__axc-tag-text: var(--ax-text-warning-strong);
|
||||
--__axc-tag-text-strong: var(--ax-text-warning-contrast);
|
||||
}
|
||||
|
||||
.navds-tag--error {
|
||||
--__axc-tag-border: var(--ax-border-danger);
|
||||
--__axc-tag-bg: var(--ax-bg-danger-moderateA);
|
||||
--__axc-tag-bg-strong: var(--ax-bg-danger-strong);
|
||||
--__axc-tag-text: var(--ax-text-danger-strong);
|
||||
--__axc-tag-text-strong: var(--ax-text-danger-contrast);
|
||||
}
|
||||
|
||||
.navds-tag--neutral {
|
||||
--__axc-tag-border: var(--ax-border-neutral);
|
||||
--__axc-tag-bg: var(--ax-bg-neutral-moderateA);
|
||||
--__axc-tag-bg-strong: var(--ax-bg-neutral-strong);
|
||||
--__axc-tag-text: var(--ax-text-neutral-strong);
|
||||
--__axc-tag-text-strong: var(--ax-text-neutral-contrast);
|
||||
}
|
||||
|
||||
.navds-tag--meta-purple,
|
||||
.navds-tag--alt1 {
|
||||
--__axc-tag-border: var(--ax-border-meta-purple);
|
||||
--__axc-tag-bg: var(--ax-bg-meta-purple-moderateA);
|
||||
--__axc-tag-bg-strong: var(--ax-bg-meta-purple-strong);
|
||||
--__axc-tag-text: var(--ax-text-meta-purple-strong);
|
||||
--__axc-tag-text-strong: var(--ax-text-meta-purple-contrast);
|
||||
}
|
||||
|
||||
.navds-tag--meta-lime,
|
||||
.navds-tag--alt2 {
|
||||
--__axc-tag-border: var(--ax-border-meta-lime);
|
||||
--__axc-tag-bg: var(--ax-bg-meta-lime-moderateA);
|
||||
--__axc-tag-bg-strong: var(--ax-bg-meta-lime-strong);
|
||||
--__axc-tag-text: var(--ax-text-meta-lime-strong);
|
||||
--__axc-tag-text-strong: var(--ax-text-meta-lime-contrast);
|
||||
}
|
||||
|
||||
.navds-tag--small {
|
||||
min-height: 1.5rem;
|
||||
padding: 0 var(--a-spacing-1-alt);
|
||||
padding: 0 var(--ax-spacing-1-alt);
|
||||
|
||||
--__ac-tag-icon-size: 1.25rem;
|
||||
--__axc-tag-icon-size: 1.25rem;
|
||||
}
|
||||
|
||||
.navds-tag--xsmall {
|
||||
min-height: 1.25rem;
|
||||
padding: 0 var(--a-spacing-1);
|
||||
padding: 0 var(--ax-spacing-1);
|
||||
|
||||
--__ac-tag-icon-size: 1rem;
|
||||
--__ac-tag-icon-margin: -1px;
|
||||
}
|
||||
|
||||
.navds-tag:has(.navds-tag__icon--left) {
|
||||
gap: var(--a-spacing-05);
|
||||
--__axc-tag-icon-size: 1rem;
|
||||
--__axc-tag-icon-margin: -1px;
|
||||
}
|
||||
|
||||
.navds-tag__icon--left {
|
||||
font-size: var(--__ac-tag-icon-size);
|
||||
margin-inline-start: var(--__ac-tag-icon-margin);
|
||||
font-size: var(--__axc-tag-icon-size);
|
||||
margin-inline-start: var(--__axc-tag-icon-margin);
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.navds-tag--error {
|
||||
border-color: var(--ac-tag-error-border, var(--a-border-danger));
|
||||
background-color: var(--ac-tag-error-bg, var(--a-surface-danger-subtle));
|
||||
color: var(--ac-tag-error-text, var(--a-text-default));
|
||||
.navds-tag--outline {
|
||||
box-shadow: inset 0 0 0 1px var(--__axc-tag-border);
|
||||
background: var(--__axc-tag-bg);
|
||||
color: var(--__axc-tag-text);
|
||||
}
|
||||
|
||||
.navds-tag--error-filled {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-error-filled-bg, var(--a-surface-danger));
|
||||
color: var(--ac-tag-error-filled-text, var(--a-text-on-danger));
|
||||
.navds-tag--moderate {
|
||||
background: var(--__axc-tag-bg);
|
||||
color: var(--__axc-tag-text);
|
||||
}
|
||||
|
||||
.navds-tag--error-moderate {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-error-moderate-bg, var(--a-surface-danger-moderate));
|
||||
color: var(--ac-tag-error-moderate-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--success {
|
||||
border-color: var(--ac-tag-success-border, var(--a-border-success));
|
||||
background-color: var(--ac-tag-success-bg, var(--a-surface-success-subtle));
|
||||
color: var(--ac-tag-success-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--success-filled {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-success-filled-bg, var(--a-surface-success));
|
||||
color: var(--ac-tag-success-filled-text, var(--a-text-on-success));
|
||||
}
|
||||
|
||||
.navds-tag--success-moderate {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-success-moderate-bg, var(--a-surface-success-moderate));
|
||||
color: var(--ac-tag-success-moderate-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--warning {
|
||||
border-color: var(--ac-tag-warning-border, var(--a-border-warning));
|
||||
background-color: var(--ac-tag-warning-bg, var(--a-surface-warning-subtle));
|
||||
color: var(--ac-tag-warning-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--warning-filled {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-warning-filled-bg, var(--a-surface-warning));
|
||||
color: var(--ac-tag-warning-filled-text, var(--a-text-on-warning));
|
||||
}
|
||||
|
||||
.navds-tag--warning-moderate {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-warning-moderate-bg, var(--a-surface-warning-moderate));
|
||||
color: var(--ac-tag-warning-moderate-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--info {
|
||||
border-color: var(--ac-tag-info-border, var(--a-border-info));
|
||||
background-color: var(--ac-tag-info-bg, var(--a-surface-info-subtle));
|
||||
color: var(--ac-tag-info-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--info-filled {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-info-filled-bg, var(--a-surface-info));
|
||||
color: var(--ac-tag-info-filled-text, var(--a-text-on-info));
|
||||
}
|
||||
|
||||
.navds-tag--info-moderate {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-info-moderate-bg, var(--a-surface-info-moderate));
|
||||
color: var(--ac-tag-info-moderate-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--neutral {
|
||||
border-color: var(--ac-tag-neutral-border, var(--a-border-default));
|
||||
background-color: var(--ac-tag-neutral-bg, var(--a-surface-neutral-subtle));
|
||||
color: var(--ac-tag-neutral-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--neutral-filled {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-neutral-filled-bg, var(--a-surface-neutral));
|
||||
color: var(--ac-tag-neutral-filled-text, var(--a-text-on-neutral));
|
||||
}
|
||||
|
||||
.navds-tag--neutral-moderate {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-neutral-moderate-bg, var(--a-surface-neutral-moderate));
|
||||
color: var(--ac-tag-neutral-moderate-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--alt1 {
|
||||
border-color: var(--ac-tag-alt-1-border, var(--a-border-alt-1));
|
||||
background-color: var(--ac-tag-alt-1-bg, var(--a-surface-alt-1-subtle));
|
||||
color: var(--ac-tag-alt-1-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--alt1-filled {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-alt-1-filled-bg, var(--a-surface-alt-1));
|
||||
color: var(--ac-tag-alt-1-filled-text, var(--a-text-on-alt-1));
|
||||
}
|
||||
|
||||
.navds-tag--alt1-moderate {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-alt-1-moderate-bg, var(--a-surface-alt-1-moderate));
|
||||
color: var(--ac-tag-alt-1-moderate-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--alt2 {
|
||||
border-color: var(--ac-tag-alt-2-border, var(--a-border-alt-2));
|
||||
background-color: var(--ac-tag-alt-2-bg, var(--a-surface-alt-2-subtle));
|
||||
color: var(--ac-tag-alt-2-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--alt2-filled {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-alt-2-filled-bg, var(--a-surface-alt-2));
|
||||
color: var(--ac-tag-alt-2-filled-text, var(--a-text-on-alt-2));
|
||||
}
|
||||
|
||||
.navds-tag--alt2-moderate {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-alt-2-moderate-bg, var(--a-surface-alt-2-moderate));
|
||||
color: var(--ac-tag-alt-2-moderate-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--alt3 {
|
||||
border-color: var(--ac-tag-alt-3-border, var(--a-border-alt-3));
|
||||
background-color: var(--ac-tag-alt-3-bg, var(--a-surface-alt-3-subtle));
|
||||
color: var(--ac-tag-alt-3-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--alt3-filled {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-alt-3-filled-bg, var(--a-surface-alt-3));
|
||||
color: var(--ac-tag-alt-3-filled-text, var(--a-text-on-alt-3));
|
||||
}
|
||||
|
||||
.navds-tag--alt3-moderate {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-alt-3-moderate-bg, var(--a-surface-alt-3-moderate));
|
||||
color: var(--ac-tag-alt-3-moderate-text, var(--a-text-default));
|
||||
.navds-tag--strong {
|
||||
background: var(--__axc-tag-bg-strong);
|
||||
color: var(--__axc-tag-text-strong);
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.navds-tag {
|
||||
forced-color-adjust: none;
|
||||
}
|
||||
|
||||
.navds-tag--neutral,
|
||||
.navds-tag--neutral-moderate {
|
||||
border-color: canvastext;
|
||||
color: canvastext;
|
||||
}
|
||||
|
||||
.navds-tag--moderate {
|
||||
box-shadow: inset 0 0 0 1px var(--__axc-tag-bg-strong);
|
||||
}
|
||||
|
||||
.navds-tag--strong {
|
||||
color: canvas;
|
||||
}
|
||||
}
|
||||
File renamed without changes.
@@ -12,18 +12,18 @@
|
||||
height: 1rem;
|
||||
box-sizing: content-box;
|
||||
grid-column: 2;
|
||||
margin-bottom: var(--a-spacing-1);
|
||||
margin-bottom: var(--ax-spacing-1);
|
||||
}
|
||||
|
||||
.navds-timeline__row-label {
|
||||
white-space: nowrap;
|
||||
width: auto;
|
||||
margin-right: var(--a-spacing-4);
|
||||
margin-right: var(--ax-spacing-4);
|
||||
grid-column: 1;
|
||||
min-height: 1.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--a-spacing-2);
|
||||
gap: var(--ax-spacing-2);
|
||||
}
|
||||
|
||||
.navds-timeline__row-label:where(:nth-last-child(2)) {
|
||||
@@ -32,19 +32,19 @@
|
||||
|
||||
.navds-timeline__axislabels-label {
|
||||
position: absolute;
|
||||
color: var(--ac-timeline-axislabel-text, var(--a-text-subtle));
|
||||
color: var(--ax-text-subtle);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.navds-timeline__row {
|
||||
display: flex;
|
||||
background: var(--ac-timeline-row-bg, var(--a-surface-subtle));
|
||||
margin: var(--a-spacing-4) 0;
|
||||
background: var(--ax-bg-neutral);
|
||||
margin: var(--ax-spacing-4) 0;
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
.navds-timeline__row--active {
|
||||
background: var(--ac-timeline-row-active-bg, var(--a-surface-selected));
|
||||
background: var(--ax-bg-accent-moderateA);
|
||||
}
|
||||
|
||||
.navds-timeline__row:last-of-type {
|
||||
@@ -62,13 +62,19 @@
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.navds-timeline__row-periods:focus {
|
||||
outline: none;
|
||||
.navds-timeline__period:focus-visible {
|
||||
z-index: 4;
|
||||
outline: 2px solid var(--ax-border-focus);
|
||||
outline-offset: 2px;
|
||||
|
||||
&& {
|
||||
box-shadow: 0 0 0 2px var(--ax-bg-default);
|
||||
}
|
||||
}
|
||||
|
||||
.navds-timeline__period {
|
||||
height: 100%;
|
||||
border-radius: var(--a-border-radius-full);
|
||||
border-radius: var(--ax-border-radius-full);
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
@@ -79,7 +85,7 @@
|
||||
}
|
||||
|
||||
.navds-timeline__period--inner {
|
||||
margin: 0 var(--a-spacing-1);
|
||||
margin: 0 var(--ax-spacing-2);
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: clip;
|
||||
@@ -97,49 +103,83 @@
|
||||
}
|
||||
|
||||
.navds-timeline__period--success {
|
||||
background: var(--ac-timeline-period-success-bg, var(--a-surface-success-subtle));
|
||||
box-shadow: inset 0 0 0 1px var(--ac-timeline-period-success-border, var(--a-border-success));
|
||||
}
|
||||
background: var(--ax-bg-success-moderate);
|
||||
border: solid 1px var(--ax-border-success);
|
||||
color: var(--ax-text-success-icon);
|
||||
|
||||
.navds-timeline__period--success.navds-timeline__period--clickable:hover {
|
||||
background: var(--a-surface-success-subtle-hover);
|
||||
background: var(--ac-timeline-period-success-bg-hover, var(--a-surface-success-subtle-hover));
|
||||
&.navds-timeline__period--clickable:hover {
|
||||
background: var(--ax-bg-success-moderate-hover);
|
||||
}
|
||||
|
||||
&.navds-timeline__period--clickable.navds-timeline__period--selected {
|
||||
background: var(--ax-bg-success-strong-pressed);
|
||||
border: none;
|
||||
color: var(--ax-text-success-contrast);
|
||||
}
|
||||
}
|
||||
|
||||
.navds-timeline__period--warning {
|
||||
background: var(--ac-timeline-period-warning-bg, var(--a-surface-warning-subtle));
|
||||
box-shadow: inset 0 0 0 1px var(--ac-timeline-period-warning-border, var(--a-border-warning));
|
||||
}
|
||||
background: var(--ax-bg-warning-moderate);
|
||||
border: solid 1px var(--ax-border-warning);
|
||||
color: var(--ax-text-warning-icon);
|
||||
|
||||
.navds-timeline__period--warning.navds-timeline__period--clickable:hover {
|
||||
background: var(--ac-timeline-period-warning-bg-hover, var(--a-surface-warning-subtle-hover));
|
||||
&.navds-timeline__period--clickable:hover {
|
||||
background: var(--ax-bg-warning-moderate-hover);
|
||||
}
|
||||
|
||||
&.navds-timeline__period--clickable.navds-timeline__period--selected {
|
||||
background: var(--ax-bg-warning-strong-pressed);
|
||||
border: none;
|
||||
color: var(--ax-text-warning-contrast);
|
||||
}
|
||||
}
|
||||
|
||||
.navds-timeline__period--danger {
|
||||
background: var(--ac-timeline-period-danger-bg, var(--a-surface-danger-subtle));
|
||||
box-shadow: inset 0 0 0 1px var(--ac-timeline-period-danger-border, var(--a-border-danger));
|
||||
}
|
||||
background: var(--ax-bg-danger-moderate);
|
||||
border: solid 1px var(--ax-border-danger);
|
||||
color: var(--ax-text-danger-icon);
|
||||
|
||||
.navds-timeline__period--danger.navds-timeline__period--clickable:hover {
|
||||
background: var(--ac-timeline-period-danger-bg-hover, var(--a-surface-danger-subtle-hover));
|
||||
&.navds-timeline__period--clickable:hover {
|
||||
background: var(--ax-bg-danger-moderate-hover);
|
||||
}
|
||||
|
||||
&.navds-timeline__period--clickable.navds-timeline__period--selected {
|
||||
background: var(--ax-bg-danger-strong-pressed);
|
||||
border: none;
|
||||
color: var(--ax-text-danger-contrast);
|
||||
}
|
||||
}
|
||||
|
||||
.navds-timeline__period--info {
|
||||
background: var(--ac-timeline-period-info-bg, var(--a-surface-info-subtle));
|
||||
box-shadow: inset 0 0 0 1px var(--ac-timeline-period-info-border, var(--a-border-info));
|
||||
}
|
||||
background: var(--ax-bg-info-moderate);
|
||||
border: solid 1px var(--ax-border-info);
|
||||
color: var(--ax-text-info-icon);
|
||||
|
||||
.navds-timeline__period--info.navds-timeline__period--clickable:hover {
|
||||
background: var(--ac-timeline-period-info-bg-hover, var(--a-surface-info-subtle-hover));
|
||||
&.navds-timeline__period--clickable:hover {
|
||||
background: var(--ax-bg-info-moderate-hover);
|
||||
}
|
||||
|
||||
&.navds-timeline__period--clickable.navds-timeline__period--selected {
|
||||
background: var(--ax-bg-info-strong-pressed);
|
||||
border: none;
|
||||
color: var(--ax-text-info-contrast);
|
||||
}
|
||||
}
|
||||
|
||||
.navds-timeline__period--neutral {
|
||||
background: var(--ac-timeline-period-neutral-bg, var(--a-bg-subtle));
|
||||
box-shadow: inset 0 0 0 1px var(--ac-timeline-period-neutral-border, var(--a-border-default));
|
||||
}
|
||||
background: var(--ax-bg-neutral-moderate);
|
||||
border: solid 1px var(--ax-border-neutral);
|
||||
color: var(--ax-text-neutral-icon);
|
||||
|
||||
.navds-timeline__period--neutral.navds-timeline__period--clickable:hover {
|
||||
background: var(--ac-timeline-period-neutral-bg-hover, var(--a-gray-200));
|
||||
&.navds-timeline__period--clickable:hover {
|
||||
background: var(--ax-bg-neutral-moderate-hover);
|
||||
}
|
||||
|
||||
&.navds-timeline__period--clickable.navds-timeline__period--selected {
|
||||
background: var(--ax-bg-neutral-strong-pressed);
|
||||
border: none;
|
||||
color: var(--ax-text-neutral-contrast);
|
||||
}
|
||||
}
|
||||
|
||||
.navds-timeline__period--connected-both {
|
||||
@@ -156,11 +196,6 @@
|
||||
border-top-left-radius: 0;
|
||||
}
|
||||
|
||||
.navds-timeline__period--selected {
|
||||
box-shadow: inset 0 0 0 2px var(--ac-timeline-period-selected-border, var(--a-border-action-selected));
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.navds-timeline__pin-wrapper {
|
||||
position: absolute;
|
||||
grid-column: 2;
|
||||
@@ -177,68 +212,34 @@
|
||||
.navds-timeline__pin-button {
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
background: var(--a-surface-default);
|
||||
box-shadow:
|
||||
inset 0 0 0 1px var(--ac-timeline-pin-bg, var(--a-surface-danger)),
|
||||
0 0 0 4px var(--ac-timeline-pin-bg, var(--a-surface-danger)),
|
||||
0 0 0 5px var(--a-surface-default);
|
||||
background: var(--ax-bg-default);
|
||||
box-shadow: inset 0 0 0 4px var(--ax-bg-danger-strong);
|
||||
z-index: 2;
|
||||
border-radius: var(--a-border-radius-full);
|
||||
padding: var(--a-spacing-1);
|
||||
border-radius: var(--ax-border-radius-full);
|
||||
padding: var(--ax-spacing-2);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.navds-timeline__pin-button::before {
|
||||
content: "";
|
||||
inset: 0;
|
||||
position: absolute;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border-radius: var(--a-border-radius-full);
|
||||
left: calc(-12.5px + 3.5px);
|
||||
top: calc(-12.5px + 3.5px);
|
||||
}
|
||||
|
||||
.navds-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);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.navds-timeline__pin-button:hover {
|
||||
box-shadow:
|
||||
inset 0 0 0 1px var(--ac-timeline-pin-bg-hover, var(--a-surface-danger-hover)),
|
||||
0 0 0 4px var(--ac-timeline-pin-bg-hover, var(--a-surface-danger-hover)),
|
||||
0 0 0 5px var(--a-surface-default);
|
||||
}
|
||||
|
||||
.navds-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) {
|
||||
.navds-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;
|
||||
&::before {
|
||||
content: "";
|
||||
inset: 0;
|
||||
position: absolute;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border-radius: var(--ax-border-radius-full);
|
||||
left: calc(-12.5px + 3.5px);
|
||||
top: calc(-12.5px + 3.5px);
|
||||
}
|
||||
|
||||
.navds-timeline__pin-button:hover:focus {
|
||||
&:hover {
|
||||
box-shadow: inset 0 0 0 4px var(--ax-bg-danger-strong-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);
|
||||
inset 0 0 0 4px var(--ax-border-danger-strong),
|
||||
0 0 0 2px var(--ax-bg-default);
|
||||
outline: 2px solid var(--ax-border-focus);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,11 +249,11 @@
|
||||
height: calc(100% - var(--navdsc-timeline-pin-size) * 2);
|
||||
width: 1px;
|
||||
margin: 0 auto;
|
||||
background: var(--a-surface-inverted);
|
||||
background: var(--ax-border-strong);
|
||||
}
|
||||
|
||||
.navds-timeline__zoom {
|
||||
margin-top: var(--a-spacing-6);
|
||||
margin-top: var(--ax-spacing-6);
|
||||
float: right;
|
||||
display: flex;
|
||||
list-style-type: none;
|
||||
@@ -262,54 +263,42 @@
|
||||
all: unset;
|
||||
cursor: pointer;
|
||||
padding: 6px 9px 6px 8px;
|
||||
border: 1px solid var(--ac-timeline-zoom-border, var(--a-border-default));
|
||||
border: 1px solid var(--ax-border-default);
|
||||
border-width: 1px 0 1px 1px;
|
||||
background: var(--ac-timeline-zoom-bg, var(--a-surface-default));
|
||||
background: var(--ax-bg-default);
|
||||
}
|
||||
|
||||
.navds-timeline__zoom li:first-child .navds-timeline__zoom-button {
|
||||
border-radius: var(--a-border-radius-medium) 0 0 var(--a-border-radius-medium);
|
||||
border-radius: var(--ax-border-radius-medium) 0 0 var(--ax-border-radius-medium);
|
||||
}
|
||||
|
||||
.navds-timeline__zoom li:last-child .navds-timeline__zoom-button {
|
||||
border-width: 1px;
|
||||
border-radius: 0 var(--a-border-radius-medium) var(--a-border-radius-medium) 0;
|
||||
border-radius: 0 var(--ax-border-radius-medium) var(--ax-border-radius-medium) 0;
|
||||
}
|
||||
|
||||
.navds-timeline__zoom li:only-child .navds-timeline__zoom-button {
|
||||
border-radius: var(--a-border-radius-medium);
|
||||
border-radius: var(--ax-border-radius-medium);
|
||||
}
|
||||
|
||||
.navds-timeline__zoom-button:not([aria-pressed="true"]):hover {
|
||||
background: var(--ac-timeline-zoom-bg-hover, var(--a-surface-action-subtle-hover));
|
||||
background: var(--ax-bg-neutral-moderate-hoverA);
|
||||
}
|
||||
|
||||
.navds-timeline__zoom-button[aria-pressed="true"] {
|
||||
background: var(--ac-timeline-zoom-selected-bg, var(--a-surface-inverted));
|
||||
color: var(--ac-timeline-zoom-selected-text, var(--a-text-on-inverted));
|
||||
}
|
||||
|
||||
.navds-timeline__period:focus-visible {
|
||||
outline: none;
|
||||
z-index: 4;
|
||||
box-shadow: 0 0 0 2px var(--a-border-focus);
|
||||
}
|
||||
|
||||
.navds-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;
|
||||
background: var(--ax-bg-neutral-strong-pressed);
|
||||
border-color: var(--ax-bg-neutral-strong-pressed);
|
||||
color: var(--ax-text-neutral-contrast);
|
||||
}
|
||||
|
||||
.navds-timeline__zoom li:focus-within {
|
||||
z-index: var(--a-z-index-focus);
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.navds-timeline__zoom-button:focus-visible {
|
||||
box-shadow:
|
||||
0 0 0 1px var(--a-surface-default),
|
||||
0 0 0 3px var(--a-border-focus);
|
||||
0 0 0 1px var(--ax-bg-default),
|
||||
0 0 0 3px var(--ax-border-focus);
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
@@ -318,80 +307,18 @@
|
||||
padding-right: 6px;
|
||||
}
|
||||
|
||||
@supports not selector(:focus-visible) {
|
||||
.navds-timeline__period:focus {
|
||||
outline: none;
|
||||
z-index: 4;
|
||||
box-shadow: 0 0 0 2px var(--a-border-focus);
|
||||
}
|
||||
|
||||
.navds-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;
|
||||
}
|
||||
|
||||
.navds-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;
|
||||
}
|
||||
|
||||
.navds-timeline__zoom li:not(:last-child) .navds-timeline__zoom-button:focus {
|
||||
margin-right: 2px;
|
||||
padding-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Timeline Popover
|
||||
*/
|
||||
|
||||
.navds-timeline__popover {
|
||||
z-index: var(--a-z-index-popover);
|
||||
background-color: var(--ac-popover-bg, var(--a-surface-default));
|
||||
box-shadow: var(--a-shadow-medium);
|
||||
z-index: 5;
|
||||
background-color: var(--ax-bg-raised);
|
||||
box-shadow: var(--ax-shadow-dialog);
|
||||
border: 1px solid;
|
||||
border-color: var(--ac-popover-border, var(--a-border-default));
|
||||
border-radius: var(--a-border-radius-large);
|
||||
padding: var(--a-spacing-3);
|
||||
}
|
||||
|
||||
.navds-timeline__popover:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.navds-timeline__popover-arrow {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
transform: rotate(45deg);
|
||||
background-color: var(--ac-popover-bg, var(--a-surface-default));
|
||||
border: 1px solid;
|
||||
border-color: var(--ac-popover-border, var(--a-border-default));
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.navds-timeline__popover[data-placement^="top"] > .navds-timeline__popover-arrow {
|
||||
border-left-color: transparent;
|
||||
border-top-color: transparent;
|
||||
}
|
||||
|
||||
.navds-timeline__popover[data-placement^="bottom"] > .navds-timeline__popover-arrow {
|
||||
border-bottom-color: transparent;
|
||||
border-right-color: transparent;
|
||||
}
|
||||
|
||||
.navds-timeline__popover[data-placement^="left"] > .navds-timeline__popover-arrow {
|
||||
border-left-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
|
||||
.navds-timeline__popover[data-placement^="right"] > .navds-timeline__popover-arrow {
|
||||
border-right-color: transparent;
|
||||
border-top-color: transparent;
|
||||
border-color: var(--ax-border-subtleA);
|
||||
border-radius: var(--ax-border-radius-large);
|
||||
padding: var(--ax-spacing-4) var(--ax-spacing-5);
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
@@ -426,24 +353,4 @@
|
||||
outline-offset: 2px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.navds-timeline__popover[data-placement^="top"] > .navds-timeline__popover-arrow {
|
||||
border-left-color: canvas;
|
||||
border-top-color: canvas;
|
||||
}
|
||||
|
||||
.navds-timeline__popover[data-placement^="bottom"] > .navds-timeline__popover-arrow {
|
||||
border-bottom-color: canvas;
|
||||
border-right-color: canvas;
|
||||
}
|
||||
|
||||
.navds-timeline__popover[data-placement^="left"] > .navds-timeline__popover-arrow {
|
||||
border-left-color: canvas;
|
||||
border-bottom-color: canvas;
|
||||
}
|
||||
|
||||
.navds-timeline__popover[data-placement^="right"] > .navds-timeline__popover-arrow {
|
||||
border-right-color: canvas;
|
||||
border-top-color: canvas;
|
||||
}
|
||||
}
|
||||
@@ -1,81 +1,106 @@
|
||||
@keyframes tooltipFadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
.navds-tooltip {
|
||||
z-index: 3000;
|
||||
background-color: var(--ax-bg-raised);
|
||||
color: var(--ax-text-default);
|
||||
border-radius: var(--ax-border-radius-medium);
|
||||
padding: 0 var(--ax-spacing-1-alt);
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
|
||||
animation-duration: 150ms;
|
||||
text-align: center;
|
||||
border: 1px solid var(--ax-border-subtleA);
|
||||
box-shadow: var(--ax-shadow-dialog);
|
||||
}
|
||||
|
||||
.navds-tooltip:where([data-state="open"]):where([data-side="bottom"]) {
|
||||
animation-name: aksel-tooltip-from-bottom, aksel-tooltip-fade-in;
|
||||
}
|
||||
|
||||
.navds-tooltip:where([data-state="open"]):where([data-side="top"]) {
|
||||
animation-name: aksel-tooltip-from-top, aksel-tooltip-fade-in;
|
||||
}
|
||||
|
||||
.navds-tooltip:where([data-state="open"]):where([data-side="left"]) {
|
||||
animation-name: aksel-tooltip-from-left, aksel-tooltip-fade-in;
|
||||
}
|
||||
|
||||
.navds-tooltip:where([data-state="open"]):where([data-side="right"]) {
|
||||
animation-name: aksel-tooltip-from-right, aksel-tooltip-fade-in;
|
||||
}
|
||||
|
||||
@keyframes aksel-tooltip-from-bottom {
|
||||
from {
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
100% {
|
||||
to {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes aksel-tooltip-from-top {
|
||||
from {
|
||||
transform: translateY(4px);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes aksel-tooltip-from-left {
|
||||
from {
|
||||
transform: translateX(4px);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes aksel-tooltip-from-right {
|
||||
from {
|
||||
transform: translateX(-4px);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes aksel-tooltip-fade-in {
|
||||
from {
|
||||
opacity: 0.01;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.navds-tooltip {
|
||||
z-index: var(--a-z-index-tooltip);
|
||||
background-color: var(--ac-tooltip-bg, var(--a-surface-inverted));
|
||||
color: var(--ac-tooltip-text, var(--a-text-on-inverted));
|
||||
border-radius: var(--a-border-radius-small);
|
||||
padding: 0 var(--a-spacing-2);
|
||||
align-items: center;
|
||||
filter: drop-shadow(0 2px 4px rgba(0 0 0 / 0.1)) drop-shadow(0 4px 6px rgba(0 0 0 / 0.1));
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
animation-duration: 0.2s;
|
||||
animation-name: tooltipFadeIn;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.navds-tooltip__arrow {
|
||||
height: 0.4375rem;
|
||||
width: 0.4375rem;
|
||||
transform: rotate(45deg);
|
||||
z-index: -1;
|
||||
background-color: var(--ac-tooltip-bg, var(--a-surface-inverted));
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.navds-tooltip__keys {
|
||||
padding-bottom: var(--a-spacing-1);
|
||||
padding-bottom: var(--ax-spacing-1);
|
||||
display: flex;
|
||||
gap: var(--a-spacing-1);
|
||||
gap: var(--ax-spacing-1);
|
||||
}
|
||||
|
||||
.navds-tooltip__key {
|
||||
font-family: var(--a-font-family);
|
||||
background-color: var(--ac-tooltip-key-bg, var(--a-surface-neutral));
|
||||
color: var(--ac-tooltip-key-text, var(--a-text-on-inverted));
|
||||
border-radius: var(--a-border-radius-small);
|
||||
padding: 0 var(--a-spacing-1);
|
||||
font-family: var(--ax-font-family);
|
||||
color: var(--ax-text-default);
|
||||
padding: 0 var(--ax-spacing-1);
|
||||
min-width: 1.125rem;
|
||||
height: 1.125rem;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
border-radius: var(--ax-border-radius-small);
|
||||
background: var(--ax-bg-neutral-moderateA);
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.navds-tooltip {
|
||||
--__a-tooltip-high-contrast-border: 1px solid transparent;
|
||||
|
||||
border: var(--__a-tooltip-high-contrast-border);
|
||||
}
|
||||
|
||||
.navds-tooltip[data-side="top"] .navds-tooltip__arrow {
|
||||
border-bottom: var(--__a-tooltip-high-contrast-border);
|
||||
border-right: var(--__a-tooltip-high-contrast-border);
|
||||
}
|
||||
|
||||
.navds-tooltip[data-side="right"] .navds-tooltip__arrow {
|
||||
border-bottom: var(--__a-tooltip-high-contrast-border);
|
||||
border-left: var(--__a-tooltip-high-contrast-border);
|
||||
}
|
||||
|
||||
.navds-tooltip[data-side="bottom"] .navds-tooltip__arrow {
|
||||
border-left: var(--__a-tooltip-high-contrast-border);
|
||||
border-top: var(--__a-tooltip-high-contrast-border);
|
||||
}
|
||||
|
||||
.navds-tooltip[data-side="left"] .navds-tooltip__arrow {
|
||||
border-top: var(--__a-tooltip-high-contrast-border);
|
||||
border-right: var(--__a-tooltip-high-contrast-border);
|
||||
@media (forced-colors: active) {
|
||||
& {
|
||||
outline: 1px solid;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,3 @@
|
||||
/* stylelint-disable csstools/value-no-unknown-custom-properties */
|
||||
|
||||
/* ------------------------- Global typo-definitions ------------------------ */
|
||||
body,
|
||||
:host {
|
||||
font-family: "Source Sans 3", "Source Sans Pro", Arial, sans-serif;
|
||||
line-height: 1.333;
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
|
||||
/* ----------------------------- Typo-components ---------------------------- */
|
||||
|
||||
/* Heading */
|
||||
.navds-heading {
|
||||
font-weight: var(--ax-font-weight-bold);
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
border-color: var(--a-border-subtle);
|
||||
}
|
||||
|
||||
.navds-combobox__button-clear svg,
|
||||
.navds-combobox__button-toggle-list svg,
|
||||
.navds-combobox__list svg {
|
||||
width: var(--__ac-combobox-icon-size);
|
||||
@@ -195,19 +194,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.navds-combobox__button-clear {
|
||||
border-radius: var(--a-border-radius-medium);
|
||||
color: var(--ac-combobox-clear-icon, var(--a-text-subtle));
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 1rem;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.navds-combobox__input::-webkit-search-cancel-button {
|
||||
display: none;
|
||||
}
|
||||
@@ -225,14 +211,12 @@
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.navds-combobox__button-clear:active:hover,
|
||||
.navds-combobox__button-toggle-list:active:hover {
|
||||
color: var(--ac-combobox-clear-icon-active, var(--a-text-action));
|
||||
color: var(--a-text-action);
|
||||
}
|
||||
|
||||
.navds-combobox__button-clear:hover,
|
||||
.navds-combobox__button-toggle-list:hover {
|
||||
color: var(--ac-combobox-clear-icon-hover, var(--a-text-action-selected));
|
||||
color: var(--a-text-action-selected);
|
||||
}
|
||||
|
||||
.navds-combobox__button-toggle-list:focus-visible {
|
||||
@@ -406,10 +390,6 @@
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.navds-combobox__button-clear:hover {
|
||||
color: highlight;
|
||||
}
|
||||
|
||||
.navds-combobox__wrapper-inner:has(.navds-combobox__input:focus-visible) {
|
||||
outline-color: highlight;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.navds-alert .navds-link,
|
||||
.navds-alert:not(.navds-alert--inline) .navds-link,
|
||||
.navds-confirmation-panel .navds-link {
|
||||
color: var(--a-text-default);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "@navikt/ds-css",
|
||||
"version": "7.7.0",
|
||||
"description": "CSS for NAV Designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"version": "7.8.1",
|
||||
"description": "CSS for Nav Designsystem",
|
||||
"author": "Aksel | Nav designsystem team",
|
||||
"keywords": [
|
||||
"css"
|
||||
],
|
||||
@@ -20,29 +20,43 @@
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/navikt/aksel.git"
|
||||
},
|
||||
"main": "./dist/index.css",
|
||||
"scripts": {
|
||||
"build": "node config/bundle.js",
|
||||
"build": "node config/bundle.js && yarn build:darkside",
|
||||
"watch": "nodemon --ignore dist -e css --watch . --exec \"yarn build\"",
|
||||
"css:get-version": "node config/get-version.js"
|
||||
"css:get-version": "node config/get-version.js",
|
||||
"build:darkside": "tsx ./config/bundle.darkside.ts",
|
||||
"test": "yarn build && vitest run"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@navikt/ds-tokens": "^7.7.0",
|
||||
"@navikt/ds-tokens": "^7.8.1",
|
||||
"@types/clean-css": "4.2.11",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"browserslist": "^4.24.2",
|
||||
"clean-css": "5.3.3",
|
||||
"cssnano": "6.0.0",
|
||||
"fast-glob": "3.2.11",
|
||||
"lightningcss": "^1.28.0",
|
||||
"lodash": "^4.17.21",
|
||||
"nodemon": "^3.0.1",
|
||||
"normalize.css": "^8.0.1",
|
||||
"postcss": "^8.4.31",
|
||||
"postcss-cli": "^9.0.0",
|
||||
"postcss-combine-duplicated-selectors": "10.0.3",
|
||||
"postcss-import": "^14.1.0"
|
||||
"postcss-import": "^14.1.0",
|
||||
"tsx": "^4.7.1",
|
||||
"vitest": "^1.2.2"
|
||||
},
|
||||
"browserslist": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not ie <= 11",
|
||||
"not op_mini all"
|
||||
]
|
||||
],
|
||||
"main": "./dist/index.css",
|
||||
"exports": {
|
||||
".": "./dist/index.css",
|
||||
"./dist/*": "./dist/*",
|
||||
"./darkside": "./dist/darkside/index.min.css",
|
||||
"./tokens.json": "./tokens.json"
|
||||
}
|
||||
}
|
||||
@@ -206,7 +206,7 @@
|
||||
transition: transform 150ms ease-in-out;
|
||||
}
|
||||
|
||||
.navds-table__toggle-expand-cell:hover {
|
||||
.navds-table__expandable-row:not(.navds-table__expandable-row--expansion-disabled) .navds-table__toggle-expand-cell:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
@@ -127,37 +127,43 @@
|
||||
color: var(--ac-tag-neutral-moderate-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--alt1 {
|
||||
.navds-tag--alt1,
|
||||
.navds-tag--outline.navds-tag--meta-purple {
|
||||
border-color: var(--ac-tag-alt-1-border, var(--a-border-alt-1));
|
||||
background-color: var(--ac-tag-alt-1-bg, var(--a-surface-alt-1-subtle));
|
||||
color: var(--ac-tag-alt-1-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--alt1-filled {
|
||||
.navds-tag--alt1-filled,
|
||||
.navds-tag--strong.navds-tag--meta-purple {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-alt-1-filled-bg, var(--a-surface-alt-1));
|
||||
color: var(--ac-tag-alt-1-filled-text, var(--a-text-on-alt-1));
|
||||
}
|
||||
|
||||
.navds-tag--alt1-moderate {
|
||||
.navds-tag--alt1-moderate,
|
||||
.navds-tag--moderate.navds-tag--meta-purple {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-alt-1-moderate-bg, var(--a-surface-alt-1-moderate));
|
||||
color: var(--ac-tag-alt-1-moderate-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--alt2 {
|
||||
.navds-tag--alt2,
|
||||
.navds-tag--outline.navds-tag--meta-lime {
|
||||
border-color: var(--ac-tag-alt-2-border, var(--a-border-alt-2));
|
||||
background-color: var(--ac-tag-alt-2-bg, var(--a-surface-alt-2-subtle));
|
||||
color: var(--ac-tag-alt-2-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--alt2-filled {
|
||||
.navds-tag--alt2-filled,
|
||||
.navds-tag--strong.navds-tag--meta-lime {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-alt-2-filled-bg, var(--a-surface-alt-2));
|
||||
color: var(--ac-tag-alt-2-filled-text, var(--a-text-on-alt-2));
|
||||
}
|
||||
|
||||
.navds-tag--alt2-moderate {
|
||||
.navds-tag--alt2-moderate,
|
||||
.navds-tag--moderate.navds-tag--meta-lime {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-alt-2-moderate-bg, var(--a-surface-alt-2-moderate));
|
||||
color: var(--ac-tag-alt-2-moderate-text, var(--a-text-default));
|
||||
|
||||
@@ -387,9 +387,6 @@
|
||||
"--ac-search-error-border": "--a-border-danger"
|
||||
},
|
||||
"combobox": {
|
||||
"--ac-combobox-clear-icon": "--a-text-subtle",
|
||||
"--ac-combobox-clear-icon-hover": "--a-text-action-selected",
|
||||
"--ac-combobox-clear-icon-active": "--a-text-action",
|
||||
"--ac-combobox-list-bg": "--a-surface-default",
|
||||
"--ac-combobox-list-text": "--a-text-default",
|
||||
"--ac-combobox-list-border-color": "--a-border-divider",
|
||||
|
||||
@@ -1,5 +1,45 @@
|
||||
# @navikt/ds-react
|
||||
|
||||
## 7.8.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Combobox: Only open dropdown-list onClick, not onFocus. ([#3440](https://github.com/navikt/aksel/pull/3440))
|
||||
|
||||
- Combobox: Fix issue where you could select more options than defined in maxSelected ([#3434](https://github.com/navikt/aksel/pull/3434))
|
||||
|
||||
- Timeline: In cases where earliest found date were after current date, timeline-start ended up defaulting to current date. ([#3458](https://github.com/navikt/aksel/pull/3458))
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-tokens@7.8.1
|
||||
- @navikt/aksel-icons@7.8.1
|
||||
|
||||
## 7.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Chips.Removable: Removed prop `removeLabel` ([#3429](https://github.com/navikt/aksel/pull/3429))
|
||||
|
||||
- i18n: :sparkles: Implemented i18n support for all components. Components come with support for nb, nn and en locales ([Docs](https://aksel.nav.no/komponenter/core/provider#84d7ea5ec517)) ([#3429](https://github.com/navikt/aksel/pull/3429))
|
||||
|
||||
- Combobox: Removed clear button, removed tokens staring with `--ac-combobox-clear`, deprecated props `clearButton`/`clearButtonLabel`. ([#3433](https://github.com/navikt/aksel/pull/3433))
|
||||
|
||||
- Combobox: Changed prop `maxSelected` to number ([#3433](https://github.com/navikt/aksel/pull/3433))
|
||||
|
||||
- DatePicker/MonthPicker: Added new `translations` prop and deprecated `locale` prop ([#3429](https://github.com/navikt/aksel/pull/3429))
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Timeline: Deprecated prop `axisLabelTemplates`. Use [Provider](https://aksel.nav.no/komponenter/core/provider#84d7ea5ec517) if you still need to change the date formats. ([#3429](https://github.com/navikt/aksel/pull/3429))
|
||||
|
||||
- Search: Deprecated prop `clearButtonLabel`. Use [Provider](https://aksel.nav.no/komponenter/core/provider#84d7ea5ec517) if you still need to change the label. ([#3429](https://github.com/navikt/aksel/pull/3429))
|
||||
|
||||
- Textarea: Deprecated prop `i18n`. Use [Provider](https://aksel.nav.no/komponenter/core/provider#84d7ea5ec517) if you still need to change these texts. ([#3429](https://github.com/navikt/aksel/pull/3429))
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-tokens@7.8.0
|
||||
- @navikt/aksel-icons@7.8.0
|
||||
|
||||
## 7.7.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react",
|
||||
"version": "7.7.0",
|
||||
"version": "7.8.1",
|
||||
"description": "React components from the Norwegian Labour and Welfare Administration.",
|
||||
"author": "Aksel, a team part of the Norwegian Labour and Welfare Administration.",
|
||||
"license": "MIT",
|
||||
@@ -8,7 +8,7 @@
|
||||
"react",
|
||||
"typescript",
|
||||
"javascript",
|
||||
"NAV"
|
||||
"Nav"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -40,6 +40,16 @@
|
||||
"default": "./cjs/index.js"
|
||||
}
|
||||
},
|
||||
"./locales": {
|
||||
"import": {
|
||||
"types": "./esm/util/i18n/locales/index.d.ts",
|
||||
"default": "./esm/util/i18n/locales/index.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./cjs/util/i18n/locales/index.d.ts",
|
||||
"default": "./cjs/util/i18n/locales/index.js"
|
||||
}
|
||||
},
|
||||
"./Accordion": {
|
||||
"import": {
|
||||
"types": "./esm/accordion/index.d.ts",
|
||||
@@ -604,8 +614,8 @@
|
||||
"dependencies": {
|
||||
"@floating-ui/react": "0.25.4",
|
||||
"@floating-ui/react-dom": "^2.0.9",
|
||||
"@navikt/aksel-icons": "^7.7.0",
|
||||
"@navikt/ds-tokens": "^7.7.0",
|
||||
"@navikt/aksel-icons": "^7.8.1",
|
||||
"@navikt/ds-tokens": "^7.8.1",
|
||||
"clsx": "^2.1.0",
|
||||
"date-fns": "^3.0.0",
|
||||
"react-day-picker": "8.10.1"
|
||||
|
||||
@@ -96,8 +96,8 @@ export const Inline: StoryFn = () => {
|
||||
<Alert variant="info" inline>
|
||||
Id elit esse enim reprehenderit enim nisi veniam nostrud. Id elit esse
|
||||
enim reprehenderit enim nisi veniam nostrud. Id elit esse enim
|
||||
reprehenderit enim nisi veniam nostrud. Id elit esse enim reprehenderit
|
||||
enim nisi veniam nostrud.
|
||||
reprehenderit enim nisi veniam nostrud.{" "}
|
||||
<Link href="#">Id elit esse enim reprehenderit</Link>
|
||||
</Alert>
|
||||
<Alert variant="info" size="small" inline>
|
||||
Id elit esse enim reprehenderit enim nisi veniam nostrud.
|
||||
@@ -105,8 +105,8 @@ export const Inline: StoryFn = () => {
|
||||
<Alert variant="info" size="small" inline>
|
||||
Id elit esse enim reprehenderit enim nisi veniam nostrud. Id elit esse
|
||||
enim reprehenderit enim nisi veniam nostrud. Id elit esse enim
|
||||
reprehenderit enim nisi veniam nostrud. Id elit esse enim reprehenderit
|
||||
enim nisi veniam nostrud.
|
||||
reprehenderit enim nisi veniam nostrud.{" "}
|
||||
<Link href="#">Id elit esse enim reprehenderit</Link>
|
||||
</Alert>
|
||||
</VStack>
|
||||
);
|
||||
|
||||
@@ -16,11 +16,6 @@ export interface ChipsRemovableProps
|
||||
* Click callback
|
||||
*/
|
||||
onDelete?: () => void;
|
||||
/**
|
||||
* Replaces label read for screen-readers
|
||||
* @default "slett"
|
||||
*/
|
||||
removeLabel?: string;
|
||||
}
|
||||
|
||||
export const RemovableChips = forwardRef<
|
||||
@@ -32,7 +27,6 @@ export const RemovableChips = forwardRef<
|
||||
children,
|
||||
variant = "action",
|
||||
onDelete,
|
||||
removeLabel,
|
||||
className,
|
||||
onClick,
|
||||
type = "button",
|
||||
@@ -51,9 +45,7 @@ export const RemovableChips = forwardRef<
|
||||
className,
|
||||
`navds-chips__removable--${variant}`,
|
||||
)}
|
||||
aria-label={`${children} ${
|
||||
removeLabel ?? translate("Removable.labelSuffix")
|
||||
}`}
|
||||
aria-label={`${children} ${translate("Removable.labelSuffix")}`}
|
||||
onClick={composeEventHandlers(onClick, onDelete)}
|
||||
>
|
||||
<span className="navds-chips__chip-text">{children}</span>
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
export { useDateInputContext, DateContext } from "./useDateInputContext";
|
||||
export { useDateInputContext, DateInputContext } from "./useDateInputContext";
|
||||
export {
|
||||
useSharedMonthContext,
|
||||
SharedMonthProvider,
|
||||
} from "./useSharedMonthContext";
|
||||
export {
|
||||
useDateTranslationContext,
|
||||
DateTranslationContextProvider,
|
||||
} from "./useDateTranslationContext";
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createContext, useContext } from "react";
|
||||
|
||||
interface DateContextContextProps {
|
||||
interface DateInputContextProps {
|
||||
/**
|
||||
* Open state for popover
|
||||
*/
|
||||
@@ -19,13 +19,15 @@ interface DateContextContextProps {
|
||||
defined: boolean;
|
||||
}
|
||||
|
||||
export const DateContext = createContext<DateContextContextProps | null>(null);
|
||||
export const DateInputContext = createContext<DateInputContextProps | null>(
|
||||
null,
|
||||
);
|
||||
|
||||
export const useDateInputContext = () => {
|
||||
const context = useContext(DateContext);
|
||||
const context = useContext(DateInputContext);
|
||||
|
||||
if (!context) {
|
||||
console.warn("useDateInputContext must be used with DateContext");
|
||||
console.warn("useDateInputContext must be used with DateInputContext");
|
||||
}
|
||||
|
||||
return context;
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { createContext } from "../../util/create-context";
|
||||
import { TFunction } from "../../util/i18n/i18n.context";
|
||||
|
||||
interface DateTranslationContextProps {
|
||||
translate: TFunction<"DatePicker">;
|
||||
}
|
||||
|
||||
export const [DateTranslationContextProvider, useDateTranslationContext] =
|
||||
createContext<DateTranslationContextProps>();
|
||||
@@ -5,11 +5,11 @@ import { DateRange, DayPicker, isMatch } from "react-day-picker";
|
||||
import { omit } from "../../util";
|
||||
import { useId } from "../../util/hooks";
|
||||
import { useMergeRefs } from "../../util/hooks/useMergeRefs";
|
||||
import { useDateLocale } from "../../util/i18n/i18n.context";
|
||||
import { DateContext } from "../context";
|
||||
import { useDateLocale, useI18n } from "../../util/i18n/i18n.context";
|
||||
import { DateInputContext, DateTranslationContextProvider } from "../context";
|
||||
import { DatePickerInput } from "../parts/DateInput";
|
||||
import { DateWrapper } from "../parts/DateWrapper";
|
||||
import { getLocaleFromString } from "../utils";
|
||||
import { getLocaleFromString, getTranslations } from "../utils";
|
||||
import DatePickerStandalone from "./DatePickerStandalone";
|
||||
import Caption from "./parts/Caption";
|
||||
import DropdownCaption from "./parts/DropdownCaption";
|
||||
@@ -68,6 +68,7 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
|
||||
{
|
||||
children,
|
||||
locale,
|
||||
translations,
|
||||
dropdownCaption,
|
||||
disabled = [],
|
||||
disableWeekends = false,
|
||||
@@ -86,6 +87,11 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const translate = useI18n(
|
||||
"DatePicker",
|
||||
translations,
|
||||
getTranslations(locale),
|
||||
);
|
||||
const langProviderLocale = useDateLocale();
|
||||
const ariaId = useId(id);
|
||||
const [open, setOpen] = useState(_open ?? false);
|
||||
@@ -151,37 +157,40 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
|
||||
);
|
||||
|
||||
return (
|
||||
<DateContext.Provider
|
||||
value={{
|
||||
open: _open ?? open,
|
||||
onOpen: () => {
|
||||
setOpen((x) => !x);
|
||||
onOpenToggle?.();
|
||||
},
|
||||
ariaId,
|
||||
defined: true,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
ref={mergedRef}
|
||||
className={cl("navds-date__wrapper", wrapperClassName)}
|
||||
<DateTranslationContextProvider translate={translate}>
|
||||
<DateInputContext.Provider
|
||||
value={{
|
||||
open: _open ?? open,
|
||||
onOpen: () => {
|
||||
setOpen((x) => !x);
|
||||
onOpenToggle?.();
|
||||
},
|
||||
ariaId,
|
||||
defined: true,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
<DateWrapper
|
||||
open={_open ?? open}
|
||||
anchor={wrapperRef}
|
||||
onClose={() => onClose?.() ?? setOpen(false)}
|
||||
locale={locale}
|
||||
variant={mode}
|
||||
popoverProps={{
|
||||
id: ariaId,
|
||||
strategy,
|
||||
}}
|
||||
<div
|
||||
ref={mergedRef}
|
||||
className={cl("navds-date__wrapper", wrapperClassName)}
|
||||
>
|
||||
{DatePickerComponent}
|
||||
</DateWrapper>
|
||||
</div>
|
||||
</DateContext.Provider>
|
||||
{children}
|
||||
<DateWrapper
|
||||
open={_open ?? open}
|
||||
anchor={wrapperRef}
|
||||
onClose={() => onClose?.() ?? setOpen(false)}
|
||||
locale={locale}
|
||||
translate={translate}
|
||||
variant={mode}
|
||||
popoverProps={{
|
||||
id: ariaId,
|
||||
strategy,
|
||||
}}
|
||||
>
|
||||
{DatePickerComponent}
|
||||
</DateWrapper>
|
||||
</div>
|
||||
</DateInputContext.Provider>
|
||||
</DateTranslationContextProvider>
|
||||
);
|
||||
},
|
||||
) as DatePickerComponent;
|
||||
|
||||
@@ -3,8 +3,9 @@ import { isWeekend } from "date-fns";
|
||||
import React, { forwardRef } from "react";
|
||||
import { DateRange, DayPicker, isMatch } from "react-day-picker";
|
||||
import { omit } from "../../util";
|
||||
import { useDateLocale } from "../../util/i18n/i18n.context";
|
||||
import { getLocaleFromString } from "../utils";
|
||||
import { useDateLocale, useI18n } from "../../util/i18n/i18n.context";
|
||||
import { DateTranslationContextProvider } from "../context";
|
||||
import { getLocaleFromString, getTranslations } from "../utils";
|
||||
import Caption from "./parts/Caption";
|
||||
import DropdownCaption from "./parts/DropdownCaption";
|
||||
import { HeadRow } from "./parts/HeadRow";
|
||||
@@ -51,6 +52,7 @@ export const DatePickerStandalone: DatePickerStandaloneType = forwardRef<
|
||||
{
|
||||
className,
|
||||
locale,
|
||||
translations,
|
||||
dropdownCaption,
|
||||
disabled = [],
|
||||
disableWeekends = false,
|
||||
@@ -64,6 +66,11 @@ export const DatePickerStandalone: DatePickerStandaloneType = forwardRef<
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const translate = useI18n(
|
||||
"DatePicker",
|
||||
translations,
|
||||
getTranslations(locale),
|
||||
);
|
||||
const langProviderLocale = useDateLocale();
|
||||
const [selectedDates, setSelectedDates] = React.useState<
|
||||
Date | Date[] | DateRange | undefined
|
||||
@@ -84,41 +91,43 @@ export const DatePickerStandalone: DatePickerStandaloneType = forwardRef<
|
||||
ref={ref}
|
||||
className={cl("navds-date__standalone-wrapper", className)}
|
||||
>
|
||||
<DayPicker
|
||||
locale={locale ? getLocaleFromString(locale) : langProviderLocale}
|
||||
mode={mode}
|
||||
onSelect={handleSelect}
|
||||
selected={selected ?? selectedDates}
|
||||
components={{
|
||||
Caption: dropdownCaption ? DropdownCaption : Caption,
|
||||
Head: TableHead,
|
||||
HeadRow,
|
||||
WeekNumber,
|
||||
Row,
|
||||
}}
|
||||
className="navds-date"
|
||||
classNames={{ vhidden: "navds-sr-only" }}
|
||||
disabled={(day) => {
|
||||
return (
|
||||
(disableWeekends && isWeekend(day)) || isMatch(day, disabled)
|
||||
);
|
||||
}}
|
||||
weekStartsOn={1}
|
||||
initialFocus={false}
|
||||
modifiers={{
|
||||
weekend: (day) => disableWeekends && isWeekend(day),
|
||||
}}
|
||||
modifiersClassNames={{
|
||||
weekend: "rdp-day__weekend",
|
||||
}}
|
||||
showWeekNumber={showWeekNumber}
|
||||
onWeekNumberClick={
|
||||
mode === "multiple" ? onWeekNumberClick : undefined
|
||||
}
|
||||
fixedWeeks={fixedWeeks}
|
||||
showOutsideDays
|
||||
{...omit(rest, ["children", "id"])}
|
||||
/>
|
||||
<DateTranslationContextProvider translate={translate}>
|
||||
<DayPicker
|
||||
locale={locale ? getLocaleFromString(locale) : langProviderLocale}
|
||||
mode={mode}
|
||||
onSelect={handleSelect}
|
||||
selected={selected ?? selectedDates}
|
||||
components={{
|
||||
Caption: dropdownCaption ? DropdownCaption : Caption,
|
||||
Head: TableHead,
|
||||
HeadRow,
|
||||
WeekNumber,
|
||||
Row,
|
||||
}}
|
||||
className="navds-date"
|
||||
classNames={{ vhidden: "navds-sr-only" }}
|
||||
disabled={(day) => {
|
||||
return (
|
||||
(disableWeekends && isWeekend(day)) || isMatch(day, disabled)
|
||||
);
|
||||
}}
|
||||
weekStartsOn={1}
|
||||
initialFocus={false}
|
||||
modifiers={{
|
||||
weekend: (day) => disableWeekends && isWeekend(day),
|
||||
}}
|
||||
modifiersClassNames={{
|
||||
weekend: "rdp-day__weekend",
|
||||
}}
|
||||
showWeekNumber={showWeekNumber}
|
||||
onWeekNumberClick={
|
||||
mode === "multiple" ? onWeekNumberClick : undefined
|
||||
}
|
||||
fixedWeeks={fixedWeeks}
|
||||
showOutsideDays
|
||||
{...omit(rest, ["children", "id"])}
|
||||
/>
|
||||
</DateTranslationContextProvider>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -247,7 +247,7 @@ export const Validering = () => {
|
||||
<DatePicker.Input
|
||||
error={
|
||||
error
|
||||
? "NAV-kontoret er ikke åpent i helger. Velg en annen dag."
|
||||
? "Nav-kontoret er ikke åpent i helger. Velg en annen dag."
|
||||
: undefined
|
||||
}
|
||||
{...inputProps}
|
||||
|
||||
@@ -3,8 +3,7 @@ import { CaptionProps, useDayPicker, useNavigation } from "react-day-picker";
|
||||
import { ArrowLeftIcon, ArrowRightIcon } from "@navikt/aksel-icons";
|
||||
import { Button } from "../../../button";
|
||||
import { Label } from "../../../typography";
|
||||
import { useI18n } from "../../../util/i18n/i18n.context";
|
||||
import { getTranslations } from "../../utils";
|
||||
import { useDateTranslationContext } from "../../context";
|
||||
import WeekRow from "./WeekRow";
|
||||
|
||||
/**
|
||||
@@ -16,7 +15,7 @@ export const DatePickerCaption = ({ displayMonth, id }: CaptionProps) => {
|
||||
formatters: { formatCaption },
|
||||
locale,
|
||||
} = useDayPicker();
|
||||
const translate = useI18n("DatePicker", getTranslations(locale.code));
|
||||
const translate = useDateTranslationContext().translate;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -4,8 +4,8 @@ import { CaptionProps, useDayPicker, useNavigation } from "react-day-picker";
|
||||
import { ArrowLeftIcon, ArrowRightIcon } from "@navikt/aksel-icons";
|
||||
import { Button } from "../../../button";
|
||||
import { Select } from "../../../form/select";
|
||||
import { useI18n } from "../../../util/i18n/i18n.context";
|
||||
import { getMonths, getTranslations, getYears } from "../../utils";
|
||||
import { useDateTranslationContext } from "../../context";
|
||||
import { getMonths, getYears } from "../../utils";
|
||||
import WeekRow from "./WeekRow";
|
||||
|
||||
/**
|
||||
@@ -19,7 +19,7 @@ export const DropdownCaption = ({ displayMonth, id }: CaptionProps) => {
|
||||
formatters: { formatYearCaption, formatMonthCaption, formatCaption },
|
||||
locale,
|
||||
} = useDayPicker();
|
||||
const translate = useI18n("DatePicker", getTranslations(locale.code));
|
||||
const translate = useDateTranslationContext().translate;
|
||||
|
||||
if (!fromDate || !toDate) {
|
||||
console.warn("Using dropdownCaption required fromDate and toDate");
|
||||
|
||||
@@ -4,8 +4,7 @@ import { Button as RDPButton, useDayPicker } from "react-day-picker";
|
||||
import { Button } from "../../../button";
|
||||
import { UNSAFE_useAkselTheme } from "../../../provider";
|
||||
import { Detail } from "../../../typography";
|
||||
import { useI18n } from "../../../util/i18n/i18n.context";
|
||||
import { getTranslations } from "../../utils";
|
||||
import { useDateTranslationContext } from "../../context";
|
||||
|
||||
export interface WeekNumberProps {
|
||||
/** The number of the week. */
|
||||
@@ -21,14 +20,9 @@ function WeekNumber({
|
||||
number: weekNumber,
|
||||
dates,
|
||||
}: WeekNumberProps): JSX.Element {
|
||||
const {
|
||||
onWeekNumberClick,
|
||||
styles,
|
||||
classNames,
|
||||
locale: { code },
|
||||
} = useDayPicker();
|
||||
const { onWeekNumberClick, styles, classNames } = useDayPicker();
|
||||
const themeContext = UNSAFE_useAkselTheme(false);
|
||||
const translate = useI18n("DatePicker", getTranslations(code));
|
||||
const translate = useDateTranslationContext().translate;
|
||||
|
||||
if (!onWeekNumberClick) {
|
||||
return (
|
||||
|
||||
@@ -3,14 +3,13 @@ import { useDayPicker } from "react-day-picker";
|
||||
import { Show } from "../../../layout/responsive";
|
||||
import { Detail } from "../../../typography";
|
||||
import { useId } from "../../../util/hooks";
|
||||
import { useI18n } from "../../../util/i18n/i18n.context";
|
||||
import { getTranslations } from "../../utils";
|
||||
import { useDateTranslationContext } from "../../context";
|
||||
import { getMonthWeeks } from "../../utils/get-month-weeks";
|
||||
import WeekNumber from "./WeekNumber";
|
||||
|
||||
const WeekRow = ({ displayMonth }: { displayMonth: Date }) => {
|
||||
const { locale, fixedWeeks, onWeekNumberClick } = useDayPicker();
|
||||
const translate = useI18n("DatePicker", getTranslations(locale.code));
|
||||
const translate = useDateTranslationContext().translate;
|
||||
const labelId = useId();
|
||||
|
||||
if (!onWeekNumberClick) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { DateRange, DayPickerBase, Matcher } from "react-day-picker";
|
||||
import { ComponentTranslation } from "../../util/i18n/i18n.types";
|
||||
|
||||
export type SingleMode = {
|
||||
mode?: "single";
|
||||
@@ -52,8 +53,15 @@ export interface DatePickerDefaultProps
|
||||
/**
|
||||
* Changes datepicker locale
|
||||
* @default "nb" (norsk bokmål)
|
||||
* @deprecated Use `<Provider />`-component
|
||||
*/
|
||||
locale?: "nb" | "nn" | "en";
|
||||
/**
|
||||
* i18n-API for customizing texts and labels.
|
||||
*
|
||||
* **NB: If you need to change the language, use [Provider](https://aksel.nav.no/komponenter/core/provider#84d7ea5ec517) instead.**
|
||||
*/
|
||||
translations?: ComponentTranslation<"DatePicker">;
|
||||
/**
|
||||
* The earliest day to start navigation.
|
||||
*/
|
||||
|
||||
@@ -10,9 +10,7 @@ import { useDayPicker } from "react-day-picker";
|
||||
import { ArrowLeftIcon, ArrowRightIcon } from "@navikt/aksel-icons";
|
||||
import { Button } from "../../button";
|
||||
import { Select } from "../../form/select";
|
||||
import { useI18n } from "../../util/i18n/i18n.context";
|
||||
import { useSharedMonthContext } from "../context";
|
||||
import { getTranslations } from "../utils";
|
||||
import { useDateTranslationContext, useSharedMonthContext } from "../context";
|
||||
|
||||
export const MonthCaption = () => {
|
||||
const {
|
||||
@@ -22,7 +20,7 @@ export const MonthCaption = () => {
|
||||
locale,
|
||||
} = useDayPicker();
|
||||
const { hasDropdown, year, toYear } = useSharedMonthContext();
|
||||
const translate = useI18n("DatePicker", getTranslations(locale.code));
|
||||
const translate = useDateTranslationContext().translate;
|
||||
|
||||
const years: Date[] = [];
|
||||
|
||||
|
||||
@@ -3,11 +3,15 @@ import React, { forwardRef, useState } from "react";
|
||||
import { DayPickerProvider } from "react-day-picker";
|
||||
import { useId } from "../../util/hooks";
|
||||
import { useMergeRefs } from "../../util/hooks/useMergeRefs";
|
||||
import { useDateLocale } from "../../util/i18n/i18n.context";
|
||||
import { DateContext, SharedMonthProvider } from "../context";
|
||||
import { useDateLocale, useI18n } from "../../util/i18n/i18n.context";
|
||||
import {
|
||||
DateInputContext,
|
||||
DateTranslationContextProvider,
|
||||
SharedMonthProvider,
|
||||
} from "../context";
|
||||
import { MonthPickerInput } from "../parts/DateInput";
|
||||
import { DateWrapper } from "../parts/DateWrapper";
|
||||
import { getLocaleFromString } from "../utils";
|
||||
import { getLocaleFromString, getTranslations } from "../utils";
|
||||
import MonthCaption from "./MonthCaption";
|
||||
import MonthPickerStandalone from "./MonthPickerStandalone";
|
||||
import MonthSelector from "./MonthSelector";
|
||||
@@ -69,6 +73,7 @@ export const MonthPicker = forwardRef<HTMLDivElement, MonthPickerProps>(
|
||||
onClose,
|
||||
onOpenToggle,
|
||||
locale,
|
||||
translations,
|
||||
onMonthSelect,
|
||||
className,
|
||||
wrapperClassName,
|
||||
@@ -79,6 +84,11 @@ export const MonthPicker = forwardRef<HTMLDivElement, MonthPickerProps>(
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const translate = useI18n(
|
||||
"DatePicker",
|
||||
translations,
|
||||
getTranslations(locale),
|
||||
);
|
||||
const langProviderLocale = useDateLocale();
|
||||
const ariaId = useId(id);
|
||||
const [open, setOpen] = useState(_open ?? false);
|
||||
@@ -103,61 +113,64 @@ export const MonthPicker = forwardRef<HTMLDivElement, MonthPickerProps>(
|
||||
}
|
||||
|
||||
return (
|
||||
<DateContext.Provider
|
||||
value={{
|
||||
open: _open ?? open,
|
||||
onOpen: () => {
|
||||
setOpen((x) => !x);
|
||||
onOpenToggle?.();
|
||||
},
|
||||
ariaId,
|
||||
defined: true,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
ref={mergedRef}
|
||||
className={cl("navds-date__wrapper", wrapperClassName)}
|
||||
<DateTranslationContextProvider translate={translate}>
|
||||
<DateInputContext.Provider
|
||||
value={{
|
||||
open: _open ?? open,
|
||||
onOpen: () => {
|
||||
setOpen((x) => !x);
|
||||
onOpenToggle?.();
|
||||
},
|
||||
ariaId,
|
||||
defined: true,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
<DateWrapper
|
||||
open={_open ?? open}
|
||||
anchor={wrapperRef}
|
||||
onClose={() => onClose?.() ?? setOpen(false)}
|
||||
locale={locale}
|
||||
variant="month"
|
||||
popoverProps={{
|
||||
id: ariaId,
|
||||
strategy,
|
||||
}}
|
||||
<div
|
||||
ref={mergedRef}
|
||||
className={cl("navds-date__wrapper", wrapperClassName)}
|
||||
>
|
||||
<DayPickerProvider
|
||||
initialProps={{
|
||||
locale: locale
|
||||
? getLocaleFromString(locale)
|
||||
: langProviderLocale,
|
||||
selected: selected ?? selectedMonth,
|
||||
toDate,
|
||||
fromDate,
|
||||
month: selected ?? selectedMonth,
|
||||
{children}
|
||||
<DateWrapper
|
||||
open={_open ?? open}
|
||||
anchor={wrapperRef}
|
||||
onClose={() => onClose?.() ?? setOpen(false)}
|
||||
locale={locale}
|
||||
translate={translate}
|
||||
variant="month"
|
||||
popoverProps={{
|
||||
id: ariaId,
|
||||
strategy,
|
||||
}}
|
||||
>
|
||||
<div className={cl("rdp-month", className)}>
|
||||
<SharedMonthProvider
|
||||
dropdownCaption={dropdownCaption}
|
||||
disabled={disabled}
|
||||
selected={selected ?? selectedMonth}
|
||||
onSelect={handleSelect}
|
||||
year={year}
|
||||
onYearChange={onYearChange}
|
||||
>
|
||||
<MonthCaption />
|
||||
<MonthSelector />
|
||||
</SharedMonthProvider>
|
||||
</div>
|
||||
</DayPickerProvider>
|
||||
</DateWrapper>
|
||||
</div>
|
||||
</DateContext.Provider>
|
||||
<DayPickerProvider
|
||||
initialProps={{
|
||||
locale: locale
|
||||
? getLocaleFromString(locale)
|
||||
: langProviderLocale,
|
||||
selected: selected ?? selectedMonth,
|
||||
toDate,
|
||||
fromDate,
|
||||
month: selected ?? selectedMonth,
|
||||
}}
|
||||
>
|
||||
<div className={cl("rdp-month", className)}>
|
||||
<SharedMonthProvider
|
||||
dropdownCaption={dropdownCaption}
|
||||
disabled={disabled}
|
||||
selected={selected ?? selectedMonth}
|
||||
onSelect={handleSelect}
|
||||
year={year}
|
||||
onYearChange={onYearChange}
|
||||
>
|
||||
<MonthCaption />
|
||||
<MonthSelector />
|
||||
</SharedMonthProvider>
|
||||
</div>
|
||||
</DayPickerProvider>
|
||||
</DateWrapper>
|
||||
</div>
|
||||
</DateInputContext.Provider>
|
||||
</DateTranslationContextProvider>
|
||||
);
|
||||
},
|
||||
) as MonthPickerComponent;
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef, useState } from "react";
|
||||
import { DayPickerProvider } from "react-day-picker";
|
||||
import { SharedMonthProvider } from "../context";
|
||||
import { getLocaleFromString } from "../utils";
|
||||
import { useDateLocale, useI18n } from "../../util/i18n/i18n.context";
|
||||
import {
|
||||
DateTranslationContextProvider,
|
||||
SharedMonthProvider,
|
||||
} from "../context";
|
||||
import { getLocaleFromString, getTranslations } from "../utils";
|
||||
import MonthCaption from "./MonthCaption";
|
||||
import MonthSelector from "./MonthSelector";
|
||||
import { MonthPickerProps } from "./types";
|
||||
@@ -34,7 +38,8 @@ export const MonthPickerStandalone = forwardRef<
|
||||
disabled = [],
|
||||
selected,
|
||||
className,
|
||||
locale = "nb",
|
||||
locale,
|
||||
translations,
|
||||
onMonthSelect,
|
||||
defaultSelected,
|
||||
year,
|
||||
@@ -42,6 +47,12 @@ export const MonthPickerStandalone = forwardRef<
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const translate = useI18n(
|
||||
"DatePicker",
|
||||
translations,
|
||||
getTranslations(locale),
|
||||
);
|
||||
const langProviderLocale = useDateLocale();
|
||||
const [selectedMonth, setSelectedMonth] = useState<Date | undefined>(
|
||||
defaultSelected,
|
||||
);
|
||||
@@ -58,29 +69,31 @@ export const MonthPickerStandalone = forwardRef<
|
||||
|
||||
return (
|
||||
<div ref={ref} className={cl("navds-date__wrapper", className)}>
|
||||
<DayPickerProvider
|
||||
initialProps={{
|
||||
locale: getLocaleFromString(locale),
|
||||
selected: selected ?? selectedMonth,
|
||||
toDate,
|
||||
fromDate,
|
||||
month: selected ?? selectedMonth,
|
||||
}}
|
||||
>
|
||||
<div className="navds-date rdp-month">
|
||||
<SharedMonthProvider
|
||||
dropdownCaption={dropdownCaption}
|
||||
disabled={disabled}
|
||||
selected={selected ?? selectedMonth}
|
||||
onSelect={handleSelect}
|
||||
year={year}
|
||||
onYearChange={onYearChange}
|
||||
>
|
||||
<MonthCaption />
|
||||
<MonthSelector />
|
||||
</SharedMonthProvider>
|
||||
</div>
|
||||
</DayPickerProvider>
|
||||
<DateTranslationContextProvider translate={translate}>
|
||||
<DayPickerProvider
|
||||
initialProps={{
|
||||
locale: locale ? getLocaleFromString(locale) : langProviderLocale,
|
||||
selected: selected ?? selectedMonth,
|
||||
toDate,
|
||||
fromDate,
|
||||
month: selected ?? selectedMonth,
|
||||
}}
|
||||
>
|
||||
<div className="navds-date rdp-month">
|
||||
<SharedMonthProvider
|
||||
dropdownCaption={dropdownCaption}
|
||||
disabled={disabled}
|
||||
selected={selected ?? selectedMonth}
|
||||
onSelect={handleSelect}
|
||||
year={year}
|
||||
onYearChange={onYearChange}
|
||||
>
|
||||
<MonthCaption />
|
||||
<MonthSelector />
|
||||
</SharedMonthProvider>
|
||||
</div>
|
||||
</DayPickerProvider>
|
||||
</DateTranslationContextProvider>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ComponentTranslation } from "../../util/i18n/i18n.types";
|
||||
import { Matcher } from "../utils";
|
||||
|
||||
export interface MonthPickerProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
@@ -25,8 +26,15 @@ export interface MonthPickerProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
/**
|
||||
* Changes monthpicker locale
|
||||
* @default "nb" (norsk bokmål)
|
||||
* @deprecated Use `<Provider />`-component
|
||||
*/
|
||||
locale?: "nb" | "nn" | "en";
|
||||
/**
|
||||
* i18n-API for customizing texts and labels.
|
||||
*
|
||||
* **NB: If you need to change the language, use [Provider](https://aksel.nav.no/komponenter/core/provider#84d7ea5ec517) instead.**
|
||||
*/
|
||||
translations?: ComponentTranslation<"DatePicker">;
|
||||
/**
|
||||
* Display dropdown for choosing year. Needs `fromDate` + `toDate` to work.
|
||||
* @default false
|
||||
|
||||
@@ -5,8 +5,7 @@ import { ReadOnlyIcon } from "../../form/ReadOnlyIcon";
|
||||
import { FormFieldProps, useFormField } from "../../form/useFormField";
|
||||
import { BodyShort, ErrorMessage, Label } from "../../typography";
|
||||
import { omit } from "../../util";
|
||||
import { useI18n } from "../../util/i18n/i18n.context";
|
||||
import { useDateInputContext } from "../context";
|
||||
import { useDateInputContext, useDateTranslationContext } from "../context";
|
||||
|
||||
export interface DateInputProps
|
||||
extends FormFieldProps,
|
||||
@@ -47,7 +46,7 @@ const DateInput = forwardRef<HTMLInputElement, DateInputProps>((props, ref) => {
|
||||
} = props;
|
||||
|
||||
const buttonRef = useRef<HTMLButtonElement>(null);
|
||||
const translate = useI18n("DatePicker");
|
||||
const translate = useDateTranslationContext().translate;
|
||||
|
||||
const isDatepickerVariant = variant === "datepicker";
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ import { Modal } from "../../modal";
|
||||
import { useModalContext } from "../../modal/Modal.context";
|
||||
import { Popover } from "../../popover";
|
||||
import { useMedia } from "../../util/hooks";
|
||||
import { useI18n } from "../../util/i18n/i18n.context";
|
||||
import { getTranslations } from "../utils";
|
||||
import { TFunction, useI18n } from "../../util/i18n/i18n.context";
|
||||
import { getGlobalTranslations } from "../utils";
|
||||
|
||||
const variantToLabel = {
|
||||
single: "chooseDate",
|
||||
@@ -22,6 +22,7 @@ type DateWrapperProps = {
|
||||
anchor: HTMLDivElement | null;
|
||||
/** @deprecated Temporary to support locale prop */
|
||||
locale: "nb" | "nn" | "en" | undefined;
|
||||
translate: TFunction<"DatePicker">;
|
||||
variant: "single" | "multiple" | "range" | "month";
|
||||
popoverProps: {
|
||||
id?: string;
|
||||
@@ -35,10 +36,11 @@ export const DateWrapper = ({
|
||||
onClose,
|
||||
anchor,
|
||||
locale,
|
||||
translate,
|
||||
variant,
|
||||
popoverProps,
|
||||
}: DateWrapperProps) => {
|
||||
const translate = useI18n("DatePicker", getTranslations(locale));
|
||||
const translateGlobal = useI18n("global", getGlobalTranslations(locale));
|
||||
const modalRef = useRef<HTMLDialogElement>(null);
|
||||
const isInModal = useModalContext(false) !== undefined;
|
||||
const hideModal =
|
||||
@@ -86,7 +88,7 @@ export const DateWrapper = ({
|
||||
size="small"
|
||||
type="button"
|
||||
>
|
||||
{translate("close")}
|
||||
{translateGlobal("close")}
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
@@ -5,7 +5,11 @@ export {
|
||||
INPUT_DATE_STRING_FORMAT_MONTH,
|
||||
parseDate,
|
||||
} from "./parse-date";
|
||||
export { getLocaleFromString, getTranslations } from "./locale";
|
||||
export {
|
||||
getLocaleFromString,
|
||||
getTranslations,
|
||||
getGlobalTranslations,
|
||||
} from "./locale";
|
||||
export { disableDate } from "./dates-disabled";
|
||||
|
||||
export { dateIsInCurrentMonth, isValidDate } from "./check-dates";
|
||||
|
||||
@@ -16,7 +16,7 @@ export const getLocaleFromString = (locale: "nb" | "nn" | "en" = "nb") => {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* Temporary for backwards compatibility with locale prop
|
||||
* Temporary for backwards compatibility with locale prop. Can be removed when locale prop has been removed.
|
||||
*/
|
||||
export const getTranslations = (locale: string | undefined) => {
|
||||
switch (locale) {
|
||||
@@ -29,3 +29,19 @@ export const getTranslations = (locale: string | undefined) => {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* Temporary for backwards compatibility with locale prop. Can be removed when locale prop has been removed.
|
||||
*/
|
||||
export const getGlobalTranslations = (locale: string | undefined) => {
|
||||
switch (locale) {
|
||||
case "nn":
|
||||
return nn_translations.global;
|
||||
case "en":
|
||||
case "en-GB":
|
||||
return en_translations.global;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
@@ -27,21 +27,20 @@ const ComboboxWrapper = ({
|
||||
const wrapperRef = useRef<HTMLDivElement | null>(null);
|
||||
const [hasFocusWithin, setHasFocusWithin] = useState(false);
|
||||
|
||||
function onFocusInsideWrapper(e) {
|
||||
function onFocusInsideWrapper(event: React.FocusEvent<HTMLDivElement>) {
|
||||
if (
|
||||
!wrapperRef.current?.contains(e.relatedTarget) &&
|
||||
toggleOpenButtonRef?.current !== e.target
|
||||
!wrapperRef.current?.contains(event.relatedTarget) &&
|
||||
toggleOpenButtonRef?.current !== event.target
|
||||
) {
|
||||
toggleIsListOpen(true);
|
||||
setHasFocusWithin(true);
|
||||
}
|
||||
}
|
||||
|
||||
function onBlurWrapper(e) {
|
||||
if (!wrapperRef.current?.contains(e.relatedTarget)) {
|
||||
function onBlurWrapper(event: React.FocusEvent<HTMLDivElement>) {
|
||||
if (!wrapperRef.current?.contains(event.relatedTarget)) {
|
||||
toggleIsListOpen(false);
|
||||
setHasFocusWithin(false);
|
||||
clearInput(e);
|
||||
clearInput(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,12 +26,12 @@ const FilteredOptions = () => {
|
||||
const { maxSelected } = useSelectedOptionsContext();
|
||||
|
||||
const shouldRenderNonSelectables =
|
||||
maxSelected?.isLimitReached || // Render maxSelected message
|
||||
maxSelected.isLimitReached || // Render maxSelected message
|
||||
isLoading || // Render loading message
|
||||
(!isLoading && filteredOptions.length === 0 && !allowNewValues); // Render no hits message
|
||||
|
||||
const shouldRenderFilteredOptionsList =
|
||||
(allowNewValues && isValueNew && !maxSelected?.isLimitReached) || // Render add new option
|
||||
(allowNewValues && isValueNew && !maxSelected.isLimitReached) || // Render add new option
|
||||
filteredOptions.length > 0; // Render filtered options
|
||||
|
||||
return (
|
||||
@@ -45,7 +45,7 @@ const FilteredOptions = () => {
|
||||
>
|
||||
{shouldRenderNonSelectables && (
|
||||
<div className="navds-combobox__list_non-selectables" role="status">
|
||||
{maxSelected?.isLimitReached && <MaxSelectedMessage />}
|
||||
{maxSelected.isLimitReached && <MaxSelectedMessage />}
|
||||
{isLoading && <LoadingMessage />}
|
||||
{!isLoading && filteredOptions.length === 0 && !allowNewValues && (
|
||||
<NoSearchHitsMessage />
|
||||
@@ -60,7 +60,7 @@ const FilteredOptions = () => {
|
||||
role="listbox"
|
||||
className="navds-combobox__list-options"
|
||||
>
|
||||
{isValueNew && !maxSelected?.isLimitReached && allowNewValues && (
|
||||
{isValueNew && !maxSelected.isLimitReached && allowNewValues && (
|
||||
<AddNewOption />
|
||||
)}
|
||||
{filteredOptions.map((option) => (
|
||||
|
||||
@@ -39,7 +39,7 @@ const FilteredOptionsItem = ({ option }: { option: ComboboxOption }) => {
|
||||
const [start, highlight, end] = useTextHighlight(option.label, searchTerm);
|
||||
|
||||
const isDisabled = (_option: ComboboxOption) =>
|
||||
maxSelected?.isLimitReached && !isInList(_option.value, selectedOptions);
|
||||
maxSelected.isLimitReached && !isInList(_option.value, selectedOptions);
|
||||
|
||||
return (
|
||||
<li
|
||||
|
||||
@@ -9,14 +9,7 @@ const MaxSelectedMessage = () => {
|
||||
inputProps: { id },
|
||||
} = useInputContext();
|
||||
const { maxSelected, selectedOptions } = useSelectedOptionsContext();
|
||||
const translate = useI18n(
|
||||
"Combobox",
|
||||
maxSelected?.message ? { maxSelected: maxSelected.message } : undefined,
|
||||
);
|
||||
|
||||
if (!maxSelected) {
|
||||
return null;
|
||||
}
|
||||
const translate = useI18n("Combobox");
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -25,7 +18,7 @@ const MaxSelectedMessage = () => {
|
||||
>
|
||||
{translate("maxSelected", {
|
||||
selected: selectedOptions.length,
|
||||
limit: maxSelected.limit,
|
||||
limit: maxSelected.limit || 0,
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -142,13 +142,13 @@ const FilteredOptionsProvider = ({
|
||||
}
|
||||
virtualFocus.resetFocus();
|
||||
if (newState ?? !isInternalListOpen) {
|
||||
setHideCaret(!!maxSelected?.isLimitReached);
|
||||
setHideCaret(maxSelected.isLimitReached);
|
||||
}
|
||||
setInternalListOpen((oldState) => newState ?? !oldState);
|
||||
},
|
||||
[
|
||||
virtualFocus,
|
||||
maxSelected?.isLimitReached,
|
||||
maxSelected.isLimitReached,
|
||||
isInternalListOpen,
|
||||
setHideCaret,
|
||||
disabled,
|
||||
@@ -178,7 +178,7 @@ const FilteredOptionsProvider = ({
|
||||
}
|
||||
}
|
||||
const maybeMaxSelectedOptionsId =
|
||||
maxSelected?.isLimitReached &&
|
||||
maxSelected.isLimitReached &&
|
||||
filteredOptionsUtils.getMaxSelectedOptionsId(id);
|
||||
|
||||
return (
|
||||
@@ -188,7 +188,7 @@ const FilteredOptionsProvider = ({
|
||||
}, [
|
||||
isListOpen,
|
||||
isLoading,
|
||||
maxSelected?.isLimitReached,
|
||||
maxSelected.isLimitReached,
|
||||
value,
|
||||
partialAriaDescribedBy,
|
||||
shouldAutocomplete,
|
||||
|
||||
@@ -93,7 +93,7 @@ const InputProvider = ({ children, value: props }: Props) => {
|
||||
);
|
||||
|
||||
const clearInput = useCallback(
|
||||
(event: React.PointerEvent | React.KeyboardEvent | React.MouseEvent) => {
|
||||
(event: React.PointerEvent | React.KeyboardEvent | React.FocusEvent) => {
|
||||
onClear?.(event);
|
||||
externalOnChange?.("");
|
||||
setInternalValue("");
|
||||
|
||||
@@ -75,7 +75,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
|
||||
|
||||
const onEnter = useCallback(
|
||||
(event: React.KeyboardEvent) => {
|
||||
const isTextInSelectedOptions = (text: string) =>
|
||||
const isSelected = (text: string) =>
|
||||
selectedOptions.some(
|
||||
(option) =>
|
||||
option.label.toLocaleLowerCase() === text.toLocaleLowerCase(),
|
||||
@@ -85,10 +85,10 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
|
||||
event.preventDefault();
|
||||
// Selecting a value from the dropdown / FilteredOptions
|
||||
toggleOption(currentOption, event);
|
||||
if (!isMultiSelect && !isTextInSelectedOptions(currentOption.label)) {
|
||||
if (!isMultiSelect && !isSelected(currentOption.label)) {
|
||||
toggleIsListOpen(false);
|
||||
}
|
||||
} else if (isTextInSelectedOptions(value)) {
|
||||
} else if (isSelected(value)) {
|
||||
event.preventDefault();
|
||||
// Trying to set the same value that is already set, so just clearing the input
|
||||
clearInput(event);
|
||||
@@ -109,23 +109,23 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
|
||||
filteredOptionsUtil.normalizeText(value) ===
|
||||
filteredOptionsUtil.normalizeText(autoCompletedOption?.label ?? "");
|
||||
|
||||
let selectedValue: ComboboxOption | undefined;
|
||||
let optionToToggle: ComboboxOption | undefined;
|
||||
|
||||
if (
|
||||
shouldAutocomplete &&
|
||||
autoCompletedOption &&
|
||||
autoCompleteMatchesValue
|
||||
) {
|
||||
selectedValue = autoCompletedOption;
|
||||
optionToToggle = autoCompletedOption;
|
||||
} else if (allowNewValues && isValueNew) {
|
||||
selectedValue = { label: value, value };
|
||||
optionToToggle = { label: value, value };
|
||||
}
|
||||
|
||||
if (!selectedValue) {
|
||||
if (!optionToToggle) {
|
||||
return;
|
||||
}
|
||||
toggleOption(selectedValue, event);
|
||||
if (!isMultiSelect && !isTextInSelectedOptions(selectedValue.label)) {
|
||||
toggleOption(optionToToggle, event);
|
||||
if (!isMultiSelect && !isSelected(optionToToggle.label)) {
|
||||
toggleIsListOpen(false);
|
||||
}
|
||||
}
|
||||
@@ -279,7 +279,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
|
||||
value={value}
|
||||
onBlur={composeEventHandlers(onBlur, virtualFocus.resetFocus)}
|
||||
onClick={() => {
|
||||
setHideCaret(!!maxSelected?.isLimitReached);
|
||||
setHideCaret(maxSelected.isLimitReached);
|
||||
value !== searchTerm && onChange(value);
|
||||
}}
|
||||
onInput={onChangeHandler}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef } from "react";
|
||||
import { XMarkIcon } from "@navikt/aksel-icons";
|
||||
import { useMergeRefs } from "../../../util/hooks";
|
||||
import { useI18n } from "../../../util/i18n/i18n.context";
|
||||
import { useFilteredOptionsContext } from "../FilteredOptions/filteredOptionsContext";
|
||||
import SelectedOptions from "../SelectedOptions/SelectedOptions";
|
||||
import { useSelectedOptionsContext } from "../SelectedOptions/selectedOptionsContext";
|
||||
@@ -28,35 +26,31 @@ export const InputController = forwardRef<
|
||||
>
|
||||
>((props, ref) => {
|
||||
const {
|
||||
clearButton = true,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- Remove when prop has been removed from ComboboxProps.
|
||||
clearButton,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- Remove when prop has been removed from ComboboxProps.
|
||||
clearButtonLabel,
|
||||
toggleListButton = true,
|
||||
inputClassName,
|
||||
shouldShowSelectedOptions = true,
|
||||
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
const {
|
||||
clearInput,
|
||||
focusInput,
|
||||
inputProps,
|
||||
value,
|
||||
size = "medium",
|
||||
inputRef,
|
||||
toggleOpenButtonRef,
|
||||
readOnly,
|
||||
} = useInputContext();
|
||||
|
||||
const { activeDecendantId } = useFilteredOptionsContext();
|
||||
const { activeDecendantId, toggleIsListOpen } = useFilteredOptionsContext();
|
||||
const { selectedOptions } = useSelectedOptionsContext();
|
||||
|
||||
const mergedInputRef = useMergeRefs(inputRef, ref);
|
||||
|
||||
const translate = useI18n(
|
||||
"Combobox",
|
||||
clearButtonLabel ? { clear: clearButtonLabel } : undefined,
|
||||
);
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line jsx-a11y/click-events-have-key-events
|
||||
<div
|
||||
@@ -64,7 +58,14 @@ export const InputController = forwardRef<
|
||||
"navds-combobox__wrapper-inner--virtually-unfocused":
|
||||
activeDecendantId !== undefined,
|
||||
})}
|
||||
onClick={focusInput}
|
||||
onClick={() => {
|
||||
if (inputProps.disabled || readOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
toggleIsListOpen(true);
|
||||
focusInput();
|
||||
}}
|
||||
>
|
||||
{!shouldShowSelectedOptions ? (
|
||||
<Input
|
||||
@@ -86,19 +87,7 @@ export const InputController = forwardRef<
|
||||
/>
|
||||
</SelectedOptions>
|
||||
)}
|
||||
<div>
|
||||
{value && clearButton && (
|
||||
<div
|
||||
onClick={clearInput}
|
||||
className="navds-combobox__button-clear"
|
||||
aria-hidden
|
||||
title={translate("clear")}
|
||||
>
|
||||
<XMarkIcon />
|
||||
</div>
|
||||
)}
|
||||
{toggleListButton && <ToggleListButton ref={toggleOpenButtonRef} />}
|
||||
</div>
|
||||
{toggleListButton && <ToggleListButton ref={toggleOpenButtonRef} />}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
@@ -12,7 +12,7 @@ type SelectedOptionsContextValue = {
|
||||
removeSelectedOption: (option: ComboboxOption) => void;
|
||||
prevSelectedOptions?: ComboboxOption[];
|
||||
selectedOptions: ComboboxOption[];
|
||||
maxSelected?: ComboboxProps["maxSelected"] & { isLimitReached: boolean };
|
||||
maxSelected: { limit: number | undefined; isLimitReached: boolean };
|
||||
setSelectedOptions: (any) => void;
|
||||
toggleOption: (
|
||||
option: ComboboxOption,
|
||||
@@ -101,14 +101,17 @@ const SelectedOptionsProvider = ({
|
||||
[customOptions, onToggleSelected, removeCustomOption],
|
||||
);
|
||||
|
||||
const maxSelectedLimit =
|
||||
typeof maxSelected === "object" ? maxSelected.limit : maxSelected;
|
||||
const isLimitReached =
|
||||
(!!maxSelected?.limit && selectedOptions.length >= maxSelected.limit) ||
|
||||
(!isMultiSelect && selectedOptions.length > 0);
|
||||
!!maxSelectedLimit && selectedOptions.length >= maxSelectedLimit;
|
||||
const newHideCaret =
|
||||
isLimitReached || (!isMultiSelect && selectedOptions.length > 0);
|
||||
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: We explicitly want to run this effect when selectedOptions changes to match the view with the selected options.
|
||||
useEffect(() => {
|
||||
setHideCaret(isLimitReached);
|
||||
}, [isLimitReached, selectedOptions, setHideCaret]);
|
||||
setHideCaret(newHideCaret);
|
||||
}, [newHideCaret, selectedOptions, setHideCaret]);
|
||||
|
||||
const toggleOption = useCallback(
|
||||
(
|
||||
@@ -117,6 +120,8 @@ const SelectedOptionsProvider = ({
|
||||
) => {
|
||||
if (isInList(option.value, selectedOptions)) {
|
||||
removeSelectedOption(option);
|
||||
} else if (isMultiSelect && isLimitReached) {
|
||||
return;
|
||||
} else {
|
||||
addSelectedOption(option);
|
||||
}
|
||||
@@ -129,6 +134,8 @@ const SelectedOptionsProvider = ({
|
||||
focusInput,
|
||||
removeSelectedOption,
|
||||
selectedOptions,
|
||||
isLimitReached,
|
||||
isMultiSelect,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -142,8 +149,8 @@ const SelectedOptionsProvider = ({
|
||||
selectedOptions,
|
||||
setSelectedOptions,
|
||||
toggleOption,
|
||||
maxSelected: maxSelected && {
|
||||
...maxSelected,
|
||||
maxSelected: {
|
||||
limit: maxSelectedLimit,
|
||||
isLimitReached,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -38,16 +38,8 @@ const options = [
|
||||
"grapefruit",
|
||||
];
|
||||
|
||||
export const Default: StoryFn<
|
||||
ComboboxProps & { maxSelected?: number; maxSelectedMessage?: string }
|
||||
> = ({ maxSelected, maxSelectedMessage, ...rest }) => (
|
||||
<UNSAFE_Combobox
|
||||
{...rest}
|
||||
maxSelected={
|
||||
maxSelected && { limit: maxSelected, message: maxSelectedMessage }
|
||||
}
|
||||
id="combobox"
|
||||
/>
|
||||
export const Default: StoryFn<ComboboxProps> = (props) => (
|
||||
<UNSAFE_Combobox {...props} id="combobox" />
|
||||
);
|
||||
Default.args = {
|
||||
options,
|
||||
@@ -77,16 +69,13 @@ Default.argTypes = {
|
||||
maxSelected: {
|
||||
control: { type: "number" },
|
||||
},
|
||||
maxSelectedMessage: {
|
||||
control: { type: "text" },
|
||||
},
|
||||
size: {
|
||||
options: ["medium", "small"],
|
||||
defaultValue: "medium",
|
||||
control: { type: "radio" },
|
||||
},
|
||||
clearButtonLabel: {
|
||||
control: { type: "text" },
|
||||
toggleListButton: {
|
||||
control: { type: "boolean" },
|
||||
},
|
||||
};
|
||||
|
||||
@@ -426,7 +415,7 @@ export const MaxSelectedOptions: StoryFn = ({ open }: { open?: boolean }) => {
|
||||
id="combobox-with-max-selected-options"
|
||||
label="Komboboks med begrenset antall valg"
|
||||
options={options}
|
||||
maxSelected={{ limit: 2 }}
|
||||
maxSelected={2}
|
||||
selectedOptions={selectedOptions}
|
||||
onToggleSelected={(option, isSelected) =>
|
||||
isSelected
|
||||
|
||||
@@ -45,15 +45,11 @@ export interface ComboboxProps
|
||||
*/
|
||||
allowNewValues?: boolean;
|
||||
/**
|
||||
* Adds a button to clear the input value when not empty.
|
||||
* NB: Will not clear selected values.
|
||||
* @default true
|
||||
* @deprecated The clear button has been removed. This prop has no effect.
|
||||
*/
|
||||
clearButton?: boolean;
|
||||
/**
|
||||
* Custom name for the clear button. Requires `clearButton` to be `true`.
|
||||
*
|
||||
* @default "Tøm"
|
||||
* @deprecated The clear button has been removed. This prop has no effect.
|
||||
*/
|
||||
clearButtonLabel?: string;
|
||||
/**
|
||||
@@ -102,7 +98,7 @@ export interface ComboboxProps
|
||||
* @param event
|
||||
*/
|
||||
onClear?: (
|
||||
event: React.PointerEvent | React.KeyboardEvent | React.MouseEvent,
|
||||
event: React.PointerEvent | React.KeyboardEvent | React.FocusEvent,
|
||||
) => void;
|
||||
/**
|
||||
* Callback function triggered whenever an option is selected or de-selected.
|
||||
@@ -124,19 +120,15 @@ export interface ComboboxProps
|
||||
*/
|
||||
selectedOptions?: string[] | ComboboxOption[];
|
||||
/**
|
||||
* Options for the maximum number of selected options.
|
||||
* Maximum number of selected options.
|
||||
* @example maxSelected={3}
|
||||
*/
|
||||
maxSelected?: {
|
||||
/**
|
||||
* The limit for maximum selected options
|
||||
*/
|
||||
limit: number;
|
||||
/**
|
||||
* Message to display when the limit for maximum selected options has been reached
|
||||
* @default "{selected} av maks {limit} er valgt."
|
||||
*/
|
||||
message?: string;
|
||||
};
|
||||
maxSelected?:
|
||||
| {
|
||||
/** @deprecated Provide a number instead of an object */
|
||||
limit: number;
|
||||
}
|
||||
| number;
|
||||
/**
|
||||
* Set to `true` to enable inline autocomplete.
|
||||
*
|
||||
|
||||
@@ -2,8 +2,6 @@ import { Meta, StoryObj } from "@storybook/react";
|
||||
import { expect, userEvent, within } from "@storybook/test";
|
||||
import React, { useRef } from "react";
|
||||
import { VStack } from "../../layout/stack";
|
||||
import UNSAFE_AkselLanguageProvider from "../../provider/i18n/LanguageProvider";
|
||||
import nn from "../../util/i18n/locales/nn";
|
||||
import { ErrorSummary } from "./ErrorSummary";
|
||||
|
||||
export default {
|
||||
@@ -136,18 +134,3 @@ export const Chromatic: Story = {
|
||||
chromatic: { disable: false },
|
||||
},
|
||||
};
|
||||
|
||||
export const ProvidedTranslations: Story = {
|
||||
render: () => {
|
||||
return (
|
||||
<UNSAFE_AkselLanguageProvider translations={nn}>
|
||||
<ErrorSummary size="small">
|
||||
<ErrorSummary.Item href="#1">Checkbox må fylles ut</ErrorSummary.Item>
|
||||
<ErrorSummary.Item href="#2">
|
||||
Tekstfeltet må ha en godkjent e-post
|
||||
</ErrorSummary.Item>
|
||||
</ErrorSummary>
|
||||
</UNSAFE_AkselLanguageProvider>
|
||||
);
|
||||
},
|
||||
};
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Meta, StoryFn } from "@storybook/react";
|
||||
import React, { useState } from "react";
|
||||
import VStack from "../../layout/stack/VStack";
|
||||
import UNSAFE_AkselLanguageProvider from "../../provider/i18n/LanguageProvider";
|
||||
import { Provider } from "../../provider";
|
||||
import en from "../../util/i18n/locales/en";
|
||||
import FormProgress, { FormProgressProps } from "./FormProgress";
|
||||
|
||||
export default {
|
||||
@@ -27,7 +28,7 @@ export const Default: StoryFn<ControllableProps> = (props) => (
|
||||
Saksopplysninger
|
||||
</FormProgress.Step>
|
||||
<FormProgress.Step interactive={false}>
|
||||
Søknadstekst for en veldig spesifikk prosess i NAV som har lang tekst
|
||||
Søknadstekst for en veldig spesifikk prosess i Nav som har lang tekst
|
||||
</FormProgress.Step>
|
||||
<FormProgress.Step href="#">Vedlegg</FormProgress.Step>
|
||||
<FormProgress.Step href="#">Oppsummering</FormProgress.Step>
|
||||
@@ -41,14 +42,12 @@ Default.args = { activeStep: 2, totalSteps: 7, interactiveSteps: true };
|
||||
export const ProvidedTranslations: StoryFn = () => {
|
||||
const translations = {
|
||||
FormProgress: {
|
||||
step: "Step {activeStep} of {totalSteps}",
|
||||
showAllSteps: "Show all steps",
|
||||
hideAllSteps: "Hide all steps",
|
||||
step: "Step {activeStep}/{totalSteps}",
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<UNSAFE_AkselLanguageProvider translations={translations}>
|
||||
<Provider locale={en} translations={translations}>
|
||||
<FormProgress activeStep={2} totalSteps={7} interactiveSteps>
|
||||
<FormProgress.Step href="#" completed>
|
||||
Start søknad
|
||||
@@ -58,19 +57,19 @@ export const ProvidedTranslations: StoryFn = () => {
|
||||
Saksopplysninger
|
||||
</FormProgress.Step>
|
||||
<FormProgress.Step interactive={false}>
|
||||
Søknadstekst for en veldig spesifikk prosess i NAV som har lang tekst
|
||||
Søknadstekst for en veldig spesifikk prosess i Nav som har lang tekst
|
||||
</FormProgress.Step>
|
||||
<FormProgress.Step href="#">Vedlegg</FormProgress.Step>
|
||||
<FormProgress.Step href="#">Oppsummering</FormProgress.Step>
|
||||
<FormProgress.Step href="#">Innsending</FormProgress.Step>
|
||||
</FormProgress>
|
||||
</UNSAFE_AkselLanguageProvider>
|
||||
</Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const DefaultTranslations: StoryFn = () => {
|
||||
return (
|
||||
<UNSAFE_AkselLanguageProvider>
|
||||
<Provider>
|
||||
<FormProgress activeStep={2} totalSteps={7} interactiveSteps>
|
||||
<FormProgress.Step href="#" completed>
|
||||
Start søknad
|
||||
@@ -80,22 +79,22 @@ export const DefaultTranslations: StoryFn = () => {
|
||||
Saksopplysninger
|
||||
</FormProgress.Step>
|
||||
<FormProgress.Step interactive={false}>
|
||||
Søknadstekst for en veldig spesifikk prosess i NAV som har lang tekst
|
||||
Søknadstekst for en veldig spesifikk prosess i Nav som har lang tekst
|
||||
</FormProgress.Step>
|
||||
<FormProgress.Step href="#">Vedlegg</FormProgress.Step>
|
||||
<FormProgress.Step href="#">Oppsummering</FormProgress.Step>
|
||||
<FormProgress.Step href="#">Innsending</FormProgress.Step>
|
||||
</FormProgress>
|
||||
</UNSAFE_AkselLanguageProvider>
|
||||
</Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const ComponentTranslations: StoryFn = () => {
|
||||
const globalTranslations = {
|
||||
FormProgress: {
|
||||
step: "Step {activeStep} of {totalSteps}",
|
||||
showAllSteps: "Show all steps",
|
||||
hideAllSteps: "Hide all steps",
|
||||
step: "Step {activeStep}/{totalSteps}",
|
||||
showAllSteps: "Show all",
|
||||
hideAllSteps: "Hide all",
|
||||
},
|
||||
};
|
||||
const translations = {
|
||||
@@ -104,7 +103,7 @@ export const ComponentTranslations: StoryFn = () => {
|
||||
hideAllSteps: "Fela öll skref",
|
||||
};
|
||||
return (
|
||||
<UNSAFE_AkselLanguageProvider translations={globalTranslations}>
|
||||
<Provider locale={en} translations={globalTranslations}>
|
||||
<FormProgress
|
||||
translations={translations}
|
||||
activeStep={2}
|
||||
@@ -119,13 +118,13 @@ export const ComponentTranslations: StoryFn = () => {
|
||||
Saksopplysninger
|
||||
</FormProgress.Step>
|
||||
<FormProgress.Step interactive={false}>
|
||||
Søknadstekst for en veldig spesifikk prosess i NAV som har lang tekst
|
||||
Søknadstekst for en veldig spesifikk prosess i Nav som har lang tekst
|
||||
</FormProgress.Step>
|
||||
<FormProgress.Step href="#">Vedlegg</FormProgress.Step>
|
||||
<FormProgress.Step href="#">Oppsummering</FormProgress.Step>
|
||||
<FormProgress.Step href="#">Innsending</FormProgress.Step>
|
||||
</FormProgress>
|
||||
</UNSAFE_AkselLanguageProvider>
|
||||
</Provider>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -52,7 +52,8 @@ export interface SearchProps
|
||||
onSearchClick?: (value: string) => void;
|
||||
/**
|
||||
* Sets the `aria-label` for the clear button.
|
||||
* @default "Tøm"
|
||||
* @default "Tøm feltet"
|
||||
* @deprecated Use `<Provider />`-component
|
||||
*/
|
||||
clearButtonLabel?: string;
|
||||
/**
|
||||
@@ -91,7 +92,7 @@ interface SearchComponent
|
||||
* @example
|
||||
* ```jsx
|
||||
* <form role="search">
|
||||
* <Search label="Søk alle NAV sine sider" variant="primary" />
|
||||
* <Search label="Søk alle Nav sine sider" variant="primary" />
|
||||
* </form>
|
||||
* ```
|
||||
*/
|
||||
|
||||
@@ -54,6 +54,7 @@ export interface TextareaProps
|
||||
UNSAFE_autoScrollbar?: boolean;
|
||||
/**
|
||||
* i18n-translations for counter-text
|
||||
* @deprecated Use `<Provider />`-component
|
||||
*/
|
||||
i18n?: {
|
||||
/** @default tegn igjen */
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import cl from "clsx";
|
||||
import React, { HTMLAttributes, forwardRef } from "react";
|
||||
import { UNSAFE_useAkselTheme } from "../provider";
|
||||
import { DefaultIllustration } from "./Illustration";
|
||||
import { DarksideGudiepanelIllustration } from "./Illustration.darkside";
|
||||
|
||||
export interface GuidePanelProps extends HTMLAttributes<HTMLDivElement> {
|
||||
/**
|
||||
@@ -34,22 +36,64 @@ export interface GuidePanelProps extends HTMLAttributes<HTMLDivElement> {
|
||||
* ```
|
||||
*/
|
||||
export const GuidePanel = forwardRef<HTMLDivElement, GuidePanelProps>(
|
||||
({ children, className, illustration, poster, ...rest }, ref) => (
|
||||
<div
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl("navds-guide-panel", className, {
|
||||
"navds-guide-panel--poster": poster === true,
|
||||
"navds-guide-panel--not-poster": poster === false,
|
||||
"navds-guide-panel--responsive-poster": poster === undefined,
|
||||
})}
|
||||
>
|
||||
<div className="navds-guide">
|
||||
{illustration ?? <DefaultIllustration />}
|
||||
({ children, className, illustration, poster, ...rest }, ref) => {
|
||||
const themeContext = UNSAFE_useAkselTheme(false);
|
||||
|
||||
return (
|
||||
<div
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl("navds-guide-panel", className, {
|
||||
"navds-guide-panel--poster": poster === true,
|
||||
"navds-guide-panel--not-poster": poster === false,
|
||||
"navds-guide-panel--responsive-poster": poster === undefined,
|
||||
})}
|
||||
data-responsive={poster === undefined}
|
||||
data-poster={poster}
|
||||
>
|
||||
<div className="navds-guide">
|
||||
{illustration ??
|
||||
(themeContext ? (
|
||||
<DarksideGudiepanelIllustration />
|
||||
) : (
|
||||
<DefaultIllustration />
|
||||
))}
|
||||
</div>
|
||||
<div className="navds-guide-panel__content">
|
||||
{themeContext && (
|
||||
<svg
|
||||
viewBox="0 0 33 22"
|
||||
width="33"
|
||||
height="22"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="navds-guide-panel__tail"
|
||||
>
|
||||
<path
|
||||
d="M8.74229e-08 22L0 20L33 20V22L8.74229e-08 22Z"
|
||||
fill="var(--ax-bg-raised)"
|
||||
/>
|
||||
<path
|
||||
d="M31 20.0001L2 20.0001C2.09817 10.0296 3 7.00011 6 2.00011C8 12.5001 20 20.0001 31 20.0001Z"
|
||||
fill="var(--ax-bg-raised)"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M0 20C-2.87106e-10 19.9934 3.21047e-05 19.987 9.68646e-05 19.9804C0.0494722 14.9659 0.299239 11.5341 0.964025 8.68212C1.64231 5.77217 2.72947 3.56367 4.28501 0.971094C4.71185 0.259692 5.53358 -0.114327 6.35038 0.0310157C7.16718 0.176359 7.80944 0.810884 7.96467 1.62586C8.84145 6.22896 11.9453 10.3172 16.2599 13.2908C20.5715 16.2623 25.9294 18.0001 31 18.0001C32.1046 18.0001 33 18.8954 33 20L0 20ZM6.755 4.70521C8.97688 10.7068 14.4934 15.469 20.8803 18.0001C24.1345 19.2897 27.6146 20.0001 31 20.0001L2 20.0001C2.00689 19.3003 2.01774 18.6346 2.033 18.0001C2.19625 11.2107 2.86405 7.98363 4.58479 4.54371C4.9944 3.72487 5.46367 2.89399 6 2.00011C6.17639 2.92619 6.43058 3.82889 6.755 4.70521Z"
|
||||
fill="var(--ax-border-info)"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
{themeContext ? (
|
||||
<div className="navds-guide-panel__content-inner">{children}</div>
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="navds-guide-panel__content">{children}</div>
|
||||
</div>
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
export default GuidePanel;
|
||||
@@ -0,0 +1,96 @@
|
||||
import React from "react";
|
||||
import { useI18n } from "../util/i18n/i18n.context";
|
||||
|
||||
export const DarksideGudiepanelIllustration = () => {
|
||||
const translate = useI18n("GuidePanel");
|
||||
|
||||
return (
|
||||
<svg
|
||||
width="80"
|
||||
height="80"
|
||||
viewBox="0 0 80 80"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-label={translate("illustrationLabel")}
|
||||
focusable={false}
|
||||
role="img"
|
||||
>
|
||||
<g clipPath="url(#clip0_1387_21067)">
|
||||
<rect
|
||||
width="80"
|
||||
height="80"
|
||||
rx="40"
|
||||
fill="var(--ax-bg-info-moderate)"
|
||||
/>
|
||||
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M55.1888 40.4309C53.795 44.9809 51.0663 48.7578 47.5693 51.0691L47.7484 53.0953L47.7474 53.1777L45.857 69.8798H33.8679L33.8181 69.5289L31.5004 53.149L31.5862 51.1003C28.0715 48.7951 25.3274 45.012 23.9257 40.4499C23.8781 40.4544 23.83 40.4567 23.7812 40.4567C22.8745 40.4567 22.1562 39.6596 22.1562 38.694V33.2299C22.1562 32.5826 22.479 32.0107 22.9648 31.704C23.7229 21.5029 30.8443 13.4856 39.554 13.4856C48.2401 13.4856 55.3472 21.4598 56.1376 31.6212C56.7049 31.8987 57.0938 32.5185 57.0938 33.2299V38.694C57.0938 39.6601 56.3765 40.4567 55.4688 40.4567C55.3731 40.4567 55.2796 40.4479 55.1888 40.4309Z"
|
||||
fill="#F5F6F7"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M47.1471 51.6344C47.0789 55.2818 43.7373 59.0238 39.625 59.0238C35.4948 59.0238 32.142 55.2492 32.1022 51.5868C29.9622 52.1324 26.6956 53.778 23.9995 56.528C21.3885 59.191 19.3125 63.194 19.3125 66.2992V85H59.9375V66.2992C59.9375 63.1877 57.8167 59.1779 55.1575 56.5118C52.4983 53.8457 49.3007 52.2224 47.1471 51.6344Z"
|
||||
fill="#156389"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M31.9671 51.7135C29.9959 52.4334 26.6891 54.0069 24.1875 56.3965C16.875 54.7596 13.625 50.8701 13.625 50.8701C13.625 50.8701 20.3621 44.2597 20.3662 32.698V32.6858C20.3662 19.1479 27.6319 9.80769 39.6022 9.80769C51.5742 9.80769 58.8399 19.1479 58.8399 32.6858H58.883C58.883 44.2556 65.625 50.8701 65.625 50.8701C65.625 50.8701 62.375 54.7596 55.0625 56.3942L55.0515 56.3965C52.6353 54.1854 49.1309 52.48 47.2243 51.759L47.2265 51.7583L47.1508 50.9013L47.1917 50.8303C50.7891 48.5155 53.5804 44.616 54.9262 39.904C55.0909 39.9962 55.277 40.0481 55.4739 40.0481C56.1476 40.0481 56.6928 39.4432 56.6928 38.694V33.2299C56.6928 32.5888 56.2936 32.0529 55.7564 31.9115C55.7559 31.9041 55.7554 31.8967 55.7549 31.8893C38.7466 33.7984 32.6199 22.0681 32.117 22.0673C32.117 22.0673 26.4686 26.1538 23.769 31.0125C23.769 31.0125 23.3576 31.9297 23.3556 31.9605C22.8934 32.1528 22.5637 32.648 22.5637 33.2299V38.694C22.5637 39.4432 23.1103 40.0481 23.7826 40.0481C23.9316 40.0481 24.0743 40.0185 24.2062 39.9643C25.5668 44.6786 28.3759 48.5739 31.9901 50.8733L32.0035 50.9013L31.9695 51.7135H31.9671Z"
|
||||
fill="#A93D70"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M33.8159 35.8563C32.766 35.9417 32.4722 34.2696 32.7885 33.1775C32.848 32.9706 33.1956 32.0283 33.8109 32.0283C34.4254 32.0283 34.6968 32.5433 34.7345 32.6319C35.1865 33.6965 34.9645 35.7622 33.8159 35.8563"
|
||||
fill="#202733"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M45.9927 35.8563C47.0425 35.9417 47.3364 34.2696 47.0201 33.1775C46.9606 32.9706 46.613 32.0283 45.9977 32.0283C45.3832 32.0283 45.1118 32.5433 45.0741 32.6319C44.6221 33.6965 44.8441 35.7622 45.9927 35.8563"
|
||||
fill="#202733"
|
||||
/>
|
||||
<path
|
||||
d="M40.2935 37.5041C40.9213 37.396 41.3501 37.4638 41.5036 37.6748C42.0833 38.4721 41.8979 39.3156 40.9035 40.0081C40.3806 40.372 39.661 40.5001 39.28 40.3114C39.0937 40.2191 38.8758 40.3133 38.7934 40.5218C38.7109 40.7304 38.7951 40.9742 38.9814 41.0665C39.6111 41.3784 40.5794 41.206 41.2931 40.7092C42.6445 39.7682 42.9537 38.3611 42.0758 37.1534C41.7042 36.643 41.0465 36.5389 40.1812 36.688C39.9799 36.7227 39.8418 36.9335 39.8728 37.1589C39.9038 37.3842 40.0921 37.5388 40.2935 37.5041Z"
|
||||
fill="#202733"
|
||||
/>
|
||||
<path
|
||||
d="M44.8337 42.9837C44.7968 43.0623 44.7122 43.2128 44.5763 43.4111C44.3463 43.7466 44.0574 44.083 43.7066 44.3967C42.6611 45.3315 41.3002 45.8721 39.5683 45.8226C37.8795 45.7744 36.5247 45.2422 35.4626 44.384C35.0726 44.0689 34.7506 43.7315 34.4933 43.3951C34.3415 43.1967 34.2468 43.0464 34.2053 42.968C34.1056 42.7795 33.8606 42.7019 33.6581 42.7946C33.4555 42.8874 33.3721 43.1154 33.4718 43.3039C33.5318 43.4175 33.6487 43.6029 33.8273 43.8364C34.1206 44.2197 34.4852 44.6019 34.9266 44.9585C36.1256 45.9273 37.6579 46.5293 39.5432 46.5831C41.5064 46.6391 43.0759 46.0157 44.273 44.9453C44.6733 44.5875 45.0023 44.2043 45.2656 43.8203C45.4257 43.5868 45.5298 43.4015 45.5829 43.2882C45.6733 43.0956 45.5788 42.8714 45.3719 42.7873C45.165 42.7033 44.924 42.7912 44.8337 42.9837Z"
|
||||
fill="#202733"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M53.8629 70.5H42.8865C42.3966 70.5 42 70.0974 42 69.6V63.609C42 63.1117 42.3966 62.7083 42.8865 62.7083H53.8629C54.3527 62.7083 54.75 63.1117 54.75 63.609V69.6C54.75 70.0974 54.3527 70.5 53.8629 70.5"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M49.0346 63.9451H47.8971C47.8128 63.9451 47.7449 63.8775 47.7449 63.7937V63.6029C47.7449 63.5197 47.8128 63.4515 47.8971 63.4515H49.0346C49.1188 63.4515 49.1867 63.5197 49.1867 63.6029V63.7937C49.1867 63.8775 49.1188 63.9451 49.0346 63.9451"
|
||||
fill="#202733"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M48.1365 63.7708H48.7955V62H48.1365V63.7708Z"
|
||||
fill="#818997"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M52.5417 65.5H51.6457C51.6457 65.5 51.5839 65.5 51.5621 65.5545L51.0662 67.0725L50.5708 65.5545C50.5489 65.5 50.4868 65.5 50.4868 65.5H48.764C48.7267 65.5 48.6954 65.5311 48.6954 65.5682V66.0837C48.6954 65.6748 48.2603 65.5 48.0055 65.5C47.4349 65.5 47.053 65.8758 46.934 66.4472C46.9276 66.0681 46.8961 65.9323 46.794 65.7932C46.7471 65.7251 46.6793 65.6678 46.6055 65.6204C46.4535 65.5314 46.317 65.5 46.0237 65.5H45.6794C45.6794 65.5 45.6171 65.5 45.5952 65.5545L45.2818 66.331V65.5682C45.2818 65.5311 45.2508 65.5 45.2136 65.5H44.4167C44.4167 65.5 44.3552 65.5 44.3328 65.5545L44.0071 66.362C44.0071 66.362 43.9746 66.4427 44.0489 66.4427H44.3552V67.9813C44.3552 68.0195 44.3853 68.0497 44.4236 68.0497H45.2136C45.2508 68.0497 45.2818 68.0195 45.2818 67.9813V66.4427H45.5898C45.7664 66.4427 45.8039 66.4475 45.8726 66.4796C45.914 66.4952 45.9513 66.5268 45.9716 66.5633C46.0133 66.6417 46.0237 66.7359 46.0237 67.0135V67.9813C46.0237 68.0195 46.0544 68.0497 46.0923 68.0497H46.8494C46.8494 68.0497 46.935 68.0497 46.9688 67.9652L47.1366 67.5505C47.3597 67.863 47.7269 68.0497 48.1833 68.0497H48.283C48.283 68.0497 48.3691 68.0497 48.4032 67.9652L48.6954 67.2415V67.9813C48.6954 68.0195 48.7267 68.0497 48.764 68.0497H49.5368C49.5368 68.0497 49.6221 68.0497 49.6564 67.9652C49.6564 67.9652 49.9655 67.1978 49.9667 67.192H49.9671C49.979 67.1281 49.8983 67.1281 49.8983 67.1281H49.6225V65.8113L50.4904 67.9652C50.5243 68.0497 50.6097 68.0497 50.6097 68.0497H51.5228C51.5228 68.0497 51.6087 68.0497 51.6426 67.9652L52.6048 65.5826C52.6381 65.5 52.5417 65.5 52.5417 65.5V65.5ZM48.6954 67.128H48.1763C47.9696 67.128 47.8015 66.9607 47.8015 66.7538C47.8015 66.5473 47.9696 66.3789 48.1763 66.3789H48.3215C48.5276 66.3789 48.6954 66.5473 48.6954 66.7538V67.128Z"
|
||||
fill="#C30000"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1387_21067">
|
||||
<rect width="80" height="80" rx="40" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -1,26 +1,9 @@
|
||||
import React, { SVGProps } from "react";
|
||||
import { useId } from "../util/hooks";
|
||||
import React from "react";
|
||||
import { useI18n } from "../util/i18n/i18n.context";
|
||||
|
||||
interface SVGRProps {
|
||||
title?: string;
|
||||
titleId?: string;
|
||||
}
|
||||
|
||||
export type DefaultIllustrationType = React.FunctionComponent<
|
||||
SVGProps<SVGSVGElement> & SVGRProps
|
||||
>;
|
||||
|
||||
export const DefaultIllustration: DefaultIllustrationType = ({
|
||||
title,
|
||||
titleId: _titleId,
|
||||
...props
|
||||
}) => {
|
||||
export const DefaultIllustration = () => {
|
||||
const translate = useI18n("GuidePanel");
|
||||
|
||||
let titleId: string | undefined = useId();
|
||||
titleId = title ? (_titleId ? _titleId : "title-" + titleId) : undefined;
|
||||
|
||||
return (
|
||||
<svg
|
||||
width="56"
|
||||
@@ -31,10 +14,7 @@ export const DefaultIllustration: DefaultIllustrationType = ({
|
||||
aria-label={translate("illustrationLabel")}
|
||||
focusable={false}
|
||||
role="img"
|
||||
aria-labelledby={titleId}
|
||||
{...props}
|
||||
>
|
||||
{title ? <title id={titleId}>{title}</title> : null}
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
|
||||
@@ -31,14 +31,16 @@ export const Default: StoryObj<{ poster?: boolean; colorOverride?: boolean }> =
|
||||
: {};
|
||||
|
||||
return (
|
||||
<GuidePanel style={style} poster={props?.poster}>
|
||||
{panelText}
|
||||
</GuidePanel>
|
||||
<VStack gap="2">
|
||||
<GuidePanel style={style} poster={props?.poster}>
|
||||
{panelText}
|
||||
</GuidePanel>
|
||||
</VStack>
|
||||
);
|
||||
},
|
||||
|
||||
args: {
|
||||
poster: false,
|
||||
poster: undefined,
|
||||
colorOverride: false,
|
||||
},
|
||||
};
|
||||
@@ -66,14 +68,16 @@ export const PosterVariants: Story = {
|
||||
|
||||
export const ColorOverride: Story = {
|
||||
render: () => (
|
||||
<GuidePanel
|
||||
style={{
|
||||
"--ac-guide-panel-illustration-bg": "var(--a-purple-200)",
|
||||
"--ac-guide-panel-border": "var(--a-purple-400)",
|
||||
}}
|
||||
>
|
||||
{panelText}
|
||||
</GuidePanel>
|
||||
<div>
|
||||
<GuidePanel
|
||||
style={{
|
||||
"--ac-guide-panel-illustration-bg": "var(--a-purple-200)",
|
||||
"--ac-guide-panel-border": "var(--a-purple-400)",
|
||||
}}
|
||||
>
|
||||
{panelText}
|
||||
</GuidePanel>
|
||||
</div>
|
||||
),
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
"use client";
|
||||
export { default as GuidePanel, type GuidePanelProps } from "./GuidePanel";
|
||||
export { DefaultIllustration as GuidePanelDefaultIllustration } from "./Illustration";
|
||||
@@ -25,11 +25,7 @@ export {
|
||||
} from "./date/monthpicker";
|
||||
export { Dropdown, type DropdownProps } from "./dropdown";
|
||||
export { ExpansionCard, type ExpansionCardProps } from "./expansion-card";
|
||||
export {
|
||||
GuidePanel,
|
||||
GuidePanelDefaultIllustration,
|
||||
type GuidePanelProps,
|
||||
} from "./guide-panel";
|
||||
export { GuidePanel, type GuidePanelProps } from "./guide-panel";
|
||||
export { HelpText, type HelpTextProps } from "./help-text";
|
||||
export {
|
||||
InternalHeader,
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef } from "react";
|
||||
import { BorderKeys } from "@navikt/ds-tokens/darkside/tokens/semantic-roles";
|
||||
import type {
|
||||
BorderColorKeys,
|
||||
BorderColorWithRoleKeys,
|
||||
BorderRadiusKeys,
|
||||
DefaultBgKeys,
|
||||
ShadowKeys,
|
||||
StaticBgKeys,
|
||||
} from "@navikt/ds-tokens/types";
|
||||
import { Slot } from "../../slot/Slot";
|
||||
import { omit } from "../../util";
|
||||
import { OverridableComponent } from "../../util/types";
|
||||
@@ -10,27 +17,21 @@ import BasePrimitive, {
|
||||
} from "../base/BasePrimitive";
|
||||
import { PrimitiveAsChildProps } from "../base/PrimitiveAsChildProps";
|
||||
import { getResponsiveProps } from "../utilities/css";
|
||||
import {
|
||||
BorderRadiiToken,
|
||||
ResponsiveProp,
|
||||
SemanticRoleBgDarkside,
|
||||
SemanticShadowTokens,
|
||||
SemanticStaticBgDarkside,
|
||||
SemanticStaticBorderDarkside,
|
||||
SpaceDelimitedAttribute,
|
||||
} from "../utilities/types";
|
||||
import { ResponsiveProp, SpaceDelimitedAttribute } from "../utilities/types";
|
||||
|
||||
export type BoxNewProps = React.HTMLAttributes<HTMLDivElement> & {
|
||||
/**
|
||||
* CSS `background-color` property.
|
||||
* Accepts a [background/surface color token](https://aksel.nav.no/grunnleggende/styling/design-tokens#afff774dad80).
|
||||
* @see {@link DefaultBgKeys} and {@link StaticBgKeys}
|
||||
*/
|
||||
background?: SemanticStaticBgDarkside | SemanticRoleBgDarkside;
|
||||
background?: DefaultBgKeys | StaticBgKeys;
|
||||
/**
|
||||
* CSS `border-color` property.
|
||||
* Accepts a [border color token](https://aksel.nav.no/grunnleggende/styling/design-tokens#adb1767e2f87).
|
||||
* @see {@link BorderColorKeys} and {@link BorderColorWithRoleKeys}
|
||||
*/
|
||||
borderColor?: BorderKeys | SemanticStaticBorderDarkside;
|
||||
borderColor?: Exclude<BorderColorKeys, "focus"> | BorderColorWithRoleKeys;
|
||||
/**
|
||||
* CSS `border-radius` property.
|
||||
* Accepts a [radius token](https://aksel.nav.no/grunnleggende/styling/design-tokens#6d79c5605d31)
|
||||
@@ -39,8 +40,11 @@ export type BoxNewProps = React.HTMLAttributes<HTMLDivElement> & {
|
||||
* borderRadius='full'
|
||||
* borderRadius='0 full large small'
|
||||
* borderRadius={{xs: 'small large', sm: '0', md: 'large', lg: 'full'}}
|
||||
* @see {@link BorderRadiusKeys}
|
||||
*/
|
||||
borderRadius?: ResponsiveProp<SpaceDelimitedAttribute<BorderRadiiToken>>;
|
||||
borderRadius?: ResponsiveProp<
|
||||
SpaceDelimitedAttribute<BorderRadiusKeys | "0">
|
||||
>;
|
||||
/**
|
||||
* CSS `border-width` property. If this is not set there will be no border.
|
||||
* @example
|
||||
@@ -51,8 +55,9 @@ export type BoxNewProps = React.HTMLAttributes<HTMLDivElement> & {
|
||||
/** Shadow on box. Accepts a shadow token.
|
||||
* @example
|
||||
* shadow='small'
|
||||
* @see {@link ShadowKeys}
|
||||
*/
|
||||
shadow?: SemanticShadowTokens;
|
||||
shadow?: ShadowKeys;
|
||||
} & PrimitiveProps &
|
||||
PrimitiveAsChildProps;
|
||||
|
||||
|
||||
@@ -407,7 +407,7 @@ export const BoxNewDarksideLight: Story = {
|
||||
<Box.New
|
||||
background="accent-moderate"
|
||||
shadow="dialog"
|
||||
borderColor="brand-one-strong"
|
||||
borderColor="brand-magenta-strong"
|
||||
borderWidth="2"
|
||||
padding="5"
|
||||
paddingInline="20"
|
||||
@@ -423,7 +423,7 @@ export const BoxNewDarksideDark: Story = {
|
||||
<Box.New
|
||||
background="accent-moderate"
|
||||
shadow="dialog"
|
||||
borderColor="brand-one-strong"
|
||||
borderColor="brand-magenta-strong"
|
||||
borderWidth="2"
|
||||
padding="5"
|
||||
paddingInline="20"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef } from "react";
|
||||
import { type BorderRadiusKeys } from "@navikt/ds-tokens/types";
|
||||
import { UNSAFE_useAkselTheme } from "../../provider";
|
||||
import { Slot } from "../../slot/Slot";
|
||||
import { omit } from "../../util";
|
||||
@@ -13,7 +14,6 @@ import { getResponsiveProps } from "../utilities/css";
|
||||
import {
|
||||
BackgroundColorToken,
|
||||
BorderColorToken,
|
||||
BorderRadiiToken,
|
||||
ResponsiveProp,
|
||||
ShadowToken,
|
||||
SpaceDelimitedAttribute,
|
||||
@@ -41,7 +41,9 @@ export type BoxProps = React.HTMLAttributes<HTMLDivElement> & {
|
||||
* borderRadius='0 full large small'
|
||||
* borderRadius={{xs: 'small large', sm: '0', md: 'large', lg: 'full'}}
|
||||
*/
|
||||
borderRadius?: ResponsiveProp<SpaceDelimitedAttribute<BorderRadiiToken>>;
|
||||
borderRadius?: ResponsiveProp<
|
||||
SpaceDelimitedAttribute<BorderRadiusKeys | "0">
|
||||
>;
|
||||
/**
|
||||
* CSS `border-width` property. If this is not set there will be no border.
|
||||
* @example
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { Meta, StoryFn } from "@storybook/react";
|
||||
import React, { useEffect } from "react";
|
||||
import bgColors from "@navikt/ds-tokens/src/colors-bg.json";
|
||||
import { Box } from "../box";
|
||||
import { HGrid } from "../grid";
|
||||
import { VStack } from "../stack";
|
||||
@@ -43,7 +42,7 @@ Default.argTypes = {
|
||||
},
|
||||
background: {
|
||||
control: "radio",
|
||||
options: Object.keys(bgColors.a),
|
||||
options: ["bg-default", "bg-subtle"],
|
||||
},
|
||||
belowFold: {
|
||||
control: "boolean",
|
||||
|
||||
@@ -1,27 +1,23 @@
|
||||
/* Darkside tokens */
|
||||
import { semanticTokenConfig } from "@navikt/ds-tokens/darkside/tokens/semantic";
|
||||
import { SemanticTokensForAllRolesConfigT } from "@navikt/ds-tokens/darkside/tokens/semantic-roles";
|
||||
import { shadowTokenConfig } from "@navikt/ds-tokens/darkside/tokens/shadow";
|
||||
import type {
|
||||
BreakPointKeys,
|
||||
LegacyBgColorKeys,
|
||||
LegacyBorderColorKeys,
|
||||
LegacyShadowKeys,
|
||||
LegacySurfaceColorKeys,
|
||||
SpacingKeys,
|
||||
} from "@navikt/ds-tokens/types";
|
||||
|
||||
/* Old */
|
||||
import borderRadii from "@navikt/ds-tokens/src/border.json";
|
||||
import bgColors from "@navikt/ds-tokens/src/colors-bg.json";
|
||||
import borderColors from "@navikt/ds-tokens/src/colors-border.json";
|
||||
import surfaceColors from "@navikt/ds-tokens/src/colors-surface.json";
|
||||
import shadows from "@navikt/ds-tokens/src/shadow.json";
|
||||
import Spacing from "@navikt/ds-tokens/src/spacing.json";
|
||||
export type BackgroundColorToken = LegacyBgColorKeys;
|
||||
export type SurfaceColorToken = LegacySurfaceColorKeys;
|
||||
export type BorderColorToken = LegacyBorderColorKeys;
|
||||
export type ShadowToken = LegacyShadowKeys;
|
||||
|
||||
export type BackgroundColorToken = keyof typeof bgColors.a;
|
||||
export type SurfaceColorToken = keyof typeof surfaceColors.a;
|
||||
export type BorderColorToken = keyof typeof borderColors.a;
|
||||
export type BorderRadiiToken =
|
||||
| keyof (typeof borderRadii.a)["border-radius"]
|
||||
| "0";
|
||||
export type ShadowToken = keyof typeof shadows.a.shadow;
|
||||
export type BreakpointsAlias = Extract<
|
||||
BreakPointKeys,
|
||||
"xs" | "sm" | "md" | "lg" | "xl" | "2xl"
|
||||
>;
|
||||
|
||||
export type BreakpointsAlias = "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
|
||||
|
||||
export type SpacingScale = keyof (typeof Spacing)["a"]["spacing"];
|
||||
export type SpacingScale = SpacingKeys;
|
||||
|
||||
export type SpaceDelimitedAttribute<T extends string> =
|
||||
| T
|
||||
@@ -33,21 +29,3 @@ type FixedResponsiveT<T> = {
|
||||
};
|
||||
|
||||
export type ResponsiveProp<T> = T | FixedResponsiveT<T>;
|
||||
|
||||
/**
|
||||
* Darkside tokens
|
||||
*/
|
||||
export type SemanticShadowTokens = keyof ReturnType<
|
||||
typeof shadowTokenConfig
|
||||
>["shadow"];
|
||||
|
||||
export type SemanticStaticBgDarkside = keyof ReturnType<
|
||||
typeof semanticTokenConfig
|
||||
>["bg"];
|
||||
|
||||
export type SemanticRoleBgDarkside =
|
||||
keyof SemanticTokensForAllRolesConfigT<"color">["bg"];
|
||||
|
||||
export type SemanticStaticBorderDarkside = keyof ReturnType<
|
||||
typeof semanticTokenConfig
|
||||
>["border"];
|
||||
@@ -2,7 +2,7 @@ import { useFloatingPortalNode } from "@floating-ui/react";
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef, useContext, useEffect, useRef } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { DateContext } from "../date/context";
|
||||
import { DateInputContext } from "../date/context";
|
||||
import { useProvider } from "../provider/Provider";
|
||||
import { Detail, Heading } from "../typography";
|
||||
import { composeEventHandlers } from "../util/composeEventHandlers";
|
||||
@@ -106,7 +106,7 @@ export const Modal = forwardRef<HTMLDialogElement, ModalProps>(
|
||||
const rootElement = useProvider()?.rootElement;
|
||||
const portalNode = useFloatingPortalNode({ root: rootElement });
|
||||
|
||||
const dateContext = useContext(DateContext);
|
||||
const dateContext = useContext(DateInputContext);
|
||||
const isNested = useModalContext(false) !== undefined;
|
||||
if (isNested && !dateContext) {
|
||||
console.error("Modals should not be nested");
|
||||
|
||||
@@ -17,7 +17,7 @@ export interface ModalHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
const ModalHeader = forwardRef<HTMLDivElement, ModalHeaderProps>(
|
||||
({ children, className, closeButton = true, ...rest }, ref) => {
|
||||
const context = useModalContext();
|
||||
const translate = useI18n("Modal");
|
||||
const translate = useI18n("global");
|
||||
|
||||
return (
|
||||
<div {...rest} ref={ref} className={cl("navds-modal__header", className)}>
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
} from "@floating-ui/react";
|
||||
import cl from "clsx";
|
||||
import React, { HTMLAttributes, forwardRef, useContext, useRef } from "react";
|
||||
import { DateContext } from "../date/context";
|
||||
import { DateInputContext } from "../date/context";
|
||||
import { useModalContext } from "../modal/Modal.context";
|
||||
import { DismissableLayer } from "../overlays/dismissablelayer/DismissableLayer";
|
||||
import { UNSAFE_useAkselTheme } from "../provider";
|
||||
@@ -121,7 +121,7 @@ export const Popover = forwardRef<HTMLDivElement, PopoverProps>(
|
||||
) => {
|
||||
const arrowRef = useRef<HTMLDivElement | null>(null);
|
||||
const isInModal = useModalContext(false) !== undefined;
|
||||
const isInDatepicker = useContext(DateContext) !== null;
|
||||
const isInDatepicker = useContext(DateInputContext) !== null;
|
||||
const chosenStrategy = userStrategy ?? (isInModal ? "fixed" : "absolute");
|
||||
const chosenFlip = isInDatepicker ? false : _flip;
|
||||
|
||||
|
||||
@@ -1,21 +1,50 @@
|
||||
import React, { createContext, useContext } from "react";
|
||||
import { PartialTranslations, Translations } from "../util/i18n/i18n.types";
|
||||
import nb from "../util/i18n/locales/nb";
|
||||
|
||||
export interface ProviderContextType {
|
||||
type ProviderContextType = {
|
||||
rootElement?: HTMLElement;
|
||||
locale: Translations;
|
||||
translations?: PartialTranslations | PartialTranslations[];
|
||||
};
|
||||
|
||||
export const ProviderContext = createContext<ProviderContextType>({
|
||||
locale: nb,
|
||||
});
|
||||
|
||||
export type ProviderProps = {
|
||||
children: React.ReactNode;
|
||||
/**
|
||||
* Global root-element to attach portals to (Tooltip)
|
||||
* Global root-element to attach portals to. Used by Tooltip, Modal (optionally) and ActionMenu.
|
||||
*/
|
||||
rootElement?: HTMLElement;
|
||||
}
|
||||
|
||||
export const ProviderContext = createContext<ProviderContextType | undefined>(
|
||||
undefined,
|
||||
} & (
|
||||
| {
|
||||
/**
|
||||
* Aksel locale
|
||||
* @default nb
|
||||
* @example
|
||||
* ```jsx
|
||||
* import { en } from "@navikt/ds-react/locales";
|
||||
* <Provider locale={en}>
|
||||
* {app}
|
||||
* </Provider>
|
||||
* ```
|
||||
*/
|
||||
locale: Translations;
|
||||
/**
|
||||
* Use this if you need to override some of the default translations.
|
||||
* Can be a single object or an array of objects.
|
||||
* Must be used together with the `locale` prop.
|
||||
*/
|
||||
translations?: PartialTranslations | PartialTranslations[];
|
||||
}
|
||||
| {
|
||||
locale?: never;
|
||||
translations?: never;
|
||||
}
|
||||
);
|
||||
|
||||
export interface ProviderProps {
|
||||
children?: React.ReactNode;
|
||||
rootElement?: HTMLElement;
|
||||
}
|
||||
|
||||
export const useProvider = () => useContext(ProviderContext);
|
||||
|
||||
/**
|
||||
@@ -31,9 +60,23 @@ export const useProvider = () => useContext(ProviderContext);
|
||||
* </Provider>
|
||||
* ```
|
||||
*/
|
||||
export const Provider = ({ children, ...rest }: ProviderProps) => {
|
||||
export const Provider = ({
|
||||
children,
|
||||
rootElement,
|
||||
locale,
|
||||
translations,
|
||||
}: ProviderProps) => {
|
||||
const parentContext = useProvider();
|
||||
return (
|
||||
<ProviderContext.Provider value={rest}>{children}</ProviderContext.Provider>
|
||||
<ProviderContext.Provider
|
||||
value={{
|
||||
rootElement: rootElement || parentContext.rootElement,
|
||||
locale: locale || parentContext.locale || nb,
|
||||
translations: translations || parentContext.translations,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</ProviderContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
import React, { createContext, useContext } from "react";
|
||||
import { PartialTranslations } from "../../util/i18n/i18n.types";
|
||||
import nb from "../../util/i18n/locales/nb";
|
||||
|
||||
export interface LanguageProviderContextType {
|
||||
/**
|
||||
* Merged with the default language translations object (officially provided translations).
|
||||
*/
|
||||
translations: PartialTranslations | PartialTranslations[];
|
||||
}
|
||||
|
||||
export const LanguageProviderContext =
|
||||
createContext<LanguageProviderContextType>({
|
||||
translations: nb,
|
||||
});
|
||||
|
||||
export interface LanguageProviderProps {
|
||||
children?: React.ReactNode;
|
||||
translations?: PartialTranslations | PartialTranslations[];
|
||||
}
|
||||
|
||||
export const useProvider = () => useContext(LanguageProviderContext);
|
||||
|
||||
/**
|
||||
* @private Feature is under development and should not be used in any applications.
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <UNSAFE_AkselLanguageProvider translations={{...}}>
|
||||
* {app}
|
||||
* </UNSAFE_AkselLanguageProvider>
|
||||
* ```
|
||||
*/
|
||||
export const UNSAFE_AkselLanguageProvider = ({
|
||||
children,
|
||||
translations,
|
||||
}: LanguageProviderProps) => {
|
||||
return (
|
||||
<LanguageProviderContext.Provider
|
||||
value={{
|
||||
translations: translations ?? nb,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</LanguageProviderContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export default UNSAFE_AkselLanguageProvider;
|
||||
@@ -60,7 +60,7 @@ export const Default = ({ asButton, ...props }) => {
|
||||
Saksopplysninger
|
||||
</Stepper.Step>
|
||||
<Stepper.Step {...newProps} completed={props.completed}>
|
||||
Søknadstekst for en veldig spesifikk prosess i NAV som må beskrives og
|
||||
Søknadstekst for en veldig spesifikk prosess i Nav som må beskrives og
|
||||
forklares i sitt fulle i denne labelen
|
||||
</Stepper.Step>
|
||||
<Stepper.Step {...newProps}>Vedlegg</Stepper.Step>
|
||||
@@ -93,7 +93,7 @@ export const Horizontal: StoryFn<Story> = () => {
|
||||
<Stepper.Step {...props}>Personopplysninger</Stepper.Step>
|
||||
<Stepper.Step {...props}>Saksopplysninger</Stepper.Step>
|
||||
<Stepper.Step {...props}>
|
||||
Søknadstekst for en veldig spesifikk prosess i NAV som har lang tekst
|
||||
Søknadstekst for en veldig spesifikk prosess i Nav som har lang tekst
|
||||
</Stepper.Step>
|
||||
<Stepper.Step {...props}>Vedlegg</Stepper.Step>
|
||||
<Stepper.Step {...props}>Oppsummering</Stepper.Step>
|
||||
@@ -116,7 +116,7 @@ export const Vertical: StoryFn<Story> = () => {
|
||||
<Stepper.Step {...props}>Personopplysninger</Stepper.Step>
|
||||
<Stepper.Step {...props}>Saksopplysninger</Stepper.Step>
|
||||
<Stepper.Step {...props}>
|
||||
Søknadstekst for en veldig spesifikk prosess i NAV som har lang tekst
|
||||
Søknadstekst for en veldig spesifikk prosess i Nav som har lang tekst
|
||||
</Stepper.Step>
|
||||
<Stepper.Step {...props}>Vedlegg</Stepper.Step>
|
||||
<Stepper.Step {...props}>Oppsummering</Stepper.Step>
|
||||
@@ -138,7 +138,7 @@ export const DisplayOnly: StoryFn<Story> = () => {
|
||||
<Stepper.Step completed>Personopplysninger</Stepper.Step>
|
||||
<Stepper.Step>Saksopplysninger</Stepper.Step>
|
||||
<Stepper.Step>
|
||||
Søknadstekst for en veldig spesifikk prosess i NAV som har lang tekst
|
||||
Søknadstekst for en veldig spesifikk prosess i Nav som har lang tekst
|
||||
</Stepper.Step>
|
||||
<Stepper.Step>Vedlegg</Stepper.Step>
|
||||
<Stepper.Step>Oppsummering</Stepper.Step>
|
||||
@@ -154,7 +154,7 @@ export const DisplayOnly: StoryFn<Story> = () => {
|
||||
<Stepper.Step completed>Personopplysninger</Stepper.Step>
|
||||
<Stepper.Step>Saksopplysninger</Stepper.Step>
|
||||
<Stepper.Step>
|
||||
Søknadstekst for en veldig spesifikk prosess i NAV som har lang tekst
|
||||
Søknadstekst for en veldig spesifikk prosess i Nav som har lang tekst
|
||||
</Stepper.Step>
|
||||
<Stepper.Step>Vedlegg</Stepper.Step>
|
||||
<Stepper.Step>Oppsummering</Stepper.Step>
|
||||
@@ -178,7 +178,7 @@ export const CompletedSteps: StoryFn<Story> = () => {
|
||||
<Stepper.Step completed>Personopplysninger</Stepper.Step>
|
||||
<Stepper.Step completed={activeStep > 3}>Saksopplysninger</Stepper.Step>
|
||||
<Stepper.Step completed={activeStep >= 4}>
|
||||
Søknadstekst for en veldig spesifikk prosess i NAV som har lang tekst
|
||||
Søknadstekst for en veldig spesifikk prosess i Nav som har lang tekst
|
||||
</Stepper.Step>
|
||||
<Stepper.Step completed={activeStep > 5} interactive={false}>
|
||||
Vedlegg
|
||||
@@ -198,7 +198,7 @@ export const CompletedSteps: StoryFn<Story> = () => {
|
||||
</Stepper.Step>
|
||||
<Stepper.Step completed={activeStep > 3}>Saksopplysninger</Stepper.Step>
|
||||
<Stepper.Step completed={activeStep >= 4}>
|
||||
Søknadstekst for en veldig spesifikk prosess i NAV som har lang tekst
|
||||
Søknadstekst for en veldig spesifikk prosess i Nav som har lang tekst
|
||||
</Stepper.Step>
|
||||
<Stepper.Step completed={activeStep > 5}>Vedlegg</Stepper.Step>
|
||||
<Stepper.Step completed={activeStep > 6}>Oppsummering</Stepper.Step>
|
||||
|
||||
@@ -78,6 +78,7 @@ export const ExpandableRow: ExpandableRowType = forwardRef(
|
||||
onChange: onOpenChange,
|
||||
});
|
||||
const translate = useI18n("global");
|
||||
|
||||
const id = useId();
|
||||
|
||||
const expansionHandler = (event: React.MouseEvent<HTMLElement>) => {
|
||||
@@ -110,7 +111,7 @@ export const ExpandableRow: ExpandableRowType = forwardRef(
|
||||
className={cl("navds-table__toggle-expand-cell", {
|
||||
"navds-table__toggle-expand-cell--open": _open,
|
||||
})}
|
||||
onClick={expansionHandler}
|
||||
onClick={!expansionDisabled ? expansionHandler : () => null}
|
||||
>
|
||||
{!expansionDisabled && (
|
||||
<button
|
||||
@@ -129,13 +130,19 @@ export const ExpandableRow: ExpandableRowType = forwardRef(
|
||||
</DataCell>
|
||||
{togglePlacement === "left" && children}
|
||||
</Row>
|
||||
<tr className="navds-table__expanded-row" aria-hidden={!_open} id={id}>
|
||||
<tr
|
||||
data-state={_open ? "open" : "closed"}
|
||||
className="navds-table__expanded-row"
|
||||
aria-hidden={!_open}
|
||||
id={id}
|
||||
>
|
||||
<td colSpan={colSpan} className="navds-table__expanded-row-cell">
|
||||
<AnimateHeight
|
||||
className="navds-table__expanded-row-collapse"
|
||||
innerClassName="navds-table__expanded-row-content"
|
||||
height={_open ? "auto" : 0}
|
||||
duration={250}
|
||||
duration={150}
|
||||
easing="cubic-bezier(0.39,0.57,0.56,1)"
|
||||
>
|
||||
{content}
|
||||
</AnimateHeight>
|
||||
|
||||
@@ -31,7 +31,13 @@ export interface TagProps extends HTMLAttributes<HTMLSpanElement> {
|
||||
| "alt2-moderate"
|
||||
| "alt3"
|
||||
| "alt3-filled"
|
||||
| "alt3-moderate";
|
||||
| "alt3-moderate"
|
||||
| "meta-purple"
|
||||
| "meta-purple-filled"
|
||||
| "meta-purple-moderate"
|
||||
| "meta-lime"
|
||||
| "meta-lime-filled"
|
||||
| "meta-lime-moderate";
|
||||
/**
|
||||
* @default "medium"
|
||||
*/
|
||||
@@ -54,23 +60,31 @@ export interface TagProps extends HTMLAttributes<HTMLSpanElement> {
|
||||
* ```
|
||||
*/
|
||||
export const Tag = forwardRef<HTMLSpanElement, TagProps>(
|
||||
({ children, className, variant, size = "medium", icon, ...rest }, ref) => (
|
||||
<BodyShort
|
||||
{...rest}
|
||||
ref={ref}
|
||||
as="span"
|
||||
size={size === "medium" ? "medium" : "small"}
|
||||
className={cl(
|
||||
"navds-tag",
|
||||
className,
|
||||
`navds-tag--${variant}`,
|
||||
`navds-tag--${size}`,
|
||||
)}
|
||||
>
|
||||
{icon && <span className="navds-tag__icon--left">{icon}</span>}
|
||||
{children}
|
||||
</BodyShort>
|
||||
),
|
||||
({ children, className, variant, size = "medium", icon, ...rest }, ref) => {
|
||||
const filledVariant = variant?.endsWith("-filled") && "strong";
|
||||
const moderateVariant = variant?.endsWith("-moderate") && "moderate";
|
||||
const color = variant?.replace("-filled", "").replace("-moderate", "");
|
||||
|
||||
return (
|
||||
<BodyShort
|
||||
{...rest}
|
||||
ref={ref}
|
||||
as="span"
|
||||
size={size === "medium" ? "medium" : "small"}
|
||||
className={cl(
|
||||
"navds-tag",
|
||||
className,
|
||||
`navds-tag--${variant}`,
|
||||
`navds-tag--${size}`,
|
||||
`navds-tag--${filledVariant || moderateVariant || "outline"}`,
|
||||
`navds-tag--${color}`,
|
||||
)}
|
||||
>
|
||||
{icon && <span className="navds-tag__icon--left">{icon}</span>}
|
||||
{children}
|
||||
</BodyShort>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
export default Tag;
|
||||
Loaded 100 of 227 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user