Compare commits

...
Author SHA1 Message Date
github-actions[bot]andgithub-actions[bot] fbc580e6bc Version Packages (#3420)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-12-06 14:30:55 +01:00
Halvor Haugan 13a9a2159f Refactor accordion stories (#3432) 2024-12-05 22:01:54 +01:00
Vegard HaugstvedtandHalvor Haugan 89e069d1d6 CopyButton: i18n & remove prop activeTitle (#3426)
Co-authored-by: Halvor Haugan <halvor.haugan@nav.no>
2024-12-05 13:36:33 +01:00
Halvor Haugan 4896bb1569 FormSummary: add translation (#3428) 2024-12-05 13:17:13 +01:00
Ken 713ccafed1 🐛 Accordion now deconstructs sanity-references (#3422) 2024-12-05 10:23:13 +01:00
Ken 4632a3ae2b [Darkside] Updated components based on Figma-comments (#3417)
* 💄 Alert now synced with standardized panel padding

* 💄 Expansioncard synced with standardized panel padding

* 💄 Chat synced with standardized panel padding

* 💄 ErrorSummary synced with standardized panel padding

* 💄 FileUpload synced with standardized panel padding

* 💄 FormSummary synced with standardized panel padding

* 💄 FormSummary synced with standardized panel padding

* 💄 Modal synced with standardized panel padding

* 💄 Popover/Helptext synced with standardized panel padding

* 💄 Text-neutral did not work in darkmode for Button. Now uses text-default
2024-12-04 16:26:21 +01:00
KenandHalvor Haugan f6666302f5 [Darkside] Updated Primitives CSS to use new token-prefix (#3405)
* 📝 Overlap comments

* WIP: update primitives prefixing

* ♻️ Use updated prefix in primitives ts-code

* ♻️ Use updated token-prefix in css

* ♻️ Use updated tokens in primitives css utilities

* 🔥 Removed backwards-compat with old stack CSS

* [Darkside] Primtives prop-support (#3423)

* :refactor: Support primitives with new theme

* :refactor: Use sub-component for new Box update

* ♻️ Update support for new and old theme in Page and Box

* ♻️ Resolve instances where tokens were not correctly named for theme-support

* ♻️ Avoid exposing component before necesarry

* ♻️ Avoid having to import figma-types in ds-react

* ♻️ Using camelCase on tokens breaks primtives. Now uses kebab-case

* 🔥 Removed comment used as notes

* Update @navikt/core/react/src/layout/page/Page.tsx

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* Update @navikt/core/react/src/layout/box/Box.tsx

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* ♻️ Remove redundant prefix const

* ♻️ remove redundant T-suffix on types

* ♻️ Better previews on hover when checking token-props

---------

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* ♻️ More fine-grained exception-testing for use of old props in Box

---------

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>
2024-12-04 10:35:32 +01:00
Halvor HauganandKen bae136f847 Translate GuidePanel and HelpText, remove text from InternalHeader. (#3424)
Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
2024-12-04 10:29:26 +01:00
Ken 53d1fe517e [Darkside] Tailwind: Added tests for new config setup 2024-12-03 12:48:59 +01:00
Ken ea0d7c1386 [Darkside] Tailwind: Added shadow-token support 2024-12-03 12:41:35 +01:00
8ea6c220dc [Darkside] datemonthpicker (#3357)
* 🚧 wip

* [Darkside] ErrorSummary updated CSS (#3331)

* First run for errorsummary css update

* Added nesting

* [Darkside] Fileupload CSS update (#3343)

* ✨ Updated Dropzone with darkmode

* ♻️ Added nesting for root

* ♻️ ac -> acx prefix for interla tokens

* ♻️ Removed reduntant token

* ♻️ More nesting

* 💄 Align overlay on drag better

* ⚰️ Removed test-code

* 💄 Update hover-border for dropzone

* 🐛 Removed border-color update on hover in disabled state

* ♻️ Use bg input on area, use border default

* [Darkside] Link CSS update (#3353)

* ✨ Darkmode-support for existing link-component

* :refactor: Adjusted line offsets and thickness

* [Darkside] ExpansionCard CSS update (#3338)

* 💄 Initial css-update expansioncard

* 📝 Added sub-headers

* 💫 Button animation

* ✨ Added data attrb for open-state

* 💫 Updated content animation

* ♻️ Added nesting

* ♻️ Better nesting of rules

* ♻️ Use outline for hover border

* ♻️ Use border as default outline

* 🔥 Remove redundant border css

* 🔥 Removed divider transition, unused state attributes in react

* [aksel.nav.no] Update examples of Page (#3349)

* Changesets: Run yarn as part of create-version

* Combobox: Fix issue where using arrow keys in list would make the entire page scroll (#3364)

* [Darkside] FormSummary updated CSS (#3345)

* :refactor: Use updated CSS for darkside

* 💄 Replace accent bg with info bg

* [Docs] Use NAV-dekorator for Page examples (#3362)

* [aksel.nav.no] Update examples of Page

* comment

* comment + rename + style->class

* fix

* 📝 Use NAV-dekorator for Page-examples

* 🚚 Moved content to separate __parts location

* :refactor: Updated examples

* Update aksel.nav.no/website/components/website-modules/examples/__parts/PageDemoContent.tsx

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* 🐛 Use correct import syntax for parts

* 📝 Add description to page-block default story

* 💄 Removed spacing from all typo-headings in demo

* 🐛 Removed react import from content part

---------

Co-authored-by: Halvor Haugan <halvor.haugan@nav.no>
Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* Git hooks that notify when yarn.lock have changed (#3361)

* 💄 first pass css updates

* 🎨 nest CSS

* Datepicker: 💄 css layer changes & remove extra border

* 🔥 remove resolved todo

* 💄 border radius for caption buttons

* 🎨 drastically simplify focus outline

* change: make button selector less wildcardy

* change: outline smaller for rdp-cell buttons

* change: width large enough to show 4 characters in year caption

* change: match design for range middle selected

* change: remove redundant error CSS

* change: remove unused CSS

* change: un-shuffle css import ordering for date.css

* change: remove unused CSS

* change: week buttons & day button active

* change: use secondary-neutral button for weeknumber buttons

* change: same selector for month and day buttons, active state

* 🐛 Fixed weeknumber as the button broke old datepicker

* change: remove double border on captions, active state on disabled

* ♻️ Updated weeknumber to be barkw-compat with old system

* 🚚 Moved date-import further up

---------

Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>
Co-authored-by: Halvor Haugan <halvor.haugan@nav.no>
Co-authored-by: Ken <ken.aleksander@gmail.com>
2024-12-03 12:09:53 +01:00
Ken 9a190d371b [Darkside]: Removed hover-effect from disabled button in forced-color mode 2024-12-03 11:38:45 +01:00
KenandHalvor Haugan 685066e791 [Darkside] Search CSS update (#3385)
* ♻️ Use variables for Button-adjustment

* :refactor: Removed redundant selector nesting for disabled buttons

* :refactor: Use aksel-button for clearbutton

* ✨ Added darkmode support to Search

* :refactor: Updated paddings

* :refactor: Added disabled-support

* :refactor: Updated border of button when input is hovered

* Update @navikt/core/react/src/form/search/Search.tsx

* 🐛 Add correct button CSS from main

* 💄 Placeholder set to text-neutral

* ♻️ Undo nesting

* ♻️ Better error-css structure

* 📝 Added disabled-stories

* 💄 Set opacity on searchicon when disabled

* Update @navikt/core/react/src/form/search/Search.tsx

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

---------

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>
2024-12-03 11:24:56 +01:00
Lars Eirik Korsgaard Hansen 41a21d280a fix forced colors toggle group (#3421) 2024-12-02 13:26:34 +01:00
Halvor Haugan 1895f4f763 Combobox: add translations and adjust buttons (#3409)
Hid buttons from screen readers since you can't tab to them anyways. Moved sr-only text on clear button to title attr. Removed sr-only text on toggle list button. Removed prop toggleListButtonLabel.
2024-12-02 12:55:02 +01:00
Halvor Haugan 8bc9a80bd4 Adjust examples of Combobox (#3419) 2024-12-02 10:42:59 +01:00
Lars Eirik Korsgaard Hansen d5a6285110 [Darkside] Togglegroup CSS update (#3400) 2024-12-02 10:38:28 +01:00
Vegard Haugstvedt 856e54aa2d Bugfix/CopyButton: Reduce over announcing active state (#3374)
* Prevent active text being announced waaay too many times.

* Add changeset

* New attempt at consistently reduced status messages on "copy" click

* Remove aria-relevant and aria-atomic to make announcement consistent between Safari and other browsers
2024-11-29 15:43:49 +01:00
95 changed files with 2175 additions and 1907 deletions

No files matched your search

+2
View File
@@ -1,5 +1,7 @@
# @navikt/aksel-icons
## 7.7.0
## 7.6.0
### Minor Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/aksel-icons",
"version": "7.6.0",
"version": "7.7.0",
"author": "Aksel | NAV",
"homepage": "https://aksel.nav.no/ikoner",
"repository": {
+2
View File
@@ -1,5 +1,7 @@
# @navikt/aksel-stylelint
## 7.7.0
## 7.6.0
## 7.5.3
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/aksel-stylelint",
"version": "7.6.0",
"version": "7.7.0",
"author": "Aksel | NAV",
"homepage": "https://aksel.nav.no/grunnleggende/kode/stylelint",
"repository": {
@@ -35,8 +35,8 @@
"dev": "yarn watch:lint"
},
"devDependencies": {
"@navikt/ds-css": "^7.6.0",
"@navikt/ds-tokens": "^7.6.0",
"@navikt/ds-css": "^7.7.0",
"@navikt/ds-tokens": "^7.7.0",
"concurrently": "9.0.1",
"postcss-selector-parser": "^6.0.13",
"postcss-value-parser": "^4.2.0",
+7
View File
@@ -1,5 +1,12 @@
# @navikt/aksel
## 7.7.0
### Patch Changes
- Updated dependencies []:
- @navikt/ds-css@7.7.0
## 7.6.0
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/aksel",
"version": "7.6.0",
"version": "7.7.0",
"description": "Aksel command line interface. Handles css-imports, codemods and more",
"author": "Aksel | NAV designsystem team",
"license": "MIT",
@@ -29,7 +29,7 @@
},
"homepage": "https://aksel.nav.no/grunnleggende/kode/kommandolinje",
"dependencies": {
"@navikt/ds-css": "7.6.0",
"@navikt/ds-css": "7.7.0",
"axios": "1.7.4",
"chalk": "4.1.0",
"clipboardy": "^2.3.0",
+2
View File
@@ -1,5 +1,7 @@
# @navikt/ds-css
## 7.7.0
## 7.6.0
### Minor Changes
+2 -2
View File
@@ -1,7 +1,7 @@
.navds-alert {
border-radius: var(--ax-border-radius-xlarge);
border: 1px solid;
padding: var(--ax-spacing-4);
padding: var(--ax-spacing-4) var(--ax-spacing-5);
display: flex;
gap: var(--ax-spacing-3);
align-items: center;
@@ -25,7 +25,7 @@
}
.navds-alert--small {
padding: var(--ax-spacing-2) var(--ax-spacing-4);
padding: var(--ax-spacing-3) var(--ax-spacing-4);
gap: var(--ax-spacing-2);
> .navds-alert__icon {
+12 -14
View File
@@ -92,16 +92,16 @@
&:is(:disabled, .navds-button--disabled) {
background-color: var(--ax-bg-accent-strong);
}
}
@media (forced-colors: active) {
.navds-button.navds-button--primary {
background-color: highlight;
color: highlighttext;
}
@media (forced-colors: active) {
&:not(:disabled) {
background-color: highlight;
color: highlighttext;
}
.navds-button.navds-button--primary span {
forced-color-adjust: none;
& span {
forced-color-adjust: none;
}
}
}
@@ -163,13 +163,12 @@
--__axc-button-border-color: var(--ax-border-default);
background-color: transparent;
color: var(--ax-text-neutral);
color: var(--ax-text-default);
&:hover {
--__axc-button-border-color: var(--ax-border-strong);
background-color: var(--ax-bg-neutral-moderate-hoverA);
color: var(--ax-text-neutral-strong);
}
&:active {
@@ -215,11 +214,10 @@
****************************/
.navds-button--tertiary-neutral {
background-color: transparent;
color: var(--ax-text-neutral);
color: var(--ax-text-default);
&:hover {
background-color: var(--ax-bg-neutral-moderate-hoverA);
color: var(--ax-text-neutral-strong);
}
&:active {
@@ -287,14 +285,14 @@
background-color: ButtonFace;
}
.navds-button:hover {
.navds-button:not(:disabled):hover {
background-color: highlighttext;
border-color: highlight;
color: highlight;
box-shadow: none;
}
.navds-button:hover span {
.navds-button:not(:disabled):hover span {
forced-color-adjust: none;
}
+2 -2
View File
@@ -54,7 +54,7 @@
}
.navds-chat__bubble {
padding: var(--ax-spacing-4);
padding: var(--ax-spacing-4) var(--ax-spacing-5);
width: fit-content;
background-color: var(--ax-bg-raised);
display: flex;
@@ -66,7 +66,7 @@
}
.navds-chat--small .navds-chat__bubble {
padding: var(--ax-spacing-3);
padding: var(--ax-spacing-3) var(--ax-spacing-4);
}
/* -------------------------- Chat bubble variants -------------------------- */
+203 -264
View File
@@ -1,108 +1,140 @@
.navds-date {
padding: var(--a-spacing-4) var(--a-spacing-3);
padding: var(--ax-spacing-4) var(--ax-spacing-3);
.rdp-day_range_middle {
&.rdp-day_disabled {
color: var(--ax-text-default);
background: var(--ax-bg-neutral-moderateA);
}
&.rdp-day_selected {
background-color: var(--ax-bg-accent-moderateA);
box-shadow: inset 0 0 0 1px var(--ax-border-accent-subtleA);
color: var(--ax-text-default);
}
}
.rdp-month,
&.rdp-month {
display: grid;
gap: var(--ax-spacing-5);
}
.navds-date__caption-label {
text-transform: capitalize;
}
.rdp-head_cell {
text-transform: capitalize;
font-size: var(--ax-font-size-small);
}
.rdp-button {
all: unset;
display: block;
width: 2.5rem;
height: 2.5rem;
text-align: center;
border-radius: var(--ax-border-radius-medium);
}
.rdp-day_range_start {
border-radius: var(--ax-border-radius-xlarge) var(--ax-border-radius-medium) var(--ax-border-radius-medium)
var(--ax-border-radius-xlarge);
}
.rdp-day_range_end:not(.rdp-day_range_start) {
border-radius: var(--ax-border-radius-medium) var(--ax-border-radius-xlarge) var(--ax-border-radius-xlarge)
var(--ax-border-radius-medium);
}
.rdp-day_range_start.rdp-day_range_end {
border-radius: var(--ax-border-radius-xlarge);
}
.navds-date__field {
display: flex;
flex-direction: column;
width: 100%;
position: relative;
}
.rdp-day_selected,
.navds-monthpicker__month--selected {
color: var(--ax-text-accent-contrast);
background: var(--ax-bg-accent-strong-pressed);
cursor: pointer;
}
.rdp-day_disabled {
cursor: not-allowed;
text-decoration: line-through;
background-color: var(--ax-bg-neutral-moderateA);
color: var(--ax-text-subtle);
}
.rdp-button:where(:not(.rdp-day_selected, [disabled])):hover,
.navds-date__month-button:where(:not(.rdp-day_selected, [disabled])):hover {
background: var(--ax-bg-accent-moderate-hoverA);
cursor: pointer;
}
.rdp-day_today {
position: relative;
&::before {
width: 6px;
height: 6px;
display: block;
background-color: var(--ax-text-accent);
border-radius: var(--ax-border-radius-full);
content: "";
position: absolute;
bottom: 5px;
left: 50%;
transform: translateX(-50%);
}
&.rdp-day_selected:not(.rdp-day_range_middle),
&:active {
&::before {
background-color: var(--ax-text-accent-contrast);
}
}
}
.rdp-day_outside {
visibility: hidden;
pointer-events: none;
}
.navds-date__modal & {
padding: 0;
}
.navds-date__modal-body > & {
padding: 0;
}
}
.navds-date .rdp-day_range_middle.rdp-day_disabled {
color: var(--ac-date-middle-text, var(--a-text-on-action));
background: var(--ac-date-middle-bg, var(--a-surface-action-selected));
}
.navds-date .rdp-month,
.navds-date.rdp-month {
display: grid;
gap: var(--a-spacing-5);
}
.navds-date__caption-label {
text-transform: capitalize;
}
.navds-date .rdp-head_cell {
text-transform: capitalize;
font-size: var(--a-font-size-small);
}
.navds-date .rdp-weeknumber {
font-size: var(--a-font-size-small);
.navds-date__caption {
display: flex;
justify-content: space-between;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
border-radius: var(--a-border-radius-medium);
margin: var(--a-spacing-2);
color: var(--a-text-subtle);
gap: var(--ax-spacing-1);
padding-inline: var(--ax-spacing-1);
}
.navds-date .rdp-weeknumber.rdp-button {
.navds-date__caption-button {
width: 2rem;
height: 2rem;
box-shadow: 0 0 0 1px var(--a-border-default);
color: var(--a-text-subtle);
font-size: var(--a-font-size-small);
}
.navds-date .rdp-weeknumber.rdp-button:active {
background-color: var(--a-surface-action-active);
color: var(--a-text-on-action);
box-shadow: none;
color: var(--ax-text-default);
}
.navds-date__caption__month .navds-select__container select {
text-transform: capitalize;
}
.navds-date .rdp-button {
all: unset;
display: block;
width: 2.5rem;
height: 2.5rem;
text-align: center;
border-radius: var(--a-border-radius-medium);
}
.navds-date .rdp-day_range_start {
border-radius: var(--a-border-radius-xlarge) var(--a-border-radius-medium) var(--a-border-radius-medium)
var(--a-border-radius-xlarge);
}
.navds-date .rdp-day_range_end:not(.rdp-day_range_start) {
border-radius: var(--a-border-radius-medium) var(--a-border-radius-xlarge) var(--a-border-radius-xlarge)
var(--a-border-radius-medium);
}
.navds-date .rdp-day_range_start.rdp-day_range_end {
border-radius: var(--a-border-radius-xlarge);
}
.navds-date .rdp-button:not(.rdp-day_selected, [disabled]):focus-visible,
.navds-date .navds-date__month-button:not(.rdp-day_selected, [disabled]):focus-visible {
box-shadow: var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-date .rdp-button:not(.rdp-day_selected, [disabled]):focus,
.navds-date .navds-date__month-button:not(.rdp-day_selected, [disabled]):focus {
box-shadow: var(--a-shadow-focus);
}
}
.navds-date .rdp-button.rdp-day_selected:not([disabled]):focus-visible,
.navds-date .navds-date__month-button.rdp-day_selected:not([disabled]):focus-visible {
box-shadow:
inset 0 0 0 1px var(--a-surface-default),
var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-date .rdp-button.rdp-day_selected:not([disabled]):focus,
.navds-date .navds-date__month-button.rdp-day_selected:not([disabled]):focus {
box-shadow:
inset 0 0 0 1px var(--a-surface-default),
var(--a-shadow-focus);
}
}
/* Monthpicker */
.navds-date__month-button {
all: unset;
@@ -110,24 +142,10 @@
width: 3rem;
height: 3rem;
text-transform: capitalize;
border-radius: var(--a-border-radius-medium);
border-radius: var(--ax-border-radius-medium);
cursor: pointer;
}
.navds-date__month-button:focus-visible,
.navds-monthpicker__caption-button:focus-visible {
box-shadow: var(--a-shadow-focus);
z-index: 1;
}
@supports not selector(:focus-visible) {
.navds-date__month-button:focus,
.navds-monthpicker__caption-button:focus {
box-shadow: var(--a-shadow-focus);
z-index: 1;
}
}
.navds-date__year-label {
display: flex;
align-items: center;
@@ -137,13 +155,69 @@
.navds-date__standalone-wrapper {
height: fit-content;
width: fit-content;
.rdp-cell > button.rdp-day,
button.navds-date__month-button {
&:focus-visible {
outline: 2px solid var(--ax-border-focus);
outline-offset: 1px;
}
&:active:not(:disabled) {
color: var(--ax-text-accent-contrast);
background-color: var(--ax-bg-accent-strong-pressed);
}
}
}
.navds-date .navds-date__field {
display: flex;
flex-direction: column;
width: 100%;
position: relative;
.navds-date__field-input {
&.navds-text-field__input {
padding-right: var(--ax-spacing-12);
}
.navds-form-field--small & {
padding-right: var(--ax-spacing-8);
}
}
.navds-date__field-button {
position: absolute;
right: 0.0625rem;
top: 50%;
transform: translateY(-50%);
color: var(--ax-text-default);
display: inline-flex;
cursor: pointer;
margin: 0;
text-decoration: none;
border: none;
background: none;
border-radius: calc(var(--ax-border-radius-medium) - 1px);
padding: var(--ax-spacing-3);
align-items: center;
justify-content: center;
font-size: 1.5rem;
height: calc(100% - 0.125rem);
border-start-start-radius: 0;
border-end-start-radius: 0;
.navds-form-field--small & {
padding: var(--ax-spacing-1);
}
.navds-form-field--disabled & {
opacity: 1;
cursor: not-allowed;
}
/* Readonly */
.navds-date__field--readonly & {
cursor: default;
}
&:focus-visible {
outline-color: var(--ax-border-focus);
}
}
.navds-date__field-wrapper {
@@ -153,146 +227,23 @@
width: fit-content;
}
.navds-date .rdp-day_selected,
.navds-monthpicker__month--selected {
color: var(--ac-date-selected-text, var(--a-text-on-action));
background: var(--ac-date-selected-bg, var(--a-surface-action-selected));
cursor: pointer;
}
.navds-date .rdp-day_disabled {
cursor: not-allowed;
text-decoration: line-through;
background-color: var(--ac-date-disabled-bg, var(--a-surface-neutral-subtle));
color: var(--ac-date-disabled-text, var(--a-text-subtle));
}
.navds-date .rdp-button:where(:not(.rdp-day_selected, [disabled])):hover,
.navds-date__month-button:where(:not(.rdp-day_selected, [disabled])):hover {
background: var(--ac-date-hover-bg, var(--a-surface-action-subtle-hover));
cursor: pointer;
}
.navds-date .rdp-day_today {
box-shadow: 0 0 0 1px var(--ac-date-today-border, var(--a-border-action-selected));
text-decoration: underline;
}
.navds-date__caption {
display: flex;
justify-content: space-between;
align-items: center;
gap: var(--a-spacing-1);
padding-inline: var(--a-spacing-1);
}
.navds-date__caption-button,
.navds-date__caption-button:disabled,
.navds-date__caption-button:disabled:hover {
color: var(--ac-date-caption-text, var(--a-text-default));
}
.navds-date__field-input {
padding-right: var(--a-spacing-12);
}
.navds-form-field--small .navds-date__field-input {
padding-right: var(--a-spacing-8);
}
/* Error-handling */
.navds-date__field--error .navds-date__field-input:not(:hover, :disabled) {
border-color: var(--ac-date-input-error-border, var(--a-border-danger));
box-shadow: inset 0 0 0 1px var(--ac-date-input-error-border, var(--a-border-danger));
}
.navds-date__field--error .navds-date__field-input:focus-visible:not(:hover, :disabled) {
box-shadow:
inset 0 0 0 1px var(--ac-date-input-error-border, var(--a-border-danger)),
var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-date__field--error .navds-date__field-input:focus:not(:hover, :disabled) {
box-shadow:
inset 0 0 0 1px var(--ac-date-input-error-border, var(--a-border-danger)),
var(--a-shadow-focus);
}
}
.navds-date__field-button {
position: absolute;
right: 0.0625rem;
top: 50%;
transform: translateY(-50%);
color: var(--ac-date-input-button-text, var(--a-text-default));
display: inline-flex;
cursor: pointer;
margin: 0;
text-decoration: none;
border: none;
background: none;
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% - 0.125rem);
border-start-start-radius: 0;
border-end-start-radius: 0;
}
.navds-form-field--small .navds-date__field-button {
padding: var(--a-spacing-1);
}
.navds-date__field-button:hover:where(:not([disabled])) {
color: var(--ac-date-input-button-hover-text, var(--a-text-action-on-action-subtle));
background-color: var(--ac-date-input-button-hover-bg, var(--a-surface-action-subtle-hover));
}
.navds-form-field--disabled .navds-date__field-button {
opacity: 1;
cursor: not-allowed;
}
.navds-date__field-button:focus-visible {
outline: none;
box-shadow: var(--a-shadow-focus);
border-radius: var(--a-border-radius-medium);
}
@supports not selector(:focus-visible) {
.navds-date__field-button:focus {
outline: none;
box-shadow: var(--a-shadow-focus);
}
}
.navds-date__caption__year {
width: 5rem;
}
.navds-date .rdp-day_outside {
visibility: hidden;
pointer-events: none;
}
/* Readonly */
.navds-date__field--readonly .navds-date__field-button {
cursor: default;
color: var(--a-gray-500);
}
.navds-date__caption-button {
width: 2rem;
height: 2rem;
}
.navds-date__week-row {
display: flex;
align-items: center;
gap: var(--a-spacing-05);
gap: var(--ax-spacing-05);
}
.navds-date__weeknumber {
--__axc-button-border-width: 1px;
}
.navds-date__weeknumber-number {
font-size: 0.875rem;
color: var(--ax-text-subtle);
.navds-date__weeknumber:active & {
color: var(--ax-text-neutral-contrast);
}
}
.navds-date__week-wrapper {
@@ -303,37 +254,25 @@
margin: 0;
}
.navds-date__modal.navds-date {
padding: 0;
}
.navds-date__modal-body {
display: flex;
flex-direction: column;
align-items: flex-end;
padding: var(--a-spacing-4);
gap: var(--a-spacing-2);
}
.navds-date__modal-body > .navds-date {
padding: 0;
}
.navds-date__popover:where(.navds-popover) {
border: none;
padding: var(--ax-spacing-4);
gap: var(--ax-spacing-2);
}
@media (min-width: 480px) {
.navds-date {
padding: var(--a-spacing-5) var(--a-spacing-4);
padding: var(--ax-spacing-5) var(--ax-spacing-4);
}
.navds-date__modal-body {
padding: var(--a-spacing-6);
padding: var(--ax-spacing-6);
}
.navds-date__caption {
gap: var(--a-spacing-2);
gap: var(--ax-spacing-2);
}
.navds-date .rdp-button,
@@ -17,6 +17,7 @@
/* ------------------------ ExpansionCard Small-size ------------------------ */
.navds-expansioncard--small {
--__axc-expansioncard-padding-inline: var(--ax-spacing-4);
--__axc-expansioncard-padding-block: var(--ax-spacing-3);
& > .navds-expansioncard__header .navds-expansioncard__title--small {
margin-top: var(--ax-spacing-05);
@@ -1,6 +1,6 @@
.navds-error-summary {
background-color: var(--ax-bg-default);
padding: var(--ax-spacing-5);
padding: var(--ax-spacing-4) var(--ax-spacing-5);
border: 4px solid var(--ax-border-danger);
border-radius: var(--ax-border-radius-xlarge);
outline-offset: 2px;
@@ -18,7 +18,7 @@
}
.navds-error-summary--small {
padding: var(--ax-spacing-3);
padding: var(--ax-spacing-3) var(--ax-spacing-4);
& .navds-error-summary__heading {
scroll-margin-top: var(--ax-spacing-4);
@@ -1,7 +1,6 @@
/* --------------------------- FileUpload Dropzone -------------------------- */
.navds-dropzone__area {
--__axc-dropzone-background: var(--ax-bg-input);
--__axc-dropzone-padding: var(--ax-spacing-6);
--__axc-dropzone-icon-padding: var(--ax-spacing-2);
--__axc-dropzone-animation-length-long: 400ms;
--__axc-dropzone-animation-length-short: 250ms;
@@ -15,7 +14,7 @@
flex-direction: column;
gap: var(--ax-spacing-4);
text-align: center;
padding: var(--__axc-dropzone-padding);
padding: var(--ax-spacing-4) var(--ax-spacing-5);
border: 1px dashed var(--ax-border-default);
border-radius: var(--ax-border-radius-xlarge);
background-color: var(--__axc-dropzone-background);
@@ -95,7 +94,7 @@
}
.navds-dropzone__area-release {
top: var(--__axc-dropzone-padding);
top: var(--ax-spacing-4);
display: grid;
position: absolute;
z-index: 1;
@@ -159,7 +158,7 @@ li.navds-file-item {
outline-offset: -1px;
transition: outline-color 250ms cubic-bezier(0, 0.3, 0.15, 1);
border-radius: var(--ax-border-radius-xlarge);
padding: var(--ax-spacing-3);
padding: var(--ax-spacing-3) var(--ax-spacing-4);
display: flex;
gap: var(--ax-spacing-3);
align-items: flex-start;
@@ -51,7 +51,7 @@
.navds-form-progress__stepper {
border: 1px solid var(--ax-border-subtle);
border-radius: var(--ax-border-radius-large);
padding: var(--ax-spacing-4);
padding: var(--ax-spacing-4) var(--ax-spacing-5);
margin-top: var(--ax-spacing-1);
background: var(--ax-bg-raised);
}
@@ -31,7 +31,7 @@
}
.navds-form-summary__answers {
padding: var(--ax-spacing-5) var(--ax-spacing-6) var(--ax-spacing-6);
padding: var(--ax-spacing-4) var(--ax-spacing-5);
margin: 0;
}
@@ -72,7 +72,7 @@
.navds-form-summary__value .navds-form-summary__answers {
margin-top: var(--ax-spacing-2);
padding: var(--ax-spacing-4);
padding: var(--ax-spacing-4) var(--ax-spacing-5);
background: var(--ax-bg-info-moderateA);
border-radius: var(--ax-border-radius-large);
border: 1px solid var(--ax-border-info-subtleA);
@@ -1,19 +1,3 @@
[data-theme="dark"] {
--__ac-search-button-border: var(--a-border-on-inverted);
--__ac-search-button-border-hover: var(--a-blue-200);
--__ac-search-clear-icon: var(--a-white);
--__ac-search-clear-icon-hover: var(--a-blue-200);
--__ac-search-error-border: var(--a-red-300);
}
[data-theme="light"] {
--__ac-search-button-border: initial;
--__ac-search-button-border-hover: initial;
--__ac-search-clear-icon: initial;
--__ac-search-clear-icon-hover: initial;
--__ac-search-error-border: initial;
}
.navds-search {
display: flex;
flex-direction: column;
@@ -25,204 +9,142 @@
width: 100%;
}
.navds-search--with-size :where(.navds-search__wrapper-inner) {
width: inherit;
.navds-search--with-size {
& .navds-search__wrapper-inner {
width: inherit;
}
& .navds-search__wrapper {
width: fit-content;
}
}
.navds-search__wrapper {
display: inline-flex;
align-items: center;
border-radius: var(--ax-border-radius-medium);
/* We have to outline the whole container to include the Search-buttons */
&:has(.navds-search__input:focus-visible) {
outline: 2px solid var(--ax-border-focus);
outline-offset: 2px;
}
}
/* ------------------------------ Search input ------------------------------ */
.navds-search__input {
padding-right: var(--a-spacing-10);
}
padding-right: var(--ax-spacing-10);
.navds-form-field--small .navds-search__input {
padding-right: var(--a-spacing-8);
&:focus-visible {
outline: none;
}
&.navds-search__input--primary,
&.navds-search__input--secondary {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-right: none;
}
}
.navds-search__input--simple {
padding-left: var(--a-spacing-11);
padding-left: var(--ax-spacing-10);
}
.navds-form-field--small .navds-search__input--simple {
padding-left: var(--a-spacing-7);
}
/* ------------------------------ Search sizing ----------------------------- */
.navds-form-field--small {
& .navds-search__input {
padding-right: var(--ax-spacing-7);
}
.navds-search__input:not(.navds-search__input--simple) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
& .navds-search__input--simple {
padding-left: var(--ax-spacing-7);
}
& .navds-search__search-icon {
left: var(--ax-spacing-1);
font-size: 1.25rem;
}
& .navds-search__button-clear {
right: var(--ax-spacing-1);
}
}
/* ------------------------------- Search icon ------------------------------ */
.navds-search__search-icon {
position: absolute;
left: var(--a-spacing-3);
left: var(--ax-spacing-2);
top: 50%;
transform: translateY(-50%);
pointer-events: none;
font-size: 1.5rem;
}
.navds-form-field--small .navds-search__search-icon {
left: var(--a-spacing-2);
font-size: 1rem;
}
.navds-search__button-clear {
position: absolute;
right: 0.75rem;
border-radius: var(--a-border-radius-medium);
color: var(--ac-search-clear-icon, var(--__ac-search-clear-icon, var(--a-text-default)));
height: 32px;
width: 32px;
top: 50%;
transform: translateY(-50%);
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
background: none;
border: none;
font-size: 1.25rem;
padding: 0;
}
.navds-form-field--small .navds-search__button-clear {
right: 0.5rem;
height: 24px;
width: 24px;
}
.navds-search__button-clear:hover {
color: var(--ac-search-clear-icon-hover, var(--__ac-search-clear-icon-hover, var(--a-text-action-hover)));
}
.navds-search__button-clear:focus-visible {
outline: 2px solid transparent;
box-shadow: var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-search__button-clear:focus {
outline: 2px solid transparent;
box-shadow: var(--a-shadow-focus);
.navds-search--disabled & {
opacity: 0.3;
}
}
/* --------------------------- Search Clear-button -------------------------- */
.navds-search__button-clear {
position: absolute;
right: var(--ax-spacing-2);
top: 50%;
transform: translateY(-50%);
}
/* ------------------------------ Search Button ----------------------------- */
.navds-search__button-search {
flex-shrink: 0;
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);
}
.navds-form-field--small .navds-search__button-search svg {
font-size: 1rem;
}
.navds-form-field--small .navds-search__button-search {
min-width: 2.5rem;
border-top-right-radius: var(--ax-border-radius-medium);
border-bottom-right-radius: var(--ax-border-radius-medium);
}
.navds-search__button-search.navds-button--secondary {
box-shadow:
-1px 0 0 0 var(--ac-search-button-border, var(--__ac-search-button-border, var(--a-border-default))) inset,
0 1px 0 0 var(--ac-search-button-border, var(--__ac-search-button-border, var(--a-border-default))) inset,
0 -1px 0 0 var(--ac-search-button-border, var(--__ac-search-button-border, var(--a-border-default))) inset;
}
--__axc-button-border-width: 1px;
--__axc-button-border-color: var(--ax-border-default);
.navds-search__button-search.navds-button--secondary:where(:hover, :active) {
box-shadow:
-1px 0 0 0 var(--ac-search-button-border-hover, var(--__ac-search-button-border-hover, var(--a-border-action-hover))) inset,
0 1px 0 0 var(--ac-search-button-border-hover, var(--__ac-search-button-border-hover, var(--a-border-action-hover))) inset,
0 -1px 0 0 var(--ac-search-button-border-hover, var(--__ac-search-button-border-hover, var(--a-border-action-hover))) inset,
-1px 0 0 0 var(--ac-search-button-border-hover, var(--__ac-search-button-border-hover, var(--a-border-action-hover)));
z-index: 1;
}
.navds-search__wrapper-inner:focus-within + .navds-search__button-search.navds-button--secondary:hover {
z-index: auto;
}
.navds-search__button-search.navds-button--secondary:focus-visible {
box-shadow:
0 0 0 1px var(--ac-search-button-border, var(--__ac-search-button-border, var(--a-border-default))) inset,
var(--a-shadow-focus);
}
.navds-search__button-search.navds-button--secondary:focus-visible:hover {
box-shadow:
0 0 0 1px var(--ac-search-button-border-hover, var(--__ac-search-button-border-hover, var(--a-border-action-hover))) inset,
var(--a-shadow-focus);
}
.navds-search__button-search.navds-button--secondary:focus-visible:active {
box-shadow:
0 0 0 1px var(--ac-search-button-focus-active-border, var(--a-surface-default)) inset,
var(--a-shadow-focus);
}
@supports not selector(:focus-visible) {
.navds-search__button-search.navds-button--secondary:focus {
box-shadow:
0 0 0 1px var(--ac-search-button-border, var(--__ac-search-button-border, var(--a-border-default))) inset,
var(--a-shadow-focus);
&:hover:not(:disabled) {
--__axc-button-border-color: var(--ax-border-accent-strong);
}
.navds-search__button-search.navds-button--secondary:focus:hover {
box-shadow:
0 0 0 1px var(--ac-search-button-border-hover, var(--__ac-search-button-border-hover, var(--a-border-action))) inset,
var(--a-shadow-focus);
}
.navds-search__button-search.navds-button--secondary:focus:active {
box-shadow:
0 0 0 1px var(--ac-search-button-focus-active-border, var(--a-surface-default)) inset,
var(--a-shadow-focus);
&:active:not(:disabled) {
--__axc-button-border-color: transparent;
}
}
/* Error-handling */
.navds-search--error .navds-search__input:not(:hover, :disabled) {
border-color: var(--ac-search-error-border, var(--__ac-search-error-border, var(--a-border-danger)));
box-shadow: inset 0 0 0 1px var(--ac-search-error-border, var(--__ac-search-error-border, var(--a-border-danger)));
/* Special-case where we hover/focus input, and want the secondary-button to match input-border */
.navds-search:not(.navds-search--error, .navds-search--disabled)
.navds-search__wrapper:has(.navds-search__input:is(:hover, :focus-visible))
.navds-search__button-search.navds-button--secondary:not(:hover, :active) {
--__axc-button-border-color: var(--ax-border-accent-strong);
}
.navds-search--error .navds-search__input:focus-visible:not(:hover, :disabled) {
/* --------------------------- Search Error-state --------------------------- */
.navds-search--error .navds-search__input:not(:disabled) {
border-color: var(--ax-border-danger);
box-shadow:
inset 0 0 0 1px var(--ac-search-error-border, var(--__ac-search-error-border, var(--a-border-danger))),
var(--a-shadow-focus);
inset -2px 0 0 0 var(--ax-border-danger),
inset 0 0 0 1px var(--ax-border-danger);
&.navds-search__input--simple {
box-shadow: inset 0 0 0 1px var(--ax-border-danger);
}
}
/* Focus layering */
/* -------------------------- Search Focus layering ------------------------- */
.navds-search__input:focus-visible,
.navds-search__button-clear,
.navds-search__button-search:focus-visible {
z-index: 1;
}
@supports not selector(:focus-visible) {
.navds-search--error .navds-search__input:focus:not(:hover, :disabled) {
box-shadow:
inset 0 0 0 1px var(--ac-search-error-border, var(--__ac-search-error-border, var(--a-border-danger))),
var(--a-shadow-focus);
}
/* -------------------------- Search disabled state ------------------------- */
.navds-search__input:focus,
.navds-search__button-search:focus {
z-index: 1;
}
}
@media (forced-colors: active) {
.navds-modal {
outline: 2px solid transparent;
}
.navds-search__button-clear:hover {
color: highlight;
/* We can't re-use disabled-state for form-fields since opacity multiplies on search-button */
.navds-search--disabled {
.navds-search__input {
opacity: 0.3;
cursor: not-allowed;
}
}
@@ -25,7 +25,7 @@
}
&::placeholder {
color: var(--ax-text-subtle);
color: var(--ax-text-neutral);
}
&[size] {
+1 -4
View File
@@ -13,9 +13,6 @@
@import "@navikt/ds-tokens/dist/darkside/tokens.css" layer(aksel.theme);
@import "./baseline/theme.darkside.css" layer(aksel.theme);
/* TODO: Remove this reference after stack is updated with darkside support */
@import "../primitives/stack.css" layer(aksel.components);
/* ------------------------------- Components ------------------------------- */
@import "./button.darkside.css" layer(aksel.components);
@import "./chips.darkside.css" layer(aksel.components);
@@ -31,6 +28,7 @@
@import "./alert.darkside.css" layer(aksel.components);
@import "./chat.darkside.css" layer(aksel.components);
@import "./copybutton.darkside.css" layer(aksel.components);
@import "./date.darkside.css" layer(aksel.components);
@import "./dropdown.darkside.css" layer(aksel.components);
@import "./action-menu.darkside.css" layer(aksel.components);
@import "./expansioncard.darkside.css" layer(aksel.components);
@@ -42,7 +40,6 @@
@import "./modal.darkside.css" layer(aksel.components);
@import "./pagination.darkside.css" layer(aksel.components);
@import "./popover.darkside.css" layer(aksel.components);
@import "./date.darkside.css" layer(aksel.components);
@import "./tag.darkside.css" layer(aksel.components);
@import "./timeline.darkside.css" layer(aksel.components);
@import "./tooltip.darkside.css" layer(aksel.components);
+6 -6
View File
@@ -60,15 +60,15 @@
width: 450px;
& .navds-modal__header {
padding: var(--ax-spacing-4) var(--ax-spacing-4) var(--ax-spacing-3) var(--ax-spacing-4);
padding: var(--ax-spacing-3) var(--ax-spacing-4);
}
& .navds-modal__body {
padding: var(--ax-spacing-2) var(--ax-spacing-4) var(--ax-spacing-4);
padding: var(--ax-spacing-3) var(--ax-spacing-4);
}
& .navds-modal__footer {
padding: var(--ax-spacing-4);
padding: var(--ax-spacing-3) var(--ax-spacing-4);
}
}
@@ -121,7 +121,7 @@
}
.navds-modal__header {
padding: var(--ax-spacing-6) var(--ax-spacing-6) var(--ax-spacing-4) var(--ax-spacing-6);
padding: var(--ax-spacing-4) var(--ax-spacing-5);
}
.navds-modal__header-icon {
@@ -138,7 +138,7 @@
}
.navds-modal__body {
padding: var(--ax-spacing-6);
padding: var(--ax-spacing-4) var(--ax-spacing-5);
overflow: auto;
overscroll-behavior: contain;
position: relative; /* Needed to make sr-only elements position correctly - see Storybook */
@@ -164,7 +164,7 @@
display: flex;
flex-flow: row-reverse wrap;
gap: var(--ax-spacing-4);
padding: var(--ax-spacing-4) var(--ax-spacing-6) var(--ax-spacing-6) var(--ax-spacing-6);
padding: var(--ax-spacing-4) var(--ax-spacing-5);
}
.navds-modal__footer :nth-of-type(2) {
@@ -10,7 +10,7 @@
}
.navds-popover__content {
padding: var(--ax-spacing-4);
padding: var(--ax-spacing-4) var(--ax-spacing-5);
}
.navds-popover--hidden {
File diff suppressed because it is too large. Load diff
@@ -1,103 +1,103 @@
.navds-bleed {
--__ac-bleed-margin-inline-xs: initial;
--__ac-bleed-margin-inline-sm: var(--__ac-bleed-margin-inline-xs);
--__ac-bleed-margin-inline-md: var(--__ac-bleed-margin-inline-sm);
--__ac-bleed-margin-inline-lg: var(--__ac-bleed-margin-inline-md);
--__ac-bleed-margin-inline-xl: var(--__ac-bleed-margin-inline-lg);
--__ac-bleed-margin-inline-2xl: var(--__ac-bleed-margin-inline-xl);
--__ac-bleed-margin-block-xs: initial;
--__ac-bleed-margin-block-sm: var(--__ac-bleed-margin-block-xs);
--__ac-bleed-margin-block-md: var(--__ac-bleed-margin-block-sm);
--__ac-bleed-margin-block-lg: var(--__ac-bleed-margin-block-md);
--__ac-bleed-margin-block-xl: var(--__ac-bleed-margin-block-lg);
--__ac-bleed-margin-block-2xl: var(--__ac-bleed-margin-block-xl);
--__axc-bleed-margin-inline-xs: initial;
--__axc-bleed-margin-inline-sm: var(--__axc-bleed-margin-inline-xs);
--__axc-bleed-margin-inline-md: var(--__axc-bleed-margin-inline-sm);
--__axc-bleed-margin-inline-lg: var(--__axc-bleed-margin-inline-md);
--__axc-bleed-margin-inline-xl: var(--__axc-bleed-margin-inline-lg);
--__axc-bleed-margin-inline-2xl: var(--__axc-bleed-margin-inline-xl);
--__axc-bleed-margin-block-xs: initial;
--__axc-bleed-margin-block-sm: var(--__axc-bleed-margin-block-xs);
--__axc-bleed-margin-block-md: var(--__axc-bleed-margin-block-sm);
--__axc-bleed-margin-block-lg: var(--__axc-bleed-margin-block-md);
--__axc-bleed-margin-block-xl: var(--__axc-bleed-margin-block-lg);
--__axc-bleed-margin-block-2xl: var(--__axc-bleed-margin-block-xl);
/** defaults */
--__ac-bleed-margin-inline: var(--__ac-bleed-margin-inline-xs);
--__ac-bleed-margin-block: var(--__ac-bleed-margin-block-xs);
--__axc-bleed-margin-inline: var(--__axc-bleed-margin-inline-xs);
--__axc-bleed-margin-block: var(--__axc-bleed-margin-block-xs);
margin-inline: var(--__ac-bleed-margin-inline);
margin-block: var(--__ac-bleed-margin-block);
margin-inline: var(--__axc-bleed-margin-inline);
margin-block: var(--__axc-bleed-margin-block);
}
.navds-bleed--padding {
--__ac-bleed-padding-inline-xs: initial;
--__ac-bleed-padding-inline-sm: var(--__ac-bleed-padding-inline-xs);
--__ac-bleed-padding-inline-md: var(--__ac-bleed-padding-inline-sm);
--__ac-bleed-padding-inline-lg: var(--__ac-bleed-padding-inline-md);
--__ac-bleed-padding-inline-xl: var(--__ac-bleed-padding-inline-lg);
--__ac-bleed-padding-inline-2xl: var(--__ac-bleed-padding-inline-xl);
--__ac-bleed-padding-block-xs: initial;
--__ac-bleed-padding-block-sm: var(--__ac-bleed-padding-block-xs);
--__ac-bleed-padding-block-md: var(--__ac-bleed-padding-block-sm);
--__ac-bleed-padding-block-lg: var(--__ac-bleed-padding-block-md);
--__ac-bleed-padding-block-xl: var(--__ac-bleed-padding-block-lg);
--__ac-bleed-padding-block-2xl: var(--__ac-bleed-padding-block-xl);
--__axc-bleed-padding-inline-xs: initial;
--__axc-bleed-padding-inline-sm: var(--__axc-bleed-padding-inline-xs);
--__axc-bleed-padding-inline-md: var(--__axc-bleed-padding-inline-sm);
--__axc-bleed-padding-inline-lg: var(--__axc-bleed-padding-inline-md);
--__axc-bleed-padding-inline-xl: var(--__axc-bleed-padding-inline-lg);
--__axc-bleed-padding-inline-2xl: var(--__axc-bleed-padding-inline-xl);
--__axc-bleed-padding-block-xs: initial;
--__axc-bleed-padding-block-sm: var(--__axc-bleed-padding-block-xs);
--__axc-bleed-padding-block-md: var(--__axc-bleed-padding-block-sm);
--__axc-bleed-padding-block-lg: var(--__axc-bleed-padding-block-md);
--__axc-bleed-padding-block-xl: var(--__axc-bleed-padding-block-lg);
--__axc-bleed-padding-block-2xl: var(--__axc-bleed-padding-block-xl);
/** defaults */
--__ac-bleed-padding-inline: var(--__ac-bleed-padding-inline-xs);
--__ac-bleed-padding-block: var(--__ac-bleed-padding-block-xs);
--__axc-bleed-padding-inline: var(--__axc-bleed-padding-inline-xs);
--__axc-bleed-padding-block: var(--__axc-bleed-padding-block-xs);
padding-inline: var(--__ac-bleed-padding-inline);
padding-block: var(--__ac-bleed-padding-block);
padding-inline: var(--__axc-bleed-padding-inline);
padding-block: var(--__axc-bleed-padding-block);
}
@media (min-width: 480px) {
.navds-bleed {
--__ac-bleed-margin-inline: var(--__ac-bleed-margin-inline-sm);
--__ac-bleed-margin-block: var(--__ac-bleed-margin-block-sm);
--__axc-bleed-margin-inline: var(--__axc-bleed-margin-inline-sm);
--__axc-bleed-margin-block: var(--__axc-bleed-margin-block-sm);
}
.navds-bleed--padding {
--__ac-bleed-padding-inline: var(--__ac-bleed-padding-inline-sm);
--__ac-bleed-padding-block: var(--__ac-bleed-padding-block-sm);
--__axc-bleed-padding-inline: var(--__axc-bleed-padding-inline-sm);
--__axc-bleed-padding-block: var(--__axc-bleed-padding-block-sm);
}
}
@media (min-width: 768px) {
.navds-bleed {
--__ac-bleed-margin-inline: var(--__ac-bleed-margin-inline-md);
--__ac-bleed-margin-block: var(--__ac-bleed-margin-block-md);
--__axc-bleed-margin-inline: var(--__axc-bleed-margin-inline-md);
--__axc-bleed-margin-block: var(--__axc-bleed-margin-block-md);
}
.navds-bleed--padding {
--__ac-bleed-padding-inline: var(--__ac-bleed-padding-inline-md);
--__ac-bleed-padding-block: var(--__ac-bleed-padding-block-md);
--__axc-bleed-padding-inline: var(--__axc-bleed-padding-inline-md);
--__axc-bleed-padding-block: var(--__axc-bleed-padding-block-md);
}
}
@media (min-width: 1024px) {
.navds-bleed {
--__ac-bleed-margin-inline: var(--__ac-bleed-margin-inline-lg);
--__ac-bleed-margin-block: var(--__ac-bleed-margin-block-lg);
--__axc-bleed-margin-inline: var(--__axc-bleed-margin-inline-lg);
--__axc-bleed-margin-block: var(--__axc-bleed-margin-block-lg);
}
.navds-bleed--padding {
--__ac-bleed-padding-inline: var(--__ac-bleed-padding-inline-lg);
--__ac-bleed-padding-block: var(--__ac-bleed-padding-block-lg);
--__axc-bleed-padding-inline: var(--__axc-bleed-padding-inline-lg);
--__axc-bleed-padding-block: var(--__axc-bleed-padding-block-lg);
}
}
@media (min-width: 1280px) {
.navds-bleed {
--__ac-bleed-margin-inline: var(--__ac-bleed-margin-inline-xl);
--__ac-bleed-margin-block: var(--__ac-bleed-margin-block-xl);
--__axc-bleed-margin-inline: var(--__axc-bleed-margin-inline-xl);
--__axc-bleed-margin-block: var(--__axc-bleed-margin-block-xl);
}
.navds-bleed--padding {
--__ac-bleed-padding-inline: var(--__ac-bleed-padding-inline-xl);
--__ac-bleed-padding-block: var(--__ac-bleed-padding-block-xl);
--__axc-bleed-padding-inline: var(--__axc-bleed-padding-inline-xl);
--__axc-bleed-padding-block: var(--__axc-bleed-padding-block-xl);
}
}
@media (min-width: 1440px) {
.navds-bleed {
--__ac-bleed-margin-inline: var(--__ac-bleed-margin-inline-2xl);
--__ac-bleed-margin-block: var(--__ac-bleed-margin-block-2xl);
--__axc-bleed-margin-inline: var(--__axc-bleed-margin-inline-2xl);
--__axc-bleed-margin-block: var(--__axc-bleed-margin-block-2xl);
}
.navds-bleed--padding {
--__ac-bleed-padding-inline: var(--__ac-bleed-padding-inline-2xl);
--__ac-bleed-padding-block: var(--__ac-bleed-padding-block-2xl);
--__axc-bleed-padding-inline: var(--__axc-bleed-padding-inline-2xl);
--__axc-bleed-padding-block: var(--__axc-bleed-padding-block-2xl);
}
}
@@ -1,66 +1,66 @@
.navds-box-bg {
--__ac-box-background: initial;
--__axc-box-background: initial;
background-color: var(--__ac-box-background);
background-color: var(--__axc-box-background);
}
.navds-box-border-color {
--__ac-box-border-color: initial;
--__axc-box-border-color: initial;
border-color: var(--__ac-box-border-color);
border-color: var(--__axc-box-border-color);
}
.navds-box-border-width {
--__ac-box-border-width: initial;
--__axc-box-border-width: initial;
border-style: solid;
border-width: var(--__ac-box-border-width, 0);
border-width: var(--__axc-box-border-width, 0);
}
.navds-box-border-radius {
--__ac-box-border-radius-xs: initial;
--__ac-box-border-radius-sm: var(--__ac-box-border-radius-xs);
--__ac-box-border-radius-md: var(--__ac-box-border-radius-sm);
--__ac-box-border-radius-lg: var(--__ac-box-border-radius-md);
--__ac-box-border-radius-xl: var(--__ac-box-border-radius-lg);
--__ac-box-border-radius-2xl: var(--__ac-box-border-radius-xl);
--__ac-box-border-radius: var(--__ac-box-border-radius-xs);
--__axc-box-border-radius-xs: initial;
--__axc-box-border-radius-sm: var(--__axc-box-border-radius-xs);
--__axc-box-border-radius-md: var(--__axc-box-border-radius-sm);
--__axc-box-border-radius-lg: var(--__axc-box-border-radius-md);
--__axc-box-border-radius-xl: var(--__axc-box-border-radius-lg);
--__axc-box-border-radius-2xl: var(--__axc-box-border-radius-xl);
--__axc-box-border-radius: var(--__axc-box-border-radius-xs);
border-radius: var(--__ac-box-border-radius);
border-radius: var(--__axc-box-border-radius);
}
.navds-box-shadow {
--__ac-box-shadow: initial;
--__axc-box-shadow: initial;
box-shadow: var(--__ac-box-shadow);
box-shadow: var(--__axc-box-shadow);
}
@media (min-width: 480px) {
.navds-box-border-radius {
--__ac-box-border-radius: var(--__ac-box-border-radius-sm);
--__axc-box-border-radius: var(--__axc-box-border-radius-sm);
}
}
@media (min-width: 768px) {
.navds-box-border-radius {
--__ac-box-border-radius: var(--__ac-box-border-radius-md);
--__axc-box-border-radius: var(--__axc-box-border-radius-md);
}
}
@media (min-width: 1024px) {
.navds-box-border-radius {
--__ac-box-border-radius: var(--__ac-box-border-radius-lg);
--__axc-box-border-radius: var(--__axc-box-border-radius-lg);
}
}
@media (min-width: 1280px) {
.navds-box-border-radius {
--__ac-box-border-radius: var(--__ac-box-border-radius-xl);
--__axc-box-border-radius: var(--__axc-box-border-radius-xl);
}
}
@media (min-width: 1440px) {
.navds-box-border-radius {
--__ac-box-border-radius: var(--__ac-box-border-radius-2xl);
--__axc-box-border-radius: var(--__axc-box-border-radius-2xl);
}
}
@@ -1,80 +1,80 @@
.navds-hgrid {
--__ac-hgrid-columns-xs: initial;
--__ac-hgrid-columns-sm: var(--__ac-hgrid-columns-xs);
--__ac-hgrid-columns-md: var(--__ac-hgrid-columns-sm);
--__ac-hgrid-columns-lg: var(--__ac-hgrid-columns-md);
--__ac-hgrid-columns-xl: var(--__ac-hgrid-columns-lg);
--__ac-hgrid-columns-2xl: var(--__ac-hgrid-columns-xl);
--__ac-hgrid-columns: var(--__ac-hgrid-columns-xs);
--__axc-hgrid-columns-xs: initial;
--__axc-hgrid-columns-sm: var(--__axc-hgrid-columns-xs);
--__axc-hgrid-columns-md: var(--__axc-hgrid-columns-sm);
--__axc-hgrid-columns-lg: var(--__axc-hgrid-columns-md);
--__axc-hgrid-columns-xl: var(--__axc-hgrid-columns-lg);
--__axc-hgrid-columns-2xl: var(--__axc-hgrid-columns-xl);
--__axc-hgrid-columns: var(--__axc-hgrid-columns-xs);
display: grid;
grid-template-columns: var(--__ac-hgrid-columns);
grid-template-columns: var(--__axc-hgrid-columns);
}
.navds-hgrid-gap {
--__ac-hgrid-gap-xs: initial;
--__ac-hgrid-gap-sm: var(--__ac-hgrid-gap-xs);
--__ac-hgrid-gap-md: var(--__ac-hgrid-gap-sm);
--__ac-hgrid-gap-lg: var(--__ac-hgrid-gap-md);
--__ac-hgrid-gap-xl: var(--__ac-hgrid-gap-lg);
--__ac-hgrid-gap-2xl: var(--__ac-hgrid-gap-xl);
--__ac-hgrid-gap: var(--__ac-hgrid-gap-xs);
--__axc-hgrid-gap-xs: initial;
--__axc-hgrid-gap-sm: var(--__axc-hgrid-gap-xs);
--__axc-hgrid-gap-md: var(--__axc-hgrid-gap-sm);
--__axc-hgrid-gap-lg: var(--__axc-hgrid-gap-md);
--__axc-hgrid-gap-xl: var(--__axc-hgrid-gap-lg);
--__axc-hgrid-gap-2xl: var(--__axc-hgrid-gap-xl);
--__axc-hgrid-gap: var(--__axc-hgrid-gap-xs);
gap: var(--__ac-hgrid-gap);
gap: var(--__axc-hgrid-gap);
}
.navds-hgrid-align {
--__ac-hgrid-align: initial;
--__axc-hgrid-align: initial;
align-items: var(--__ac-hgrid-align);
align-items: var(--__axc-hgrid-align);
}
@media (min-width: 480px) {
.navds-hgrid {
--__ac-hgrid-columns: var(--__ac-hgrid-columns-sm);
--__axc-hgrid-columns: var(--__axc-hgrid-columns-sm);
}
.navds-hgrid-gap {
--__ac-hgrid-gap: var(--__ac-hgrid-gap-sm);
--__axc-hgrid-gap: var(--__axc-hgrid-gap-sm);
}
}
@media (min-width: 768px) {
.navds-hgrid {
--__ac-hgrid-columns: var(--__ac-hgrid-columns-md);
--__axc-hgrid-columns: var(--__axc-hgrid-columns-md);
}
.navds-hgrid-gap {
--__ac-hgrid-gap: var(--__ac-hgrid-gap-md);
--__axc-hgrid-gap: var(--__axc-hgrid-gap-md);
}
}
@media (min-width: 1024px) {
.navds-hgrid {
--__ac-hgrid-columns: var(--__ac-hgrid-columns-lg);
--__axc-hgrid-columns: var(--__axc-hgrid-columns-lg);
}
.navds-hgrid-gap {
--__ac-hgrid-gap: var(--__ac-hgrid-gap-lg);
--__axc-hgrid-gap: var(--__axc-hgrid-gap-lg);
}
}
@media (min-width: 1280px) {
.navds-hgrid {
--__ac-hgrid-columns: var(--__ac-hgrid-columns-xl);
--__axc-hgrid-columns: var(--__axc-hgrid-columns-xl);
}
.navds-hgrid-gap {
--__ac-hgrid-gap: var(--__ac-hgrid-gap-xl);
--__axc-hgrid-gap: var(--__axc-hgrid-gap-xl);
}
}
@media (min-width: 1440px) {
.navds-hgrid {
--__ac-hgrid-columns: var(--__ac-hgrid-columns-2xl);
--__axc-hgrid-columns: var(--__axc-hgrid-columns-2xl);
}
.navds-hgrid-gap {
--__ac-hgrid-gap: var(--__ac-hgrid-gap-2xl);
--__axc-hgrid-gap: var(--__axc-hgrid-gap-2xl);
}
}
@@ -5,28 +5,3 @@
@import "./hgrid.darkside.css";
@import "./stack.darkside.css";
@import "./responsive.darkside.css";
/* TODO: Custom override to avoid having to edit react-syntax in Primtives. Remove after fix */
:root {
--a-spacing-1-alt: var(--ax-spacing-1-alt);
--a-spacing-05: var(--ax-spacing-05);
--a-spacing-32: var(--ax-spacing-32);
--a-spacing-24: var(--ax-spacing-24);
--a-spacing-20: var(--ax-spacing-20);
--a-spacing-18: var(--ax-spacing-18);
--a-spacing-16: var(--ax-spacing-16);
--a-spacing-14: var(--ax-spacing-14);
--a-spacing-12: var(--ax-spacing-12);
--a-spacing-11: var(--ax-spacing-11);
--a-spacing-10: var(--ax-spacing-10);
--a-spacing-9: var(--ax-spacing-9);
--a-spacing-8: var(--ax-spacing-8);
--a-spacing-7: var(--ax-spacing-7);
--a-spacing-6: var(--ax-spacing-6);
--a-spacing-5: var(--ax-spacing-5);
--a-spacing-4: var(--ax-spacing-4);
--a-spacing-3: var(--ax-spacing-3);
--a-spacing-2: var(--ax-spacing-2);
--a-spacing-1: var(--ax-spacing-1);
--a-spacing-0: var(--ax-spacing-0);
}
@@ -3,15 +3,12 @@
flex-direction: column;
min-height: 100vh;
min-height: 100lvh;
/* stylelint-disable-next-line csstools/value-no-unknown-custom-properties */
background-color: var(--__ac-page-background);
}
/* Page.Block */
.navds-pageblock {
/* stylelint-disable-next-line length-zero-no-unit */
--__ac-page-padding-inline: 0px;
--__axc-page-padding-inline: 0px;
margin-inline: auto;
width: 100%;
@@ -27,11 +24,11 @@
}
.navds-page__content--padding {
padding-block-end: var(--a-spacing-16);
padding-block-end: var(--ax-spacing-16);
}
.navds-pageblock--text {
max-width: calc(var(--a-text-width-max) + var(--__ac-page-padding-inline) + var(--__ac-page-padding-inline));
max-width: calc(576px + var(--__axc-page-padding-inline) + var(--__axc-page-padding-inline));
}
.navds-pageblock--md {
@@ -51,13 +48,13 @@
}
.navds-pageblock--gutters {
--__ac-page-padding-inline: var(--a-spacing-4);
--__axc-page-padding-inline: var(--a-spacing-4);
padding-inline: var(--__ac-page-padding-inline);
padding-inline: var(--__axc-page-padding-inline);
}
@media (min-width: 1024px) {
.navds-pageblock--gutters {
--__ac-page-padding-inline: var(--a-spacing-12);
--__axc-page-padding-inline: var(--a-spacing-12);
}
}
@@ -3,51 +3,51 @@
}
.navds-stack-gap {
--__ac-stack-gap-xs: initial;
--__ac-stack-gap-sm: var(--__ac-stack-gap-xs);
--__ac-stack-gap-md: var(--__ac-stack-gap-sm);
--__ac-stack-gap-lg: var(--__ac-stack-gap-md);
--__ac-stack-gap-xl: var(--__ac-stack-gap-lg);
--__ac-stack-gap-2xl: var(--__ac-stack-gap-xl);
--__ac-stack-gap: var(--__ac-stack-gap-xs);
--__axc-stack-gap-xs: initial;
--__axc-stack-gap-sm: var(--__axc-stack-gap-xs);
--__axc-stack-gap-md: var(--__axc-stack-gap-sm);
--__axc-stack-gap-lg: var(--__axc-stack-gap-md);
--__axc-stack-gap-xl: var(--__axc-stack-gap-lg);
--__axc-stack-gap-2xl: var(--__axc-stack-gap-xl);
--__axc-stack-gap: var(--__axc-stack-gap-xs);
gap: var(--__ac-stack-gap);
gap: var(--__axc-stack-gap);
}
.navds-stack-align {
--__ac-stack-align-xs: initial;
--__ac-stack-align-sm: var(--__ac-stack-align-xs);
--__ac-stack-align-md: var(--__ac-stack-align-sm);
--__ac-stack-align-lg: var(--__ac-stack-align-md);
--__ac-stack-align-xl: var(--__ac-stack-align-lg);
--__ac-stack-align-2xl: var(--__ac-stack-align-xl);
--__ac-stack-align: var(--__ac-stack-align-xs);
--__axc-stack-align-xs: initial;
--__axc-stack-align-sm: var(--__axc-stack-align-xs);
--__axc-stack-align-md: var(--__axc-stack-align-sm);
--__axc-stack-align-lg: var(--__axc-stack-align-md);
--__axc-stack-align-xl: var(--__axc-stack-align-lg);
--__axc-stack-align-2xl: var(--__axc-stack-align-xl);
--__axc-stack-align: var(--__axc-stack-align-xs);
align-items: var(--__ac-stack-align);
align-items: var(--__axc-stack-align);
}
.navds-stack-justify {
--__ac-stack-justify-xs: initial;
--__ac-stack-justify-sm: var(--__ac-stack-justify-xs);
--__ac-stack-justify-md: var(--__ac-stack-justify-sm);
--__ac-stack-justify-lg: var(--__ac-stack-justify-md);
--__ac-stack-justify-xl: var(--__ac-stack-justify-lg);
--__ac-stack-justify-2xl: var(--__ac-stack-justify-xl);
--__ac-stack-justify: var(--__ac-stack-justify-xs);
--__axc-stack-justify-xs: initial;
--__axc-stack-justify-sm: var(--__axc-stack-justify-xs);
--__axc-stack-justify-md: var(--__axc-stack-justify-sm);
--__axc-stack-justify-lg: var(--__axc-stack-justify-md);
--__axc-stack-justify-xl: var(--__axc-stack-justify-lg);
--__axc-stack-justify-2xl: var(--__axc-stack-justify-xl);
--__axc-stack-justify: var(--__axc-stack-justify-xs);
justify-content: var(--__ac-stack-justify);
justify-content: var(--__axc-stack-justify);
}
.navds-stack-direction {
--__ac-stack-direction-xs: initial;
--__ac-stack-direction-sm: var(--__ac-stack-direction-xs);
--__ac-stack-direction-md: var(--__ac-stack-direction-sm);
--__ac-stack-direction-lg: var(--__ac-stack-direction-md);
--__ac-stack-direction-xl: var(--__ac-stack-direction-lg);
--__ac-stack-direction-2xl: var(--__ac-stack-direction-xl);
--__ac-stack-direction: var(--__ac-stack-direction-xs);
--__axc-stack-direction-xs: initial;
--__axc-stack-direction-sm: var(--__axc-stack-direction-xs);
--__axc-stack-direction-md: var(--__axc-stack-direction-sm);
--__axc-stack-direction-lg: var(--__axc-stack-direction-md);
--__axc-stack-direction-xl: var(--__axc-stack-direction-lg);
--__axc-stack-direction-2xl: var(--__axc-stack-direction-xl);
--__axc-stack-direction: var(--__axc-stack-direction-xs);
flex-direction: var(--__ac-stack-direction);
flex-direction: var(--__axc-stack-direction);
}
.navds-stack-wrap {
@@ -60,96 +60,96 @@
}
.navds-stack > .navds-stack__spacer {
margin-block-start: calc(var(--__ac-stack-gap) * -1);
margin-inline-start: calc(var(--__ac-stack-gap) * -1);
margin-block-start: calc(var(--__axc-stack-gap) * -1);
margin-inline-start: calc(var(--__axc-stack-gap) * -1);
}
@media (min-width: 480px) {
.navds-stack-gap {
--__ac-stack-gap: var(--__ac-stack-gap-sm);
--__axc-stack-gap: var(--__axc-stack-gap-sm);
}
.navds-stack-align {
--__ac-stack-align: var(--__ac-stack-align-sm);
--__axc-stack-align: var(--__axc-stack-align-sm);
}
.navds-stack-justify {
--__ac-stack-justify: var(--__ac-stack-justify-sm);
--__axc-stack-justify: var(--__axc-stack-justify-sm);
}
.navds-stack-direction {
--__ac-stack-direction: var(--__ac-stack-direction-sm);
--__axc-stack-direction: var(--__axc-stack-direction-sm);
}
}
@media (min-width: 768px) {
.navds-stack-gap {
--__ac-stack-gap: var(--__ac-stack-gap-md);
--__axc-stack-gap: var(--__axc-stack-gap-md);
}
.navds-stack-align {
--__ac-stack-align: var(--__ac-stack-align-md);
--__axc-stack-align: var(--__axc-stack-align-md);
}
.navds-stack-justify {
--__ac-stack-justify: var(--__ac-stack-justify-md);
--__axc-stack-justify: var(--__axc-stack-justify-md);
}
.navds-stack-direction {
--__ac-stack-direction: var(--__ac-stack-direction-md);
--__axc-stack-direction: var(--__axc-stack-direction-md);
}
}
@media (min-width: 1024px) {
.navds-stack-gap {
--__ac-stack-gap: var(--__ac-stack-gap-lg);
--__axc-stack-gap: var(--__axc-stack-gap-lg);
}
.navds-stack-align {
--__ac-stack-align: var(--__ac-stack-align-lg);
--__axc-stack-align: var(--__axc-stack-align-lg);
}
.navds-stack-justify {
--__ac-stack-justify: var(--__ac-stack-justify-lg);
--__axc-stack-justify: var(--__axc-stack-justify-lg);
}
.navds-stack-direction {
--__ac-stack-direction: var(--__ac-stack-direction-lg);
--__axc-stack-direction: var(--__axc-stack-direction-lg);
}
}
@media (min-width: 1280px) {
.navds-stack-gap {
--__ac-stack-gap: var(--__ac-stack-gap-xl);
--__axc-stack-gap: var(--__axc-stack-gap-xl);
}
.navds-stack-align {
--__ac-stack-align: var(--__ac-stack-align-xl);
--__axc-stack-align: var(--__axc-stack-align-xl);
}
.navds-stack-justify {
--__ac-stack-justify: var(--__ac-stack-justify-xl);
--__axc-stack-justify: var(--__axc-stack-justify-xl);
}
.navds-stack-direction {
--__ac-stack-direction: var(--__ac-stack-direction-xl);
--__axc-stack-direction: var(--__axc-stack-direction-xl);
}
}
@media (min-width: 1440px) {
.navds-stack-gap {
--__ac-stack-gap: var(--__ac-stack-gap-2xl);
--__axc-stack-gap: var(--__axc-stack-gap-2xl);
}
.navds-stack-align {
--__ac-stack-align: var(--__ac-stack-align-2xl);
--__axc-stack-align: var(--__axc-stack-align-2xl);
}
.navds-stack-justify {
--__ac-stack-justify: var(--__ac-stack-justify-2xl);
--__axc-stack-justify: var(--__axc-stack-justify-2xl);
}
.navds-stack-direction {
--__ac-stack-direction: var(--__ac-stack-direction-2xl);
--__axc-stack-direction: var(--__axc-stack-direction-2xl);
}
}
@@ -1,180 +1,112 @@
.navds-toggle-group__wrapper {
display: grid;
justify-items: start;
gap: var(--a-spacing-2);
gap: var(--ax-spacing-2);
}
.navds-toggle-group__wrapper--fill {
justify-items: initial;
}
/* Main Togglegroup */
.navds-toggle-group {
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) + 0.0625rem);
gap: var(--a-spacing-1);
border-radius: var(--ax-border-radius-medium);
background-color: transparent;
box-shadow: inset 0 0 0 1px var(--ax-border-default);
padding: var(--ax-spacing-1);
gap: var(--ax-spacing-1);
display: inline-grid;
grid-auto-flow: column;
grid-auto-columns: 1fr;
}
.navds-toggle-group--small {
padding: calc(var(--a-spacing-05) + 0.0625rem);
}
.navds-toggle-group--neutral {
background-color: var(--ac-toggle-group-neutral-bg, var(--a-surface-transparent));
box-shadow: inset 0 0 0 1px var(--ac-toggle-group-neutral-border, var(--a-border-default));
}
/* Button */
.navds-toggle-group__button {
display: inline-flex;
align-items: center;
justify-content: center;
padding: var(--a-spacing-1) var(--a-spacing-3);
min-height: 2.375rem;
padding: var(--ax-spacing-1) var(--ax-spacing-3);
min-height: 2.5rem;
border: none;
cursor: pointer;
background-color: var(--ac-toggle-group-button-bg, var(--a-surface-transparent));
color: var(--ac-toggle-group-button-text, var(--a-text-default));
border-radius: var(--a-border-radius-small);
background-color: transparent;
color: var(--ax-text-default);
border-radius: var(--ax-border-radius-small);
min-width: fit-content;
font-weight: var(--a-font-weight-regular);
}
.navds-toggle-group--medium > :where(.navds-toggle-group__button:first-of-type:focus-visible) {
border-start-start-radius: 1px;
border-end-start-radius: 1px;
}
.navds-toggle-group--medium > :where(.navds-toggle-group__button:last-of-type:focus-visible) {
border-start-end-radius: 1px;
border-end-end-radius: 1px;
}
.navds-toggle-group--neutral > .navds-toggle-group__button {
background-color: var(--ac-toggle-group-button-neutral-bg, var(--a-surface-transparent));
color: var(--ac-toggle-group-button-neutral-text, var(--a-text-default));
}
.navds-toggle-group__button:hover {
background-color: var(--ac-toggle-group-button-hover-bg, var(--a-surface-action-subtle));
color: var(--ac-toggle-group-button-hover-text, var(--a-text-default));
}
.navds-toggle-group--neutral > .navds-toggle-group__button:hover {
background-color: var(--ac-toggle-group-button-neutral-hover-bg, var(--a-surface-neutral-subtle-hover));
color: var(--ac-toggle-group-button-neutral-hover-text, var(--a-text-default));
}
.navds-toggle-group__button:focus-visible {
outline: 2px solid transparent;
outline-offset: 1px;
box-shadow:
0 0 0 1px var(--a-surface-default),
0 0 0 4px var(--a-border-focus);
}
@supports not selector(:focus-visible) {
.navds-toggle-group__button:focus {
outline: 2px solid transparent;
outline-offset: 1px;
box-shadow:
0 0 0 1px var(--a-surface-default),
0 0 0 4px var(--a-border-focus);
&:hover {
background-color: var(--ax-bg-accent-moderate-hoverA);
color: var(--ax-text-default);
}
}
.navds-toggle-group__button:focus-visible:hover[aria-pressed="false"] {
box-shadow:
0 0 0 1px var(--ac-toggle-group-button-hover-bg, var(--a-surface-action-subtle)),
0 0 0 4px var(--a-border-focus);
}
@supports not selector(:focus-visible) {
.navds-toggle-group__button:focus:hover[aria-pressed="false"] {
box-shadow:
0 0 0 1px var(--ac-toggle-group-button-hover-bg, var(--a-surface-action-subtle)),
0 0 0 4px var(--a-border-focus);
&:focus-visible {
outline: 2px solid var(--ax-border-focus);
outline-offset: 2px;
}
}
.navds-toggle-group--neutral > .navds-toggle-group__button:focus:hover[aria-pressed="false"] {
box-shadow:
0 0 0 1px var(--ac-toggle-group-button-neutral-hover-bg, var(--a-surface-neutral-subtle-hover)),
0 0 0 4px var(--a-border-focus);
}
@supports not selector(:focus-visible) {
.navds-toggle-group--neutral > .navds-toggle-group__button:focus-visible:hover[aria-pressed="false"] {
box-shadow:
0 0 0 1px var(--ac-toggle-group-button-neutral-hover-bg, var(--a-surface-neutral-subtle-hover)),
0 0 0 4px var(--a-border-focus);
&[aria-checked="true"] {
background-color: var(--ax-bg-accent-strong-pressed);
color: var(--ax-text-accent-contrast);
}
}
.navds-toggle-group__button-inner {
display: flex;
align-items: center;
gap: var(--a-spacing-2);
font-weight: inherit;
gap: var(--ax-spacing-2);
> * {
flex-shrink: 0;
}
> svg {
font-size: var(--ax-font-size-heading-medium);
}
}
.navds-toggle-group__button-inner > * {
flex-shrink: 0;
/* Modifier neutral variant */
:where(.navds-toggle-group--neutral) .navds-toggle-group__button {
&:hover {
background-color: var(--ax-bg-neutral-moderate-hoverA);
}
&[aria-checked="true"] {
background-color: var(--ax-bg-neutral-strong-pressed);
color: var(--ax-text-neutral-contrast);
}
}
.navds-toggle-group__button[aria-pressed="true"],
.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));
}
.navds-toggle-group--neutral > .navds-toggle-group__button[aria-pressed="true"],
.navds-toggle-group--neutral > .navds-toggle-group__button[aria-checked="true"] {
background-color: var(--ac-toggle-group-neutral-selected-bg, var(--a-surface-neutral-selected));
color: var(--ac-toggle-group-neutral-selected-text, var(--a-text-on-neutral));
}
.navds-toggle-group--small > .navds-toggle-group__button {
padding: var(--a-spacing-05) var(--a-spacing-3);
min-height: 1.625rem;
min-width: fit-content;
}
.navds-toggle-group__button > .navds-toggle-group__button-inner > svg {
font-size: 1.5rem;
}
.navds-toggle-group--small > .navds-toggle-group__button > .navds-toggle-group__button-inner > svg {
font-size: 1.125rem;
/* Modifier small size */
.navds-toggle-group--small {
& .navds-toggle-group__button {
padding: var(--ax-spacing-05) var(--ax-spacing-3);
min-height: 1.5rem;
}
& .navds-toggle-group__button-inner > svg {
font-size: var(--ax-font-size-xlarge);
}
}
/* High contrast */
@media (forced-colors: active) {
.navds-toggle-group {
border: 2px solid transparent;
}
.navds-toggle-group__button[aria-checked="true"]:hover,
.navds-toggle-group__button:hover {
background-color: highlighttext;
color: highlight;
outline: 1px solid highlight;
}
.navds-toggle-group__button[aria-checked="true"],
.navds-toggle-group__button[aria-pressed="true"] {
.navds-toggle-group__button[aria-checked="true"] {
background-color: selecteditem;
color: selecteditemtext;
}
.navds-toggle-group__button[aria-checked="true"] > *,
.navds-toggle-group__button[aria-pressed="true"] > * {
forced-color-adjust: none;
}
.navds-toggle-group__button:active {
background-color: unset !important;
}
.navds-toggle-group__button:focus-visible {
outline-color: highlight;
}
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-css",
"version": "7.6.0",
"version": "7.7.0",
"description": "CSS for NAV Designsystem",
"author": "Aksel | NAV designsystem team",
"keywords": [
@@ -27,7 +27,7 @@
"css:get-version": "node config/get-version.js"
},
"devDependencies": {
"@navikt/ds-tokens": "^7.6.0",
"@navikt/ds-tokens": "^7.7.0",
"autoprefixer": "^10.4.20",
"cssnano": "6.0.0",
"fast-glob": "3.2.11",
+20
View File
@@ -1,5 +1,25 @@
# @navikt/ds-react
## 7.7.0
### Minor Changes
- CopyButton: Removed prop `activeTitle`. Use `activeText` instead. ([#3426](https://github.com/navikt/aksel/pull/3426))
- Combobox: :boom: Removed prop `toggleListButtonLabel` ([#3409](https://github.com/navikt/aksel/pull/3409))
### Patch Changes
- Combobox: Hid buttons from screen readers, added `title` on clear button, removed sr-only text on toggle list button. ([#3409](https://github.com/navikt/aksel/pull/3409))
- InternalHeader.UserButton: Remove `title`-attribute on icon and improved types. ([#3424](https://github.com/navikt/aksel/pull/3424))
- CopyButton: Fix issue where state changes are announced multiple times using VO in Chrome ([#3374](https://github.com/navikt/aksel/pull/3374))
- Updated dependencies []:
- @navikt/ds-tokens@7.7.0
- @navikt/aksel-icons@7.7.0
## 7.6.0
### Minor Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-react",
"version": "7.6.0",
"version": "7.7.0",
"description": "React components from the Norwegian Labour and Welfare Administration.",
"author": "Aksel, a team part of the Norwegian Labour and Welfare Administration.",
"license": "MIT",
@@ -604,8 +604,8 @@
"dependencies": {
"@floating-ui/react": "0.25.4",
"@floating-ui/react-dom": "^2.0.9",
"@navikt/aksel-icons": "^7.6.0",
"@navikt/ds-tokens": "^7.6.0",
"@navikt/aksel-icons": "^7.7.0",
"@navikt/ds-tokens": "^7.7.0",
"clsx": "^2.1.0",
"date-fns": "^3.0.0",
"react-day-picker": "8.10.1"
@@ -1,37 +1,21 @@
import { StoryObj } from "@storybook/react";
import { Meta, StoryObj } from "@storybook/react";
import React, { useState } from "react";
import { Accordion, AccordionProps } from ".";
import AccordionContent from "./AccordionContent";
import AccordionHeader from "./AccordionHeader";
import AccordionItem from "./AccordionItem";
export default {
title: "ds-react/Accordion",
component: Accordion,
subcomponents: {
AccordionItem,
AccordionContent,
AccordionHeader,
},
parameters: {
chromatic: { disable: true },
},
decorators: [
(Story) => (
<div
style={{
width: "600px",
minHeight: "100vh",
display: "flex",
flexDirection: "column",
gap: "1rem",
}}
>
<div style={{ width: "500px", minHeight: "100vh" }}>
<Story />
</div>
),
],
};
} satisfies Meta<typeof Accordion>;
type Story = StoryObj<typeof Accordion>;
@@ -60,46 +44,21 @@ const SmallContent = () => (
</Accordion.Content>
);
const Item = (props) => {
const [open, setOpen] = useState(false);
if (props.defaultOpen) {
return (
<Accordion.Item
defaultOpen={props.defaultOpen}
onOpenChange={console.log}
>
<Accordion.Header>Accordion header text</Accordion.Header>
<SmallContent />
</Accordion.Item>
);
}
return props.controlled ? (
<Accordion.Item open={open} onOpenChange={console.log}>
<Accordion.Header onClick={() => setOpen(!open)}>
Accordion header text
</Accordion.Header>
<Content />
</Accordion.Item>
) : (
<Accordion.Item onOpenChange={console.log}>
<Accordion.Header>Accordion header text</Accordion.Header>
<Content />
</Accordion.Item>
);
};
const Item = ({ defaultOpen = false }) => (
<Accordion.Item defaultOpen={defaultOpen} onOpenChange={console.log}>
<Accordion.Header>Accordion header text</Accordion.Header>
{defaultOpen ? <SmallContent /> : <Content />}
</Accordion.Item>
);
export const Controls: Story = {
render: ({ ...props }) => {
render: (props) => {
return (
<div style={{ width: 500 }}>
<Accordion {...props}>
{[...Array(4)].map((_, y) => (
<Item key={y} {...props} />
))}
</Accordion>
</div>
<Accordion {...props}>
{[...Array(4)].map((_, y) => (
<Item key={y} />
))}
</Accordion>
);
},
argTypes: {
@@ -128,13 +87,11 @@ export const Controls: Story = {
export const DefaultOpen: Story = {
render: () => {
return (
<div style={{ width: 500 }}>
<Accordion>
{[...Array(4)].map((_, y) => (
<Item key={y} defaultOpen={y === 2} />
))}
</Accordion>
</div>
<Accordion>
{[...Array(4)].map((_, y) => (
<Item key={y} defaultOpen={y === 2} />
))}
</Accordion>
);
},
};
@@ -142,7 +99,7 @@ export const DefaultOpen: Story = {
export const Variants: Story = {
render: () => {
return (
<div style={{ width: 500 }} className="colgap">
<div className="colgap">
<h3>Default</h3>
<Accordion>
{[...Array(2)].map((_, y) => (
@@ -166,22 +123,20 @@ export const ControlledState: Story = {
const [open2, setOpen2] = useState(false);
return (
<div style={{ width: 500 }}>
<Accordion>
<Accordion.Item open={open}>
<Accordion.Header onClick={() => setOpen(!open)}>
Accordion header text
</Accordion.Header>
<Content />
</Accordion.Item>
<Accordion.Item open={open2}>
<Accordion.Header onClick={() => setOpen2(!open2)}>
Accordion header text
</Accordion.Header>
<Content />
</Accordion.Item>
</Accordion>
</div>
<Accordion>
<Accordion.Item open={open}>
<Accordion.Header onClick={() => setOpen(!open)}>
Accordion header text
</Accordion.Header>
<Content />
</Accordion.Item>
<Accordion.Item open={open2}>
<Accordion.Header onClick={() => setOpen2(!open2)}>
Accordion header text
</Accordion.Header>
<Content />
</Accordion.Item>
</Accordion>
);
},
};
@@ -216,7 +171,7 @@ const headingSizes: AccordionProps["headingSize"][] = [
export const Size: Story = {
render: () => (
<div style={{ width: 500 }} className="colgap">
<div className="colgap">
{sizes.map((size) => (
<SingleHeaderAccordion key={size} size={size} />
))}
@@ -226,7 +181,7 @@ export const Size: Story = {
export const HeadingSize: Story = {
render: () => (
<div style={{ width: 500 }} className="colgap">
<div className="colgap">
{headingSizes.map((size) => (
<SingleHeaderAccordion key={size} headingSize={size} />
))}
@@ -237,14 +192,14 @@ export const HeadingSize: Story = {
export const Indent: Story = {
render: () => {
return (
<div style={{ width: 500 }} className="colgap">
<h3>No indent</h3>
<div className="colgap">
<h3>Indent</h3>
<Accordion indent>
{[...Array(2)].map((_, y) => (
<Item key={y} defaultOpen />
))}
</Accordion>
<h3>Indent</h3>
<h3>No indent</h3>
<Accordion indent={false}>
{[...Array(2)].map((_, y) => (
<Item key={y} defaultOpen />
@@ -10,6 +10,7 @@ import { CheckmarkIcon, FilesIcon } from "@navikt/aksel-icons";
import { Label } from "../typography";
import { composeEventHandlers } from "../util/composeEventHandlers";
import copy from "../util/copy";
import { useI18n } from "../util/i18n/i18n.context";
export interface CopyButtonProps
extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
@@ -32,7 +33,7 @@ export interface CopyButtonProps
text?: string;
/**
* Text shown when button is clicked.
* Only set if used with `text`-prop.
* Will be used as accessible label (title) if `text`-prop is not set.
* @default "Kopiert!"
*/
activeText?: string;
@@ -62,11 +63,6 @@ export interface CopyButtonProps
* @default "Kopier"
*/
title?: string;
/**
* Accessible label for icon in active-state (ignored if text is set).
* @default "Kopiert"
*/
activeTitle?: string;
/**
* Icon position in button.
* @default "left"
@@ -91,15 +87,14 @@ export const CopyButton = forwardRef<HTMLButtonElement, CopyButtonProps>(
className,
copyText,
text,
activeText = "Kopiert!",
activeText,
variant = "neutral",
size = "medium",
onActiveChange,
icon,
activeIcon,
activeDuration = 2000,
title = "Kopier",
activeTitle = "Kopiert",
title,
iconPosition = "left",
onClick,
...rest
@@ -108,6 +103,7 @@ export const CopyButton = forwardRef<HTMLButtonElement, CopyButtonProps>(
) => {
const [active, setActive] = useState(false);
const timeoutRef = useRef<number>();
const translate = useI18n("CopyButton");
useEffect(() => {
return () => {
@@ -127,19 +123,21 @@ export const CopyButton = forwardRef<HTMLButtonElement, CopyButtonProps>(
}, activeDuration);
};
const activeString = activeText || translate("activeText");
const copyIcon = (
<span className="navds-copybutton__icon">
{active
? activeIcon ?? (
<CheckmarkIcon
aria-hidden={!!text}
title={text ? undefined : activeTitle}
title={text ? undefined : activeString}
/>
)
: icon ?? (
<FilesIcon
aria-hidden={!!text}
title={text ? undefined : title}
title={text ? undefined : title || translate("title")}
/>
)}
</span>
@@ -150,7 +148,6 @@ export const CopyButton = forwardRef<HTMLButtonElement, CopyButtonProps>(
ref={ref}
type="button"
{...rest}
aria-live="polite"
className={cl(
"navds-copybutton",
className,
@@ -166,24 +163,11 @@ export const CopyButton = forwardRef<HTMLButtonElement, CopyButtonProps>(
>
<span className="navds-copybutton__content">
{iconPosition === "left" && copyIcon}
{text &&
(active ? (
<Label
as="span"
size={size === "medium" ? "medium" : "small"}
aria-live="polite"
>
{activeText}
</Label>
) : (
<Label
as="span"
size={size === "medium" ? "medium" : "small"}
aria-live="polite"
>
{text}
</Label>
))}
{text && (
<Label as="span" size={size === "medium" ? "medium" : "small"}>
{active ? activeString : text}
</Label>
)}
{iconPosition === "right" && copyIcon}
</span>
</button>
@@ -27,6 +27,10 @@ export const Default: Story = {
control: { type: "radio" },
options: ["neutral", "action"],
},
iconPosition: {
control: { type: "radio" },
options: ["left", "right"],
},
},
args: {
size: "medium",
@@ -34,6 +38,7 @@ export const Default: Story = {
copyText: "3.14",
text: "",
activeText: "",
title: "",
},
};
@@ -1,6 +1,9 @@
/* https://github.com/gpbl/react-day-picker/blob/7f78cd5/src/components/WeekNumber/WeekNumber.tsx#L21 */
import React from "react";
import { Button, useDayPicker } from "react-day-picker";
import { Button as RDPButton, useDayPicker } from "react-day-picker";
import { Button } from "../../../button";
import { UNSAFE_useAkselTheme } from "../../../provider";
import { Detail } from "../../../typography";
import { useI18n } from "../../../util/i18n/i18n.context";
import { getTranslations } from "../../utils";
@@ -24,32 +27,54 @@ function WeekNumber({
classNames,
locale: { code },
} = useDayPicker();
const themeContext = UNSAFE_useAkselTheme(false);
const translate = useI18n("DatePicker", getTranslations(code));
if (!onWeekNumberClick) {
return (
<span
<Detail
as="span"
textColor="subtle"
className={classNames.weeknumber}
style={styles.weeknumber}
aria-label={translate("weekNumber", { week: weekNumber })}
>
{weekNumber}
</span>
</Detail>
);
}
if (themeContext) {
return (
<Button
variant="secondary-neutral"
size="small"
name="week-number"
aria-label={translate("selectWeekNumber", { week: weekNumber })}
style={styles.weeknumber}
className="navds-date__weeknumber"
onClick={(event) => {
onWeekNumberClick(weekNumber, dates, event);
}}
icon={
<span className="navds-date__weeknumber-number">{weekNumber}</span>
}
/>
);
}
return (
<Button
<RDPButton
name="week-number"
aria-label={translate("selectWeekNumber", { week: weekNumber })}
className={classNames.weeknumber}
style={styles.weeknumber}
className={classNames.weeknumber}
onClick={(event) => {
onWeekNumberClick(weekNumber, dates, event);
}}
>
{weekNumber}
</Button>
</RDPButton>
);
}
@@ -2,6 +2,7 @@ import cl from "clsx";
import React from "react";
import { PlusIcon } from "@navikt/aksel-icons";
import { BodyShort, Label } from "../../../typography";
import { useI18n } from "../../../util/i18n/i18n.context";
import { useInputContext } from "../Input/Input.context";
import { useSelectedOptionsContext } from "../SelectedOptions/selectedOptionsContext";
import { isInList, toComboboxOption } from "../combobox-utils";
@@ -22,6 +23,7 @@ const AddNewOption = () => {
} = useFilteredOptionsContext();
const { isMultiSelect, selectedOptions, toggleOption } =
useSelectedOptionsContext();
const translate = useI18n("Combobox");
return (
<li
tabIndex={-1}
@@ -51,7 +53,7 @@ const AddNewOption = () => {
>
<PlusIcon aria-hidden />
<BodyShort size={size}>
Legg til{" "}
{translate("addOption")}{" "}
<Label as="span" size={size}>
&#8220;{searchTerm}&#8221;
</Label>
@@ -1,5 +1,6 @@
import React from "react";
import { Loader } from "../../../loader";
import { useI18n } from "../../../util/i18n/i18n.context";
import { useInputContext } from "../Input/Input.context";
import filteredOptionsUtil from "./filtered-options-util";
@@ -7,12 +8,13 @@ const LoadingMessage = () => {
const {
inputProps: { id },
} = useInputContext();
const translate = useI18n("Combobox");
return (
<div
className="navds-combobox__list-item--loading"
id={filteredOptionsUtil.getIsLoadingId(id)}
>
<Loader title="Søker..." />
<Loader title={translate("loading")} />
</div>
);
};
@@ -1,4 +1,5 @@
import React from "react";
import { useI18n } from "../../../util/i18n/i18n.context";
import { useInputContext } from "../Input/Input.context";
import { useSelectedOptionsContext } from "../SelectedOptions/selectedOptionsContext";
import filteredOptionsUtil from "./filtered-options-util";
@@ -8,6 +9,10 @@ const MaxSelectedMessage = () => {
inputProps: { id },
} = useInputContext();
const { maxSelected, selectedOptions } = useSelectedOptionsContext();
const translate = useI18n(
"Combobox",
maxSelected?.message ? { maxSelected: maxSelected.message } : undefined,
);
if (!maxSelected) {
return null;
@@ -18,8 +23,10 @@ const MaxSelectedMessage = () => {
className="navds-combobox__list-item--max-selected"
id={filteredOptionsUtil.getMaxSelectedOptionsId(id)}
>
{maxSelected.message ??
`${selectedOptions.length} av ${maxSelected.limit} er valgt.`}
{translate("maxSelected", {
selected: selectedOptions.length,
limit: maxSelected.limit,
})}
</div>
);
};
@@ -15,7 +15,7 @@ interface InputContextValue extends FormFieldType {
searchTerm: string;
setSearchTerm: React.Dispatch<React.SetStateAction<string>>;
shouldAutocomplete?: boolean;
toggleOpenButtonRef: React.RefObject<HTMLButtonElement>;
toggleOpenButtonRef: React.RefObject<HTMLDivElement>;
hideCaret: boolean;
setHideCaret: React.Dispatch<React.SetStateAction<boolean>>;
}
@@ -72,7 +72,7 @@ const InputProvider = ({ children, value: props }: Props) => {
"comboboxfield",
);
const inputRef = useRef<HTMLInputElement | null>(null);
const toggleOpenButtonRef = useRef<HTMLButtonElement>(null);
const toggleOpenButtonRef = useRef<HTMLDivElement>(null);
const [internalValue, setInternalValue] = useState<string>(defaultValue);
const [hideCaret, setHideCaret] = useState(false);
@@ -3,6 +3,7 @@ import cl from "clsx";
import React, { forwardRef } from "react";
import { XMarkIcon } from "@navikt/aksel-icons";
import { useMergeRefs } from "../../../util/hooks";
import { useI18n } from "../../../util/i18n/i18n.context";
import { useFilteredOptionsContext } from "../FilteredOptions/filteredOptionsContext";
import SelectedOptions from "../SelectedOptions/SelectedOptions";
import { useSelectedOptionsContext } from "../SelectedOptions/selectedOptionsContext";
@@ -11,7 +12,6 @@ import Input from "./Input";
import { useInputContext } from "./Input.context";
import ToggleListButton from "./ToggleListButton";
/* eslint-disable jsx-a11y/click-events-have-key-events */
export const InputController = forwardRef<
HTMLInputElement,
Omit<
@@ -31,7 +31,6 @@ export const InputController = forwardRef<
clearButton = true,
clearButtonLabel,
toggleListButton = true,
toggleListButtonLabel,
inputClassName,
shouldShowSelectedOptions = true,
...rest
@@ -53,7 +52,13 @@ export const InputController = forwardRef<
const mergedInputRef = useMergeRefs(inputRef, ref);
const translate = useI18n(
"Combobox",
clearButtonLabel ? { clear: clearButtonLabel } : undefined,
);
return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events
<div
className={cl("navds-combobox__wrapper-inner navds-text-field__input", {
"navds-combobox__wrapper-inner--virtually-unfocused":
@@ -83,24 +88,16 @@ export const InputController = forwardRef<
)}
<div>
{value && clearButton && (
<button
type="button"
<div
onClick={clearInput}
className="navds-combobox__button-clear"
tabIndex={-1}
aria-hidden
title={translate("clear")}
>
<span className="navds-sr-only">
{clearButtonLabel ? clearButtonLabel : "Tøm"}
</span>
<XMarkIcon aria-hidden />
</button>
)}
{toggleListButton && (
<ToggleListButton
toggleListButtonLabel={toggleListButtonLabel}
ref={toggleOpenButtonRef}
/>
<XMarkIcon />
</div>
)}
{toggleListButton && <ToggleListButton ref={toggleOpenButtonRef} />}
</div>
</div>
);
@@ -3,38 +3,22 @@ import { ChevronDownIcon, ChevronUpIcon } from "@navikt/aksel-icons";
import { useFilteredOptionsContext } from "../FilteredOptions/filteredOptionsContext";
import { useInputContext } from "./Input.context";
interface ToggleListButtonProps {
toggleListButtonLabel?: string;
}
export const ToggleListButton = forwardRef<
HTMLButtonElement,
ToggleListButtonProps
>(({ toggleListButtonLabel }, ref) => {
export const ToggleListButton = forwardRef<HTMLDivElement>((_, ref) => {
const { isListOpen, toggleIsListOpen } = useFilteredOptionsContext();
const { focusInput } = useInputContext();
return (
<button
type="button"
onPointerUp={() => {
<div
ref={ref}
onClick={() => {
toggleIsListOpen();
focusInput();
}}
onKeyDown={({ key }) => key === "Enter" && toggleIsListOpen()}
className="navds-combobox__button-toggle-list"
aria-expanded={isListOpen}
tabIndex={-1}
ref={ref}
aria-hidden
>
<span className="navds-sr-only">
{toggleListButtonLabel ?? "Alternativer"}
</span>
{isListOpen ? (
<ChevronUpIcon aria-hidden />
) : (
<ChevronDownIcon aria-hidden />
)}
</button>
{isListOpen ? <ChevronUpIcon /> : <ChevronDownIcon />}
</div>
);
});
@@ -14,12 +14,6 @@ const Option = ({ option }: { option: ComboboxOption }) => {
const { isMultiSelect, removeSelectedOption } = useSelectedOptionsContext();
const { focusInput, readOnly, inputProps } = useInputContext();
const onClick = (e) => {
e.stopPropagation();
removeSelectedOption(option);
focusInput();
};
if (!isMultiSelect) {
return (
<div className="navds-combobox__selected-options--no-bg">
@@ -28,12 +22,24 @@ const Option = ({ option }: { option: ComboboxOption }) => {
);
}
return readOnly || inputProps.disabled ? (
<Chips.Toggle variant="neutral" checkmark={false} as="div">
if (readOnly || inputProps.disabled) {
return (
<Chips.Toggle variant="neutral" checkmark={false} as="div">
{option.label}
</Chips.Toggle>
);
}
return (
<Chips.Removable
onClick={(event) => {
event.stopPropagation();
removeSelectedOption(option);
focusInput();
}}
>
{option.label}
</Chips.Toggle>
) : (
<Chips.Removable onClick={onClick}>{option.label}</Chips.Removable>
</Chips.Removable>
);
};
@@ -3,6 +3,7 @@ import { act, render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import React, { useId } from "react";
import { describe, expect, test, vi } from "vitest";
import nb from "../../../util/i18n/locales/nb";
import { ComboboxProps, UNSAFE_Combobox } from "../index";
const options = [
@@ -73,7 +74,7 @@ describe("Render combobox", () => {
test("Should show loading icon when loading (used for async search)", async () => {
render(<App options={[]} isListOpen isLoading />);
expect(await screen.findByText("Søker...")).toBeInTheDocument();
expect(await screen.findByText(nb.Combobox.loading)).toBeInTheDocument();
});
test("Should not select previous focused element when closes", async () => {
@@ -38,13 +38,14 @@ const options = [
"grapefruit",
];
export const Default: StoryFn<ComboboxProps & { maxSelected?: number }> = ({
maxSelected,
...rest
}) => (
export const Default: StoryFn<
ComboboxProps & { maxSelected?: number; maxSelectedMessage?: string }
> = ({ maxSelected, maxSelectedMessage, ...rest }) => (
<UNSAFE_Combobox
{...rest}
maxSelected={maxSelected && { limit: maxSelected }}
maxSelected={
maxSelected && { limit: maxSelected, message: maxSelectedMessage }
}
id="combobox"
/>
);
@@ -76,11 +77,17 @@ Default.argTypes = {
maxSelected: {
control: { type: "number" },
},
maxSelectedMessage: {
control: { type: "text" },
},
size: {
options: ["medium", "small"],
defaultValue: "medium",
control: { type: "radio" },
},
clearButtonLabel: {
control: { type: "text" },
},
};
export const WithPlaceholder: StoryFunction = () => {
@@ -132,7 +132,8 @@ export interface ComboboxProps
*/
limit: number;
/**
* Override the message to display when the limit for maximum selected options has been reached
* Message to display when the limit for maximum selected options has been reached
* @default "{selected} av maks {limit} er valgt."
*/
message?: string;
};
@@ -154,12 +155,6 @@ export interface ComboboxProps
* @default true
*/
toggleListButton?: boolean;
/**
* Custom name for the toggle list-button. Requires "toggleListButton" to be `true`.
*
* @default "Alternativer"
*/
toggleListButtonLabel?: string;
/**
* Set this to override the value of the input field.
*
@@ -1,9 +1,9 @@
import cl from "clsx";
import React, { forwardRef } from "react";
import { Link } from "../../link";
import { useI18n } from "../../util/i18n/i18n.context";
import { OverridableComponent } from "../../util/types";
// export type FormSummaryEditProps = Partial<LinkProps>;
export interface FormSummaryEditProps
extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
/**
@@ -22,17 +22,18 @@ export interface FormSummaryEditProps
export const FormSummaryEditLink: OverridableComponent<
FormSummaryEditProps,
HTMLAnchorElement
> = forwardRef(
({ children = "Endre svar", className, as = "a", ...rest }, ref) => (
> = forwardRef(({ children, className, as = "a", ...rest }, ref) => {
const translate = useI18n("FormSummary");
return (
<Link
ref={ref}
as={as}
{...rest}
className={cl("navds-form-summary__edit", className)}
>
{children}
{children || translate("editAnswer")}
</Link>
),
);
);
});
export default FormSummaryEditLink;
+33 -12
View File
@@ -6,6 +6,8 @@ import React, {
useState,
} from "react";
import { MagnifyingGlassIcon, XMarkIcon } from "@navikt/aksel-icons";
import { Button } from "../../button";
import { UNSAFE_useAkselTheme } from "../../provider";
import { BodyShort, ErrorMessage, Label } from "../../typography";
import { omit } from "../../util";
import { useMergeRefs } from "../../util/hooks/useMergeRefs";
@@ -122,6 +124,8 @@ export const Search = forwardRef<HTMLInputElement, SearchProps>(
...rest
} = props;
const themeContext = UNSAFE_useAkselTheme(false);
const searchRef = useRef<HTMLInputElement | null>(null);
const mergedRef = useMergeRefs(searchRef, ref);
const translate = useI18n("Search");
@@ -142,6 +146,34 @@ export const Search = forwardRef<HTMLInputElement, SearchProps>(
onSearchClick?.(`${value ?? internalValue}`);
};
const showClearButton =
clearButton && !inputProps.disabled && (value ?? internalValue);
const ClearButton = () =>
themeContext ? (
<Button
className="navds-search__button-clear"
variant="tertiary-neutral"
size={size === "medium" ? "small" : "xsmall"}
icon={<XMarkIcon aria-hidden />}
title={clearButtonLabel || translate("clear")}
hidden={!showClearButton}
onClick={(event) => handleClear({ trigger: "Click", event })}
/>
) : (
<button
type="button"
onClick={(event) => handleClear({ trigger: "Click", event })}
className="navds-search__button-clear"
hidden={!showClearButton}
>
<span className="navds-sr-only">
{clearButtonLabel || translate("clear")}
</span>
<XMarkIcon aria-hidden />
</button>
);
return (
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
<div
@@ -210,18 +242,7 @@ export const Search = forwardRef<HTMLInputElement, SearchProps>(
)}
{...(htmlSize ? { size: Number(htmlSize) } : {})}
/>
{(value ?? internalValue) && clearButton && (
<button
type="button"
onClick={(event) => handleClear({ trigger: "Click", event })}
className="navds-search__button-clear"
>
<span className="navds-sr-only">
{clearButtonLabel || translate("clear")}
</span>
<XMarkIcon aria-hidden />
</button>
)}
<ClearButton />
</div>
<SearchContext.Provider
value={{
@@ -105,6 +105,21 @@ export const ErrorVariants = () => (
</div>
);
export const Disabled = () => (
<div className="rowgap">
<div className="colgap">
<Search disabled label="Søk" />
<Search disabled label="Søk" variant="secondary" />
<Search disabled label="Søk" variant="simple" />
</div>
<div className="colgap">
<Search disabled error="errormsg" label="Søk" />
<Search disabled error="errormsg" label="Søk" variant="secondary" />
<Search disabled error="errormsg" label="Søk" variant="simple" />
</div>
</div>
);
export const Placeholder = () => (
<div className="rowgap">
<div className="colgap">
@@ -210,6 +225,10 @@ export const Chromatic: Story = {
<h2>ErrorVariants</h2>
<ErrorVariants />
</div>
<div>
<h2>Disabled</h2>
<Disabled />
</div>
<div>
<h2>Placeholder</h2>
<Placeholder />
@@ -1,5 +1,6 @@
import React, { SVGProps } from "react";
import { useId } from "../util/hooks";
import { useI18n } from "../util/i18n/i18n.context";
interface SVGRProps {
title?: string;
@@ -15,6 +16,8 @@ export const DefaultIllustration: DefaultIllustrationType = ({
titleId: _titleId,
...props
}) => {
const translate = useI18n("GuidePanel");
let titleId: string | undefined = useId();
titleId = title ? (_titleId ? _titleId : "title-" + titleId) : undefined;
@@ -25,7 +28,7 @@ export const DefaultIllustration: DefaultIllustrationType = ({
viewBox="0 0 56 85"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-label="NAV veileder illustrasjon"
aria-label={translate("illustrationLabel")}
focusable={false}
role="img"
aria-labelledby={titleId}
@@ -4,6 +4,7 @@ import { Popover, PopoverProps } from "../popover";
import { UNSAFE_useAkselTheme } from "../provider";
import { composeEventHandlers } from "../util/composeEventHandlers";
import { useMergeRefs } from "../util/hooks/useMergeRefs";
import { useI18n } from "../util/i18n/i18n.context";
import { HelpTextIcon } from "./HelpTextIcon";
export interface HelpTextProps
@@ -12,7 +13,7 @@ export interface HelpTextProps
children: React.ReactNode;
/**
* Adds a title-tooltip with the given text
* @default "hjelp"
* @default "Mer informasjon"
*/
title?: string;
/**
@@ -41,7 +42,7 @@ export const HelpText = forwardRef<HTMLButtonElement, HelpTextProps>(
children,
placement,
strategy = "absolute",
title = "hjelp",
title,
onClick,
wrapperClassName,
...rest
@@ -50,10 +51,11 @@ export const HelpText = forwardRef<HTMLButtonElement, HelpTextProps>(
) => {
const buttonRef = useRef<HTMLButtonElement | null>(null);
const mergedRef = useMergeRefs(buttonRef, ref);
const [open, setOpen] = useState(false);
const themeContext = UNSAFE_useAkselTheme(false);
const translate = useI18n("HelpText");
const titleWithFallback = title || translate("title");
return (
<div className={cl("navds-help-text", wrapperClassName)}>
@@ -65,8 +67,8 @@ export const HelpText = forwardRef<HTMLButtonElement, HelpTextProps>(
type="button"
aria-expanded={open}
>
<HelpTextIcon title={title} />
<HelpTextIcon filled title={title} />
<HelpTextIcon title={titleWithFallback} />
<HelpTextIcon filled title={titleWithFallback} />
</button>
<Popover
onClose={() => setOpen(false)}
@@ -3,7 +3,7 @@ import React, { forwardRef } from "react";
import { OverridableComponent } from "../util/types";
export interface InternalHeaderButtonProps
extends React.AnchorHTMLAttributes<HTMLButtonElement> {
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
/**
* Application Button
*/
@@ -6,7 +6,7 @@ import { OverridableComponent } from "../util/types";
import InternalHeaderButton from "./InternalHeaderButton";
export interface InternalHeaderUserButtonProps
extends React.AnchorHTMLAttributes<HTMLButtonElement> {
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
/**
* User name
*/
@@ -33,7 +33,7 @@ export const InternalHeaderUserButton: OverridableComponent<
</BodyShort>
{description && <Detail as="div">{description}</Detail>}
</div>
<ChevronDownIcon title="vis meny" />
<ChevronDownIcon aria-hidden />
</InternalHeaderButton>
));
@@ -40,22 +40,22 @@ export const Default = {
>
<MenuGridIcon
style={{ fontSize: "1.5rem" }}
title="MenuGridIconer og oppslagsverk"
title="Systemer og oppslagsverk"
/>
</InternalHeader.Button>
<Dropdown.Menu strategy="fixed">
<Dropdown.Menu.List>
<Dropdown.Menu.List.Item>
<span>A.Inntekt</span>
<ExternalLinkIcon style={{ fontSize: "0.875rem" }} />
<ExternalLinkIcon aria-hidden fontSize="0.875rem" />
</Dropdown.Menu.List.Item>
<Dropdown.Menu.List.Item>
<span>Aa-registeret</span>
<ExternalLinkIcon style={{ fontSize: "0.875rem" }} />
<ExternalLinkIcon aria-hidden fontSize="0.875rem" />
</Dropdown.Menu.List.Item>
<Dropdown.Menu.List.Item>
<span>Gosys</span>
<ExternalLinkIcon style={{ fontSize: "0.875rem" }} />
<ExternalLinkIcon aria-hidden fontSize="0.875rem" />
</Dropdown.Menu.List.Item>
</Dropdown.Menu.List>
</Dropdown.Menu>
@@ -86,7 +86,7 @@ export const Default = {
}}
>
<BodyShort title="Ola Normann">KH</BodyShort>
<ChevronDownIcon />
<ChevronDownIcon title="Brukermeny" />
</InternalHeader.Button>
<Dropdown.Menu strategy="fixed">
<div>
@@ -172,7 +172,7 @@ export const UserWithMenu = () => (
}}
>
<BodyShort title="Ola Normann">KH</BodyShort>
<ChevronDownIcon />
<ChevronDownIcon title="Brukermeny" />
</InternalHeader.Button>
<Dropdown.Menu strategy="fixed">
<div>
@@ -208,22 +208,22 @@ export const UserWithMenuGridIconMenu = () => (
>
<MenuGridIcon
style={{ fontSize: "1.5rem" }}
title="MenuGridIconer og oppslagsverk"
title="Systemer og oppslagsverk"
/>
</InternalHeader.Button>
<Dropdown.Menu strategy="fixed">
<Dropdown.Menu.List>
<Dropdown.Menu.List.Item>
<span>A.Inntekt</span>
<ExternalLinkIcon style={{ fontSize: "0.875rem" }} />
<ExternalLinkIcon aria-hidden fontSize="0.875rem" />
</Dropdown.Menu.List.Item>
<Dropdown.Menu.List.Item>
<span>Aa-registeret</span>
<ExternalLinkIcon style={{ fontSize: "0.875rem" }} />
<ExternalLinkIcon aria-hidden fontSize="0.875rem" />
</Dropdown.Menu.List.Item>
<Dropdown.Menu.List.Item>
<span>Gosys</span>
<ExternalLinkIcon style={{ fontSize: "0.875rem" }} />
<ExternalLinkIcon aria-hidden fontSize="0.875rem" />
</Dropdown.Menu.List.Item>
</Dropdown.Menu.List>
</Dropdown.Menu>
@@ -1,5 +1,6 @@
import cl from "clsx";
import React from "react";
import { UNSAFE_useAkselTheme } from "../../provider";
import { Slot } from "../../slot/Slot";
import { getResponsiveProps, getResponsiveValue } from "../utilities/css";
import { ResponsiveProp, SpacingScale } from "../utilities/types";
@@ -251,39 +252,42 @@ export const BasePrimitive = ({
flexShrink,
gridColumn,
}: BasePrimitiveProps) => {
const themeContext = UNSAFE_useAkselTheme(false);
const prefix = themeContext ? "ax" : "a";
const style: React.CSSProperties = {
/* Padding */
...getResponsiveProps("r", "p", "spacing", padding),
...getResponsiveProps("r", "pi", "spacing", paddingInline),
...getResponsiveProps("r", "pb", "spacing", paddingBlock),
...getResponsiveProps(prefix, "r", "p", "spacing", padding),
...getResponsiveProps(prefix, "r", "pi", "spacing", paddingInline),
...getResponsiveProps(prefix, "r", "pb", "spacing", paddingBlock),
/* Margin */
...getResponsiveProps("r", "m", "spacing", margin),
...getResponsiveProps("r", "mi", "spacing", marginInline),
...getResponsiveProps("r", "mb", "spacing", marginBlock),
...getResponsiveProps(prefix, "r", "m", "spacing", margin),
...getResponsiveProps(prefix, "r", "mi", "spacing", marginInline),
...getResponsiveProps(prefix, "r", "mb", "spacing", marginBlock),
/* Width & height */
...getResponsiveValue("r", "w", width),
...getResponsiveValue("r", "minw", minWidth),
...getResponsiveValue("r", "maxw", maxWidth),
...getResponsiveValue("r", "h", height),
...getResponsiveValue("r", "minh", minHeight),
...getResponsiveValue("r", "maxh", maxHeight),
...getResponsiveValue(prefix, "r", "w", width),
...getResponsiveValue(prefix, "r", "minw", minWidth),
...getResponsiveValue(prefix, "r", "maxw", maxWidth),
...getResponsiveValue(prefix, "r", "h", height),
...getResponsiveValue(prefix, "r", "minh", minHeight),
...getResponsiveValue(prefix, "r", "maxh", maxHeight),
/* Positon & inset */
...getResponsiveValue("r", "position", position),
...getResponsiveProps("r", "inset", "spacing", inset),
...getResponsiveProps("r", "top", "spacing", top),
...getResponsiveProps("r", "right", "spacing", right),
...getResponsiveProps("r", "bottom", "spacing", bottom),
...getResponsiveProps("r", "left", "spacing", left),
...getResponsiveValue(prefix, "r", "position", position),
...getResponsiveProps(prefix, "r", "inset", "spacing", inset),
...getResponsiveProps(prefix, "r", "top", "spacing", top),
...getResponsiveProps(prefix, "r", "right", "spacing", right),
...getResponsiveProps(prefix, "r", "bottom", "spacing", bottom),
...getResponsiveProps(prefix, "r", "left", "spacing", left),
/* Overflow */
...getResponsiveValue("r", "overflow", overflow),
...getResponsiveValue("r", "overflowx", overflowX),
...getResponsiveValue("r", "overflowy", overflowY),
...getResponsiveValue(prefix, "r", "overflow", overflow),
...getResponsiveValue(prefix, "r", "overflowx", overflowX),
...getResponsiveValue(prefix, "r", "overflowy", overflowY),
/* Flex */
...getResponsiveValue("r", "flex-basis", flexBasis),
...getResponsiveValue("r", "flex-grow", flexGrow),
...getResponsiveValue("r", "flex-shrink", flexShrink),
...getResponsiveValue(prefix, "r", "flex-basis", flexBasis),
...getResponsiveValue(prefix, "r", "flex-grow", flexGrow),
...getResponsiveValue(prefix, "r", "flex-shrink", flexShrink),
/* Grid */
...getResponsiveValue("r", "grid-column", gridColumn),
...getResponsiveValue(prefix, "r", "grid-column", gridColumn),
};
return (
@@ -1,5 +1,6 @@
import cl from "clsx";
import React, { forwardRef } from "react";
import { UNSAFE_useAkselTheme } from "../../provider";
import { Slot } from "../../slot/Slot";
import { getResponsiveProps } from "../utilities/css";
import { ResponsiveProp, SpacingScale } from "../utilities/types";
@@ -80,9 +81,13 @@ export const Bleed = forwardRef<HTMLDivElement, BleedProps>(
},
ref,
) => {
const themeContext = UNSAFE_useAkselTheme(false);
const prefix = themeContext ? "ax" : "a";
let style: React.CSSProperties = {
..._style,
...getResponsiveProps(
prefix,
"bleed",
"margin-inline",
"spacing",
@@ -92,6 +97,7 @@ export const Bleed = forwardRef<HTMLDivElement, BleedProps>(
),
...getResponsiveProps(
prefix,
"bleed",
"margin-block",
"spacing",
@@ -105,6 +111,7 @@ export const Bleed = forwardRef<HTMLDivElement, BleedProps>(
style = {
...style,
...getResponsiveProps(
prefix,
"bleed",
"padding-inline",
"spacing",
@@ -113,6 +120,7 @@ export const Bleed = forwardRef<HTMLDivElement, BleedProps>(
["0", "full", "px"],
),
...getResponsiveProps(
prefix,
"bleed",
"padding-block",
"spacing",
@@ -0,0 +1,154 @@
import cl from "clsx";
import React, { forwardRef } from "react";
import { BorderKeys } from "@navikt/ds-tokens/darkside/tokens/semantic-roles";
import { Slot } from "../../slot/Slot";
import { omit } from "../../util";
import { OverridableComponent } from "../../util/types";
import BasePrimitive, {
PRIMITIVE_PROPS,
PrimitiveProps,
} from "../base/BasePrimitive";
import { PrimitiveAsChildProps } from "../base/PrimitiveAsChildProps";
import { getResponsiveProps } from "../utilities/css";
import {
BorderRadiiToken,
ResponsiveProp,
SemanticRoleBgDarkside,
SemanticShadowTokens,
SemanticStaticBgDarkside,
SemanticStaticBorderDarkside,
SpaceDelimitedAttribute,
} from "../utilities/types";
export type BoxNewProps = React.HTMLAttributes<HTMLDivElement> & {
/**
* CSS `background-color` property.
* Accepts a [background/surface color token](https://aksel.nav.no/grunnleggende/styling/design-tokens#afff774dad80).
*/
background?: SemanticStaticBgDarkside | SemanticRoleBgDarkside;
/**
* CSS `border-color` property.
* Accepts a [border color token](https://aksel.nav.no/grunnleggende/styling/design-tokens#adb1767e2f87).
*/
borderColor?: BorderKeys | SemanticStaticBorderDarkside;
/**
* CSS `border-radius` property.
* Accepts a [radius token](https://aksel.nav.no/grunnleggende/styling/design-tokens#6d79c5605d31)
* or an object of radius tokens for different breakpoints.
* @example
* borderRadius='full'
* borderRadius='0 full large small'
* borderRadius={{xs: 'small large', sm: '0', md: 'large', lg: 'full'}}
*/
borderRadius?: ResponsiveProp<SpaceDelimitedAttribute<BorderRadiiToken>>;
/**
* CSS `border-width` property. If this is not set there will be no border.
* @example
* borderWidth='2'
* borderWidth='1 2 3 4'
*/
borderWidth?: SpaceDelimitedAttribute<"0" | "1" | "2" | "3" | "4" | "5">;
/** Shadow on box. Accepts a shadow token.
* @example
* shadow='small'
*/
shadow?: SemanticShadowTokens;
} & PrimitiveProps &
PrimitiveAsChildProps;
/**
*
* Foundational Layout-primitive for generic encapsulation & styling.
*
* @see [📝 Documentation](https://aksel.nav.no/komponenter/primitives/box)
* @see 🏷️ {@link BoxProps}
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
*
* @example
* <Box padding="4">
* <BodyShort>Hei</BodyShort>
* </Box>
*
* @example
* <Box padding={{xs: '2', sm: '3', md: '4', lg: '5', xl: '6'}}>
* <BodyShort>Hei</BodyShort>
* </Box>
*
* @example
* <VStack gap="8">
* <Box padding="4">
* <BodyShort>Hei</BodyShort>
* </Box>
* <Box padding="4">
* <BodyShort>Hei</BodyShort>
* </Box>
* </VStack>
*/
export const BoxNew: OverridableComponent<BoxNewProps, HTMLDivElement> =
forwardRef(
(
{
children,
className,
as: Component = "div",
background,
borderColor,
borderWidth,
borderRadius,
shadow,
style: _style,
asChild,
...rest
},
ref,
) => {
const style: React.CSSProperties = {
..._style,
"--__axc-box-background": background
? `var(--ax-bg-${background})`
: undefined,
"--__axc-box-shadow": shadow ? `var(--ax-shadow-${shadow})` : undefined,
"--__axc-box-border-color": borderColor
? `var(--ax-border-${borderColor})`
: undefined,
"--__axc-box-border-width": borderWidth
? borderWidth
.split(" ")
.map((x) => `${x}px`)
.join(" ")
: undefined,
...getResponsiveProps(
"ax",
"box",
"border-radius",
"border-radius",
borderRadius,
false,
["0"],
),
};
const Comp = asChild ? Slot : Component;
return (
<BasePrimitive {...rest}>
<Comp
{...omit(rest, PRIMITIVE_PROPS)}
ref={ref}
style={style}
className={cl("navds-box", className, {
"navds-box-bg": background,
"navds-box-border-color": borderColor,
"navds-box-border-width": borderWidth,
"navds-box-border-radius": borderRadius,
"navds-box-shadow": shadow,
})}
>
{children}
</Comp>
</BasePrimitive>
);
},
);
export default BoxNew;
@@ -402,6 +402,38 @@ export const AsChild = () => (
</VStack>
);
export const BoxNewDarksideLight: Story = {
render: () => (
<Box.New
background="accent-moderate"
shadow="dialog"
borderColor="brand-one-strong"
borderWidth="2"
padding="5"
paddingInline="20"
>
Box
</Box.New>
),
globals: { theme: "light", mode: "darkside" },
};
export const BoxNewDarksideDark: Story = {
render: () => (
<Box.New
background="accent-moderate"
shadow="dialog"
borderColor="brand-one-strong"
borderWidth="2"
padding="5"
paddingInline="20"
>
Box
</Box.New>
),
globals: { theme: "dark", mode: "darkside" },
};
export const Chromatic: Story = {
render: () => (
<VStack gap="2">
+90 -61
View File
@@ -1,5 +1,6 @@
import cl from "clsx";
import React, { forwardRef } from "react";
import { UNSAFE_useAkselTheme } from "../../provider";
import { Slot } from "../../slot/Slot";
import { omit } from "../../util";
import { OverridableComponent } from "../../util/types";
@@ -18,6 +19,7 @@ import {
SpaceDelimitedAttribute,
SurfaceColorToken,
} from "../utilities/types";
import BoxNew from "./Box.darkside";
export type BoxProps = React.HTMLAttributes<HTMLDivElement> & {
/**
@@ -55,6 +57,11 @@ export type BoxProps = React.HTMLAttributes<HTMLDivElement> & {
} & PrimitiveProps &
PrimitiveAsChildProps;
interface BoxComponentType
extends OverridableComponent<BoxProps, HTMLDivElement> {
New: typeof BoxNew;
}
/**
* Foundational Layout-primitive for generic encapsulation & styling.
*
@@ -82,69 +89,91 @@ export type BoxProps = React.HTMLAttributes<HTMLDivElement> & {
* </Box>
* </VStack>
*/
export const Box: OverridableComponent<BoxProps, HTMLDivElement> = forwardRef(
(
{
children,
className,
as: Component = "div",
background,
borderColor,
borderWidth,
borderRadius,
shadow,
style: _style,
asChild,
...rest
},
ref,
) => {
const style: React.CSSProperties = {
..._style,
"--__ac-box-background": background
? `var(--a-${background})`
: undefined,
"--__ac-box-shadow": shadow ? `var(--a-shadow-${shadow})` : undefined,
"--__ac-box-border-color": borderColor
? `var(--a-${borderColor})`
: undefined,
"--__ac-box-border-width": borderWidth
? borderWidth
.split(" ")
.map((x) => `${x}px`)
.join(" ")
: undefined,
...getResponsiveProps(
"box",
"border-radius",
"border-radius",
export const BoxComponent: OverridableComponent<BoxProps, HTMLDivElement> =
forwardRef(
(
{
children,
className,
as: Component = "div",
background,
borderColor,
borderWidth,
borderRadius,
false,
["0"],
),
};
shadow,
style: _style,
asChild,
...rest
},
ref,
) => {
const themeContext = UNSAFE_useAkselTheme(false);
const Comp = asChild ? Slot : Component;
if (
process.env.NODE_ENV !== "production" &&
themeContext &&
(background || borderColor || shadow)
) {
console.warn(
`<Box /> with properties 'background', 'borderColor' or 'shadow' cannot be used with AkselTheme (darkmode-support). To continue using these properties, migrate to '<Box.New>'`,
);
}
return (
<BasePrimitive {...rest}>
<Comp
{...omit(rest, PRIMITIVE_PROPS)}
ref={ref}
style={style}
className={cl("navds-box", className, {
"navds-box-bg": background,
"navds-box-border-color": borderColor,
"navds-box-border-width": borderWidth,
"navds-box-border-radius": borderRadius,
"navds-box-shadow": shadow,
})}
>
{children}
</Comp>
</BasePrimitive>
);
},
);
const prefix = themeContext ? "ax" : "a";
const style: React.CSSProperties = {
..._style,
[`--__${prefix}c-box-background`]: background
? `var(--a-${background})`
: undefined,
[`--__${prefix}c-box-shadow`]: shadow
? `var(--a-shadow-${shadow})`
: undefined,
[`--__${prefix}c-box-border-color`]: borderColor
? `var(--a-${borderColor})`
: undefined,
[`--__${prefix}c-box-border-width`]: borderWidth
? borderWidth
.split(" ")
.map((x) => `${x}px`)
.join(" ")
: undefined,
...getResponsiveProps(
prefix,
"box",
"border-radius",
"border-radius",
borderRadius,
false,
["0"],
),
};
const Comp = asChild ? Slot : Component;
return (
<BasePrimitive {...rest}>
<Comp
{...omit(rest, PRIMITIVE_PROPS)}
ref={ref}
style={style}
className={cl("navds-box", className, {
"navds-box-bg": background,
"navds-box-border-color": borderColor,
"navds-box-border-width": borderWidth,
"navds-box-border-radius": borderRadius,
"navds-box-shadow": shadow,
})}
>
{children}
</Comp>
</BasePrimitive>
);
},
);
export const Box = BoxComponent as BoxComponentType;
Box.New = BoxNew;
export default Box;
@@ -1,2 +1,5 @@
"use client";
export { default as Box, type BoxProps } from "./Box";
/* TODO: Uncomment this when ready to expose darkmode-support. Remember to update top-level `index.ts` at the same time. */
/* export { default as BoxNew, type BoxNewProps } from "./Box.darkside"; */
+7 -3
View File
@@ -1,5 +1,6 @@
import cl from "clsx";
import React, { forwardRef } from "react";
import { UNSAFE_useAkselTheme } from "../../provider";
import { Slot } from "../../slot/Slot";
import { OverridableComponent, omit } from "../../util";
import BasePrimitive, {
@@ -77,11 +78,14 @@ export const HGrid: OverridableComponent<HGridProps, HTMLDivElement> =
},
ref,
) => {
const themeContext = UNSAFE_useAkselTheme(false);
const prefix = themeContext ? "ax" : "a";
const styles: React.CSSProperties = {
...style,
"--__ac-hgrid-align": align,
...getResponsiveProps(`hgrid`, "gap", "spacing", gap),
...getResponsiveValue(`hgrid`, "columns", formatGrid(columns)),
[`--__${prefix}c-hgrid-align`]: align,
...getResponsiveProps(prefix, `hgrid`, "gap", "spacing", gap),
...getResponsiveValue(prefix, `hgrid`, "columns", formatGrid(columns)),
};
const Comp = asChild ? Slot : Component;
@@ -1,5 +1,6 @@
import cl from "clsx";
import React, { forwardRef } from "react";
import { UNSAFE_useAkselTheme } from "../../provider";
import { OverridableComponent } from "../../util";
import { BackgroundColorToken } from "../utilities/types";
import { PageBlock } from "./parts/PageBlock";
@@ -14,6 +15,7 @@ export interface PageProps extends React.HTMLAttributes<HTMLElement> {
* Background color.
* Accepts a [background color token](https://aksel.nav.no/grunnleggende/styling/design-tokens#753d1cf4d1d6).
* @default "bg-default"
* @deprecated 'background'-prop will be removed in future major-versions. Use `<Box asChild background="...">` wrapped around `<Page>`.
*/
background?: BackgroundColorToken;
/**
@@ -52,6 +54,14 @@ export const PageComponent: OverridableComponent<PageProps, HTMLElement> =
},
ref,
) => {
const themeContext = UNSAFE_useAkselTheme(false);
if (process.env.NODE_ENV !== "production" && themeContext && background) {
console.warn(
`Prop \`background\` is deprecated and cannot be used with theme-support. Instead wrap component with \`<Box asChild background>\``,
);
}
const style: React.CSSProperties = {
..._style,
"--__ac-page-background": `var(--a-${background})`,
@@ -1,5 +1,6 @@
import cl from "clsx";
import React, { HTMLAttributes, forwardRef } from "react";
import { UNSAFE_useAkselTheme } from "../../provider";
import { Slot } from "../../slot/Slot";
import { omit } from "../../util";
import { OverridableComponent } from "../../util/types";
@@ -83,12 +84,15 @@ export const Stack: OverridableComponent<StackProps, HTMLDivElement> =
},
ref,
) => {
const themeContext = UNSAFE_useAkselTheme(false);
const prefix = themeContext ? "ax" : "a";
const style: React.CSSProperties = {
..._style,
...getResponsiveProps(`stack`, "gap", "spacing", gap),
...getResponsiveValue(`stack`, "direction", direction),
...getResponsiveValue(`stack`, "align", align),
...getResponsiveValue(`stack`, "justify", justify),
...getResponsiveProps(prefix, `stack`, "gap", "spacing", gap),
...getResponsiveValue(prefix, `stack`, "direction", direction),
...getResponsiveValue(prefix, `stack`, "align", align),
...getResponsiveValue(prefix, `stack`, "justify", justify),
};
const Comp = asChild ? Slot : Component;
+18 -12
View File
@@ -1,6 +1,7 @@
import { ResponsiveProp } from "./types";
export function getResponsiveValue<T = string>(
prefix: string,
componentName: string,
componentProp: string,
responsiveProp?: ResponsiveProp<T>,
@@ -11,13 +12,13 @@ export function getResponsiveValue<T = string>(
if (typeof responsiveProp === "string") {
return {
[`--__ac-${componentName}-${componentProp}-xs`]: responsiveProp,
[`--__${prefix}c-${componentName}-${componentProp}-xs`]: responsiveProp,
};
}
return Object.fromEntries(
Object.entries(responsiveProp).map(([breakpointAlias, responsiveValue]) => [
`--__ac-${componentName}-${componentProp}-${breakpointAlias}`,
`--__${prefix}c-${componentName}-${componentProp}-${breakpointAlias}`,
responsiveValue,
]),
);
@@ -37,6 +38,7 @@ const translateTokenStringToCSS = (
tokenSubgroup: string,
tokenExceptions: string[],
invert: boolean,
prefix: string,
) => {
return tokenString
.split(" ")
@@ -54,7 +56,7 @@ const translateTokenStringToCSS = (
return "auto";
}
let output = `var(--a-${tokenSubgroup}-${x})`;
let output = `var(--${prefix}-${tokenSubgroup}-${x})`;
if (tokenExceptions.includes(x)) {
output = translateExceptionToCSS(x);
}
@@ -70,6 +72,7 @@ const translateTokenStringToCSS = (
};
export function getResponsiveProps<T extends string>(
prefix: string,
componentName: string,
componentProp: string,
tokenSubgroup: string,
@@ -83,27 +86,30 @@ export function getResponsiveProps<T extends string>(
if (typeof responsiveProp === "string") {
return {
[`--__ac-${componentName}-${componentProp}-xs`]:
[`--__${prefix}c-${componentName}-${componentProp}-xs`]:
translateTokenStringToCSS(
componentProp,
responsiveProp,
tokenSubgroup,
tokenExceptions,
invert,
prefix,
),
};
}
const styleProps = {};
Object.entries(responsiveProp).forEach(([breakpointAlias, aliasOrScale]) => {
styleProps[`--__ac-${componentName}-${componentProp}-${breakpointAlias}`] =
translateTokenStringToCSS(
componentProp,
aliasOrScale,
tokenSubgroup,
tokenExceptions,
invert,
);
styleProps[
`--__${prefix}c-${componentName}-${componentProp}-${breakpointAlias}`
] = translateTokenStringToCSS(
componentProp,
aliasOrScale,
tokenSubgroup,
tokenExceptions,
invert,
prefix,
);
});
return styleProps;
}
@@ -1,3 +1,9 @@
/* Darkside tokens */
import { semanticTokenConfig } from "@navikt/ds-tokens/darkside/tokens/semantic";
import { SemanticTokensForAllRolesConfigT } from "@navikt/ds-tokens/darkside/tokens/semantic-roles";
import { shadowTokenConfig } from "@navikt/ds-tokens/darkside/tokens/shadow";
/* Old */
import borderRadii from "@navikt/ds-tokens/src/border.json";
import bgColors from "@navikt/ds-tokens/src/colors-bg.json";
import borderColors from "@navikt/ds-tokens/src/colors-border.json";
@@ -27,3 +33,21 @@ type FixedResponsiveT<T> = {
};
export type ResponsiveProp<T> = T | FixedResponsiveT<T>;
/**
* Darkside tokens
*/
export type SemanticShadowTokens = keyof ReturnType<
typeof shadowTokenConfig
>["shadow"];
export type SemanticStaticBgDarkside = keyof ReturnType<
typeof semanticTokenConfig
>["bg"];
export type SemanticRoleBgDarkside =
keyof SemanticTokensForAllRolesConfigT<"color">["bg"];
export type SemanticStaticBorderDarkside = keyof ReturnType<
typeof semanticTokenConfig
>["border"];
@@ -45,9 +45,16 @@ export default {
labelSuffix: "delete",
},
},
CopyButton: {
title: "Copy",
activeText: "Copied!",
},
ErrorSummary: {
heading: "You must correct the following errors before you can continue:",
},
FormSummary: {
editAnswer: "Edit answer",
},
Loader: {
title: "Waiting…",
},
@@ -117,4 +124,16 @@ export default {
closeDatePicker: "Close date picker",
closeMonthPicker: "Close month picker",
},
Combobox: {
addOption: "Add",
loading: "Searching…",
maxSelected: "{selected} of max {limit} are selected.",
clear: "Clear",
},
GuidePanel: {
illustrationLabel: "Illustration of advisor",
},
HelpText: {
title: "More information",
},
} satisfies Translations;
@@ -49,9 +49,16 @@ export default {
labelSuffix: "slett",
},
},
CopyButton: {
title: "Kopier",
activeText: "Kopiert!",
},
ErrorSummary: {
heading: "Du må rette disse feilene før du kan fortsette:",
},
FormSummary: {
editAnswer: "Endre svar",
},
Loader: {
title: "Venter…",
},
@@ -122,4 +129,18 @@ export default {
closeDatePicker: "Lukk datovelger",
closeMonthPicker: "Lukk månedsvelger",
},
Combobox: {
/** The input value will be appended to the end of this text, e.g. `Legg til "input value"`. */
addOption: "Legg til",
/** Loader title */
loading: "Søker…",
maxSelected: "{selected} av maks {limit} er valgt.",
clear: "Tøm",
},
GuidePanel: {
illustrationLabel: "Illustrasjon av veileder",
},
HelpText: {
title: "Mer informasjon",
},
} satisfies TranslationMap;
@@ -45,9 +45,16 @@ export default {
labelSuffix: "slett",
},
},
CopyButton: {
title: "Kopier",
activeText: "Kopiert!",
},
ErrorSummary: {
heading: "Du må rette desse feila før du kan halde fram:",
},
FormSummary: {
editAnswer: "Endre svar",
},
Loader: {
title: "Ventar…",
},
@@ -117,4 +124,16 @@ export default {
closeDatePicker: "Lukk datoveljar",
closeMonthPicker: "Lukk månadsveljar",
},
Combobox: {
addOption: "Legg til",
loading: "Søker…",
maxSelected: "{selected} av maks {limit} er valt.",
clear: "Tøm",
},
GuidePanel: {
illustrationLabel: "Illustrasjon av rettleiar",
},
HelpText: {
title: "Meir informasjon",
},
} satisfies Translations;
+2
View File
@@ -1,5 +1,7 @@
# @navikt/ds-tailwind
## 7.7.0
## 7.6.0
## 7.5.3
+66
View File
@@ -0,0 +1,66 @@
import { describe, expect, test } from "vitest";
import { breakpointsTokenConfig } from "@navikt/ds-tokens/darkside/tokens/breakpoints";
import { config, extractTokensForCategory } from "./darkside";
describe("Darkside tailwind config", () => {
test("should have correct color tokens", () => {
const colorKeys = Object.keys(config.theme.colors);
expect(colorKeys).not.toContain("spacing");
expect(colorKeys).not.toContain("shadow");
expect(colorKeys).not.toContain("font-weight");
expect(colorKeys).not.toContain("font-size");
expect(colorKeys).not.toContain("font-line-height");
expect(colorKeys).not.toContain("font-family");
expect(colorKeys).not.toContain("border-radius");
expect(colorKeys).not.toContain("breakpoint");
});
test("should have correct screen breakpoints", () => {
expect(config.theme.screens.sm).toBe(
breakpointsTokenConfig.breakpoint.sm.value,
);
expect(config.theme.screens.md).toBe(
breakpointsTokenConfig.breakpoint.md.value,
);
expect(config.theme.screens.lg).toBe(
breakpointsTokenConfig.breakpoint.lg.value,
);
expect(config.theme.screens.xl).toBe(
breakpointsTokenConfig.breakpoint.xl.value,
);
expect(config.theme.screens["2xl"]).toBe(
breakpointsTokenConfig.breakpoint["2xl"].value,
);
});
test("should have correct extended properties", () => {
expect(config.theme.extend.shadow).toEqual(
extractTokensForCategory("shadow"),
);
expect(config.theme.extend.spacing).toEqual(
extractTokensForCategory("spacing"),
);
expect(config.theme.extend.fontWeight).toEqual(
extractTokensForCategory("font-weight"),
);
expect(config.theme.extend.fontSize).toEqual(
extractTokensForCategory("font-size"),
);
expect(config.theme.extend.lineHeight).toEqual(
extractTokensForCategory("font-line-height"),
);
expect(config.theme.extend.fontFamily).toEqual(
extractTokensForCategory("font-family"),
);
expect(config.theme.extend.borderRadius).toEqual(
extractTokensForCategory("border-radius"),
);
});
test("should extract tokens correctly for a given category", () => {
const spacingTokens = extractTokensForCategory("spacing");
Object.entries(spacingTokens).forEach(([key]) => {
expect(key).not.toContain("spacing-");
});
});
});
+3 -5
View File
@@ -21,7 +21,6 @@ const nonColorTokens = [
];
/*
* Assumes that all remaining names not in nonColorTokens are colors
* TODO: Should probably write some tests on this when tokens are more stable
*/
const colorTokensEntries = Object.entries(transformedTokens).filter(([key]) => {
return !nonColorTokens.find((prefix) => key.toLowerCase().includes(prefix));
@@ -29,13 +28,11 @@ const colorTokensEntries = Object.entries(transformedTokens).filter(([key]) => {
const colors = Object.fromEntries(colorTokensEntries);
/**
* TODO features
* - Shadow
* TODO deprecations:
* - max-width
* - z-index
*/
const config = {
export const config = {
theme: {
colors,
screens: {
@@ -46,6 +43,7 @@ const config = {
"2xl": breakpointsTokenConfig.breakpoint["2xl"].value,
},
extend: {
shadow: extractTokensForCategory("shadow"),
spacing: extractTokensForCategory("spacing"),
fontWeight: extractTokensForCategory("font-weight"),
fontSize: extractTokensForCategory("font-size"),
@@ -65,7 +63,7 @@ writeFileSync("tailwind.darkside.config.js", outputString);
/* -------------------------------------------------------------------------- */
/* Cherry-picks object keys we want */
function extractTokensForCategory(tokenName: string) {
export function extractTokensForCategory(tokenName: string) {
const tokens = Object.entries(transformedTokens)
.filter(([key]) => key.startsWith(tokenName))
/* We want extract only the value from each token, so we replace the name: "spacing-4" -> "4" */
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-tailwind",
"version": "7.6.0",
"version": "7.7.0",
"description": "Tailwind config based on @navikt/ds-tokens",
"author": "Aksel | NAV designsystem team",
"keywords": [
@@ -25,7 +25,7 @@
"directory": "@navikt/core/tailwind"
},
"devDependencies": {
"@navikt/ds-tokens": "^7.6.0",
"@navikt/ds-tokens": "^7.7.0",
"color": "4.2.3",
"lodash": "^4.17.21",
"tailwindcss": "^3.3.3",
+2
View File
@@ -1,5 +1,7 @@
# @navikt/ds-tokens
## 7.7.0
## 7.6.0
## 7.5.3
@@ -68,75 +68,75 @@ export const globalColorDarkModeConfigWithoutAlpha: GlobalConfigT = {
},
/* Info is currently just a copy of brandThree */
info: {
"100": { value: "#071e2d", type: "global-color", group: "brandThree" },
"200": { value: "#0d2534", type: "global-color", group: "brandThree" },
"300": { value: "#122d3e", type: "global-color", group: "brandThree" },
"400": { value: "#19394c", type: "global-color", group: "brandThree" },
"500": { value: "#43718d", type: "global-color", group: "brandThree" },
"600": { value: "#5a839b", type: "global-color", group: "brandThree" },
"700": { value: "#7396ab", type: "global-color", group: "brandThree" },
"800": { value: "#7f9fb3", type: "global-color", group: "brandThree" },
"900": { value: "#93afc0", type: "global-color", group: "brandThree" },
"1000": { value: "#b7cbd7", type: "global-color", group: "brandThree" },
"100": { value: "#071e2d", type: "global-color", group: "info" },
"200": { value: "#0d2534", type: "global-color", group: "info" },
"300": { value: "#122d3e", type: "global-color", group: "info" },
"400": { value: "#19394c", type: "global-color", group: "info" },
"500": { value: "#43718d", type: "global-color", group: "info" },
"600": { value: "#5a839b", type: "global-color", group: "info" },
"700": { value: "#7396ab", type: "global-color", group: "info" },
"800": { value: "#7f9fb3", type: "global-color", group: "info" },
"900": { value: "#93afc0", type: "global-color", group: "info" },
"1000": { value: "#b7cbd7", type: "global-color", group: "info" },
},
brandOne: {
"100": { value: "#321220", type: "global-color", group: "brandOne" },
"200": { value: "#3a1827", type: "global-color", group: "brandOne" },
"300": { value: "#42202e", type: "global-color", group: "brandOne" },
"400": { value: "#4e2a39", type: "global-color", group: "brandOne" },
"500": { value: "#a35276", type: "global-color", group: "brandOne" },
"600": { value: "#b06886", type: "global-color", group: "brandOne" },
"700": { value: "#be7f99", type: "global-color", group: "brandOne" },
"800": { value: "#c58aa2", type: "global-color", group: "brandOne" },
"900": { value: "#cf9eb1", type: "global-color", group: "brandOne" },
"1000": { value: "#e1c0cc", type: "global-color", group: "brandOne" },
"brand-one": {
"100": { value: "#321220", type: "global-color", group: "brand-one" },
"200": { value: "#3a1827", type: "global-color", group: "brand-one" },
"300": { value: "#42202e", type: "global-color", group: "brand-one" },
"400": { value: "#4e2a39", type: "global-color", group: "brand-one" },
"500": { value: "#a35276", type: "global-color", group: "brand-one" },
"600": { value: "#b06886", type: "global-color", group: "brand-one" },
"700": { value: "#be7f99", type: "global-color", group: "brand-one" },
"800": { value: "#c58aa2", type: "global-color", group: "brand-one" },
"900": { value: "#cf9eb1", type: "global-color", group: "brand-one" },
"1000": { value: "#e1c0cc", type: "global-color", group: "brand-one" },
},
brandTwo: {
"100": { value: "#2d160e", type: "global-color", group: "brandTwo" },
"200": { value: "#351d15", type: "global-color", group: "brandTwo" },
"300": { value: "#3d241c", type: "global-color", group: "brandTwo" },
"400": { value: "#493027", type: "global-color", group: "brandTwo" },
"500": { value: "#975e4a", type: "global-color", group: "brandTwo" },
"600": { value: "#ab6f5b", type: "global-color", group: "brandTwo" },
"700": { value: "#c0836e", type: "global-color", group: "brandTwo" },
"800": { value: "#c78e79", type: "global-color", group: "brandTwo" },
"900": { value: "#d1a08c", type: "global-color", group: "brandTwo" },
"1000": { value: "#e3c2b1", type: "global-color", group: "brandTwo" },
"brand-two": {
"100": { value: "#2d160e", type: "global-color", group: "brand-two" },
"200": { value: "#351d15", type: "global-color", group: "brand-two" },
"300": { value: "#3d241c", type: "global-color", group: "brand-two" },
"400": { value: "#493027", type: "global-color", group: "brand-two" },
"500": { value: "#975e4a", type: "global-color", group: "brand-two" },
"600": { value: "#ab6f5b", type: "global-color", group: "brand-two" },
"700": { value: "#c0836e", type: "global-color", group: "brand-two" },
"800": { value: "#c78e79", type: "global-color", group: "brand-two" },
"900": { value: "#d1a08c", type: "global-color", group: "brand-two" },
"1000": { value: "#e3c2b1", type: "global-color", group: "brand-two" },
},
brandThree: {
"100": { value: "#071e2d", type: "global-color", group: "brandThree" },
"200": { value: "#0d2534", type: "global-color", group: "brandThree" },
"300": { value: "#122d3e", type: "global-color", group: "brandThree" },
"400": { value: "#19394c", type: "global-color", group: "brandThree" },
"500": { value: "#43718d", type: "global-color", group: "brandThree" },
"600": { value: "#5a839b", type: "global-color", group: "brandThree" },
"700": { value: "#7396ab", type: "global-color", group: "brandThree" },
"800": { value: "#7f9fb3", type: "global-color", group: "brandThree" },
"900": { value: "#93afc0", type: "global-color", group: "brandThree" },
"1000": { value: "#b7cbd7", type: "global-color", group: "brandThree" },
"brand-three": {
"100": { value: "#071e2d", type: "global-color", group: "brand-three" },
"200": { value: "#0d2534", type: "global-color", group: "brand-three" },
"300": { value: "#122d3e", type: "global-color", group: "brand-three" },
"400": { value: "#19394c", type: "global-color", group: "brand-three" },
"500": { value: "#43718d", type: "global-color", group: "brand-three" },
"600": { value: "#5a839b", type: "global-color", group: "brand-three" },
"700": { value: "#7396ab", type: "global-color", group: "brand-three" },
"800": { value: "#7f9fb3", type: "global-color", group: "brand-three" },
"900": { value: "#93afc0", type: "global-color", group: "brand-three" },
"1000": { value: "#b7cbd7", type: "global-color", group: "brand-three" },
},
dataOne: {
"100": { value: "#221a2c", type: "global-color", group: "dataOne" },
"200": { value: "#272032", type: "global-color", group: "dataOne" },
"300": { value: "#2f273a", type: "global-color", group: "dataOne" },
"400": { value: "#3a3245", type: "global-color", group: "dataOne" },
"500": { value: "#776491", type: "global-color", group: "dataOne" },
"600": { value: "#8876a1", type: "global-color", group: "dataOne" },
"700": { value: "#9b8bb0", type: "global-color", group: "dataOne" },
"800": { value: "#a495b7", type: "global-color", group: "dataOne" },
"900": { value: "#b2a7c3", type: "global-color", group: "dataOne" },
"1000": { value: "#cdc5d9", type: "global-color", group: "dataOne" },
"data-one": {
"100": { value: "#221a2c", type: "global-color", group: "data-one" },
"200": { value: "#272032", type: "global-color", group: "data-one" },
"300": { value: "#2f273a", type: "global-color", group: "data-one" },
"400": { value: "#3a3245", type: "global-color", group: "data-one" },
"500": { value: "#776491", type: "global-color", group: "data-one" },
"600": { value: "#8876a1", type: "global-color", group: "data-one" },
"700": { value: "#9b8bb0", type: "global-color", group: "data-one" },
"800": { value: "#a495b7", type: "global-color", group: "data-one" },
"900": { value: "#b2a7c3", type: "global-color", group: "data-one" },
"1000": { value: "#cdc5d9", type: "global-color", group: "data-one" },
},
dataTwo: {
"100": { value: "#1c1f00", type: "global-color", group: "dataTwo" },
"200": { value: "#222500", type: "global-color", group: "dataTwo" },
"300": { value: "#292d00", type: "global-color", group: "dataTwo" },
"400": { value: "#343900", type: "global-color", group: "dataTwo" },
"500": { value: "#6a7200", type: "global-color", group: "dataTwo" },
"600": { value: "#7c8400", type: "global-color", group: "dataTwo" },
"700": { value: "#8f9800", type: "global-color", group: "dataTwo" },
"800": { value: "#99a200", type: "global-color", group: "dataTwo" },
"900": { value: "#a9b325", type: "global-color", group: "dataTwo" },
"1000": { value: "#c5d14c", type: "global-color", group: "dataTwo" },
"data-two": {
"100": { value: "#1c1f00", type: "global-color", group: "data-two" },
"200": { value: "#222500", type: "global-color", group: "data-two" },
"300": { value: "#292d00", type: "global-color", group: "data-two" },
"400": { value: "#343900", type: "global-color", group: "data-two" },
"500": { value: "#6a7200", type: "global-color", group: "data-two" },
"600": { value: "#7c8400", type: "global-color", group: "data-two" },
"700": { value: "#8f9800", type: "global-color", group: "data-two" },
"800": { value: "#99a200", type: "global-color", group: "data-two" },
"900": { value: "#a9b325", type: "global-color", group: "data-two" },
"1000": { value: "#c5d14c", type: "global-color", group: "data-two" },
},
};
@@ -78,64 +78,64 @@ export const globalColorLightModeConfigWithoutAlpha: GlobalConfigT = {
"900": { value: "#00557d", type: "global-color", group: "info" },
"1000": { value: "#002942", type: "global-color", group: "info" },
},
brandOne: {
"100": { value: "#fbf3f6", type: "global-color", group: "brandOne" },
"200": { value: "#f8eaef", type: "global-color", group: "brandOne" },
"300": { value: "#f3dde5", type: "global-color", group: "brandOne" },
"400": { value: "#eccad6", type: "global-color", group: "brandOne" },
"500": { value: "#c26f92", type: "global-color", group: "brandOne" },
"600": { value: "#b65781", type: "global-color", group: "brandOne" },
"700": { value: "#a93d70", type: "global-color", group: "brandOne" },
"800": { value: "#a33069", type: "global-color", group: "brandOne" },
"900": { value: "#98185d", type: "global-color", group: "brandOne" },
"1000": { value: "#52002b", type: "global-color", group: "brandOne" },
"brand-one": {
"100": { value: "#fbf3f6", type: "global-color", group: "brand-one" },
"200": { value: "#f8eaef", type: "global-color", group: "brand-one" },
"300": { value: "#f3dde5", type: "global-color", group: "brand-one" },
"400": { value: "#eccad6", type: "global-color", group: "brand-one" },
"500": { value: "#c26f92", type: "global-color", group: "brand-one" },
"600": { value: "#b65781", type: "global-color", group: "brand-one" },
"700": { value: "#a93d70", type: "global-color", group: "brand-one" },
"800": { value: "#a33069", type: "global-color", group: "brand-one" },
"900": { value: "#98185d", type: "global-color", group: "brand-one" },
"1000": { value: "#52002b", type: "global-color", group: "brand-one" },
},
brandTwo: {
"100": { value: "#fff4ee", type: "global-color", group: "brandTwo" },
"200": { value: "#fdebe0", type: "global-color", group: "brandTwo" },
"300": { value: "#fcddcd", type: "global-color", group: "brandTwo" },
"400": { value: "#f8c8b1", type: "global-color", group: "brandTwo" },
"500": { value: "#c0765d", type: "global-color", group: "brandTwo" },
"600": { value: "#a9654e", type: "global-color", group: "brandTwo" },
"700": { value: "#915541", type: "global-color", group: "brandTwo" },
"800": { value: "#874e3b", type: "global-color", group: "brandTwo" },
"900": { value: "#764332", type: "global-color", group: "brandTwo" },
"1000": { value: "#3c1f15", type: "global-color", group: "brandTwo" },
"brand-two": {
"100": { value: "#fff4ee", type: "global-color", group: "brand-two" },
"200": { value: "#fdebe0", type: "global-color", group: "brand-two" },
"300": { value: "#fcddcd", type: "global-color", group: "brand-two" },
"400": { value: "#f8c8b1", type: "global-color", group: "brand-two" },
"500": { value: "#c0765d", type: "global-color", group: "brand-two" },
"600": { value: "#a9654e", type: "global-color", group: "brand-two" },
"700": { value: "#915541", type: "global-color", group: "brand-two" },
"800": { value: "#874e3b", type: "global-color", group: "brand-two" },
"900": { value: "#764332", type: "global-color", group: "brand-two" },
"1000": { value: "#3c1f15", type: "global-color", group: "brand-two" },
},
brandThree: {
"100": { value: "#eef6fc", type: "global-color", group: "brandThree" },
"200": { value: "#e3eff7", type: "global-color", group: "brandThree" },
"300": { value: "#d7e6f0", type: "global-color", group: "brandThree" },
"400": { value: "#c0d6e4", type: "global-color", group: "brandThree" },
"500": { value: "#5a8fae", type: "global-color", group: "brandThree" },
"600": { value: "#417da0", type: "global-color", group: "brandThree" },
"700": { value: "#246b91", type: "global-color", group: "brandThree" },
"800": { value: "#156389", type: "global-color", group: "brandThree" },
"900": { value: "#00557d", type: "global-color", group: "brandThree" },
"1000": { value: "#002942", type: "global-color", group: "brandThree" },
"brand-three": {
"100": { value: "#eef6fc", type: "global-color", group: "brand-three" },
"200": { value: "#e3eff7", type: "global-color", group: "brand-three" },
"300": { value: "#d7e6f0", type: "global-color", group: "brand-three" },
"400": { value: "#c0d6e4", type: "global-color", group: "brand-three" },
"500": { value: "#5a8fae", type: "global-color", group: "brand-three" },
"600": { value: "#417da0", type: "global-color", group: "brand-three" },
"700": { value: "#246b91", type: "global-color", group: "brand-three" },
"800": { value: "#156389", type: "global-color", group: "brand-three" },
"900": { value: "#00557d", type: "global-color", group: "brand-three" },
"1000": { value: "#002942", type: "global-color", group: "brand-three" },
},
dataOne: {
"100": { value: "#f7f5f9", type: "global-color", group: "dataOne" },
"200": { value: "#f0edf4", type: "global-color", group: "dataOne" },
"300": { value: "#e6e1ed", type: "global-color", group: "dataOne" },
"400": { value: "#d7cfe3", type: "global-color", group: "dataOne" },
"500": { value: "#9580b1", type: "global-color", group: "dataOne" },
"600": { value: "#846ca4", type: "global-color", group: "dataOne" },
"700": { value: "#725a91", type: "global-color", group: "dataOne" },
"800": { value: "#6a5289", type: "global-color", group: "dataOne" },
"900": { value: "#5e467c", type: "global-color", group: "dataOne" },
"1000": { value: "#331a4d", type: "global-color", group: "dataOne" },
"data-one": {
"100": { value: "#f7f5f9", type: "global-color", group: "data-one" },
"200": { value: "#f0edf4", type: "global-color", group: "data-one" },
"300": { value: "#e6e1ed", type: "global-color", group: "data-one" },
"400": { value: "#d7cfe3", type: "global-color", group: "data-one" },
"500": { value: "#9580b1", type: "global-color", group: "data-one" },
"600": { value: "#846ca4", type: "global-color", group: "data-one" },
"700": { value: "#725a91", type: "global-color", group: "data-one" },
"800": { value: "#6a5289", type: "global-color", group: "data-one" },
"900": { value: "#5e467c", type: "global-color", group: "data-one" },
"1000": { value: "#331a4d", type: "global-color", group: "data-one" },
},
dataTwo: {
"100": { value: "#f4f9d1", type: "global-color", group: "dataTwo" },
"200": { value: "#ebf4a9", type: "global-color", group: "dataTwo" },
"300": { value: "#e0ec6b", type: "global-color", group: "dataTwo" },
"400": { value: "#d0dc00", type: "global-color", group: "dataTwo" },
"500": { value: "#878f00", type: "global-color", group: "dataTwo" },
"600": { value: "#757c00", type: "global-color", group: "dataTwo" },
"700": { value: "#646900", type: "global-color", group: "dataTwo" },
"800": { value: "#5c6100", type: "global-color", group: "dataTwo" },
"900": { value: "#515400", type: "global-color", group: "dataTwo" },
"1000": { value: "#2a2800", type: "global-color", group: "dataTwo" },
"data-two": {
"100": { value: "#f4f9d1", type: "global-color", group: "data-two" },
"200": { value: "#ebf4a9", type: "global-color", group: "data-two" },
"300": { value: "#e0ec6b", type: "global-color", group: "data-two" },
"400": { value: "#d0dc00", type: "global-color", group: "data-two" },
"500": { value: "#878f00", type: "global-color", group: "data-two" },
"600": { value: "#757c00", type: "global-color", group: "data-two" },
"700": { value: "#646900", type: "global-color", group: "data-two" },
"800": { value: "#5c6100", type: "global-color", group: "data-two" },
"900": { value: "#515400", type: "global-color", group: "data-two" },
"1000": { value: "#2a2800", type: "global-color", group: "data-two" },
},
};
@@ -2,127 +2,167 @@ import _ from "lodash";
import {
type ColorTheme,
type GlobalColorRoles,
StyleDictionaryToken,
type StyleDictionaryTokenConfig,
TokenTypes,
globalColorRoles,
} from "../util";
const configForRole = (
role: GlobalColorRoles,
theme: ColorTheme,
): StyleDictionaryTokenConfig<"color"> => ({
export type BgKeys =
| GlobalColorRoles
| `${GlobalColorRoles}-hover`
| `${GlobalColorRoles}-hoverA`
| `${GlobalColorRoles}-moderate`
| `${GlobalColorRoles}-moderateA`
| `${GlobalColorRoles}-moderate-hover`
| `${GlobalColorRoles}-moderate-hoverA`
| `${GlobalColorRoles}-moderate-pressed`
| `${GlobalColorRoles}-moderate-pressedA`
| `${GlobalColorRoles}-strong`
| `${GlobalColorRoles}-strong-hover`
| `${GlobalColorRoles}-strong-pressed`
| `${GlobalColorRoles}-raised`
| `${GlobalColorRoles}-raised-hover`;
export type TextKeys =
| GlobalColorRoles
| `${GlobalColorRoles}-strong`
| `${GlobalColorRoles}-icon`;
export type BorderKeys =
| GlobalColorRoles
| `${GlobalColorRoles}-subtle`
| `${GlobalColorRoles}-subtleA`
| `${GlobalColorRoles}-strong`;
export type SemanticTokensForAllRolesConfigT<T extends TokenTypes> = {
bg: {
[role]: {
value: `{ax.${role}.100.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-hover`]: {
value: `{ax.${role}.200.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-hoverA`]: {
value: `{ax.${role}.200A.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-moderate`]: {
value: `{ax.${role}.200.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-moderateA`]: {
value: `{ax.${role}.200A.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-moderate-hover`]: {
value: `{ax.${role}.300.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-moderate-hoverA`]: {
value: `{ax.${role}.300A.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-moderate-pressed`]: {
value: `{ax.${role}.400.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-moderate-pressedA`]: {
value: `{ax.${role}.400A.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-strong`]: {
value: `{ax.${role}.600.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-strong-hover`]: {
value: `{ax.${role}.700.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-strong-pressed`]: {
value: `{ax.${role}.800.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-raised`]: {
/* We bump raised for darkmode */
value: `{ax.${role}.${theme === "light" ? "100" : "200"}.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-raised-hover`]: {
value: `{ax.${role}.${theme === "light" ? "200" : "300"}.value}`,
type: "color",
group: `background.${role}`,
},
},
[k in BgKeys]: Record<string, StyleDictionaryToken<T>>;
};
text: {
[role]: {
value: `{ax.${role}.700.value}`,
type: "color",
group: `text.${role}`,
},
[`${role}-strong`]: {
value: `{ax.${role}.900.value}`,
type: "color",
group: `text.${role}`,
},
[`${role}-icon`]: {
value: `{ax.${role}.600.value}`,
type: "color",
group: `text.${role}`,
},
},
[k in TextKeys]: Record<string, StyleDictionaryToken<T>>;
};
border: {
[role]: {
value: `{ax.${role}.500.value}`,
type: "color",
group: `border.${role}`,
[k in BorderKeys]: Record<string, StyleDictionaryToken<T>>;
};
};
const configForRole = (role: GlobalColorRoles, theme: ColorTheme) => {
return {
bg: {
[role]: {
value: `{ax.${role}.100.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-hover`]: {
value: `{ax.${role}.200.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-hoverA`]: {
value: `{ax.${role}.200A.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-moderate`]: {
value: `{ax.${role}.200.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-moderateA`]: {
value: `{ax.${role}.200A.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-moderate-hover`]: {
value: `{ax.${role}.300.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-moderate-hoverA`]: {
value: `{ax.${role}.300A.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-moderate-pressed`]: {
value: `{ax.${role}.400.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-moderate-pressedA`]: {
value: `{ax.${role}.400A.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-strong`]: {
value: `{ax.${role}.600.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-strong-hover`]: {
value: `{ax.${role}.700.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-strong-pressed`]: {
value: `{ax.${role}.800.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-raised`]: {
/* We bump raised for darkmode */
value: `{ax.${role}.${theme === "light" ? "100" : "200"}.value}`,
type: "color",
group: `background.${role}`,
},
[`${role}-raised-hover`]: {
value: `{ax.${role}.${theme === "light" ? "200" : "300"}.value}`,
type: "color",
group: `background.${role}`,
},
},
[`${role}-subtle`]: {
value: `{ax.${role}.400.value}`,
type: "color",
group: `border.${role}`,
text: {
[role]: {
value: `{ax.${role}.700.value}`,
type: "color",
group: `text.${role}`,
},
[`${role}-strong`]: {
value: `{ax.${role}.900.value}`,
type: "color",
group: `text.${role}`,
},
[`${role}-icon`]: {
value: `{ax.${role}.600.value}`,
type: "color",
group: `text.${role}`,
},
},
[`${role}-subtleA`]: {
value: `{ax.${role}.400A.value}`,
type: "color",
group: `border.${role}`,
border: {
[role]: {
value: `{ax.${role}.500.value}`,
type: "color",
group: `border.${role}`,
},
[`${role}-subtle`]: {
value: `{ax.${role}.400.value}`,
type: "color",
group: `border.${role}`,
},
[`${role}-subtleA`]: {
value: `{ax.${role}.400A.value}`,
type: "color",
group: `border.${role}`,
},
[`${role}-strong`]: {
value: `{ax.${role}.600.value}`,
type: "color",
group: `border.${role}`,
},
},
[`${role}-strong`]: {
value: `{ax.${role}.600.value}`,
type: "color",
group: `border.${role}`,
},
},
});
} satisfies StyleDictionaryTokenConfig<"color">;
};
/**
* We need to deep merge the token config for each role to get the complete token config for all roles.
@@ -1,8 +1,6 @@
import { ColorTheme, StyleDictionaryTokenConfig } from "../util";
export function semanticTokenConfig(
theme: ColorTheme,
): StyleDictionaryTokenConfig<"color"> {
export function semanticTokenConfig(theme: ColorTheme) {
return {
text: {
default: {
@@ -99,5 +97,5 @@ export function semanticTokenConfig(
scopes: ["EFFECT_COLOR"],
},
},
};
} satisfies StyleDictionaryTokenConfig<"color">;
}
@@ -1,8 +1,6 @@
import { ColorTheme, StyleDictionaryTokenConfig } from "../util";
export function shadowTokenConfig(
theme: ColorTheme,
): StyleDictionaryTokenConfig<"shadow"> {
export function shadowTokenConfig(theme: ColorTheme) {
return {
shadow: {
dialog: {
@@ -15,5 +13,5 @@ export function shadowTokenConfig(
figmaIgnore: true,
},
},
};
} satisfies StyleDictionaryTokenConfig<"shadow">;
}
@@ -39,31 +39,31 @@ export const textContrastTokenConfig = (): {
group: "text.warning",
},
/* Brand */
"brandOne-contrast": {
"brand-one-contrast": {
value: "{ax.neutral.000.value}",
type: "color",
group: "text.brandOne",
group: "text.brand-one",
},
"brandTwo-contrast": {
"brand-two-contrast": {
value: "{ax.neutral.000.value}",
type: "color",
group: "text.brandTwo",
group: "text.brand-two",
},
"brandThree-contrast": {
"brand-three-contrast": {
value: "{ax.neutral.000.value}",
type: "color",
group: "text.brandThree",
group: "text.brand-three",
},
/* Data */
"dataOne-contrast": {
"data-one-contrast": {
value: "{ax.neutral.000.value}",
type: "color",
group: "text.dataOne",
group: "text.data-one",
},
"dataTwo-contrast": {
"data-two-contrast": {
value: "{ax.neutral.000.value}",
type: "color",
group: "text.dataTwo",
group: "text.data-two",
},
},
});
+29 -6
View File
@@ -27,11 +27,11 @@ export const globalColorRoles = [
"warning",
"danger",
"info",
"brandOne",
"brandTwo",
"brandThree",
"dataOne",
"dataTwo",
"brand-one",
"brand-two",
"brand-three",
"data-one",
"data-two",
] as const;
export type GlobalColorRoles = (typeof globalColorRoles)[number];
@@ -88,7 +88,30 @@ export type StyleDictionaryToken<T extends TokenTypes> = {
* Optional extra scopes for the token.
* Token will include all default scopes based on `type`, and any extra specified here.
*/
scopes?: VariableScope[];
scopes?: (
| "ALL_SCOPES"
| "TEXT_CONTENT"
| "CORNER_RADIUS"
| "WIDTH_HEIGHT"
| "GAP"
| "ALL_FILLS"
| "FRAME_FILL"
| "SHAPE_FILL"
| "TEXT_FILL"
| "STROKE_COLOR"
| "STROKE_FLOAT"
| "EFFECT_FLOAT"
| "EFFECT_COLOR"
| "OPACITY"
| "FONT_FAMILY"
| "FONT_STYLE"
| "FONT_WEIGHT"
| "FONT_SIZE"
| "LINE_HEIGHT"
| "LETTER_SPACING"
| "PARAGRAPH_SPACING"
| "PARAGRAPH_INDENT"
)[];
/**
* In some cases, we want to hide tokens from the Figma plugin.
* Currently only relevant for shadow-tokens.
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-tokens",
"version": "7.6.0",
"version": "7.7.0",
"description": "Design-tokens for NAV designsystem",
"author": "Aksel | NAV designsystem team",
"keywords": [
+14
View File
@@ -1,5 +1,19 @@
# Changelog
## 7.7
### @navikt/ds-react
- CopyButton: Removed prop `activeTitle`. Use `activeText` instead. ([#3426](https://github.com/navikt/aksel/pull/3426))
- Combobox: :boom: Removed prop `toggleListButtonLabel` ([#3409](https://github.com/navikt/aksel/pull/3409))
* Combobox: Hid buttons from screen readers, added `title` on clear button, removed sr-only text on toggle list button. ([#3409](https://github.com/navikt/aksel/pull/3409))
* InternalHeader.UserButton: Remove `title`-attribute on icon and improved types. ([#3424](https://github.com/navikt/aksel/pull/3424))
* CopyButton: Fix issue where state changes are announced multiple times using VO in Chrome ([#3374](https://github.com/navikt/aksel/pull/3374))
## 7.6
### @navikt/aksel-icons
+5 -5
View File
@@ -15,10 +15,10 @@
"playroom"
],
"dependencies": {
"@navikt/aksel-icons": "^7.6.0",
"@navikt/ds-css": "^7.6.0",
"@navikt/ds-react": "^7.6.0",
"@navikt/ds-tailwind": "^7.6.0",
"@navikt/ds-tokens": "^7.6.0"
"@navikt/aksel-icons": "^7.7.0",
"@navikt/ds-css": "^7.7.0",
"@navikt/ds-react": "^7.7.0",
"@navikt/ds-tailwind": "^7.7.0",
"@navikt/ds-tokens": "^7.7.0"
}
}
@@ -4,10 +4,6 @@ import { withDsExample } from "@/web/examples/withDsExample";
const Example = () => {
const [value, setValue] = useState("");
const mockPersistUserAddedValues = (option, isSelected) => {
console.info("custom option", { option, isSelected });
};
const [selectedOptions, setSelectedOptions] = useState(
initialSelectedOptions,
);
@@ -15,6 +11,9 @@ const Example = () => {
() => initialOptions.filter((option) => option.includes(value)),
[value],
);
const mockPersistUserAddedValues = (option: string, isSelected: boolean) => {
console.info("custom option", { option, isSelected });
};
const onToggleSelected = (
option: string,
@@ -32,19 +31,17 @@ const Example = () => {
};
return (
<div>
<UNSAFE_Combobox
allowNewValues
label="Hvilke land har du besøkt de siste 6 ukene? Velg opptil flere."
filteredOptions={filteredOptions}
isMultiSelect
onChange={setValue}
onToggleSelected={onToggleSelected}
selectedOptions={selectedOptions}
options={initialOptions}
value={value}
/>
</div>
<UNSAFE_Combobox
allowNewValues
label="Hvilke land har du besøkt de siste 6 ukene?"
filteredOptions={filteredOptions}
isMultiSelect
onChange={setValue}
onToggleSelected={onToggleSelected}
selectedOptions={selectedOptions}
options={initialOptions}
value={value}
/>
);
};
@@ -77,5 +74,5 @@ export const Demo = {
export const args = {
index: 5,
desc: "Du kan overstyre blant annet value, selectedOptions, filteredOptions.",
desc: "Du kan overstyre blant annet value, selectedOptions og filteredOptions.",
};
@@ -3,30 +3,28 @@ import { withDsExample } from "@/web/examples/withDsExample";
const Example = () => {
return (
<div>
<UNSAFE_Combobox
allowNewValues
label="Hva er dine favorittdrikker? Legg gjerne til flere alternativer."
options={initialOptions}
isMultiSelect
/>
</div>
<UNSAFE_Combobox
allowNewValues
label="Hva er dine favorittdrikker? Legg gjerne til flere alternativer."
options={initialOptions}
isMultiSelect
/>
);
};
const initialOptions = [
"tea",
"coffee",
"hot chocolate",
"te",
"kaffe",
"varm sjokolade",
"lemonade",
"orange juice",
"apple juice",
"appelsinjuice",
"eplejuice",
"smoothie",
"milk",
"water",
"soda",
"beer",
"wine",
"melk",
"vann",
"brus",
"øl",
"vin",
];
// EXAMPLES DO NOT INCLUDE CONTENT BELOW THIS LINE
@@ -39,5 +37,5 @@ export const Demo = {
export const args = {
index: 6,
desc: "Ved Multi Select kan brukeren velge flere valg fra nedtrekkslisten.",
desc: "Med `allowNewValues` kan brukeren legge til egne verdier som ikke finnes i listen.",
};
@@ -3,27 +3,25 @@ import { withDsExample } from "@/web/examples/withDsExample";
const Example = () => {
return (
<div>
<UNSAFE_Combobox
label="Hva er de kuleste transportmidlene?"
options={initialOptions}
isMultiSelect
/>
</div>
<UNSAFE_Combobox
label="Hva er de kuleste transportmidlene?"
options={options}
isMultiSelect
/>
);
};
const initialOptions = [
"car",
"bus",
"train",
const options = [
"bil",
"buss",
"tog",
"skateboard",
"bicycle",
"motorcycle",
"boat",
"airplane",
"helicopter",
"truck",
"sykkel",
"motorsykkel",
"båt",
"fly",
"helikopter",
"lastebil",
"van",
"scooter",
];
@@ -38,5 +36,5 @@ export const Demo = {
export const args = {
index: 4,
desc: "Ved Multi Select kan brukeren velge flere valg fra listen.",
desc: "Med `isMultiSelect` kan brukeren velge flere alternativer fra nedtrekkslisten.",
};
@@ -52,16 +52,16 @@ const Example = () => {
};
const options = [
"car",
"bus",
"train",
"bil",
"buss",
"tog",
"skateboard",
"bicycle",
"motorcycle",
"boat",
"airplane",
"helicopter",
"truck",
"sykkel",
"motorsykkel",
"båt",
"fly",
"helikopter",
"lastebil",
"van",
"scooter",
];
@@ -5,32 +5,31 @@ const Example = () => {
const selectedOptions = ["napoleonskake", "donut"];
return (
<div>
<UNSAFE_Combobox
options={initialOptions}
label="Hva er dine favorittfrukter?"
description="Bare de fruktene som du spiser minst 5 av om dagen teller vi som en favorittfrukt."
selectedOptions={selectedOptions}
isMultiSelect
readOnly
/>
</div>
<UNSAFE_Combobox
options={options}
label="Hva er dine favorittfrukter?"
description="Bare de fruktene som du spiser minst 5 av om dagen teller vi som en favorittfrukt."
selectedOptions={selectedOptions}
isMultiSelect
readOnly
/>
);
};
const initialOptions = [
"banana",
"apple",
"tangerine",
"pear",
"grape",
const options = [
"ananas",
"banan",
"bringebær",
"drue",
"eple",
"grapefrukt",
"jordbær",
"kiwi",
"mandarin",
"mango",
"passion fruit",
"pineapple",
"strawberry",
"watermelon",
"grape fruit",
"pære",
"pasjonsfrukt",
"vannmelon",
];
// EXAMPLES DO NOT INCLUDE CONTENT BELOW THIS LINE
@@ -3,17 +3,15 @@ import { withDsExample } from "@/web/examples/withDsExample";
const Example = () => {
return (
<div>
<UNSAFE_Combobox
label="Hva er den aller kuleste Star Wars-filmen noensinne, helt objektivt?"
options={initialOptions}
shouldAutocomplete={true}
/>
</div>
<UNSAFE_Combobox
label="Hva er den aller kuleste Star Wars-filmen noensinne, helt objektivt?"
options={options}
shouldAutocomplete
/>
);
};
const initialOptions = [
const options = [
"A New Hope",
"The Empire Strikes Back",
"Return of the Jedi",
@@ -37,5 +35,5 @@ export const Demo = {
export const args = {
index: 2,
desc: "Ved Single Select velger brukeren ett valg fra listen. Med autocomplete foreslås et valg fra listen som matcher det brukeren skriver.",
desc: "Med `shouldAutocomplete` foreslås et valg fra listen som matcher det brukeren skriver.",
};
@@ -3,28 +3,24 @@ import { withDsExample } from "@/web/examples/withDsExample";
const Example = () => {
return (
<div>
<UNSAFE_Combobox
label="Hva er din favorittfrukt?"
options={initialOptions}
/>
</div>
<UNSAFE_Combobox label="Hva er din favorittfrukt?" options={options} />
);
};
const initialOptions = [
"banana",
"apple",
"tangerine",
"pear",
"grape",
const options = [
"ananas",
"banan",
"bringebær",
"drue",
"eple",
"grapefrukt",
"jordbær",
"kiwi",
"mandarin",
"mango",
"passion fruit",
"pineapple",
"strawberry",
"watermelon",
"grape fruit",
"pære",
"pasjonsfrukt",
"vannmelon",
];
// EXAMPLES DO NOT INCLUDE CONTENT BELOW THIS LINE
@@ -8,23 +8,21 @@ const Example = () => {
options[1].value,
]);
return (
<div>
<UNSAFE_Combobox
label="Velg temakoder (opptil 3)"
options={options.map((o) => ({
label: `${o.label} [${o.value}]`,
value: o.value,
}))}
isMultiSelect
maxSelected={{ limit: 3 }}
selectedOptions={selectedOptions}
onToggleSelected={(option, isSelected) =>
isSelected
? setSelectedOptions([...selectedOptions, option])
: setSelectedOptions(selectedOptions.filter((o) => o !== option))
}
/>
</div>
<UNSAFE_Combobox
label="Velg opptil 3 temakoder"
options={options.map((o) => ({
label: `${o.label} [${o.value}]`,
value: o.value,
}))}
isMultiSelect
maxSelected={{ limit: 3 }}
selectedOptions={selectedOptions}
onToggleSelected={(option, isSelected) =>
isSelected
? setSelectedOptions([...selectedOptions, option])
: setSelectedOptions(selectedOptions.filter((o) => o !== option))
}
/>
);
};
@@ -3,29 +3,28 @@ import { withDsExample } from "@/web/examples/withDsExample";
const Example = () => {
return (
<div>
<UNSAFE_Combobox
label="Hva er din favorittfrukt?"
options={initialOptions}
error="Du må velge en favorittfrukt."
/>
</div>
<UNSAFE_Combobox
label="Hva er din favorittfrukt?"
options={options}
error="Du må velge en favorittfrukt."
/>
);
};
const initialOptions = [
"banana",
"apple",
"tangerine",
"pear",
"grape",
const options = [
"ananas",
"banan",
"bringebær",
"drue",
"eple",
"grapefrukt",
"jordbær",
"kiwi",
"mandarin",
"mango",
"passion fruit",
"pineapple",
"strawberry",
"watermelon",
"grape fruit",
"pære",
"pasjonsfrukt",
"vannmelon",
];
// EXAMPLES DO NOT INCLUDE CONTENT BELOW THIS LINE
@@ -38,5 +37,4 @@ export const Demo = {
export const args = {
index: 3,
desc: "Ved Single Select velger brukeren kun ett valg fra nedtrekkslisten.",
};
@@ -8,34 +8,32 @@ const Example = () => {
options[1],
]);
return (
<div>
<UNSAFE_Combobox
label="Hva er de kuleste transportmidlene? (velg opptil 3)"
options={options}
isMultiSelect
maxSelected={{ limit: 3 }}
selectedOptions={selectedOptions}
onToggleSelected={(option, isSelected) =>
isSelected
? setSelectedOptions([...selectedOptions, option])
: setSelectedOptions(selectedOptions.filter((o) => o !== option))
}
/>
</div>
<UNSAFE_Combobox
label="Hva er de kuleste transportmidlene? (Velg opptil 3)"
options={options}
isMultiSelect
maxSelected={{ limit: 3 }}
selectedOptions={selectedOptions}
onToggleSelected={(option, isSelected) =>
isSelected
? setSelectedOptions([...selectedOptions, option])
: setSelectedOptions(selectedOptions.filter((o) => o !== option))
}
/>
);
};
const options = [
"car",
"bus",
"train",
"bil",
"buss",
"tog",
"skateboard",
"bicycle",
"motorcycle",
"boat",
"airplane",
"helicopter",
"truck",
"sykkel",
"motorsykkel",
"båt",
"fly",
"helikopter",
"lastebil",
"van",
"scooter",
];
@@ -50,5 +48,5 @@ export const Demo = {
export const args = {
index: 7,
desc: "Ved å sette en grense for maks antall valgte vil brukeren få opp en beskjed om at hen ikke kan velge flere når grensen er nådd. Resterende valg vil også bli inaktive.",
desc: "Ved å sette en grense for maks antall valg vil brukeren få opp en beskjed om at hen ikke kan velge flere når grensen er nådd. Resterende alternativer blir inaktive.",
};
@@ -126,6 +126,7 @@ const accordionBlock = `_type == "accordion"=>{
...,
content[]{
...,
${markDef},
${defaultBlock}
}
}
+17 -17
View File
@@ -3711,7 +3711,7 @@ __metadata:
languageName: node
linkType: hard
"@navikt/aksel-icons@npm:^7.6.0, @navikt/aksel-icons@workspace:@navikt/aksel-icons":
"@navikt/aksel-icons@npm:^7.7.0, @navikt/aksel-icons@workspace:@navikt/aksel-icons":
version: 0.0.0-use.local
resolution: "@navikt/aksel-icons@workspace:@navikt/aksel-icons"
dependencies:
@@ -3742,8 +3742,8 @@ __metadata:
version: 0.0.0-use.local
resolution: "@navikt/aksel-stylelint@workspace:@navikt/aksel-stylelint"
dependencies:
"@navikt/ds-css": "npm:^7.6.0"
"@navikt/ds-tokens": "npm:^7.6.0"
"@navikt/ds-css": "npm:^7.7.0"
"@navikt/ds-tokens": "npm:^7.7.0"
concurrently: "npm:9.0.1"
postcss-selector-parser: "npm:^6.0.13"
postcss-value-parser: "npm:^4.2.0"
@@ -3758,7 +3758,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@navikt/aksel@workspace:@navikt/aksel"
dependencies:
"@navikt/ds-css": "npm:7.6.0"
"@navikt/ds-css": "npm:7.7.0"
axios: "npm:1.7.4"
chalk: "npm:4.1.0"
clipboardy: "npm:^2.3.0"
@@ -3779,11 +3779,11 @@ __metadata:
languageName: unknown
linkType: soft
"@navikt/ds-css@npm:*, @navikt/ds-css@npm:7.6.0, @navikt/ds-css@npm:^7.6.0, @navikt/ds-css@workspace:@navikt/core/css":
"@navikt/ds-css@npm:*, @navikt/ds-css@npm:7.7.0, @navikt/ds-css@npm:^7.7.0, @navikt/ds-css@workspace:@navikt/core/css":
version: 0.0.0-use.local
resolution: "@navikt/ds-css@workspace:@navikt/core/css"
dependencies:
"@navikt/ds-tokens": "npm:^7.6.0"
"@navikt/ds-tokens": "npm:^7.7.0"
autoprefixer: "npm:^10.4.20"
cssnano: "npm:6.0.0"
fast-glob: "npm:3.2.11"
@@ -3797,14 +3797,14 @@ __metadata:
languageName: unknown
linkType: soft
"@navikt/ds-react@npm:*, @navikt/ds-react@npm:^7.6.0, @navikt/ds-react@workspace:@navikt/core/react":
"@navikt/ds-react@npm:*, @navikt/ds-react@npm:^7.7.0, @navikt/ds-react@workspace:@navikt/core/react":
version: 0.0.0-use.local
resolution: "@navikt/ds-react@workspace:@navikt/core/react"
dependencies:
"@floating-ui/react": "npm:0.25.4"
"@floating-ui/react-dom": "npm:^2.0.9"
"@navikt/aksel-icons": "npm:^7.6.0"
"@navikt/ds-tokens": "npm:^7.6.0"
"@navikt/aksel-icons": "npm:^7.7.0"
"@navikt/ds-tokens": "npm:^7.7.0"
"@testing-library/dom": "npm:9.3.4"
"@testing-library/jest-dom": "npm:^5.16.0"
"@testing-library/react": "npm:^15.0.7"
@@ -3832,11 +3832,11 @@ __metadata:
languageName: unknown
linkType: soft
"@navikt/ds-tailwind@npm:^7.6.0, @navikt/ds-tailwind@workspace:@navikt/core/tailwind":
"@navikt/ds-tailwind@npm:^7.7.0, @navikt/ds-tailwind@workspace:@navikt/core/tailwind":
version: 0.0.0-use.local
resolution: "@navikt/ds-tailwind@workspace:@navikt/core/tailwind"
dependencies:
"@navikt/ds-tokens": "npm:^7.6.0"
"@navikt/ds-tokens": "npm:^7.7.0"
color: "npm:4.2.3"
lodash: "npm:^4.17.21"
tailwindcss: "npm:^3.3.3"
@@ -3846,7 +3846,7 @@ __metadata:
languageName: unknown
linkType: soft
"@navikt/ds-tokens@npm:^7.6.0, @navikt/ds-tokens@workspace:@navikt/core/tokens":
"@navikt/ds-tokens@npm:^7.7.0, @navikt/ds-tokens@workspace:@navikt/core/tokens":
version: 0.0.0-use.local
resolution: "@navikt/ds-tokens@workspace:@navikt/core/tokens"
dependencies:
@@ -7719,11 +7719,11 @@ __metadata:
version: 0.0.0-use.local
resolution: "aksel.nav.no@workspace:aksel.nav.no"
dependencies:
"@navikt/aksel-icons": "npm:^7.6.0"
"@navikt/ds-css": "npm:^7.6.0"
"@navikt/ds-react": "npm:^7.6.0"
"@navikt/ds-tailwind": "npm:^7.6.0"
"@navikt/ds-tokens": "npm:^7.6.0"
"@navikt/aksel-icons": "npm:^7.7.0"
"@navikt/ds-css": "npm:^7.7.0"
"@navikt/ds-react": "npm:^7.7.0"
"@navikt/ds-tailwind": "npm:^7.7.0"
"@navikt/ds-tokens": "npm:^7.7.0"
languageName: unknown
linkType: soft