mirror of
https://github.com/navikt/aksel.git
synced 2026-10-16 10:42:03 +00:00
Compare commits
45
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8cd6512181 | ||
|
|
7e976f9e20 | ||
|
|
db828bddd3 | ||
|
|
443b129fe1 | ||
|
|
561fecbcac | ||
|
|
00177898f5 | ||
|
|
38f5e63008 | ||
|
|
c3d65a681e | ||
|
|
3025e4eb5c | ||
|
|
043277f79b | ||
|
|
a2b3936878 | ||
|
|
c90abe7c23 | ||
|
|
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
|
||||
|
||||
@@ -47,12 +47,12 @@ jobs:
|
||||
- name: Chromatic
|
||||
uses: chromaui/action@latest
|
||||
id: chromatic_tests
|
||||
continue-on-error: true
|
||||
continue-on-error: false
|
||||
with:
|
||||
autoAcceptChanges: "main"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
||||
exitZeroOnChanges: false
|
||||
exitZeroOnChanges: true
|
||||
buildScriptName: "build:storybook-chromatic"
|
||||
onlyChanged: true
|
||||
untraced: "**/package.json|yarn.lock|**/*.md"
|
||||
@@ -62,14 +62,14 @@ jobs:
|
||||
STORYBOOK_GITHUB_SHA: ${{ github.sha }}
|
||||
|
||||
- name: Get commit sha
|
||||
if: "!contains(github.event.head_commit.message, '[ci skip]') && github.event_name != 'push'"
|
||||
if: github.event_name != 'push' && !contains(github.event.head_commit.message, '[ci skip]')
|
||||
id: vars
|
||||
shell: bash
|
||||
run: |
|
||||
echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
|
||||
|
||||
- name: Find Comment
|
||||
if: "!contains(github.event.head_commit.message, '[ci skip]') && github.event_name != 'push'"
|
||||
if: github.event_name != 'push' && !contains(github.event.head_commit.message, '[ci skip]')
|
||||
uses: peter-evans/find-comment@v2
|
||||
id: fc
|
||||
with:
|
||||
@@ -78,19 +78,7 @@ jobs:
|
||||
body-includes: Storybook demo
|
||||
|
||||
- name: Create or update comment
|
||||
if: steps.chromatic_tests.outcome == 'success' && !contains(github.event.head_commit.message, '[ci skip]') && github.event_name != 'push'
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
## [Storybook demo](${{steps.chromatic_tests.outputs.storybookUrl}})
|
||||
|
||||
[${{ steps.vars.outputs.sha_short }}](https://github.com/navikt/aksel/commit/${{ steps.vars.outputs.sha_short }}) | ${{steps.chromatic_tests.outputs.componentCount}} komponenter | ${{steps.chromatic_tests.outputs.specCount}} stories
|
||||
edit-mode: replace
|
||||
|
||||
- name: Create or update failed comment
|
||||
if: steps.chromatic_tests.outcome != 'success' && !contains(github.event.head_commit.message, '[ci skip]') && github.event_name != 'push'
|
||||
if: github.event_name != 'push' && !contains(github.event.head_commit.message, '[ci skip]')
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
@@ -98,10 +86,9 @@ jobs:
|
||||
body: |
|
||||
## [Storybook demo](${{steps.chromatic_tests.outputs.storybookUrl}}) / [Chromatic](${{steps.chromatic_tests.outputs.url}})
|
||||
|
||||
### 📝 Endringer til review: ${{steps.chromatic_tests.outputs.changeCount}}
|
||||
${{ steps.chromatic_tests.outputs.changeCount > 0 && format('### 📝 Changes to review: {0}', steps.chromatic_tests.outputs.changeCount) || '' }}
|
||||
${{ steps.chromatic_tests.outputs.errorCount > 0 && format('### ❌ Stories with errors: {0}', steps.chromatic_tests.outputs.errorCount) || '' }}
|
||||
${{ steps.chromatic_tests.outputs.interactionTestFailuresCount > 0 && format('### ❌ Failed interaction tests: {0}', steps.chromatic_tests.outputs.interactionTestFailuresCount) || '' }}
|
||||
|
||||
${{ steps.chromatic_tests.outputs.errorCount > 0 && format('### ❌ Stories med feil: {0}', steps.chromatic_tests.outputs.errorCount) || '' }}
|
||||
${{ steps.chromatic_tests.outputs.interactionTestFailuresCount > 0 && format('### ❌ Feilede interaksjonstester: {0}', steps.chromatic_tests.outputs.interactionTestFailuresCount) || '' }}
|
||||
|
||||
[${{ steps.vars.outputs.sha_short }}](https://github.com/navikt/aksel/commit/${{ steps.vars.outputs.sha_short }}) | ${{steps.chromatic_tests.outputs.componentCount}} komponenter | ${{steps.chromatic_tests.outputs.specCount}} stories
|
||||
[${{ steps.vars.outputs.sha_short }}](https://github.com/navikt/aksel/commit/${{ steps.vars.outputs.sha_short }}) | ${{steps.chromatic_tests.outputs.componentCount}} components | ${{steps.chromatic_tests.outputs.specCount}} stories
|
||||
edit-mode: replace
|
||||
@@ -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,11 @@ 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 } from "../@navikt/core/react/src/provider";
|
||||
import { Theme } from "../@navikt/core/react/src/theme";
|
||||
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";
|
||||
@@ -29,9 +29,9 @@ const ModeDecorator = ({ children, mode, theme }) => {
|
||||
}, [mode]);
|
||||
|
||||
return mode === "darkside" ? (
|
||||
<UNSAFE_AkselTheme theme={theme || undefined} hasBackground={false}>
|
||||
<Theme theme={theme || undefined} hasBackground={false}>
|
||||
{children}
|
||||
</UNSAFE_AkselTheme>
|
||||
</Theme>
|
||||
) : (
|
||||
children
|
||||
);
|
||||
@@ -46,9 +46,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,11 @@
|
||||
# @navikt/aksel-icons
|
||||
|
||||
## 7.9.0
|
||||
|
||||
## 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.9.0",
|
||||
"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,15 @@
|
||||
# @navikt/aksel-stylelint
|
||||
|
||||
## 7.9.0
|
||||
|
||||
## 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.9.0",
|
||||
"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.9.0",
|
||||
"@navikt/ds-tokens": "^7.9.0",
|
||||
"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,26 @@
|
||||
# @navikt/aksel
|
||||
|
||||
## 7.9.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`db828bd`](https://github.com/navikt/aksel/commit/db828bddd393ba1d03d8e68fe80c9211da43e54a), [`0017789`](https://github.com/navikt/aksel/commit/00177898f55573a682a43819b08304c1f60a732a), [`c90abe7`](https://github.com/navikt/aksel/commit/c90abe7c23e2520e5131d138f3193a4de0e28b9d), [`0017789`](https://github.com/navikt/aksel/commit/00177898f55573a682a43819b08304c1f60a732a)]:
|
||||
- @navikt/ds-css@7.9.0
|
||||
|
||||
## 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.9.0",
|
||||
"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.9.0",
|
||||
"axios": "1.7.4",
|
||||
"chalk": "4.1.0",
|
||||
"clipboardy": "^2.3.0",
|
||||
|
||||
@@ -1,5 +1,38 @@
|
||||
# @navikt/ds-css
|
||||
|
||||
## 7.9.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- ErrorSummary: :sparkles: new prop to prefix error with a warning icon. ([#3445](https://github.com/navikt/aksel/pull/3445))
|
||||
All form components: replace dot with warning icon in error message.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Switch: Update switch to better reflect unchecked state. ([#3468](https://github.com/navikt/aksel/pull/3468))
|
||||
|
||||
- Select: :bug: Focus-border no longer cancels out error-border. ([#3465](https://github.com/navikt/aksel/pull/3465))
|
||||
|
||||
- Textarea: :bug: Focus-border no longer cancels out error-border. ([#3465](https://github.com/navikt/aksel/pull/3465))
|
||||
|
||||
## 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
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
margin-right: var(--ac-button-icon-margin);
|
||||
}
|
||||
|
||||
.navds-button__icon:only-child {
|
||||
.navds-button--icon-only .navds-button__icon {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@@ -497,6 +497,10 @@
|
||||
}
|
||||
|
||||
/* Loader overrides */
|
||||
.navds-button .navds-loader {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.navds-button .navds-loader .navds-loader__foreground {
|
||||
stroke: var(--ac-button-loader-stroke, currentColor);
|
||||
}
|
||||
@@ -506,6 +510,10 @@
|
||||
stroke: var(--ac-button-primary-loader-stroke-bg, rgb(255 255 255 / 0.3));
|
||||
}
|
||||
|
||||
.navds-button--loading > :not(.navds-loader) {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.navds-button:not(.navds-button--loading):where(:disabled, .navds-button--disabled) {
|
||||
opacity: 1;
|
||||
|
||||
@@ -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";
|
||||
@@ -69,7 +69,7 @@
|
||||
margin-right: var(--__axc-button-icon-margin);
|
||||
}
|
||||
|
||||
&:only-child {
|
||||
.navds-button--icon-only & {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
@@ -260,10 +260,14 @@
|
||||
}
|
||||
|
||||
.navds-button:not(.navds-button--loading):where(:disabled, .navds-button--disabled) {
|
||||
opacity: 0.3;
|
||||
opacity: var(--ax-opacity-disabled);
|
||||
}
|
||||
|
||||
/* Loader overrides */
|
||||
.navds-button .navds-loader {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.navds-button .navds-loader .navds-loader__foreground {
|
||||
stroke: currentColor;
|
||||
}
|
||||
@@ -273,6 +277,10 @@
|
||||
stroke: rgb(255 255 255 / 0.3);
|
||||
}
|
||||
|
||||
.navds-button--loading > :not(.navds-loader) {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.navds-button:not(.navds-button--loading):where(:disabled, .navds-button--disabled) {
|
||||
opacity: 1;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -9,21 +9,8 @@
|
||||
color: var(--ax-text-subtle);
|
||||
}
|
||||
|
||||
.navds-form-field .navds-error-message,
|
||||
.navds-fieldset .navds-error-message,
|
||||
.navds-file-item .navds-error-message {
|
||||
display: flex;
|
||||
gap: var(--ax-spacing-2);
|
||||
}
|
||||
|
||||
.navds-form-field .navds-error-message::before,
|
||||
.navds-fieldset .navds-error-message::before,
|
||||
.navds-file-item .navds-error-message::before {
|
||||
content: "•";
|
||||
}
|
||||
|
||||
.navds-form-field--disabled {
|
||||
opacity: 0.3;
|
||||
opacity: var(--ax-opacity-disabled);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
@@ -41,7 +28,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;
|
||||
}
|
||||
}
|
||||
@@ -13,11 +13,10 @@
|
||||
border-radius: var(--ax-border-radius-medium);
|
||||
background-color: transparent;
|
||||
box-shadow: inset 0 0 0 1px var(--ax-border-default);
|
||||
padding: var(--ax-spacing-1);
|
||||
gap: var(--ax-spacing-1);
|
||||
display: inline-grid;
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: 1fr;
|
||||
gap: 1px;
|
||||
}
|
||||
|
||||
/* Button */
|
||||
@@ -26,13 +25,14 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--ax-spacing-1) var(--ax-spacing-3);
|
||||
min-height: 2.5rem;
|
||||
min-height: 3rem;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
color: var(--ax-text-default);
|
||||
border-radius: var(--ax-border-radius-small);
|
||||
border-radius: var(--ax-border-radius-medium);
|
||||
min-width: fit-content;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--ax-bg-accent-moderate-hoverA);
|
||||
@@ -42,12 +42,23 @@
|
||||
&:focus-visible {
|
||||
outline: 2px solid var(--ax-border-focus);
|
||||
outline-offset: 2px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&[aria-checked="true"] {
|
||||
&[data-selected="true"] {
|
||||
background-color: var(--ax-bg-accent-strong-pressed);
|
||||
color: var(--ax-text-accent-contrast);
|
||||
}
|
||||
|
||||
&:not([data-selected="true"], :first-child, &[data-selected="true"] + &)::before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 1px;
|
||||
height: 50%;
|
||||
background-color: var(--ax-border-subtleA);
|
||||
left: -1px;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
.navds-toggle-group__button-inner {
|
||||
@@ -70,7 +81,7 @@
|
||||
background-color: var(--ax-bg-neutral-moderate-hoverA);
|
||||
}
|
||||
|
||||
&[aria-checked="true"] {
|
||||
&[data-selected="true"] {
|
||||
background-color: var(--ax-bg-neutral-strong-pressed);
|
||||
color: var(--ax-text-neutral-contrast);
|
||||
}
|
||||
@@ -80,7 +91,7 @@
|
||||
.navds-toggle-group--small {
|
||||
& .navds-toggle-group__button {
|
||||
padding: var(--ax-spacing-05) var(--ax-spacing-3);
|
||||
min-height: 1.5rem;
|
||||
min-height: 2rem;
|
||||
}
|
||||
|
||||
& .navds-toggle-group__button-inner > svg {
|
||||
@@ -94,14 +105,13 @@
|
||||
border: 2px solid transparent;
|
||||
}
|
||||
|
||||
.navds-toggle-group__button[aria-checked="true"]:hover,
|
||||
.navds-toggle-group__button:hover {
|
||||
background-color: highlighttext;
|
||||
color: highlight;
|
||||
outline: 1px solid highlight;
|
||||
}
|
||||
|
||||
.navds-toggle-group__button[aria-checked="true"] {
|
||||
.navds-toggle-group__button[data-selected="true"] {
|
||||
background-color: selecteditem;
|
||||
color: selecteditemtext;
|
||||
forced-color-adjust: none;
|
||||
|
||||
@@ -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);
|
||||
@@ -216,6 +204,18 @@ body,
|
||||
|
||||
.navds-error-message {
|
||||
color: var(--ax-text-danger);
|
||||
|
||||
&.navds-error-message--show-icon {
|
||||
display: flex;
|
||||
gap: var(--ax-spacing-1);
|
||||
|
||||
& svg {
|
||||
margin-top: 0.15em;
|
||||
flex: 0 0 auto;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------- Utilities ------------------------------- */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -17,19 +17,6 @@
|
||||
color: var(--ac-form-description, var(--__ac-form-description, var(--a-text-subtle)));
|
||||
}
|
||||
|
||||
.navds-form-field .navds-error-message,
|
||||
.navds-fieldset .navds-error-message,
|
||||
.navds-file-item .navds-error-message {
|
||||
display: flex;
|
||||
gap: var(--a-spacing-2);
|
||||
}
|
||||
|
||||
.navds-form-field .navds-error-message::before,
|
||||
.navds-fieldset .navds-error-message::before,
|
||||
.navds-file-item .navds-error-message::before {
|
||||
content: "•";
|
||||
}
|
||||
|
||||
.navds-form-field--disabled {
|
||||
opacity: 0.3;
|
||||
cursor: not-allowed;
|
||||
|
||||
@@ -73,11 +73,15 @@
|
||||
/**
|
||||
Error handling
|
||||
*/
|
||||
.navds-select--error > * select:not(:hover, :focus, :disabled) {
|
||||
.navds-select--error > * .navds-select__input:not(:hover, :disabled) {
|
||||
box-shadow: 0 0 0 1px var(--ac-select-error-border, var(--a-surface-danger));
|
||||
border-color: var(--ac-select-error-border, var(--a-surface-danger));
|
||||
}
|
||||
|
||||
.navds-select--error .navds-select__input:focus {
|
||||
box-shadow: var(--a-shadow-focus);
|
||||
}
|
||||
|
||||
/**
|
||||
Disabled
|
||||
*/
|
||||
|
||||
@@ -72,12 +72,15 @@
|
||||
.navds-switch__track {
|
||||
width: 2.75rem;
|
||||
height: 1.5rem;
|
||||
background-color: var(--ac-switch-bg, var(--a-surface-neutral));
|
||||
background-color: var(--ac-switch-bg, var(--a-surface-default));
|
||||
border: 2px solid var(--a-border-default);
|
||||
position: absolute;
|
||||
top: var(--a-spacing-3);
|
||||
left: 0;
|
||||
border-radius: var(--a-border-radius-full);
|
||||
transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-property: background-color, border-color;
|
||||
transition-duration: 100ms;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.navds-switch--small > .navds-switch__track {
|
||||
@@ -92,18 +95,20 @@
|
||||
|
||||
.navds-switch__input:checked ~ .navds-switch__track {
|
||||
background-color: var(--ac-switch-checked-bg, var(--a-surface-action-selected));
|
||||
border-color: var(--ac-switch-checked-bg, var(--a-surface-action-selected));
|
||||
}
|
||||
|
||||
.navds-switch__input:hover ~ .navds-switch__track {
|
||||
background-color: var(--ac-switch-hover-bg, var(--a-surface-neutral-hover));
|
||||
background-color: var(--ac-switch-hover-bg, var(--a-surface-subtle));
|
||||
}
|
||||
|
||||
.navds-switch__input:hover:checked ~ .navds-switch__track {
|
||||
.navds-switch__input:hover:checked:not(:disabled) ~ .navds-switch__track {
|
||||
background-color: var(--ac-switch-checked-hover-bg, var(--a-surface-action-selected-hover));
|
||||
border-color: var(--ac-switch-checked-hover-bg, var(--a-surface-action-selected-hover));
|
||||
}
|
||||
|
||||
.navds-switch__input:disabled ~ .navds-switch__track {
|
||||
background-color: var(--ac-switch-bg, var(--a-surface-neutral));
|
||||
background-color: var(--ac-switch-bg, var(--a-surface-default));
|
||||
}
|
||||
|
||||
.navds-switch__input:checked:disabled ~ .navds-switch__track {
|
||||
@@ -129,15 +134,15 @@
|
||||
|
||||
/* Thumb */
|
||||
.navds-switch__thumb {
|
||||
background-color: var(--ac-switch-thumb-bg, var(--a-surface-default));
|
||||
background-color: var(--ac-switch-thumb-bg, var(--a-surface-neutral));
|
||||
color: var(--ac-switch-thumb-icon, var(--a-icon-subtle));
|
||||
border-radius: var(--a-border-radius-full);
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
width: 1.125rem;
|
||||
height: 1.125rem;
|
||||
position: absolute;
|
||||
transform: translateX(0);
|
||||
left: var(--a-spacing-05);
|
||||
top: var(--a-spacing-05);
|
||||
left: 0.0625rem;
|
||||
top: 0.0625rem;
|
||||
transition: transform 250ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -147,6 +152,11 @@
|
||||
.navds-switch__input:checked ~ .navds-switch__track > .navds-switch__thumb {
|
||||
transform: translateX(1.25rem);
|
||||
color: var(--ac-switch-thumb-icon-checked, var(--a-icon-action-selected));
|
||||
background-color: var(--a-surface-default);
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.navds-switch__input:checked ~ .navds-switch__track .navds-switch__checkmark {
|
||||
@@ -195,6 +205,7 @@
|
||||
.navds-switch--readonly > .navds-switch__input:checked ~ .navds-switch__track,
|
||||
.navds-switch--readonly > .navds-switch__input:checked:hover ~ .navds-switch__track {
|
||||
background-color: var(--a-surface-neutral-moderate);
|
||||
border-color: var(--a-border-subtle);
|
||||
}
|
||||
|
||||
.navds-switch--readonly > .navds-switch__label-wrapper,
|
||||
@@ -212,12 +223,12 @@
|
||||
}
|
||||
|
||||
.navds-switch--readonly .navds-switch__thumb {
|
||||
background-color: var(--a-surface-subtle);
|
||||
box-shadow: 0 0 0 2px var(--a-border-default);
|
||||
background-color: var(--a-surface-neutral);
|
||||
}
|
||||
|
||||
.navds-switch--readonly > .navds-switch__input:checked ~ .navds-switch__track > .navds-switch__thumb {
|
||||
color: var(--a-icon-subtle);
|
||||
color: var(--a-icon-on-neutral);
|
||||
background-color: var(--a-surface-neutral);
|
||||
}
|
||||
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
@@ -237,7 +248,9 @@
|
||||
}
|
||||
|
||||
.navds-switch__thumb,
|
||||
.navds-switch--readonly .navds-switch__thumb {
|
||||
.navds-switch--readonly .navds-switch__thumb,
|
||||
.navds-switch__input:checked ~ .navds-switch__track > .navds-switch__thumb,
|
||||
.navds-switch--readonly .navds-switch__input:checked ~ .navds-switch__track > .navds-switch__thumb {
|
||||
background-color: fieldtext;
|
||||
}
|
||||
|
||||
@@ -246,11 +259,8 @@
|
||||
color: field;
|
||||
}
|
||||
|
||||
.navds-switch__track {
|
||||
width: calc(2.75rem + 4px);
|
||||
height: calc(1.5rem + 4px);
|
||||
top: var(--a-spacing-3);
|
||||
border: 2px solid fieldtext;
|
||||
.navds-switch--disabled:not(.navds-switch--loading) .navds-switch__input:checked ~ .navds-switch__track > .navds-switch__thumb {
|
||||
background-color: graytext;
|
||||
}
|
||||
|
||||
.navds-switch__input:focus-visible ~ .navds-switch__track {
|
||||
@@ -264,6 +274,7 @@
|
||||
|
||||
.navds-switch--disabled:not(.navds-switch--loading) .navds-switch__thumb {
|
||||
background-color: graytext;
|
||||
border-color: graytext;
|
||||
}
|
||||
|
||||
.navds-switch--disabled:not(.navds-switch--loading) .navds-switch__track {
|
||||
|
||||
@@ -111,16 +111,13 @@
|
||||
/**
|
||||
Error handling
|
||||
*/
|
||||
.navds-textarea--error .navds-textarea__input:not(:hover, :focus-visible, :disabled) {
|
||||
.navds-textarea--error .navds-textarea__input:not(:hover, :disabled) {
|
||||
box-shadow: 0 0 0 1px var(--ac-textarea-error-border, var(--__ac-textarea-error-border, var(--a-border-danger)));
|
||||
border-color: var(--ac-textarea-error-border, var(--__ac-textarea-error-border, var(--a-border-danger)));
|
||||
}
|
||||
|
||||
@supports not selector(:focus-visible) {
|
||||
.navds-textarea--error .navds-textarea__input:not(:hover, :focus, :disabled) {
|
||||
box-shadow: 0 0 0 1px var(--ac-textarea-error-border, var(--__ac-textarea-error-border, var(--a-border-danger)));
|
||||
border-color: var(--ac-textarea-error-border, var(--__ac-textarea-error-border, var(--a-border-danger)));
|
||||
}
|
||||
.navds-textarea--error .navds-textarea__input:focus-visible {
|
||||
box-shadow: var(--a-shadow-focus);
|
||||
}
|
||||
|
||||
.navds-textarea__input:disabled {
|
||||
|
||||
@@ -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.9.0",
|
||||
"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.9.0",
|
||||
"@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",
|
||||
@@ -414,11 +411,11 @@
|
||||
},
|
||||
"switch": {
|
||||
"--ac-switch-action": "--a-surface-action-selected",
|
||||
"--ac-switch-bg": "--a-surface-neutral",
|
||||
"--ac-switch-bg": "--a-surface-default",
|
||||
"--ac-switch-checked-bg": "--a-surface-action-selected",
|
||||
"--ac-switch-hover-bg": "--a-surface-neutral-hover",
|
||||
"--ac-switch-hover-bg": "--a-surface-subtle",
|
||||
"--ac-switch-checked-hover-bg": "--a-surface-action-selected-hover",
|
||||
"--ac-switch-thumb-bg": "--a-surface-default",
|
||||
"--ac-switch-thumb-bg": "--a-surface-neutral",
|
||||
"--ac-switch-thumb-icon": "--a-icon-subtle",
|
||||
"--ac-switch-thumb-icon-checked": "--a-icon-action-selected"
|
||||
},
|
||||
|
||||
@@ -216,6 +216,18 @@
|
||||
color: var(--ac-typo-error-text, var(--__ac-typo-error-text, var(--a-text-danger)));
|
||||
}
|
||||
|
||||
.navds-error-message.navds-error-message--show-icon {
|
||||
display: flex;
|
||||
gap: var(--a-spacing-1);
|
||||
}
|
||||
|
||||
.navds-error-message.navds-error-message--show-icon svg {
|
||||
margin-top: 0.15em;
|
||||
flex: 0 0 auto;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
.navds-typo--truncate {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
|
||||
@@ -1,5 +1,64 @@
|
||||
# @navikt/ds-react
|
||||
|
||||
## 7.9.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- ErrorSummary: :sparkles: new prop to prefix error with a warning icon. ([#3445](https://github.com/navikt/aksel/pull/3445))
|
||||
All form components: replace dot with warning icon in error message.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Button: Fix edge-case where setting "loading={true}" in a Modal caused the button to get 0 width and not show spinner ([#3252](https://github.com/navikt/aksel/pull/3252))
|
||||
|
||||
- Switch: Update switch to better reflect unchecked state. ([#3468](https://github.com/navikt/aksel/pull/3468))
|
||||
|
||||
- Textarea: resize immediately upon receiving resize event (eg. inside modal opening). ([#3463](https://github.com/navikt/aksel/pull/3463))
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-tokens@7.9.0
|
||||
- @navikt/aksel-icons@7.9.0
|
||||
|
||||
## 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.9.0",
|
||||
"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.9.0",
|
||||
"@navikt/ds-tokens": "^7.9.0",
|
||||
"clsx": "^2.1.0",
|
||||
"date-fns": "^3.0.0",
|
||||
"react-day-picker": "8.10.1"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef, useContext } from "react";
|
||||
import { UNSAFE_useAkselTheme } from "../provider";
|
||||
import { useThemeInternal } from "../theme/Theme";
|
||||
import { BodyLong } from "../typography";
|
||||
import { AccordionItemContext } from "./AccordionItem";
|
||||
|
||||
@@ -16,7 +16,7 @@ const AccordionContent = forwardRef<HTMLDivElement, AccordionContentProps>(
|
||||
({ children, className, ...rest }, ref) => {
|
||||
const context = useContext(AccordionItemContext);
|
||||
|
||||
const themeContext = UNSAFE_useAkselTheme(false);
|
||||
const themeContext = useThemeInternal(false);
|
||||
|
||||
if (context === null) {
|
||||
console.error(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef, useContext } from "react";
|
||||
import { ChevronDownIcon } from "@navikt/aksel-icons";
|
||||
import { UNSAFE_useAkselTheme } from "../provider";
|
||||
import { useThemeInternal } from "../theme/Theme";
|
||||
import { Heading } from "../typography";
|
||||
import { composeEventHandlers } from "../util/composeEventHandlers";
|
||||
import { AccordionContext } from "./AccordionContext";
|
||||
@@ -20,7 +20,7 @@ const AccordionHeader = forwardRef<HTMLButtonElement, AccordionHeaderProps>(
|
||||
const itemContext = useContext(AccordionItemContext);
|
||||
const accordionContext = useContext(AccordionContext);
|
||||
|
||||
const themeContext = UNSAFE_useAkselTheme(false);
|
||||
const themeContext = useThemeInternal(false);
|
||||
|
||||
if (itemContext === null) {
|
||||
console.error(
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef, useRef, useState } from "react";
|
||||
import React, { forwardRef } from "react";
|
||||
import { Loader } from "../loader";
|
||||
import { Label } from "../typography";
|
||||
import { omit } from "../util";
|
||||
import { composeEventHandlers } from "../util/composeEventHandlers";
|
||||
import { useClientLayoutEffect } from "../util/hooks";
|
||||
import { useMergeRefs } from "../util/hooks/useMergeRefs";
|
||||
import { OverridableComponent } from "../util/types";
|
||||
|
||||
export interface ButtonProps
|
||||
@@ -74,37 +72,18 @@ export const Button: OverridableComponent<ButtonProps, HTMLButtonElement> =
|
||||
size = "medium",
|
||||
loading = false,
|
||||
disabled,
|
||||
style,
|
||||
icon,
|
||||
iconPosition = "left",
|
||||
onKeyUp,
|
||||
...rest
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const buttonRef = useRef<HTMLButtonElement | null>(null);
|
||||
const [widthOverride, setWidthOverride] = useState<number>();
|
||||
|
||||
const mergedRef = useMergeRefs(buttonRef, ref);
|
||||
|
||||
useClientLayoutEffect(() => {
|
||||
if (loading) {
|
||||
const requestID = window.requestAnimationFrame(() => {
|
||||
setWidthOverride(
|
||||
buttonRef?.current?.getBoundingClientRect()?.width,
|
||||
);
|
||||
});
|
||||
return () => {
|
||||
setWidthOverride(undefined);
|
||||
cancelAnimationFrame(requestID);
|
||||
};
|
||||
}
|
||||
}, [loading, children]);
|
||||
|
||||
const filterProps: React.ButtonHTMLAttributes<HTMLButtonElement> =
|
||||
disabled ?? widthOverride ? omit(rest, ["href"]) : rest;
|
||||
disabled || loading ? omit(rest, ["href"]) : rest;
|
||||
|
||||
const handleKeyUp = (e: React.KeyboardEvent<HTMLButtonElement>) => {
|
||||
if (e.key === " " && !disabled && !widthOverride) {
|
||||
if (e.key === " " && !disabled && !loading) {
|
||||
e.currentTarget.click();
|
||||
}
|
||||
};
|
||||
@@ -113,41 +92,32 @@ export const Button: OverridableComponent<ButtonProps, HTMLButtonElement> =
|
||||
<Component
|
||||
{...(Component !== "button" ? { role: "button" } : {})}
|
||||
{...filterProps}
|
||||
ref={mergedRef}
|
||||
onKeyUp={composeEventHandlers(filterProps.onKeyUp, handleKeyUp)}
|
||||
ref={ref}
|
||||
onKeyUp={composeEventHandlers(onKeyUp, handleKeyUp)}
|
||||
className={cl(
|
||||
className,
|
||||
"navds-button",
|
||||
`navds-button--${variant}`,
|
||||
`navds-button--${size}`,
|
||||
{
|
||||
"navds-button--loading": widthOverride,
|
||||
"navds-button--loading": loading,
|
||||
"navds-button--icon-only": !!icon && !children,
|
||||
"navds-button--disabled": disabled ?? widthOverride,
|
||||
"navds-button--disabled": disabled ?? loading,
|
||||
},
|
||||
)}
|
||||
style={{
|
||||
...style,
|
||||
width: widthOverride,
|
||||
}}
|
||||
disabled={disabled ?? widthOverride ? true : undefined}
|
||||
disabled={disabled ?? loading ? true : undefined}
|
||||
>
|
||||
{widthOverride ? (
|
||||
<Loader size={size} />
|
||||
) : (
|
||||
<>
|
||||
{icon && iconPosition === "left" && (
|
||||
<span className="navds-button__icon">{icon}</span>
|
||||
)}
|
||||
{children && (
|
||||
<Label as="span" size={size === "medium" ? "medium" : "small"}>
|
||||
{children}
|
||||
</Label>
|
||||
)}
|
||||
{icon && iconPosition === "right" && (
|
||||
<span className="navds-button__icon">{icon}</span>
|
||||
)}
|
||||
</>
|
||||
{icon && iconPosition === "left" && (
|
||||
<span className="navds-button__icon">{icon}</span>
|
||||
)}
|
||||
{loading && <Loader size={size} />}
|
||||
{children && (
|
||||
<Label as="span" size={size === "medium" ? "medium" : "small"}>
|
||||
{children}
|
||||
</Label>
|
||||
)}
|
||||
{icon && iconPosition === "right" && (
|
||||
<span className="navds-button__icon">{icon}</span>
|
||||
)}
|
||||
</Component>
|
||||
);
|
||||
|
||||
@@ -2,6 +2,8 @@ import { StoryObj } from "@storybook/react";
|
||||
import React from "react";
|
||||
import { StarIcon as BaseStarIcon } from "@navikt/aksel-icons";
|
||||
import { HStack, VStack } from "../layout/stack";
|
||||
import { Modal } from "../modal";
|
||||
import { BodyLong } from "../typography";
|
||||
import { Button } from "./index";
|
||||
|
||||
export default {
|
||||
@@ -154,6 +156,51 @@ export const DisabledAsLink: Story = {
|
||||
render: () => <ButtonGrid disabled href="#" as="a" />,
|
||||
};
|
||||
|
||||
export const InsideModal: Story = {
|
||||
render: () => {
|
||||
const ref = React.useRef<HTMLDialogElement>(null);
|
||||
|
||||
return (
|
||||
<div className="py-16">
|
||||
<Button onClick={() => ref.current?.showModal()}>Åpne modal</Button>
|
||||
|
||||
<Modal ref={ref} header={{ heading: "Overskrift" }}>
|
||||
<Modal.Body>
|
||||
<BodyLong>
|
||||
Culpa aliquip ut cupidatat laborum minim quis ex in aliqua. Qui
|
||||
incididunt dolor do ad ut. Incididunt eiusmod nostrud deserunt
|
||||
duis laborum. Proident aute culpa qui nostrud velit adipisicing
|
||||
minim. Consequat aliqua aute dolor do sit Lorem nisi mollit velit.
|
||||
Aliqua exercitation non minim minim pariatur sunt laborum ipsum.
|
||||
Exercitation nostrud est laborum magna non non aliqua qui esse.
|
||||
</BodyLong>
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<Button loading type="button" onClick={() => ref.current?.close()}>
|
||||
Primær
|
||||
</Button>
|
||||
<Button
|
||||
loading
|
||||
type="button"
|
||||
variant="secondary"
|
||||
onClick={() => ref.current?.close()}
|
||||
>
|
||||
Sekundær
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
variant="tertiary"
|
||||
onClick={() => ref.current?.close()}
|
||||
>
|
||||
Tertiær
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export const Chromatic: Story = {
|
||||
render: () => (
|
||||
<VStack gap="6" align="center">
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
import React from "react";
|
||||
import { Button as RDPButton, useDayPicker } from "react-day-picker";
|
||||
import { Button } from "../../../button";
|
||||
import { UNSAFE_useAkselTheme } from "../../../provider";
|
||||
import { useThemeInternal } from "../../../theme/Theme";
|
||||
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 themeContext = UNSAFE_useAkselTheme(false);
|
||||
const translate = useI18n("DatePicker", getTranslations(code));
|
||||
const { onWeekNumberClick, styles, classNames } = useDayPicker();
|
||||
const themeContext = useThemeInternal(false);
|
||||
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";
|
||||
|
||||
@@ -151,7 +150,11 @@ const DateInput = forwardRef<HTMLInputElement, DateInputProps>((props, ref) => {
|
||||
aria-relevant="additions removals"
|
||||
aria-live="polite"
|
||||
>
|
||||
{showErrorMsg && <ErrorMessage size={size}>{props.error}</ErrorMessage>}
|
||||
{showErrorMsg && (
|
||||
<ErrorMessage size={size} showIcon>
|
||||
{props.error}
|
||||
</ErrorMessage>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
@@ -71,7 +71,11 @@ export const Combobox = forwardRef<
|
||||
aria-relevant="additions removals"
|
||||
aria-live="polite"
|
||||
>
|
||||
{showErrorMsg && <ErrorMessage size={size}>{error}</ErrorMessage>}
|
||||
{showErrorMsg && (
|
||||
<ErrorMessage size={size} showIcon>
|
||||
{error}
|
||||
</ErrorMessage>
|
||||
)}
|
||||
</div>
|
||||
</ComboboxWrapper>
|
||||
);
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -91,7 +91,11 @@ export const ConfirmationPanel = forwardRef<
|
||||
</Checkbox>
|
||||
</div>
|
||||
<div className="navds-form-field__error" id={errorId} role="alert">
|
||||
{showErrorMsg && <ErrorMessage size={size}>{props.error}</ErrorMessage>}
|
||||
{showErrorMsg && (
|
||||
<ErrorMessage size={size} showIcon>
|
||||
{props.error}
|
||||
</ErrorMessage>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
},
|
||||
};
|
||||
@@ -113,7 +113,9 @@ export const Fieldset = forwardRef<HTMLFieldSetElement, FieldsetProps>(
|
||||
className="navds-fieldset__error"
|
||||
>
|
||||
{showErrorMsg && (
|
||||
<ErrorMessage size={size}>{props.error}</ErrorMessage>
|
||||
<ErrorMessage size={size} showIcon>
|
||||
{props.error}
|
||||
</ErrorMessage>
|
||||
)}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
@@ -177,7 +177,7 @@ const Dropzone = forwardRef<HTMLInputElement, FileUploadDropzoneProps>(
|
||||
aria-relevant="additions removals"
|
||||
aria-live="polite"
|
||||
>
|
||||
{showErrorMsg && <ErrorMessage>{error}</ErrorMessage>}
|
||||
{showErrorMsg && <ErrorMessage showIcon>{error}</ErrorMessage>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import React, {
|
||||
} from "react";
|
||||
import { MagnifyingGlassIcon, XMarkIcon } from "@navikt/aksel-icons";
|
||||
import { Button } from "../../button";
|
||||
import { UNSAFE_useAkselTheme } from "../../provider";
|
||||
import { useThemeInternal } from "../../theme/Theme";
|
||||
import { BodyShort, ErrorMessage, Label } from "../../typography";
|
||||
import { omit } from "../../util";
|
||||
import { useMergeRefs } from "../../util/hooks/useMergeRefs";
|
||||
@@ -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>
|
||||
* ```
|
||||
*/
|
||||
@@ -124,7 +125,7 @@ export const Search = forwardRef<HTMLInputElement, SearchProps>(
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
const themeContext = UNSAFE_useAkselTheme(false);
|
||||
const themeContext = useThemeInternal(false);
|
||||
|
||||
const searchRef = useRef<HTMLInputElement | null>(null);
|
||||
const mergedRef = useMergeRefs(searchRef, ref);
|
||||
@@ -262,7 +263,9 @@ export const Search = forwardRef<HTMLInputElement, SearchProps>(
|
||||
aria-live="polite"
|
||||
>
|
||||
{showErrorMsg && (
|
||||
<ErrorMessage size={size}>{props.error}</ErrorMessage>
|
||||
<ErrorMessage size={size} showIcon>
|
||||
{props.error}
|
||||
</ErrorMessage>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -151,7 +151,9 @@ export const Select = forwardRef<HTMLSelectElement, SelectProps>(
|
||||
aria-live="polite"
|
||||
>
|
||||
{showErrorMsg && (
|
||||
<ErrorMessage size={size}>{props.error}</ErrorMessage>
|
||||
<ErrorMessage size={size} showIcon>
|
||||
{props.error}
|
||||
</ErrorMessage>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,6 @@ import React, {
|
||||
useState,
|
||||
} from "react";
|
||||
import { Loader } from "../../loader";
|
||||
import { UNSAFE_useAkselTheme } from "../../provider";
|
||||
import { BodyShort } from "../../typography";
|
||||
import { omit } from "../../util";
|
||||
import { ReadOnlyIconWithTitle } from "../ReadOnlyIcon";
|
||||
@@ -69,8 +68,6 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
|
||||
defaultChecked ?? checkedProp ?? false,
|
||||
);
|
||||
|
||||
const themeContext = UNSAFE_useAkselTheme(false);
|
||||
|
||||
useEffect(() => {
|
||||
checkedProp !== undefined && setChecked(checkedProp);
|
||||
}, [checkedProp]);
|
||||
@@ -121,13 +118,7 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
|
||||
<Loader
|
||||
size="xsmall"
|
||||
aria-live="polite"
|
||||
variant={
|
||||
checked
|
||||
? "interaction"
|
||||
: themeContext
|
||||
? "inverted"
|
||||
: "neutral"
|
||||
}
|
||||
variant={checked ? "interaction" : "inverted"}
|
||||
/>
|
||||
) : (
|
||||
<svg
|
||||
|
||||
@@ -54,6 +54,7 @@ export interface TextareaProps
|
||||
UNSAFE_autoScrollbar?: boolean;
|
||||
/**
|
||||
* i18n-translations for counter-text
|
||||
* @deprecated Use `<Provider />`-component
|
||||
*/
|
||||
i18n?: {
|
||||
/** @default tegn igjen */
|
||||
@@ -192,7 +193,9 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
|
||||
aria-live="polite"
|
||||
>
|
||||
{showErrorMsg && (
|
||||
<ErrorMessage size={size}>{props.error}</ErrorMessage>
|
||||
<ErrorMessage size={size} showIcon>
|
||||
{props.error}
|
||||
</ErrorMessage>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Meta, StoryFn, StoryObj } from "@storybook/react";
|
||||
import { expect, userEvent, within } from "@storybook/test";
|
||||
import React, { useState } from "react";
|
||||
import { Button } from "../../button";
|
||||
import { VStack } from "../../layout/stack";
|
||||
import { Modal } from "../../modal";
|
||||
import { Textarea } from "./index";
|
||||
|
||||
@@ -74,6 +75,24 @@ export const WithError: StoryFn = () => {
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<VStack
|
||||
style={{
|
||||
maxWidth: "400px",
|
||||
}}
|
||||
gap="4"
|
||||
>
|
||||
<Textarea
|
||||
label="Ipsum enim quis culpa"
|
||||
error="Consectetur labore velit eiusmod Lorem ut nostrud mollit labore ullamco laboris laboris in."
|
||||
/>
|
||||
|
||||
<Textarea
|
||||
label="Ipsum enim quis culpa"
|
||||
error="Consectetur labore velit eiusmod Lorem ut nostrud mollit labore ullamco laboris laboris in."
|
||||
size="small"
|
||||
/>
|
||||
</VStack>
|
||||
|
||||
<Textarea
|
||||
label="Ipsum enim quis culpa"
|
||||
error="Consectetur labore velit eiusmod Lorem ut nostrud mollit labore ullamco laboris laboris in."
|
||||
@@ -207,6 +226,27 @@ AutoScrollbar.argTypes = {
|
||||
minRows: { type: "number" },
|
||||
};
|
||||
|
||||
export const InsideModal: StoryFn<typeof Textarea> = () => {
|
||||
const ref = React.useRef<HTMLDialogElement>(null);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button onClick={() => ref.current?.showModal()}>Open modal</Button>
|
||||
<React.StrictMode>
|
||||
<Modal
|
||||
ref={ref}
|
||||
header={{ heading: "Skjema" }}
|
||||
aria-label="Modal med textarea"
|
||||
>
|
||||
<Modal.Body>
|
||||
<Textarea label="Har du noen tilbakemeldinger?" />
|
||||
</Modal.Body>
|
||||
</Modal>
|
||||
</React.StrictMode>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const ModalStrictMode: StoryFn<typeof Textarea> = () => {
|
||||
// Story added after fixing an issue where TextareaAutoSize would reach max re-renders
|
||||
// and set the height to 2px when used in StrictMode in a Modal that is initially open.
|
||||
|
||||
Loaded 100 of 272 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user