diff --git a/.github/workflows/feature-branch-deploy.yml b/.github/workflows/feature-branch-deploy.yml index 3aa092916d..a20e568662 100644 --- a/.github/workflows/feature-branch-deploy.yml +++ b/.github/workflows/feature-branch-deploy.yml @@ -52,7 +52,7 @@ jobs: touch ./storybook/dist/${{ github.sha }}.txt - name: Pushing to pages branch - uses: JamesIves/github-pages-deploy-action@62fec3add6773ec5dbbf18d2ee4260911aa35cf4 # v4.6.9 + uses: JamesIves/github-pages-deploy-action@15de0f09300eea763baee31dff6c6184995c5f6a # v4.7.2 with: branch: gh-pages folder: storybook/dist diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 49a04fe8b4..748d109b0d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -66,7 +66,7 @@ jobs: if: ${{ steps.release.outputs.releases_created == 'true' }} - name: Deploy to GitHub Pages - uses: JamesIves/github-pages-deploy-action@62fec3add6773ec5dbbf18d2ee4260911aa35cf4 # v4.6.9 + uses: JamesIves/github-pages-deploy-action@15de0f09300eea763baee31dff6c6184995c5f6a # v4.7.2 with: branch: gh-pages folder: dist/storybook diff --git a/package.json b/package.json index 8520fb2c77..13843201d1 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "prettier": "3.4.2", "rimraf": "6.0.1", "stylelint": "16.11.0", - "stylelint-config-standard-scss": "13.1.0", + "stylelint-config-standard-scss": "14.0.0", "stylelint-order": "6.0.4", "stylelint-use-logical": "2.1.2", "typescript": "5.7.2", diff --git a/packages/css/src/components/accordion/accordion.scss b/packages/css/src/components/accordion/accordion.scss index 5355c17281..244d99b619 100644 --- a/packages/css/src/components/accordion/accordion.scss +++ b/packages/css/src/components/accordion/accordion.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; .ams-accordion { display: flex; diff --git a/packages/css/src/components/blockquote/blockquote.scss b/packages/css/src/components/blockquote/blockquote.scss index e1f39d94ef..911abf3fb8 100644 --- a/packages/css/src/components/blockquote/blockquote.scss +++ b/packages/css/src/components/blockquote/blockquote.scss @@ -3,8 +3,8 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/hyphenation"; -@import "../../common/text-rendering"; +@use "../../common/hyphenation" as *; +@use "../../common/text-rendering" as *; @mixin reset-blockquote { margin-block: 0; diff --git a/packages/css/src/components/breadcrumb/breadcrumb.scss b/packages/css/src/components/breadcrumb/breadcrumb.scss index 1fc4231726..9e18fc47b7 100644 --- a/packages/css/src/components/breadcrumb/breadcrumb.scss +++ b/packages/css/src/components/breadcrumb/breadcrumb.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; @mixin reset-ol { margin-block: 0; diff --git a/packages/css/src/components/breakout/breakout.scss b/packages/css/src/components/breakout/breakout.scss index fb27c4bccb..978666fbcc 100644 --- a/packages/css/src/components/breakout/breakout.scss +++ b/packages/css/src/components/breakout/breakout.scss @@ -3,9 +3,9 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/breakpoint"; -@import "../grid/grid"; -@import "../grid/mixins"; +@use "../../common/breakpoint" as *; +@use "../grid/grid" as *; +@use "../grid/mixins" as *; $ams-breakout-row-span-max: 4; diff --git a/packages/css/src/components/button/button.scss b/packages/css/src/components/button/button.scss index baf5276da5..1dbdce57e0 100644 --- a/packages/css/src/components/button/button.scss +++ b/packages/css/src/components/button/button.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; @mixin reset-button { border: 0; diff --git a/packages/css/src/components/character-count/character-count.scss b/packages/css/src/components/character-count/character-count.scss index e359156634..b838676a38 100644 --- a/packages/css/src/components/character-count/character-count.scss +++ b/packages/css/src/components/character-count/character-count.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; .ams-character-count { color: var(--ams-character-count-color); diff --git a/packages/css/src/components/checkbox/checkbox.scss b/packages/css/src/components/checkbox/checkbox.scss index e2c93e2863..71877569f8 100644 --- a/packages/css/src/components/checkbox/checkbox.scss +++ b/packages/css/src/components/checkbox/checkbox.scss @@ -3,9 +3,9 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/input-label-focus"; -@import "../../common/hide-input"; -@import "../../common/text-rendering"; +@use "../../common/input-label-focus" as *; +@use "../../common/hide-input" as *; +@use "../../common/text-rendering" as *; .ams-checkbox__input { @include hide-input; diff --git a/packages/css/src/components/column/column.scss b/packages/css/src/components/column/column.scss index 8094a40840..137c162c23 100644 --- a/packages/css/src/components/column/column.scss +++ b/packages/css/src/components/column/column.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/size"; +@use "../../common/size" as *; .ams-column { display: flex; diff --git a/packages/css/src/components/date-input/date-input.scss b/packages/css/src/components/date-input/date-input.scss index b7022e7722..e19f30be63 100644 --- a/packages/css/src/components/date-input/date-input.scss +++ b/packages/css/src/components/date-input/date-input.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; @mixin reset-input { -webkit-appearance: none; // Reset appearance for Safari < 15.4 diff --git a/packages/css/src/components/description-list/description-list.scss b/packages/css/src/components/description-list/description-list.scss index 7a5680868a..ce8a678d3d 100644 --- a/packages/css/src/components/description-list/description-list.scss +++ b/packages/css/src/components/description-list/description-list.scss @@ -3,13 +3,17 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/breakpoint"; -@import "../../common/text-rendering"; +@use "../../common/breakpoint" as *; +@use "../../common/text-rendering" as *; @mixin reset-dl { margin-block: 0; } +@mixin reset-dd { + margin-inline: 0; +} + .ams-description-list { box-sizing: border-box; color: var(--ams-description-list-color); @@ -25,19 +29,23 @@ } @media screen and (min-width: $ams-breakpoint-medium) { - .ams-description-list { + .ams-description-list, + .ams-description-list__section { grid-template-columns: auto 1fr; } - .ams-description-list--terms-width-sm { + .ams-description-list--terms-width-sm, + .ams-description-list--terms-width-sm .ams-description-list__section { grid-template-columns: 1fr 4fr; } - .ams-description-list--terms-width-md { + .ams-description-list--terms-width-md, + .ams-description-list--terms-width-md .ams-description-list__section { grid-template-columns: 1fr 2fr; } - .ams-description-list--terms-width-lg { + .ams-description-list--terms-width-lg, + .ams-description-list--terms-width-lg .ams-description-list__section { grid-template-columns: 1fr 1fr; } } @@ -54,8 +62,22 @@ } } -@mixin reset-dd { - margin-inline: 0; +.ams-description-list__section { + @media screen and (min-width: $ams-breakpoint-medium) { + column-gap: var(--ams-description-list-column-gap); + display: grid; + grid-column: span 2; + + > :only-of-type { + grid-row: 1 / 9; + } + } +} + +// Aligns terms and descriptions in a section to the grid of the list. +// The extra class selector increases specificity to match earlier declarations. +.ams-description-list .ams-description-list__section { + grid-template-columns: subgrid; } .ams-description-list__description { diff --git a/packages/css/src/components/error-message/error-message.scss b/packages/css/src/components/error-message/error-message.scss index bdc789802b..b688421cc9 100644 --- a/packages/css/src/components/error-message/error-message.scss +++ b/packages/css/src/components/error-message/error-message.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; @mixin reset-p { margin-block: 0; diff --git a/packages/css/src/components/field-set/field-set.scss b/packages/css/src/components/field-set/field-set.scss index 9ee7d329b9..2e4328e126 100644 --- a/packages/css/src/components/field-set/field-set.scss +++ b/packages/css/src/components/field-set/field-set.scss @@ -3,8 +3,8 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/hyphenation"; -@import "../../common/text-rendering"; +@use "../../common/hyphenation" as *; +@use "../../common/text-rendering" as *; @mixin reset-fieldset { border: 0; diff --git a/packages/css/src/components/file-input/file-input.scss b/packages/css/src/components/file-input/file-input.scss index 4b73941f5f..c90b269461 100644 --- a/packages/css/src/components/file-input/file-input.scss +++ b/packages/css/src/components/file-input/file-input.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; @mixin reset-button { border: 0; diff --git a/packages/css/src/components/file-list/README.md b/packages/css/src/components/file-list/README.md new file mode 100644 index 0000000000..76d64e4540 --- /dev/null +++ b/packages/css/src/components/file-list/README.md @@ -0,0 +1,5 @@ + + +# File List + +An overview of files, showing their name, type, size, and a preview. diff --git a/packages/css/src/components/file-list/file-list.scss b/packages/css/src/components/file-list/file-list.scss new file mode 100644 index 0000000000..af4045d11d --- /dev/null +++ b/packages/css/src/components/file-list/file-list.scss @@ -0,0 +1,55 @@ +/** + * @license EUPL-1.2+ + * Copyright Gemeente Amsterdam + */ + +@use "../../common/text-rendering" as *; + +@mixin reset-ul { + list-style: none; + margin-block: 0; + padding-inline: 0; +} + +.ams-file-list { + display: flex; + flex-direction: column; + gap: var(--ams-file-list-gap); + padding-block: var(--ams-file-list-padding-block); + + @include text-rendering; + @include reset-ul; +} + +.ams-file-list__item { + display: flex; + flex-direction: row; + font-family: var(--ams-file-list-file-font-family); + font-size: var(--ams-file-list-file-font-size); + font-weight: var(--ams-file-list-file-font-weight); + gap: var(--ams-file-list-file-gap); + line-height: var(--ams-file-list-file-line-height); +} + +.ams-file-list__item-preview { + display: grid; + flex: 0 0 var(--ams-file-list-file-preview-width); + place-items: center; + + img { + inline-size: 100%; + min-block-size: auto; + } +} + +.ams-file-list__item-info { + flex: 1; + gap: var(--ams-file-list-file-gap); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.ams-file-input__item-details { + color: var(--ams-file-list-file-details-color); +} diff --git a/packages/css/src/components/gap/gap.scss b/packages/css/src/components/gap/gap.scss index b5e2b5ee2a..6d5ad3aef6 100644 --- a/packages/css/src/components/gap/gap.scss +++ b/packages/css/src/components/gap/gap.scss @@ -3,13 +3,14 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/size"; +@use "sass:map"; +@use "../../common/size" as *; [class|="ams-gap-"] { display: grid !important; } -@each $size in map-keys($ams-sizes) { +@each $size in map.keys($ams-sizes) { @if $size != "no" { .ams-gap--#{$size} { grid-gap: var(--ams-gap-#{$size}) !important; diff --git a/packages/css/src/components/grid/_mixins.scss b/packages/css/src/components/grid/_mixins.scss index 7d1a55922f..d7797cdb74 100644 --- a/packages/css/src/components/grid/_mixins.scss +++ b/packages/css/src/components/grid/_mixins.scss @@ -1,3 +1,5 @@ +@use "../../common/breakpoint" as *; + /** * @license EUPL-1.2+ * Copyright Gemeente Amsterdam diff --git a/packages/css/src/components/grid/grid.scss b/packages/css/src/components/grid/grid.scss index 33185a2964..91107b2ed0 100644 --- a/packages/css/src/components/grid/grid.scss +++ b/packages/css/src/components/grid/grid.scss @@ -3,8 +3,8 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/breakpoint"; -@import "mixins"; +@use "../../common/breakpoint" as *; +@use "mixins" as *; $ams-grid-column-count: 12; diff --git a/packages/css/src/components/header/header.scss b/packages/css/src/components/header/header.scss index 1014dbb3a3..7c80af5d0a 100644 --- a/packages/css/src/components/header/header.scss +++ b/packages/css/src/components/header/header.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/breakpoint"; +@use "../../common/breakpoint" as *; .ams-header { align-items: center; diff --git a/packages/css/src/components/heading/heading.scss b/packages/css/src/components/heading/heading.scss index 3eb185c147..ee567e0465 100644 --- a/packages/css/src/components/heading/heading.scss +++ b/packages/css/src/components/heading/heading.scss @@ -3,8 +3,8 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/hyphenation"; -@import "../../common/text-rendering"; +@use "../../common/hyphenation" as *; +@use "../../common/text-rendering" as *; @mixin reset-hx { margin-block: 0; diff --git a/packages/css/src/components/image-slider/image-slider.scss b/packages/css/src/components/image-slider/image-slider.scss index 36a87b3aa7..ccb18d05c7 100644 --- a/packages/css/src/components/image-slider/image-slider.scss +++ b/packages/css/src/components/image-slider/image-slider.scss @@ -2,7 +2,7 @@ * @license EUPL-1.2+ * Copyright Gemeente Amsterdam */ -@import "../../common/breakpoint"; +@use "../../common/breakpoint" as *; .ams-image-slider { display: grid; diff --git a/packages/css/src/components/index.scss b/packages/css/src/components/index.scss index 995f0179fe..f8417eaa30 100644 --- a/packages/css/src/components/index.scss +++ b/packages/css/src/components/index.scss @@ -4,66 +4,67 @@ */ /* Append here */ -@import "./action-group/action-group"; -@import "./breakout/breakout"; -@import "./hint/hint"; -@import "./password-input/password-input"; -@import "./form-error-list/form-error-list"; -@import "./image-slider/image-slider"; -@import "./table-of-contents/table-of-contents"; -@import "./error-message/error-message"; -@import "./file-input/file-input"; -@import "./field/field"; -@import "./select/select"; -@import "./time-input/time-input"; -@import "./date-input/date-input"; -@import "./document/document"; -@import "./avatar/avatar"; -@import "./character-count/character-count"; -@import "./description-list/description-list"; -@import "./row/row"; -@import "./radio/radio"; -@import "./tabs/tabs"; -@import "./text-area/text-area"; -@import "./column/column"; -@import "./margin/margin"; -@import "./gap/gap"; -@import "./field-set/field-set"; -@import "./link-list/link-list"; -@import "./badge/badge"; -@import "./table/table"; -@import "./mega-menu/mega-menu"; -@import "./icon-button/icon-button"; -@import "./skip-link/skip-link"; -@import "./overlap/overlap"; -@import "./header/header"; -@import "./mark/mark"; -@import "./text-input/text-input"; -@import "./search-field/search-field"; -@import "./logo/logo"; -@import "./dialog/dialog"; -@import "./image/image"; -@import "./pagination/pagination"; -@import "./accordion/accordion"; -@import "./alert/alert"; -@import "./aspect-ratio/aspect-ratio"; -@import "./blockquote/blockquote"; -@import "./breadcrumb/breadcrumb"; -@import "./button/button"; -@import "./card/card"; -@import "./checkbox/checkbox"; -@import "./label/label"; -@import "./grid/grid"; -@import "./heading/heading"; -@import "./spotlight/spotlight"; -@import "./icon/icon"; -@import "./link/link"; -@import "./ordered-list/ordered-list"; -@import "./page-heading/page-heading"; -@import "./page-menu/page-menu"; -@import "./paragraph/paragraph"; -@import "./screen/screen"; -@import "./switch/switch"; -@import "./top-task-link/top-task-link"; -@import "./unordered-list/unordered-list"; -@import "./visually-hidden/visually-hidden"; +@use "file-list/file-list"; +@use "action-group/action-group"; +@use "breakout/breakout"; +@use "hint/hint"; +@use "password-input/password-input"; +@use "form-error-list/form-error-list"; +@use "image-slider/image-slider"; +@use "table-of-contents/table-of-contents"; +@use "error-message/error-message"; +@use "file-input/file-input"; +@use "field/field"; +@use "select/select"; +@use "time-input/time-input"; +@use "date-input/date-input"; +@use "document/document"; +@use "avatar/avatar"; +@use "character-count/character-count"; +@use "description-list/description-list"; +@use "row/row"; +@use "radio/radio"; +@use "tabs/tabs"; +@use "text-area/text-area"; +@use "column/column"; +@use "margin/margin"; +@use "gap/gap"; +@use "field-set/field-set"; +@use "link-list/link-list"; +@use "badge/badge"; +@use "table/table"; +@use "mega-menu/mega-menu"; +@use "icon-button/icon-button"; +@use "skip-link/skip-link"; +@use "overlap/overlap"; +@use "header/header"; +@use "mark/mark"; +@use "text-input/text-input"; +@use "search-field/search-field"; +@use "logo/logo"; +@use "dialog/dialog"; +@use "image/image"; +@use "pagination/pagination"; +@use "accordion/accordion"; +@use "alert/alert"; +@use "aspect-ratio/aspect-ratio"; +@use "blockquote/blockquote"; +@use "breadcrumb/breadcrumb"; +@use "button/button"; +@use "card/card"; +@use "checkbox/checkbox"; +@use "label/label"; +@use "grid/grid"; +@use "heading/heading"; +@use "spotlight/spotlight"; +@use "icon/icon"; +@use "link/link"; +@use "ordered-list/ordered-list"; +@use "page-heading/page-heading"; +@use "page-menu/page-menu"; +@use "paragraph/paragraph"; +@use "screen/screen"; +@use "switch/switch"; +@use "top-task-link/top-task-link"; +@use "unordered-list/unordered-list"; +@use "visually-hidden/visually-hidden"; diff --git a/packages/css/src/components/label/label.scss b/packages/css/src/components/label/label.scss index 53ab1f55a4..f69e82209e 100644 --- a/packages/css/src/components/label/label.scss +++ b/packages/css/src/components/label/label.scss @@ -3,8 +3,8 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/hyphenation"; -@import "../../common/text-rendering"; +@use "../../common/hyphenation" as *; +@use "../../common/text-rendering" as *; .ams-label { color: var(--ams-label-color); diff --git a/packages/css/src/components/link-list/link-list.scss b/packages/css/src/components/link-list/link-list.scss index 450968b00b..bbe89d58e0 100644 --- a/packages/css/src/components/link-list/link-list.scss +++ b/packages/css/src/components/link-list/link-list.scss @@ -3,8 +3,8 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/hyphenation"; -@import "../../common/text-rendering"; +@use "../../common/hyphenation" as *; +@use "../../common/text-rendering" as *; @mixin reset-ul { list-style: none; diff --git a/packages/css/src/components/link/link.scss b/packages/css/src/components/link/link.scss index 8ce355a48c..cdeded0c22 100644 --- a/packages/css/src/components/link/link.scss +++ b/packages/css/src/components/link/link.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; .ams-link { color: var(--ams-link-color); diff --git a/packages/css/src/components/margin/margin.scss b/packages/css/src/components/margin/margin.scss index 45b9953919..6fee9d553b 100644 --- a/packages/css/src/components/margin/margin.scss +++ b/packages/css/src/components/margin/margin.scss @@ -3,9 +3,10 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/size"; +@use "sass:map"; +@use "../../common/size" as *; -@each $size in map-keys($ams-sizes) { +@each $size in map.keys($ams-sizes) { @if $size != "no" { .ams-mb--#{$size} { margin-block-end: var(--ams-margin-#{$size}) !important; diff --git a/packages/css/src/components/ordered-list/ordered-list.scss b/packages/css/src/components/ordered-list/ordered-list.scss index 3ac1f633f0..c104507de0 100644 --- a/packages/css/src/components/ordered-list/ordered-list.scss +++ b/packages/css/src/components/ordered-list/ordered-list.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; @mixin reset-ol { list-style-type: none; diff --git a/packages/css/src/components/page-heading/page-heading.scss b/packages/css/src/components/page-heading/page-heading.scss index a982fcee05..a51aa9e2ab 100644 --- a/packages/css/src/components/page-heading/page-heading.scss +++ b/packages/css/src/components/page-heading/page-heading.scss @@ -3,8 +3,8 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/hyphenation"; -@import "../../common/text-rendering"; +@use "../../common/hyphenation" as *; +@use "../../common/text-rendering" as *; @mixin reset-h1 { margin-block: 0; diff --git a/packages/css/src/components/page-menu/page-menu.scss b/packages/css/src/components/page-menu/page-menu.scss index 3ca0ac7b17..57e3466894 100644 --- a/packages/css/src/components/page-menu/page-menu.scss +++ b/packages/css/src/components/page-menu/page-menu.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; @mixin reset-ul { margin-block: 0; diff --git a/packages/css/src/components/pagination/pagination.scss b/packages/css/src/components/pagination/pagination.scss index ab63116416..4ac40cd44b 100644 --- a/packages/css/src/components/pagination/pagination.scss +++ b/packages/css/src/components/pagination/pagination.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; @mixin reset-ol { list-style-type: none; diff --git a/packages/css/src/components/paragraph/paragraph.scss b/packages/css/src/components/paragraph/paragraph.scss index 8b9108021a..a6abf28e70 100644 --- a/packages/css/src/components/paragraph/paragraph.scss +++ b/packages/css/src/components/paragraph/paragraph.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; @mixin reset-p { margin-block: 0; diff --git a/packages/css/src/components/password-input/password-input.scss b/packages/css/src/components/password-input/password-input.scss index 902b82f255..27102085e4 100644 --- a/packages/css/src/components/password-input/password-input.scss +++ b/packages/css/src/components/password-input/password-input.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; @mixin reset-input { -webkit-appearance: none; // Reset appearance for Safari < 15.4 diff --git a/packages/css/src/components/radio/radio.scss b/packages/css/src/components/radio/radio.scss index a9ba889b1f..9a60153556 100644 --- a/packages/css/src/components/radio/radio.scss +++ b/packages/css/src/components/radio/radio.scss @@ -3,9 +3,9 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/input-label-focus"; -@import "../../common/hide-input"; -@import "../../common/text-rendering"; +@use "../../common/input-label-focus" as *; +@use "../../common/hide-input" as *; +@use "../../common/text-rendering" as *; .ams-radio__input { @include hide-input; diff --git a/packages/css/src/components/row/row.scss b/packages/css/src/components/row/row.scss index 943401dc44..ac8ef1ea09 100644 --- a/packages/css/src/components/row/row.scss +++ b/packages/css/src/components/row/row.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/size"; +@use "../../common/size" as *; .ams-row { display: flex; diff --git a/packages/css/src/components/search-field/search-field.scss b/packages/css/src/components/search-field/search-field.scss index 56c378fd90..43ea03ca62 100644 --- a/packages/css/src/components/search-field/search-field.scss +++ b/packages/css/src/components/search-field/search-field.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; .ams-search-field { display: flex; diff --git a/packages/css/src/components/switch/switch.scss b/packages/css/src/components/switch/switch.scss index 827b1efdfb..65d82d3c44 100644 --- a/packages/css/src/components/switch/switch.scss +++ b/packages/css/src/components/switch/switch.scss @@ -3,8 +3,8 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/input-label-focus"; -@import "../../common/hide-input"; +@use "../../common/input-label-focus" as *; +@use "../../common/hide-input" as *; .ams-switch__input { @include hide-input; diff --git a/packages/css/src/components/table-of-contents/table-of-contents.scss b/packages/css/src/components/table-of-contents/table-of-contents.scss index b312071d3c..5c0740f54f 100644 --- a/packages/css/src/components/table-of-contents/table-of-contents.scss +++ b/packages/css/src/components/table-of-contents/table-of-contents.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; @mixin reset-ul { margin-block: 0; diff --git a/packages/css/src/components/tabs/tabs.scss b/packages/css/src/components/tabs/tabs.scss index 3c4b8f10b2..278921c595 100644 --- a/packages/css/src/components/tabs/tabs.scss +++ b/packages/css/src/components/tabs/tabs.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/breakpoint"; +@use "../../common/breakpoint" as *; @mixin reset-button { background-color: transparent; diff --git a/packages/css/src/components/text-area/text-area.scss b/packages/css/src/components/text-area/text-area.scss index 0587b12d12..ba165dcfc0 100644 --- a/packages/css/src/components/text-area/text-area.scss +++ b/packages/css/src/components/text-area/text-area.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; @mixin reset-textarea { -webkit-appearance: none; // Reset appearance for Safari < 15.4 diff --git a/packages/css/src/components/text-input/text-input.scss b/packages/css/src/components/text-input/text-input.scss index 0ee5b3ee81..934407a5f3 100644 --- a/packages/css/src/components/text-input/text-input.scss +++ b/packages/css/src/components/text-input/text-input.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; @mixin reset-input { -webkit-appearance: none; // Reset appearance for Safari < 15.4 diff --git a/packages/css/src/components/time-input/time-input.scss b/packages/css/src/components/time-input/time-input.scss index 10c41af4d2..2469c079e5 100644 --- a/packages/css/src/components/time-input/time-input.scss +++ b/packages/css/src/components/time-input/time-input.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; @mixin reset-input { -webkit-appearance: none; // Reset appearance for Safari < 15.4 diff --git a/packages/css/src/components/top-task-link/top-task-link.scss b/packages/css/src/components/top-task-link/top-task-link.scss index b1418d6215..5be5f0c304 100644 --- a/packages/css/src/components/top-task-link/top-task-link.scss +++ b/packages/css/src/components/top-task-link/top-task-link.scss @@ -3,8 +3,8 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/hyphenation"; -@import "../../common/text-rendering"; +@use "../../common/hyphenation" as *; +@use "../../common/text-rendering" as *; .ams-top-task-link { break-inside: avoid; diff --git a/packages/css/src/components/unordered-list/unordered-list.scss b/packages/css/src/components/unordered-list/unordered-list.scss index d602dda30f..7c29691216 100644 --- a/packages/css/src/components/unordered-list/unordered-list.scss +++ b/packages/css/src/components/unordered-list/unordered-list.scss @@ -3,7 +3,7 @@ * Copyright Gemeente Amsterdam */ -@import "../../common/text-rendering"; +@use "../../common/text-rendering" as *; @mixin reset-ul { list-style: none; diff --git a/packages/react/src/DescriptionList/DescriptionList.tsx b/packages/react/src/DescriptionList/DescriptionList.tsx index 7f63876075..ef7069c7b5 100644 --- a/packages/react/src/DescriptionList/DescriptionList.tsx +++ b/packages/react/src/DescriptionList/DescriptionList.tsx @@ -7,6 +7,7 @@ import clsx from 'clsx' import { forwardRef } from 'react' import type { ForwardedRef, HTMLAttributes, PropsWithChildren } from 'react' import { DescriptionListDescription } from './DescriptionListDescription' +import { DescriptionListSection } from './DescriptionListSection' import { DescriptionListTerm } from './DescriptionListTerm' export const descriptionListTermsWidths = ['sm', 'md', 'lg'] as const @@ -42,6 +43,7 @@ const DescriptionListRoot = forwardRef( DescriptionListRoot.displayName = 'DescriptionList' export const DescriptionList = Object.assign(DescriptionListRoot, { - Term: DescriptionListTerm, Description: DescriptionListDescription, + Section: DescriptionListSection, + Term: DescriptionListTerm, }) diff --git a/packages/react/src/DescriptionList/DescriptionListSection.test.tsx b/packages/react/src/DescriptionList/DescriptionListSection.test.tsx new file mode 100644 index 0000000000..bd12f1c927 --- /dev/null +++ b/packages/react/src/DescriptionList/DescriptionListSection.test.tsx @@ -0,0 +1,41 @@ +import { render } from '@testing-library/react' +import { createRef } from 'react' +import { DescriptionList } from './DescriptionList' +import '@testing-library/jest-dom' + +describe('Description List Section', () => { + it('renders', () => { + const { container } = render(Test) + + const component = container.querySelector(':only-child') + + expect(component).toBeInTheDocument() + expect(component).toBeVisible() + }) + + it('renders a design system BEM class name', () => { + const { container } = render(Test) + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass('ams-description-list__section') + }) + + it('renders an additional class name', () => { + const { container } = render(Test) + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass('ams-description-list__section extra') + }) + + it('supports ForwardRef in React', () => { + const ref = createRef() + + const { container } = render(Test) + + const component = container.querySelector(':only-child') + + expect(ref.current).toBe(component) + }) +}) diff --git a/packages/react/src/DescriptionList/DescriptionListSection.tsx b/packages/react/src/DescriptionList/DescriptionListSection.tsx new file mode 100644 index 0000000000..81b2771ded --- /dev/null +++ b/packages/react/src/DescriptionList/DescriptionListSection.tsx @@ -0,0 +1,20 @@ +/** + * @license EUPL-1.2+ + * Copyright Gemeente Amsterdam + */ + +import clsx from 'clsx' +import { forwardRef } from 'react' +import type { ForwardedRef, HTMLAttributes, PropsWithChildren } from 'react' + +export type DescriptionListSectionProps = PropsWithChildren> + +export const DescriptionListSection = forwardRef( + ({ children, className, ...restProps }: DescriptionListSectionProps, ref: ForwardedRef) => ( +
+ {children} +
+ ), +) + +DescriptionListSection.displayName = 'DescriptionList.Section' diff --git a/packages/react/src/FileList/FileList.test.tsx b/packages/react/src/FileList/FileList.test.tsx new file mode 100644 index 0000000000..d280a4c907 --- /dev/null +++ b/packages/react/src/FileList/FileList.test.tsx @@ -0,0 +1,41 @@ +import { render, screen } from '@testing-library/react' +import { createRef } from 'react' +import { FileList } from './FileList' +import '@testing-library/jest-dom' + +describe('FileList', () => { + it('renders', () => { + render() + + const component = screen.getByRole('list') + + expect(component).toBeInTheDocument() + expect(component).toBeVisible() + }) + + it('renders a design system BEM class name', () => { + render() + + const component = screen.getByRole('list') + + expect(component).toHaveClass('ams-file-list') + }) + + it('renders an additional class name', () => { + render() + + const component = screen.getByRole('list') + + expect(component).toHaveClass('ams-file-list extra') + }) + + it('supports ForwardRef in React', () => { + const ref = createRef() + + render() + + const component = screen.getByRole('list') + + expect(ref.current).toBe(component) + }) +}) diff --git a/packages/react/src/FileList/FileList.tsx b/packages/react/src/FileList/FileList.tsx new file mode 100644 index 0000000000..26ded755e5 --- /dev/null +++ b/packages/react/src/FileList/FileList.tsx @@ -0,0 +1,25 @@ +/** + * @license EUPL-1.2+ + * Copyright Gemeente Amsterdam + */ + +import clsx from 'clsx' +import { forwardRef } from 'react' +import type { ForwardedRef, HTMLAttributes, PropsWithChildren } from 'react' +import { FileListItem } from './FileListItem' + +export type FileListProps = {} & PropsWithChildren> + +export const FileListRoot = forwardRef( + ({ children, className, ...restProps }: FileListProps, ref: ForwardedRef) => ( +
    + {children} +
+ ), +) + +FileListRoot.displayName = 'FileList' + +export const FileList = Object.assign(FileListRoot, { + Item: FileListItem, +}) diff --git a/packages/react/src/FileList/FileListItem.test.tsx b/packages/react/src/FileList/FileListItem.test.tsx new file mode 100644 index 0000000000..ec2e567ba2 --- /dev/null +++ b/packages/react/src/FileList/FileListItem.test.tsx @@ -0,0 +1,57 @@ +import { fireEvent, render, screen } from '@testing-library/react' +import { createRef } from 'react' +import '@testing-library/jest-dom' +import { FileListItem } from './FileListItem' + +describe('FileListItem', () => { + const file = new File(['sample content'], 'sample.txt', { type: 'text/plain' }) + it('renders', () => { + render() + + const component = screen.getByRole('listitem') + + expect(component).toBeInTheDocument() + expect(component).toBeVisible() + }) + + it('renders a design system BEM class name', () => { + render() + + const component = screen.getByRole('listitem') + + expect(component).toHaveClass('ams-file-list__item') + }) + + it('renders an additional class name', () => { + render() + + const component = screen.getByRole('listitem') + + expect(component).toHaveClass('ams-file-list__item extra') + }) + + it('supports ForwardRef in React', () => { + const ref = createRef() + + render() + + const component = screen.getByRole('listitem') + + expect(ref.current).toBe(component) + }) + + it('renders the file name', () => { + render() + + expect(screen.getByText('sample.txt')).toBeInTheDocument() + }) + + it('calls onDelete when the remove button is clicked', () => { + const onDelete = jest.fn() + render() + + fireEvent.click(screen.getByRole('button')) + + expect(onDelete).toHaveBeenCalledTimes(1) + }) +}) diff --git a/packages/react/src/FileList/FileListItem.tsx b/packages/react/src/FileList/FileListItem.tsx new file mode 100644 index 0000000000..1ae2f5efcb --- /dev/null +++ b/packages/react/src/FileList/FileListItem.tsx @@ -0,0 +1,47 @@ +/** + * @license EUPL-1.2+ + * Copyright Gemeente Amsterdam + */ + +import { DocumentIcon } from '@amsterdam/design-system-react-icons' +import clsx from 'clsx' +import { forwardRef } from 'react' +import type { ForwardedRef, HTMLAttributes } from 'react' +import { Button } from '../Button' +import { Icon } from '../Icon' +import { formatFileSize } from '../common/formatFileSize' +import { formatFileType } from '../common/formatFileType' + +export type FileListItemProps = { + file: File + onDelete?: () => void +} & HTMLAttributes + +export const FileListItem = forwardRef( + ({ file, onDelete, className, ...restProps }: FileListItemProps, ref: ForwardedRef) => ( +
  • +
    + {file.type.startsWith('image/') ? ( + {file.name} + ) : ( + + )} +
    +
    + {file.name} +
    + ({formatFileType(file.type)}, {formatFileSize(file.size)}) +
    +
    + {onDelete && ( +
    + +
    + )} +
  • + ), +) + +FileListItem.displayName = 'FileList.Item' diff --git a/packages/react/src/FileList/README.md b/packages/react/src/FileList/README.md new file mode 100644 index 0000000000..e149ac3384 --- /dev/null +++ b/packages/react/src/FileList/README.md @@ -0,0 +1,5 @@ + + +# React File List component + +[File List documentation](../../../css/src/components/file-list/README.md) diff --git a/packages/react/src/FileList/index.ts b/packages/react/src/FileList/index.ts new file mode 100644 index 0000000000..8083f1fe0f --- /dev/null +++ b/packages/react/src/FileList/index.ts @@ -0,0 +1,2 @@ +export { FileList } from './FileList' +export type { FileListProps } from './FileList' diff --git a/packages/react/src/Tabs/Tabs.tsx b/packages/react/src/Tabs/Tabs.tsx index 476c145231..2322cb3443 100644 --- a/packages/react/src/Tabs/Tabs.tsx +++ b/packages/react/src/Tabs/Tabs.tsx @@ -5,7 +5,7 @@ import clsx from 'clsx' import { forwardRef, useEffect, useId, useImperativeHandle, useMemo, useRef, useState } from 'react' -import type { ForwardedRef, HTMLAttributes, PropsWithChildren, ReactNode } from 'react' +import type { ForwardedRef, HTMLAttributes, PropsWithChildren } from 'react' import { TabsButton } from './TabsButton' import { TabsContext } from './TabsContext' import { TabsList } from './TabsList' @@ -25,7 +25,7 @@ const TabsRoot = forwardRef( const allTabs = useMemo(() => { if (!Array.isArray(children)) return [] - return (children[0].props.children as ReactNode[]).map((child) => child) + return children[0].props.children }, [children]) useEffect(() => { diff --git a/packages/react/src/common/formatFileSize.test.tsx b/packages/react/src/common/formatFileSize.test.tsx new file mode 100644 index 0000000000..f2bcdab8b5 --- /dev/null +++ b/packages/react/src/common/formatFileSize.test.tsx @@ -0,0 +1,22 @@ +import { formatFileSize } from './formatFileSize' + +describe('formatFileSize', () => { + it('formats bytes correctly', () => { + expect(formatFileSize(500)).toBe('500 bytes') + }) + + it('formats kilobytes correctly', () => { + expect(formatFileSize(1024, 1)).toBe('1 kB') + expect(formatFileSize(2048, 1)).toBe('2 kB') + }) + + it('formats megabytes correctly', () => { + expect(formatFileSize(1048576, 1)).toBe('1 MB') + expect(formatFileSize(2097152, 1)).toBe('2 MB') + }) + + it('formats gigabytes correctly', () => { + expect(formatFileSize(1073741824, 1)).toBe('1 GB') + expect(formatFileSize(2147483648, 1)).toBe('2 GB') + }) +}) diff --git a/packages/react/src/common/formatFileSize.tsx b/packages/react/src/common/formatFileSize.tsx new file mode 100644 index 0000000000..a17666e3e6 --- /dev/null +++ b/packages/react/src/common/formatFileSize.tsx @@ -0,0 +1,20 @@ +/** + * @license EUPL-1.2+ + * Copyright Gemeente Amsterdam + */ + +/** + * @param fileSize The size of the file in bytes. + * @param precision The number of significant digits in the output. + * @returns A human readable file size + */ +export const formatFileSize = (fileSize: number, precision = 3) => { + const UNITS = ['bytes', 'kB', 'MB', 'GB'] + + if (fileSize === 0) return '0 bytes' + + const exponent = Math.floor(Math.log10(fileSize) / 3) + const size = (fileSize / Math.pow(1000, exponent)).toPrecision(precision) + + return `${size} ${UNITS[exponent]}` +} diff --git a/packages/react/src/common/formatFileType.test.tsx b/packages/react/src/common/formatFileType.test.tsx new file mode 100644 index 0000000000..3846c8f801 --- /dev/null +++ b/packages/react/src/common/formatFileType.test.tsx @@ -0,0 +1,29 @@ +import { formatFileType } from './formatFileType' + +describe('formatFileType', () => { + it('formats image types correctly', () => { + expect(formatFileType('image/gif')).toBe('gif') + expect(formatFileType('image/jpeg')).toBe('jpg') + expect(formatFileType('image/png')).toBe('png') + }) + + it('formats text types correctly', () => { + expect(formatFileType('text/plain')).toBe('txt') + }) + + it('formats application types correctly', () => { + expect(formatFileType('application/pdf')).toBe('pdf') + expect(formatFileType('application/msword')).toBe('Word') + expect(formatFileType('application/vnd.openxmlformats-officedocument.wordprocessingml.document')).toBe('Word') + expect(formatFileType('application/vnd.ms-excel')).toBe('Excel') + expect(formatFileType('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')).toBe('Excel') + expect(formatFileType('application/vnd.ms-powerpoint')).toBe('PowerPoint') + expect(formatFileType('application/vnd.openxmlformats-officedocument.presentationml.presentation')).toBe( + 'PowerPoint', + ) + }) + + it('returns the original file type for unknown types', () => { + expect(formatFileType('unknown/type')).toBe('Document') + }) +}) diff --git a/packages/react/src/common/formatFileType.tsx b/packages/react/src/common/formatFileType.tsx new file mode 100644 index 0000000000..17e47d5530 --- /dev/null +++ b/packages/react/src/common/formatFileType.tsx @@ -0,0 +1,35 @@ +/** + * @license EUPL-1.2+ + * Copyright Gemeente Amsterdam + */ + +/** + * + * @param fileType + * @returns Human readable file type + */ +export const formatFileType = (fileType: string) => { + switch (fileType) { + case 'image/gif': + return 'gif' + case 'image/jpeg': + return 'jpg' + case 'image/png': + return 'png' + case 'text/plain': + return 'txt' + case 'application/pdf': + return 'pdf' + case 'application/msword': + case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': + return 'Word' + case 'application/vnd.ms-excel': + case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': + return 'Excel' + case 'application/vnd.ms-powerpoint': + case 'application/vnd.openxmlformats-officedocument.presentationml.presentation': + return 'PowerPoint' + default: + return 'Document' + } +} diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 9b88224382..5bb39cae01 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -4,6 +4,7 @@ */ /* Append here */ +export * from './FileList' export * from './ActionGroup' export * from './Breakout' export * from './Hint' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 22bd90ab78..953ccaec20 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -92,8 +92,8 @@ importers: specifier: 16.11.0 version: 16.11.0(typescript@5.7.2) stylelint-config-standard-scss: - specifier: 13.1.0 - version: 13.1.0(postcss@8.4.49)(stylelint@16.11.0(typescript@5.7.2)) + specifier: 14.0.0 + version: 14.0.0(postcss@8.4.49)(stylelint@16.11.0(typescript@5.7.2)) stylelint-order: specifier: 6.0.4 version: 6.0.4(stylelint@16.11.0(typescript@5.7.2)) @@ -352,7 +352,7 @@ importers: version: 8.4.7(@storybook/test@8.4.7(storybook@8.4.7(prettier@3.4.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7(prettier@3.4.2))(typescript@5.7.2) '@storybook/react-vite': specifier: 8.4.7 - version: 8.4.7(@storybook/test@8.4.7(storybook@8.4.7(prettier@3.4.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.28.1)(storybook@8.4.7(prettier@3.4.2))(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)) + version: 8.4.7(@storybook/test@8.4.7(storybook@8.4.7(prettier@3.4.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.28.1)(storybook@8.4.7(prettier@3.4.2))(typescript@5.7.2)(vite@6.0.3(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)(yaml@2.5.0)) '@storybook/theming': specifier: 8.4.7 version: 8.4.7(storybook@8.4.7(prettier@3.4.2)) @@ -361,7 +361,7 @@ importers: version: 18.3.12 '@vitejs/plugin-react': specifier: 4.3.4 - version: 4.3.4(vite@5.4.11(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)) + version: 4.3.4(vite@6.0.3(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)(yaml@2.5.0)) '@whitespace/storybook-addon-html': specifier: 6.1.1 version: 6.1.1(prettier@3.4.2)(react-syntax-highlighter@15.5.0(react@18.3.1)) @@ -381,8 +381,8 @@ importers: specifier: 8.4.7 version: 8.4.7(prettier@3.4.2) vite: - specifier: 5.4.11 - version: 5.4.11(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1) + specifier: 6.0.3 + version: 6.0.3(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)(yaml@2.5.0) packages: @@ -1122,141 +1122,147 @@ packages: '@emnapi/runtime@1.3.1': resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} - '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} + '@esbuild/aix-ppc64@0.24.0': + resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} + engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} + '@esbuild/android-arm64@0.24.0': + resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} + engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} + '@esbuild/android-arm@0.24.0': + resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} + engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} + '@esbuild/android-x64@0.24.0': + resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} + engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} + '@esbuild/darwin-arm64@0.24.0': + resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} + engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} + '@esbuild/darwin-x64@0.24.0': + resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} + engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} + '@esbuild/freebsd-arm64@0.24.0': + resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} + engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} + '@esbuild/freebsd-x64@0.24.0': + resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} + engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} + '@esbuild/linux-arm64@0.24.0': + resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} + engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} + '@esbuild/linux-arm@0.24.0': + resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} + engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} + '@esbuild/linux-ia32@0.24.0': + resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} + engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} + '@esbuild/linux-loong64@0.24.0': + resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} + engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} + '@esbuild/linux-mips64el@0.24.0': + resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} + engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} + '@esbuild/linux-ppc64@0.24.0': + resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} + engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} + '@esbuild/linux-riscv64@0.24.0': + resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} + engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} + '@esbuild/linux-s390x@0.24.0': + resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} + engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} + '@esbuild/linux-x64@0.24.0': + resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} + engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} + '@esbuild/netbsd-x64@0.24.0': + resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} + engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} + '@esbuild/openbsd-arm64@0.24.0': + resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.24.0': + resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} + engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} + '@esbuild/sunos-x64@0.24.0': + resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} + engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} + '@esbuild/win32-arm64@0.24.0': + resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} + engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} + '@esbuild/win32-ia32@0.24.0': + resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} + engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} + '@esbuild/win32-x64@0.24.0': + resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} + engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -3531,9 +3537,9 @@ packages: peerDependencies: esbuild: '>=0.12 <1' - esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} + esbuild@0.24.0: + resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} + engines: {node: '>=18'} hasBin: true escalade@3.1.2: @@ -4855,9 +4861,6 @@ packages: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} - known-css-properties@0.29.0: - resolution: {integrity: sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==} - known-css-properties@0.35.0: resolution: {integrity: sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==} @@ -5110,6 +5113,9 @@ packages: mdn-data@2.12.1: resolution: {integrity: sha512-rsfnCbOHjqrhWxwt5/wtSLzpoKTzW7OXdT5lLOIH1OTYhWu9rRJveGq0sKvDZODABH7RX+uoR+DYcpFnq4Tf6Q==} + mdn-data@2.13.0: + resolution: {integrity: sha512-OmD1FDyP706JqPqtLqgev/QCK0qudBdUuKKag6InQ/elEw3Cm2AhXYktcSggdc/vWniYqIsofkcteMEOioW5vQ==} + mdurl@2.0.0: resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} @@ -5850,10 +5856,6 @@ packages: peerDependencies: postcss: ^8.4.29 - postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} - engines: {node: '>=4'} - postcss-selector-parser@7.0.0: resolution: {integrity: sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==} engines: {node: '>=4'} @@ -6605,34 +6607,34 @@ packages: babel-plugin-macros: optional: true - stylelint-config-recommended-scss@14.0.0: - resolution: {integrity: sha512-HDvpoOAQ1RpF+sPbDOT2Q2/YrBDEJDnUymmVmZ7mMCeNiFSdhRdyGEimBkz06wsN+HaFwUh249gDR+I9JR7Onw==} + stylelint-config-recommended-scss@14.1.0: + resolution: {integrity: sha512-bhaMhh1u5dQqSsf6ri2GVWWQW5iUjBYgcHkh7SgDDn92ijoItC/cfO/W+fpXshgTQWhwFkP1rVcewcv4jaftRg==} engines: {node: '>=18.12.0'} peerDependencies: postcss: ^8.3.3 - stylelint: ^16.0.2 + stylelint: ^16.6.1 peerDependenciesMeta: postcss: optional: true - stylelint-config-recommended@14.0.0: - resolution: {integrity: sha512-jSkx290CglS8StmrLp2TxAppIajzIBZKYm3IxT89Kg6fGlxbPiTiyH9PS5YUuVAFwaJLl1ikiXX0QWjI0jmgZQ==} + stylelint-config-recommended@14.0.1: + resolution: {integrity: sha512-bLvc1WOz/14aPImu/cufKAZYfXs/A/owZfSMZ4N+16WGXLoX5lOir53M6odBxvhgmgdxCVnNySJmZKx73T93cg==} engines: {node: '>=18.12.0'} peerDependencies: - stylelint: ^16.0.0 + stylelint: ^16.1.0 - stylelint-config-standard-scss@13.1.0: - resolution: {integrity: sha512-Eo5w7/XvwGHWkeGLtdm2FZLOMYoZl1omP2/jgFCXyl2x5yNz7/8vv4Tj6slHvMSSUNTaGoam/GAZ0ZhukvalfA==} + stylelint-config-standard-scss@14.0.0: + resolution: {integrity: sha512-6Pa26D9mHyi4LauJ83ls3ELqCglU6VfCXchovbEqQUiEkezvKdv6VgsIoMy58i00c854wVmOw0k8W5FTpuaVqg==} engines: {node: '>=18.12.0'} peerDependencies: postcss: ^8.3.3 - stylelint: ^16.3.1 + stylelint: ^16.11.0 peerDependenciesMeta: postcss: optional: true - stylelint-config-standard@36.0.0: - resolution: {integrity: sha512-3Kjyq4d62bYFp/Aq8PMKDwlgUyPU4nacXsjDLWJdNPRUgpuxALu1KnlAHIj36cdtxViVhXexZij65yM0uNIHug==} + stylelint-config-standard@36.0.1: + resolution: {integrity: sha512-8aX8mTzJ6cuO8mmD5yon61CWuIM4UD8Q5aBcWKGSf6kg+EC3uhB+iOywpTK4ca6ZL7B49en8yanOFtUW0qNzyw==} engines: {node: '>=18.12.0'} peerDependencies: stylelint: ^16.1.0 @@ -6642,8 +6644,8 @@ packages: peerDependencies: stylelint: ^14.0.0 || ^15.0.0 || ^16.0.1 - stylelint-scss@6.1.0: - resolution: {integrity: sha512-kCfK8TQzthGwb4vaZniZgxRsVbCM4ZckmT1b/H5m4FU3I8Dz0id9llKsy1NMp3XXqC8+OPD4rVKtUbSxXlJb5g==} + stylelint-scss@6.10.0: + resolution: {integrity: sha512-y03if6Qw9xBMoVaf7tzp5BbnYhYvudIKzURkhSHzcHG0bW0fAYvQpTUVJOe7DyhHaxeThBil4ObEMvGbV7+M+w==} engines: {node: '>=18.12.0'} peerDependencies: stylelint: ^16.0.2 @@ -7056,22 +7058,27 @@ packages: vfile@6.0.1: resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} - vite@5.4.11: - resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==} - engines: {node: ^18.0.0 || >=20.0.0} + vite@6.0.3: + resolution: {integrity: sha512-Cmuo5P0ENTN6HxLSo6IHsjCLn/81Vgrp81oaiFFMRa8gGDj5xEjIcEpf2ZymZtZR8oU0P2JX5WuUp/rlXcHkAw==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' less: '*' lightningcss: ^1.21.0 sass: '*' sass-embedded: '*' stylus: '*' sugarss: '*' - terser: ^5.4.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 peerDependenciesMeta: '@types/node': optional: true + jiti: + optional: true less: optional: true lightningcss: @@ -7086,6 +7093,10 @@ packages: optional: true terser: optional: true + tsx: + optional: true + yaml: + optional: true vscode-json-languageservice@4.2.1: resolution: {integrity: sha512-xGmv9QIWs2H8obGbWg+sIPI/3/pFgj/5OWBhNzs00BkYQ9UaB2F6JJaGB/2/YOZJ3BvLXQTC4Q7muqU25QgAhA==} @@ -8229,73 +8240,76 @@ snapshots: tslib: 2.8.1 optional: true - '@esbuild/aix-ppc64@0.21.5': + '@esbuild/aix-ppc64@0.24.0': optional: true - '@esbuild/android-arm64@0.21.5': + '@esbuild/android-arm64@0.24.0': optional: true - '@esbuild/android-arm@0.21.5': + '@esbuild/android-arm@0.24.0': optional: true - '@esbuild/android-x64@0.21.5': + '@esbuild/android-x64@0.24.0': optional: true - '@esbuild/darwin-arm64@0.21.5': + '@esbuild/darwin-arm64@0.24.0': optional: true - '@esbuild/darwin-x64@0.21.5': + '@esbuild/darwin-x64@0.24.0': optional: true - '@esbuild/freebsd-arm64@0.21.5': + '@esbuild/freebsd-arm64@0.24.0': optional: true - '@esbuild/freebsd-x64@0.21.5': + '@esbuild/freebsd-x64@0.24.0': optional: true - '@esbuild/linux-arm64@0.21.5': + '@esbuild/linux-arm64@0.24.0': optional: true - '@esbuild/linux-arm@0.21.5': + '@esbuild/linux-arm@0.24.0': optional: true - '@esbuild/linux-ia32@0.21.5': + '@esbuild/linux-ia32@0.24.0': optional: true - '@esbuild/linux-loong64@0.21.5': + '@esbuild/linux-loong64@0.24.0': optional: true - '@esbuild/linux-mips64el@0.21.5': + '@esbuild/linux-mips64el@0.24.0': optional: true - '@esbuild/linux-ppc64@0.21.5': + '@esbuild/linux-ppc64@0.24.0': optional: true - '@esbuild/linux-riscv64@0.21.5': + '@esbuild/linux-riscv64@0.24.0': optional: true - '@esbuild/linux-s390x@0.21.5': + '@esbuild/linux-s390x@0.24.0': optional: true - '@esbuild/linux-x64@0.21.5': + '@esbuild/linux-x64@0.24.0': optional: true - '@esbuild/netbsd-x64@0.21.5': + '@esbuild/netbsd-x64@0.24.0': optional: true - '@esbuild/openbsd-x64@0.21.5': + '@esbuild/openbsd-arm64@0.24.0': optional: true - '@esbuild/sunos-x64@0.21.5': + '@esbuild/openbsd-x64@0.24.0': optional: true - '@esbuild/win32-arm64@0.21.5': + '@esbuild/sunos-x64@0.24.0': optional: true - '@esbuild/win32-ia32@0.21.5': + '@esbuild/win32-arm64@0.24.0': optional: true - '@esbuild/win32-x64@0.21.5': + '@esbuild/win32-ia32@0.24.0': + optional: true + + '@esbuild/win32-x64@0.24.0': optional: true '@eslint-community/eslint-utils@4.4.0(eslint@8.57.1)': @@ -8610,11 +8624,11 @@ snapshots: '@types/yargs': 17.0.24 chalk: 4.1.2 - '@joshwooding/vite-plugin-react-docgen-typescript@0.4.2(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1))': + '@joshwooding/vite-plugin-react-docgen-typescript@0.4.2(typescript@5.7.2)(vite@6.0.3(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)(yaml@2.5.0))': dependencies: magic-string: 0.27.0 react-docgen-typescript: 2.2.2(typescript@5.7.2) - vite: 5.4.11(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1) + vite: 6.0.3(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)(yaml@2.5.0) optionalDependencies: typescript: 5.7.2 @@ -9080,13 +9094,13 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@storybook/builder-vite@8.4.7(storybook@8.4.7(prettier@3.4.2))(vite@5.4.11(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1))': + '@storybook/builder-vite@8.4.7(storybook@8.4.7(prettier@3.4.2))(vite@6.0.3(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)(yaml@2.5.0))': dependencies: '@storybook/csf-plugin': 8.4.7(storybook@8.4.7(prettier@3.4.2)) browser-assert: 1.2.1 storybook: 8.4.7(prettier@3.4.2) ts-dedent: 2.2.0 - vite: 5.4.11(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1) + vite: 6.0.3(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)(yaml@2.5.0) '@storybook/components@8.4.7(storybook@8.4.7(prettier@3.4.2))': dependencies: @@ -9101,8 +9115,8 @@ snapshots: '@storybook/csf': 0.1.12 better-opn: 3.0.2 browser-assert: 1.2.1 - esbuild: 0.21.5 - esbuild-register: 3.5.0(esbuild@0.21.5) + esbuild: 0.24.0 + esbuild-register: 3.5.0(esbuild@0.24.0) jsdoc-type-pratt-parser: 4.1.0 process: 0.11.10 recast: 0.23.6 @@ -9154,11 +9168,11 @@ snapshots: react-dom: 18.3.1(react@18.3.1) storybook: 8.4.7(prettier@3.4.2) - '@storybook/react-vite@8.4.7(@storybook/test@8.4.7(storybook@8.4.7(prettier@3.4.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.28.1)(storybook@8.4.7(prettier@3.4.2))(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1))': + '@storybook/react-vite@8.4.7(@storybook/test@8.4.7(storybook@8.4.7(prettier@3.4.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.28.1)(storybook@8.4.7(prettier@3.4.2))(typescript@5.7.2)(vite@6.0.3(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)(yaml@2.5.0))': dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.4.2(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.4.2(typescript@5.7.2)(vite@6.0.3(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)(yaml@2.5.0)) '@rollup/pluginutils': 5.1.3(rollup@4.28.1) - '@storybook/builder-vite': 8.4.7(storybook@8.4.7(prettier@3.4.2))(vite@5.4.11(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)) + '@storybook/builder-vite': 8.4.7(storybook@8.4.7(prettier@3.4.2))(vite@6.0.3(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)(yaml@2.5.0)) '@storybook/react': 8.4.7(@storybook/test@8.4.7(storybook@8.4.7(prettier@3.4.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7(prettier@3.4.2))(typescript@5.7.2) find-up: 5.0.0 magic-string: 0.30.10 @@ -9168,7 +9182,7 @@ snapshots: resolve: 1.22.8 storybook: 8.4.7(prettier@3.4.2) tsconfig-paths: 4.2.0 - vite: 5.4.11(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1) + vite: 6.0.3(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)(yaml@2.5.0) transitivePeerDependencies: - '@storybook/test' - rollup @@ -9653,14 +9667,14 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@vitejs/plugin-react@4.3.4(vite@5.4.11(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1))': + '@vitejs/plugin-react@4.3.4(vite@6.0.3(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)(yaml@2.5.0))': dependencies: '@babel/core': 7.26.0 '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.0) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 5.4.11(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1) + vite: 6.0.3(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)(yaml@2.5.0) transitivePeerDependencies: - supports-color @@ -10905,38 +10919,39 @@ snapshots: is-date-object: 1.0.5 is-symbol: 1.0.4 - esbuild-register@3.5.0(esbuild@0.21.5): + esbuild-register@3.5.0(esbuild@0.24.0): dependencies: debug: 4.3.7 - esbuild: 0.21.5 + esbuild: 0.24.0 transitivePeerDependencies: - supports-color - esbuild@0.21.5: + esbuild@0.24.0: optionalDependencies: - '@esbuild/aix-ppc64': 0.21.5 - '@esbuild/android-arm': 0.21.5 - '@esbuild/android-arm64': 0.21.5 - '@esbuild/android-x64': 0.21.5 - '@esbuild/darwin-arm64': 0.21.5 - '@esbuild/darwin-x64': 0.21.5 - '@esbuild/freebsd-arm64': 0.21.5 - '@esbuild/freebsd-x64': 0.21.5 - '@esbuild/linux-arm': 0.21.5 - '@esbuild/linux-arm64': 0.21.5 - '@esbuild/linux-ia32': 0.21.5 - '@esbuild/linux-loong64': 0.21.5 - '@esbuild/linux-mips64el': 0.21.5 - '@esbuild/linux-ppc64': 0.21.5 - '@esbuild/linux-riscv64': 0.21.5 - '@esbuild/linux-s390x': 0.21.5 - '@esbuild/linux-x64': 0.21.5 - '@esbuild/netbsd-x64': 0.21.5 - '@esbuild/openbsd-x64': 0.21.5 - '@esbuild/sunos-x64': 0.21.5 - '@esbuild/win32-arm64': 0.21.5 - '@esbuild/win32-ia32': 0.21.5 - '@esbuild/win32-x64': 0.21.5 + '@esbuild/aix-ppc64': 0.24.0 + '@esbuild/android-arm': 0.24.0 + '@esbuild/android-arm64': 0.24.0 + '@esbuild/android-x64': 0.24.0 + '@esbuild/darwin-arm64': 0.24.0 + '@esbuild/darwin-x64': 0.24.0 + '@esbuild/freebsd-arm64': 0.24.0 + '@esbuild/freebsd-x64': 0.24.0 + '@esbuild/linux-arm': 0.24.0 + '@esbuild/linux-arm64': 0.24.0 + '@esbuild/linux-ia32': 0.24.0 + '@esbuild/linux-loong64': 0.24.0 + '@esbuild/linux-mips64el': 0.24.0 + '@esbuild/linux-ppc64': 0.24.0 + '@esbuild/linux-riscv64': 0.24.0 + '@esbuild/linux-s390x': 0.24.0 + '@esbuild/linux-x64': 0.24.0 + '@esbuild/netbsd-x64': 0.24.0 + '@esbuild/openbsd-arm64': 0.24.0 + '@esbuild/openbsd-x64': 0.24.0 + '@esbuild/sunos-x64': 0.24.0 + '@esbuild/win32-arm64': 0.24.0 + '@esbuild/win32-ia32': 0.24.0 + '@esbuild/win32-x64': 0.24.0 escalade@3.1.2: {} @@ -12539,8 +12554,6 @@ snapshots: kleur@4.1.5: {} - known-css-properties@0.29.0: {} - known-css-properties@0.35.0: {} leven@3.1.0: {} @@ -12959,6 +12972,8 @@ snapshots: mdn-data@2.12.1: {} + mdn-data@2.13.0: {} + mdurl@2.0.0: {} memfs@4.9.3: @@ -13981,11 +13996,6 @@ snapshots: dependencies: postcss: 8.4.49 - postcss-selector-parser@6.1.2: - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - postcss-selector-parser@7.0.0: dependencies: cssesc: 3.0.0 @@ -14884,31 +14894,31 @@ snapshots: optionalDependencies: '@babel/core': 7.26.0 - stylelint-config-recommended-scss@14.0.0(postcss@8.4.49)(stylelint@16.11.0(typescript@5.7.2)): + stylelint-config-recommended-scss@14.1.0(postcss@8.4.49)(stylelint@16.11.0(typescript@5.7.2)): dependencies: postcss-scss: 4.0.9(postcss@8.4.49) stylelint: 16.11.0(typescript@5.7.2) - stylelint-config-recommended: 14.0.0(stylelint@16.11.0(typescript@5.7.2)) - stylelint-scss: 6.1.0(stylelint@16.11.0(typescript@5.7.2)) + stylelint-config-recommended: 14.0.1(stylelint@16.11.0(typescript@5.7.2)) + stylelint-scss: 6.10.0(stylelint@16.11.0(typescript@5.7.2)) optionalDependencies: postcss: 8.4.49 - stylelint-config-recommended@14.0.0(stylelint@16.11.0(typescript@5.7.2)): + stylelint-config-recommended@14.0.1(stylelint@16.11.0(typescript@5.7.2)): dependencies: stylelint: 16.11.0(typescript@5.7.2) - stylelint-config-standard-scss@13.1.0(postcss@8.4.49)(stylelint@16.11.0(typescript@5.7.2)): + stylelint-config-standard-scss@14.0.0(postcss@8.4.49)(stylelint@16.11.0(typescript@5.7.2)): dependencies: stylelint: 16.11.0(typescript@5.7.2) - stylelint-config-recommended-scss: 14.0.0(postcss@8.4.49)(stylelint@16.11.0(typescript@5.7.2)) - stylelint-config-standard: 36.0.0(stylelint@16.11.0(typescript@5.7.2)) + stylelint-config-recommended-scss: 14.1.0(postcss@8.4.49)(stylelint@16.11.0(typescript@5.7.2)) + stylelint-config-standard: 36.0.1(stylelint@16.11.0(typescript@5.7.2)) optionalDependencies: postcss: 8.4.49 - stylelint-config-standard@36.0.0(stylelint@16.11.0(typescript@5.7.2)): + stylelint-config-standard@36.0.1(stylelint@16.11.0(typescript@5.7.2)): dependencies: stylelint: 16.11.0(typescript@5.7.2) - stylelint-config-recommended: 14.0.0(stylelint@16.11.0(typescript@5.7.2)) + stylelint-config-recommended: 14.0.1(stylelint@16.11.0(typescript@5.7.2)) stylelint-order@6.0.4(stylelint@16.11.0(typescript@5.7.2)): dependencies: @@ -14916,12 +14926,15 @@ snapshots: postcss-sorting: 8.0.2(postcss@8.4.49) stylelint: 16.11.0(typescript@5.7.2) - stylelint-scss@6.1.0(stylelint@16.11.0(typescript@5.7.2)): + stylelint-scss@6.10.0(stylelint@16.11.0(typescript@5.7.2)): dependencies: - known-css-properties: 0.29.0 + css-tree: 3.0.1 + is-plain-object: 5.0.0 + known-css-properties: 0.35.0 + mdn-data: 2.13.0 postcss-media-query-parser: 0.2.3 postcss-resolve-nested-selector: 0.1.6 - postcss-selector-parser: 6.1.2 + postcss-selector-parser: 7.0.0 postcss-value-parser: 4.2.0 stylelint: 16.11.0(typescript@5.7.2) @@ -15437,9 +15450,9 @@ snapshots: unist-util-stringify-position: 4.0.0 vfile-message: 4.0.2 - vite@5.4.11(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1): + vite@6.0.3(@types/node@22.10.1)(sass@1.82.0)(terser@5.17.1)(yaml@2.5.0): dependencies: - esbuild: 0.21.5 + esbuild: 0.24.0 postcss: 8.4.49 rollup: 4.28.1 optionalDependencies: @@ -15447,6 +15460,7 @@ snapshots: fsevents: 2.3.3 sass: 1.82.0 terser: 5.17.1 + yaml: 2.5.0 vscode-json-languageservice@4.2.1: dependencies: diff --git a/proprietary/tokens/src/components/ams/file-list.tokens.json b/proprietary/tokens/src/components/ams/file-list.tokens.json new file mode 100644 index 0000000000..e30532d050 --- /dev/null +++ b/proprietary/tokens/src/components/ams/file-list.tokens.json @@ -0,0 +1,21 @@ +{ + "ams": { + "file-list": { + "gap": { "value": "{ams.space.md}" }, + "padding-block": { "value": "{ams.space.md}" }, + "file": { + "font-family": { "value": "{ams.text.font-family}" }, + "font-size": { "value": "{ams.text.level.6.font-size}" }, + "font-weight": { "value": "{ams.text.font-weight.normal}" }, + "gap": { "value": "{ams.space.sm}" }, + "line-height": { "value": "{ams.text.level.6.line-height}" }, + "details": { + "color": { "value": "{ams.brand.color.neutral.60}" } + }, + "preview": { + "width": { "value": "clamp(2.5rem, 10vw, 5rem)" } + } + } + } + } +} diff --git a/storybook/package.json b/storybook/package.json index 9516f9d6a5..cbf79293e8 100644 --- a/storybook/package.json +++ b/storybook/package.json @@ -52,6 +52,6 @@ "remark-gfm": "4.0.0", "require-from-string": "2.0.2", "storybook": "8.4.7", - "vite": "5.4.11" + "vite": "6.0.3" } } diff --git a/storybook/src/components/DescriptionList/DescriptionList.docs.mdx b/storybook/src/components/DescriptionList/DescriptionList.docs.mdx index 88728215f8..4e34bfd49d 100644 --- a/storybook/src/components/DescriptionList/DescriptionList.docs.mdx +++ b/storybook/src/components/DescriptionList/DescriptionList.docs.mdx @@ -20,6 +20,12 @@ A term may have multiple descriptions. +### Multiple terms + +If multiple terms share a single description, group them in a `DescriptionList.Section` component to ensure proper grid layout. + + + ### Rich description A description can include rich content such as inline formatting, links, paragraphs, and even lists. diff --git a/storybook/src/components/DescriptionList/DescriptionList.stories.tsx b/storybook/src/components/DescriptionList/DescriptionList.stories.tsx index 5430965a8c..81598822ec 100644 --- a/storybook/src/components/DescriptionList/DescriptionList.stories.tsx +++ b/storybook/src/components/DescriptionList/DescriptionList.stories.tsx @@ -54,6 +54,26 @@ export const MultipleDescriptions: Story = { }, } +export const MultipleTerms: Story = { + args: { + termsWidth: 'md', + children: [ + Achternaam, + + De naam die een persoon van zijn of haar ouders krijgt + , + + Voornaam + Roepnaam + Bijnaam + De naam waarmee een persoon wordt aangesproken + , + Geboortedatum, + De datum waarop een persoon is geboren, + ], + }, +} + export const RichDescription: Story = { render: (args) => ( diff --git a/storybook/src/components/FileList/FileInputWithFileList.tsx b/storybook/src/components/FileList/FileInputWithFileList.tsx new file mode 100644 index 0000000000..9d29f7557c --- /dev/null +++ b/storybook/src/components/FileList/FileInputWithFileList.tsx @@ -0,0 +1,39 @@ +import { FileInput, FileList } from '@amsterdam/design-system-react' +import { useRef, useState } from 'react' + +export const FileInputWithFileList = () => { + const inputRef = useRef(null) + const [files, setFiles] = useState(null) + + const changeFiles = () => { + if (inputRef.current) { + setFiles(inputRef.current.files) + } + } + + const removeFile = (index: number) => { + if (files) { + const newFiles = new DataTransfer() + Array.from(files).forEach((file, i) => { + if (i !== index) newFiles.items.add(file) + }) + if (inputRef.current) { + inputRef.current.files = newFiles.files + } + setFiles(newFiles.files) + } + } + + return ( + <> + + {files && ( + + {Array.from(files).map((file, index) => ( + removeFile(index)} /> + ))} + + )} + + ) +} diff --git a/storybook/src/components/FileList/FileList.docs.mdx b/storybook/src/components/FileList/FileList.docs.mdx new file mode 100644 index 0000000000..a9b6ca795b --- /dev/null +++ b/storybook/src/components/FileList/FileList.docs.mdx @@ -0,0 +1,23 @@ +{/* @license CC0-1.0 */} + +import { Canvas, Markdown, Meta, Primary, Source } from "@storybook/blocks"; +import FileInputWithFileList from "./FileInputWithFileList?raw"; +import * as FileListStories from "./FileList.stories.tsx"; +import README from "../../../../packages/css/src/components/file-list/README.md?raw"; + + + +{README} + + + +## Examples + +### Using a file input + +To connect a File Input to a File List, use the `onChange` event to update the +list of files and use `onDelete` when removing a file from the list. + + + + diff --git a/storybook/src/components/FileList/FileList.stories.tsx b/storybook/src/components/FileList/FileList.stories.tsx new file mode 100644 index 0000000000..47a9a77e28 --- /dev/null +++ b/storybook/src/components/FileList/FileList.stories.tsx @@ -0,0 +1,44 @@ +/** + * @license EUPL-1.2+ + * Copyright Gemeente Amsterdam + */ + +import { FileList } from '@amsterdam/design-system-react/src' +import { Meta, StoryObj } from '@storybook/react' +import { FileInputWithFileList } from './FileInputWithFileList' + +const meta = { + title: 'Components/Forms/File List', + component: FileList, + args: { + children: [ + {}} + />, + {}} + />, + ], + }, +} satisfies Meta + +export default meta + +type Story = StoryObj + +export const Default: Story = {} + +export const WithInput: Story = { + parameters: { + docs: { + canvas: { + sourceState: 'none', + }, + }, + }, + render: () => , +}