mirror of
https://github.com/navikt/aksel.git
synced 2026-10-13 09:12:03 +00:00
Compare commits
131
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
265e105fd0 | ||
|
|
8d934e0931 | ||
|
|
6981fbccff | ||
|
|
bfee5a822e | ||
|
|
58ed3b5367 | ||
|
|
00b3dd7d59 | ||
|
|
90db7dd0c1 | ||
|
|
b6d0304d5a | ||
|
|
de0a797e09 | ||
|
|
c4eaf0f350 | ||
|
|
fb9897e6a0 | ||
|
|
3438b5d7e7 | ||
|
|
3583062824 | ||
|
|
2993f809ad | ||
|
|
fe25e1fdf2 | ||
|
|
5cda39ce19 | ||
|
|
6cb25e44de | ||
|
|
5812d6ee87 | ||
|
|
a402777c70 | ||
|
|
d4064bd461 | ||
|
|
1c482e03b8 | ||
|
|
608e1f3944 | ||
|
|
107d6f3d93 | ||
|
|
09d41e9b6d | ||
|
|
ebacbddd44 | ||
|
|
e58b072c84 | ||
|
|
e7cb3753a0 | ||
|
|
7486ba11f9 | ||
|
|
cf01a6e162 | ||
|
|
a67f95433f | ||
|
|
dd03078e33 | ||
|
|
72321e3846 | ||
|
|
1cd8ac93ed | ||
|
|
48d6f14103 | ||
|
|
44da7fcdc6 | ||
|
|
e68ab5cb2c | ||
|
|
c721b392f9 | ||
|
|
1d0d0ce665 | ||
|
|
9d02940543 | ||
|
|
7ff63a2c63 | ||
|
|
49f33a78d8 | ||
|
|
06aaec70f0 | ||
|
|
5fbf230e47 | ||
|
|
53265c247e | ||
|
|
d78f33df79 | ||
|
|
4375c55ab6 | ||
|
|
0de8238ecf | ||
|
|
647b14a238 | ||
|
|
64901adccb | ||
|
|
49ddb2094c | ||
|
|
8a5f209735 | ||
|
|
d3bd1202ed | ||
|
|
4bf6027518 | ||
|
|
c8e203c523 | ||
|
|
267799ca0e | ||
|
|
42934af3a1 | ||
|
|
eff8a902c5 | ||
|
|
d34a8f45ef | ||
|
|
d1ceb40439 | ||
|
|
e033b34c3b | ||
|
|
de3991d0f0 | ||
|
|
9641215506 | ||
|
|
8a82e1c1f6 | ||
|
|
a2dfc8699b | ||
|
|
492cfc1801 | ||
|
|
9ca5932fed | ||
|
|
5950673fbf | ||
|
|
5b42ff07ee | ||
|
|
09ba52ea76 | ||
|
|
a82bccf707 | ||
|
|
89ae778c24 | ||
|
|
5b2669d35d | ||
|
|
8a82bb4a96 | ||
|
|
7871e0f95c | ||
|
|
3182888a07 | ||
|
|
f2742da085 | ||
|
|
92721aefa0 | ||
|
|
e6fdfdc9b4 | ||
|
|
93975bc935 | ||
|
|
3a0dac3997 | ||
|
|
1d43710af0 | ||
|
|
6df7c78e3c | ||
|
|
476d79e487 | ||
|
|
238a715c92 | ||
|
|
0fadd33e3e | ||
|
|
eadc0bce13 | ||
|
|
678db9b11b | ||
|
|
e3027cc196 | ||
|
|
ac0fd790e3 | ||
|
|
c344c9beb4 | ||
|
|
5cb5dea4ff | ||
|
|
054c63b161 | ||
|
|
f60ba32f97 | ||
|
|
54811b394d | ||
|
|
c6b0570c4c | ||
|
|
8baa1ab0b4 | ||
|
|
06ceeb3e6f | ||
|
|
02f19858c7 | ||
|
|
799e26a628 | ||
|
|
f5e5843916 | ||
|
|
4b8ed30554 | ||
|
|
28430f1345 | ||
|
|
d242325863 | ||
|
|
ae70bfa719 | ||
|
|
0aef861622 | ||
|
|
525b021e0f | ||
|
|
761344c34e | ||
|
|
a67f61c33f | ||
|
|
b05958863b | ||
|
|
883ae00dfa | ||
|
|
6eb8a79092 | ||
|
|
718b3204d8 | ||
|
|
45970ac0fb | ||
|
|
fe5e8ada74 | ||
|
|
3e625a5cb5 | ||
|
|
edc3495ce6 | ||
|
|
2520bc7ff5 | ||
|
|
44446e753a | ||
|
|
4156326752 | ||
|
|
23970486ed | ||
|
|
a8f1069650 | ||
|
|
f9c8320b74 | ||
|
|
c4839a12ed | ||
|
|
60f64d7f70 | ||
|
|
e32dbe5c5d | ||
|
|
de36269582 | ||
|
|
6cb6c52770 | ||
|
|
a877d24ed0 | ||
|
|
a1b6332fa1 | ||
|
|
99c08b8e4a | ||
|
|
d39ed906c6 |
No files matched your search
@@ -1,6 +1,9 @@
|
||||
{
|
||||
"$schema": "https://unpkg.com/@changesets/config@2.2.0/schema.json",
|
||||
"changelog": ["@changesets/changelog-github", { "repo": "navikt/aksel" }],
|
||||
"changelog": [
|
||||
"@svitejs/changesets-changelog-github-compact",
|
||||
{ "repo": "navikt/aksel" }
|
||||
],
|
||||
"commit": false,
|
||||
"fixed": [
|
||||
[
|
||||
|
||||
@@ -1,17 +1,44 @@
|
||||
### :memo: PR Checklist
|
||||
### Description
|
||||
|
||||
<!-- Remove non-relevant fields -->
|
||||
<!-- PR description/motivation
|
||||
add links to project-tasks, slack discussions etc here
|
||||
-->
|
||||
|
||||
- [ ] :sparkles: New component? Add CSS-mappings to `@navikt/core/css/config/_mappings.js`.
|
||||
### Change summary
|
||||
|
||||
- [ ] :wastebasket: Are you deprecating a CSS class? (are you removing the last known reference to a CSS class?). Add it to `@navikt/aksel-stylelint/src/deprecations.ts` with a suitable description.
|
||||
<!-- Short summary of changes in PR
|
||||
- added variant x
|
||||
- fixed bug in y
|
||||
-->
|
||||
|
||||
- [ ] :balance_scale: Is the feature/component/code sufficiently complex to warrant tests? Add some unit-tests :test_tube:
|
||||
### PR Checklist 📝 (Remove fields after check!)
|
||||
|
||||
- [ ] :balance_scale: Does the feature/component add some complex user-interactions? Consider adding some [interaction-tests with storybook](https://storybook.js.org/docs/react/writing-tests/interaction-testing) :test_tube:
|
||||
#### New component? ✨
|
||||
|
||||
- [ ] :boom: Are there breaking changes? Consider adding a codemod for easier migration.
|
||||
- Check that component-styling is correctly configured in `@navikt/core/css/config/_mappings.js`. This is needed for correct build and CDN upload.
|
||||
- Check that styling is correctly exported from `@navikt/core/css/index.css`
|
||||
- Check that correct tokens for component is documented in `@navikt/core/css/tokens.json`
|
||||
- Check that only needed components and types are exported from `@navikt/core/react/src/index.ts`
|
||||
- Add JSDoc to component (see other components for reference)
|
||||
- Create storybook-stories for relevant component variations and compositions. Stories are used for [visual regression testing](https://www.chromatic.com/docs/), so make sure they are complete.
|
||||
- Is the component sufficiently complex to warrant tests? Add some unit-tests for jest.
|
||||
|
||||
- [ ] :test_tube: Are all variations and cases shown in the storybook stories? Stories are used for [visual regression testing](https://www.chromatic.com/docs/), so make sure they are complete.
|
||||
#### Component-updates 🎉
|
||||
|
||||
- [ ] Run `yarn changeset` for version and changelog generation
|
||||
- Revalidate if everything under `New component` is still accounted for
|
||||
- Deprecating/removing a CSS class? Add it to `@navikt/aksel-stylelint/src/deprecations.ts` with a suitable description. This helps stylelint-users keep their code clean and bug-free.
|
||||
|
||||
#### Documentation 📝
|
||||
|
||||
- Add/update component-demos for component `aksel.nav.no/website/pages/eksempler`
|
||||
- Create/Update documentation in sanity if needed
|
||||
Note: Props, tokens and examples only updates to sanity on merge to main
|
||||
|
||||
#### Versioning 🏷️
|
||||
|
||||
- Run `yarn changeset` to generate a version-entry for change.
|
||||
- - Bug/hotfix: Patch
|
||||
- - New feature: Minor
|
||||
- - Breaking change: Major
|
||||
- Adding breaking changes? Consider adding a codemod for easier migration.
|
||||
- Breaking changes also needs documentation under "Migration"-page on website
|
||||
@@ -75,7 +75,7 @@ jobs:
|
||||
with:
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
comment-author: "github-actions[bot]"
|
||||
body-includes: github-comment-finder
|
||||
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'
|
||||
@@ -84,7 +84,7 @@ jobs:
|
||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
### [<img id="github-comment-finder" src="https://raw.githubusercontent.com/storybookjs/brand/main/logo/logo-storybook-inverse.svg" height="32"/>](${{steps.storybook_url.outputs.replaced}})
|
||||
## [Storybook demo](${{steps.storybook_url.outputs.replaced}})
|
||||
|
||||
[${{ 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
|
||||
@@ -96,7 +96,7 @@ jobs:
|
||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
### [<img id="github-comment-finder" src="https://raw.githubusercontent.com/storybookjs/brand/main/logo/logo-storybook-inverse.svg" height="32"/>](${{steps.storybook_url.outputs.replaced}})
|
||||
## [Storybook demo](${{steps.storybook_url.outputs.replaced}})
|
||||
|
||||
### [Endringer til review](${{steps.chromatic_tests.outputs.url}}): ${{steps.chromatic_tests.outputs.changeCount}}
|
||||
|
||||
|
||||
@@ -28,6 +28,10 @@ jobs:
|
||||
node-version: 16.13.0
|
||||
cache: yarn
|
||||
|
||||
- uses: denoland/setup-deno@v1
|
||||
with:
|
||||
deno-version: v1.x
|
||||
|
||||
- name: Restore cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
|
||||
@@ -10,6 +10,11 @@ module.exports = (indexers) => {
|
||||
const exampleIndexer = async (fileName: string, opts) => {
|
||||
let code = readFileSync(fileName, "utf-8").toString();
|
||||
|
||||
code = code
|
||||
.split("\n")
|
||||
.filter((line) => !line.includes("withDsExample"))
|
||||
.join("\n");
|
||||
|
||||
code = code.replace("export const args =", "const args =");
|
||||
|
||||
code += `\nexport default { title: "Eksempler/${fileName
|
||||
|
||||
+3
-8
@@ -1,5 +1,4 @@
|
||||
const storyIndexers = require("./indexer");
|
||||
|
||||
const path = require("path");
|
||||
const { mergeConfig } = require("vite");
|
||||
|
||||
@@ -59,15 +58,11 @@ module.exports = {
|
||||
},
|
||||
async viteFinal(config) {
|
||||
return mergeConfig(config, {
|
||||
define: { "process.env": {} },
|
||||
define: {
|
||||
"process.env": {},
|
||||
},
|
||||
resolve: {
|
||||
alias: [
|
||||
/*
|
||||
// Example
|
||||
{
|
||||
find: "@components",
|
||||
replacement: path.resolve(__dirname, "./src/components"),
|
||||
}, */
|
||||
{
|
||||
find: "components",
|
||||
replacement: path.resolve(
|
||||
|
||||
@@ -4,7 +4,7 @@ import "./layout.css";
|
||||
export const parameters = {
|
||||
options: {
|
||||
storySort: {
|
||||
method: "",
|
||||
method: "alphabetical",
|
||||
order: ["Intro", "ds-react", ["form"], ["Default"], "ds-icons"],
|
||||
locales: "",
|
||||
},
|
||||
|
||||
@@ -1,233 +1,135 @@
|
||||
# @navikt/aksel-icons
|
||||
|
||||
## 4.2.0
|
||||
## 5.0.3
|
||||
|
||||
## 4.1.7
|
||||
## 5.0.2
|
||||
|
||||
## 4.1.6
|
||||
## 5.0.1
|
||||
|
||||
## 5.0.0
|
||||
|
||||
## 4.12.1
|
||||
|
||||
## 4.12.0
|
||||
|
||||
## 4.11.2
|
||||
|
||||
## 4.11.1
|
||||
|
||||
## 4.11.0
|
||||
|
||||
## 4.10.2
|
||||
|
||||
## 4.10.1
|
||||
|
||||
## 4.10.0
|
||||
|
||||
## 4.9.1
|
||||
|
||||
## 4.9.0
|
||||
|
||||
## 4.8.0
|
||||
|
||||
## 4.7.4
|
||||
|
||||
## 4.7.3
|
||||
|
||||
## 4.7.2
|
||||
|
||||
## 4.7.1
|
||||
|
||||
## 4.7.0
|
||||
|
||||
## 4.6.1
|
||||
|
||||
## 4.6.0
|
||||
|
||||
## 4.5.0
|
||||
|
||||
## 4.4.2
|
||||
|
||||
## 4.4.1
|
||||
|
||||
## 4.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2054](https://github.com/navikt/aksel/pull/2054) [`8f16d1571`](https://github.com/navikt/aksel/commit/8f16d1571ec7cf452c09618a9a918ee2a634c75a) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: Nye ikoner
|
||||
|
||||
- ChevronRightLast
|
||||
- ChevronLeftLast
|
||||
|
||||
## 4.1.4
|
||||
|
||||
## 4.1.3
|
||||
|
||||
## 4.1.2
|
||||
|
||||
## 4.1.1
|
||||
|
||||
## 4.1.0
|
||||
|
||||
## 4.0.0
|
||||
|
||||
## 3.4.2
|
||||
|
||||
## 3.4.1
|
||||
|
||||
## 3.4.0
|
||||
|
||||
## 3.3.1
|
||||
|
||||
## 3.3.0
|
||||
|
||||
## 3.2.4
|
||||
- Nye ikoner `ChevronRightLast` og `ChevronLeftLast` ([PR](https://github.com/navikt/aksel/pull/2054))
|
||||
|
||||
## 3.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1998](https://github.com/navikt/aksel/pull/1998) [`53c98181c`](https://github.com/navikt/aksel/commit/53c98181c327ead3406bec3487c10232af7d463a) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: Nye ikoner!
|
||||
|
||||
- :sparkles: FileParagraph
|
||||
- :sparkles: FilePlus
|
||||
|
||||
## 3.2.2
|
||||
|
||||
## 3.2.1
|
||||
|
||||
## 3.2.0
|
||||
|
||||
## 3.1.3
|
||||
|
||||
## 3.1.2
|
||||
|
||||
## 3.1.1
|
||||
|
||||
## 3.1.0
|
||||
|
||||
## 3.0.1
|
||||
|
||||
## 3.0.0
|
||||
- Nye ikoner `FileParagraph` og `FilePlus` ([PR](https://github.com/navikt/aksel/pull/1998))
|
||||
|
||||
## 2.9.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1959](https://github.com/navikt/aksel/pull/1959) [`8790c5997`](https://github.com/navikt/aksel/commit/8790c5997e0d647419bdb5080c86781d08c196b8) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :lipstick: Statusikoner er nå tydeligere og mer konsistente.
|
||||
- Oppdatert Statusikoner til å være tydeligere og mer konsistente. ([PR](https://github.com/navikt/aksel/pull/1959))
|
||||
|
||||
## 2.9.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- :bug: CheckmarkIcon
|
||||
- Fikset `CheckmarkIcon`-bug
|
||||
|
||||
## 2.9.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1956](https://github.com/navikt/aksel/pull/1956) [`8c8559009`](https://github.com/navikt/aksel/commit/8c8559009982911bc4402913656ba4cc6a223dd1) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Fikset CheckmarkCircleIcon
|
||||
|
||||
## 2.9.5
|
||||
|
||||
## 2.9.4
|
||||
- Fikset `CheckmarkCircleIcon`-bug ([PR](https://github.com/navikt/aksel/pull/1956))
|
||||
|
||||
## 2.9.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1950](https://github.com/navikt/aksel/pull/1950) [`c03d53d5a`](https://github.com/navikt/aksel/commit/c03d53d5aa2dc7f06a223d48069fa21ee39bb396) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :sparkles: Nye ikoner
|
||||
|
||||
- :tada: BulletList
|
||||
- :tada: NumberList
|
||||
|
||||
## 2.9.2
|
||||
|
||||
## 2.9.1
|
||||
|
||||
## 2.9.0
|
||||
|
||||
## 2.8.16
|
||||
- Nye ikoner `BulletList` og `NumberList` ([PR](https://github.com/navikt/aksel/pull/1950))
|
||||
|
||||
## 2.8.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1928](https://github.com/navikt/aksel/pull/1928) [`dfe923582`](https://github.com/navikt/aksel/commit/dfe923582a57b41c77cfb4fbfa7c56be047ef2b0) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: Lagt til nye ikoner :tada:
|
||||
|
||||
- HandKnot.svg
|
||||
- HandKnotFilled.svg
|
||||
|
||||
- [#1930](https://github.com/navikt/aksel/pull/1930) [`6682be1c8`](https://github.com/navikt/aksel/commit/6682be1c8e6562213c64e5be4bed70fef54ab865) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Alle pakker implementerer nå npm provenance (beta)
|
||||
|
||||
## 2.8.14
|
||||
- :tada: Nye ikoner `HandKnot` og `HandKnotFilled` ([PR](https://github.com/navikt/aksel/pull/1928))
|
||||
|
||||
## 2.8.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1921](https://github.com/navikt/aksel/pull/1921) [`ecd6241e5`](https://github.com/navikt/aksel/commit/ecd6241e5751519fbda800a5f41a613957dbf77c) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Oppdatert ikoner :tada:
|
||||
|
||||
## 2.8.12
|
||||
- Oppdatert `InformationSquare`-ikon ([PR](https://github.com/navikt/aksel/pull/1921))
|
||||
|
||||
## 2.8.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1909](https://github.com/navikt/aksel/pull/1909) [`270427910`](https://github.com/navikt/aksel/commit/2704279107a5fbf93048de37d014e78f6721438f) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Oppdatert ikoner
|
||||
|
||||
## 2.8.10
|
||||
|
||||
## 2.8.9
|
||||
- Oppdatert `VideoSlack`, `Questionmark` og `Information`-ikoner ([PR](https://github.com/navikt/aksel/pull/1909))
|
||||
|
||||
## 2.8.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`ed8e28454`](https://github.com/navikt/aksel/commit/ed8e284540a9e3a5be7d1d5e393f31db86962613) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :sparkles: Nye ikoner
|
||||
|
||||
- :tada: VideoSlash
|
||||
- :tada: VideoSlashFill
|
||||
|
||||
## 2.8.7
|
||||
|
||||
## 2.8.6
|
||||
|
||||
## 2.8.5
|
||||
- Nye ikoner `VideoSlash` og `VideoSlashFill`
|
||||
|
||||
## 2.8.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Fikset Sourcemap-bug i Aksel-icons
|
||||
|
||||
## 2.8.3
|
||||
|
||||
## 2.8.2
|
||||
|
||||
## 2.8.1
|
||||
|
||||
## 2.8.0
|
||||
|
||||
## 2.7.8
|
||||
- Fikset Sourcemap-bug
|
||||
|
||||
## 2.7.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`a22ac3eb7`](https://github.com/navikt/aksel/commit/a22ac3eb78135bf93d4771802475396849809c03) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :Sparkles: Nye ikoner
|
||||
|
||||
- :tada: CaretUpDownFilledDown
|
||||
- :tada: CaretUpDownFilledUp
|
||||
- :tada: CloudDown
|
||||
- :tada: CloudDownFill
|
||||
- :tada: CloudUp
|
||||
- :tada: CloudUpFill
|
||||
- :tada: HddDown
|
||||
- :tada: HddDownFill
|
||||
- :tada: HddUp
|
||||
- :tada: HddUpFill
|
||||
- :tada: Inbox
|
||||
- :tada: InboxDown
|
||||
- :tada: InboxDownFill
|
||||
- :tada: InboxFill
|
||||
- :tada: InboxUp
|
||||
- :tada: InboxUpFill
|
||||
- :tada: ShoppingBasket
|
||||
- :tada: ShoppingBasketFill
|
||||
|
||||
## 2.7.6
|
||||
|
||||
## 2.7.5
|
||||
- Nye ikoner `CaretUpDownFilledDown`, `CaretUpDownFilledUp`, `CloudDown`, `CloudDownFill`, `CloudUp`, `CloudUpFill`, `HddDown`, `HddDownFill`, `HddUp`, `HddUpFill`, `Inbox`, `InboxDown`, `InboxDownFill`, `InboxFill`, `InboxUp`, `InboxUpFill`, `ShoppingBasket`, `ShoppingBasketFill`
|
||||
|
||||
## 2.7.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1852](https://github.com/navikt/aksel/pull/1852) [`a4fd1dd22`](https://github.com/navikt/aksel/commit/a4fd1dd227b9b56b747f962aa0c2b2dc9b4e30a4) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Oppdatert ikonpakke med nye ikoner :rocket:
|
||||
|
||||
- :tada: CaretDownFill
|
||||
- :tada: CaretLeft
|
||||
- :tada: CaretLeftFill
|
||||
- :tada: CaretLeftRight
|
||||
- :tada: CaretLeftRightFill
|
||||
- :tada: CaretRight
|
||||
- :tada: CaretRightFill
|
||||
- :tada: CaretUpDownFill
|
||||
- :tada: CaretUpFill
|
||||
- :tada: Escalator
|
||||
- :tada: Moon
|
||||
- :tada: MoonFill
|
||||
- :fire: EscalatorStroke
|
||||
|
||||
## 2.7.3
|
||||
|
||||
## 2.7.2
|
||||
|
||||
## 2.7.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`7d9517cf9`](https://github.com/navikt/aksel/commit/7d9517cf90331b57441a0787a04eef66efd1b9b0) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Public-access for ny ikonpakke i GPR
|
||||
- Nye ikoner, `CaretDownFill`, `CaretLeft`, `CaretLeftFill`, `CaretLeftRight`, `CaretLeftRightFill`, `CaretRight`, `CaretRightFill`, `CaretUpDownFill`, `CaretUpFill`, `Escalator`, `Moon`, `MoonFill`. Fjernet `EscalatorStroke` ([PR](https://github.com/navikt/aksel/pull/1852))
|
||||
|
||||
## 2.7.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1847](https://github.com/navikt/aksel/pull/1847) [`de291a972`](https://github.com/navikt/aksel/commit/de291a9722c262d40fecaec7be55b71f86e60160) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Ny ikonpakke med for core icons 3! `@navikt/aksel-icons`
|
||||
- Ny ikonpakke med for core icons 3! `@navikt/aksel-icons` ([PR](https://github.com/navikt/aksel/pull/1847))
|
||||
@@ -58,7 +58,7 @@
|
||||
.icon-button {
|
||||
min-height: 3rem;
|
||||
min-width: 3rem;
|
||||
border-radius: 2px;
|
||||
border-radius: var(--a-border-radius-small);
|
||||
display: grid;
|
||||
place-content: center;
|
||||
background-color: var(--a-surface-default);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import meta from "@navikt/aksel-icons/metadata";
|
||||
|
||||
const subCategorizeIcons = (
|
||||
icons: typeof meta[1][]
|
||||
): { sub_category: string; icons: typeof meta[1][] }[] => {
|
||||
const categories: { sub_category: string; icons: typeof meta[1][] }[] = [];
|
||||
icons: (typeof meta)[1][]
|
||||
): { sub_category: string; icons: (typeof meta)[1][] }[] => {
|
||||
const categories: { sub_category: string; icons: (typeof meta)[1][] }[] = [];
|
||||
|
||||
for (const icon of icons) {
|
||||
const i = categories.findIndex(
|
||||
@@ -19,14 +19,14 @@ const subCategorizeIcons = (
|
||||
};
|
||||
|
||||
export const categorizeIcons = (
|
||||
icons: typeof meta[1][]
|
||||
icons: (typeof meta)[1][]
|
||||
): {
|
||||
category: string;
|
||||
sub_categories: { sub_category: string; icons: typeof meta[1][] }[];
|
||||
sub_categories: { sub_category: string; icons: (typeof meta)[1][] }[];
|
||||
}[] => {
|
||||
const categories: {
|
||||
category: string;
|
||||
icons: typeof meta[1][];
|
||||
icons: (typeof meta)[1][];
|
||||
}[] = [];
|
||||
|
||||
for (const icon of icons) {
|
||||
@@ -42,14 +42,14 @@ export const categorizeIcons = (
|
||||
.map((x) => ({ ...x, sub_categories: subCategorizeIcons(x.icons) }));
|
||||
};
|
||||
|
||||
const noFill = (icon: typeof meta[1], icons: typeof meta[1][]) => {
|
||||
const noFill = (icon: (typeof meta)[1], icons: (typeof meta)[1][]) => {
|
||||
const foundFill = icons.find(
|
||||
(x) => x.name.endsWith("Fill") && x.name.replace("Fill", "") === icon.name
|
||||
);
|
||||
return !foundFill;
|
||||
};
|
||||
|
||||
export const getFillIcon = (icons: typeof meta[1][]) => {
|
||||
export const getFillIcon = (icons: (typeof meta)[1][]) => {
|
||||
return icons.filter(
|
||||
(x, _, z) => x.variant.toLowerCase() === "fill" || noFill(x, z)
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/aksel-icons",
|
||||
"version": "4.2.0",
|
||||
"version": "5.0.3",
|
||||
"author": "Aksel | NAV",
|
||||
"homepage": "https://aksel.nav.no/ikoner",
|
||||
"repository": {
|
||||
|
||||
@@ -1,56 +1,75 @@
|
||||
# @navikt/aksel-stylelint
|
||||
|
||||
## 4.2.0
|
||||
## 5.0.3
|
||||
|
||||
### Minor Changes
|
||||
## 5.0.2
|
||||
|
||||
- [#2048](https://github.com/navikt/aksel/pull/2048) [`b1625ba38`](https://github.com/navikt/aksel/commit/b1625ba3882b430d678d0623922d7fb56aa724b3) Thanks [@HalvorHaugan](https://github.com/HalvorHaugan)! - Oppdatert Chat
|
||||
## 5.0.1
|
||||
|
||||
- :sparkles: Ny prop `size` som kan settes til "small" for en mer kompakt layout
|
||||
- :sparkles: Ny prop `variant` som erstatter `backgroundColor` og `avatarBgColor`
|
||||
- :sparkles: `avatar` er nå valgfritt
|
||||
- :wheelchair: Forbedret UU
|
||||
- :lipstick: Oppdatert utseende
|
||||
## 5.0.0
|
||||
|
||||
## 4.1.7
|
||||
## 4.12.1
|
||||
|
||||
## 4.1.6
|
||||
## 4.12.0
|
||||
|
||||
## 4.1.5
|
||||
## 4.11.2
|
||||
|
||||
## 4.1.4
|
||||
## 4.11.1
|
||||
|
||||
## 4.1.3
|
||||
## 4.11.0
|
||||
|
||||
## 4.1.2
|
||||
## 4.10.2
|
||||
|
||||
## 4.1.1
|
||||
## 4.10.1
|
||||
|
||||
## 4.10.0
|
||||
|
||||
## 4.9.1
|
||||
|
||||
## 4.9.0
|
||||
|
||||
## 4.8.0
|
||||
|
||||
## 4.7.4
|
||||
|
||||
## 4.7.3
|
||||
|
||||
## 4.7.2
|
||||
|
||||
## 4.7.1
|
||||
|
||||
## 4.7.0
|
||||
|
||||
## 4.6.1
|
||||
|
||||
## 4.6.0
|
||||
|
||||
## 4.5.0
|
||||
|
||||
## 4.4.2
|
||||
|
||||
## 4.4.1
|
||||
|
||||
## 4.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2035](https://github.com/navikt/aksel/pull/2035) [`7b42f536a`](https://github.com/navikt/aksel/commit/7b42f536aa90c1b5dbe2b19f1bbe292701546420) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: Oppdatert Chips
|
||||
|
||||
- Toggle Chips har nå varianter: neutral og action
|
||||
- Toggle Chips har nå en ny prop: `checkmark` som slår av/på checkmark ved selected-state
|
||||
|
||||
## 4.0.0
|
||||
- Deprecated klassenavn `navds-chips--icon-left` ([PR](https://github.com/navikt/aksel/pull/2035))
|
||||
|
||||
## 3.4.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2017](https://github.com/navikt/aksel/pull/2017) [`7615dbbb5`](https://github.com/navikt/aksel/commit/7615dbbb54c7c96e2252366188547b27b2ac1142) Thanks [@JulianNymark](https://github.com/JulianNymark)! - add missing dependency
|
||||
- La til riktige dependencies ([PR](https://github.com/navikt/aksel/pull/2017))
|
||||
|
||||
## 3.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- :bug: Stylelint hotfix, inkluderer nå dist-mappe (kanskje..)
|
||||
- Inkluderer nå dist-mappe i release
|
||||
|
||||
## 3.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1973](https://github.com/navikt/aksel/pull/1973) [`61c411421`](https://github.com/navikt/aksel/commit/61c4114214841ec42f48e1abd0d72d2a42d265ab) Thanks [@JulianNymark](https://github.com/JulianNymark)! - add stylelint plugin
|
||||
- Stylelint-pakke for Aksel ([PR](https://github.com/navikt/aksel/pull/1973))
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/aksel-stylelint",
|
||||
"version": "4.2.0",
|
||||
"version": "5.0.3",
|
||||
"author": "Aksel | NAV",
|
||||
"homepage": "https://aksel.nav.no/grunnleggende/kode/stylelint",
|
||||
"repository": {
|
||||
@@ -35,8 +35,8 @@
|
||||
"dev": "yarn watch:lint"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@navikt/ds-css": "^4.2.0",
|
||||
"@navikt/ds-tokens": "^4.2.0",
|
||||
"@navikt/ds-css": "^5.0.3",
|
||||
"@navikt/ds-tokens": "^5.0.3",
|
||||
"@types/jest": "^29.0.0",
|
||||
"concurrently": "7.2.1",
|
||||
"copyfiles": "2.4.1",
|
||||
|
||||
@@ -25,4 +25,17 @@ export const deprecations: DeprecatedList = [
|
||||
message:
|
||||
"In v4.1.0 Chips. Toggle no longer handles special alignment for checkmark-icon, thus removing this class",
|
||||
},
|
||||
{
|
||||
classes: ["navds-modal__overlay"],
|
||||
message:
|
||||
"Removed in v5.0.0, use `.navds-modal::backdrop` and `.navds-modal--polyfilled + .backdrop` instead",
|
||||
},
|
||||
{
|
||||
classes: ["navds-modal__button--shake"],
|
||||
message: "Removed in v5.0.0",
|
||||
},
|
||||
{
|
||||
classes: ["navds-modal__content"],
|
||||
message: "Renamed to `.navds-modal__body` in v5.0.0",
|
||||
},
|
||||
];
|
||||
+142
-230
@@ -1,278 +1,190 @@
|
||||
# @navikt/aksel
|
||||
|
||||
## 4.2.0
|
||||
## 5.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b1625ba38`](https://github.com/navikt/aksel/commit/b1625ba3882b430d678d0623922d7fb56aa724b3)]:
|
||||
- @navikt/ds-css@4.2.0
|
||||
- Updated dependencies [[`8d934e093`](https://github.com/navikt/aksel/commit/8d934e0931caaa6f774a8f1b20fa34a19ece7218), [`8d934e093`](https://github.com/navikt/aksel/commit/8d934e0931caaa6f774a8f1b20fa34a19ece7218)]:
|
||||
- @navikt/ds-css@5.0.3
|
||||
|
||||
## 4.1.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`42b5af64a`](https://github.com/navikt/aksel/commit/42b5af64ab35d0f2d126d41f8fc3e61fe2834b36)]:
|
||||
- @navikt/ds-css@4.1.7
|
||||
|
||||
## 4.1.6
|
||||
## 5.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@4.1.6
|
||||
- @navikt/ds-css@5.0.2
|
||||
|
||||
## 4.1.5
|
||||
## 5.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`90db7dd0c`](https://github.com/navikt/aksel/commit/90db7dd0c120c16a387d3169c05c1f33dc694323)]:
|
||||
- @navikt/ds-css@5.0.1
|
||||
|
||||
## 5.0.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`2993f809a`](https://github.com/navikt/aksel/commit/2993f809adbf26fe88237066fea7f3e1a21b6690), [`2993f809a`](https://github.com/navikt/aksel/commit/2993f809adbf26fe88237066fea7f3e1a21b6690), [`3438b5d7e`](https://github.com/navikt/aksel/commit/3438b5d7e75037889946d4f89e95cd1f91bbb2d0)]:
|
||||
- @navikt/ds-css@5.0.0
|
||||
|
||||
## 4.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5cda39ce1`](https://github.com/navikt/aksel/commit/5cda39ce19fa3f25ae18a0b07dd85e97378edd26)]:
|
||||
- @navikt/ds-css@4.12.1
|
||||
|
||||
## 4.12.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1c482e03b`](https://github.com/navikt/aksel/commit/1c482e03b845c4e6f6f1e174a58992fbeeabb52e), [`107d6f3d9`](https://github.com/navikt/aksel/commit/107d6f3d935cbc9bb94bc15cea63431cd15bbd61), [`09d41e9b6`](https://github.com/navikt/aksel/commit/09d41e9b6da5486a55faaf8088191b4a8374e420), [`a402777c7`](https://github.com/navikt/aksel/commit/a402777c70a18899ef4239b10a6335a671e26167)]:
|
||||
- @navikt/ds-css@4.12.0
|
||||
|
||||
## 4.11.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`72321e384`](https://github.com/navikt/aksel/commit/72321e3846f785318ebdba9f8e06cf13b09cd524)]:
|
||||
- @navikt/ds-css@4.11.2
|
||||
|
||||
## 4.11.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e68ab5cb2`](https://github.com/navikt/aksel/commit/e68ab5cb2cd91c2f0234c864ee71821ed07a8203)]:
|
||||
- @navikt/ds-css@4.11.1
|
||||
|
||||
## 4.11.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`64901adcc`](https://github.com/navikt/aksel/commit/64901adccb8f19fbe06cdab4a70d47978e90e343), [`0de8238ec`](https://github.com/navikt/aksel/commit/0de8238ecf22e9f1fbc0e1b0cfe7a5cd7254901e), [`647b14a23`](https://github.com/navikt/aksel/commit/647b14a23888f82bacc4806d3afaacb5e39178fa)]:
|
||||
- @navikt/ds-css@4.11.0
|
||||
|
||||
## 4.10.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@4.1.5
|
||||
- @navikt/ds-css@4.10.2
|
||||
|
||||
## 4.1.4
|
||||
## 4.10.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e06096105`](https://github.com/navikt/aksel/commit/e060961050c75ec815e5c125001f1ff99106e298)]:
|
||||
- @navikt/ds-css@4.1.4
|
||||
- Updated dependencies [[`d3bd1202e`](https://github.com/navikt/aksel/commit/d3bd1202eddb23dd3f1f09c3e4086ff3b19737d6)]:
|
||||
- @navikt/ds-css@4.10.1
|
||||
|
||||
## 4.1.3
|
||||
## 4.10.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`267799ca0`](https://github.com/navikt/aksel/commit/267799ca0ecc0c549e159f94124befb654e29331)]:
|
||||
- @navikt/ds-css@4.10.0
|
||||
|
||||
## 4.9.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`eff8a902c`](https://github.com/navikt/aksel/commit/eff8a902c50fd5ebc56616e866aa0a61b9eb5efc)]:
|
||||
- @navikt/ds-css@4.9.1
|
||||
|
||||
## 4.9.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e033b34c3`](https://github.com/navikt/aksel/commit/e033b34c3b85fb98dd11dd0300bb20075e1b06e8)]:
|
||||
- @navikt/ds-css@4.9.0
|
||||
|
||||
## 4.8.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8a82e1c1f`](https://github.com/navikt/aksel/commit/8a82e1c1f66ea38fca77b25d74b14926bd817dd9)]:
|
||||
- @navikt/ds-css@4.8.0
|
||||
|
||||
## 4.7.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`492cfc180`](https://github.com/navikt/aksel/commit/492cfc1801df4ab16306185345d5089e24a0d659)]:
|
||||
- @navikt/ds-css@4.7.4
|
||||
|
||||
## 4.7.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@4.1.3
|
||||
- @navikt/ds-css@4.7.3
|
||||
|
||||
## 4.1.2
|
||||
## 4.7.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e6fdfdc9b`](https://github.com/navikt/aksel/commit/e6fdfdc9b44156b6eb8ebc0eda3a9259dce800ff)]:
|
||||
- @navikt/ds-css@4.7.2
|
||||
|
||||
## 4.7.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@4.1.2
|
||||
- @navikt/ds-css@4.7.1
|
||||
|
||||
## 4.1.1
|
||||
## 4.7.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`91343563c`](https://github.com/navikt/aksel/commit/91343563c916a554d8ade5401c28ab4c3b3e26af)]:
|
||||
- @navikt/ds-css@4.1.1
|
||||
- Updated dependencies [[`e3027cc19`](https://github.com/navikt/aksel/commit/e3027cc1966623433cfc2d28915273486c7bf611)]:
|
||||
- @navikt/ds-css@4.7.0
|
||||
|
||||
## 4.1.0
|
||||
## 4.6.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7b42f536a`](https://github.com/navikt/aksel/commit/7b42f536aa90c1b5dbe2b19f1bbe292701546420), [`c028f36e2`](https://github.com/navikt/aksel/commit/c028f36e2bc58223ebf8b655980dde7eafb30add), [`b2f796d68`](https://github.com/navikt/aksel/commit/b2f796d681f1c1d76d26d1fd743268c8c618a854), [`db8c38a09`](https://github.com/navikt/aksel/commit/db8c38a094cd183db54aebecb62d5b223920a040)]:
|
||||
- @navikt/ds-css@4.1.0
|
||||
- Updated dependencies [[`28430f134`](https://github.com/navikt/aksel/commit/28430f13455a8ecc10447e5e1ad75625d29c4bcb)]:
|
||||
- @navikt/ds-css@4.6.1
|
||||
|
||||
## 4.6.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ae70bfa71`](https://github.com/navikt/aksel/commit/ae70bfa7192db46d8dea0dfb0222a857efc46be5)]:
|
||||
- @navikt/ds-css@4.6.0
|
||||
|
||||
## 4.5.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b05958863`](https://github.com/navikt/aksel/commit/b05958863b1adadb1b6a3fcceb4477e7411b66b5), [`b05958863`](https://github.com/navikt/aksel/commit/b05958863b1adadb1b6a3fcceb4477e7411b66b5)]:
|
||||
- @navikt/ds-css@4.5.0
|
||||
|
||||
## 4.4.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@4.4.2
|
||||
|
||||
## 4.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`415632675`](https://github.com/navikt/aksel/commit/4156326752eaf7a97855b33653850362dada8788)]:
|
||||
- @navikt/ds-css@4.4.1
|
||||
|
||||
## 4.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- [#2026](https://github.com/navikt/aksel/pull/2026) [`895bdc08e`](https://github.com/navikt/aksel/commit/895bdc08e50647d9b9186cbf0e9ab069323de56c) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :test-tube: Datepicker og Monthpicker er nå ute av beta. Kjør codemod for migrering, eller `cmd/ctrl + shift + f` og erstatt `UNSAFE_` med ``
|
||||
- Codemod for migrering av Datepicker/Monthpicker ut av Beta. `npx @navikt/aksel codemod v4-date` ([PR](https://github.com/navikt/aksel/pull/2026))
|
||||
|
||||
- UNSAFE-prefix er fjernet fra Datepicker og Monthpicker
|
||||
|
||||
```bash
|
||||
npx @navikt/aksel codemod v4-date
|
||||
```
|
||||
|
||||
- [#2026](https://github.com/navikt/aksel/pull/2026) [`895bdc08e`](https://github.com/navikt/aksel/commit/895bdc08e50647d9b9186cbf0e9ab069323de56c) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :truck: Komponenter i `@navikt/ds-react-internal` er flyttet over til `@navikt/ds-react`
|
||||
|
||||
- `<Header />` er renamet til `<InternalHeader />`
|
||||
- Dropdown, Timeline og InternalHeader(Header) er flyttet over til `@navikt/ds-react`
|
||||
- All styling fra `@navikt/ds-css-internal` er flyttet til `@navikt/ds-css` og classname-prefix er endret fra `navdsi` -> `navds` for flyttede komponenter. Sett opp [stylelint med configen vår](https://aksel.nav.no/grunnleggende/kode/stylelint), så vil du få feilmelding om du bruker gamle klassenavn.
|
||||
- Fikset cascading-problem mellom dropdown og popover. Dropdown blir ikke lengre påvirket av import-rekkefølge av popover.
|
||||
- Styling for flyttede komponenter finnes nå på CDN (https://aksel.nav.no/grunnleggende/kode/css-import)
|
||||
|
||||
Kjør codemod for migrering:
|
||||
|
||||
```bash
|
||||
// React
|
||||
npx @navikt/aksel codemod v4-internal-react
|
||||
|
||||
// CSS
|
||||
npx @navikt/aksel codemod v4-internal-css
|
||||
```
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`895bdc08e`](https://github.com/navikt/aksel/commit/895bdc08e50647d9b9186cbf0e9ab069323de56c), [`895bdc08e`](https://github.com/navikt/aksel/commit/895bdc08e50647d9b9186cbf0e9ab069323de56c)]:
|
||||
- @navikt/ds-css@4.0.0
|
||||
|
||||
## 3.4.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@3.4.2
|
||||
|
||||
## 3.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@3.4.1
|
||||
|
||||
## 3.4.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b958d41a2`](https://github.com/navikt/aksel/commit/b958d41a20c66327658514fcf24ae20893c9531a)]:
|
||||
- @navikt/ds-css@3.4.0
|
||||
|
||||
## 3.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@3.3.1
|
||||
|
||||
## 3.3.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@3.3.0
|
||||
|
||||
## 3.2.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`30eee0dac`](https://github.com/navikt/aksel/commit/30eee0dac4e3e5a1379033283a6885e646e80458)]:
|
||||
- @navikt/ds-css@3.2.4
|
||||
|
||||
## 3.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`475e994f4`](https://github.com/navikt/aksel/commit/475e994f494b2080ffc05eb1684b6a244e3e2969), [`444e905e0`](https://github.com/navikt/aksel/commit/444e905e01965fd5cac40ff20c5225b072e67221)]:
|
||||
- @navikt/ds-css@3.2.3
|
||||
|
||||
## 3.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@3.2.2
|
||||
|
||||
## 3.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@3.2.1
|
||||
|
||||
## 3.2.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`affcab14c`](https://github.com/navikt/aksel/commit/affcab14c3d536929dfa64a36f5b43f9d0e8c3b7)]:
|
||||
- @navikt/ds-css@3.2.0
|
||||
|
||||
## 3.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e8ecf309a`](https://github.com/navikt/aksel/commit/e8ecf309a910e47fd3cea6c54cd993ab1196910f)]:
|
||||
- @navikt/ds-css@3.1.3
|
||||
|
||||
## 3.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@3.1.2
|
||||
|
||||
## 3.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@3.1.1
|
||||
|
||||
## 3.1.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`9d2cd9e7f`](https://github.com/navikt/aksel/commit/9d2cd9e7fffb3cf6310c88229ee39ea85db19bca), [`f1c4c46eb`](https://github.com/navikt/aksel/commit/f1c4c46ebb0522561483f18e3b86b190cf9cc372)]:
|
||||
- @navikt/ds-css@3.1.0
|
||||
|
||||
## 3.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@3.0.1
|
||||
|
||||
## 3.0.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`166ee5feb`](https://github.com/navikt/aksel/commit/166ee5feb3c987c4e633eb449812116bfd865d3f), [`166ee5feb`](https://github.com/navikt/aksel/commit/166ee5feb3c987c4e633eb449812116bfd865d3f)]:
|
||||
- @navikt/ds-css@3.0.0
|
||||
|
||||
## 2.9.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@2.9.8
|
||||
|
||||
## 2.9.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@2.9.7
|
||||
|
||||
## 2.9.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@2.9.6
|
||||
|
||||
## 2.9.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@2.9.5
|
||||
- Codemods for migrering fra `@navikt/ds-react-internal` til `@navikt/ds-react` [Guide](https://aksel.nav.no/grunnleggende/kode/migrering#h3b8538e1981d) ([PR](https://github.com/navikt/aksel/pull/2026))
|
||||
|
||||
## 2.9.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1952](https://github.com/navikt/aksel/pull/1952) [`27b2b4a11`](https://github.com/navikt/aksel/commit/27b2b4a11caf5ca05c96c686c453653d8a900e5f) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :truck: Flyttet Codemods from `@navikt/ds-codemods` -> `@navikt/aksel`.
|
||||
|
||||
- `@navikt/ds-codemods` vil bli deprecated ettehvert.
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@2.9.4
|
||||
|
||||
## 2.9.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@2.9.3
|
||||
|
||||
## 2.9.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@2.9.2
|
||||
|
||||
## 2.9.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@2.9.1
|
||||
|
||||
## 2.9.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`657b7f3f3`](https://github.com/navikt/aksel/commit/657b7f3f3e62c5ce3173e6c95a29fcd237ce7343)]:
|
||||
- @navikt/ds-css@2.9.0
|
||||
- :truck: Flyttet Codemods fra `@navikt/ds-codemods` -> `@navikt/aksel`. `@navikt/ds-codemods` regnes nå som deprecated ([PR](https://github.com/navikt/aksel/pull/1952))
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/aksel",
|
||||
"version": "4.2.0",
|
||||
"version": "5.0.3",
|
||||
"description": "Aksel command line interface. Handles css-imports, codemods and more",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"license": "MIT",
|
||||
@@ -29,7 +29,7 @@
|
||||
},
|
||||
"homepage": "https://aksel.nav.no/grunnleggende/kode/kommandolinje",
|
||||
"dependencies": {
|
||||
"@navikt/ds-css": "4.2.0",
|
||||
"@navikt/ds-css": "5.0.3",
|
||||
"axios": "1.3.6",
|
||||
"chalk": "4.1.0",
|
||||
"clipboardy": "^2.3.0",
|
||||
|
||||
+221
-331
@@ -1,512 +1,402 @@
|
||||
# @navikt/ds-css
|
||||
|
||||
## 5.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ConfirmationPanel: Fikset opplesing av feilmelding ([#2199](https://github.com/navikt/aksel/pull/2199))
|
||||
|
||||
- Checkbox: Fikset checkbox-alignment ved bruk av tailwindcss ([#2199](https://github.com/navikt/aksel/pull/2199))
|
||||
|
||||
## 5.0.2
|
||||
|
||||
## 5.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Checkbox: Hotfix da checkmark ikke var sentrert hvis man brukte tailwind ([`90db7dd0c`](https://github.com/navikt/aksel/commit/90db7dd0c120c16a387d3169c05c1f33dc694323))
|
||||
|
||||
## 5.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- Oppdatert Modal - Se [Migrering](https://aksel.nav.no/grunnleggende/kode/migrering) ([#2135](https://github.com/navikt/aksel/pull/2135))
|
||||
|
||||
- :sparkles: Støtte for header og footer
|
||||
- :boom: Bruker nå native dialog i stedet for react-modal (med polyfill for eldre nettlesere)
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Table: ExpandableRow har oppdatert knapp for å matche Accordion og ExpansionCard ([#2178](https://github.com/navikt/aksel/pull/2178))
|
||||
|
||||
- Table: Alle størrelser har justert padding. Small-size table bruker nå også standard typografi-størrelse (18px). ([#2178](https://github.com/navikt/aksel/pull/2178))
|
||||
|
||||
## 4.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Added red border to Combobox in error state ([#2184](https://github.com/navikt/aksel/pull/2184))
|
||||
|
||||
## 4.12.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- CopyButton: Har nå prop 'iconPosition' for å høyre/venstre aligne ikon ([#2173](https://github.com/navikt/aksel/pull/2173))
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- List: Fikset sentrering, margins ([#2168](https://github.com/navikt/aksel/pull/2168))
|
||||
|
||||
- Checkbox: Checkmark er nå SVG-ikon og ikke Base64 ([#2171](https://github.com/navikt/aksel/pull/2171))
|
||||
|
||||
- Alert: Fikset alignment av status-ikon mot tekst ([#2179](https://github.com/navikt/aksel/pull/2179))
|
||||
|
||||
## 4.11.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- :lipstick: ToggleGroup: fjern semibold fra selected button ([#2167](https://github.com/navikt/aksel/pull/2167))
|
||||
|
||||
## 4.11.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Border-radius: Fikset hardkodet border-radius i Datepicker, ToggleGroup og Combobox. ([#2159](https://github.com/navikt/aksel/pull/2159))
|
||||
|
||||
## 4.11.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- HGrid: Ny komponent 'HGrid' er ute i Beta: [Dokumentasjon](https://aksel.nav.no/komponenter/core/hgrid) ([#1838](https://github.com/navikt/aksel/pull/1838))
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- List: Fikset alignment av ikoner ([#2149](https://github.com/navikt/aksel/pull/2149))
|
||||
|
||||
- Font: La til egen font for semibold italic for bedre skalering cross-browser ([#2150](https://github.com/navikt/aksel/pull/2150))
|
||||
|
||||
## 4.10.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Link: Fikset visited farger og inline SVG-reset ved bruk av tailwind
|
||||
|
||||
## 4.10.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Link: La til 'variant', 'underline' og 'inlineText'-prop ([#2093](https://github.com/navikt/aksel/pull/2093))
|
||||
|
||||
## 4.9.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Tweaks to combobox - updated example, small bugfixes, better affordance for selected options and added flag for "isAddedByUser" to onToggleSelected ([#2144](https://github.com/navikt/aksel/pull/2144))
|
||||
|
||||
## 4.9.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Table: ExpandableRow kan nå åpnes med 'expandOnRowClick'-prop ([#2127](https://github.com/navikt/aksel/pull/2127))
|
||||
|
||||
## 4.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Nye komponenter `VStack`, `HStack` og `Spacer` for å enklere kunne lage layout med flexbox og spacing-variabler. ([#2040](https://github.com/navikt/aksel/pull/2040))
|
||||
|
||||
## 4.7.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Oppdatert bruk av REM i komponenter for forbedret utrykk ved font-scaling i browser ([#2126](https://github.com/navikt/aksel/pull/2126))
|
||||
|
||||
## 4.7.3
|
||||
|
||||
## 4.7.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Stepper: Fikset `hotizontal`-bug når step var `completed` ([#2116](https://github.com/navikt/aksel/pull/2116))
|
||||
|
||||
## 4.7.1
|
||||
|
||||
## 4.7.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Ny komponent Combobox! ([#1868](https://github.com/navikt/aksel/pull/1868))
|
||||
|
||||
## 4.6.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Skjema: Labels og Legends bruker nå inline-flex når readOnly er satt ([#2089](https://github.com/navikt/aksel/pull/2089))
|
||||
|
||||
## 4.6.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Skjema: De fleste skjemakomponenter har nå styling for `readOnly`-state ([#2080](https://github.com/navikt/aksel/pull/2080))
|
||||
|
||||
## 4.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- - Alert: La til `closeButton`-prop ([#2079](https://github.com/navikt/aksel/pull/2079))
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- - Button: Fikset outline-bug i tertiary-variant ved `:active`-state ([#2079](https://github.com/navikt/aksel/pull/2079))
|
||||
|
||||
## 4.4.2
|
||||
|
||||
## 4.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- :lipstick: Chat: fjernet border, satt avatar svg til 24x24px, byttet om "subtle" og "neutral" ([#2077](https://github.com/navikt/aksel/pull/2077))
|
||||
|
||||
## 4.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Shadow-tokens er oppdatert: Datepicker har nå ikke border, Modal bruker shadow-xlarge, LinkCard bruker shadow-xsmall ([PR](https://github.com/navikt/aksel/pull/2041))
|
||||
|
||||
## 4.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Popover/Helptext: Maksbredde på 100vw - 1.5rem. Treffer ikke lengre kanten på skjermen. ([PR](https://github.com/navikt/aksel/pull/2069))
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ExpansionCard: Ved nesting av komponetene fikk man styling fra parent ([PR](https://github.com/navikt/aksel/pull/2067))
|
||||
|
||||
## 4.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2048](https://github.com/navikt/aksel/pull/2048) [`b1625ba38`](https://github.com/navikt/aksel/commit/b1625ba3882b430d678d0623922d7fb56aa724b3) Thanks [@HalvorHaugan](https://github.com/HalvorHaugan)! - Oppdatert Chat
|
||||
|
||||
- :sparkles: Ny prop `size` som kan settes til "small" for en mer kompakt layout
|
||||
- :sparkles: Ny prop `variant` som erstatter `backgroundColor` og `avatarBgColor`
|
||||
- :sparkles: `avatar` er nå valgfritt
|
||||
- :wheelchair: Forbedret UU
|
||||
- :lipstick: Oppdatert utseende
|
||||
|
||||
## 4.1.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`42b5af64a`](https://github.com/navikt/aksel/commit/42b5af64ab35d0f2d126d41f8fc3e61fe2834b36) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Fikset jsdom-problemer ved rendring av Timeline
|
||||
|
||||
## 4.1.6
|
||||
|
||||
## 4.1.5
|
||||
- Chat: `small`-size, innebygde varianter for farge og oppdatert utseende. ([PR](https://github.com/navikt/aksel/pull/2048))
|
||||
|
||||
## 4.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2049](https://github.com/navikt/aksel/pull/2049) [`e06096105`](https://github.com/navikt/aksel/commit/e060961050c75ec815e5c125001f1ff99106e298) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Subtle-description på form-elementer brakk bruk av Readmore
|
||||
|
||||
## 4.1.3
|
||||
|
||||
## 4.1.2
|
||||
- Readmore: setter nå eksplisitt color for å ikke arve text-subtle fra parent. ([PR](https://github.com/navikt/aksel/pull/2049))
|
||||
|
||||
## 4.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`91343563c`](https://github.com/navikt/aksel/commit/91343563c916a554d8ade5401c28ab4c3b3e26af) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Fikset markering av tekst i skeleton.
|
||||
- :bug: Fikset cursor-markering av tekst i skeleton.
|
||||
|
||||
## 4.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2035](https://github.com/navikt/aksel/pull/2035) [`7b42f536a`](https://github.com/navikt/aksel/commit/7b42f536aa90c1b5dbe2b19f1bbe292701546420) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: Oppdatert Chips
|
||||
- Chips: `neutral` og `action`-varianter av Chips.Toggle. Opt-out mulighet for Checkmark. Oppdatert checkmark-ikon ([PR](https://github.com/navikt/aksel/pull/2035))
|
||||
|
||||
- Toggle Chips har nå varianter: neutral og action
|
||||
- Toggle Chips har nå en ny prop: `checkmark` som slår av/på checkmark ved selected-state
|
||||
|
||||
- [#2036](https://github.com/navikt/aksel/pull/2036) [`b2f796d68`](https://github.com/navikt/aksel/commit/b2f796d681f1c1d76d26d1fd743268c8c618a854) Thanks [@KenAJoh](https://github.com/KenAJoh)! - - Oppdatert text-subtle og icon-subtle tokens til 700-skala (tidligere 600).
|
||||
|
||||
- Icon-subtle bruker nå grayalpha.
|
||||
- Alle description-felter på fieldsets har nå text-subtle som farge.
|
||||
|
||||
- [#1821](https://github.com/navikt/aksel/pull/1821) [`db8c38a09`](https://github.com/navikt/aksel/commit/db8c38a094cd183db54aebecb62d5b223920a040) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: Ny komponent Skeleton!
|
||||
|
||||
- varianter: text, circle, rounded og rectangle
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2027](https://github.com/navikt/aksel/pull/2027) [`c028f36e2`](https://github.com/navikt/aksel/commit/c028f36e2bc58223ebf8b655980dde7eafb30add) Thanks [@JulianNymark](https://github.com/JulianNymark)! - :sparkles: La til `indent`-prop på Accordion
|
||||
- Alle description-felter på fieldsets har nå `text-subtle` som farge. ([PR](https://github.com/navikt/aksel/pull/2036))
|
||||
|
||||
## 4.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- [#2026](https://github.com/navikt/aksel/pull/2026) [`895bdc08e`](https://github.com/navikt/aksel/commit/895bdc08e50647d9b9186cbf0e9ab069323de56c) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :test-tube: Datepicker og Monthpicker er nå ute av beta. Kjør codemod for migrering, eller `cmd/ctrl + shift + f` og erstatt `UNSAFE_` med ``
|
||||
- All styling fra `@navikt/ds-css-internal` er flyttet til `@navikt/ds-css`. ([PR](https://github.com/navikt/aksel/pull/2026))
|
||||
|
||||
- UNSAFE-prefix er fjernet fra Datepicker og Monthpicker
|
||||
- classname-prefix er endret fra `navdsi` -> `navds` for flyttede komponenter.
|
||||
|
||||
```bash
|
||||
npx @navikt/aksel codemod v4-date
|
||||
```
|
||||
- Fikset cascading-problem mellom dropdown og popover. Dropdown blir ikke lengre påvirket av import-rekkefølge av popover.
|
||||
|
||||
- [#2026](https://github.com/navikt/aksel/pull/2026) [`895bdc08e`](https://github.com/navikt/aksel/commit/895bdc08e50647d9b9186cbf0e9ab069323de56c) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :truck: Komponenter i `@navikt/ds-react-internal` er flyttet over til `@navikt/ds-react`
|
||||
|
||||
- `<Header />` er renamet til `<InternalHeader />`
|
||||
- Dropdown, Timeline og InternalHeader(Header) er flyttet over til `@navikt/ds-react`
|
||||
- All styling fra `@navikt/ds-css-internal` er flyttet til `@navikt/ds-css` og classname-prefix er endret fra `navdsi` -> `navds` for flyttede komponenter. Sett opp [stylelint med configen vår](https://aksel.nav.no/grunnleggende/kode/stylelint), så vil du få feilmelding om du bruker gamle klassenavn.
|
||||
- Fikset cascading-problem mellom dropdown og popover. Dropdown blir ikke lengre påvirket av import-rekkefølge av popover.
|
||||
- Styling for flyttede komponenter finnes nå på CDN (https://aksel.nav.no/grunnleggende/kode/css-import)
|
||||
|
||||
Kjør codemod for migrering:
|
||||
|
||||
```bash
|
||||
// React
|
||||
npx @navikt/aksel codemod v4-internal-react
|
||||
|
||||
// CSS
|
||||
npx @navikt/aksel codemod v4-internal-css
|
||||
```
|
||||
|
||||
## 3.4.2
|
||||
|
||||
## 3.4.1
|
||||
- Styling for flyttede komponenter finnes nå på CDN [Guide](https://aksel.nav.no/grunnleggende/kode/css-import)
|
||||
|
||||
## 3.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2010](https://github.com/navikt/aksel/pull/2010) [`b958d41a2`](https://github.com/navikt/aksel/commit/b958d41a20c66327658514fcf24ae20893c9531a) Thanks [@HalvorHaugan](https://github.com/HalvorHaugan)! - Ny variant "moderate" i Tag
|
||||
|
||||
## 3.3.1
|
||||
|
||||
## 3.3.0
|
||||
|
||||
## 3.2.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2000](https://github.com/navikt/aksel/pull/2000) [`30eee0dac`](https://github.com/navikt/aksel/commit/30eee0dac4e3e5a1379033283a6885e646e80458) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Search støtter nå htmlSize-prop
|
||||
- Tag: `moderate`-variant ([PR](https://github.com/navikt/aksel/pull/2010))
|
||||
|
||||
## 3.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1993](https://github.com/navikt/aksel/pull/1993) [`475e994f4`](https://github.com/navikt/aksel/commit/475e994f494b2080ffc05eb1684b6a244e3e2969) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Fikset small-variant av datepicker-input
|
||||
- Datepicker: Fikset small-variant av datepicker-input. ([PR](https://github.com/navikt/aksel/pull/1993))
|
||||
|
||||
- :recycle: Refactored Datepicker.Input-button for bugfix
|
||||
|
||||
- [#1994](https://github.com/navikt/aksel/pull/1994) [`444e905e0`](https://github.com/navikt/aksel/commit/444e905e01965fd5cac40ff20c5225b072e67221) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: CopyButton har nå en `xsmall`-variant
|
||||
|
||||
- Kan nå lettere brukes i tabeller
|
||||
|
||||
## 3.2.2
|
||||
|
||||
## 3.2.1
|
||||
|
||||
## 3.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1982](https://github.com/navikt/aksel/pull/1982) [`affcab14c`](https://github.com/navikt/aksel/commit/affcab14c3d536929dfa64a36f5b43f9d0e8c3b7) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :sparkles: Ny komponent `<CopyButton />`!
|
||||
|
||||
- Erstatter `<CopyToClipboard />` fra `@navikt/ds-react-internal`
|
||||
- CopyToClipboard er markert som deprecated. Den vil fortsatt fungere, men noen lintere vil kunne ende opp med å klage på den.
|
||||
- CopyButton: `xsmall`-size for bruk i tabeller ([PR](https://github.com/navikt/aksel/pull/1994))
|
||||
|
||||
## 3.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1976](https://github.com/navikt/aksel/pull/1976) [`e8ecf309a`](https://github.com/navikt/aksel/commit/e8ecf309a910e47fd3cea6c54cd993ab1196910f) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :lipstick: Oppdatert utseende for ToggleGroup
|
||||
|
||||
- Medium og Small er begge 10px lavere
|
||||
- Mindre border-radius
|
||||
|
||||
## 3.1.2
|
||||
|
||||
## 3.1.1
|
||||
- :lipstick: Oppdatert utseende for ToggleGroup. `Medium` og `Small`-size er begge 10px lavere, mindre border-radius ([PR](https://github.com/navikt/aksel/pull/1976))
|
||||
|
||||
## 3.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1966](https://github.com/navikt/aksel/pull/1966) [`f1c4c46eb`](https://github.com/navikt/aksel/commit/f1c4c46ebb0522561483f18e3b86b190cf9cc372) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :lipstick: Alle komponenter bruker nå default `:focus-visible` for fokusmarkering.
|
||||
(Alle komponenter som bruker `:focus-visible` har også en fallback for `:focus`)
|
||||
- Alle komponenter bruker nå default `:focus-visible` for fokusmarkering. Medfølger også fallback for `:focus` ([PR](https://github.com/navikt/aksel/pull/1966))
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1967](https://github.com/navikt/aksel/pull/1967) [`9d2cd9e7f`](https://github.com/navikt/aksel/commit/9d2cd9e7fffb3cf6310c88229ee39ea85db19bca) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :lipstick: Oppdatert Label og Description spacing for skjemakomponenter
|
||||
|
||||
## 3.0.1
|
||||
- Oppdatert Label og Description spacing for skjemakomponenter ([PR](https://github.com/navikt/aksel/pull/1967))
|
||||
|
||||
## 3.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- [#1964](https://github.com/navikt/aksel/pull/1964) [`166ee5feb`](https://github.com/navikt/aksel/commit/166ee5feb3c987c4e633eb449812116bfd865d3f) Thanks [@KenAJoh](https://github.com/KenAJoh)! - **Accordion**
|
||||
|
||||
- Accordion oppdatet til å ha chevron left-aligned.
|
||||
- Neutral-variant lagt til
|
||||
- Diverse nye size-options for heading og paddinger.
|
||||
- Deler av Accordion-CSS er refaktorert. Dette vil kunne brekke overskrevne stiler.
|
||||
|
||||
- [#1964](https://github.com/navikt/aksel/pull/1964) [`166ee5feb`](https://github.com/navikt/aksel/commit/166ee5feb3c987c4e633eb449812116bfd865d3f) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Aksels løsninger bruker nå `@navikt/aksel-icons`
|
||||
|
||||
**Sideeffects av ikonendringer**
|
||||
|
||||
- Komponenter som tidligere brukte Expand-ikon har fått oppdatert animasjon (table, readmore og accordion)
|
||||
- Alert bruker samme ikonstørrelse for alle størrelser
|
||||
- Chips har justert padding/ikonstørrelser
|
||||
- Datepicker hover-bug på knapper er fikset
|
||||
- Helptekst bruker nå et custom-ikon.
|
||||
- Select har fått justert padding rundt ikon
|
||||
- Switch bruker samme checkmark som checkbox, er nå avrundet
|
||||
- ReadMore har justert margin for alignment med ikon, fjernet content-animasjon
|
||||
- Tabs bruker default text-default nå
|
||||
- Stepper har endret hvordan den styler checkmark-ikon.
|
||||
|
||||
## 2.9.8
|
||||
|
||||
## 2.9.7
|
||||
|
||||
## 2.9.6
|
||||
|
||||
## 2.9.5
|
||||
|
||||
## 2.9.4
|
||||
|
||||
## 2.9.3
|
||||
|
||||
## 2.9.2
|
||||
|
||||
## 2.9.1
|
||||
- Accordion: Chevron er left-aligned, deler av styling er refaktorert, `size`-props og `neutral`-variant ([PR](https://github.com/navikt/aksel/pull/1964))
|
||||
|
||||
## 2.9.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1941](https://github.com/navikt/aksel/pull/1941) [`657b7f3f3`](https://github.com/navikt/aksel/commit/657b7f3f3e62c5ce3173e6c95a29fcd237ce7343) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: CSS nå tilgjengelig som separate filer
|
||||
|
||||
- Kan lastest fra CDN
|
||||
- Tilbys nå i minified-versjoner
|
||||
- Kommandoline: `npx @navikt/aksel css-imports` for å raskt komme i gang med CSS-optimalisering
|
||||
|
||||
## 2.8.16
|
||||
|
||||
## 2.8.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1930](https://github.com/navikt/aksel/pull/1930) [`6682be1c8`](https://github.com/navikt/aksel/commit/6682be1c8e6562213c64e5be4bed70fef54ab865) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Alle pakker implementerer nå npm provenance (beta)
|
||||
|
||||
## 2.8.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`f0d9a8853`](https://github.com/navikt/aksel/commit/f0d9a8853f56854a4049bd3f6cc34968e9d6c380) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Fixes shown month on open in Datepicker/MonthPicker, better handling of out-of-range 'today'
|
||||
|
||||
## 2.8.13
|
||||
|
||||
## 2.8.12
|
||||
|
||||
## 2.8.11
|
||||
|
||||
## 2.8.10
|
||||
- CSS nå tilgjengelig som separate filer: Kan lastest fra CDN, minified-versjoner tilgjengelig ([PR](https://github.com/navikt/aksel/pull/1941))
|
||||
|
||||
## 2.8.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1905](https://github.com/navikt/aksel/pull/1905) [`212194964`](https://github.com/navikt/aksel/commit/212194964c4dd576e1ffc031316dff8cbe5016a2) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :sparkles: Padding/border-radius tokens for button.css
|
||||
|
||||
## 2.8.8
|
||||
- Button: Padding/border-radius tokens ([PR](https://github.com/navikt/aksel/pull/1905))
|
||||
|
||||
## 2.8.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`7f3f025db`](https://github.com/navikt/aksel/commit/7f3f025db2ad605df4240605a733d10d08db753a) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Fikset typografi for radio, checkbox. Button token for tertiary
|
||||
- Button: token for tertiary
|
||||
|
||||
## 2.8.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`2eb358ad8`](https://github.com/navikt/aksel/commit/2eb358ad888979d21c385b3900973946f3f466be) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Alert, Chips og ErrorSummary har nå bedre utvalg av tokens
|
||||
- Alert, Chips og ErrorSummary har nå bedre utvalg av tokens
|
||||
|
||||
## 2.8.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`f66437082`](https://github.com/navikt/aksel/commit/f664370826ed51bda7ad681e1f1799c26d2c1f0a) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :art: Accordion-tokens for header bakgrunn
|
||||
- Accordion: tokens for header-bakgrunn
|
||||
|
||||
- [#1879](https://github.com/navikt/aksel/pull/1879) [`55b585618`](https://github.com/navikt/aksel/commit/55b585618341a4d8bf26ed9b9e129d897b1600dc) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Fikset tekstfarge i select på iphone
|
||||
|
||||
## 2.8.4
|
||||
|
||||
## 2.8.3
|
||||
- Select: Fikset tekstfarge på iphone ([PR](https://github.com/navikt/aksel/pull/1879))
|
||||
|
||||
## 2.8.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1870](https://github.com/navikt/aksel/pull/1870) [`9c495cf50`](https://github.com/navikt/aksel/commit/9c495cf5037a7453e51e273ab93e4232576f4958) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Oppdatert typografi for ExpansioCard
|
||||
|
||||
## 2.8.1
|
||||
|
||||
## 2.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1820](https://github.com/navikt/aksel/pull/1820) [`c6d51a019`](https://github.com/navikt/aksel/commit/c6d51a01902e4fd7916a422e17ed175f39acd458) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: Ny komponent! ExpansionCard. Oppfølger fra gammel Ekspanderbartpanel.
|
||||
- ExpansioCard: Oppdatert typografi ([PR](https://github.com/navikt/aksel/pull/1870))
|
||||
|
||||
## 2.7.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1863](https://github.com/navikt/aksel/pull/1863) [`7ace69f21`](https://github.com/navikt/aksel/commit/7ace69f215760bbb5bf997670c897403d8ee558d) Thanks [@it-vegard](https://github.com/it-vegard)! - Added focus indicator for tabpanel
|
||||
|
||||
## 2.7.7
|
||||
|
||||
## 2.7.6
|
||||
- Tabs: La til focus-markering for Tabs.Panel ([PR](https://github.com/navikt/aksel/pull/1863))
|
||||
|
||||
## 2.7.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- :bug: Fikset token-bug i togglegroup
|
||||
|
||||
## 2.7.4
|
||||
|
||||
## 2.7.3
|
||||
|
||||
## 2.7.2
|
||||
|
||||
## 2.7.1
|
||||
|
||||
## 2.7.0
|
||||
|
||||
## 2.6.2
|
||||
|
||||
## 2.6.1
|
||||
|
||||
## 2.6.0
|
||||
|
||||
## 2.5.1
|
||||
|
||||
## 2.5.0
|
||||
- ToggleGroup: Fikset token-bug
|
||||
|
||||
## 2.4.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`f962bc781`](https://github.com/navikt/aksel/commit/f962bc7816027c24e334d9754c3e07cda951cf56) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Fikset disabled-opacity bug i select for Chrome
|
||||
- Select: Fikset disabled + opacity bug for Chrome
|
||||
|
||||
## 2.4.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1823](https://github.com/navikt/aksel/pull/1823) [`a7ce61f84`](https://github.com/navikt/aksel/commit/a7ce61f840e5bfaafc4f70e550167fe0095555b8) Thanks [@kschieren](https://github.com/kschieren)! - added support for nested lists
|
||||
|
||||
## 2.4.1
|
||||
|
||||
## 2.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1807](https://github.com/navikt/aksel/pull/1807) [`70eeb24b3`](https://github.com/navikt/aksel/commit/70eeb24b38ac871c7f2e31e1621b949669c401b6) Thanks [@kschieren](https://github.com/kschieren)! - Added List component
|
||||
- List: La til støtte for nesting ([PR](https://github.com/navikt/aksel/pull/1823))
|
||||
|
||||
## 2.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`241b2e678`](https://github.com/navikt/aksel/commit/241b2e678f1f40909e2d36fe095dcbce8673f174) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Fikset feil bruk av fallback-tokens i textarea, timeline
|
||||
- Fikset feil bruk av fallback-tokens i Textarea og Timeline
|
||||
|
||||
## 2.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1813](https://github.com/navikt/aksel/pull/1813) [`7702c6527`](https://github.com/navikt/aksel/commit/7702c65275a4d86a8260852d091e6dd4cfe9217c) Thanks [@ingfo](https://github.com/ingfo)! - Fiksa sentrering av tekst i Select i Firefox
|
||||
- Select: Fikset sentrering av tekst i Firefox ([PR](https://github.com/navikt/aksel/pull/1813))
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`51b62cca7`](https://github.com/navikt/aksel/commit/51b62cca7b857e92669cd0b09e620b131faf80e5) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Select small 34px høyde -> 32px
|
||||
- Select: `small`-variant er nå 32px (var 34px)
|
||||
|
||||
## 2.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1789](https://github.com/navikt/aksel/pull/1789) [`c0929a534`](https://github.com/navikt/aksel/commit/c0929a534dc8effece5435f8be550cb7931a52b1) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Button og ToggleGroup har nå en neutral-variant, oppdatert neutral-tokens
|
||||
- ToggleGroup: `Neutral`-variant. ([PR](https://github.com/navikt/aksel/pull/1789))
|
||||
|
||||
## 2.1.7
|
||||
|
||||
## 2.1.6
|
||||
|
||||
## 2.1.5
|
||||
|
||||
## 2.1.4
|
||||
|
||||
## 2.1.3
|
||||
- Button: `Neutral`-variant.
|
||||
|
||||
## 2.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`62f36da5e`](https://github.com/navikt/aksel/commit/62f36da5e74fc7f53414d42b310c3b57597795bc) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Small textfield har nå 8px horisontal padding (4px før)
|
||||
|
||||
## 2.1.1
|
||||
|
||||
## 2.1.0
|
||||
|
||||
## 2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
## 2.0.16
|
||||
|
||||
## 2.0.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1748](https://github.com/navikt/aksel/pull/1748) [`22dfd8e60`](https://github.com/navikt/aksel/commit/22dfd8e60315c421749394d35e41f412a00a7593) Thanks [@KenAJoh](https://github.com/KenAJoh)! - toptextPosition prop i Chat for horisontal plassering av navn og dato.
|
||||
|
||||
## 2.0.14
|
||||
|
||||
## 2.0.13
|
||||
- TextField: `small`-variant har nå 8px horisontal padding (før 4px)
|
||||
|
||||
## 2.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1737](https://github.com/navikt/aksel/pull/1737) [`8a1ef5e7e`](https://github.com/navikt/aksel/commit/8a1ef5e7e2c066cb80c13e14329e1585e2c427f8) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Fikset default visuell error-state for radio
|
||||
|
||||
## 2.0.11
|
||||
|
||||
## 2.0.10
|
||||
|
||||
## 2.0.9
|
||||
|
||||
## 2.0.8
|
||||
|
||||
## 2.0.7
|
||||
|
||||
## 2.0.6
|
||||
- Radio: Fikset default visuell error-state ([PR](https://github.com/navikt/aksel/pull/1737))
|
||||
|
||||
## 2.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Reverserte border-width endrind i button
|
||||
|
||||
## 2.0.4
|
||||
|
||||
## 2.0.3
|
||||
|
||||
## 2.0.2
|
||||
- Button: Reverserte border-width endrinder (var 1.5px, nå 2px)
|
||||
|
||||
## 2.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`e8007328d`](https://github.com/navikt/aksel/commit/e8007328db3f6d5be696cf24f03304c79be0f3f7) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Bugfixer ved bruk av tokens
|
||||
- Bugfixer ved bruk av tokens oppdatert i v2.0.0
|
||||
|
||||
## 2.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- [`6b96e4833`](https://github.com/navikt/aksel/commit/6b96e48330c2e013a1acee85cefccd9ccc1aece4) Thanks [@KenAJoh](https://github.com/KenAJoh)! - v2: Tokens update and font-loading
|
||||
- Fontlasting: Fonter lastes nå fra NAV-CDN
|
||||
|
||||
## 1.5.10
|
||||
- Tokens: Alle komponenter bruker nå semantiske tokens for som standard, med innebygd støtte for komponent-spesifikke tokens.
|
||||
|
||||
## 1.5.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 4px -> 2px gap chips-toggle active
|
||||
|
||||
## 1.5.8
|
||||
|
||||
## 1.5.7
|
||||
|
||||
## 1.5.6
|
||||
|
||||
## 1.5.5
|
||||
|
||||
## 1.5.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1709](https://github.com/navikt/aksel/pull/1709) [`77302a30b`](https://github.com/navikt/aksel/commit/77302a30b8eef8dc00b2d2e9c904a3f57da81a11) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Oppdatert ikoner
|
||||
- Chips: 4px -> 2px gap mellom checkmark i Chips.Toggle
|
||||
|
||||
## 1.5.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Byttet om på alt-farge rekkefølge
|
||||
|
||||
## 1.5.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- :memo: Rename FilterChips to ToggleChips
|
||||
- Tokens: Byttet om på rekkefølge av alt-farger
|
||||
|
||||
## 1.5.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Flex-wrap chips.css
|
||||
- Chips. Bruker nå standard flex-wrap
|
||||
|
||||
## 1.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1684](https://github.com/navikt/aksel/pull/1684) [`e19bf67b3`](https://github.com/navikt/aksel/commit/e19bf67b337dea39989c68b5e9c2591cf0d5b40f) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :sparkles: Oppdaterte tag-varianter
|
||||
|
||||
- [#1668](https://github.com/navikt/aksel/pull/1668) [`97c5f60e9`](https://github.com/navikt/aksel/commit/97c5f60e9111da7e08f55c8d0aa29581f0a9b1ca) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Chips komponent :sparkles:
|
||||
|
||||
## 1.4.4
|
||||
|
||||
## 1.4.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- :sparkles: Validering og inputFormat i Date-komponenter
|
||||
|
||||
## 1.4.2
|
||||
|
||||
## 1.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`3c08651df`](https://github.com/navikt/aksel/commit/3c08651df28c3e19dd8c8a7a1d0032200bec473d) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Date-komponenter følger språkrådets dato-formatering for måneder.
|
||||
|
||||
## 1.4.0
|
||||
- Tag: `filled`-varianter ([PR](https://github.com/navikt/aksel/pull/1684))
|
||||
|
||||
## 1.3.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`40f0b3340`](https://github.com/navikt/aksel/commit/40f0b3340d01bf85fecc04f2f3a8e8b2acf996f1) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Bump for latest-tag
|
||||
- Fikset bruk av `:watch` for diverse parsere (less, parcel)
|
||||
|
||||
## 1.3.38
|
||||
## 1.3.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Tokens tilgjengeligjøres nå også på `:host`. Dette lar shadow-dom brukere konsumere tokens direkte.
|
||||
@@ -24,9 +24,17 @@
|
||||
font-size: 1.5rem;
|
||||
align-self: flex-start;
|
||||
height: var(--a-font-line-height-xlarge);
|
||||
margin-inline: var(--a-spacing-1);
|
||||
margin-block: 0;
|
||||
margin-block-start: -1px;
|
||||
background: radial-gradient(circle, var(--a-surface-default) 50%, 0, transparent);
|
||||
}
|
||||
|
||||
.navds-alert--close-button > .navds-alert__icon,
|
||||
.navds-alert--small > .navds-alert__icon {
|
||||
margin-block-start: 0;
|
||||
}
|
||||
|
||||
.navds-alert--small > .navds-alert__icon {
|
||||
height: var(--a-font-line-height-large);
|
||||
}
|
||||
@@ -73,3 +81,11 @@
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.navds-alert__button-wrapper {
|
||||
align-self: flex-start;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
@@ -5,6 +5,13 @@
|
||||
font-display: swap;
|
||||
src: url("https://cdn.nav.no/aksel/fonts/SourceSans3-italic.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url("https://cdn.nav.no/aksel/fonts/SourceSans3-italic-latin-semibold") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
|
||||
@@ -294,7 +294,6 @@
|
||||
.navds-button--tertiary:active {
|
||||
color: var(--ac-button-tertiary-active-text, var(--a-text-on-action));
|
||||
background-color: var(--ac-button-tertiary-active-bg, var(--a-surface-action-active));
|
||||
box-shadow: inset 0 0 0 1px var(--a-surface-default);
|
||||
}
|
||||
|
||||
.navds-button--tertiary:active:hover {
|
||||
@@ -346,7 +345,6 @@
|
||||
.navds-button--tertiary-neutral:active {
|
||||
color: var(--ac-button-tertiary-neutral-active-text, var(--a-text-on-neutral));
|
||||
background-color: var(--ac-button-tertiary-neutral-active-bg, var(--a-surface-neutral-active));
|
||||
box-shadow: inset 0 0 0 1px var(--a-surface-default);
|
||||
}
|
||||
|
||||
.navds-button--tertiary-neutral:active:hover {
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
align-items: center;
|
||||
box-shadow: var(--a-shadow-xsmall);
|
||||
background-color: var(--ac-chat-avatar-bg, var(--a-surface-neutral-subtle));
|
||||
border: 1px solid var(--ac-chat-border-color, var(--a-border-subtle));
|
||||
border-radius: var(--a-border-radius-full);
|
||||
color: var(--ac-chat-avatar-color, var(--a-text-default));
|
||||
display: flex;
|
||||
@@ -35,14 +34,16 @@
|
||||
overflow: hidden;
|
||||
height: 2.5rem;
|
||||
width: 2.5rem;
|
||||
line-height: 2.5rem; /* Makes text properly vertically centered in Chrome */
|
||||
font-size: 1.06rem;
|
||||
letter-spacing: 0.024rem;
|
||||
}
|
||||
|
||||
.navds-chat__avatar svg {
|
||||
align-self: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
max-width: 1.5rem;
|
||||
max-height: 1.5rem;
|
||||
}
|
||||
|
||||
.navds-chat__bubble {
|
||||
@@ -50,7 +51,6 @@
|
||||
box-shadow: var(--a-shadow-xsmall);
|
||||
width: fit-content;
|
||||
background-color: var(--ac-chat-bubble-bg, var(--a-surface-neutral-subtle));
|
||||
border: 1px solid var(--ac-chat-border-color, var(--a-border-subtle));
|
||||
border-radius: var(--a-border-radius-xlarge);
|
||||
border-bottom-left-radius: 2px;
|
||||
display: flex;
|
||||
@@ -72,8 +72,8 @@
|
||||
background-color: var(--a-surface-info-subtle);
|
||||
}
|
||||
|
||||
.navds-chat--neutral .navds-chat__bubble,
|
||||
.navds-chat--neutral .navds-chat__avatar {
|
||||
.navds-chat--subtle .navds-chat__bubble,
|
||||
.navds-chat--subtle .navds-chat__avatar {
|
||||
background-color: var(--a-surface-default);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
padding: 0 var(--a-spacing-3);
|
||||
text-decoration: none;
|
||||
border-radius: var(--a-border-radius-full);
|
||||
min-height: 32px;
|
||||
min-height: 2rem;
|
||||
}
|
||||
|
||||
.navds-chips--small .navds-chips__chip {
|
||||
min-height: 24px;
|
||||
min-height: 1.5rem;
|
||||
padding: 0 var(--a-spacing-2);
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,11 @@ const StyleMappings = {
|
||||
{ component: "Checkbox", main: formCss, dependencies: [typoCss] },
|
||||
{ component: "CheckboxGroup", main: formCss, dependencies: [typoCss] },
|
||||
{ component: "Chips", main: "chips.css", dependencies: [typoCss] },
|
||||
{
|
||||
component: "UNSAFE_Combobox",
|
||||
main: "combobox.css",
|
||||
dependencies: [typoCss, "chips.css"],
|
||||
},
|
||||
{
|
||||
component: "ConfirmationPanel",
|
||||
main: formCss,
|
||||
@@ -94,6 +99,10 @@ const StyleMappings = {
|
||||
main: "help-text.css",
|
||||
dependencies: ["popover.css"],
|
||||
},
|
||||
{
|
||||
component: "HGrid",
|
||||
main: "hgrid.css",
|
||||
},
|
||||
{ component: "Ingress", main: typoCss },
|
||||
{
|
||||
component: "InternalHeader",
|
||||
@@ -112,7 +121,7 @@ const StyleMappings = {
|
||||
{
|
||||
component: "Modal",
|
||||
main: "modal.css",
|
||||
dependencies: ["button.css"],
|
||||
dependencies: [typoCss, "button.css"],
|
||||
},
|
||||
{
|
||||
component: "Pagination",
|
||||
@@ -129,6 +138,18 @@ const StyleMappings = {
|
||||
{ component: "Select", main: formCss, dependencies: [typoCss] },
|
||||
{ component: "Skeleton", main: "skeleton.css", dependencies: [] },
|
||||
{ component: "Stepper", main: "stepper.css", dependencies: [typoCss] },
|
||||
{
|
||||
component: "HStack",
|
||||
main: "stack.css",
|
||||
},
|
||||
{
|
||||
component: "VStack",
|
||||
main: "stack.css",
|
||||
},
|
||||
{
|
||||
component: "Spacer",
|
||||
main: "stack.css",
|
||||
},
|
||||
{ component: "Switch", main: formCss, dependencies: [typoCss] },
|
||||
{ component: "Table", main: "table.css", dependencies: [typoCss] },
|
||||
{ component: "Tabs", main: "tabs.css", dependencies: [typoCss] },
|
||||
|
||||
@@ -52,7 +52,14 @@
|
||||
.navds-copybutton__icon {
|
||||
font-size: 1.5rem;
|
||||
display: flex;
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
||||
.navds-copybutton__icon:first-of-type {
|
||||
margin-left: -0.25rem;
|
||||
}
|
||||
|
||||
.navds-copybutton__icon:last-of-type {
|
||||
margin-right: -0.25rem;
|
||||
}
|
||||
|
||||
.navds-copybutton__icon:only-child {
|
||||
@@ -60,7 +67,7 @@
|
||||
}
|
||||
|
||||
:where(.navds-copybutton--small, .navds-copybutton--xsmall):where(:not(:only-child)) {
|
||||
margin: -2px;
|
||||
margin: -0.125rem;
|
||||
}
|
||||
|
||||
.navds-copybutton:focus-visible {
|
||||
|
||||
@@ -223,7 +223,7 @@
|
||||
|
||||
.navds-date__field-button {
|
||||
position: absolute;
|
||||
right: 1px;
|
||||
right: 0.0625rem;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: var(--ac-date-input-button-text, var(--a-text-default));
|
||||
@@ -233,12 +233,12 @@
|
||||
text-decoration: none;
|
||||
border: none;
|
||||
background: none;
|
||||
border-radius: 3px;
|
||||
border-radius: calc(var(--a-border-radius-medium) - 1px);
|
||||
padding: var(--a-spacing-3);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.5rem;
|
||||
height: calc(100% - 2px);
|
||||
height: calc(100% - 0.125rem);
|
||||
border-start-start-radius: 0;
|
||||
border-end-start-radius: 0;
|
||||
}
|
||||
@@ -278,3 +278,12 @@
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.navds-date__popover:where(.navds-popover) {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* Readonly */
|
||||
.navds-date__field--readonly .navds-date__field-button {
|
||||
cursor: default;
|
||||
}
|
||||
@@ -66,7 +66,7 @@
|
||||
*************************/
|
||||
|
||||
.navds-expansioncard__title--small {
|
||||
margin-top: 10px;
|
||||
margin-top: 0.625rem;
|
||||
}
|
||||
|
||||
.navds-expansioncard__title--medium {
|
||||
@@ -77,7 +77,7 @@
|
||||
margin-top: var(--a-spacing-1);
|
||||
}
|
||||
|
||||
.navds-expansioncard--small :where(.navds-expansioncard__title--small) {
|
||||
.navds-expansioncard--small > :where(.navds-expansioncard__header) :where(.navds-expansioncard__title--small) {
|
||||
margin-top: var(--a-spacing-05);
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
transition: transform 150ms ease-in-out;
|
||||
}
|
||||
|
||||
.navds-expansioncard--open :where(.navds-expansioncard__header-chevron) {
|
||||
.navds-expansioncard--open > :where(.navds-expansioncard__header) :where(.navds-expansioncard__header-chevron) {
|
||||
transform: translateY(0) rotate(180deg);
|
||||
}
|
||||
|
||||
@@ -135,7 +135,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.navds-expansioncard--open :where(.navds-expansioncard__header-button):hover :where(.navds-expansioncard__header-chevron) {
|
||||
.navds-expansioncard--open
|
||||
> :where(.navds-expansioncard__header)
|
||||
> :where(.navds-expansioncard__header-button):hover
|
||||
:where(.navds-expansioncard__header-chevron) {
|
||||
transform: translateY(-1px) rotate(180deg);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,320 @@
|
||||
.navds-combobox__wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.navds-combobox__wrapper-inner {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
padding: calc(var(--a-spacing-2) - 2px) var(--a-spacing-2);
|
||||
}
|
||||
|
||||
.navds-combobox__wrapper-inner > :first-child {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.navds-combobox__wrapper-inner > :last-child {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
}
|
||||
|
||||
.navds-form-field--small .navds-combobox__wrapper-inner {
|
||||
padding: var(--a-spacing-1) calc(var(--a-spacing-3) / 2);
|
||||
}
|
||||
|
||||
.navds-combobox__wrapper-inner:hover {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.navds-combobox--error .navds-text-field__input:not(:hover):not(:disabled) {
|
||||
border-color: var(--ac-combobox-error-border, var(--a-border-danger));
|
||||
box-shadow: 0 0 0 1px var(--ac-combobox-error-border, var(--a-border-danger));
|
||||
}
|
||||
|
||||
.navds-combobox--error
|
||||
.navds-text-field__input:not(:hover):not(:disabled):not(.navds-combobox__wrapper-inner--virtually-unfocused):focus-within {
|
||||
box-shadow: 0 0 0 1px var(--ac-combobox-error-border, var(--a-border-danger)), var(--a-shadow-focus);
|
||||
}
|
||||
|
||||
.navds-combobox__selected-options {
|
||||
gap: var(--a-spacing-2);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.navds-combobox__selected-options > li {
|
||||
margin: auto 0;
|
||||
border-radius: var(--a-border-radius-full);
|
||||
}
|
||||
|
||||
.navds-combobox__selected-options > li:last-of-type {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.navds-combobox__selected-options--no-bg {
|
||||
font-family: inherit;
|
||||
font-size: var(--a-font-size-large);
|
||||
font-weight: var(--a-font-weight-regular);
|
||||
letter-spacing: 0;
|
||||
line-height: var(--a-font-line-height-large);
|
||||
margin: 0;
|
||||
padding-left: 0.25rem;
|
||||
}
|
||||
|
||||
.navds-combobox__input-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.navds-combobox__input {
|
||||
z-index: 1;
|
||||
flex: 1;
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
min-width: 10ch;
|
||||
width: 100%;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.navds-combobox__input:focus-visible {
|
||||
outline: none;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.navds-combobox__wrapper-inner:has(.navds-combobox__input:focus-visible) {
|
||||
box-shadow: 0 0 0 1px var(--a-surface-default) inset, var(--a-shadow-focus);
|
||||
box-shadow: var(--a-shadow-focus);
|
||||
}
|
||||
|
||||
.navds-combobox__wrapper-inner:has(.navds-combobox__input:focus-visible).navds-combobox__wrapper-inner--virtually-unfocused {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
@supports not selector(:focus-visible) {
|
||||
.navds-combobox__input:focus {
|
||||
outline: none;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.navds-combobox__wrapper-inner:has(.navds-combobox__input:focus) {
|
||||
box-shadow: 0 0 0 1px var(--a-surface-default) inset, var(--a-shadow-focus);
|
||||
box-shadow: var(--a-shadow-focus);
|
||||
}
|
||||
|
||||
.navds-combobox__wrapper-inner:has(.navds-combobox__input:focus).navds-combobox__wrapper-inner--virtually-unfocused {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
@supports not selector(:has) {
|
||||
.navds-combobox--focused .navds-combobox__wrapper-inner {
|
||||
box-shadow: 0 0 0 1px var(--a-surface-default) inset, var(--a-shadow-focus);
|
||||
box-shadow: var(--a-shadow-focus);
|
||||
}
|
||||
|
||||
.navds-combobox--focused .navds-combobox__wrapper-inner.navds-combobox__wrapper-inner--virtually-unfocused {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.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__button-clear svg {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
|
||||
.navds-combobox__input::-webkit-search-cancel-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navds-combobox__button-toggle-list {
|
||||
border-radius: var(--a-border-radius-medium);
|
||||
color: var(--a-text-default);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 1rem;
|
||||
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));
|
||||
}
|
||||
|
||||
.navds-combobox__button-clear:hover,
|
||||
.navds-combobox__button-toggle-list:hover {
|
||||
color: var(--ac-combobox-clear-icon-hover, var(--a-text-action-selected));
|
||||
}
|
||||
|
||||
.navds-combobox__button-toggle-list:focus-visible {
|
||||
box-shadow: 0 0 0 1px var(--a-surface-default) inset, var(--a-shadow-focus);
|
||||
box-shadow: var(--a-shadow-focus);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@supports not selector(:focus-visible) {
|
||||
.navds-combobox__button-toggle-list:focus {
|
||||
box-shadow: 0 0 0 1px var(--a-surface-default) inset, var(--a-shadow-focus);
|
||||
box-shadow: var(--a-shadow-focus);
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.navds-combobox__button-toggle-list svg {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.navds-form-field--small .navds-combobox__button-toggle-list svg,
|
||||
.navds-form-field--small .navds-combobox__button-clear svg {
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
}
|
||||
|
||||
/* dropdown list */
|
||||
|
||||
.navds-combobox__list {
|
||||
max-height: 290px;
|
||||
overflow-y: auto;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 9999;
|
||||
top: calc(100% + var(--a-spacing-2));
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
border: 1px solid var(--ac-combobox-list-border-color, var(--a-border-divider));
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
padding: 0;
|
||||
box-shadow: var(--a-shadow-small);
|
||||
border-radius: var(--a-border-radius-medium);
|
||||
gap: var(--a-spacing-1) 0;
|
||||
background-color: var(--ac-combobox-list-bg, var(--a-surface-default));
|
||||
color: var(--ac-combobox-list-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-combobox__list--closed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navds-combobox__list svg {
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
}
|
||||
|
||||
.navds-combobox__list-item,
|
||||
.navds-combobox__list-item__no-options,
|
||||
.navds-combobox__list-item__new-option {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: var(--a-spacing-3);
|
||||
width: 100%;
|
||||
background-color: var(--ac-combobox-list-item-bg, var(--a-surface-default));
|
||||
}
|
||||
|
||||
.navds-form-field--small .navds-combobox__list-item,
|
||||
.navds-form-field--small .navds-combobox__list-item__no-options,
|
||||
.navds-form-field--small .navds-combobox__list-item__new-option {
|
||||
padding: calc(var(--a-spacing-3) / 2) var(--a-spacing-2);
|
||||
}
|
||||
|
||||
.navds-combobox__list-item--loading {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: var(--a-spacing-3);
|
||||
background-color: var(--ac-combobox-list-item-loading-bg, var(--a-surface-default));
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.navds-combobox__list-item--focus,
|
||||
.navds-combobox__list-item:hover {
|
||||
background-color: var(--ac-combobox-list-item-hover-bg, var(--a-surface-hover));
|
||||
cursor: pointer;
|
||||
border-left: 4px solid var(--ac-combobox-list-item-hover-border-left, var(--a-border-strong));
|
||||
padding-left: calc(var(--a-spacing-3) - 4px);
|
||||
}
|
||||
|
||||
.navds-form-field--small .navds-combobox__list-item--focus,
|
||||
.navds-form-field--small .navds-combobox__list-item:hover {
|
||||
padding-left: calc(var(--a-spacing-2) - 4px);
|
||||
}
|
||||
|
||||
.navds-combobox__list-item--selected {
|
||||
background-color: var(--ac-combobox-list-item-selected-bg, var(--a-surface-selected));
|
||||
}
|
||||
|
||||
.navds-combobox__list-item--selected p {
|
||||
font-weight: var(--a-font-weight-bold);
|
||||
}
|
||||
|
||||
.navds-combobox__list-item--selected.navds-combobox__list-item--focus,
|
||||
.navds-combobox__list-item--selected:hover {
|
||||
background-color: var(--ac-combobox-list-item-selected-hover-bg, var(--a-surface-action-subtle-hover));
|
||||
border-left: 4px solid var(--ac-combobox-list-item-selected-hover-border-left, var(--a-border-focus));
|
||||
padding-left: calc(var(--a-spacing-3) - 4px);
|
||||
}
|
||||
|
||||
.navds-combobox__list-item__new-option {
|
||||
border-bottom: 1px solid var(--a-border-divider);
|
||||
background: var(--a-surface-neutral-subtle);
|
||||
cursor: pointer;
|
||||
justify-content: flex-start;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.navds-combobox__list-item__new-option:hover {
|
||||
border-bottom: 1px solid var(--a-border-divider);
|
||||
background: var(--a-surface-neutral-subtle-hover);
|
||||
}
|
||||
|
||||
.navds-combobox__list-item__new-option--focus {
|
||||
box-shadow: var(--a-shadow-focus) inset, var(--a-border-action) 0 0 0 5px inset;
|
||||
border-radius: calc(var(--a-border-radius-medium) - 1px);
|
||||
}
|
||||
|
||||
/* Mobile */
|
||||
|
||||
@media (max-width: 479px) {
|
||||
.navds-combobox__button-toggle-list {
|
||||
right: 0.5rem;
|
||||
}
|
||||
|
||||
/* add bigger click area for input */
|
||||
.navds-combobox__input {
|
||||
min-width: min-content;
|
||||
padding: 0.75rem 0;
|
||||
}
|
||||
|
||||
.navds-combobox__selected-options {
|
||||
gap: var(--a-spacing-1);
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,10 @@
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.navds-fieldset--readonly > :where(.navds-fieldset__legend) {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.navds-fieldset:disabled > .navds-fieldset__legend,
|
||||
.navds-fieldset:disabled > .navds-fieldset__description {
|
||||
opacity: 0.3;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
}
|
||||
|
||||
.navds-form-field__description {
|
||||
margin-top: -6px;
|
||||
margin-top: -0.375rem;
|
||||
color: var(--ac-form-description, var(--a-text-subtle));
|
||||
}
|
||||
|
||||
@@ -36,3 +36,14 @@
|
||||
.navds-form-field__subdescription {
|
||||
color: var(--ac-form-subdescription, var(--a-text-subtle));
|
||||
}
|
||||
|
||||
.navds-form-field--readonly > :where(.navds-form-field__label) {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.navds-form-field__readonly-icon {
|
||||
margin-top: var(--a-spacing-05);
|
||||
margin-right: var(--a-spacing-2);
|
||||
flex-shrink: 0;
|
||||
align-self: flex-start;
|
||||
}
|
||||
@@ -11,3 +11,4 @@
|
||||
@import "text-field.css";
|
||||
@import "textarea.css";
|
||||
@import "search.css";
|
||||
@import "combobox.css";
|
||||
@@ -7,10 +7,10 @@
|
||||
.navds-checkbox__input,
|
||||
.navds-radio__input {
|
||||
position: absolute;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
top: 0;
|
||||
left: -12px;
|
||||
left: -0.75rem;
|
||||
z-index: 1;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
@@ -22,6 +22,9 @@
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
gap: var(--a-spacing-2);
|
||||
|
||||
--__ac-radio-checkbox-readonly-bg: var(--a-surface-subtle);
|
||||
--__ac-radio-checkbox-readonly-border: var(--a-border-subtle);
|
||||
}
|
||||
|
||||
.navds-checkbox__label::before,
|
||||
@@ -48,15 +51,15 @@
|
||||
|
||||
.navds-checkbox--small > .navds-checkbox__input,
|
||||
.navds-radio--small > .navds-radio__input {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
top: 0;
|
||||
left: -6px;
|
||||
left: -0.375rem;
|
||||
}
|
||||
|
||||
.navds-checkbox--small > .navds-checkbox__label,
|
||||
.navds-radio--small > .navds-radio__label {
|
||||
padding: 6px 0;
|
||||
padding: 0.375rem 0;
|
||||
}
|
||||
|
||||
.navds-checkbox--small > .navds-checkbox__label::before,
|
||||
@@ -102,7 +105,7 @@
|
||||
background-color: var(--ac-radio-checkbox-bg, var(--a-surface-default));
|
||||
width: 0.75rem;
|
||||
height: 0.25rem;
|
||||
border-radius: 1px; /* Custom value OK */
|
||||
border-radius: 1px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@@ -111,16 +114,34 @@
|
||||
}
|
||||
|
||||
.navds-checkbox__input:checked + .navds-checkbox__label::before {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMyAxMCI+ICAgIDxnPiAgICA8cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNNCwxMGMtMC40LDAtMC44LTAuMS0xLjEtMC40TDAuNCw3LjFDMC4xLDYuOCwwLDYuNCwwLDZzMC4yLTAuOCwwLjUtMS4xQzEsNC40LDIsNC40LDIuNSw0LjlMNCw2LjRsNi40LTYgICAgQzEwLjgsMC4xLDExLjEsMCwxMS41LDBjMC40LDAsMC44LDAuMiwxLDAuNWMwLjYsMC42LDAuNSwxLjYtMC4xLDIuMXYwTDUsOS42QzQuNyw5LjksNC40LDEwLDQsMTB6IE0xMS44LDEuOUwxMS44LDEuOSAgICBDMTEuOCwxLjksMTEuOCwxLjksMTEuOCwxLjl6IE0xMS4yLDEuMUMxMS4yLDEuMSwxMS4yLDEuMSwxMS4yLDEuMUwxMS4yLDEuMXoiLz4gICAgPC9nPjwvc3ZnPg==);
|
||||
background-position: 6px center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 13px;
|
||||
box-shadow: none;
|
||||
background-color: var(--ac-radio-checkbox-action, var(--a-surface-action));
|
||||
}
|
||||
|
||||
.navds-checkbox__input:where(:not(:checked)) + .navds-checkbox__label > .navds-checkbox__icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navds-checkbox__input:checked + .navds-checkbox__label > .navds-checkbox__icon {
|
||||
color: var(--ac-radio-checkbox-bg, var(--a-surface-default));
|
||||
position: absolute;
|
||||
height: 1.5rem;
|
||||
transform: translate(0.375rem);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.navds-checkbox--small .navds-checkbox__input:checked + .navds-checkbox__label > .navds-checkbox__icon {
|
||||
transform: translate(0.25rem, -10%);
|
||||
}
|
||||
|
||||
/* Tailwind sets all svg to block */
|
||||
.navds-checkbox__icon > svg {
|
||||
display: inline;
|
||||
vertical-align: initial;
|
||||
}
|
||||
|
||||
.navds-checkbox--small > .navds-checkbox__input:checked + .navds-checkbox__label::before {
|
||||
background-position: 4px center;
|
||||
background-position: 0.25rem center;
|
||||
}
|
||||
|
||||
.navds-checkbox__input:indeterminate:focus-visible + .navds-checkbox__label::before,
|
||||
@@ -244,3 +265,60 @@
|
||||
.navds-radio--disabled > .navds-radio__label {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Readonly */
|
||||
.navds-checkbox--readonly > :where(.navds-checkbox__input, .navds-checkbox__label),
|
||||
.navds-radio--readonly > :where(.navds-radio__input, .navds-radio__label) {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.navds-checkbox--readonly .navds-checkbox__label-text {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.navds-checkbox--readonly > .navds-checkbox__input:hover + .navds-checkbox__label,
|
||||
.navds-radio--readonly > .navds-radio__input:hover + .navds-radio__label {
|
||||
color: var(--a-text-default);
|
||||
}
|
||||
|
||||
.navds-checkbox--readonly
|
||||
> .navds-checkbox__input:not(:disabled):not(:checked):not(:indeterminate)
|
||||
+ .navds-checkbox__label::before,
|
||||
.navds-checkbox--readonly
|
||||
> .navds-checkbox__input:hover:not(:checked):not(:indeterminate):not(:focus-visible)
|
||||
+ .navds-checkbox__label::before,
|
||||
.navds-radio--readonly > .navds-radio__input:not(:disabled):not(:checked):not(:indeterminate) + .navds-radio__label::before,
|
||||
.navds-radio--readonly
|
||||
> .navds-radio__input:hover:not(:checked):not(:indeterminate):not(:focus-visible)
|
||||
+ .navds-radio__label::before {
|
||||
background-color: var(--__ac-radio-checkbox-readonly-bg);
|
||||
box-shadow: inset 0 0 0 2px var(--__ac-radio-checkbox-readonly-border);
|
||||
}
|
||||
|
||||
.navds-checkbox--readonly > .navds-checkbox__input:focus-visible + .navds-checkbox__label::before,
|
||||
.navds-radio--readonly > .navds-radio__input:focus-visible + .navds-radio__label::before {
|
||||
--__ac-radio-checkbox-readonly-border: var(--a-border-subtle), var(--a-shadow-focus);
|
||||
}
|
||||
|
||||
.navds-checkbox--readonly > .navds-checkbox__input:checked + .navds-checkbox__label::before {
|
||||
box-shadow: inset 0 0 0 2px var(--__ac-radio-checkbox-readonly-border);
|
||||
background-color: var(--__ac-radio-checkbox-readonly-bg);
|
||||
}
|
||||
|
||||
.navds-checkbox--readonly > .navds-checkbox__input:checked + .navds-checkbox__label > .navds-checkbox__icon {
|
||||
color: var(--a-icon-subtle);
|
||||
}
|
||||
|
||||
.navds-radio--readonly > .navds-radio__input:checked + .navds-radio__label::before {
|
||||
box-shadow: inset 0 0 0 2px var(--__ac-radio-checkbox-readonly-border), inset 0 0 0 4px var(--__ac-radio-checkbox-readonly-bg);
|
||||
background-color: var(--a-icon-subtle);
|
||||
}
|
||||
|
||||
.navds-checkbox--readonly > .navds-checkbox__input:indeterminate + .navds-checkbox__label::before {
|
||||
box-shadow: inset 0 0 0 2px var(--__ac-radio-checkbox-readonly-border);
|
||||
background-color: var(--__ac-radio-checkbox-readonly-bg);
|
||||
}
|
||||
|
||||
.navds-checkbox--readonly > .navds-checkbox__input:indeterminate + .navds-checkbox__label::after {
|
||||
background-color: var(--a-icon-subtle);
|
||||
}
|
||||
@@ -104,8 +104,8 @@
|
||||
|
||||
.navds-search__button-search {
|
||||
flex-shrink: 0;
|
||||
min-width: 64px;
|
||||
min-height: 32px;
|
||||
min-width: 4rem;
|
||||
min-height: 2rem;
|
||||
border-radius: 0;
|
||||
border-top-right-radius: var(--a-border-radius-medium);
|
||||
border-bottom-right-radius: var(--a-border-radius-medium);
|
||||
@@ -116,7 +116,7 @@
|
||||
}
|
||||
|
||||
.navds-form-field--small .navds-search__button-search {
|
||||
min-width: 40px;
|
||||
min-width: 2.5rem;
|
||||
}
|
||||
|
||||
.navds-search__button-search.navds-button--secondary {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
color: var(--ac-select-text, var(--a-text-default));
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
min-height: 48px;
|
||||
min-height: 3rem;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
padding: 0.5rem;
|
||||
@@ -45,7 +45,7 @@
|
||||
}
|
||||
|
||||
.navds-form-field--small .navds-select__input {
|
||||
min-height: 32px;
|
||||
min-height: 2rem;
|
||||
padding: 0 2rem 0 0.25rem;
|
||||
}
|
||||
|
||||
@@ -79,3 +79,9 @@
|
||||
.navds-select__input:disabled > option {
|
||||
color: var(--a-text-default);
|
||||
}
|
||||
|
||||
.navds-select--readonly .navds-select__input {
|
||||
background-color: var(--a-surface-subtle);
|
||||
border-color: var(--a-border-subtle);
|
||||
cursor: default;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
.navds-switch {
|
||||
position: relative;
|
||||
min-height: 48px;
|
||||
min-height: 3rem;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
.navds-switch--small {
|
||||
position: relative;
|
||||
min-height: 32px;
|
||||
min-height: 2rem;
|
||||
}
|
||||
|
||||
/* Input */
|
||||
@@ -18,14 +18,14 @@
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
opacity: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.navds-switch--small > .navds-switch__input {
|
||||
height: 32px;
|
||||
height: 2rem;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
@@ -47,11 +47,11 @@
|
||||
}
|
||||
|
||||
.navds-switch--small > .navds-switch__label-wrapper > .navds-switch__content {
|
||||
padding: calc(var(--a-spacing-2) - 2px) 0 calc(var(--a-spacing-2) - 2px) 3.25rem;
|
||||
padding: calc(var(--a-spacing-2) - var(--a-spacing-05)) 0 calc(var(--a-spacing-2) - var(--a-spacing-05)) 3.25rem;
|
||||
}
|
||||
|
||||
.navds-switch--right.navds-switch--small > .navds-switch__label-wrapper > .navds-switch__content {
|
||||
padding: calc(var(--a-spacing-2) - 2px) 3.25rem calc(var(--a-spacing-2) - 2px) 0;
|
||||
padding: calc(var(--a-spacing-2) - var(--a-spacing-05)) 3.25rem calc(var(--a-spacing-2) - var(--a-spacing-05)) 0;
|
||||
}
|
||||
|
||||
.navds-switch--with-description,
|
||||
@@ -70,8 +70,8 @@
|
||||
|
||||
/* Track */
|
||||
.navds-switch__track {
|
||||
width: 44px;
|
||||
height: 24px;
|
||||
width: 2.75rem;
|
||||
height: 1.5rem;
|
||||
background-color: var(--ac-switch-bg, var(--a-surface-neutral));
|
||||
position: absolute;
|
||||
top: var(--a-spacing-3);
|
||||
@@ -125,12 +125,12 @@
|
||||
background-color: var(--ac-switch-thumb-bg, var(--a-surface-default));
|
||||
color: var(--ac-switch-thumb-icon, var(--a-icon-subtle));
|
||||
border-radius: var(--a-border-radius-full);
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
position: absolute;
|
||||
transform: translateX(0);
|
||||
left: 2px;
|
||||
top: 2px;
|
||||
left: var(--a-spacing-05);
|
||||
top: var(--a-spacing-05);
|
||||
transition: transform 250ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -138,17 +138,17 @@
|
||||
}
|
||||
|
||||
.navds-switch__input:checked ~ .navds-switch__track > .navds-switch__thumb {
|
||||
transform: translateX(20px);
|
||||
transform: translateX(1.25rem);
|
||||
color: var(--ac-switch-thumb-icon-checked, var(--a-icon-success));
|
||||
}
|
||||
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
.navds-switch__input:hover ~ .navds-switch__track > .navds-switch__thumb {
|
||||
transform: translateX(2px);
|
||||
transform: translateX(0.125rem);
|
||||
}
|
||||
|
||||
.navds-switch__input:checked:hover ~ .navds-switch__track > .navds-switch__thumb {
|
||||
transform: translateX(18px);
|
||||
transform: translateX(1.125rem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@
|
||||
}
|
||||
|
||||
.navds-switch__input:checked:disabled:hover ~ .navds-switch__track > .navds-switch__thumb {
|
||||
transform: translateX(20px);
|
||||
transform: translateX(1.25rem);
|
||||
}
|
||||
|
||||
/* Loader */
|
||||
@@ -178,3 +178,44 @@
|
||||
.navds-switch__input:disabled ~ .navds-switch__label-wrapper {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Readonly */
|
||||
.navds-switch--readonly > .navds-switch__track,
|
||||
.navds-switch--readonly > .navds-switch__input:hover ~ .navds-switch__track,
|
||||
.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);
|
||||
}
|
||||
|
||||
.navds-switch--readonly > .navds-switch__label-wrapper,
|
||||
.navds-switch--readonly > .navds-switch__input {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.navds-switch--readonly > .navds-switch__input:hover ~ .navds-switch__label-wrapper,
|
||||
.navds-switch--readonly .navds-switch__label-wrapper:hover {
|
||||
color: var(--a-text-default);
|
||||
}
|
||||
|
||||
.navds-switch--readonly .navds-switch__label {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.navds-switch--readonly .navds-switch__thumb {
|
||||
background-color: var(--a-surface-subtle);
|
||||
box-shadow: 0 0 0 2px var(--a-border-default);
|
||||
}
|
||||
|
||||
.navds-switch--readonly > .navds-switch__input:checked ~ .navds-switch__track > .navds-switch__thumb {
|
||||
color: var(--a-icon-subtle);
|
||||
}
|
||||
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
.navds-switch--readonly > .navds-switch__input:hover ~ .navds-switch__track > .navds-switch__thumb {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.navds-switch--readonly > .navds-switch__input:checked:hover ~ .navds-switch__track > .navds-switch__thumb {
|
||||
transform: translateX(1.25rem);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
background-color: var(--ac-textfield-bg, var(--a-surface-default));
|
||||
border-radius: var(--a-border-radius-medium);
|
||||
border: 1px solid var(--ac-textfield-border, var(--a-border-default));
|
||||
min-height: 48px;
|
||||
min-height: 3rem;
|
||||
width: 100%;
|
||||
color: var(--ac-textfield-text, var(--a-text-default));
|
||||
}
|
||||
@@ -27,8 +27,8 @@
|
||||
}
|
||||
|
||||
.navds-form-field--small .navds-text-field__input {
|
||||
padding: 0 0.5rem;
|
||||
min-height: 32px;
|
||||
padding: 0 var(--a-spacing-2);
|
||||
min-height: 2rem;
|
||||
}
|
||||
|
||||
.navds-text-field__input:hover {
|
||||
@@ -73,11 +73,10 @@
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.navds-text-field__input[readonly] {
|
||||
background-color: var(--ac-textfield-bg, var(--a-surface-default));
|
||||
border-color: var(--ac-textfield-border, var(--a-border-default));
|
||||
box-shadow: none;
|
||||
cursor: not-allowed;
|
||||
.navds-text-field--readonly .navds-text-field__input {
|
||||
background-color: var(--a-surface-subtle);
|
||||
border-color: var(--a-border-subtle);
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
}
|
||||
|
||||
.navds-form-field--small .navds-textarea__input {
|
||||
padding: 6px;
|
||||
padding: 0.375rem;
|
||||
}
|
||||
|
||||
.navds-form-field--small .navds-textarea--counter.navds-textarea__input {
|
||||
@@ -64,8 +64,8 @@
|
||||
font-style: italic;
|
||||
position: absolute;
|
||||
text-align: left;
|
||||
left: 1px;
|
||||
bottom: 1px;
|
||||
left: 0.0625rem;
|
||||
bottom: 0.0625rem;
|
||||
padding: var(--a-spacing-1) var(--a-spacing-2);
|
||||
}
|
||||
|
||||
@@ -99,9 +99,8 @@
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.navds-textarea__input[readonly] {
|
||||
background-color: var(--ac-textarea-bg, var(--a-surface-default));
|
||||
border-color: var(--ac-textarea-border, var(--a-border-default));
|
||||
box-shadow: none;
|
||||
cursor: not-allowed;
|
||||
.navds-textarea--readonly .navds-textarea__input {
|
||||
background-color: var(--a-surface-subtle);
|
||||
border-color: var(--a-border-subtle);
|
||||
cursor: default;
|
||||
}
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
.navds-help-text__popover.navds-popover {
|
||||
background-color: var(--ac-help-text-popover-bg, var(--a-surface-info-subtle));
|
||||
max-width: min(65ch, 90vw);
|
||||
max-width: min(65ch, calc(100vw - 1.5rem));
|
||||
|
||||
--ac-popover-border: var(--a-border-info);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
.navds-hgrid {
|
||||
--__ac-hgrid-columns-xs: initial;
|
||||
--__ac-hgrid-columns-sm: initial;
|
||||
--__ac-hgrid-columns-md: initial;
|
||||
--__ac-hgrid-columns-lg: initial;
|
||||
--__ac-hgrid-columns-xl: initial;
|
||||
--__ac-hgrid-columns: var(--__ac-hgrid-columns-xs);
|
||||
--__ac-hgrid-gap-xs: initial;
|
||||
--__ac-hgrid-gap-sm: initial;
|
||||
--__ac-hgrid-gap-md: initial;
|
||||
--__ac-hgrid-gap-lg: initial;
|
||||
--__ac-hgrid-gap-xl: initial;
|
||||
--__ac-hgrid-gap: var(--__ac-hgrid-gap-xs);
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: var(--__ac-hgrid-columns);
|
||||
gap: var(--__ac-hgrid-gap);
|
||||
}
|
||||
|
||||
@media (min-width: 480px) {
|
||||
.navds-hgrid {
|
||||
--__ac-hgrid-columns: var(--__ac-hgrid-columns-sm, var(--__ac-hgrid-columns-xs));
|
||||
--__ac-hgrid-gap: var(--__ac-hgrid-gap-sm, var(--__ac-hgrid-gap-xs));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.navds-hgrid {
|
||||
--__ac-hgrid-columns: var(--__ac-hgrid-columns-md, var(--__ac-hgrid-columns-sm, var(--__ac-hgrid-columns-xs)));
|
||||
--__ac-hgrid-gap: var(--__ac-hgrid-gap-md, var(--__ac-hgrid-gap-sm, var(--__ac-hgrid-gap-xs)));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.navds-hgrid {
|
||||
--__ac-hgrid-columns: var(
|
||||
--__ac-hgrid-columns-lg,
|
||||
var(--__ac-hgrid-columns-md, var(--__ac-hgrid-columns-sm, var(--__ac-hgrid-columns-xs)))
|
||||
);
|
||||
--__ac-hgrid-gap: var(--__ac-hgrid-gap-lg, var(--__ac-hgrid-gap-md, var(--__ac-hgrid-gap-sm, var(--__ac-hgrid-gap-xs))));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.navds-hgrid {
|
||||
--__ac-hgrid-columns: var(
|
||||
--__ac-hgrid-columns-xl,
|
||||
var(--__ac-hgrid-columns-lg, var(--__ac-hgrid-columns-md, var(--__ac-hgrid-columns-sm, var(--__ac-hgrid-columns-xs))))
|
||||
);
|
||||
--__ac-hgrid-gap: var(
|
||||
--__ac-hgrid-gap-xl,
|
||||
var(--__ac-hgrid-gap-lg, var(--__ac-hgrid-gap-md, var(--__ac-hgrid-gap-sm, var(--__ac-hgrid-gap-xs))))
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
@import "guide-panel.css";
|
||||
@import "form/index.css";
|
||||
@import "help-text.css";
|
||||
@import "hgrid.css";
|
||||
@import "internalheader.css";
|
||||
@import "link.css";
|
||||
@import "loader.css";
|
||||
@@ -29,6 +30,7 @@
|
||||
@import "link-panel.css";
|
||||
@import "read-more.css";
|
||||
@import "skeleton.css";
|
||||
@import "stack.css";
|
||||
@import "stepper.css";
|
||||
@import "table.css";
|
||||
@import "tabs.css";
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
display: flex;
|
||||
align-self: stretch;
|
||||
background: var(--ac-internalheader-bg, var(--a-surface-inverted));
|
||||
min-height: var(--a-spacing-12);
|
||||
min-height: 3rem;
|
||||
|
||||
--navds-internalheader-focus: inset 0 0 0 2px var(--a-border-focus-on-inverted);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
}
|
||||
|
||||
.navds-link-panel:hover {
|
||||
box-shadow: var(--a-shadow-medium);
|
||||
box-shadow: var(--a-shadow-small);
|
||||
border-color: var(--ac-link-panel-hover-border, var(--a-border-action));
|
||||
}
|
||||
|
||||
|
||||
@@ -6,15 +6,35 @@
|
||||
gap: var(--a-spacing-1);
|
||||
}
|
||||
|
||||
.navds-alert .navds-link,
|
||||
.navds-confirmation-panel .navds-link {
|
||||
color: var(--a-text-default);
|
||||
.navds-link.navds-link--inline-text {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.navds-link.navds-link--inline-text > svg {
|
||||
/* stylelint-disable-next-line plugin/declaration-block-no-ignored-properties */
|
||||
margin: 0.1em 0.1em -0.1em;
|
||||
transform: translateY(0.05em);
|
||||
display: inline;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.navds-link:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.navds-link.navds-link--remove-underline {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.navds-link.navds-link--remove-underline:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.navds-alert .navds-link,
|
||||
.navds-confirmation-panel .navds-link {
|
||||
color: var(--a-text-default);
|
||||
}
|
||||
|
||||
.navds-link:focus-visible {
|
||||
outline: none;
|
||||
color: var(--ac-link-focus-text, var(--a-text-on-action));
|
||||
@@ -45,3 +65,15 @@
|
||||
color: inherit;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.navds-link--action {
|
||||
color: var(--ac-link-action-text, var(--a-text-action));
|
||||
}
|
||||
|
||||
.navds-link--neutral {
|
||||
color: var(--ac-link-neutral-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-link--subtle {
|
||||
color: var(--ac-link-subtle-text, var(--a-text-subtle));
|
||||
}
|
||||
@@ -1,14 +1,24 @@
|
||||
.navds-list ul,
|
||||
.navds-list ol {
|
||||
padding: 0;
|
||||
margin-block: var(--a-spacing-4);
|
||||
}
|
||||
|
||||
.navds-list--nested {
|
||||
margin: var(--a-spacing-4) 0 var(--a-spacing-8) 0;
|
||||
.navds-list--nested ul,
|
||||
.navds-list--nested ol {
|
||||
margin-block: var(--a-spacing-2);
|
||||
}
|
||||
|
||||
.navds-list li:not(.navds-list__item--noMargin) {
|
||||
margin-bottom: var(--a-spacing-5);
|
||||
.navds-list li {
|
||||
margin-block-end: var(--a-spacing-5);
|
||||
}
|
||||
|
||||
.navds-list--small li {
|
||||
margin-block-end: var(--a-spacing-2);
|
||||
}
|
||||
|
||||
.navds-list--nested li {
|
||||
margin-block-end: var(--a-spacing-3);
|
||||
}
|
||||
|
||||
.navds-list:last-child > ul > li:last-child,
|
||||
@@ -34,15 +44,30 @@
|
||||
|
||||
.navds-list .navds-list__item-marker--bullet {
|
||||
display: flex;
|
||||
margin-top: 6px;
|
||||
align-items: center;
|
||||
height: var(--a-font-line-height-large);
|
||||
grid-column: 1 / 2;
|
||||
/* stylelint-disable-next-line csstools/value-no-unknown-custom-properties */
|
||||
color: var(--ac-list-marker-ul-color, var(--ac-list-marker-color, var(--a-icon-default)));
|
||||
}
|
||||
|
||||
.navds-list--small .navds-list__item-marker--bullet {
|
||||
height: var(--a-font-line-height-medium);
|
||||
}
|
||||
|
||||
.navds-list__item-marker--icon {
|
||||
/* stylelint-disable-next-line csstools/value-no-unknown-custom-properties */
|
||||
color: var(--ac-list-marker-icon-color, var(--ac-list-marker-color, var(--a-icon-default)));
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: var(--a-font-line-height-large);
|
||||
padding-block-end: 1px;
|
||||
}
|
||||
|
||||
.navds-list--small .navds-list__item-marker--icon {
|
||||
height: var(--a-font-line-height-medium);
|
||||
}
|
||||
|
||||
.navds-list__item-marker--icon svg {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.navds-list ul .navds-list__item-content {
|
||||
@@ -51,6 +76,7 @@
|
||||
|
||||
.navds-list ol {
|
||||
padding-left: var(--a-spacing-2);
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.navds-list ol li {
|
||||
@@ -60,7 +86,12 @@
|
||||
|
||||
.navds-list ol li::marker {
|
||||
font-weight: var(--a-font-weight-bold);
|
||||
font-size: var(--a-font-size-medium);
|
||||
/* stylelint-disable-next-line csstools/value-no-unknown-custom-properties */
|
||||
font-size: var(--a-font-size-large);
|
||||
color: var(--ac-list-marker-ol-color, var(--ac-list-marker-color, var(--a-icon-default)));
|
||||
line-height: var(--a-font-line-height-large);
|
||||
}
|
||||
|
||||
.navds-list--small ol li::marker {
|
||||
font-size: var(--a-font-size-small);
|
||||
line-height: var(--a-font-line-height-medium);
|
||||
}
|
||||
+127
-43
@@ -1,68 +1,152 @@
|
||||
.ReactModal__Body--open {
|
||||
.navds-modal__document-body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.navds-modal {
|
||||
background-color: var(--ac-modal-bg, var(--a-surface-default));
|
||||
border-radius: var(--a-border-radius-medium);
|
||||
display: block;
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
border: 1px solid var(--ac-modal-border, var(--a-border-subtle));
|
||||
border-radius: var(--a-border-radius-large);
|
||||
box-shadow: var(--a-shadow-xlarge);
|
||||
padding: 0;
|
||||
position: fixed;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.navds-modal__content {
|
||||
padding: var(--a-spacing-4);
|
||||
.navds-modal[open] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
animation: akselModalFadeIn 0.35s cubic-bezier(0.15, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.navds-modal:focus-visible,
|
||||
.navds-modal--focus {
|
||||
box-shadow: var(--a-shadow-focus);
|
||||
outline: none;
|
||||
.navds-modal--polyfilled {
|
||||
top: 50%;
|
||||
transform: translate(0, -50%);
|
||||
overflow: auto;
|
||||
|
||||
/* From polyfill (dialog-polyfill/dist/dialog-polyfill.css): */
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: fit-content;
|
||||
height: fit-content;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
@supports not selector(:focus-visible) {
|
||||
.navds-modal:focus,
|
||||
.navds-modal--focus {
|
||||
box-shadow: var(--a-shadow-focus);
|
||||
outline: none;
|
||||
.navds-modal--polyfilled:not([open]) {
|
||||
display: none; /* from polyfill */
|
||||
}
|
||||
|
||||
._dialog_overlay {
|
||||
/* From polyfill */
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.navds-modal--small {
|
||||
width: var(--ac-modal-width-small, 450px);
|
||||
}
|
||||
|
||||
.navds-modal--medium {
|
||||
width: var(--ac-modal-width-medium, 700px);
|
||||
}
|
||||
|
||||
@media (min-width: 480px) {
|
||||
.navds-modal {
|
||||
max-width: calc((100% - 6px) - 2em);
|
||||
max-height: calc((100% - 6px) - 2em);
|
||||
}
|
||||
|
||||
.navds-modal--autowidth {
|
||||
max-width: min(700px, calc((100% - 6px) - 2em));
|
||||
}
|
||||
}
|
||||
|
||||
.navds-modal__overlay {
|
||||
.navds-modal::backdrop {
|
||||
/*
|
||||
* Cannot use --a-surface-backdrop because ::backdrop does not inherit from anything but itself.
|
||||
* But consumers can do `::backdrop { --ac-modal-backdrop: white; }`
|
||||
* We can add ::backdrop to tokens.css when we remove the polyfill.
|
||||
*/
|
||||
background: var(--ac-modal-backdrop, rgb(2 20 49 / 0.49));
|
||||
animation: akselModalBackdropFadeIn 0.35s cubic-bezier(0.15, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.navds-modal--polyfilled + .backdrop /* Cannot be combined with ::backdrop selector */ {
|
||||
background: var(--ac-modal-backdrop, rgb(2 20 49 / 0.49));
|
||||
|
||||
/* From polyfill: */
|
||||
position: fixed;
|
||||
z-index: var(--a-z-index-modal);
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: var(--ac-modal-backdrop, var(--a-surface-backdrop));
|
||||
padding: var(--a-spacing-4);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.navds-modal__button--shake {
|
||||
transform: rotate(0deg);
|
||||
transition: transform 100ms cubic-bezier(0.82, 2, 1, 0.3);
|
||||
}
|
||||
|
||||
/* prettier-ignore */
|
||||
.navds-modal__overlay:active > .navds-modal:not(:active) > .navds-modal__button--shake {
|
||||
transform: rotate(10deg);
|
||||
transition: transform 100ms cubic-bezier(0.82, -2, 1, 0.3);
|
||||
}
|
||||
|
||||
.navds-modal__button {
|
||||
position: absolute;
|
||||
top: var(--a-spacing-4);
|
||||
right: var(--a-spacing-4);
|
||||
display: flex;
|
||||
padding: var(--a-spacing-2);
|
||||
margin-left: var(--a-spacing-4);
|
||||
float: right;
|
||||
}
|
||||
|
||||
.navds-modal__button svg {
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
.navds-modal__header {
|
||||
padding: var(--a-spacing-6) var(--a-spacing-6) var(--a-spacing-4) var(--a-spacing-6);
|
||||
}
|
||||
|
||||
.navds-modal__header-icon svg {
|
||||
display: inline;
|
||||
vertical-align: -0.25rem;
|
||||
margin-right: var(--a-spacing-1);
|
||||
}
|
||||
|
||||
.navds-modal__label {
|
||||
font-weight: 600;
|
||||
color: var(--a-text-subtle);
|
||||
}
|
||||
|
||||
.navds-modal__body {
|
||||
padding: var(--a-spacing-6);
|
||||
overflow: auto;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
|
||||
.navds-modal__header + .navds-modal__body {
|
||||
padding-top: var(--a-spacing-0);
|
||||
}
|
||||
|
||||
.navds-modal__footer {
|
||||
display: flex;
|
||||
flex-flow: row-reverse wrap;
|
||||
gap: var(--a-spacing-4);
|
||||
padding: var(--a-spacing-4) var(--a-spacing-6) var(--a-spacing-6) var(--a-spacing-6);
|
||||
}
|
||||
|
||||
.navds-modal__footer :nth-of-type(2) {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
@keyframes akselModalFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translate3d(0, calc(5% + 4px), 0);
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
to {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes akselModalBackdropFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css",
|
||||
"version": "4.2.0",
|
||||
"version": "5.0.3",
|
||||
"description": "CSS for NAV Designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
@@ -27,11 +27,11 @@
|
||||
"css:get-version": "node config/get-version.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@navikt/ds-tokens": "^4.2.0",
|
||||
"@navikt/ds-tokens": "^5.0.3",
|
||||
"cssnano": "6.0.0",
|
||||
"fast-glob": "3.2.11",
|
||||
"lodash": "4.17.21",
|
||||
"nodemon": "^2.0.12",
|
||||
"nodemon": "^3.0.1",
|
||||
"normalize.css": "^8.0.1",
|
||||
"postcss": "^8.4.0",
|
||||
"postcss-cli": "^9.0.0",
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
border: 1px solid;
|
||||
border-color: var(--ac-popover-border, var(--a-border-default));
|
||||
border-radius: var(--a-border-radius-medium);
|
||||
max-width: calc(100vw - var(--a-spacing-6));
|
||||
}
|
||||
|
||||
.navds-popover__content {
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
gap: var(--a-spacing-05);
|
||||
color: var(--ac-read-more-text, var(--a-text-action));
|
||||
border-radius: var(--a-border-radius-small);
|
||||
padding: var(--a-spacing-1) var(--a-spacing-1) var(--a-spacing-1) 2px;
|
||||
padding: var(--a-spacing-1) var(--a-spacing-1) var(--a-spacing-1) var(--a-spacing-05);
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
.navds-read-more--small .navds-read-more__button {
|
||||
padding: 2px var(--a-spacing-1) 2px 2px;
|
||||
padding: var(--a-spacing-05) var(--a-spacing-1) var(--a-spacing-05) var(--a-spacing-05);
|
||||
}
|
||||
|
||||
.navds-read-more__button:hover {
|
||||
@@ -39,14 +39,14 @@
|
||||
.navds-read-more__content {
|
||||
margin-top: var(--a-spacing-1);
|
||||
border-left: 2px solid var(--ac-read-more-line, var(--a-border-divider));
|
||||
margin-left: 13px;
|
||||
padding-left: 13px;
|
||||
margin-left: 0.8125rem;
|
||||
padding-left: 0.8125rem;
|
||||
color: var(--a-text-default);
|
||||
}
|
||||
|
||||
.navds-read-more--small .navds-read-more__content {
|
||||
margin-left: 11px;
|
||||
padding-left: 11px;
|
||||
margin-left: 0.6875rem;
|
||||
padding-left: 0.6875rem;
|
||||
}
|
||||
|
||||
.navds-read-more__content--closed {
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
.navds-stack {
|
||||
--__ac-stack-align: initial;
|
||||
--__ac-stack-justify: initial;
|
||||
--__ac-stack-direction: initial;
|
||||
--__ac-stack-wrap: initial;
|
||||
--__ac-stack-gap-xs: initial;
|
||||
--__ac-stack-gap-sm: initial;
|
||||
--__ac-stack-gap-md: initial;
|
||||
--__ac-stack-gap-lg: initial;
|
||||
--__ac-stack-gap-xl: initial;
|
||||
--__ac-stack-gap: var(--__ac-stack-gap-xs);
|
||||
|
||||
gap: var(--__ac-stack-gap);
|
||||
display: flex;
|
||||
align-items: var(--__ac-stack-align);
|
||||
justify-content: var(--__ac-stack-justify);
|
||||
flex-flow: var(--__ac-stack-direction) var(--__ac-stack-wrap);
|
||||
}
|
||||
|
||||
.navds-stack__spacer {
|
||||
flex: 1;
|
||||
justify-self: stretch;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.navds-stack > .navds-stack__spacer {
|
||||
margin-block-start: calc(var(--__ac-stack-gap) * -1);
|
||||
}
|
||||
|
||||
.navds-hstack > .navds-stack__spacer {
|
||||
margin-inline-start: calc(var(--__ac-stack-gap) * -1);
|
||||
}
|
||||
|
||||
@media (min-width: 480px) {
|
||||
.navds-stack {
|
||||
--__ac-stack-gap: var(--__ac-stack-gap-sm, var(--__ac-stack-gap-xs));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.navds-stack {
|
||||
--__ac-stack-gap: var(--__ac-stack-gap-md, var(--__ac-stack-gap-sm, var(--__ac-stack-gap-xs)));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.navds-stack {
|
||||
--__ac-stack-gap: var(--__ac-stack-gap-lg, var(--__ac-stack-gap-md, var(--__ac-stack-gap-sm, var(--__ac-stack-gap-xs))));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.navds-stack {
|
||||
--__ac-stack-gap: var(
|
||||
--__ac-stack-gap-xl,
|
||||
var(--__ac-stack-gap-lg, var(--__ac-stack-gap-md, var(--__ac-stack-gap-sm, var(--__ac-stack-gap-xs))))
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,10 @@
|
||||
background-color: var(--ac-stepper-line-completed, var(--a-border-selected));
|
||||
}
|
||||
|
||||
.navds-stepper__item--behind.navds-stepper__item--completed + .navds-stepper__item > .navds-stepper__line--1 {
|
||||
background-color: var(--ac-stepper-line-completed, var(--a-border-selected));
|
||||
}
|
||||
|
||||
.navds-stepper__line--1 {
|
||||
grid-row: line-1;
|
||||
display: none;
|
||||
@@ -109,7 +113,7 @@ button.navds-stepper__step {
|
||||
.navds-stepper__circle--success {
|
||||
border: none;
|
||||
background: none;
|
||||
font-size: 28px;
|
||||
font-size: 1.75rem;
|
||||
color: var(--a-text-on-action);
|
||||
background-color: var(--ac-stepper-text, var(--a-surface-action));
|
||||
}
|
||||
@@ -213,6 +217,12 @@ button.navds-stepper__step {
|
||||
background-color: var(--ac-stepper-non-interactive-line-completed, var(--a-border-strong));
|
||||
}
|
||||
|
||||
.navds-stepper__item--non-interactive.navds-stepper__item--behind.navds-stepper__item--completed
|
||||
+ .navds-stepper__item
|
||||
> .navds-stepper__line--1 {
|
||||
background-color: var(--ac-stepper-non-interactive-line-completed, var(--a-border-strong));
|
||||
}
|
||||
|
||||
:where(.navds-stepper__step--non-interactive.navds-stepper__step--active) .navds-stepper__circle {
|
||||
background-color: var(--ac-stepper-non-interactive-active-bg, var(--a-surface-inverted));
|
||||
border-color: var(--ac-stepper-non-interactive-active-border, var(--a-surface-inverted));
|
||||
|
||||
+64
-37
@@ -16,7 +16,7 @@
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.navds-table__body .navds-table__row--shade-on-hover:hover {
|
||||
.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));
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
.navds-table__header-cell,
|
||||
.navds-table__data-cell {
|
||||
display: table-cell;
|
||||
padding: var(--a-spacing-4) var(--a-spacing-3);
|
||||
padding: var(--a-spacing-3) var(--a-spacing-2);
|
||||
border-bottom: 1px solid var(--ac-table-row-border, var(--a-border-default));
|
||||
text-align: left;
|
||||
}
|
||||
@@ -74,17 +74,22 @@
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
|
||||
.navds-table--large .navds-table__header-cell,
|
||||
.navds-table--large .navds-table__data-cell {
|
||||
padding: var(--a-spacing-4) var(--a-spacing-2);
|
||||
}
|
||||
|
||||
.navds-table--small .navds-table__header-cell,
|
||||
.navds-table--small .navds-table__data-cell {
|
||||
padding: var(--a-spacing-2) var(--a-spacing-3);
|
||||
padding: var(--a-spacing-1) var(--a-spacing-2);
|
||||
}
|
||||
|
||||
.navds-table .navds-checkbox .navds-checkbox__input {
|
||||
top: -12px;
|
||||
top: -0.75rem;
|
||||
}
|
||||
|
||||
.navds-table .navds-checkbox--small .navds-checkbox__input {
|
||||
top: -6px;
|
||||
top: -0.375rem;
|
||||
}
|
||||
|
||||
.navds-table .navds-checkbox .navds-checkbox__label {
|
||||
@@ -154,6 +159,10 @@
|
||||
transition: border-bottom-color 190ms cubic-bezier(0.6, 0.04, 0.98, 0.335);
|
||||
}
|
||||
|
||||
.navds-table__expandable-row.navds-table__expandable-row--clickable:not(.navds-table__expandable-row--expansion-disabled):hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.navds-table__expandable-row--open .navds-table__data-cell {
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
@@ -167,55 +176,73 @@
|
||||
}
|
||||
|
||||
.navds-table__toggle-expand-cell {
|
||||
padding: 0;
|
||||
width: 56px;
|
||||
padding: 0 var(--a-spacing-2);
|
||||
position: relative;
|
||||
width: 2.5rem;
|
||||
}
|
||||
|
||||
.navds-table--large .navds-table__toggle-expand-cell {
|
||||
padding: 0 var(--a-spacing-2);
|
||||
}
|
||||
|
||||
.navds-table--small .navds-table__toggle-expand-cell {
|
||||
padding: 0;
|
||||
width: 36px;
|
||||
padding: var(--a-spacing-1) var(--a-spacing-2);
|
||||
}
|
||||
|
||||
.navds-table__toggle-expand-button {
|
||||
all: unset;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
display: grid;
|
||||
place-content: center;
|
||||
cursor: pointer;
|
||||
padding: var(--a-spacing-4);
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: var(--a-border-radius-medium);
|
||||
height: 2rem;
|
||||
width: 2rem;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.navds-table--small .navds-table__toggle-expand-button {
|
||||
padding: var(--a-spacing-2);
|
||||
.navds-table__expandable-icon {
|
||||
transition: transform 150ms ease-in-out;
|
||||
}
|
||||
|
||||
.navds-table__toggle-expand-button:hover,
|
||||
.navds-table__expandable-row--clickable:hover .navds-table__toggle-expand-button {
|
||||
background-color: var(--a-surface-hover);
|
||||
}
|
||||
|
||||
.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);
|
||||
}
|
||||
|
||||
.navds-table__toggle-expand-button:focus-visible {
|
||||
box-shadow: inset var(--a-shadow-focus);
|
||||
outline: none;
|
||||
box-shadow: var(--a-shadow-focus);
|
||||
}
|
||||
|
||||
@supports not selector(:focus-visible) {
|
||||
.navds-table__toggle-expand-button:focus {
|
||||
box-shadow: inset var(--a-shadow-focus);
|
||||
outline: none;
|
||||
box-shadow: var(--a-shadow-focus);
|
||||
}
|
||||
}
|
||||
|
||||
.navds-table__expandable-icon {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.navds-table--small .navds-table__expandable-icon {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.navds-table__toggle-expand-button:hover .navds-table__expandable-icon {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
.navds-table__toggle-expand-cell--open .navds-table__expandable-icon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.navds-table__toggle-expand-cell--open .navds-table__toggle-expand-button:hover .navds-table__expandable-icon {
|
||||
transform: translateY(-1px) rotate(180deg);
|
||||
.navds-table__toggle-expand-button::after {
|
||||
inset: 0;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.navds-table__expanded-row-cell {
|
||||
@@ -231,9 +258,9 @@
|
||||
}
|
||||
|
||||
.navds-table__expanded-row-content {
|
||||
padding: var(--a-spacing-4) 4.25rem;
|
||||
padding: var(--a-spacing-4) calc(var(--a-spacing-2) + 3rem);
|
||||
}
|
||||
|
||||
.navds-table--small .navds-table__expanded-row-content {
|
||||
padding: var(--a-spacing-2) var(--a-spacing-12);
|
||||
padding: var(--a-spacing-2) calc(var(--a-spacing-2) + 3rem);
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
.navds-tabs__scroll-button {
|
||||
padding: var(--a-spacing-3) var(--a-spacing-4);
|
||||
width: 44px;
|
||||
width: 2.75rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@@ -38,11 +38,11 @@
|
||||
|
||||
.navds-tabs--small .navds-tabs__scroll-button {
|
||||
padding: 0.375rem var(--a-spacing-4);
|
||||
width: 32px;
|
||||
width: 2rem;
|
||||
}
|
||||
|
||||
.navds-tabs__tab {
|
||||
min-height: 48px;
|
||||
min-height: 3rem;
|
||||
padding: var(--a-spacing-3) var(--a-spacing-4);
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
@@ -92,7 +92,7 @@
|
||||
}
|
||||
|
||||
.navds-tabs__tab--small {
|
||||
min-height: 32px;
|
||||
min-height: 2rem;
|
||||
padding: 0.375rem var(--a-spacing-4);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,17 +5,17 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--a-spacing-05) var(--a-spacing-2);
|
||||
min-height: 32px;
|
||||
min-height: 2rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.navds-tag--small {
|
||||
min-height: 24px;
|
||||
min-height: 1.5rem;
|
||||
padding: 0 0.375rem;
|
||||
}
|
||||
|
||||
.navds-tag--xsmall {
|
||||
min-height: 20px;
|
||||
min-height: 1.25rem;
|
||||
padding: 0 var(--a-spacing-1);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
height: 1rem;
|
||||
box-sizing: content-box;
|
||||
grid-column: 2;
|
||||
margin-bottom: var(--a-spacing-1);
|
||||
}
|
||||
|
||||
.navds-timeline__row-label {
|
||||
@@ -181,7 +182,7 @@
|
||||
0 0 0 4px var(--ac-timeline-pin-bg, var(--a-surface-danger)), 0 0 0 5px var(--a-surface-default);
|
||||
z-index: 2;
|
||||
border-radius: var(--a-border-radius-full);
|
||||
padding: 3.5px;
|
||||
padding: var(--a-spacing-1);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -232,7 +233,7 @@
|
||||
.navds-timeline__pin-wrapper::before {
|
||||
content: "";
|
||||
top: var(--navdsc-timeline-pin-size);
|
||||
height: calc(94% - var(--navdsc-timeline-pin-size));
|
||||
height: calc(88% - var(--navdsc-timeline-pin-size));
|
||||
width: 1px;
|
||||
margin: 0 auto;
|
||||
background: var(--a-surface-inverted);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
border-radius: var(--a-border-radius-medium);
|
||||
background-color: var(--ac-toggle-group-bg, var(--a-surface-transparent));
|
||||
box-shadow: inset 0 0 0 1px var(--ac-toggle-group-border, var(--a-border-default));
|
||||
padding: calc(var(--a-spacing-1) + 1px);
|
||||
padding: calc(var(--a-spacing-1) + 0.0625rem);
|
||||
gap: var(--a-spacing-1);
|
||||
display: inline-grid;
|
||||
grid-auto-flow: column;
|
||||
@@ -16,7 +16,7 @@
|
||||
}
|
||||
|
||||
.navds-toggle-group--small {
|
||||
padding: calc(var(--a-spacing-05) + 1px);
|
||||
padding: calc(var(--a-spacing-05) + 0.0625rem);
|
||||
}
|
||||
|
||||
.navds-toggle-group--neutral {
|
||||
@@ -29,12 +29,12 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--a-spacing-1) var(--a-spacing-3);
|
||||
min-height: 38px;
|
||||
min-height: 2.375rem;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
background-color: var(--ac-toggle-group-button-bg, var(--a-surface-transparent));
|
||||
color: var(--ac-toggle-group-button-text, var(--a-text-default));
|
||||
border-radius: 2px;
|
||||
border-radius: var(--a-border-radius-small);
|
||||
min-width: fit-content;
|
||||
font-weight: var(--a-font-weight-regular);
|
||||
}
|
||||
@@ -113,7 +113,6 @@
|
||||
.navds-toggle-group__button[aria-checked="true"] {
|
||||
background-color: var(--ac-toggle-group-selected-bg, var(--a-surface-action-selected));
|
||||
color: var(--ac-toggle-group-selected-text, var(--a-text-on-action));
|
||||
font-weight: var(--a-font-weight-bold);
|
||||
}
|
||||
|
||||
.navds-toggle-group--neutral > .navds-toggle-group__button[aria-pressed="true"],
|
||||
@@ -124,7 +123,7 @@
|
||||
|
||||
.navds-toggle-group--small > .navds-toggle-group__button {
|
||||
padding: var(--a-spacing-05) var(--a-spacing-3);
|
||||
min-height: 26px;
|
||||
min-height: 1.625rem;
|
||||
min-width: fit-content;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,6 @@
|
||||
"--ac-button-tertiary-neutral-active-hover-bg": "--a-surface-neutral-active"
|
||||
},
|
||||
"chat": {
|
||||
"--ac-chat-border-color": "--a-border-subtle",
|
||||
"--ac-chat-avatar-bg": "--a-surface-neutral-subtle",
|
||||
"--ac-chat-avatar-color": "--a-text-default",
|
||||
"--ac-chat-bubble-bg": "--a-surface-neutral-subtle",
|
||||
@@ -176,7 +175,10 @@
|
||||
"--ac-link-focus-border": "--a-border-focus",
|
||||
"--ac-link-active-text": "--a-text-on-action",
|
||||
"--ac-link-active-bg": "--a-border-focus",
|
||||
"--ac-link-active-border": "--a-border-focus"
|
||||
"--ac-link-active-border": "--a-border-focus",
|
||||
"--ac-link-action-text": "--a-text-action",
|
||||
"--ac-link-neutral-text": "--a-text-default",
|
||||
"--ac-link-subtle-text": "--a-text-subtle"
|
||||
},
|
||||
"list": {
|
||||
"--ac-list-marker-ul-color": "--ac-list-marker-color",
|
||||
@@ -194,7 +196,10 @@
|
||||
},
|
||||
"modal": {
|
||||
"--ac-modal-bg": "--a-surface-default",
|
||||
"--ac-modal-backdrop": "--a-surface-backdrop"
|
||||
"--ac-modal-border": "--a-border-subtle",
|
||||
"--ac-modal-backdrop": "--a-surface-backdrop",
|
||||
"--ac-modal-width-small": "450px",
|
||||
"--ac-modal-width-medium": "700px"
|
||||
},
|
||||
"pagination": {
|
||||
"--ac-pagination-text": "--a-text-default",
|
||||
@@ -373,6 +378,22 @@
|
||||
"--ac-search-button-focus-active-border": "--a-surface-default",
|
||||
"--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",
|
||||
"--ac-combobox-list-item-bg": "--a-surface-default",
|
||||
"--ac-combobox-list-item-hover-bg": "--a-surface-hover",
|
||||
"--ac-combobox-list-item-selected-bg": "--a-surface-default",
|
||||
"--ac-combobox-list-item-selected-hover-bg": "--a-surface-action-subtle-hover",
|
||||
"--ac-combobox-list-item-loading-bg": "--a-surface-default",
|
||||
"--ac-combobox-list-item-hover-border-left": "--a-border-strong",
|
||||
"--ac-combobox-list-item-selected-hover-border-left": "--a-border-focus",
|
||||
"--ac-combobox-error-border": "--a-border-danger"
|
||||
},
|
||||
"select": {
|
||||
"--ac-select-bg": "--a-surface-default",
|
||||
"--ac-select-text": "--a-text-default",
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
}
|
||||
|
||||
.navds-tooltip__arrow {
|
||||
height: 7px;
|
||||
width: 7px;
|
||||
height: 0.4375rem;
|
||||
width: 0.4375rem;
|
||||
transform: rotate(45deg);
|
||||
z-index: -1;
|
||||
background-color: var(--ac-tooltip-bg, var(--a-surface-inverted));
|
||||
@@ -45,8 +45,8 @@
|
||||
color: var(--ac-tooltip-key-text, var(--a-text-on-inverted));
|
||||
border-radius: var(--a-border-radius-small);
|
||||
padding: 0 var(--a-spacing-1);
|
||||
min-width: 18px;
|
||||
height: 18px;
|
||||
min-width: 1.125rem;
|
||||
height: 1.125rem;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
+418
-786
File diff suppressed because it is too large.
Load diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react",
|
||||
"version": "4.2.0",
|
||||
"version": "5.0.3",
|
||||
"description": "Aksel react-components for NAV designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"license": "MIT",
|
||||
@@ -38,13 +38,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@floating-ui/react": "0.24.1",
|
||||
"@navikt/aksel-icons": "^4.2.0",
|
||||
"@navikt/aksel-icons": "^5.0.3",
|
||||
"@radix-ui/react-tabs": "1.0.0",
|
||||
"@radix-ui/react-toggle-group": "1.0.0",
|
||||
"clsx": "^1.2.1",
|
||||
"date-fns": "2.29.3",
|
||||
"react-day-picker": "8.3.4",
|
||||
"react-modal": "3.15.1"
|
||||
"react-day-picker": "8.3.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/dom": "8.13.0",
|
||||
@@ -53,7 +52,6 @@
|
||||
"@testing-library/user-event": "^14.2.0",
|
||||
"@types/faker": "5.5.8",
|
||||
"@types/jest": "^29.0.0",
|
||||
"@types/react-modal": "^3.13.1",
|
||||
"concurrently": "7.2.1",
|
||||
"copyfiles": "^2.4.1",
|
||||
"faker": "5.5.3",
|
||||
|
||||
@@ -3,10 +3,12 @@ import {
|
||||
CheckmarkCircleFillIcon,
|
||||
ExclamationmarkTriangleFillIcon,
|
||||
XMarkOctagonFillIcon,
|
||||
XMarkIcon,
|
||||
} from "@navikt/aksel-icons";
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef } from "react";
|
||||
import { BodyLong } from "../typography/BodyLong";
|
||||
import { Button } from "../button";
|
||||
|
||||
export interface AlertProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
/**
|
||||
@@ -32,6 +34,17 @@ export interface AlertProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
* @default false
|
||||
*/
|
||||
inline?: boolean;
|
||||
/**
|
||||
* Removes close-button(X) when false
|
||||
* Requires onClose to be set
|
||||
* @default true
|
||||
*/
|
||||
closeButton?: boolean;
|
||||
/**
|
||||
* Callback for alert wanting to close
|
||||
* requires closeButton to be true
|
||||
*/
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
const Icon = ({ variant, ...props }) => {
|
||||
@@ -71,27 +84,46 @@ export const Alert = forwardRef<HTMLDivElement, AlertProps>(
|
||||
size = "medium",
|
||||
fullWidth = false,
|
||||
inline = false,
|
||||
closeButton = false,
|
||||
onClose,
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
) => (
|
||||
<div
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
className,
|
||||
"navds-alert",
|
||||
`navds-alert--${variant}`,
|
||||
`navds-alert--${size}`,
|
||||
{ "navds-alert--full-width": fullWidth, "navds-alert--inline": inline }
|
||||
)}
|
||||
>
|
||||
<Icon variant={variant} className="navds-alert__icon" />
|
||||
<BodyLong as="div" size={size} className="navds-alert__wrapper">
|
||||
{children}
|
||||
</BodyLong>
|
||||
</div>
|
||||
)
|
||||
) => {
|
||||
return (
|
||||
<div
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
className,
|
||||
"navds-alert",
|
||||
`navds-alert--${variant}`,
|
||||
`navds-alert--${size}`,
|
||||
{
|
||||
"navds-alert--full-width": fullWidth,
|
||||
"navds-alert--inline": inline,
|
||||
"navds-alert--close-button": closeButton,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<Icon variant={variant} className="navds-alert__icon" />
|
||||
<BodyLong as="div" size={size} className="navds-alert__wrapper">
|
||||
{children}
|
||||
</BodyLong>
|
||||
{closeButton && !inline && (
|
||||
<div className="navds-alert__button-wrapper">
|
||||
<Button
|
||||
className="navds-alert__button"
|
||||
size="small"
|
||||
variant="tertiary-neutral"
|
||||
onClick={onClose}
|
||||
icon={<XMarkIcon title="Lukk Alert" />}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default Alert;
|
||||
@@ -2,6 +2,8 @@ import type { Meta, StoryObj } from "@storybook/react";
|
||||
import React from "react";
|
||||
import { Alert } from ".";
|
||||
import { BodyLong, Heading as DsHeading, Link } from "..";
|
||||
import { within, userEvent } from "@storybook/testing-library";
|
||||
import { expect } from "@storybook/jest";
|
||||
|
||||
const meta: Meta<typeof Alert> = {
|
||||
title: "ds-react/Alert",
|
||||
@@ -20,22 +22,14 @@ const variants: Array<"error" | "warning" | "info" | "success"> = [
|
||||
];
|
||||
|
||||
export const Default: Story = {
|
||||
render: (props) => (
|
||||
<Alert
|
||||
variant={props.variant}
|
||||
size={props.size}
|
||||
fullWidth={props.fullWidth}
|
||||
inline={props.inline}
|
||||
>
|
||||
{props.children}
|
||||
</Alert>
|
||||
),
|
||||
render: (props) => <Alert {...props} />,
|
||||
|
||||
args: {
|
||||
children: "Id elit esse enim reprehenderit enim nisi veniam nostrud.",
|
||||
fullWidth: false,
|
||||
variant: "info",
|
||||
size: "medium",
|
||||
closeButton: false,
|
||||
},
|
||||
argTypes: {
|
||||
variant: {
|
||||
@@ -50,21 +44,39 @@ export const Default: Story = {
|
||||
},
|
||||
options: ["medium", "small"],
|
||||
},
|
||||
closeButton: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const Small = () => {
|
||||
return (
|
||||
<div className="colgap">
|
||||
{variants.map((variant, i) => (
|
||||
<Alert key={variant} variant={variant} size="small">
|
||||
{new Array(i + 1).fill(
|
||||
"Id elit esse enim reprehenderit enim nisi veniam nostrud."
|
||||
)}
|
||||
</Alert>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
export const Small = {
|
||||
render: (props) => {
|
||||
return (
|
||||
<div className="colgap">
|
||||
{variants.map((variant, i) => (
|
||||
<Alert
|
||||
key={variant}
|
||||
variant={variant}
|
||||
size="small"
|
||||
closeButton={props.closeButton}
|
||||
>
|
||||
{new Array(i + 1).fill(
|
||||
"Id elit esse enim reprehenderit enim nisi veniam nostrud."
|
||||
)}
|
||||
</Alert>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
args: {
|
||||
closeButton: false,
|
||||
},
|
||||
argtypes: {
|
||||
closeButton: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const FullWidth = () => {
|
||||
@@ -147,3 +159,54 @@ export const Links = () => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const AlertWithCloseButton = ({ children }: { children?: React.ReactNode }) => {
|
||||
let [show, setShow] = React.useState(true);
|
||||
|
||||
return (
|
||||
show && (
|
||||
<Alert variant="success" closeButton onClose={() => setShow(false)}>
|
||||
{children || "Content"}
|
||||
</Alert>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
export const WithCloseButton: Story = {
|
||||
render: () => {
|
||||
return (
|
||||
<div className="colgap">
|
||||
<AlertWithCloseButton />
|
||||
<AlertWithCloseButton>
|
||||
<BodyLong>
|
||||
Ullamco ullamco laborum et commodo sint culpa cupidatat culpa qui
|
||||
laboris ex. Labore ex occaecat proident qui qui fugiat magna. Fugiat
|
||||
sint commodo consequat eu aute.
|
||||
</BodyLong>
|
||||
<Link href="#">Id elit esse enim reprehenderit</Link>
|
||||
</AlertWithCloseButton>
|
||||
<AlertWithCloseButton>
|
||||
<DsHeading spacing size="small" level="3">
|
||||
Aliquip duis est in commodo pariatur
|
||||
</DsHeading>
|
||||
<BodyLong>
|
||||
Ullamco ullamco laborum et commodo sint culpa cupidatat culpa qui
|
||||
laboris ex. Labore ex occaecat proident qui qui fugiat magna. Fugiat
|
||||
sint commodo consequat eu aute.
|
||||
</BodyLong>
|
||||
</AlertWithCloseButton>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
play: async ({ canvasElement, step }) => {
|
||||
const canvas = within(canvasElement);
|
||||
const buttons = canvas.getAllByTitle("Lukk Alert");
|
||||
|
||||
await step("click button", async () => {
|
||||
await userEvent.click(buttons[0]);
|
||||
});
|
||||
|
||||
const buttonsAfter = canvas.getAllByTitle("Lukk Alert");
|
||||
expect(buttonsAfter.length).toBe(2);
|
||||
},
|
||||
};
|
||||
@@ -126,11 +126,7 @@ export const Button: OverridableComponent<ButtonProps, HTMLButtonElement> =
|
||||
<span className="navds-button__icon">{icon}</span>
|
||||
)}
|
||||
{children && (
|
||||
<Label
|
||||
as="span"
|
||||
size={size === "medium" ? "medium" : "small"}
|
||||
aria-live="polite"
|
||||
>
|
||||
<Label as="span" size={size === "medium" ? "medium" : "small"}>
|
||||
{children}
|
||||
</Label>
|
||||
)}
|
||||
|
||||
@@ -148,8 +148,9 @@ export const Loading = {
|
||||
</div>
|
||||
),
|
||||
|
||||
args: { chromatic: { disableSnapshot: true } },
|
||||
chromatic: { disableSnapshot: true },
|
||||
parameters: {
|
||||
chromatic: { disableSnapshot: true },
|
||||
},
|
||||
};
|
||||
|
||||
export const Icon = () => (
|
||||
@@ -275,6 +276,7 @@ export const LoadingWithAs = {
|
||||
</div>
|
||||
),
|
||||
|
||||
args: { chromatic: { disableSnapshot: true } },
|
||||
chromatic: { disableSnapshot: true },
|
||||
parameters: {
|
||||
chromatic: { disableSnapshot: true },
|
||||
},
|
||||
};
|
||||
@@ -26,7 +26,7 @@ export interface ChatProps extends HTMLAttributes<HTMLDivElement> {
|
||||
/**
|
||||
* Changes background color on avatar and bubbles.
|
||||
* Avoid using the same background as the surface behind Chat.
|
||||
* @default "subtle"
|
||||
* @default "neutral"
|
||||
*/
|
||||
variant?: "subtle" | "info" | "neutral";
|
||||
/**
|
||||
@@ -92,7 +92,7 @@ export const Chat = forwardRef<HTMLDivElement, ChatProps>(
|
||||
timestamp,
|
||||
avatar,
|
||||
position = "left",
|
||||
variant = "subtle",
|
||||
variant = "neutral",
|
||||
avatarBgColor,
|
||||
backgroundColor,
|
||||
toptextPosition,
|
||||
|
||||
@@ -70,7 +70,7 @@ export const Chips: ChipsComponent = forwardRef<HTMLUListElement, ChipsProps>(
|
||||
})}
|
||||
>
|
||||
{React.Children.map(children, (chip, index) => {
|
||||
return <li key={index + (chip?.toString() ?? "")}>{chip}</li>;
|
||||
return <li key={chip?.toString() || index}>{chip}</li>;
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { XMarkIcon } from "@navikt/aksel-icons";
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef } from "react";
|
||||
import { OverridableComponent } from "../util/OverridableComponent";
|
||||
|
||||
export interface RemovableChipsProps
|
||||
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
@@ -22,26 +21,27 @@ export interface RemovableChipsProps
|
||||
onDelete?: () => void;
|
||||
}
|
||||
|
||||
export const RemovableChips: OverridableComponent<
|
||||
RemovableChipsProps,
|
||||
HTMLButtonElement
|
||||
> = forwardRef(
|
||||
export const RemovableChips = forwardRef<
|
||||
HTMLButtonElement,
|
||||
RemovableChipsProps
|
||||
>(
|
||||
(
|
||||
{
|
||||
className,
|
||||
children,
|
||||
variant = "action",
|
||||
as: Component = "button",
|
||||
removeLabel = "slett",
|
||||
onDelete,
|
||||
type = "button",
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
return (
|
||||
<Component
|
||||
<button
|
||||
{...rest}
|
||||
ref={ref}
|
||||
type={type}
|
||||
className={cl(
|
||||
"navds-chips__chip navds-chips__removable navds-chips--icon-right",
|
||||
className,
|
||||
@@ -57,7 +57,7 @@ export const RemovableChips: OverridableComponent<
|
||||
<span className="navds-chips__removable-icon">
|
||||
<XMarkIcon aria-hidden />
|
||||
</span>
|
||||
</Component>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -63,6 +63,11 @@ export interface CopyButtonProps
|
||||
* @default 'Kopiert'
|
||||
*/
|
||||
activeTitle?: string;
|
||||
/**
|
||||
* Icon position in Button
|
||||
* @default "left"
|
||||
*/
|
||||
iconPosition?: "left" | "right";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,6 +96,7 @@ export const CopyButton = forwardRef<HTMLButtonElement, CopyButtonProps>(
|
||||
activeDuration = 2000,
|
||||
title = "Kopier",
|
||||
activeTitle = "Kopiert",
|
||||
iconPosition = "left",
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
@@ -119,6 +125,25 @@ export const CopyButton = forwardRef<HTMLButtonElement, CopyButtonProps>(
|
||||
}, activeDuration);
|
||||
};
|
||||
|
||||
const CopyIcon = () => {
|
||||
return active ? (
|
||||
<span className="navds-copybutton__icon">
|
||||
{activeIcon ?? (
|
||||
<CheckmarkIcon
|
||||
aria-hidden={!!text}
|
||||
title={text ? undefined : activeTitle}
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
) : (
|
||||
<span className="navds-copybutton__icon">
|
||||
{icon ?? (
|
||||
<FilesIcon aria-hidden={!!text} title={text ? undefined : title} />
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
ref={ref}
|
||||
@@ -138,25 +163,7 @@ export const CopyButton = forwardRef<HTMLButtonElement, CopyButtonProps>(
|
||||
onClick={handleClick}
|
||||
>
|
||||
<span className="navds-copybutton__content">
|
||||
{active ? (
|
||||
<span className="navds-copybutton__icon">
|
||||
{activeIcon ?? (
|
||||
<CheckmarkIcon
|
||||
aria-hidden={!!text}
|
||||
title={text ? undefined : activeTitle}
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
) : (
|
||||
<span className="navds-copybutton__icon">
|
||||
{icon ?? (
|
||||
<FilesIcon
|
||||
aria-hidden={!!text}
|
||||
title={text ? undefined : title}
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
{iconPosition === "left" && <CopyIcon />}
|
||||
|
||||
{text &&
|
||||
(active ? (
|
||||
@@ -176,6 +183,7 @@ export const CopyButton = forwardRef<HTMLButtonElement, CopyButtonProps>(
|
||||
{text}
|
||||
</Label>
|
||||
))}
|
||||
{iconPosition === "right" && <CopyIcon />}
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -60,6 +60,16 @@ export const Variants = {
|
||||
),
|
||||
};
|
||||
|
||||
export const IconPosition = {
|
||||
render: () => (
|
||||
<div className="colgap">
|
||||
<CopyButton copyText="3.14" iconPosition="left" text="Kopier" />
|
||||
|
||||
<CopyButton copyText="3.14" iconPosition="right" text="Kopier" />
|
||||
</div>
|
||||
),
|
||||
};
|
||||
|
||||
export const Sizes = {
|
||||
render: () => (
|
||||
<div className="colgap">
|
||||
|
||||
@@ -4,6 +4,7 @@ import React, { forwardRef, InputHTMLAttributes } from "react";
|
||||
import { BodyShort, ErrorMessage, Label, omit } from "..";
|
||||
import { FormFieldProps, useFormField } from "../form/useFormField";
|
||||
import { useDateInputContext } from "./context";
|
||||
import { ReadOnlyIcon } from "../form/ReadOnlyIcon";
|
||||
|
||||
export interface DateInputProps
|
||||
extends FormFieldProps,
|
||||
@@ -57,6 +58,7 @@ const DateInput = forwardRef<HTMLInputElement, DateInputProps>((props, ref) => {
|
||||
errorId,
|
||||
showErrorMsg,
|
||||
hasError,
|
||||
readOnly,
|
||||
} = useFormField(props, conditionalVariables.prefix);
|
||||
|
||||
return (
|
||||
@@ -71,6 +73,9 @@ const DateInput = forwardRef<HTMLInputElement, DateInputProps>((props, ref) => {
|
||||
"navds-date__field--error": hasError,
|
||||
"navds-form-field--disabled": !!inputProps.disabled,
|
||||
"navds-text-field--disabled": !!inputProps.disabled,
|
||||
"navds-form-field--readonly": readOnly,
|
||||
"navds-text-field--readonly": readOnly,
|
||||
"navds-date__field--readonly": readOnly,
|
||||
}
|
||||
)}
|
||||
>
|
||||
@@ -81,6 +86,7 @@ const DateInput = forwardRef<HTMLInputElement, DateInputProps>((props, ref) => {
|
||||
"navds-sr-only": hideLabel,
|
||||
})}
|
||||
>
|
||||
<ReadOnlyIcon readOnly={readOnly} />
|
||||
{label}
|
||||
</Label>
|
||||
{!!description && (
|
||||
@@ -102,6 +108,7 @@ const DateInput = forwardRef<HTMLInputElement, DateInputProps>((props, ref) => {
|
||||
{...inputProps}
|
||||
autoComplete="off"
|
||||
aria-controls={ariaId}
|
||||
readOnly={readOnly}
|
||||
className={cl(
|
||||
"navds-date__field-input",
|
||||
"navds-text-field__input",
|
||||
@@ -111,8 +118,8 @@ const DateInput = forwardRef<HTMLInputElement, DateInputProps>((props, ref) => {
|
||||
size={14}
|
||||
/>
|
||||
<button
|
||||
disabled={inputProps.disabled}
|
||||
tabIndex={open ? -1 : 0}
|
||||
disabled={inputProps.disabled || readOnly}
|
||||
tabIndex={readOnly ? -1 : open ? -1 : 0}
|
||||
onClick={() => onOpen()}
|
||||
type="button"
|
||||
className="navds-date__field-button"
|
||||
|
||||
@@ -109,9 +109,9 @@ export interface DatePickerDefaultProps
|
||||
onOpenToggle?: () => void;
|
||||
/**
|
||||
* Avoid using if possible!
|
||||
* Changes what CSS position property to use
|
||||
* Changes what CSS position property to use.
|
||||
* You want to use "fixed" if parent wrapper has position relative, but you want popover to escape
|
||||
* @default "absolute"
|
||||
* @default See Popover
|
||||
*/
|
||||
strategy?: "absolute" | "fixed";
|
||||
/**
|
||||
@@ -184,7 +184,7 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
|
||||
open: _open,
|
||||
onClose,
|
||||
onOpenToggle,
|
||||
strategy = "absolute",
|
||||
strategy,
|
||||
bubbleEscape = false,
|
||||
...rest
|
||||
},
|
||||
@@ -257,6 +257,7 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
|
||||
role="dialog"
|
||||
ref={ref}
|
||||
strategy={strategy}
|
||||
className="navds-date__popover"
|
||||
bubbleEscape={bubbleEscape}
|
||||
>
|
||||
<DayPicker
|
||||
|
||||
@@ -341,3 +341,25 @@ export const Size = () => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const Readonly = () => {
|
||||
const { datepickerProps, inputProps } = useDatepicker({
|
||||
fromDate: new Date("Aug 23 2019"),
|
||||
toDate: new Date("Feb 23 2024"),
|
||||
onDateChange: console.log,
|
||||
});
|
||||
|
||||
return (
|
||||
<div style={{ display: "flex", gap: "1rem" }}>
|
||||
<DatePicker {...datepickerProps} dropdownCaption>
|
||||
<DatePicker.Input
|
||||
size="medium"
|
||||
{...inputProps}
|
||||
value="01.02.2021"
|
||||
label="Velg dato"
|
||||
readOnly
|
||||
/>
|
||||
</DatePicker>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -166,8 +166,7 @@ export const useDatepicker = (
|
||||
const handleOpen = useCallback(
|
||||
(open: boolean) => {
|
||||
setOpen(open);
|
||||
!open &&
|
||||
setMonth(selectedDay ?? defaultSelected ?? defaultMonth ?? today);
|
||||
open && setMonth(selectedDay ?? defaultSelected ?? defaultMonth ?? today);
|
||||
},
|
||||
[defaultMonth, defaultSelected, selectedDay, today]
|
||||
);
|
||||
@@ -204,6 +203,9 @@ export const useDatepicker = (
|
||||
};
|
||||
|
||||
const handleFocus: React.FocusEventHandler<HTMLInputElement> = (e) => {
|
||||
if (e.target.readOnly) {
|
||||
return;
|
||||
}
|
||||
!open && openOnFocus && handleOpen(true);
|
||||
let day = parseDate(
|
||||
e.target.value,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useCallback, useEffect } from "react";
|
||||
import { useCallback, useEffect, RefObject } from "react";
|
||||
|
||||
export const useEscape = (
|
||||
open: boolean,
|
||||
setOpen: (openState: boolean) => void,
|
||||
focusRef: any
|
||||
focusRef: RefObject<HTMLElement>
|
||||
) => {
|
||||
const handleClose = useCallback(() => {
|
||||
setOpen(false);
|
||||
@@ -11,7 +11,12 @@ export const useEscape = (
|
||||
}, [focusRef, setOpen]);
|
||||
|
||||
const escape = useCallback(
|
||||
(e) => open && e.key === "Escape" && handleClose(),
|
||||
(event: KeyboardEvent) => {
|
||||
if (open && event.key === "Escape") {
|
||||
event.preventDefault(); // This prevents modal from closing when using datepicker inside modal
|
||||
handleClose();
|
||||
}
|
||||
},
|
||||
[handleClose, open]
|
||||
);
|
||||
|
||||
|
||||
@@ -163,8 +163,7 @@ export const useMonthpicker = (
|
||||
const handleOpen = useCallback(
|
||||
(open: boolean) => {
|
||||
setOpen(open);
|
||||
!open &&
|
||||
setYear(selectedMonth ?? defaultSelected ?? defaultYear ?? today);
|
||||
open && setYear(selectedMonth ?? defaultSelected ?? defaultYear ?? today);
|
||||
},
|
||||
[defaultSelected, defaultYear, selectedMonth, today]
|
||||
);
|
||||
@@ -201,6 +200,9 @@ export const useMonthpicker = (
|
||||
};
|
||||
|
||||
const handleFocus: React.FocusEventHandler<HTMLInputElement> = (e) => {
|
||||
if (e.target.readOnly) {
|
||||
return;
|
||||
}
|
||||
!open && openOnFocus && handleOpen(true);
|
||||
let day = parseDate(
|
||||
e.target.value,
|
||||
|
||||
@@ -321,6 +321,9 @@ export const useRangeDatepicker = (
|
||||
};
|
||||
|
||||
const handleFocus = (e, src: RangeT) => {
|
||||
if (e.target.readOnly) {
|
||||
return;
|
||||
}
|
||||
!open && openOnFocus && setOpen(true);
|
||||
let day = parseDate(
|
||||
e.target.value,
|
||||
|
||||
@@ -208,7 +208,7 @@ export const MonthPicker = forwardRef<HTMLDivElement, MonthPickerProps>(
|
||||
role="dialog"
|
||||
ref={ref}
|
||||
id={ariaId}
|
||||
className="navds-date"
|
||||
className="navds-date navds-date__popover"
|
||||
strategy={strategy}
|
||||
bubbleEscape={bubbleEscape}
|
||||
>
|
||||
|
||||
File renamed without changes.
File renamed without changes.
@@ -1,8 +1,8 @@
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef } from "react";
|
||||
import { OverridableComponent } from "../../../util/OverridableComponent";
|
||||
import GroupedHeading, { GroupedHeadingProps } from "./Heading";
|
||||
import GroupedItem, { GroupedItemProps } from "./Item";
|
||||
import GroupedHeading, { GroupedHeadingProps } from "./GroupedHeading";
|
||||
import GroupedItem, { GroupedItemProps } from "./GroupedItem";
|
||||
|
||||
export interface GroupedListProps
|
||||
extends React.HTMLAttributes<HTMLDListElement> {
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useFormField } from "./useFormField";
|
||||
export interface ConfirmationPanelProps
|
||||
extends Omit<
|
||||
CheckboxProps,
|
||||
"children" | "indeterminate" | "hideLabel" | "error"
|
||||
"children" | "indeterminate" | "hideLabel" | "error" | "readOnly"
|
||||
> {
|
||||
/**
|
||||
* Additional information on panel
|
||||
@@ -88,12 +88,7 @@ export const ConfirmationPanel = forwardRef<
|
||||
{label}
|
||||
</Checkbox>
|
||||
</div>
|
||||
<div
|
||||
className="navds-form-field__error"
|
||||
id={errorId}
|
||||
aria-relevant="additions removals"
|
||||
aria-live="polite"
|
||||
>
|
||||
<div className="navds-form-field__error" id={errorId} role="alert">
|
||||
{showErrorMsg && <ErrorMessage size={size}>{props.error}</ErrorMessage>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@ import React, { FieldsetHTMLAttributes, forwardRef, useContext } from "react";
|
||||
import { BodyShort, ErrorMessage, Label, omit } from "../..";
|
||||
import { FormFieldProps } from "../useFormField";
|
||||
import { useFieldset } from "./useFieldset";
|
||||
import { ReadOnlyIcon } from "../ReadOnlyIcon";
|
||||
|
||||
export type FieldsetContextProps = {
|
||||
/**
|
||||
@@ -21,6 +22,10 @@ export type FieldsetContextProps = {
|
||||
* Sets fieldset and all form-children to disabled
|
||||
*/
|
||||
disabled: boolean;
|
||||
/**
|
||||
* Read only-state
|
||||
*/
|
||||
readOnly?: boolean;
|
||||
};
|
||||
|
||||
export const FieldsetContext = React.createContext<FieldsetContextProps | null>(
|
||||
@@ -47,6 +52,7 @@ export interface FieldsetProps
|
||||
* @default true
|
||||
*/
|
||||
errorPropagation?: boolean;
|
||||
nativeReadOnly?: boolean;
|
||||
}
|
||||
|
||||
export const Fieldset = forwardRef<HTMLFieldSetElement, FieldsetProps>(
|
||||
@@ -57,6 +63,7 @@ export const Fieldset = forwardRef<HTMLFieldSetElement, FieldsetProps>(
|
||||
showErrorMsg,
|
||||
hasError,
|
||||
size,
|
||||
readOnly,
|
||||
inputDescriptionId,
|
||||
} = useFieldset(props);
|
||||
|
||||
@@ -69,6 +76,7 @@ export const Fieldset = forwardRef<HTMLFieldSetElement, FieldsetProps>(
|
||||
legend,
|
||||
description,
|
||||
hideLegend,
|
||||
nativeReadOnly = true,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
@@ -82,17 +90,21 @@ export const Fieldset = forwardRef<HTMLFieldSetElement, FieldsetProps>(
|
||||
}),
|
||||
size,
|
||||
disabled: props.disabled ?? false,
|
||||
readOnly,
|
||||
}}
|
||||
>
|
||||
<fieldset
|
||||
{...omit(rest, ["errorId", "error", "size"])}
|
||||
{...omit(rest, ["errorId", "error", "size", "readOnly"])}
|
||||
{...inputProps}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
className,
|
||||
"navds-fieldset",
|
||||
`navds-fieldset--${size}`,
|
||||
{ "navds-fieldset--error": hasError }
|
||||
{
|
||||
"navds-fieldset--error": hasError,
|
||||
"navds-fieldset--readonly": readOnly,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<Label
|
||||
@@ -102,6 +114,7 @@ export const Fieldset = forwardRef<HTMLFieldSetElement, FieldsetProps>(
|
||||
"navds-sr-only": !!hideLegend,
|
||||
})}
|
||||
>
|
||||
<ReadOnlyIcon readOnly={readOnly} nativeReadOnly={nativeReadOnly} />
|
||||
{legend}
|
||||
</Label>
|
||||
{!!description && (
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { PadlockLockedFillIcon } from "@navikt/aksel-icons";
|
||||
import React from "react";
|
||||
|
||||
export const ReadOnlyIcon = ({
|
||||
readOnly,
|
||||
nativeReadOnly = true,
|
||||
}: {
|
||||
readOnly?: boolean;
|
||||
nativeReadOnly?: boolean;
|
||||
}) => {
|
||||
if (readOnly) {
|
||||
return (
|
||||
<PadlockLockedFillIcon
|
||||
{...(nativeReadOnly ? { "aria-hidden": true } : { title: "readonly" })}
|
||||
className="navds-form-field__readonly-icon"
|
||||
/>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
@@ -4,6 +4,7 @@ import React, { forwardRef, SelectHTMLAttributes } from "react";
|
||||
import { ChevronDownIcon } from "@navikt/aksel-icons";
|
||||
import { BodyShort, ErrorMessage, Label, omit } from "..";
|
||||
import { FormFieldProps, useFormField } from "./useFormField";
|
||||
import { ReadOnlyIcon } from "./ReadOnlyIcon";
|
||||
|
||||
export interface SelectProps
|
||||
extends FormFieldProps,
|
||||
@@ -55,7 +56,8 @@ export const Select = forwardRef<HTMLSelectElement, SelectProps>(
|
||||
hasError,
|
||||
size,
|
||||
inputDescriptionId,
|
||||
} = useFormField(props, "textField");
|
||||
readOnly,
|
||||
} = useFormField(props, "select");
|
||||
|
||||
const {
|
||||
children,
|
||||
@@ -68,6 +70,27 @@ export const Select = forwardRef<HTMLSelectElement, SelectProps>(
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
const readOnlyEventHandlers = {
|
||||
onMouseDown: (evt) => {
|
||||
// NOTE: does not prevent click
|
||||
if (readOnly) {
|
||||
evt.preventDefault();
|
||||
// focus on the element as per readonly input behavior
|
||||
evt.target.focus();
|
||||
}
|
||||
},
|
||||
onKeyDown: (evt) => {
|
||||
if (
|
||||
readOnly &&
|
||||
["ArrowDown", "ArrowUp", "ArrowRight", "ArrowLeft", " "].includes(
|
||||
evt.key
|
||||
)
|
||||
) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cl(
|
||||
@@ -76,7 +99,9 @@ export const Select = forwardRef<HTMLSelectElement, SelectProps>(
|
||||
`navds-form-field--${size}`,
|
||||
{
|
||||
"navds-form-field--disabled": !!inputProps.disabled,
|
||||
"navds-form-field--readonly": readOnly,
|
||||
"navds-select--error": hasError,
|
||||
"navds-select--readonly": readOnly,
|
||||
}
|
||||
)}
|
||||
>
|
||||
@@ -87,6 +112,7 @@ export const Select = forwardRef<HTMLSelectElement, SelectProps>(
|
||||
"navds-sr-only": hideLabel,
|
||||
})}
|
||||
>
|
||||
<ReadOnlyIcon readOnly={readOnly} nativeReadOnly={false} />
|
||||
{label}
|
||||
</Label>
|
||||
{!!description && (
|
||||
@@ -103,8 +129,9 @@ export const Select = forwardRef<HTMLSelectElement, SelectProps>(
|
||||
)}
|
||||
<div className="navds-select__container" style={style}>
|
||||
<select
|
||||
{...omit(rest, ["error", "errorId", "size"])}
|
||||
{...omit(rest, ["error", "errorId", "size", "readOnly"])}
|
||||
{...inputProps}
|
||||
{...readOnlyEventHandlers}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
"navds-select__input",
|
||||
|
||||
@@ -7,6 +7,7 @@ import React, {
|
||||
} from "react";
|
||||
import { BodyShort, Loader, omit } from "..";
|
||||
import { FormFieldProps, useFormField } from "./useFormField";
|
||||
import { ReadOnlyIcon } from "./ReadOnlyIcon";
|
||||
|
||||
const SelectedIcon = () => (
|
||||
<svg
|
||||
@@ -63,12 +64,12 @@ export interface SwitchProps
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Switch>Slå på notifikasjoner</Switch>
|
||||
* <Switch>Varsle med SMS</Switch>
|
||||
* ```
|
||||
*/
|
||||
export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
|
||||
(props, ref) => {
|
||||
const { inputProps, size } = useFormField(props, "switch");
|
||||
const { inputProps, size, readOnly } = useFormField(props, "switch");
|
||||
|
||||
const {
|
||||
children,
|
||||
@@ -90,11 +91,6 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
|
||||
checkedProp !== undefined && setChecked(checkedProp);
|
||||
}, [checkedProp]);
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setChecked(e.target.checked);
|
||||
props.onChange && props.onChange(e);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cl(
|
||||
@@ -105,18 +101,32 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
|
||||
{
|
||||
"navds-switch--loading": loading,
|
||||
"navds-switch--disabled": inputProps.disabled ?? loading,
|
||||
"navds-switch--readonly": readOnly,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<input
|
||||
{...omit(rest, ["size"])}
|
||||
{...omit(rest, ["size", "readOnly"])}
|
||||
{...omit(inputProps, ["aria-invalid", "aria-describedby"])}
|
||||
disabled={inputProps.disabled ?? loading}
|
||||
checked={checkedProp}
|
||||
defaultChecked={defaultChecked}
|
||||
ref={ref}
|
||||
type="checkbox"
|
||||
onChange={(e) => handleChange(e)}
|
||||
onChange={(e) => {
|
||||
if (readOnly) {
|
||||
return;
|
||||
}
|
||||
setChecked(e.target.checked);
|
||||
props.onChange && props.onChange(e);
|
||||
}}
|
||||
onClick={(e) => {
|
||||
if (readOnly) {
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
props?.onClick?.(e);
|
||||
}}
|
||||
className={cl(className, "navds-switch__input")}
|
||||
/>
|
||||
<span className="navds-switch__track">
|
||||
@@ -136,6 +146,7 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
|
||||
})}
|
||||
>
|
||||
<BodyShort as="div" size={size} className="navds-switch__label">
|
||||
<ReadOnlyIcon readOnly={readOnly} nativeReadOnly={false} />
|
||||
{children}
|
||||
</BodyShort>
|
||||
{description && (
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef, InputHTMLAttributes } from "react";
|
||||
import { BodyShort, ErrorMessage, Label, omit } from "..";
|
||||
import { ReadOnlyIcon } from "./ReadOnlyIcon";
|
||||
import { FormFieldProps, useFormField } from "./useFormField";
|
||||
|
||||
export interface TextFieldProps
|
||||
@@ -30,7 +31,7 @@ export interface TextFieldProps
|
||||
* Type of form control. Picking the correct type helps user fill inn their required information
|
||||
* @default "text"
|
||||
*/
|
||||
type?: "email" | "number" | "password" | "tel" | "text" | "url";
|
||||
type?: "email" | "number" | "password" | "tel" | "text" | "url" | "time";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,6 +63,7 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
||||
htmlSize,
|
||||
hideLabel = false,
|
||||
type = "text",
|
||||
readOnly,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
@@ -71,10 +73,13 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
||||
className,
|
||||
"navds-form-field",
|
||||
`navds-form-field--${size}`,
|
||||
|
||||
{
|
||||
"navds-text-field--error": hasError,
|
||||
"navds-text-field--disabled": !!inputProps.disabled,
|
||||
"navds-form-field--disabled": !!inputProps.disabled,
|
||||
"navds-form-field--readonly": readOnly,
|
||||
"navds-text-field--readonly": readOnly,
|
||||
}
|
||||
)}
|
||||
>
|
||||
@@ -85,6 +90,7 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
||||
"navds-sr-only": hideLabel,
|
||||
})}
|
||||
>
|
||||
<ReadOnlyIcon readOnly={readOnly} />
|
||||
{label}
|
||||
</Label>
|
||||
|
||||
@@ -105,6 +111,7 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
||||
{...inputProps}
|
||||
ref={ref}
|
||||
type={type}
|
||||
readOnly={readOnly}
|
||||
className={cl(
|
||||
"navds-text-field__input",
|
||||
"navds-body-short",
|
||||
|
||||
@@ -3,6 +3,7 @@ import React, { forwardRef, useState } from "react";
|
||||
import { BodyShort, ErrorMessage, Label, omit, useId } from "..";
|
||||
import TextareaAutosize from "../util/TextareaAutoSize";
|
||||
import { FormFieldProps, useFormField } from "./useFormField";
|
||||
import { ReadOnlyIcon } from "./ReadOnlyIcon";
|
||||
|
||||
/**
|
||||
* TODO: Mulighet for lokalisering av sr-only/counter text
|
||||
@@ -85,6 +86,7 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
|
||||
hideLabel = false,
|
||||
resize,
|
||||
i18n,
|
||||
readOnly,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
@@ -115,6 +117,8 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
|
||||
`navds-form-field--${size}`,
|
||||
{
|
||||
"navds-form-field--disabled": !!inputProps.disabled,
|
||||
"navds-form-field--readonly": readOnly,
|
||||
"navds-textarea--readonly": readOnly,
|
||||
"navds-textarea--error": hasError,
|
||||
"navds-textarea--resize": resize,
|
||||
}
|
||||
@@ -127,6 +131,7 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
|
||||
"navds-sr-only": hideLabel,
|
||||
})}
|
||||
>
|
||||
<ReadOnlyIcon readOnly={readOnly} />
|
||||
{label}
|
||||
</Label>
|
||||
{!!description && (
|
||||
@@ -152,6 +157,7 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
|
||||
}
|
||||
minRows={getMinRows()}
|
||||
ref={ref}
|
||||
readOnly={readOnly}
|
||||
className={cl(
|
||||
"navds-textarea__input",
|
||||
"navds-body-short",
|
||||
@@ -203,8 +209,8 @@ export const Counter = ({ maxLength, currentLength, size, i18n }) => {
|
||||
size={size}
|
||||
>
|
||||
{difference < 0
|
||||
? `${Math.abs(difference)} ${i18n?.counterLeft ?? "tegn for mye"}`
|
||||
: `${difference} ${i18n?.counterTooMuch ?? "tegn igjen"}`}
|
||||
? `${Math.abs(difference)} ${i18n?.counterTooMuch ?? "tegn for mye"}`
|
||||
: `${difference} ${i18n?.counterLeft ?? "tegn igjen"}`}
|
||||
</BodyShort>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,6 +4,7 @@ import { BodyShort } from "../../typography";
|
||||
import { omit } from "../../util";
|
||||
import { FormFieldProps } from "../useFormField";
|
||||
import useCheckbox from "./useCheckbox";
|
||||
import { ReadOnlyIcon } from "../ReadOnlyIcon";
|
||||
|
||||
export interface CheckboxProps
|
||||
extends FormFieldProps,
|
||||
@@ -42,7 +43,7 @@ export interface CheckboxProps
|
||||
|
||||
export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
||||
(props, ref) => {
|
||||
const { inputProps, hasError, size } = useCheckbox(props);
|
||||
const { inputProps, hasError, size, readOnly, nested } = useCheckbox(props);
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -53,6 +54,7 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
||||
{
|
||||
"navds-checkbox--error": hasError,
|
||||
"navds-checkbox--disabled": inputProps.disabled,
|
||||
"navds-checkbox--readonly": readOnly,
|
||||
}
|
||||
)}
|
||||
>
|
||||
@@ -65,6 +67,7 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
||||
"hideLabel",
|
||||
"indeterminate",
|
||||
"errorId",
|
||||
"readOnly",
|
||||
])}
|
||||
{...inputProps}
|
||||
type="checkbox"
|
||||
@@ -83,12 +86,36 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
||||
}}
|
||||
/>
|
||||
<label htmlFor={inputProps.id} className="navds-checkbox__label">
|
||||
<span className="navds-checkbox__icon">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="13"
|
||||
height="10"
|
||||
viewBox="0 0 13 10"
|
||||
fill="none"
|
||||
focusable={false}
|
||||
role="img"
|
||||
aria-hidden
|
||||
>
|
||||
<path
|
||||
d="M4.03524 6.41478L10.4752 0.404669C11.0792 -0.160351 12.029 -0.130672 12.5955 0.47478C13.162 1.08027 13.1296 2.03007 12.5245 2.59621L5.02111 9.59934C4.74099 9.85904 4.37559 10 4.00025 10C3.60651 10 3.22717 9.84621 2.93914 9.56111L0.439143 7.06111C-0.146381 6.47558 -0.146381 5.52542 0.439143 4.93989C1.02467 4.35437 1.97483 4.35437 2.56036 4.93989L4.03524 6.41478Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
className={cl("navds-checkbox__content", {
|
||||
"navds-sr-only": props.hideLabel,
|
||||
})}
|
||||
>
|
||||
<BodyShort as="span" size={size}>
|
||||
<BodyShort
|
||||
as="span"
|
||||
size={size}
|
||||
className="navds-checkbox__label-text"
|
||||
>
|
||||
{!nested && (
|
||||
<ReadOnlyIcon readOnly={readOnly} nativeReadOnly={false} />
|
||||
)}
|
||||
{props.children}
|
||||
</BodyShort>
|
||||
{props.description && (
|
||||
|
||||
@@ -81,6 +81,7 @@ export const CheckboxGroup = forwardRef<
|
||||
"navds-checkbox-group",
|
||||
`navds-checkbox-group--${rest.size ?? fieldset?.size ?? "medium"}`
|
||||
)}
|
||||
nativeReadOnly={false}
|
||||
>
|
||||
<CheckboxGroupContext.Provider
|
||||
value={{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable react-hooks/rules-of-hooks */
|
||||
import { Meta } from "@storybook/react";
|
||||
import React, { useState } from "react";
|
||||
import { Checkbox, CheckboxGroup } from "../../index";
|
||||
import { Meta } from "@storybook/react";
|
||||
|
||||
export default {
|
||||
title: "ds-react/Checkbox",
|
||||
@@ -190,3 +190,37 @@ export const Indeterminate = () => {
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const Readonly = () => (
|
||||
<div className="colgap">
|
||||
<CheckboxGroup
|
||||
legend="Hvilken frukt liker du?"
|
||||
defaultValue={["banan"]}
|
||||
readOnly
|
||||
>
|
||||
<Checkbox value="banan">Banan</Checkbox>
|
||||
<Checkbox value="eple">Eple</Checkbox>
|
||||
<Checkbox value="druer" indeterminate>
|
||||
Druer
|
||||
</Checkbox>
|
||||
</CheckboxGroup>
|
||||
<CheckboxGroup
|
||||
legend="Hvilken frukt liker du?"
|
||||
error="feilmelding"
|
||||
defaultValue={["Eple"]}
|
||||
readOnly
|
||||
>
|
||||
<Checkbox value="eple" description="Epler kommer i 4 varianter">
|
||||
Eple
|
||||
</Checkbox>
|
||||
<Checkbox value="banan">Banan</Checkbox>
|
||||
</CheckboxGroup>
|
||||
<hr />
|
||||
<Checkbox value="tekst1" readOnly>
|
||||
Eple single
|
||||
</Checkbox>
|
||||
<Checkbox value="tekst1" checked readOnly>
|
||||
Banan single
|
||||
</Checkbox>
|
||||
</div>
|
||||
);
|
||||
@@ -10,7 +10,7 @@ import { omit } from "../..";
|
||||
const useCheckbox = ({ children, ...props }: CheckboxProps) => {
|
||||
const checkboxGroup = useContext(CheckboxGroupContext);
|
||||
|
||||
const { inputProps, ...rest } = useFormField(
|
||||
const { inputProps, readOnly, ...rest } = useFormField(
|
||||
omit(props, ["description"]),
|
||||
"checkbox"
|
||||
);
|
||||
@@ -30,6 +30,8 @@ const useCheckbox = ({ children, ...props }: CheckboxProps) => {
|
||||
|
||||
return {
|
||||
...rest,
|
||||
readOnly,
|
||||
nested: !!checkboxGroup,
|
||||
inputProps: {
|
||||
...inputProps,
|
||||
checked: checkboxGroup?.value
|
||||
@@ -39,9 +41,19 @@ const useCheckbox = ({ children, ...props }: CheckboxProps) => {
|
||||
? checkboxGroup.defaultValue.includes(props.value)
|
||||
: props.defaultChecked,
|
||||
onChange: (e) => {
|
||||
if (readOnly) {
|
||||
return;
|
||||
}
|
||||
props.onChange && props.onChange(e);
|
||||
checkboxGroup && checkboxGroup.toggleValue(props.value);
|
||||
},
|
||||
onClick: (e) => {
|
||||
if (readOnly) {
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
props?.onClick?.(e);
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import React from "react";
|
||||
import { XMarkIcon } from "@navikt/aksel-icons";
|
||||
|
||||
interface ClearButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
|
||||
handleClear: (event: any) => void;
|
||||
clearButtonLabel?: string;
|
||||
}
|
||||
|
||||
export const ClearButton: React.FC<ClearButtonProps> = ({
|
||||
handleClear,
|
||||
clearButtonLabel,
|
||||
...rest
|
||||
}) => {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleClear}
|
||||
className="navds-combobox__button-clear"
|
||||
{...rest}
|
||||
>
|
||||
<span className="navds-sr-only">
|
||||
{clearButtonLabel ? clearButtonLabel : "Tøm"}
|
||||
</span>
|
||||
<XMarkIcon aria-hidden />
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default ClearButton;
|
||||
@@ -0,0 +1,147 @@
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef, useMemo, useRef } from "react";
|
||||
import { BodyShort, ErrorMessage, Label, mergeRefs } from "../..";
|
||||
import ClearButton from "./ClearButton";
|
||||
import FilteredOptions from "./FilteredOptions/FilteredOptions";
|
||||
import { useFilteredOptionsContext } from "./FilteredOptions/filteredOptionsContext";
|
||||
import SelectedOptions from "./SelectedOptions/SelectedOptions";
|
||||
import ToggleListButton from "./ToggleListButton";
|
||||
import { ComboboxProps } from "./types";
|
||||
import { useSelectedOptionsContext } from "./SelectedOptions/selectedOptionsContext";
|
||||
import ComboboxWrapper from "./ComboboxWrapper";
|
||||
import { useInputContext } from "./Input/inputContext";
|
||||
import Input from "./Input/Input";
|
||||
|
||||
export const Combobox = forwardRef<
|
||||
HTMLInputElement,
|
||||
Omit<ComboboxProps, "onChange" | "options" | "size">
|
||||
>((props, ref) => {
|
||||
const {
|
||||
value: externalValue,
|
||||
onClear,
|
||||
className,
|
||||
hideLabel = false,
|
||||
description,
|
||||
label,
|
||||
clearButton = true,
|
||||
clearButtonLabel,
|
||||
toggleListButton = true,
|
||||
toggleListButtonLabel,
|
||||
inputClassName,
|
||||
shouldShowSelectedOptions = true,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
const toggleListButtonRef = useRef<HTMLButtonElement>(null);
|
||||
|
||||
const { currentOption, toggleIsListOpen } = useFilteredOptionsContext();
|
||||
const { selectedOptions } = useSelectedOptionsContext();
|
||||
|
||||
const {
|
||||
clearInput,
|
||||
error,
|
||||
errorId,
|
||||
focusInput,
|
||||
hasError,
|
||||
inputDescriptionId,
|
||||
inputProps,
|
||||
inputRef,
|
||||
value,
|
||||
showErrorMsg,
|
||||
size = "medium",
|
||||
} = useInputContext();
|
||||
|
||||
const mergedInputRef = useMemo(
|
||||
() => mergeRefs([inputRef, ref]),
|
||||
[inputRef, ref]
|
||||
);
|
||||
|
||||
return (
|
||||
<ComboboxWrapper
|
||||
className={className}
|
||||
hasError={hasError}
|
||||
inputProps={inputProps}
|
||||
inputSize={size}
|
||||
toggleIsListOpen={toggleIsListOpen}
|
||||
toggleListButtonRef={toggleListButtonRef}
|
||||
>
|
||||
<Label
|
||||
htmlFor={inputProps.id}
|
||||
size={size}
|
||||
className={cl("navds-form-field__label", {
|
||||
"navds-sr-only": hideLabel,
|
||||
})}
|
||||
>
|
||||
{label}
|
||||
</Label>
|
||||
{!!description && (
|
||||
<BodyShort
|
||||
as="div"
|
||||
className={cl("navds-form-field__description", {
|
||||
"navds-sr-only": hideLabel,
|
||||
})}
|
||||
id={inputDescriptionId}
|
||||
size={size}
|
||||
>
|
||||
{description}
|
||||
</BodyShort>
|
||||
)}
|
||||
<div className="navds-combobox__wrapper">
|
||||
<div
|
||||
className={cl(
|
||||
"navds-combobox__wrapper-inner navds-text-field__input",
|
||||
{
|
||||
"navds-combobox__wrapper-inner--virtually-unfocused":
|
||||
currentOption !== null,
|
||||
}
|
||||
)}
|
||||
onClick={focusInput}
|
||||
>
|
||||
{!shouldShowSelectedOptions ? (
|
||||
<Input
|
||||
id={inputProps.id}
|
||||
ref={mergedInputRef}
|
||||
inputClassName={inputClassName}
|
||||
{...rest}
|
||||
/>
|
||||
) : (
|
||||
<SelectedOptions selectedOptions={selectedOptions} size={size}>
|
||||
<Input
|
||||
id={inputProps.id}
|
||||
ref={mergedInputRef}
|
||||
inputClassName={inputClassName}
|
||||
{...rest}
|
||||
/>
|
||||
</SelectedOptions>
|
||||
)}
|
||||
<div>
|
||||
{value && clearButton && (
|
||||
<ClearButton
|
||||
handleClear={clearInput}
|
||||
clearButtonLabel={clearButtonLabel}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
)}
|
||||
{toggleListButton && (
|
||||
<ToggleListButton
|
||||
toggleListButtonLabel={toggleListButtonLabel}
|
||||
ref={toggleListButtonRef}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<FilteredOptions />
|
||||
</div>
|
||||
<div
|
||||
className="navds-form-field__error"
|
||||
id={errorId}
|
||||
aria-relevant="additions removals"
|
||||
aria-live="polite"
|
||||
>
|
||||
{showErrorMsg && <ErrorMessage size={size}>{error}</ErrorMessage>}
|
||||
</div>
|
||||
</ComboboxWrapper>
|
||||
);
|
||||
});
|
||||
|
||||
export default Combobox;
|
||||
@@ -0,0 +1,99 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import Combobox from "./Combobox";
|
||||
import { FilteredOptionsProvider } from "./FilteredOptions/filteredOptionsContext";
|
||||
import { CustomOptionsProvider } from "./customOptionsContext";
|
||||
import { SelectedOptionsProvider } from "./SelectedOptions/selectedOptionsContext";
|
||||
import { InputContextProvider } from "./Input/inputContext";
|
||||
import { ComboboxProps } from "./types";
|
||||
|
||||
/**
|
||||
* A component that allows the user to search in a list of options
|
||||
*
|
||||
* Has options for allowing only one or multiple options to be selected,
|
||||
* or adding new, user-submitted values.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/combobox)
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* const options = ["apple", "banana", "orange"];
|
||||
*
|
||||
* return (
|
||||
* <Combobox
|
||||
* label="Velg en verdi"
|
||||
* options={options}
|
||||
* id="my-combobox"
|
||||
* shouldAutoComplete
|
||||
* />
|
||||
* )
|
||||
* ```
|
||||
*/
|
||||
const ComboboxProvider = forwardRef<HTMLInputElement, ComboboxProps>(
|
||||
(props, ref) => {
|
||||
const {
|
||||
allowNewValues = false,
|
||||
children,
|
||||
defaultValue,
|
||||
error,
|
||||
errorId,
|
||||
filteredOptions,
|
||||
id,
|
||||
isListOpen,
|
||||
isLoading = false,
|
||||
isMultiSelect,
|
||||
onToggleSelected,
|
||||
selectedOptions,
|
||||
options,
|
||||
value,
|
||||
onChange,
|
||||
onClear,
|
||||
shouldAutocomplete,
|
||||
size,
|
||||
...rest
|
||||
} = props;
|
||||
return (
|
||||
<InputContextProvider
|
||||
value={{
|
||||
defaultValue,
|
||||
error,
|
||||
errorId,
|
||||
id,
|
||||
value,
|
||||
onChange,
|
||||
onClear,
|
||||
shouldAutocomplete,
|
||||
size,
|
||||
}}
|
||||
>
|
||||
<CustomOptionsProvider>
|
||||
<SelectedOptionsProvider
|
||||
value={{
|
||||
allowNewValues,
|
||||
isMultiSelect,
|
||||
selectedOptions,
|
||||
onToggleSelected,
|
||||
options,
|
||||
}}
|
||||
>
|
||||
<FilteredOptionsProvider
|
||||
value={{
|
||||
allowNewValues,
|
||||
filteredOptions,
|
||||
isListOpen,
|
||||
isLoading,
|
||||
isMultiSelect,
|
||||
options,
|
||||
}}
|
||||
>
|
||||
<Combobox ref={ref} {...rest}>
|
||||
{children}
|
||||
</Combobox>
|
||||
</FilteredOptionsProvider>
|
||||
</SelectedOptionsProvider>
|
||||
</CustomOptionsProvider>
|
||||
</InputContextProvider>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default ComboboxProvider;
|
||||
@@ -0,0 +1,67 @@
|
||||
import cl from "clsx";
|
||||
import React, { useRef, useState } from "react";
|
||||
|
||||
type ComboboxWrapperProps = {
|
||||
children: any;
|
||||
className?: string;
|
||||
hasError: boolean;
|
||||
inputProps: {
|
||||
disabled?: boolean;
|
||||
};
|
||||
inputSize: string;
|
||||
toggleIsListOpen: (isListOpen: boolean) => void;
|
||||
toggleListButtonRef: React.RefObject<HTMLButtonElement>;
|
||||
};
|
||||
|
||||
const ComboboxWrapper = ({
|
||||
children,
|
||||
className,
|
||||
hasError,
|
||||
inputProps,
|
||||
inputSize,
|
||||
toggleIsListOpen,
|
||||
toggleListButtonRef,
|
||||
}: ComboboxWrapperProps) => {
|
||||
const wrapperRef = useRef<HTMLDivElement | null>(null);
|
||||
const [hasFocusWithin, setHasFocusWithin] = useState(false);
|
||||
|
||||
function onFocusInsideWrapper(e) {
|
||||
if (
|
||||
!wrapperRef.current?.contains(e.relatedTarget) &&
|
||||
toggleListButtonRef?.current !== e.target
|
||||
) {
|
||||
toggleIsListOpen(true);
|
||||
setHasFocusWithin(true);
|
||||
}
|
||||
}
|
||||
|
||||
function onBlurWrapper(e) {
|
||||
if (!wrapperRef.current?.contains(e.relatedTarget)) {
|
||||
toggleIsListOpen(false);
|
||||
setHasFocusWithin(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={wrapperRef}
|
||||
className={cl(
|
||||
className,
|
||||
"navds-form-field",
|
||||
`navds-form-field--${inputSize}`,
|
||||
{
|
||||
"navds-combobox--error": hasError,
|
||||
"navds-combobox--disabled": !!inputProps.disabled,
|
||||
"navds-combobox--focused": hasFocusWithin,
|
||||
}
|
||||
)}
|
||||
onFocus={onFocusInsideWrapper}
|
||||
onBlur={onBlurWrapper}
|
||||
tabIndex={-1}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ComboboxWrapper;
|
||||
@@ -0,0 +1,23 @@
|
||||
import React from "react";
|
||||
|
||||
const CheckIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="13"
|
||||
viewBox="0 0 16 13"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
fill="#005B82"
|
||||
d="M14.2014 0L16 1.89047L4.77943 13L0 8.39552L1.79361 6.5L4.77418 9.3019L14.2014 0Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default CheckIcon;
|
||||
@@ -0,0 +1,109 @@
|
||||
import React from "react";
|
||||
import cl from "clsx";
|
||||
import { BodyShort, Label, Loader } from "../../..";
|
||||
import { CheckmarkIcon, PlusIcon } from "@navikt/aksel-icons";
|
||||
import { useFilteredOptionsContext } from "./filteredOptionsContext";
|
||||
import { useSelectedOptionsContext } from "../SelectedOptions/selectedOptionsContext";
|
||||
import { useInputContext } from "../Input/inputContext";
|
||||
|
||||
const FilteredOptions = () => {
|
||||
const {
|
||||
inputProps: { id },
|
||||
size,
|
||||
value,
|
||||
} = useInputContext();
|
||||
const {
|
||||
allowNewValues,
|
||||
isLoading,
|
||||
isListOpen,
|
||||
filteredOptions,
|
||||
filteredOptionsIndex,
|
||||
filteredOptionsRef,
|
||||
isValueNew,
|
||||
toggleIsListOpen,
|
||||
} = useFilteredOptionsContext();
|
||||
const { isMultiSelect, selectedOptions, toggleOption } =
|
||||
useSelectedOptionsContext();
|
||||
|
||||
return (
|
||||
<ul
|
||||
ref={filteredOptionsRef}
|
||||
className={cl("navds-combobox__list", {
|
||||
"navds-combobox__list--closed": !isListOpen,
|
||||
})}
|
||||
id={`${id}-filtered-options`}
|
||||
role="listbox"
|
||||
tabIndex={-1}
|
||||
>
|
||||
{isLoading && (
|
||||
<li
|
||||
className="navds-combobox__list-item--loading"
|
||||
role="option"
|
||||
aria-selected={false}
|
||||
id={`${id}-is-loading`}
|
||||
>
|
||||
<Loader aria-label="Søker..." />
|
||||
</li>
|
||||
)}
|
||||
{isValueNew && allowNewValues && (
|
||||
<li
|
||||
tabIndex={-1}
|
||||
onPointerUp={(event) => {
|
||||
toggleOption(value, event);
|
||||
if (!isMultiSelect && !selectedOptions.includes(value))
|
||||
toggleIsListOpen(false);
|
||||
}}
|
||||
id={`${id}-combobox-new-option`}
|
||||
className={cl("navds-combobox__list-item__new-option", {
|
||||
"navds-combobox__list-item__new-option--focus":
|
||||
filteredOptionsIndex === -1,
|
||||
})}
|
||||
role="option"
|
||||
aria-selected={false}
|
||||
>
|
||||
<PlusIcon aria-hidden />
|
||||
<BodyShort size={size}>
|
||||
Legg til{" "}
|
||||
<Label as="span" size={size}>
|
||||
“{value}”
|
||||
</Label>
|
||||
</BodyShort>
|
||||
</li>
|
||||
)}
|
||||
{!isLoading && filteredOptions.length === 0 && (
|
||||
<li
|
||||
className="navds-combobox__list-item__no-options"
|
||||
role="option"
|
||||
aria-selected={false}
|
||||
id={`${id}-no-hits`}
|
||||
>
|
||||
Ingen søketreff
|
||||
</li>
|
||||
)}
|
||||
{filteredOptions.map((option, index) => (
|
||||
<li
|
||||
className={cl("navds-combobox__list-item", {
|
||||
"navds-combobox__list-item--focus": index === filteredOptionsIndex,
|
||||
"navds-combobox__list-item--selected":
|
||||
selectedOptions.includes(option),
|
||||
})}
|
||||
id={`${id}-option-${option.replace(" ", "-")}`}
|
||||
key={option}
|
||||
tabIndex={-1}
|
||||
onPointerUp={(event) => {
|
||||
toggleOption(option, event);
|
||||
if (!isMultiSelect && !selectedOptions.includes(option))
|
||||
toggleIsListOpen(false);
|
||||
}}
|
||||
role="option"
|
||||
aria-selected={selectedOptions.includes(option)}
|
||||
>
|
||||
<BodyShort size={size}>{option}</BodyShort>
|
||||
{selectedOptions.includes(option) && <CheckmarkIcon />}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
|
||||
export default FilteredOptions;
|
||||
@@ -0,0 +1,275 @@
|
||||
import React, {
|
||||
useState,
|
||||
useEffect,
|
||||
useMemo,
|
||||
createContext,
|
||||
useContext,
|
||||
useCallback,
|
||||
useRef,
|
||||
useLayoutEffect,
|
||||
} from "react";
|
||||
import cl from "clsx";
|
||||
import { useCustomOptionsContext } from "../customOptionsContext";
|
||||
import { useInputContext } from "../Input/inputContext";
|
||||
import usePrevious from "../../../util/usePrevious";
|
||||
|
||||
const normalizeText = (text: string): string =>
|
||||
typeof text === "string" ? `${text}`.toLowerCase().trim() : "";
|
||||
|
||||
const isPartOfText = (value, text) =>
|
||||
normalizeText(text).startsWith(normalizeText(value ?? ""));
|
||||
|
||||
const isValueInList = (value, list) =>
|
||||
list?.find((listItem) => normalizeText(value) === normalizeText(listItem));
|
||||
|
||||
const getMatchingValuesFromList = (value, list) =>
|
||||
list?.filter((listItem) => isPartOfText(value, listItem));
|
||||
|
||||
type FilteredOptionsContextType = {
|
||||
activeDecendantId?: string;
|
||||
allowNewValues?: boolean;
|
||||
ariaDescribedBy?: string;
|
||||
filteredOptionsRef: React.RefObject<HTMLUListElement>;
|
||||
filteredOptionsIndex: number | null;
|
||||
setFilteredOptionsIndex: (index: number) => void;
|
||||
isListOpen: boolean;
|
||||
isLoading?: boolean;
|
||||
filteredOptions: string[];
|
||||
isValueNew: boolean;
|
||||
toggleIsListOpen: (newState?: boolean) => void;
|
||||
currentOption: string | null;
|
||||
resetFilteredOptionsIndex: () => void;
|
||||
moveFocusUp: () => void;
|
||||
moveFocusDown: () => void;
|
||||
moveFocusToInput: () => void;
|
||||
moveFocusToEnd: () => void;
|
||||
shouldAutocomplete?: boolean;
|
||||
};
|
||||
const FilteredOptionsContext = createContext<FilteredOptionsContextType>(
|
||||
{} as FilteredOptionsContextType
|
||||
);
|
||||
|
||||
export const FilteredOptionsProvider = ({ children, value: props }) => {
|
||||
const {
|
||||
allowNewValues,
|
||||
filteredOptions: externalFilteredOptions,
|
||||
isListOpen: isExternalListOpen,
|
||||
isLoading,
|
||||
options,
|
||||
} = props;
|
||||
const filteredOptionsRef = useRef<HTMLUListElement | null>(null);
|
||||
const {
|
||||
inputProps: { "aria-describedby": partialAriaDescribedBy, id },
|
||||
value,
|
||||
searchTerm,
|
||||
setValue,
|
||||
setSearchTerm,
|
||||
shouldAutocomplete,
|
||||
} = useInputContext();
|
||||
|
||||
const [filteredOptionsIndex, setFilteredOptionsIndex] = useState<
|
||||
number | null
|
||||
>(null);
|
||||
const [isInternalListOpen, setInternalListOpen] = useState(false);
|
||||
const { customOptions } = useCustomOptionsContext();
|
||||
|
||||
const filteredOptions = useMemo(() => {
|
||||
if (externalFilteredOptions) {
|
||||
return externalFilteredOptions;
|
||||
}
|
||||
const opts = [...customOptions, ...options];
|
||||
setFilteredOptionsIndex(null);
|
||||
return getMatchingValuesFromList(searchTerm, opts);
|
||||
}, [customOptions, externalFilteredOptions, options, searchTerm]);
|
||||
|
||||
const previousSearchTerm = usePrevious(searchTerm);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (
|
||||
shouldAutocomplete &&
|
||||
normalizeText(searchTerm) !== "" &&
|
||||
(previousSearchTerm?.length || 0) < searchTerm.length &&
|
||||
filteredOptions.length > 0 &&
|
||||
!isValueInList(searchTerm, filteredOptions)
|
||||
) {
|
||||
setValue(
|
||||
`${searchTerm}${filteredOptions[0].substring(searchTerm.length)}`
|
||||
);
|
||||
setSearchTerm(searchTerm);
|
||||
}
|
||||
}, [
|
||||
filteredOptions,
|
||||
previousSearchTerm,
|
||||
searchTerm,
|
||||
setSearchTerm,
|
||||
setValue,
|
||||
shouldAutocomplete,
|
||||
]);
|
||||
|
||||
const isListOpen = useMemo(() => {
|
||||
return isExternalListOpen ?? isInternalListOpen;
|
||||
}, [isExternalListOpen, isInternalListOpen]);
|
||||
|
||||
const toggleIsListOpen = useCallback((newState?: boolean) => {
|
||||
setFilteredOptionsIndex(null);
|
||||
setInternalListOpen((oldState) => newState ?? !oldState);
|
||||
}, []);
|
||||
|
||||
const isValueNew = useMemo(
|
||||
() => Boolean(value) && !isValueInList(value, filteredOptions),
|
||||
[value, filteredOptions]
|
||||
);
|
||||
|
||||
const getMinimumIndex = useCallback(() => {
|
||||
return isValueNew && allowNewValues ? -1 : 0;
|
||||
}, [allowNewValues, isValueNew]);
|
||||
|
||||
const ariaDescribedBy = useMemo(() => {
|
||||
let activeOption;
|
||||
if (!isLoading && filteredOptions.length === 0) {
|
||||
activeOption = `${id}-no-hits`;
|
||||
} else if ((value && value !== "") || isLoading) {
|
||||
if (shouldAutocomplete && filteredOptions[0]) {
|
||||
activeOption = `${id}-option-${filteredOptions[0].replace(" ", "-")}`;
|
||||
} else if (isListOpen && isLoading) {
|
||||
activeOption = `${id}-is-loading`;
|
||||
}
|
||||
}
|
||||
return cl(activeOption, partialAriaDescribedBy) || undefined;
|
||||
}, [
|
||||
isListOpen,
|
||||
isLoading,
|
||||
value,
|
||||
partialAriaDescribedBy,
|
||||
shouldAutocomplete,
|
||||
filteredOptions,
|
||||
id,
|
||||
]);
|
||||
|
||||
const currentOption = useMemo(() => {
|
||||
if (filteredOptionsIndex == null) {
|
||||
return null;
|
||||
}
|
||||
if (filteredOptionsIndex === -1) {
|
||||
return value;
|
||||
}
|
||||
return filteredOptions[filteredOptionsIndex];
|
||||
}, [filteredOptionsIndex, filteredOptions, value]);
|
||||
|
||||
const resetFilteredOptionsIndex = () => {
|
||||
setFilteredOptionsIndex(getMinimumIndex());
|
||||
};
|
||||
|
||||
const scrollToOption = useCallback((newIndex: number) => {
|
||||
if (
|
||||
filteredOptionsRef.current &&
|
||||
filteredOptionsRef.current.children[newIndex]
|
||||
) {
|
||||
const child = filteredOptionsRef.current.children[newIndex];
|
||||
const { top, bottom } = child.getBoundingClientRect();
|
||||
const parentRect = filteredOptionsRef.current.getBoundingClientRect();
|
||||
if (top < parentRect.top || bottom > parentRect.bottom) {
|
||||
child.scrollIntoView({ block: "nearest" });
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (filteredOptionsIndex !== null && isListOpen) {
|
||||
scrollToOption(filteredOptionsIndex);
|
||||
}
|
||||
}, [filteredOptionsIndex, isListOpen, scrollToOption]);
|
||||
|
||||
const moveFocusToInput = useCallback(() => {
|
||||
setFilteredOptionsIndex(null);
|
||||
toggleIsListOpen(false);
|
||||
}, [toggleIsListOpen]);
|
||||
|
||||
const moveFocusToEnd = useCallback(() => {
|
||||
const lastIndex = filteredOptions.length - 1;
|
||||
toggleIsListOpen(true);
|
||||
setFilteredOptionsIndex(lastIndex);
|
||||
}, [filteredOptions.length, toggleIsListOpen]);
|
||||
|
||||
const moveFocusUp = useCallback(() => {
|
||||
if (filteredOptionsIndex === null) {
|
||||
return;
|
||||
}
|
||||
if (filteredOptionsIndex === getMinimumIndex()) {
|
||||
toggleIsListOpen(false);
|
||||
setFilteredOptionsIndex(null);
|
||||
} else {
|
||||
const newIndex = Math.max(getMinimumIndex(), filteredOptionsIndex - 1);
|
||||
setFilteredOptionsIndex(newIndex);
|
||||
}
|
||||
}, [filteredOptionsIndex, getMinimumIndex, toggleIsListOpen]);
|
||||
|
||||
const moveFocusDown = useCallback(() => {
|
||||
if (filteredOptionsIndex === null || !isListOpen) {
|
||||
toggleIsListOpen(true);
|
||||
if (allowNewValues || filteredOptions.length >= 1) {
|
||||
setFilteredOptionsIndex(getMinimumIndex());
|
||||
}
|
||||
return;
|
||||
}
|
||||
const newIndex = Math.min(
|
||||
filteredOptionsIndex + 1,
|
||||
Math.max(getMinimumIndex(), filteredOptions.length - 1)
|
||||
);
|
||||
setFilteredOptionsIndex(newIndex);
|
||||
}, [
|
||||
allowNewValues,
|
||||
filteredOptions.length,
|
||||
filteredOptionsIndex,
|
||||
getMinimumIndex,
|
||||
isListOpen,
|
||||
toggleIsListOpen,
|
||||
]);
|
||||
|
||||
const activeDecendantId = useMemo(() => {
|
||||
if (filteredOptionsIndex === null) {
|
||||
return undefined;
|
||||
} else if (filteredOptionsIndex === -1) {
|
||||
return `${id}-combobox-new-option`;
|
||||
} else {
|
||||
return `${id}-option-${currentOption?.replace(" ", "-")}`;
|
||||
}
|
||||
}, [filteredOptionsIndex, currentOption, id]);
|
||||
|
||||
const filteredOptionsState = {
|
||||
activeDecendantId,
|
||||
allowNewValues,
|
||||
filteredOptionsRef,
|
||||
filteredOptionsIndex,
|
||||
setFilteredOptionsIndex,
|
||||
shouldAutocomplete,
|
||||
isListOpen,
|
||||
isLoading,
|
||||
filteredOptions,
|
||||
isValueNew,
|
||||
toggleIsListOpen,
|
||||
currentOption,
|
||||
resetFilteredOptionsIndex,
|
||||
moveFocusUp,
|
||||
moveFocusDown,
|
||||
moveFocusToInput,
|
||||
moveFocusToEnd,
|
||||
ariaDescribedBy,
|
||||
};
|
||||
|
||||
return (
|
||||
<FilteredOptionsContext.Provider value={filteredOptionsState}>
|
||||
{children}
|
||||
</FilteredOptionsContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useFilteredOptionsContext = () => {
|
||||
const context = useContext(FilteredOptionsContext);
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
"useFilteredOptionsContext must be used within a FilteredOptionsProvider"
|
||||
);
|
||||
}
|
||||
return context;
|
||||
};
|
||||
@@ -0,0 +1,185 @@
|
||||
import { omit } from "../../..";
|
||||
import React, {
|
||||
useCallback,
|
||||
forwardRef,
|
||||
InputHTMLAttributes,
|
||||
ChangeEvent,
|
||||
} from "react";
|
||||
import cl from "clsx";
|
||||
import { useSelectedOptionsContext } from "../SelectedOptions/selectedOptionsContext";
|
||||
import { useFilteredOptionsContext } from "../FilteredOptions/filteredOptionsContext";
|
||||
import { useInputContext } from "./inputContext";
|
||||
|
||||
interface InputProps
|
||||
extends Omit<InputHTMLAttributes<HTMLInputElement>, "value"> {
|
||||
ref: React.Ref<HTMLInputElement>;
|
||||
inputClassName?: string;
|
||||
errorId?: string;
|
||||
value?: string;
|
||||
error?: React.ReactNode;
|
||||
}
|
||||
|
||||
const Input = forwardRef<HTMLInputElement, InputProps>(
|
||||
({ inputClassName, error, errorId, ...rest }, ref) => {
|
||||
const { clearInput, inputProps, onChange, size, value } = useInputContext();
|
||||
const {
|
||||
selectedOptions,
|
||||
removeSelectedOption,
|
||||
toggleOption,
|
||||
isMultiSelect,
|
||||
} = useSelectedOptionsContext();
|
||||
const {
|
||||
activeDecendantId,
|
||||
allowNewValues,
|
||||
currentOption,
|
||||
filteredOptions,
|
||||
toggleIsListOpen,
|
||||
isListOpen,
|
||||
filteredOptionsIndex,
|
||||
moveFocusUp,
|
||||
moveFocusDown,
|
||||
ariaDescribedBy,
|
||||
moveFocusToInput,
|
||||
moveFocusToEnd,
|
||||
setFilteredOptionsIndex,
|
||||
shouldAutocomplete,
|
||||
} = useFilteredOptionsContext();
|
||||
|
||||
const onEnter = useCallback(
|
||||
(event: React.KeyboardEvent) => {
|
||||
if (currentOption) {
|
||||
event.preventDefault();
|
||||
// Selecting a value from the dropdown / FilteredOptions
|
||||
toggleOption(currentOption, event);
|
||||
if (!isMultiSelect && !selectedOptions.includes(currentOption))
|
||||
toggleIsListOpen(false);
|
||||
} else if (shouldAutocomplete && selectedOptions.includes(value)) {
|
||||
event.preventDefault();
|
||||
// Trying to set the same value that is already set, so just clearing the input
|
||||
clearInput(event);
|
||||
} else if ((allowNewValues || shouldAutocomplete) && value !== "") {
|
||||
event.preventDefault();
|
||||
// Autocompleting or adding a new value
|
||||
toggleOption(value, event);
|
||||
if (!isMultiSelect && !selectedOptions.includes(value))
|
||||
toggleIsListOpen(false);
|
||||
}
|
||||
},
|
||||
[
|
||||
allowNewValues,
|
||||
clearInput,
|
||||
currentOption,
|
||||
isMultiSelect,
|
||||
selectedOptions,
|
||||
shouldAutocomplete,
|
||||
toggleIsListOpen,
|
||||
toggleOption,
|
||||
value,
|
||||
]
|
||||
);
|
||||
|
||||
const handleKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
e.preventDefault();
|
||||
switch (e.key) {
|
||||
case "Escape":
|
||||
clearInput(e);
|
||||
toggleIsListOpen(false);
|
||||
break;
|
||||
case "Enter":
|
||||
case "Accept":
|
||||
onEnter(e);
|
||||
break;
|
||||
case "Home":
|
||||
moveFocusToInput();
|
||||
break;
|
||||
case "End":
|
||||
moveFocusToEnd();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleKeyDown = useCallback(
|
||||
(e) => {
|
||||
if (e.key === "Backspace") {
|
||||
if (value === "") {
|
||||
const lastSelectedOption =
|
||||
selectedOptions[selectedOptions.length - 1];
|
||||
removeSelectedOption(lastSelectedOption);
|
||||
}
|
||||
} else if (e.key === "ArrowDown") {
|
||||
// Check that cursor position is at the end of the input field,
|
||||
// so we don't interfere with text editing
|
||||
if (e.target.selectionStart === value?.length) {
|
||||
e.preventDefault();
|
||||
moveFocusDown();
|
||||
}
|
||||
} else if (e.key === "ArrowUp") {
|
||||
// Check that the FilteredOptions list is open and has virtual focus.
|
||||
// Otherwise ignore keystrokes, so it doesn't interfere with text editing
|
||||
if (isListOpen && filteredOptionsIndex !== null) {
|
||||
e.preventDefault();
|
||||
moveFocusUp();
|
||||
}
|
||||
}
|
||||
},
|
||||
[
|
||||
value,
|
||||
selectedOptions,
|
||||
removeSelectedOption,
|
||||
moveFocusDown,
|
||||
isListOpen,
|
||||
filteredOptionsIndex,
|
||||
moveFocusUp,
|
||||
]
|
||||
);
|
||||
|
||||
const onChangeHandler = useCallback(
|
||||
(event: ChangeEvent<HTMLInputElement>) => {
|
||||
const newValue = event.target.value;
|
||||
if (newValue && newValue !== "") {
|
||||
toggleIsListOpen(true);
|
||||
} else if (filteredOptions.length === 0) {
|
||||
toggleIsListOpen(false);
|
||||
}
|
||||
onChange(event);
|
||||
},
|
||||
[filteredOptions.length, onChange, toggleIsListOpen]
|
||||
);
|
||||
|
||||
const onBlur = () => {
|
||||
setFilteredOptionsIndex(-1);
|
||||
};
|
||||
|
||||
return (
|
||||
<input
|
||||
{...rest}
|
||||
{...omit(inputProps, ["aria-invalid"])}
|
||||
ref={ref}
|
||||
value={value}
|
||||
onChange={onChangeHandler}
|
||||
type="text"
|
||||
role="combobox"
|
||||
onBlur={onBlur}
|
||||
onKeyUp={handleKeyUp}
|
||||
onKeyDown={handleKeyDown}
|
||||
aria-controls={`${inputProps.id}-filtered-options`}
|
||||
aria-expanded={!!isListOpen}
|
||||
autoComplete="off"
|
||||
aria-autocomplete={shouldAutocomplete ? "both" : "list"}
|
||||
aria-activedescendant={activeDecendantId}
|
||||
aria-describedby={ariaDescribedBy}
|
||||
aria-invalid={inputProps["aria-invalid"]}
|
||||
className={cl(
|
||||
inputClassName,
|
||||
"navds-combobox__input",
|
||||
"navds-body-short",
|
||||
`navds-body-${size}`
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default Input;
|
||||
@@ -0,0 +1,130 @@
|
||||
import React, {
|
||||
ChangeEvent,
|
||||
ChangeEventHandler,
|
||||
createContext,
|
||||
useCallback,
|
||||
useContext,
|
||||
useLayoutEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { useFormField, FormFieldType } from "../../useFormField";
|
||||
|
||||
interface InputContextType extends FormFieldType {
|
||||
clearInput: (event: React.PointerEvent | React.KeyboardEvent) => void;
|
||||
error?: string;
|
||||
focusInput: () => void;
|
||||
inputRef: React.RefObject<HTMLInputElement>;
|
||||
value: string;
|
||||
setValue: (text: string) => void;
|
||||
onChange: ChangeEventHandler<HTMLInputElement>;
|
||||
searchTerm: string;
|
||||
setSearchTerm: React.Dispatch<React.SetStateAction<string>>;
|
||||
shouldAutocomplete?: boolean;
|
||||
}
|
||||
|
||||
const InputContext = createContext<InputContextType>({} as InputContextType);
|
||||
|
||||
export const InputContextProvider = ({ children, value: props }) => {
|
||||
const {
|
||||
defaultValue = "",
|
||||
description,
|
||||
disabled,
|
||||
error,
|
||||
errorId,
|
||||
id: externalId,
|
||||
value: externalValue,
|
||||
onChange: externalOnChange,
|
||||
onClear,
|
||||
shouldAutocomplete,
|
||||
size,
|
||||
} = props;
|
||||
const formFieldProps = useFormField(
|
||||
{
|
||||
description,
|
||||
disabled,
|
||||
error,
|
||||
errorId,
|
||||
id: externalId,
|
||||
size,
|
||||
},
|
||||
"comboboxfield"
|
||||
);
|
||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||
const [internalValue, setInternalValue] = useState<string>(defaultValue);
|
||||
|
||||
const value = useMemo(
|
||||
() => String(externalValue ?? internalValue),
|
||||
[externalValue, internalValue]
|
||||
);
|
||||
|
||||
const [searchTerm, setSearchTerm] = useState(value);
|
||||
|
||||
const onChange = useCallback(
|
||||
(event: ChangeEvent<HTMLInputElement>) => {
|
||||
const value = event.currentTarget.value;
|
||||
externalValue ?? setInternalValue(value);
|
||||
externalOnChange?.(event);
|
||||
setSearchTerm(value);
|
||||
},
|
||||
[externalValue, externalOnChange]
|
||||
);
|
||||
|
||||
const setValue = useCallback(
|
||||
(text) => {
|
||||
setInternalValue(text);
|
||||
},
|
||||
[setInternalValue]
|
||||
);
|
||||
|
||||
const clearInput = useCallback(
|
||||
(event: React.PointerEvent | React.KeyboardEvent) => {
|
||||
onClear?.(event);
|
||||
externalOnChange?.(null, "");
|
||||
setValue("");
|
||||
setSearchTerm("");
|
||||
},
|
||||
[externalOnChange, onClear, setValue]
|
||||
);
|
||||
|
||||
const focusInput = useCallback(() => {
|
||||
inputRef.current?.focus?.();
|
||||
}, []);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (shouldAutocomplete && inputRef && value !== searchTerm) {
|
||||
inputRef.current?.setSelectionRange?.(searchTerm.length, value.length);
|
||||
}
|
||||
}, [value, searchTerm, shouldAutocomplete]);
|
||||
|
||||
return (
|
||||
<InputContext.Provider
|
||||
value={{
|
||||
...formFieldProps,
|
||||
clearInput,
|
||||
error,
|
||||
focusInput,
|
||||
inputRef,
|
||||
value,
|
||||
setValue,
|
||||
onChange,
|
||||
searchTerm,
|
||||
setSearchTerm,
|
||||
shouldAutocomplete,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</InputContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useInputContext = () => {
|
||||
const context = useContext(InputContext);
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
"useInputContext must be used within an InputContextProvider"
|
||||
);
|
||||
}
|
||||
return context;
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
import React from "react";
|
||||
import { Chips } from "../../..";
|
||||
import { useSelectedOptionsContext } from "./selectedOptionsContext";
|
||||
import { useInputContext } from "../Input/inputContext";
|
||||
|
||||
interface SelectedOptionsProps {
|
||||
selectedOptions?: string[];
|
||||
size?: "medium" | "small";
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const Option = ({ option }: { option: string }) => {
|
||||
const { isMultiSelect, removeSelectedOption } = useSelectedOptionsContext();
|
||||
const { focusInput } = useInputContext();
|
||||
|
||||
const onClick = (e) => {
|
||||
e.stopPropagation();
|
||||
removeSelectedOption(option);
|
||||
focusInput();
|
||||
};
|
||||
|
||||
if (!isMultiSelect) {
|
||||
return (
|
||||
<div className="navds-combobox__selected-options--no-bg">{option}</div>
|
||||
);
|
||||
}
|
||||
|
||||
return <Chips.Removable onClick={onClick}>{option}</Chips.Removable>;
|
||||
};
|
||||
|
||||
const SelectedOptions: React.FC<SelectedOptionsProps> = ({
|
||||
selectedOptions = [],
|
||||
size,
|
||||
children,
|
||||
}) => {
|
||||
return (
|
||||
<Chips className="navds-combobox__selected-options" size={size}>
|
||||
{selectedOptions.length
|
||||
? selectedOptions.map((option, i) => (
|
||||
<Option key={option + i} option={option} />
|
||||
))
|
||||
: []}
|
||||
{children}
|
||||
</Chips>
|
||||
);
|
||||
};
|
||||
|
||||
export default SelectedOptions;
|
||||
@@ -0,0 +1,157 @@
|
||||
import React, {
|
||||
createContext,
|
||||
useCallback,
|
||||
useContext,
|
||||
useMemo,
|
||||
useState,
|
||||
} from "react";
|
||||
import usePrevious from "../../../util/usePrevious";
|
||||
import { useInputContext } from "../Input/inputContext";
|
||||
import { ComboboxProps } from "../types";
|
||||
import { useCustomOptionsContext } from "../customOptionsContext";
|
||||
|
||||
type SelectedOptionsContextType = {
|
||||
addSelectedOption: (option: string) => void;
|
||||
isMultiSelect?: boolean;
|
||||
removeSelectedOption: (option: string) => void;
|
||||
prevSelectedOptions?: string[];
|
||||
selectedOptions: string[];
|
||||
setSelectedOptions: (any) => void;
|
||||
toggleOption: (
|
||||
option: string,
|
||||
event: React.KeyboardEvent | React.PointerEvent
|
||||
) => void;
|
||||
};
|
||||
|
||||
const SelectedOptionsContext = createContext<SelectedOptionsContextType>(
|
||||
{} as SelectedOptionsContextType
|
||||
);
|
||||
|
||||
export const SelectedOptionsProvider = ({
|
||||
children,
|
||||
value,
|
||||
}: {
|
||||
children: any;
|
||||
value: Pick<
|
||||
ComboboxProps,
|
||||
| "allowNewValues"
|
||||
| "isMultiSelect"
|
||||
| "options"
|
||||
| "selectedOptions"
|
||||
| "onToggleSelected"
|
||||
>;
|
||||
}) => {
|
||||
const { clearInput, focusInput } = useInputContext();
|
||||
const {
|
||||
customOptions,
|
||||
removeCustomOption,
|
||||
addCustomOption,
|
||||
setCustomOptions,
|
||||
} = useCustomOptionsContext();
|
||||
const {
|
||||
allowNewValues,
|
||||
isMultiSelect,
|
||||
selectedOptions: externalSelectedOptions,
|
||||
onToggleSelected,
|
||||
options,
|
||||
} = value;
|
||||
const [internalSelectedOptions, setSelectedOptions] = useState<string[]>([]);
|
||||
const selectedOptions = useMemo(
|
||||
() =>
|
||||
externalSelectedOptions ?? [...customOptions, ...internalSelectedOptions],
|
||||
[customOptions, externalSelectedOptions, internalSelectedOptions]
|
||||
);
|
||||
|
||||
const addSelectedOption = useCallback(
|
||||
(option: string) => {
|
||||
const isCustomOption = !options
|
||||
.map((opt) => opt.toLowerCase())
|
||||
.includes(option?.toLowerCase?.());
|
||||
if (isCustomOption) {
|
||||
allowNewValues && addCustomOption(option);
|
||||
!isMultiSelect && setSelectedOptions([]);
|
||||
} else if (isMultiSelect) {
|
||||
setSelectedOptions((prevSelectedOptions) => [
|
||||
...prevSelectedOptions,
|
||||
option,
|
||||
]);
|
||||
} else {
|
||||
setSelectedOptions([option]);
|
||||
setCustomOptions([]);
|
||||
}
|
||||
onToggleSelected?.(option, true, isCustomOption);
|
||||
},
|
||||
[
|
||||
addCustomOption,
|
||||
allowNewValues,
|
||||
isMultiSelect,
|
||||
onToggleSelected,
|
||||
options,
|
||||
setCustomOptions,
|
||||
]
|
||||
);
|
||||
|
||||
const removeSelectedOption = useCallback(
|
||||
(option: string) => {
|
||||
const isCustomOption = customOptions.includes(option);
|
||||
if (isCustomOption) {
|
||||
removeCustomOption(option);
|
||||
} else {
|
||||
setSelectedOptions((prevSelectedOptions) =>
|
||||
prevSelectedOptions.filter(
|
||||
(selectedOption) => selectedOption !== option
|
||||
)
|
||||
);
|
||||
}
|
||||
onToggleSelected?.(option, false, isCustomOption);
|
||||
},
|
||||
[customOptions, onToggleSelected, removeCustomOption]
|
||||
);
|
||||
|
||||
const toggleOption = useCallback(
|
||||
(option: string, event: React.KeyboardEvent | React.PointerEvent) => {
|
||||
if (selectedOptions.includes(option)) {
|
||||
removeSelectedOption(option);
|
||||
} else {
|
||||
addSelectedOption(option);
|
||||
}
|
||||
clearInput(event);
|
||||
focusInput();
|
||||
},
|
||||
[
|
||||
addSelectedOption,
|
||||
clearInput,
|
||||
focusInput,
|
||||
removeSelectedOption,
|
||||
selectedOptions,
|
||||
]
|
||||
);
|
||||
|
||||
const prevSelectedOptions = usePrevious<string[]>(selectedOptions);
|
||||
|
||||
const selectedOptionsState = {
|
||||
addSelectedOption,
|
||||
isMultiSelect,
|
||||
removeSelectedOption,
|
||||
prevSelectedOptions,
|
||||
selectedOptions,
|
||||
setSelectedOptions,
|
||||
toggleOption,
|
||||
};
|
||||
|
||||
return (
|
||||
<SelectedOptionsContext.Provider value={selectedOptionsState}>
|
||||
{children}
|
||||
</SelectedOptionsContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useSelectedOptionsContext = () => {
|
||||
const context = useContext(SelectedOptionsContext);
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
"useSelectedOptionsContext must be used within a SelectedOptionsProvider"
|
||||
);
|
||||
}
|
||||
return context;
|
||||
};
|
||||
Loaded 100 of 364 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user