From 6a0d4574040146d91053f49cd14f45ce96d04623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 21 Mar 2024 18:29:49 +0100 Subject: [PATCH 01/37] feat(styles): turn badge into chip and update its styles update styles --- .changeset/sweet-clouds-scream.md | 5 + packages/styles/src/components/_index.scss | 2 +- packages/styles/src/components/badge.scss | 85 ---------------- packages/styles/src/components/chip.scss | 94 ++++++++++++++++++ .../styles/src/components/form-check.scss | 4 + .../styles/src/components/form-range.scss | 6 ++ .../src/mixins/{_badge.scss => _chip.scss} | 22 +++-- packages/styles/src/mixins/_index.scss | 2 +- packages/styles/src/mixins/_utilities.scss | 28 ++++-- packages/styles/src/placeholders/_badge.scss | 59 ----------- packages/styles/src/placeholders/_chip.scss | 99 +++++++++++++++++++ packages/styles/src/placeholders/_index.scss | 2 +- .../bootstrap/_overrides-variables.scss | 1 + packages/styles/src/variables/_commons.scss | 1 + .../src/variables/components/_badge.scss | 51 +++------- .../src/variables/components/_chip.scss | 42 ++++++++ .../src/variables/components/_index.scss | 1 + 17 files changed, 303 insertions(+), 201 deletions(-) create mode 100644 .changeset/sweet-clouds-scream.md delete mode 100644 packages/styles/src/components/badge.scss create mode 100644 packages/styles/src/components/chip.scss rename packages/styles/src/mixins/{_badge.scss => _chip.scss} (57%) delete mode 100644 packages/styles/src/placeholders/_badge.scss create mode 100644 packages/styles/src/placeholders/_chip.scss create mode 100644 packages/styles/src/variables/components/_chip.scss diff --git a/.changeset/sweet-clouds-scream.md b/.changeset/sweet-clouds-scream.md new file mode 100644 index 0000000000..7eab6f60de --- /dev/null +++ b/.changeset/sweet-clouds-scream.md @@ -0,0 +1,5 @@ +--- +'@swisspost/design-system-styles': major +--- + +Renamed the badge into "chip", added a disable state and updated its styles. diff --git a/packages/styles/src/components/_index.scss b/packages/styles/src/components/_index.scss index 1a2173944d..7748cc0ae2 100644 --- a/packages/styles/src/components/_index.scss +++ b/packages/styles/src/components/_index.scss @@ -4,11 +4,11 @@ @use 'accordion'; @use 'alert'; -@use 'badge'; @use 'breadcrumb'; @use 'button'; @use 'button-group'; @use 'card'; +@use 'chip'; @use 'choice-control-card'; @use 'carousel'; @use 'close'; diff --git a/packages/styles/src/components/badge.scss b/packages/styles/src/components/badge.scss deleted file mode 100644 index cc7ed9dbd9..0000000000 --- a/packages/styles/src/components/badge.scss +++ /dev/null @@ -1,85 +0,0 @@ -@forward './../variables/options'; - -@use './../lic/bootstrap-license'; -@use './../themes/bootstrap/core' as *; -@use './../themes/bootstrap/badge' as bb; - -@use './../variables/components/badge'; -@use './../variables/components/forms'; -@use './../variables/components/form-check'; -@use './../variables/color'; -@use './../mixins/utilities'; -@use './../mixins/forms' as forms-mx; -@use './../mixins/badge' as badge-mx; -@use './../placeholders/badge' as badge-ph; -@use './../functions/icons' as icons-fn; - -.badge { - @extend %badge; -} - -a, -button { - &.badge { - @include forms-mx.focus-outline; - background-color: transparent; - text-decoration: none; - transition: badge.$badge-transition; - - @include utilities.not-disabled-focus-hover { - @include badge-mx.badge-hover-state; - } - - &:active, - &.active { - @include badge-mx.badge-active-state; - } - } -} - -.badge-check { - &-label { - @extend %badge; - @include forms-mx.focus-outline; - transition: badge.$badge-transition; - cursor: pointer; - } - - &-input { - @include utilities.visuallyhidden; - } - - &-input:focus-visible + &-label { - outline-offset: forms.$input-focus-outline-thickness; - outline: forms.$input-focus-outline-thickness solid var(--post-contrast-color); - } - - &-input:not(:checked) + &-label:hover { - @include badge-mx.badge-hover-state; - } - - &-input:checked + &-label { - @include badge-mx.badge-active-state; - } -} - -@include utilities.high-contrast-mode() { - .badge-check { - &-input:focus-visible + &-label { - border-color: Highlight; - outline-color: Highlight; - } - - &-input:checked + &-label { - &:hover { - @include badge-mx.badge-hover-state; - } - } - } - - button.badge, - a.badge, - .badge-check-label { - transition: none; - } -} diff --git a/packages/styles/src/components/chip.scss b/packages/styles/src/components/chip.scss new file mode 100644 index 0000000000..0a9726955b --- /dev/null +++ b/packages/styles/src/components/chip.scss @@ -0,0 +1,94 @@ +@forward './../variables/options'; + +@use './../variables/components/chip'; +@use './../variables/components/forms'; +@use './../variables/components/form-check'; +@use './../variables/color'; +@use './../mixins/utilities'; +@use './../mixins/chip' as chip-mx; +@use './../placeholders/chip' as chip-ph; +@use './../functions/icons' as icons-fn; + +.chip { + @extend %chip; +} + +a, +button { + &.chip { + @include utilities.focus-style; + background-color: transparent; + text-decoration: none; + transition: chip.$chip-transition; + + &:is(:active, .active) { + @include chip-mx.chip-active-state; + @include utilities.disabled-style-custom { + background-color: chip.$chip-disabled-active-bg; + } + } + + &:not(:active, .active) { + @include utilities.not-disabled-focus-hover { + @include chip-mx.chip-hover-state; + } + } + + @include utilities.disabled-style; + @include utilities.disabled-style-custom { + background-color: chip.$chip-disabled-bg; + } + } +} + +.chip-check { + &-label { + @extend %chip; + transition: chip.$chip-transition; + cursor: pointer; + } + + &-input:checked { + + .chip-check-label { + @include chip-mx.chip-active-state; + } + + @include utilities.disabled-style-custom('+ .chip-check-label') { + background-color: chip.$chip-disabled-active-bg; + } + } + + &-input:not(:checked) + &-label:hover { + @include chip-mx.chip-hover-state; + } + + &-input { + @include utilities.visuallyhidden; + @include utilities.focus-style('+ .chip-check-label'); + @include utilities.disabled-style('+ .chip-check-label'); + @include utilities.disabled-style-custom('+ .chip-check-label') { + background-color: chip.$chip-disabled-bg; + } + } +} + +@include utilities.high-contrast-mode() { + .chip-check { + &-input:focus-visible + &-label { + border-color: Highlight; + outline-color: Highlight; + } + + &-input:checked + &-label { + &:hover { + @include chip-mx.chip-hover-state; + } + } + } + + button.chip, + a.chip, + .chip-check-label { + transition: none; + } +} diff --git a/packages/styles/src/components/form-check.scss b/packages/styles/src/components/form-check.scss index d0eb245bcf..3c2e04a969 100644 --- a/packages/styles/src/components/form-check.scss +++ b/packages/styles/src/components/form-check.scss @@ -1,6 +1,7 @@ @forward './../variables/options'; @use '../variables/color'; +@use '../variables/commons'; @use '../variables/type'; @use '../variables/spacing'; @use '../variables/animation'; @@ -15,6 +16,9 @@ margin-bottom: form-check.$form-check-margin-bottom; @include utility-mx.focus-style(); + @include utility-mx.focus-style-custom() { + border-radius: commons.$border-radius !important; + }; &-inline { display: inline-flex; diff --git a/packages/styles/src/components/form-range.scss b/packages/styles/src/components/form-range.scss index 66f698fdf2..6e53527e92 100644 --- a/packages/styles/src/components/form-range.scss +++ b/packages/styles/src/components/form-range.scss @@ -16,11 +16,17 @@ $webkit-thumb-width: 32px; :has(> .form-range) { @include utilities.focus-style(); + @include utilities.focus-style-custom() { + border-radius: commons.$border-radius !important; + }; } @supports not selector(:has(> .form-range)) { .form-range { @include utilities.focus-style(); + @include utilities.focus-style-custom() { + border-radius: commons.$border-radius !important; + }; } } diff --git a/packages/styles/src/mixins/_badge.scss b/packages/styles/src/mixins/_chip.scss similarity index 57% rename from packages/styles/src/mixins/_badge.scss rename to packages/styles/src/mixins/_chip.scss index 22a8d652e8..ff3487e78b 100644 --- a/packages/styles/src/mixins/_badge.scss +++ b/packages/styles/src/mixins/_chip.scss @@ -1,10 +1,15 @@ @use './../variables/components/badge'; +@use './../variables/components/chip'; @use './../mixins/utilities'; -@mixin badge-hover-state { - color: badge.$badge-hover-color; - background-color: badge.$badge-hover-bg-color; - border-color: transparent; +@mixin chip-hover-state { + color: chip.$chip-hover-color; + background-color: chip.$chip-hover-bg; + + > .badge { + background-color: badge.$badge-hover-bg-color; + border-color: badge.$badge-hover-border-color; + } @include utilities.high-contrast-mode() { background-color: Highlight; @@ -14,13 +19,14 @@ } } -@mixin badge-active-state { - color: badge.$badge-active-color; - background-color: badge.$badge-active-bg-color; +@mixin chip-active-state { + color: chip.$chip-active-color; + background-color: chip.$chip-active-bg; border-color: transparent; > .badge { - background-color: badge.$badge-nested-active-bg-color; + background-color: badge.$badge-active-bg-color; + border-color: badge.$badge-active-border-color; } @include utilities.high-contrast-mode() { diff --git a/packages/styles/src/mixins/_index.scss b/packages/styles/src/mixins/_index.scss index c7521115e2..8916e48f1c 100644 --- a/packages/styles/src/mixins/_index.scss +++ b/packages/styles/src/mixins/_index.scss @@ -1,6 +1,6 @@ @forward 'animation'; -@forward 'badge'; @forward 'button'; +@forward 'chip'; @forward 'color'; @forward 'focus'; @forward 'form-checks'; diff --git a/packages/styles/src/mixins/_utilities.scss b/packages/styles/src/mixins/_utilities.scss index 63d4363bc3..86bc670b3c 100644 --- a/packages/styles/src/mixins/_utilities.scss +++ b/packages/styles/src/mixins/_utilities.scss @@ -88,15 +88,16 @@ } @mixin focus-style($vendor-prefix: '') { - outline-style: none; - outline-offset: spacing.$size-line; - outline-width: spacing.$size-line; - outline-color: var(--post-focus-color); + &#{$vendor-prefix} { + outline-style: none; + outline-offset: spacing.$size-line; + outline-width: spacing.$size-line; + outline-color: var(--post-focus-color); + } // :has(:focus-visible) mimic a focus-visible-within pseudo-class &:is(:focus-visible, :has(:focus-visible), .pretend-focus)#{$vendor-prefix} { outline-style: solid; - border-radius: commons.$border-radius !important; @include high-contrast-mode() { outline-color: Highlight; @@ -110,7 +111,6 @@ @supports not selector(:has(:focus-visible)) { &:is(:focus-visible, :focus-within, .pretend-focus)#{$vendor-prefix} { outline-style: solid; - border-radius: commons.$border-radius !important; @include high-contrast-mode() { outline-color: Highlight; @@ -135,3 +135,19 @@ } } } + +@mixin disabled-style($selector: '') { + &:is(:disabled, .disabled)#{$selector} { + pointer-events: none; + text-decoration: line-through; + color: var(--post-gray-40); + border-color: var(--post-gray-40); + border-style: dashed; + } +} + +@mixin disabled-style-custom($selector: '') { + &:is(:disabled, .disabled)#{$selector} { + @content; + } +} diff --git a/packages/styles/src/placeholders/_badge.scss b/packages/styles/src/placeholders/_badge.scss deleted file mode 100644 index 8c187aeb71..0000000000 --- a/packages/styles/src/placeholders/_badge.scss +++ /dev/null @@ -1,59 +0,0 @@ -@use './../themes/bootstrap/core' as *; - -@use './../variables/components/badge'; - -%badge { - @include border-radius($badge-border-radius); - display: inline-flex; - justify-content: flex-start; - align-items: center; - gap: badge.$badge-gap; - padding: $badge-padding-y $badge-padding-x; - border: badge.$badge-border-width solid badge.$badge-border-color; - height: badge.$badge-height; - font-size: badge.$badge-font-size; - font-weight: $badge-font-weight; - line-height: inherit; - color: $badge-color; - text-align: center; - vertical-align: baseline; - max-width: 100%; - - > span { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - } - - > .badge { - padding: $size-micro; - height: badge.$badge-nested-height; - min-width: badge.$badge-nested-height; - color: badge.$badge-nested-color; - background-color: badge.$badge-nested-bg-color; - border-color: badge.$badge-nested-border-color; - font-size: badge.$badge-nested-font-size; - } - - > .badge, - > .btn-close { - margin-right: -1 * (badge.$badge-padding-x - badge.$badge-nested-translate-x); - } - - &.badge-sm { - height: badge.$badge-height-sm; - font-size: badge.$badge-font-size-sm; - gap: badge.$badge-gap-sm; - - > .badge, - > .btn-close { - margin-right: -1 * (badge.$badge-padding-x - badge.$badge-nested-translate-x-sm); - } - } - - // Quick fix for badges in buttons - .btn & { - position: relative; - top: -1px; - } -} diff --git a/packages/styles/src/placeholders/_chip.scss b/packages/styles/src/placeholders/_chip.scss new file mode 100644 index 0000000000..fc10eaf2f7 --- /dev/null +++ b/packages/styles/src/placeholders/_chip.scss @@ -0,0 +1,99 @@ +@use './../themes/bootstrap/core' as *; + +@use './../variables/commons'; +@use './../variables/spacing'; +@use './../variables/components/badge'; +@use './../variables/components/chip'; + +%chip { + @include border-radius(chip.$chip-border-radius); + display: inline-flex; + align-items: center; + height: chip.$chip-height; + max-width: chip.$chip-max-width; + padding-inline: chip.$chip-padding-x; + border: chip.$chip-border-width solid chip.$chip-border-color; + gap: chip.$chip-gap; + line-height: chip.$chip-line-height; + font-size: chip.$chip-font-size; + font-weight: chip.$chip-font-weight; + color: chip.$chip-color; + background-color: chip.$chip-bg; + + > span { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + } + + > .badge { + display: inline-flex; + align-items: center; + justify-content: center; + height: badge.$badge-height; + min-width: badge.$badge-height; + padding: spacing.$size-micro; + color: badge.$badge-color; + background-color: badge.$badge-bg; + border: badge.$badge-border; + font-size: badge.$badge-font-size; + } + + > .btn-close { + &:hover { + background-color: chip.$chip-hover-bg; + } + + &::before { + height: badge.$badge-height; + width: badge.$badge-height; + } + } + + > .badge, + > .btn-close { + border-radius: commons.$border-radius-pill; + + &:first-child { + margin-left: 0.5 * badge.$badge-height - chip.$chip-padding-x; + } + + &:last-child { + margin-right: 0.5 * badge.$badge-height - chip.$chip-padding-x; + } + } + + &.chip-sm { + height: chip.$chip-height-sm; + font-size: chip.$chip-font-size-sm; + gap: chip.$chip-gap-sm; + padding-inline: chip.$chip-padding-x-sm; + + > .badge { + height: badge.$badge-height-sm; + min-width: badge.$badge-height-sm; + } + + > .btn-close::before { + height: badge.$badge-height-sm; + width: badge.$badge-height-sm; + } + + > .badge, + > .btn-close { + &:first-child { + margin-left: 0.5 * badge.$badge-height-sm - chip.$chip-padding-x-sm; + } + + &:last-child { + margin-right: 0.5 * badge.$badge-height-sm - chip.$chip-padding-x-sm; + } + } + } + + // Quick fix for badges in buttons + .btn & { + position: relative; + top: -1px; + } +} diff --git a/packages/styles/src/placeholders/_index.scss b/packages/styles/src/placeholders/_index.scss index 639bb6ad75..ab2763bc0d 100644 --- a/packages/styles/src/placeholders/_index.scss +++ b/packages/styles/src/placeholders/_index.scss @@ -1,5 +1,5 @@ -@use './badge'; @use './button'; +@use './chip'; @use './close'; @use './color'; @use './dropdown'; diff --git a/packages/styles/src/themes/bootstrap/_overrides-variables.scss b/packages/styles/src/themes/bootstrap/_overrides-variables.scss index 27f3553c28..ca9d63b291 100644 --- a/packages/styles/src/themes/bootstrap/_overrides-variables.scss +++ b/packages/styles/src/themes/bootstrap/_overrides-variables.scss @@ -15,6 +15,7 @@ @forward './../../variables/components/button'; @forward './../../variables/components/card'; @forward './../../variables/components/carousel'; +@forward './../../variables/components/chip'; @forward './../../variables/components/close'; @forward './../../variables/components/datepicker'; @forward './../../variables/components/dropdowns'; diff --git a/packages/styles/src/variables/_commons.scss b/packages/styles/src/variables/_commons.scss index 3d29df6cdc..b1cd334994 100644 --- a/packages/styles/src/variables/_commons.scss +++ b/packages/styles/src/variables/_commons.scss @@ -11,6 +11,7 @@ $border-radius: 4px !default; $border-radius-sm: $border-radius !default; $border-radius-rg: $border-radius !default; $border-radius-lg: $border-radius !default; +$border-radius-pill: 50rem !default; $box-shadow-sm: 0 0 4px 0 rgba(color.$black, 0.4) !default; $box-shadow: 0 0 5px 0 rgba(color.$black, 0.3) !default; diff --git a/packages/styles/src/variables/components/_badge.scss b/packages/styles/src/variables/components/_badge.scss index d47f01e4fe..05180a9fb4 100644 --- a/packages/styles/src/variables/components/_badge.scss +++ b/packages/styles/src/variables/components/_badge.scss @@ -1,48 +1,19 @@ -@use 'sass:math'; - -@use './button'; -@use './../animation'; @use './../color'; @use './../commons'; -@use './../spacing'; -@use './../type'; +@use './../components/chip'; @use './../../functions/sizing'; -// Design System custom variables -$badge-height: button.$btn-height-rg; -$badge-gap: spacing.$size-mini; -$badge-border-color: var(--post-gray-60); -$badge-border-width: commons.$border-thick; -$badge-transition: - color 250ms, - background-color 250ms, - border-color 250ms; -$badge-hover-color: color.$black; -$badge-hover-bg-color: color.$gray-10; -$badge-active-color: color.$black; -$badge-active-bg-color: color.$yellow; - -$badge-height-sm: button.$btn-height-sm; -$badge-gap-sm: sizing.px-to-rem(6px); -$badge-font-size-sm: type.$font-size-tiny; +$badge-height: sizing.px-to-rem(24px); +$badge-height-sm: sizing.px-to-rem(16px); +$badge-font-size: sizing.px-to-rem(10px); -$badge-nested-height: sizing.px-to-rem(22px); -$badge-nested-color: color.$gray-60; -$badge-nested-bg-color: color.$gray-10; -$badge-nested-border-color: color.$white; -$badge-nested-font-size: sizing.px-to-rem(10px); -$badge-nested-translate-x: ($badge-height - $badge-nested-height) * 0.5; -$badge-nested-active-bg-color: color.$white; -$badge-nested-translate-x-sm: ($badge-height-sm - $badge-nested-height) * 0.5; +$badge-color: color.$gray-60; +$badge-bg: color.$gray-20; +$badge-border: commons.$border-thick solid $badge-bg; -$badge-check-input-height: spacing.$size-small-large; -$badge-check-input-bg-color: color.$white; +$badge-hover-bg-color: $badge-bg; +$badge-hover-border-color: color.$white; -// Bootstrap variables -$badge-font-size: type.$font-size-small; -$badge-font-weight: type.$font-weight-normal; -$badge-color: var(--post-gray-80); -$badge-padding-y: 0; -$badge-padding-x: spacing.$size-regular - sizing.px-to-rem($badge-border-width); -$badge-border-radius: 50rem; +$badge-active-bg-color: color.$white; +$badge-active-border-color: color.$white; diff --git a/packages/styles/src/variables/components/_chip.scss b/packages/styles/src/variables/components/_chip.scss new file mode 100644 index 0000000000..4c0d638d3f --- /dev/null +++ b/packages/styles/src/variables/components/_chip.scss @@ -0,0 +1,42 @@ +@use './button'; +@use './../animation'; +@use './../color'; +@use './../commons'; +@use './../spacing'; +@use './../type'; + +@use './../../functions/sizing'; + +$chip-color: color.$gray-80; +$chip-bg: color.$white; +$chip-border-color: color.$gray-60; +$chip-border-width: commons.$border-thick; +$chip-border-radius: commons.$border-radius-pill; + +$chip-height: button.$btn-height-rg; +$chip-max-width: sizing.px-to-rem(296px); +$chip-padding-x: spacing.$size-regular; +$chip-gap: spacing.$size-mini; + +$chip-font-size: type.$font-size-16; +$chip-font-weight: type.$font-weight-normal; +$chip-line-height: type.$line-height-copy; + +$chip-transition: + color animation.$transition-base-timing, + background-color animation.$transition-base-timing, + border-color animation.$transition-base-timing; + +$chip-height-sm: button.$btn-height-sm; +$chip-gap-sm: sizing.px-to-rem(6px); +$chip-font-size-sm: type.$font-size-14; +$chip-padding-x-sm: spacing.$size-small-regular; + +$chip-hover-color: color.$black; +$chip-hover-bg: color.$gray-20; + +$chip-active-color: color.$black; +$chip-active-bg: color.$yellow; + +$chip-disabled-bg: color.$white; +$chip-disabled-active-bg: color.$gray-background; diff --git a/packages/styles/src/variables/components/_index.scss b/packages/styles/src/variables/components/_index.scss index 7b970be652..69d5d76351 100644 --- a/packages/styles/src/variables/components/_index.scss +++ b/packages/styles/src/variables/components/_index.scss @@ -4,6 +4,7 @@ @forward 'button'; @forward 'card'; @forward 'carousel'; +@forward 'chip'; @forward 'close'; @forward 'datepicker'; @forward 'dropdowns'; From 760863704aea74a212c75cb82b945392bf339f29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 21 Mar 2024 18:31:27 +0100 Subject: [PATCH 02/37] fix the version of the styles package in the demo app --- packages/demo/package.json | 2 +- pnpm-lock.yaml | 22 ++++++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/demo/package.json b/packages/demo/package.json index 76d83615cd..5612f75fd8 100644 --- a/packages/demo/package.json +++ b/packages/demo/package.json @@ -26,7 +26,7 @@ "@popperjs/core": "2.11.8", "@swimlane/ngx-datatable": "20.1.0", "@swisspost/design-system-intranet-header": "workspace:5.0.11", - "@swisspost/design-system-styles": "workspace:6.6.4", + "@swisspost/design-system-styles": "6.6.3", "bootstrap": "5.3.2", "core-js": "3.36.0", "highlight.js": "11.9.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f77d90fa15..6fef318b92 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -345,8 +345,8 @@ importers: specifier: workspace:5.0.11 version: link:../intranet-header-workspace/dist/intranet-header '@swisspost/design-system-styles': - specifier: workspace:6.6.4 - version: link:../styles/dist + specifier: 6.6.3 + version: 6.6.3(@ng-bootstrap/ng-bootstrap@16.0.0)(bootstrap@5.3.2) bootstrap: specifier: 5.3.2 version: 5.3.2(@popperjs/core@2.11.8) @@ -7235,6 +7235,22 @@ packages: tslib: 2.6.2 dev: false + /@swisspost/design-system-styles@6.6.3(@ng-bootstrap/ng-bootstrap@16.0.0)(bootstrap@5.3.2): + resolution: {integrity: sha512-9BL3xK45gVeqi7HW94SaO6zSI5+NZ9nK9GZzjDJD3TSPIeJlQ57+8NpgQDVgDU6p/kliX0IsA8APi8INiQ9/dg==} + peerDependencies: + '@ng-bootstrap/ng-bootstrap': ^15.0.0 + bootstrap: ~5.3.0 + peerDependenciesMeta: + '@ng-bootstrap/ng-bootstrap': + optional: true + bootstrap: + optional: true + dependencies: + '@ng-bootstrap/ng-bootstrap': 16.0.0(@angular/common@17.3.0)(@angular/core@17.3.0)(@angular/forms@17.3.0)(@angular/localize@17.3.0)(@popperjs/core@2.11.8)(rxjs@7.8.1) + '@popperjs/core': 2.11.8 + bootstrap: 5.3.2(@popperjs/core@2.11.8) + dev: false + /@testing-library/dom@9.3.1: resolution: {integrity: sha512-0DGPd9AR3+iDTjGoMpxIkAsUihHZ3Ai6CneU6bRRrffXMgzCdlNk43jTrD2/5LT6CBb3MWTP8v510JzYtahD2w==} engines: {node: '>=14'} @@ -16031,8 +16047,6 @@ packages: peerDependenciesMeta: webpack: optional: true - webpack-sources: - optional: true dependencies: webpack: 5.90.3(esbuild@0.20.1) webpack-sources: 3.2.3 From 57707e124e1db997395186824baf8b50409090fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 21 Mar 2024 19:12:51 +0100 Subject: [PATCH 03/37] feat(docs): update chip documentation --- .changeset/selfish-lions-tap.md | 5 ++ .../snapshots/components/badge.snapshot.ts | 7 -- .../snapshots/components/chip.snapshot.ts | 7 ++ .../stories/components/badge/badge.docs.mdx | 47 ------------ .../src/stories/components/chip/chip.docs.mdx | 36 +++++++++ .../chip.snapshot.stories.ts} | 8 +- .../badge.stories.ts => chip/chip.stories.ts} | 73 ++++++++++++------- 7 files changed, 98 insertions(+), 85 deletions(-) create mode 100644 .changeset/selfish-lions-tap.md delete mode 100644 packages/documentation/cypress/snapshots/components/badge.snapshot.ts create mode 100644 packages/documentation/cypress/snapshots/components/chip.snapshot.ts delete mode 100644 packages/documentation/src/stories/components/badge/badge.docs.mdx create mode 100644 packages/documentation/src/stories/components/chip/chip.docs.mdx rename packages/documentation/src/stories/components/{badge/badge.snapshot.stories.ts => chip/chip.snapshot.stories.ts} (83%) rename packages/documentation/src/stories/components/{badge/badge.stories.ts => chip/chip.stories.ts} (70%) diff --git a/.changeset/selfish-lions-tap.md b/.changeset/selfish-lions-tap.md new file mode 100644 index 0000000000..9c7288465c --- /dev/null +++ b/.changeset/selfish-lions-tap.md @@ -0,0 +1,5 @@ +--- +'@swisspost/design-system-documentation': major +--- + +Renamed badge into "chip". diff --git a/packages/documentation/cypress/snapshots/components/badge.snapshot.ts b/packages/documentation/cypress/snapshots/components/badge.snapshot.ts deleted file mode 100644 index e17f11bc34..0000000000 --- a/packages/documentation/cypress/snapshots/components/badge.snapshot.ts +++ /dev/null @@ -1,7 +0,0 @@ -describe('Badge', () => { - it('default', () => { - cy.visit('/iframe.html?id=snapshots--badge'); - cy.get('.badge', { timeout: 30000 }).should('be.visible'); - cy.percySnapshot('Badges', { widths: [1440] }); - }); -}); diff --git a/packages/documentation/cypress/snapshots/components/chip.snapshot.ts b/packages/documentation/cypress/snapshots/components/chip.snapshot.ts new file mode 100644 index 0000000000..aaa1d6b082 --- /dev/null +++ b/packages/documentation/cypress/snapshots/components/chip.snapshot.ts @@ -0,0 +1,7 @@ +describe('Chip', () => { + it('default', () => { + cy.visit('/iframe.html?id=snapshots--chip'); + cy.get('.chip', { timeout: 30000 }).should('be.visible'); + cy.percySnapshot('Chips', { widths: [1440] }); + }); +}); diff --git a/packages/documentation/src/stories/components/badge/badge.docs.mdx b/packages/documentation/src/stories/components/badge/badge.docs.mdx deleted file mode 100644 index b46b72edd1..0000000000 --- a/packages/documentation/src/stories/components/badge/badge.docs.mdx +++ /dev/null @@ -1,47 +0,0 @@ -import { Canvas, Controls, Meta } from '@storybook/blocks'; -import { PostAlert } from '@swisspost/design-system-components-react'; -import * as badgeStories from './badge.stories'; -import StylesPackageImport from '../../../shared/styles-package-import.mdx'; - - - -# Badge - -
- Documentation and examples for badges, our small count and labeling component. -
- - -

Badge is deprecated

-

- The current `badge` component is deprecated and will be replaced with the `chip` component which will behave similarly to the current `badge` component. - There will also be a new `badge` component, but with a different behavior. Check out the new components in figma: - [Chip](https://www.figma.com/file/xZ0IW0MJO0vnFicmrHiKaY/Components-Post?type=design&node-id=11194-50777&mode=design&t=SeiMf2Vt3dmUnpMT-0) - / - [Badge](https://www.figma.com/file/xZ0IW0MJO0vnFicmrHiKaY/Components-Post?type=design&node-id=11038-51303&mode=design&t=SeiMf2Vt3dmUnpMT-0) -

-
- - -
- -
- - - -## Examples - -### Checkable - -Checkable badges are nothing more than personalized checkboxes. -Therefore, you can handle then like standard checkboxes. - - - -### Dismissible - -Dismissible badges include a close button, allowing users to easily clear them from the page. -Because the close button does not have a visible text, -it should always include a visually hidden label to ensure accessibility for assistive technology users. - - diff --git a/packages/documentation/src/stories/components/chip/chip.docs.mdx b/packages/documentation/src/stories/components/chip/chip.docs.mdx new file mode 100644 index 0000000000..cc80ac60f0 --- /dev/null +++ b/packages/documentation/src/stories/components/chip/chip.docs.mdx @@ -0,0 +1,36 @@ +import { Canvas, Controls, Meta } from '@storybook/blocks'; +import { PostAlert } from '@swisspost/design-system-components-react'; +import * as chipStories from './chip.stories'; +import StylesPackageImport from '../../../shared/styles-package-import.mdx'; + + + +# Chip + +
+ Documentation and examples for chips, our small count and labeling component. +
+ + +
+ +
+ + + +## Examples + +### Checkable + +Checkable chips are nothing more than personalized checkboxes. +Therefore, you can handle then like standard checkboxes. + + + +### Dismissible + +Dismissible chips include a close button, allowing users to easily clear them from the page. +Because the close button does not have a visible text, +it should always include a visually hidden label to ensure accessibility for assistive technology users. + + diff --git a/packages/documentation/src/stories/components/badge/badge.snapshot.stories.ts b/packages/documentation/src/stories/components/chip/chip.snapshot.stories.ts similarity index 83% rename from packages/documentation/src/stories/components/badge/badge.snapshot.stories.ts rename to packages/documentation/src/stories/components/chip/chip.snapshot.stories.ts index 3a90dca504..63287d706a 100644 --- a/packages/documentation/src/stories/components/badge/badge.snapshot.stories.ts +++ b/packages/documentation/src/stories/components/chip/chip.snapshot.stories.ts @@ -1,5 +1,5 @@ import type { Args, StoryContext, StoryObj } from '@storybook/web-components'; -import meta from './badge.stories'; +import meta from './chip.stories'; import { html } from 'lit'; import { bombArgs } from '../../../utils'; @@ -12,7 +12,7 @@ export default { type Story = StoryObj; -export const Badge: Story = { +export const Chip: Story = { render: (_args: Args, context: StoryContext) => { return html`
@@ -26,11 +26,13 @@ export const Badge: Story = { ], size: context.argTypes.size.options, interactionType: context.argTypes.interactionType.options, - nestedBadge: [false, true], + badge: [false, true], checked: [false, true], + disabled: [false, true], dismissed: [false], }) .filter(args => !(args.interactionType !== 'checkable' && args.checked === true)) + .filter(args => !(args.interactionType !== 'checkable' && args.disabled === true)) .map((args: Args) => meta.render?.({ ...context.args, ...args }, context))}
`, diff --git a/packages/documentation/src/stories/components/badge/badge.stories.ts b/packages/documentation/src/stories/components/chip/chip.stories.ts similarity index 70% rename from packages/documentation/src/stories/components/badge/badge.stories.ts rename to packages/documentation/src/stories/components/chip/chip.stories.ts index 2be92512ef..f99b07ded5 100644 --- a/packages/documentation/src/stories/components/badge/badge.stories.ts +++ b/packages/documentation/src/stories/components/chip/chip.stories.ts @@ -6,25 +6,26 @@ import { MetaComponent } from '../../../../types'; const meta: MetaComponent = { id: 'bec68e8b-445e-4760-8bd7-1b9970206d8d', - title: 'Components/Badge', + title: 'Components/Chip', tags: ['package:HTML'], - render: renderBadge, + render: renderChip, decorators: [externalControl], parameters: { - badges: [], + chips: [], }, args: { text: 'Insigno', - size: 'default', - nestedBadge: false, + size: 'large', + badge: false, interactionType: 'none', checked: false, + disabled: false, dismissed: false, }, argTypes: { text: { name: 'Text', - description: 'The text contained in the badge.', + description: 'The text contained in the chip.', control: { type: 'text', }, @@ -34,22 +35,22 @@ const meta: MetaComponent = { }, size: { name: 'Size', - description: 'The size of the badge.', + description: 'The size of the chip.', control: { type: 'radio', labels: { - 'default': 'Default', - 'badge-sm': 'Small', + 'large': 'Large', + 'chip-sm': 'Small', }, }, - options: ['default', 'badge-sm'], + options: ['large', 'chip-sm'], table: { category: 'General', }, }, - nestedBadge: { + badge: { name: 'Nested Badge', - description: 'If `true`, a nested badge is displayed inside the main badge.', + description: 'If `true`, a badge is displayed inside the chip.', control: { type: 'boolean', }, @@ -59,7 +60,7 @@ const meta: MetaComponent = { }, interactionType: { name: 'Interaction Type', - description: 'Defines how the badge can be interacted with.', + description: 'Defines how the chip can be interacted with.', control: { type: 'inline-radio', labels: { @@ -75,7 +76,22 @@ const meta: MetaComponent = { }, checked: { name: 'Checked', - description: 'If `true`, the badge is checked otherwise it is unchecked.', + description: 'If `true`, the chip is checked otherwise it is unchecked.', + if: { + arg: 'interactionType', + eq: 'checkable', + }, + control: { + type: 'boolean', + }, + table: { + category: 'Interactions', + }, + }, + disabled: { + name: 'Disabled', + description: + 'If `true`, the badge is disabled.
There are accessibility concerns with the disabled state.
Please read our disabled state accessibility guide.
', if: { arg: 'interactionType', eq: 'checkable', @@ -89,7 +105,7 @@ const meta: MetaComponent = { }, dismissed: { name: 'Dismissed', - description: 'If `true`, the badge is removed from the page otherwise it is displayed.', + description: 'If `true`, the chip is removed from the page otherwise it is displayed.', if: { arg: 'interactionType', eq: 'dismissible', @@ -118,7 +134,7 @@ function externalControl(story: any, { args }: StoryContext) { updateArgs({ dismissed: false }); }}" > - Show badge + Show chip `; @@ -129,15 +145,15 @@ function externalControl(story: any, { args }: StoryContext) { function getDefaultContent(args: Args) { return html` ${args.text} - ${args.nestedBadge ? html` 10 ` : nothing} + ${args.badge ? html` 1 ` : nothing} `; } function getCheckableContent(args: Args, updateArgs: (args: Args) => void, context: StoryContext) { - const checkboxId = `badge-example--${context.name.replace(/ /g, '-').toLowerCase()}`; + const checkboxId = `chip-example--${context.name.replace(/ /g, '-').toLowerCase()}`; const labelClasses = mapClasses({ - 'badge-check-label': true, - [args.size]: args.size !== 'default', + 'chip-check-label': true, + [args.size]: args.size !== 'large', }); const handleChange = (e: Event) => { @@ -154,9 +170,10 @@ function getCheckableContent(args: Args, updateArgs: (args: Args) => void, conte return html` @@ -171,7 +188,7 @@ function getDismissButton(updateArgs: (args: Args) => void) { `; } -function renderBadge(args: Args, context: StoryContext) { +function renderChip(args: Args, context: StoryContext) { const [_, updateArgs] = useArgs(); if (args.dismissed) return html` ${nothing} `; @@ -179,16 +196,16 @@ function renderBadge(args: Args, context: StoryContext) { const isCheckable = args.interactionType === 'checkable'; const isDismissible = args.interactionType === 'dismissible'; - const badgeClasses = mapClasses({ - 'badge': !isCheckable, - 'badge-check': isCheckable, - [args.size]: args.size !== 'default' && !isCheckable, + const chipClasses = mapClasses({ + 'chip': !isCheckable, + 'chip-check': isCheckable, + [args.size]: args.size !== 'large' && !isCheckable, }); return html` -
- ${isCheckable ? getCheckableContent(args, updateArgs, context) : getDefaultContent(args)} +
${isDismissible ? getDismissButton(updateArgs) : nothing} + ${isCheckable ? getCheckableContent(args, updateArgs, context) : getDefaultContent(args)}
`; } From f513eec61316a08bd8b3a0c9e2a5c1cd037ad789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Wed, 27 Mar 2024 11:41:45 +0100 Subject: [PATCH 04/37] feat(migrations): add migrations for the chip --- .changeset/quiet-mugs-design.md | 5 ++ packages/demo/package.json | 1 + packages/migrations/src/migrations.json | 5 ++ .../src/migrations/bootstrap/chip/index.ts | 69 +++++++++++++++++++ pnpm-lock.yaml | 3 + 5 files changed, 83 insertions(+) create mode 100644 .changeset/quiet-mugs-design.md create mode 100644 packages/migrations/src/migrations/bootstrap/chip/index.ts diff --git a/.changeset/quiet-mugs-design.md b/.changeset/quiet-mugs-design.md new file mode 100644 index 0000000000..77f0f40af0 --- /dev/null +++ b/.changeset/quiet-mugs-design.md @@ -0,0 +1,5 @@ +--- +'@swisspost/design-system-migrations': minor +--- + +Added migrations to turn badges into chips. diff --git a/packages/demo/package.json b/packages/demo/package.json index 5612f75fd8..a1f259350b 100644 --- a/packages/demo/package.json +++ b/packages/demo/package.json @@ -26,6 +26,7 @@ "@popperjs/core": "2.11.8", "@swimlane/ngx-datatable": "20.1.0", "@swisspost/design-system-intranet-header": "workspace:5.0.11", + "@swisspost/design-system-migrations": "workspace:1.0.2", "@swisspost/design-system-styles": "6.6.3", "bootstrap": "5.3.2", "core-js": "3.36.0", diff --git a/packages/migrations/src/migrations.json b/packages/migrations/src/migrations.json index 1af81682aa..9fd7f27714 100644 --- a/packages/migrations/src/migrations.json +++ b/packages/migrations/src/migrations.json @@ -100,6 +100,11 @@ "version": "6.0.0", "description": "Improves the post stepper accessibility.", "factory": "./migrations/post/stepper" + }, + "migration-bootstrap-chip": { + "version": "7.0.0", + "description": "Renames badges to chips.", + "factory": "./migrations/bootstrap/chip" } } } diff --git a/packages/migrations/src/migrations/bootstrap/chip/index.ts b/packages/migrations/src/migrations/bootstrap/chip/index.ts new file mode 100644 index 0000000000..b5ed0c5a41 --- /dev/null +++ b/packages/migrations/src/migrations/bootstrap/chip/index.ts @@ -0,0 +1,69 @@ +import { Rule } from '@angular-devkit/schematics'; +import type { AnyNode, Cheerio, CheerioAPI } from 'cheerio'; +import { DomUpdate, getDomMigrationRule } from '../../../utils/dom-migration'; + +export default function (): Rule { + return getDomMigrationRule(new BadgeCheckToChipCheckUpdate(), new BadgeToChipUpdate()); +} + +class BadgeCheckToChipCheckUpdate implements DomUpdate { + selector = '.badge-check'; + + update($elements: Cheerio, $: CheerioAPI) { + $elements.each((_i, element) => { + const $element = $(element); + + $element.removeClass('badge-check').addClass('chip-check'); + + const $label = $element.children('.badge-check-label'); + if ($label) $label.removeClass('badge-check-label').addClass('chip-check-label'); + + const $input = $element.children('.badge-check-input'); + if ($input) $input.removeClass('badge-check-input').addClass('chip-check-input'); + }); + } +} + +class BadgeToChipUpdate implements DomUpdate { + selector = '.badge'; + + update($elements: Cheerio, $: CheerioAPI) { + $elements.each((_i, element) => { + const $element = $(element); + + // do not update nested badges + const $parent = $element.parent(); + if ($parent.hasClass('chip') || $parent.hasClass('chip-check-label')) { + return; + } + + $element.removeClass('badge').addClass('chip'); + + // remove obsolete badge classes + $element + .attr('class') + ?.split(' ') + .forEach(cssClass => { + const isBgClass = cssClass.match(/^bg-\w+$/); + const isBorderClass = cssClass.match(/^border(-\w+)?$/); + const isRoundedClass = cssClass.match(/^rounded(-\w+)?$/); + + if (isBgClass || isBorderClass || isRoundedClass) { + $element.removeClass(cssClass); + + if (isBgClass && isBgClass[1] === 'active') { + $element.addClass('active'); + } + } + }); + + if ($element.hasClass('badge-sm')) { + $element.removeClass('badge-sm').addClass('chip-sm'); + } + + if ($element.hasClass('bg-active')) { + $element.removeClass('bg-active').addClass('active'); + } + }); + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6fef318b92..e1a5caca9e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -344,6 +344,9 @@ importers: '@swisspost/design-system-intranet-header': specifier: workspace:5.0.11 version: link:../intranet-header-workspace/dist/intranet-header + '@swisspost/design-system-migrations': + specifier: workspace:1.0.2 + version: link:../migrations '@swisspost/design-system-styles': specifier: 6.6.3 version: 6.6.3(@ng-bootstrap/ng-bootstrap@16.0.0)(bootstrap@5.3.2) From aca177ff782c4bc37d7d2f02cd9f8d6c791929a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Wed, 27 Mar 2024 15:13:54 +0100 Subject: [PATCH 05/37] feat(docs) update chip examples --- .changeset/selfish-lions-tap.md | 2 +- .../src/stories/components/chip/chip.docs.mdx | 30 +++++++------- .../stories/components/chip/chip.stories.ts | 41 +++++++++++-------- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/.changeset/selfish-lions-tap.md b/.changeset/selfish-lions-tap.md index 9c7288465c..e09f6a5ab2 100644 --- a/.changeset/selfish-lions-tap.md +++ b/.changeset/selfish-lions-tap.md @@ -2,4 +2,4 @@ '@swisspost/design-system-documentation': major --- -Renamed badge into "chip". +Renamed badge into "chip" and improved related examples. diff --git a/packages/documentation/src/stories/components/chip/chip.docs.mdx b/packages/documentation/src/stories/components/chip/chip.docs.mdx index cc80ac60f0..ea35a40e7f 100644 --- a/packages/documentation/src/stories/components/chip/chip.docs.mdx +++ b/packages/documentation/src/stories/components/chip/chip.docs.mdx @@ -1,36 +1,38 @@ import { Canvas, Controls, Meta } from '@storybook/blocks'; import { PostAlert } from '@swisspost/design-system-components-react'; -import * as chipStories from './chip.stories'; +import * as ChipStories from './chip.stories'; import StylesPackageImport from '../../../shared/styles-package-import.mdx'; - + # Chip
- Documentation and examples for chips, our small count and labeling component. + Display small pieces of information with which users can interact.
- +
- +
## Examples -### Checkable +### Filter Chip -Checkable chips are nothing more than personalized checkboxes. -Therefore, you can handle then like standard checkboxes. +Filter chips provide a simple means to refine content or search results based on specific attributes. +They are personalized checkboxes, allowing users to toggle them to filter content effectively. - + -### Dismissible +### Dismissible Chip -Dismissible chips include a close button, allowing users to easily clear them from the page. -Because the close button does not have a visible text, -it should always include a visually hidden label to ensure accessibility for assistive technology users. +Dismissible chips represent pieces of information entered by a user. +Each chip includes a close button, enabling users to conveniently remove them from view. - +It's important to note that the close button lacks visible text. +Therefore, it's imperative to include a visually hidden label to ensure accessibility for users relying on assistive technologies. + + diff --git a/packages/documentation/src/stories/components/chip/chip.stories.ts b/packages/documentation/src/stories/components/chip/chip.stories.ts index f99b07ded5..6c27085de2 100644 --- a/packages/documentation/src/stories/components/chip/chip.stories.ts +++ b/packages/documentation/src/stories/components/chip/chip.stories.ts @@ -9,7 +9,6 @@ const meta: MetaComponent = { title: 'Components/Chip', tags: ['package:HTML'], render: renderChip, - decorators: [externalControl], parameters: { chips: [], }, @@ -149,8 +148,11 @@ function getDefaultContent(args: Args) { `; } +let index = 0; function getCheckableContent(args: Args, updateArgs: (args: Args) => void, context: StoryContext) { - const checkboxId = `chip-example--${context.name.replace(/ /g, '-').toLowerCase()}`; + index++; + + const checkboxId = `chip-example--${context.name.replace(/ /g, '-').toLowerCase()}` + index; const labelClasses = mapClasses({ 'chip-check-label': true, [args.size]: args.size !== 'large', @@ -170,6 +172,7 @@ function getCheckableContent(args: Args, updateArgs: (args: Args) => void, conte return html` html` +
+ ${renderChip({ ...args, checked: true, text: 'Ĉiuj' }, context)} + ${renderChip({ ...args, text: 'Filtru unu' }, context)} + ${renderChip({ ...args, text: 'Filtrilo du' }, context)} + ${renderChip({ ...args, text: 'Filtrilo tri' }, context)} +
+ `, args: { - text: 'Kontrolebla Insigno', interactionType: 'checkable', }, }; export const Dismissible: Story = { - parameters: { - controls: { - exclude: ['Interaction Type'], - }, - }, + render: ({ dismissed, ...args }, context) => html` +
+ ${renderChip({ ...args, text: 'Unua uzanta enigo' }, context)} + ${renderChip({ ...args, text: 'Dua uzanta enigo' }, context)} + ${renderChip({ ...args, text: 'Tria uzanta enigo' }, context)} + ${renderChip({ ...args, text: 'Fora uzanta enigo' }, context)} +
+ `, args: { - text: 'Malakceptebla Insigno', interactionType: 'dismissible', }, }; From 48550b2e3801ecf7856405eb6638e18a9c5b6b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Wed, 27 Mar 2024 15:34:40 +0100 Subject: [PATCH 06/37] revert: fix the version of the styles package in the demo app --- packages/demo/package.json | 2 +- pnpm-lock.yaml | 22 ++++------------------ 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/packages/demo/package.json b/packages/demo/package.json index baa1dc26f7..30f385ea10 100644 --- a/packages/demo/package.json +++ b/packages/demo/package.json @@ -27,7 +27,7 @@ "@swimlane/ngx-datatable": "20.1.0", "@swisspost/design-system-intranet-header": "workspace:5.0.11", "@swisspost/design-system-migrations": "workspace:1.0.2", - "@swisspost/design-system-styles": "6.6.3", + "@swisspost/design-system-styles": "workspace:6.6.4", "bootstrap": "5.3.2", "core-js": "3.36.1", "highlight.js": "11.9.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 30c87fc593..abe4d30a04 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -348,8 +348,8 @@ importers: specifier: workspace:1.0.2 version: link:../migrations '@swisspost/design-system-styles': - specifier: 6.6.3 - version: 6.6.3(@ng-bootstrap/ng-bootstrap@16.0.0)(bootstrap@5.3.2) + specifier: workspace:6.6.4 + version: link:../styles/dist bootstrap: specifier: 5.3.2 version: 5.3.2(@popperjs/core@2.11.8) @@ -8099,22 +8099,6 @@ packages: tslib: 2.6.2 dev: false - /@swisspost/design-system-styles@6.6.3(@ng-bootstrap/ng-bootstrap@16.0.0)(bootstrap@5.3.2): - resolution: {integrity: sha512-9BL3xK45gVeqi7HW94SaO6zSI5+NZ9nK9GZzjDJD3TSPIeJlQ57+8NpgQDVgDU6p/kliX0IsA8APi8INiQ9/dg==} - peerDependencies: - '@ng-bootstrap/ng-bootstrap': ^15.0.0 - bootstrap: ~5.3.0 - peerDependenciesMeta: - '@ng-bootstrap/ng-bootstrap': - optional: true - bootstrap: - optional: true - dependencies: - '@ng-bootstrap/ng-bootstrap': 16.0.0(@angular/common@17.3.0)(@angular/core@17.3.0)(@angular/forms@17.3.0)(@angular/localize@17.3.0)(@popperjs/core@2.11.8)(rxjs@7.8.1) - '@popperjs/core': 2.11.8 - bootstrap: 5.3.2(@popperjs/core@2.11.8) - dev: false - /@testing-library/dom@9.3.1: resolution: {integrity: sha512-0DGPd9AR3+iDTjGoMpxIkAsUihHZ3Ai6CneU6bRRrffXMgzCdlNk43jTrD2/5LT6CBb3MWTP8v510JzYtahD2w==} engines: {node: '>=14'} @@ -16868,6 +16852,8 @@ packages: peerDependenciesMeta: webpack: optional: true + webpack-sources: + optional: true dependencies: webpack: 5.90.3(esbuild@0.20.1) webpack-sources: 3.2.3 From 8747c5ab500b5f62777c088ad1d7bfcf8403f2cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Wed, 27 Mar 2024 15:36:47 +0100 Subject: [PATCH 07/37] Fix code smells --- packages/styles/src/components/form-check.scss | 2 +- packages/styles/src/components/form-range.scss | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/styles/src/components/form-check.scss b/packages/styles/src/components/form-check.scss index 3c2e04a969..c89f83fd74 100644 --- a/packages/styles/src/components/form-check.scss +++ b/packages/styles/src/components/form-check.scss @@ -18,7 +18,7 @@ @include utility-mx.focus-style(); @include utility-mx.focus-style-custom() { border-radius: commons.$border-radius !important; - }; + } &-inline { display: inline-flex; diff --git a/packages/styles/src/components/form-range.scss b/packages/styles/src/components/form-range.scss index 6e53527e92..efcdf46908 100644 --- a/packages/styles/src/components/form-range.scss +++ b/packages/styles/src/components/form-range.scss @@ -18,7 +18,7 @@ $webkit-thumb-width: 32px; @include utilities.focus-style(); @include utilities.focus-style-custom() { border-radius: commons.$border-radius !important; - }; + } } @supports not selector(:has(> .form-range)) { @@ -26,7 +26,7 @@ $webkit-thumb-width: 32px; @include utilities.focus-style(); @include utilities.focus-style-custom() { border-radius: commons.$border-radius !important; - }; + } } } From 5030123f3040bfbd559adb6ec82d6b20b654bd77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 21 Mar 2024 10:44:25 +0100 Subject: [PATCH 08/37] feat(docs): update badges documentation --- .../background-colors.module.scss} | 0 .../stories/components/badge/badge.docs.mdx | 35 ++- .../stories/components/badge/badge.stories.ts | 234 +++++------------- .../cards/card-button/card-button.stories.ts | 4 +- packages/styles/src/components/badge.scss | 103 ++------ .../src/variables/components/_badge.scss | 42 ++-- 6 files changed, 135 insertions(+), 283 deletions(-) rename packages/documentation/src/{stories/components/cards/card-button/card-button.module.scss => shared/background-colors.module.scss} (100%) diff --git a/packages/documentation/src/stories/components/cards/card-button/card-button.module.scss b/packages/documentation/src/shared/background-colors.module.scss similarity index 100% rename from packages/documentation/src/stories/components/cards/card-button/card-button.module.scss rename to packages/documentation/src/shared/background-colors.module.scss diff --git a/packages/documentation/src/stories/components/badge/badge.docs.mdx b/packages/documentation/src/stories/components/badge/badge.docs.mdx index b46b72edd1..743c5fbabc 100644 --- a/packages/documentation/src/stories/components/badge/badge.docs.mdx +++ b/packages/documentation/src/stories/components/badge/badge.docs.mdx @@ -11,17 +11,6 @@ import StylesPackageImport from '../../../shared/styles-package-import.mdx'; Documentation and examples for badges, our small count and labeling component.
- -

Badge is deprecated

-

- The current `badge` component is deprecated and will be replaced with the `chip` component which will behave similarly to the current `badge` component. - There will also be a new `badge` component, but with a different behavior. Check out the new components in figma: - [Chip](https://www.figma.com/file/xZ0IW0MJO0vnFicmrHiKaY/Components-Post?type=design&node-id=11194-50777&mode=design&t=SeiMf2Vt3dmUnpMT-0) - / - [Badge](https://www.figma.com/file/xZ0IW0MJO0vnFicmrHiKaY/Components-Post?type=design&node-id=11038-51303&mode=design&t=SeiMf2Vt3dmUnpMT-0) -

-
-
@@ -31,17 +20,23 @@ import StylesPackageImport from '../../../shared/styles-package-import.mdx'; ## Examples -### Checkable +### Colors + +You can change the badge color simply by applying a `.bg-*` class to it. +See all available classes in the [background utilities documentation](/?path=/docs/60852fac-a861-4415-8276-bd38d68653bb--docs). + + + +### Large number -Checkable badges are nothing more than personalized checkboxes. -Therefore, you can handle then like standard checkboxes. +A large number will extend the badge with. +To prevent the badge from being too large you can simply use the `+` notation as shown hereafter. - + -### Dismissible +### Position -Dismissible badges include a close button, allowing users to easily clear them from the page. -Because the close button does not have a visible text, -it should always include a visually hidden label to ensure accessibility for assistive technology users. +As inline elements, the badges can be placed inside other element such as tags. +They can also be place absolutely to appear above other elements such as icons for example. - + diff --git a/packages/documentation/src/stories/components/badge/badge.stories.ts b/packages/documentation/src/stories/components/badge/badge.stories.ts index 2be92512ef..66a0282bea 100644 --- a/packages/documentation/src/stories/components/badge/badge.stories.ts +++ b/packages/documentation/src/stories/components/badge/badge.stories.ts @@ -1,32 +1,40 @@ -import { useArgs } from '@storybook/preview-api'; -import type { Args, StoryContext, StoryObj } from '@storybook/web-components'; +import { Args, StoryContext, StoryFn, StoryObj } from '@storybook/web-components'; import { html, nothing } from 'lit'; -import { mapClasses } from '../../../utils'; import { MetaComponent } from '../../../../types'; +import backgroundColors from '../../../shared/background-colors.module.scss'; const meta: MetaComponent = { id: 'bec68e8b-445e-4760-8bd7-1b9970206d8d', title: 'Components/Badge', tags: ['package:HTML'], render: renderBadge, - decorators: [externalControl], - parameters: { - badges: [], - }, + decorators: [adaptiveBackground], args: { - text: 'Insigno', - size: 'default', - nestedBadge: false, - interactionType: 'none', - checked: false, - dismissed: false, + showNumber: true, + number: 1, + size: 'large', }, argTypes: { - text: { - name: 'Text', - description: 'The text contained in the badge.', + showNumber: { + name: 'Show Number', + description: 'If `true`, the badge contains a number otherwise it is empty.', + control: { + type: 'boolean', + }, + table: { + category: 'Content', + }, + }, + number: { + name: 'Number', + description: 'The number contained in the badge.', + if: { + arg: 'showNumber', + truthy: true, + }, control: { - type: 'text', + type: 'number', + min: 0, }, table: { category: 'Content', @@ -35,161 +43,50 @@ const meta: MetaComponent = { size: { name: 'Size', description: 'The size of the badge.', + if: { + arg: 'showNumber', + truthy: true, + }, control: { type: 'radio', labels: { - 'default': 'Default', + 'large': 'Large', 'badge-sm': 'Small', }, }, - options: ['default', 'badge-sm'], + options: ['large', 'badge-sm'], table: { category: 'General', }, }, - nestedBadge: { - name: 'Nested Badge', - description: 'If `true`, a nested badge is displayed inside the main badge.', + background: { + name: 'Backround', + description: 'You can use the Background classes to color the cards', control: { - type: 'boolean', + type: 'select', }, + options: Object.keys(backgroundColors), table: { category: 'General', }, }, - interactionType: { - name: 'Interaction Type', - description: 'Defines how the badge can be interacted with.', - control: { - type: 'inline-radio', - labels: { - none: 'None', - checkable: 'Checkable', - dismissible: 'Dismissible', - }, - }, - options: ['none', 'checkable', 'dismissible'], - table: { - category: 'Interactions', - }, - }, - checked: { - name: 'Checked', - description: 'If `true`, the badge is checked otherwise it is unchecked.', - if: { - arg: 'interactionType', - eq: 'checkable', - }, - control: { - type: 'boolean', - }, - table: { - category: 'Interactions', - }, - }, - dismissed: { - name: 'Dismissed', - description: 'If `true`, the badge is removed from the page otherwise it is displayed.', - if: { - arg: 'interactionType', - eq: 'dismissible', - }, - control: { - type: 'boolean', - }, - table: { - category: 'Interactions', - }, - }, }, }; export default meta; // DECORATORS -function externalControl(story: any, { args }: StoryContext) { - const [_, updateArgs] = useArgs(); - - const button = html` - - Show badge - - `; - - return html` ${args.dismissed ? button : nothing} ${story()} `; +function adaptiveBackground(story: StoryFn, { args, context }: StoryContext) { + const bgClass = args.background === 'bg-white' ? ` bg-dark` : ''; + return html`
${story(args, context)}
`; } // RENDERER -function getDefaultContent(args: Args) { - return html` - ${args.text} - ${args.nestedBadge ? html` 10 ` : nothing} - `; -} - -function getCheckableContent(args: Args, updateArgs: (args: Args) => void, context: StoryContext) { - const checkboxId = `badge-example--${context.name.replace(/ /g, '-').toLowerCase()}`; - const labelClasses = mapClasses({ - 'badge-check-label': true, - [args.size]: args.size !== 'default', - }); - - const handleChange = (e: Event) => { - updateArgs({ checked: !args.checked }); - - if (document.activeElement === e.target) { - setTimeout(() => { - const element: HTMLInputElement | null = document.querySelector(`#${checkboxId}`); - if (element) element.focus(); - }, 25); - } - }; - - return html` - - - `; -} - -function getDismissButton(updateArgs: (args: Args) => void) { +function renderBadge(args: Args) { + const sizingClass = args.showNumber && args.size !== 'large' ? ` ${args.size}` : ''; + const bgClass = args.background && args.background !== 'bg-danger' ? ` ${args.background}` : ''; return html` - - `; -} - -function renderBadge(args: Args, context: StoryContext) { - const [_, updateArgs] = useArgs(); - - if (args.dismissed) return html` ${nothing} `; - - const isCheckable = args.interactionType === 'checkable'; - const isDismissible = args.interactionType === 'dismissible'; - - const badgeClasses = mapClasses({ - 'badge': !isCheckable, - 'badge-check': isCheckable, - [args.size]: args.size !== 'default' && !isCheckable, - }); - - return html` -
- ${isCheckable ? getCheckableContent(args, updateArgs, context) : getDefaultContent(args)} - ${isDismissible ? getDismissButton(updateArgs) : nothing} -
+
${args.showNumber ? args.number : nothing}
`; } @@ -198,26 +95,31 @@ type Story = StoryObj; export const Default: Story = {}; -export const Checkable: Story = { - parameters: { - controls: { - exclude: ['Interaction Type'], - }, - }, - args: { - text: 'Kontrolebla Insigno', - interactionType: 'checkable', - }, +export const Colors: Story = { + render: args => html` + ${renderBadge({ ...args, background: 'bg-success' })} + ${renderBadge({ ...args, background: 'bg-warning' })} + ${renderBadge({ ...args, background: 'bg-yellow' })} + ${renderBadge({ ...args, background: 'bg-light' })} + `, }; -export const Dismissible: Story = { - parameters: { - controls: { - exclude: ['Interaction Type'], - }, - }, - args: { - text: 'Malakceptebla Insigno', - interactionType: 'dismissible', - }, +export const LargeNumber: Story = { + render: args => html` + ${renderBadge({ ...args, number: 256 })} ${renderBadge({ ...args, number: '+99' })} + `, +}; + +export const Position: Story = { + render: args => html` + + Filter +
1
+
+ +
+ +
3
+
+ `, }; diff --git a/packages/documentation/src/stories/components/cards/card-button/card-button.stories.ts b/packages/documentation/src/stories/components/cards/card-button/card-button.stories.ts index 9b9757a4e9..8ea937dff0 100644 --- a/packages/documentation/src/stories/components/cards/card-button/card-button.stories.ts +++ b/packages/documentation/src/stories/components/cards/card-button/card-button.stories.ts @@ -1,8 +1,8 @@ import { Args, StoryObj } from '@storybook/web-components'; import { html } from 'lit'; import { useArgs } from '@storybook/preview-api'; -import scss from './card-button.module.scss'; import { MetaComponent } from '../../../../../types'; +import backgroundColors from '../../../../shared/background-colors.module.scss'; const meta: MetaComponent = { id: '6f8f76ec-a2b5-4eb0-87f7-4021e1a5b8d0', @@ -64,7 +64,7 @@ const meta: MetaComponent = { control: { type: 'select', }, - options: Object.keys(scss), + options: Object.keys(backgroundColors), table: { category: 'General', }, diff --git a/packages/styles/src/components/badge.scss b/packages/styles/src/components/badge.scss index cc7ed9dbd9..d10f87c15a 100644 --- a/packages/styles/src/components/badge.scss +++ b/packages/styles/src/components/badge.scss @@ -1,85 +1,36 @@ @forward './../variables/options'; -@use './../lic/bootstrap-license'; -@use './../themes/bootstrap/core' as *; -@use './../themes/bootstrap/badge' as bb; - +@use './../mixins/color' as color-mx; @use './../variables/components/badge'; -@use './../variables/components/forms'; -@use './../variables/components/form-check'; -@use './../variables/color'; -@use './../mixins/utilities'; -@use './../mixins/forms' as forms-mx; -@use './../mixins/badge' as badge-mx; -@use './../placeholders/badge' as badge-ph; -@use './../functions/icons' as icons-fn; .badge { - @extend %badge; -} - -a, -button { - &.badge { - @include forms-mx.focus-outline; - background-color: transparent; - text-decoration: none; - transition: badge.$badge-transition; - - @include utilities.not-disabled-focus-hover { - @include badge-mx.badge-hover-state; - } - - &:active, - &.active { - @include badge-mx.badge-active-state; - } - } -} - -.badge-check { - &-label { - @extend %badge; - @include forms-mx.focus-outline; - transition: badge.$badge-transition; - cursor: pointer; - } - - &-input { - @include utilities.visuallyhidden; - } - - &-input:focus-visible + &-label { - outline-offset: forms.$input-focus-outline-thickness; - outline: forms.$input-focus-outline-thickness solid var(--post-contrast-color); - } - - &-input:not(:checked) + &-label:hover { - @include badge-mx.badge-hover-state; - } - - &-input:checked + &-label { - @include badge-mx.badge-active-state; + --post-badge-height: #{badge.$badge-height}; + --post-badge-padding-x: #{badge.$badge-padding-x}; + + display: inline-flex; + align-items: center; + justify-content: center; + box-sizing: content-box; + height: var(--post-badge-height); + min-width: calc(var(--post-badge-height) - 2 * var(--post-badge-padding-x)); + padding-inline: var(--post-badge-padding-x); + border: badge.$badge-border-width solid badge.$badge-border-color; + border-radius: badge.$badge-border-radius; + line-height: badge.$badge-line-height; + font-size: badge.$badge-font-size; + background-color: badge.$badge-bg; + color: badge.$badge-color; + + &:empty { + --post-badge-height: #{badge.$badge-height-empty}; + --post-badge-padding-x: #{badge.$badge-padding-x-empty}; + border-width: badge.$badge-border-width-empty; } } -@include utilities.high-contrast-mode() { - .badge-check { - &-input:focus-visible + &-label { - border-color: Highlight; - outline-color: Highlight; - } - - &-input:checked + &-label { - &:hover { - @include badge-mx.badge-hover-state; - } - } - } - - button.badge, - a.badge, - .badge-check-label { - transition: none; - } +.badge-sm { + --post-badge-height: #{badge.$badge-height-sm}; + --post-badge-padding-x: #{badge.$badge-padding-x-sm}; + border-width: badge.$badge-border-width-sm; + font-size: badge.$badge-font-size-sm; } diff --git a/packages/styles/src/variables/components/_badge.scss b/packages/styles/src/variables/components/_badge.scss index d47f01e4fe..9214196eeb 100644 --- a/packages/styles/src/variables/components/_badge.scss +++ b/packages/styles/src/variables/components/_badge.scss @@ -1,19 +1,34 @@ -@use 'sass:math'; - -@use './button'; -@use './../animation'; @use './../color'; @use './../commons'; @use './../spacing'; @use './../type'; +@use './button'; @use './../../functions/sizing'; -// Design System custom variables -$badge-height: button.$btn-height-rg; -$badge-gap: spacing.$size-mini; -$badge-border-color: var(--post-gray-60); +$badge-border-radius: 50rem; +$badge-line-height: type.$line-height-copy; +$badge-color: color.$white; +$badge-bg: color.$error-red; +$badge-border-color: color.$white; + +$badge-height: spacing.$size-large; +$badge-height-sm: spacing.$size-regular; +$badge-height-empty: spacing.$size-mini; + +$badge-padding-x: spacing.$size-mini; +$badge-padding-x-sm: spacing.$size-micro; +$badge-padding-x-empty: 0%; // needs a unit for the calculated min-width + $badge-border-width: commons.$border-thick; +$badge-border-width-sm: commons.$border-width; +$badge-border-width-empty: commons.$border-width; + +$badge-font-size: type.$font-size-12; +$badge-font-size-sm: 10px; + +// DEPRECATED +$badge-gap: spacing.$size-mini; $badge-transition: color 250ms, background-color 250ms, @@ -22,11 +37,7 @@ $badge-hover-color: color.$black; $badge-hover-bg-color: color.$gray-10; $badge-active-color: color.$black; $badge-active-bg-color: color.$yellow; - -$badge-height-sm: button.$btn-height-sm; $badge-gap-sm: sizing.px-to-rem(6px); -$badge-font-size-sm: type.$font-size-tiny; - $badge-nested-height: sizing.px-to-rem(22px); $badge-nested-color: color.$gray-60; $badge-nested-bg-color: color.$gray-10; @@ -35,14 +46,7 @@ $badge-nested-font-size: sizing.px-to-rem(10px); $badge-nested-translate-x: ($badge-height - $badge-nested-height) * 0.5; $badge-nested-active-bg-color: color.$white; $badge-nested-translate-x-sm: ($badge-height-sm - $badge-nested-height) * 0.5; - $badge-check-input-height: spacing.$size-small-large; $badge-check-input-bg-color: color.$white; - -// Bootstrap variables -$badge-font-size: type.$font-size-small; $badge-font-weight: type.$font-weight-normal; -$badge-color: var(--post-gray-80); $badge-padding-y: 0; -$badge-padding-x: spacing.$size-regular - sizing.px-to-rem($badge-border-width); -$badge-border-radius: 50rem; From 3aa0c260f8f82c24e3d3a2ae484fc882fd5ad05d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 21 Mar 2024 10:44:25 +0100 Subject: [PATCH 09/37] feat(docs): update badges documentation --- .changeset/dry-wasps-film.md | 6 + .../background-colors.module.scss} | 0 .../stories/components/badge/badge.docs.mdx | 35 ++- .../badge/badge.snapshot.stories.ts | 12 +- .../stories/components/badge/badge.stories.ts | 239 ++++++------------ .../cards/card-button/card-button.stories.ts | 4 +- packages/styles/src/components/badge.scss | 109 +++----- .../src/variables/components/_badge.scss | 42 +-- 8 files changed, 156 insertions(+), 291 deletions(-) create mode 100644 .changeset/dry-wasps-film.md rename packages/documentation/src/{stories/components/cards/card-button/card-button.module.scss => shared/background-colors.module.scss} (100%) diff --git a/.changeset/dry-wasps-film.md b/.changeset/dry-wasps-film.md new file mode 100644 index 0000000000..335ab35008 --- /dev/null +++ b/.changeset/dry-wasps-film.md @@ -0,0 +1,6 @@ +--- +'@swisspost/design-system-styles': major +'@swisspost/design-system-documentation': patch +--- + +Restricted the badge to showing counts only and updated the styles accordingly. diff --git a/packages/documentation/src/stories/components/cards/card-button/card-button.module.scss b/packages/documentation/src/shared/background-colors.module.scss similarity index 100% rename from packages/documentation/src/stories/components/cards/card-button/card-button.module.scss rename to packages/documentation/src/shared/background-colors.module.scss diff --git a/packages/documentation/src/stories/components/badge/badge.docs.mdx b/packages/documentation/src/stories/components/badge/badge.docs.mdx index b46b72edd1..743c5fbabc 100644 --- a/packages/documentation/src/stories/components/badge/badge.docs.mdx +++ b/packages/documentation/src/stories/components/badge/badge.docs.mdx @@ -11,17 +11,6 @@ import StylesPackageImport from '../../../shared/styles-package-import.mdx'; Documentation and examples for badges, our small count and labeling component.
- -

Badge is deprecated

-

- The current `badge` component is deprecated and will be replaced with the `chip` component which will behave similarly to the current `badge` component. - There will also be a new `badge` component, but with a different behavior. Check out the new components in figma: - [Chip](https://www.figma.com/file/xZ0IW0MJO0vnFicmrHiKaY/Components-Post?type=design&node-id=11194-50777&mode=design&t=SeiMf2Vt3dmUnpMT-0) - / - [Badge](https://www.figma.com/file/xZ0IW0MJO0vnFicmrHiKaY/Components-Post?type=design&node-id=11038-51303&mode=design&t=SeiMf2Vt3dmUnpMT-0) -

-
-
@@ -31,17 +20,23 @@ import StylesPackageImport from '../../../shared/styles-package-import.mdx'; ## Examples -### Checkable +### Colors + +You can change the badge color simply by applying a `.bg-*` class to it. +See all available classes in the [background utilities documentation](/?path=/docs/60852fac-a861-4415-8276-bd38d68653bb--docs). + + + +### Large number -Checkable badges are nothing more than personalized checkboxes. -Therefore, you can handle then like standard checkboxes. +A large number will extend the badge with. +To prevent the badge from being too large you can simply use the `+` notation as shown hereafter. - + -### Dismissible +### Position -Dismissible badges include a close button, allowing users to easily clear them from the page. -Because the close button does not have a visible text, -it should always include a visually hidden label to ensure accessibility for assistive technology users. +As inline elements, the badges can be placed inside other element such as tags. +They can also be place absolutely to appear above other elements such as icons for example. - + diff --git a/packages/documentation/src/stories/components/badge/badge.snapshot.stories.ts b/packages/documentation/src/stories/components/badge/badge.snapshot.stories.ts index 3a90dca504..2181c8b0c6 100644 --- a/packages/documentation/src/stories/components/badge/badge.snapshot.stories.ts +++ b/packages/documentation/src/stories/components/badge/badge.snapshot.stories.ts @@ -20,17 +20,11 @@ export const Badge: Story = { bg => html`
${bombArgs({ - text: [ - 'Malakceptebla Insigno', - 'Contentus momentus vero siteos et accusam iretea et justo.', - ], + showNumber: [true, false], size: context.argTypes.size.options, - interactionType: context.argTypes.interactionType.options, - nestedBadge: [false, true], - checked: [false, true], - dismissed: [false], + background: context.argTypes.background.options, }) - .filter(args => !(args.interactionType !== 'checkable' && args.checked === true)) + .filter(args => !(!args.showNumber && args.size === 'small')) .map((args: Args) => meta.render?.({ ...context.args, ...args }, context))}
`, diff --git a/packages/documentation/src/stories/components/badge/badge.stories.ts b/packages/documentation/src/stories/components/badge/badge.stories.ts index 2be92512ef..55549f5773 100644 --- a/packages/documentation/src/stories/components/badge/badge.stories.ts +++ b/packages/documentation/src/stories/components/badge/badge.stories.ts @@ -1,32 +1,40 @@ -import { useArgs } from '@storybook/preview-api'; -import type { Args, StoryContext, StoryObj } from '@storybook/web-components'; +import { Args, StoryContext, StoryFn, StoryObj } from '@storybook/web-components'; import { html, nothing } from 'lit'; -import { mapClasses } from '../../../utils'; import { MetaComponent } from '../../../../types'; +import backgroundColors from '../../../shared/background-colors.module.scss'; const meta: MetaComponent = { id: 'bec68e8b-445e-4760-8bd7-1b9970206d8d', title: 'Components/Badge', tags: ['package:HTML'], render: renderBadge, - decorators: [externalControl], - parameters: { - badges: [], - }, + decorators: [adaptiveBackground], args: { - text: 'Insigno', - size: 'default', - nestedBadge: false, - interactionType: 'none', - checked: false, - dismissed: false, + showNumber: true, + number: 1, + size: 'large', }, argTypes: { - text: { - name: 'Text', - description: 'The text contained in the badge.', + showNumber: { + name: 'Show Number', + description: 'If `true`, the badge contains a number otherwise it is empty.', + control: { + type: 'boolean', + }, + table: { + category: 'Content', + }, + }, + number: { + name: 'Number', + description: 'The number contained in the badge.', + if: { + arg: 'showNumber', + truthy: true, + }, control: { - type: 'text', + type: 'number', + min: 0, }, table: { category: 'Content', @@ -35,161 +43,50 @@ const meta: MetaComponent = { size: { name: 'Size', description: 'The size of the badge.', + if: { + arg: 'showNumber', + truthy: true, + }, control: { type: 'radio', labels: { - 'default': 'Default', + 'large': 'Large', 'badge-sm': 'Small', }, }, - options: ['default', 'badge-sm'], + options: ['large', 'badge-sm'], table: { category: 'General', }, }, - nestedBadge: { - name: 'Nested Badge', - description: 'If `true`, a nested badge is displayed inside the main badge.', + background: { + name: 'Backround', + description: 'You can use the Background classes to color the cards', control: { - type: 'boolean', + type: 'select', }, + options: Object.keys(backgroundColors), table: { category: 'General', }, }, - interactionType: { - name: 'Interaction Type', - description: 'Defines how the badge can be interacted with.', - control: { - type: 'inline-radio', - labels: { - none: 'None', - checkable: 'Checkable', - dismissible: 'Dismissible', - }, - }, - options: ['none', 'checkable', 'dismissible'], - table: { - category: 'Interactions', - }, - }, - checked: { - name: 'Checked', - description: 'If `true`, the badge is checked otherwise it is unchecked.', - if: { - arg: 'interactionType', - eq: 'checkable', - }, - control: { - type: 'boolean', - }, - table: { - category: 'Interactions', - }, - }, - dismissed: { - name: 'Dismissed', - description: 'If `true`, the badge is removed from the page otherwise it is displayed.', - if: { - arg: 'interactionType', - eq: 'dismissible', - }, - control: { - type: 'boolean', - }, - table: { - category: 'Interactions', - }, - }, }, }; export default meta; // DECORATORS -function externalControl(story: any, { args }: StoryContext) { - const [_, updateArgs] = useArgs(); - - const button = html` - - Show badge - - `; - - return html` ${args.dismissed ? button : nothing} ${story()} `; +function adaptiveBackground(story: StoryFn, { args, context }: StoryContext) { + const bgClass = args.background === 'bg-white' ? ` bg-dark` : ''; + return html`
${story(args, context)}
`; } // RENDERER -function getDefaultContent(args: Args) { - return html` - ${args.text} - ${args.nestedBadge ? html` 10 ` : nothing} - `; -} - -function getCheckableContent(args: Args, updateArgs: (args: Args) => void, context: StoryContext) { - const checkboxId = `badge-example--${context.name.replace(/ /g, '-').toLowerCase()}`; - const labelClasses = mapClasses({ - 'badge-check-label': true, - [args.size]: args.size !== 'default', - }); - - const handleChange = (e: Event) => { - updateArgs({ checked: !args.checked }); - - if (document.activeElement === e.target) { - setTimeout(() => { - const element: HTMLInputElement | null = document.querySelector(`#${checkboxId}`); - if (element) element.focus(); - }, 25); - } - }; - - return html` - - - `; -} - -function getDismissButton(updateArgs: (args: Args) => void) { - return html` - - `; -} - -function renderBadge(args: Args, context: StoryContext) { - const [_, updateArgs] = useArgs(); - - if (args.dismissed) return html` ${nothing} `; - - const isCheckable = args.interactionType === 'checkable'; - const isDismissible = args.interactionType === 'dismissible'; - - const badgeClasses = mapClasses({ - 'badge': !isCheckable, - 'badge-check': isCheckable, - [args.size]: args.size !== 'default' && !isCheckable, - }); - +function renderBadge(args: Args) { + const sizingClass = args.showNumber && args.size !== 'large' ? ` ${args.size}` : ''; + const bgClass = args.background && args.background !== 'bg-danger' ? ` ${args.background}` : ''; return html` -
- ${isCheckable ? getCheckableContent(args, updateArgs, context) : getDefaultContent(args)} - ${isDismissible ? getDismissButton(updateArgs) : nothing} -
+
${args.showNumber ? args.number : nothing}
`; } @@ -198,26 +95,36 @@ type Story = StoryObj; export const Default: Story = {}; -export const Checkable: Story = { - parameters: { - controls: { - exclude: ['Interaction Type'], - }, - }, - args: { - text: 'Kontrolebla Insigno', - interactionType: 'checkable', - }, +export const Colors: Story = { + render: args => html` + ${renderBadge({ ...args, background: 'bg-success' })} + ${renderBadge({ ...args, background: 'bg-warning' })} + ${renderBadge({ ...args, background: 'bg-yellow' })} + ${renderBadge({ ...args, background: 'bg-light' })} + `, }; -export const Dismissible: Story = { - parameters: { - controls: { - exclude: ['Interaction Type'], - }, - }, - args: { - text: 'Malakceptebla Insigno', - interactionType: 'dismissible', - }, +export const LargeNumber: Story = { + render: args => html` + ${renderBadge({ ...args, number: 256 })} ${renderBadge({ ...args, number: '+99' })} + `, +}; + +export const Position: Story = { + render: args => html` +
+ Filter +
1
+
+ +
+ +
3
+
+ `, + decorators: [ + (story: StoryFn, { args, context }: StoryContext) => html` +
${story(args, context)}
+ `, + ], }; diff --git a/packages/documentation/src/stories/components/cards/card-button/card-button.stories.ts b/packages/documentation/src/stories/components/cards/card-button/card-button.stories.ts index 9b9757a4e9..8ea937dff0 100644 --- a/packages/documentation/src/stories/components/cards/card-button/card-button.stories.ts +++ b/packages/documentation/src/stories/components/cards/card-button/card-button.stories.ts @@ -1,8 +1,8 @@ import { Args, StoryObj } from '@storybook/web-components'; import { html } from 'lit'; import { useArgs } from '@storybook/preview-api'; -import scss from './card-button.module.scss'; import { MetaComponent } from '../../../../../types'; +import backgroundColors from '../../../../shared/background-colors.module.scss'; const meta: MetaComponent = { id: '6f8f76ec-a2b5-4eb0-87f7-4021e1a5b8d0', @@ -64,7 +64,7 @@ const meta: MetaComponent = { control: { type: 'select', }, - options: Object.keys(scss), + options: Object.keys(backgroundColors), table: { category: 'General', }, diff --git a/packages/styles/src/components/badge.scss b/packages/styles/src/components/badge.scss index cc7ed9dbd9..9a5a88874d 100644 --- a/packages/styles/src/components/badge.scss +++ b/packages/styles/src/components/badge.scss @@ -1,85 +1,44 @@ @forward './../variables/options'; -@use './../lic/bootstrap-license'; -@use './../themes/bootstrap/core' as *; -@use './../themes/bootstrap/badge' as bb; - +@use './../mixins/color' as color-mx; @use './../variables/components/badge'; -@use './../variables/components/forms'; -@use './../variables/components/form-check'; -@use './../variables/color'; -@use './../mixins/utilities'; -@use './../mixins/forms' as forms-mx; -@use './../mixins/badge' as badge-mx; -@use './../placeholders/badge' as badge-ph; -@use './../functions/icons' as icons-fn; .badge { - @extend %badge; -} - -a, -button { - &.badge { - @include forms-mx.focus-outline; - background-color: transparent; - text-decoration: none; - transition: badge.$badge-transition; - - @include utilities.not-disabled-focus-hover { - @include badge-mx.badge-hover-state; - } - - &:active, - &.active { - @include badge-mx.badge-active-state; - } + --post-badge-height: #{badge.$badge-height}; + --post-badge-padding-x: #{badge.$badge-padding-x}; + + display: inline-flex; + align-items: center; + justify-content: center; + box-sizing: content-box; + height: var(--post-badge-height); + min-width: calc(var(--post-badge-height) - 2 * var(--post-badge-padding-x)); + padding-inline: var(--post-badge-padding-x); + border: badge.$badge-border-width solid badge.$badge-border-color; + border-radius: badge.$badge-border-radius; + line-height: badge.$badge-line-height; + font-size: badge.$badge-font-size; + background-color: badge.$badge-bg; + color: badge.$badge-color; + + &:empty { + --post-badge-height: #{badge.$badge-height-empty}; + --post-badge-padding-x: #{badge.$badge-padding-x-empty}; + border-width: badge.$badge-border-width-empty; + + // prevent blurry border effect + outline: badge.$badge-border-width solid badge.$badge-border-color; + outline-offset: -1 * badge.$badge-border-width; } } -.badge-check { - &-label { - @extend %badge; - @include forms-mx.focus-outline; - transition: badge.$badge-transition; - cursor: pointer; - } - - &-input { - @include utilities.visuallyhidden; - } - - &-input:focus-visible + &-label { - outline-offset: forms.$input-focus-outline-thickness; - outline: forms.$input-focus-outline-thickness solid var(--post-contrast-color); - } +.badge-sm { + --post-badge-height: #{badge.$badge-height-sm}; + --post-badge-padding-x: #{badge.$badge-padding-x-sm}; + border-width: badge.$badge-border-width-sm; + font-size: badge.$badge-font-size-sm; - &-input:not(:checked) + &-label:hover { - @include badge-mx.badge-hover-state; - } - - &-input:checked + &-label { - @include badge-mx.badge-active-state; - } -} - -@include utilities.high-contrast-mode() { - .badge-check { - &-input:focus-visible + &-label { - border-color: Highlight; - outline-color: Highlight; - } - - &-input:checked + &-label { - &:hover { - @include badge-mx.badge-hover-state; - } - } - } - - button.badge, - a.badge, - .badge-check-label { - transition: none; - } + // prevent blurry border effect + outline: badge.$badge-border-width-sm solid badge.$badge-border-color; + outline-offset: -1 * badge.$badge-border-width-sm; } diff --git a/packages/styles/src/variables/components/_badge.scss b/packages/styles/src/variables/components/_badge.scss index d47f01e4fe..9214196eeb 100644 --- a/packages/styles/src/variables/components/_badge.scss +++ b/packages/styles/src/variables/components/_badge.scss @@ -1,19 +1,34 @@ -@use 'sass:math'; - -@use './button'; -@use './../animation'; @use './../color'; @use './../commons'; @use './../spacing'; @use './../type'; +@use './button'; @use './../../functions/sizing'; -// Design System custom variables -$badge-height: button.$btn-height-rg; -$badge-gap: spacing.$size-mini; -$badge-border-color: var(--post-gray-60); +$badge-border-radius: 50rem; +$badge-line-height: type.$line-height-copy; +$badge-color: color.$white; +$badge-bg: color.$error-red; +$badge-border-color: color.$white; + +$badge-height: spacing.$size-large; +$badge-height-sm: spacing.$size-regular; +$badge-height-empty: spacing.$size-mini; + +$badge-padding-x: spacing.$size-mini; +$badge-padding-x-sm: spacing.$size-micro; +$badge-padding-x-empty: 0%; // needs a unit for the calculated min-width + $badge-border-width: commons.$border-thick; +$badge-border-width-sm: commons.$border-width; +$badge-border-width-empty: commons.$border-width; + +$badge-font-size: type.$font-size-12; +$badge-font-size-sm: 10px; + +// DEPRECATED +$badge-gap: spacing.$size-mini; $badge-transition: color 250ms, background-color 250ms, @@ -22,11 +37,7 @@ $badge-hover-color: color.$black; $badge-hover-bg-color: color.$gray-10; $badge-active-color: color.$black; $badge-active-bg-color: color.$yellow; - -$badge-height-sm: button.$btn-height-sm; $badge-gap-sm: sizing.px-to-rem(6px); -$badge-font-size-sm: type.$font-size-tiny; - $badge-nested-height: sizing.px-to-rem(22px); $badge-nested-color: color.$gray-60; $badge-nested-bg-color: color.$gray-10; @@ -35,14 +46,7 @@ $badge-nested-font-size: sizing.px-to-rem(10px); $badge-nested-translate-x: ($badge-height - $badge-nested-height) * 0.5; $badge-nested-active-bg-color: color.$white; $badge-nested-translate-x-sm: ($badge-height-sm - $badge-nested-height) * 0.5; - $badge-check-input-height: spacing.$size-small-large; $badge-check-input-bg-color: color.$white; - -// Bootstrap variables -$badge-font-size: type.$font-size-small; $badge-font-weight: type.$font-weight-normal; -$badge-color: var(--post-gray-80); $badge-padding-y: 0; -$badge-padding-x: spacing.$size-regular - sizing.px-to-rem($badge-border-width); -$badge-border-radius: 50rem; From 7954f43e47cda0d93e831d58a54b579cabe2b5c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 28 Mar 2024 09:19:33 +0100 Subject: [PATCH 10/37] fix code smell --- .../src/stories/components/badge/badge.stories.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/documentation/src/stories/components/badge/badge.stories.ts b/packages/documentation/src/stories/components/badge/badge.stories.ts index 55549f5773..5a6240aecf 100644 --- a/packages/documentation/src/stories/components/badge/badge.stories.ts +++ b/packages/documentation/src/stories/components/badge/badge.stories.ts @@ -77,8 +77,8 @@ export default meta; // DECORATORS function adaptiveBackground(story: StoryFn, { args, context }: StoryContext) { - const bgClass = args.background === 'bg-white' ? ` bg-dark` : ''; - return html`
${story(args, context)}
`; + const bgClass = args.background === 'bg-white' ? `p-2 bg-dark` : 'p-2'; + return html`
${story(args, context)}
`; } // RENDERER From 7728f6e50c8a186bf28dc963c0e6f8327becce74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 28 Mar 2024 09:40:36 +0100 Subject: [PATCH 11/37] fix outline on empty badge --- packages/styles/src/components/badge.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/styles/src/components/badge.scss b/packages/styles/src/components/badge.scss index 9a5a88874d..07aa118425 100644 --- a/packages/styles/src/components/badge.scss +++ b/packages/styles/src/components/badge.scss @@ -27,8 +27,8 @@ border-width: badge.$badge-border-width-empty; // prevent blurry border effect - outline: badge.$badge-border-width solid badge.$badge-border-color; - outline-offset: -1 * badge.$badge-border-width; + outline: badge.$badge-border-width-empty solid badge.$badge-border-color; + outline-offset: -0.75 * badge.$badge-border-width-empty; } } @@ -40,5 +40,5 @@ // prevent blurry border effect outline: badge.$badge-border-width-sm solid badge.$badge-border-color; - outline-offset: -1 * badge.$badge-border-width-sm; + outline-offset: -0.75 * badge.$badge-border-width-sm; } From a34fa9d440e60c8e69eefcbafe7f5800ac10495f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 28 Mar 2024 10:07:03 +0100 Subject: [PATCH 12/37] Update documentation lead --- .../documentation/src/stories/components/badge/badge.docs.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/documentation/src/stories/components/badge/badge.docs.mdx b/packages/documentation/src/stories/components/badge/badge.docs.mdx index 743c5fbabc..d1ba0c3485 100644 --- a/packages/documentation/src/stories/components/badge/badge.docs.mdx +++ b/packages/documentation/src/stories/components/badge/badge.docs.mdx @@ -8,7 +8,7 @@ import StylesPackageImport from '../../../shared/styles-package-import.mdx'; # Badge
- Documentation and examples for badges, our small count and labeling component. + Highlight a numerical characteristic or mark an item with a status.
From c2e61671f4f2697aab99438ae6576fd937f5c08c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 28 Mar 2024 14:13:25 +0100 Subject: [PATCH 13/37] Update borders --- .../src/stories/components/badge/badge.stories.ts | 2 +- packages/styles/src/components/badge.scss | 12 +----------- packages/styles/src/variables/components/_badge.scss | 6 +----- 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/packages/documentation/src/stories/components/badge/badge.stories.ts b/packages/documentation/src/stories/components/badge/badge.stories.ts index 5a6240aecf..fcd47d4381 100644 --- a/packages/documentation/src/stories/components/badge/badge.stories.ts +++ b/packages/documentation/src/stories/components/badge/badge.stories.ts @@ -118,7 +118,7 @@ export const Position: Story = {
- +
3
`, diff --git a/packages/styles/src/components/badge.scss b/packages/styles/src/components/badge.scss index 07aa118425..89b9995e53 100644 --- a/packages/styles/src/components/badge.scss +++ b/packages/styles/src/components/badge.scss @@ -14,7 +14,7 @@ height: var(--post-badge-height); min-width: calc(var(--post-badge-height) - 2 * var(--post-badge-padding-x)); padding-inline: var(--post-badge-padding-x); - border: badge.$badge-border-width solid badge.$badge-border-color; + border: badge.$badge-border; border-radius: badge.$badge-border-radius; line-height: badge.$badge-line-height; font-size: badge.$badge-font-size; @@ -24,21 +24,11 @@ &:empty { --post-badge-height: #{badge.$badge-height-empty}; --post-badge-padding-x: #{badge.$badge-padding-x-empty}; - border-width: badge.$badge-border-width-empty; - - // prevent blurry border effect - outline: badge.$badge-border-width-empty solid badge.$badge-border-color; - outline-offset: -0.75 * badge.$badge-border-width-empty; } } .badge-sm { --post-badge-height: #{badge.$badge-height-sm}; --post-badge-padding-x: #{badge.$badge-padding-x-sm}; - border-width: badge.$badge-border-width-sm; font-size: badge.$badge-font-size-sm; - - // prevent blurry border effect - outline: badge.$badge-border-width-sm solid badge.$badge-border-color; - outline-offset: -0.75 * badge.$badge-border-width-sm; } diff --git a/packages/styles/src/variables/components/_badge.scss b/packages/styles/src/variables/components/_badge.scss index 9214196eeb..e29c6c54a8 100644 --- a/packages/styles/src/variables/components/_badge.scss +++ b/packages/styles/src/variables/components/_badge.scss @@ -10,7 +10,7 @@ $badge-border-radius: 50rem; $badge-line-height: type.$line-height-copy; $badge-color: color.$white; $badge-bg: color.$error-red; -$badge-border-color: color.$white; +$badge-border: color.$white solid commons.$border-thick; $badge-height: spacing.$size-large; $badge-height-sm: spacing.$size-regular; @@ -20,10 +20,6 @@ $badge-padding-x: spacing.$size-mini; $badge-padding-x-sm: spacing.$size-micro; $badge-padding-x-empty: 0%; // needs a unit for the calculated min-width -$badge-border-width: commons.$border-thick; -$badge-border-width-sm: commons.$border-width; -$badge-border-width-empty: commons.$border-width; - $badge-font-size: type.$font-size-12; $badge-font-size-sm: 10px; From 470eb17be4d18a371ee6e0ec12406a3802e9c774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 28 Mar 2024 16:07:24 +0100 Subject: [PATCH 14/37] merge new badges styles into chips --- .../badge/badge.snapshot.stories.ts | 35 +++++ .../stories/components/badge/badge.stories.ts | 131 ++++++++++++++++++ .../stories/components/chip/chip.stories.ts | 2 +- packages/styles/src/components/_index.scss | 1 + packages/styles/src/components/badge.scss | 5 +- packages/styles/src/components/chip.scss | 2 - packages/styles/src/mixins/_chip.scss | 6 +- packages/styles/src/placeholders/_badge.scss | 7 + packages/styles/src/placeholders/_chip.scss | 53 ++----- packages/styles/src/placeholders/_index.scss | 1 + 10 files changed, 195 insertions(+), 48 deletions(-) diff --git a/packages/documentation/src/stories/components/badge/badge.snapshot.stories.ts b/packages/documentation/src/stories/components/badge/badge.snapshot.stories.ts index e69de29bb2..2181c8b0c6 100644 --- a/packages/documentation/src/stories/components/badge/badge.snapshot.stories.ts +++ b/packages/documentation/src/stories/components/badge/badge.snapshot.stories.ts @@ -0,0 +1,35 @@ +import type { Args, StoryContext, StoryObj } from '@storybook/web-components'; +import meta from './badge.stories'; +import { html } from 'lit'; +import { bombArgs } from '../../../utils'; + +const { id, ...metaWithoutId } = meta; + +export default { + ...metaWithoutId, + title: 'Snapshots', +}; + +type Story = StoryObj; + +export const Badge: Story = { + render: (_args: Args, context: StoryContext) => { + return html` +
+ ${['bg-white', 'bg-dark'].map( + bg => html` +
+ ${bombArgs({ + showNumber: [true, false], + size: context.argTypes.size.options, + background: context.argTypes.background.options, + }) + .filter(args => !(!args.showNumber && args.size === 'small')) + .map((args: Args) => meta.render?.({ ...context.args, ...args }, context))} +
+ `, + )} +
+ `; + }, +}; diff --git a/packages/documentation/src/stories/components/badge/badge.stories.ts b/packages/documentation/src/stories/components/badge/badge.stories.ts index e69de29bb2..8a80d8cf8f 100644 --- a/packages/documentation/src/stories/components/badge/badge.stories.ts +++ b/packages/documentation/src/stories/components/badge/badge.stories.ts @@ -0,0 +1,131 @@ +import { Args, StoryContext, StoryFn, StoryObj } from '@storybook/web-components'; +import { html, nothing } from 'lit'; +import { MetaComponent } from '../../../../types'; +import backgroundColors from '../../../shared/background-colors.module.scss'; + +const meta: MetaComponent = { + id: 'bec68e8b-445e-4760-8bd7-1b9970206d8d', + title: 'Components/Badge', + tags: ['package:HTML'], + render: renderBadge, + decorators: [adaptiveBackground], + args: { + showNumber: true, + number: 1, + size: 'large', + }, + argTypes: { + showNumber: { + name: 'Show Number', + description: 'If `true`, the badge contains a number otherwise it is empty.', + control: { + type: 'boolean', + }, + table: { + category: 'Content', + }, + }, + number: { + name: 'Number', + description: 'The number contained in the badge.', + if: { + arg: 'showNumber', + truthy: true, + }, + control: { + type: 'number', + min: 0, + }, + table: { + category: 'Content', + }, + }, + size: { + name: 'Size', + description: 'The size of the badge.', + if: { + arg: 'showNumber', + truthy: true, + }, + control: { + type: 'radio', + labels: { + 'large': 'Large', + 'badge-sm': 'Small', + }, + }, + options: ['large', 'badge-sm'], + table: { + category: 'General', + }, + }, + background: { + name: 'Backround', + description: 'You can use the Background classes to color the cards', + control: { + type: 'select', + }, + options: Object.keys(backgroundColors), + table: { + category: 'General', + }, + }, + }, +}; + +export default meta; + +// DECORATORS +function adaptiveBackground(story: StoryFn, { args, context }: StoryContext) { + const bgClass = args.background === 'bg-white' ? `p-2 bg-dark` : 'p-2'; + return html`
${story(args, context)}
`; +} + +// RENDERER +function renderBadge(args: Args) { + const sizingClass = args.showNumber && args.size !== 'large' ? ` ${args.size}` : ''; + const bgClass = args.background && args.background !== 'bg-danger' ? ` ${args.background}` : ''; + return html` +
${args.showNumber ? args.number : nothing}
+ `; +} + +// STORIES +type Story = StoryObj; + +export const Default: Story = {}; + +export const Colors: Story = { + render: args => html` + ${renderBadge({ ...args, background: 'bg-success' })} + ${renderBadge({ ...args, background: 'bg-warning' })} + ${renderBadge({ ...args, background: 'bg-yellow' })} + ${renderBadge({ ...args, background: 'bg-light' })} + `, +}; + +export const LargeNumber: Story = { + render: args => html` + ${renderBadge({ ...args, number: 256 })} ${renderBadge({ ...args, number: '+99' })} + `, +}; + +export const Position: Story = { + render: args => html` +
+ Filter +
1
+
1
+
+ +
+ +
3
+
+ `, + decorators: [ + (story: StoryFn, { args, context }: StoryContext) => html` +
${story(args, context)}
+ `, + ], +}; diff --git a/packages/documentation/src/stories/components/chip/chip.stories.ts b/packages/documentation/src/stories/components/chip/chip.stories.ts index 6c27085de2..6da2fbb6f6 100644 --- a/packages/documentation/src/stories/components/chip/chip.stories.ts +++ b/packages/documentation/src/stories/components/chip/chip.stories.ts @@ -5,7 +5,7 @@ import { mapClasses } from '../../../utils'; import { MetaComponent } from '../../../../types'; const meta: MetaComponent = { - id: 'bec68e8b-445e-4760-8bd7-1b9970206d8d', + id: '12576d97-52c3-49ec-be7b-6d37728b75f5', title: 'Components/Chip', tags: ['package:HTML'], render: renderChip, diff --git a/packages/styles/src/components/_index.scss b/packages/styles/src/components/_index.scss index e101f55050..287e24d725 100644 --- a/packages/styles/src/components/_index.scss +++ b/packages/styles/src/components/_index.scss @@ -4,6 +4,7 @@ @use 'accordion'; @use 'alert'; +@use 'badge'; @use 'breadcrumb'; @use 'button'; @use 'button-group'; diff --git a/packages/styles/src/components/badge.scss b/packages/styles/src/components/badge.scss index 89b9995e53..f202a4545a 100644 --- a/packages/styles/src/components/badge.scss +++ b/packages/styles/src/components/badge.scss @@ -1,6 +1,7 @@ @forward './../variables/options'; @use './../mixins/color' as color-mx; +@use './../placeholders/badge' as badge-ph; @use './../variables/components/badge'; .badge { @@ -28,7 +29,5 @@ } .badge-sm { - --post-badge-height: #{badge.$badge-height-sm}; - --post-badge-padding-x: #{badge.$badge-padding-x-sm}; - font-size: badge.$badge-font-size-sm; + @extend %badge-sm; } diff --git a/packages/styles/src/components/chip.scss b/packages/styles/src/components/chip.scss index 0a9726955b..0990f0d888 100644 --- a/packages/styles/src/components/chip.scss +++ b/packages/styles/src/components/chip.scss @@ -19,7 +19,6 @@ button { @include utilities.focus-style; background-color: transparent; text-decoration: none; - transition: chip.$chip-transition; &:is(:active, .active) { @include chip-mx.chip-active-state; @@ -44,7 +43,6 @@ button { .chip-check { &-label { @extend %chip; - transition: chip.$chip-transition; cursor: pointer; } diff --git a/packages/styles/src/mixins/_chip.scss b/packages/styles/src/mixins/_chip.scss index ff3487e78b..ccf38df2f7 100644 --- a/packages/styles/src/mixins/_chip.scss +++ b/packages/styles/src/mixins/_chip.scss @@ -7,8 +7,7 @@ background-color: chip.$chip-hover-bg; > .badge { - background-color: badge.$badge-hover-bg-color; - border-color: badge.$badge-hover-border-color; + background-color: chip.$chip-bg; } @include utilities.high-contrast-mode() { @@ -25,8 +24,7 @@ border-color: transparent; > .badge { - background-color: badge.$badge-active-bg-color; - border-color: badge.$badge-active-border-color; + background-color: chip.$chip-bg; } @include utilities.high-contrast-mode() { diff --git a/packages/styles/src/placeholders/_badge.scss b/packages/styles/src/placeholders/_badge.scss index e69de29bb2..0b67c3c02c 100644 --- a/packages/styles/src/placeholders/_badge.scss +++ b/packages/styles/src/placeholders/_badge.scss @@ -0,0 +1,7 @@ +@use './../variables/components/badge'; + +%badge-sm { + --post-badge-height: #{badge.$badge-height-sm}; + --post-badge-padding-x: #{badge.$badge-padding-x-sm}; + font-size: badge.$badge-font-size-sm; +} diff --git a/packages/styles/src/placeholders/_chip.scss b/packages/styles/src/placeholders/_chip.scss index fc10eaf2f7..cb2411dc7e 100644 --- a/packages/styles/src/placeholders/_chip.scss +++ b/packages/styles/src/placeholders/_chip.scss @@ -4,6 +4,7 @@ @use './../variables/spacing'; @use './../variables/components/badge'; @use './../variables/components/chip'; +@use './../placeholders/badge' as badge-ph; %chip { @include border-radius(chip.$chip-border-radius); @@ -19,6 +20,7 @@ font-weight: chip.$chip-font-weight; color: chip.$chip-color; background-color: chip.$chip-bg; + transition: chip.$chip-transition; > span { text-overflow: ellipsis; @@ -27,21 +29,21 @@ } > .badge { - display: inline-flex; - align-items: center; - justify-content: center; - height: badge.$badge-height; - min-width: badge.$badge-height; - padding: spacing.$size-micro; - color: badge.$badge-color; - background-color: badge.$badge-bg; - border: badge.$badge-border; - font-size: badge.$badge-font-size; + color: chip.$chip-hover-color; + background-color: chip.$chip-hover-bg; + border-color: transparent; + transition: chip.$chip-transition; } > .btn-close { - &:hover { - background-color: chip.$chip-hover-bg; + &:not(:disabled) { + color: chip.$chip-color; + border-radius: commons.$border-radius-pill; + + &:hover { + color: chip.$chip-hover-color; + background-color: chip.$chip-hover-bg; + } } &::before { @@ -50,19 +52,6 @@ } } - > .badge, - > .btn-close { - border-radius: commons.$border-radius-pill; - - &:first-child { - margin-left: 0.5 * badge.$badge-height - chip.$chip-padding-x; - } - - &:last-child { - margin-right: 0.5 * badge.$badge-height - chip.$chip-padding-x; - } - } - &.chip-sm { height: chip.$chip-height-sm; font-size: chip.$chip-font-size-sm; @@ -70,25 +59,13 @@ padding-inline: chip.$chip-padding-x-sm; > .badge { - height: badge.$badge-height-sm; - min-width: badge.$badge-height-sm; + @extend %badge-sm; } > .btn-close::before { height: badge.$badge-height-sm; width: badge.$badge-height-sm; } - - > .badge, - > .btn-close { - &:first-child { - margin-left: 0.5 * badge.$badge-height-sm - chip.$chip-padding-x-sm; - } - - &:last-child { - margin-right: 0.5 * badge.$badge-height-sm - chip.$chip-padding-x-sm; - } - } } // Quick fix for badges in buttons diff --git a/packages/styles/src/placeholders/_index.scss b/packages/styles/src/placeholders/_index.scss index ab2763bc0d..1e55b7c161 100644 --- a/packages/styles/src/placeholders/_index.scss +++ b/packages/styles/src/placeholders/_index.scss @@ -1,3 +1,4 @@ +@use './badge'; @use './button'; @use './chip'; @use './close'; From 3939e572f9eed19bb10789b5d7877ebc227c8bd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Tue, 2 Apr 2024 08:55:39 +0200 Subject: [PATCH 15/37] Fix duplicated badge --- .../documentation/src/stories/components/badge/badge.stories.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/documentation/src/stories/components/badge/badge.stories.ts b/packages/documentation/src/stories/components/badge/badge.stories.ts index 8a80d8cf8f..2fe71f7675 100644 --- a/packages/documentation/src/stories/components/badge/badge.stories.ts +++ b/packages/documentation/src/stories/components/badge/badge.stories.ts @@ -115,7 +115,6 @@ export const Position: Story = {
Filter
1
-
1
From f6cd9852de599470b09bb396b220268d4e08ff99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Tue, 2 Apr 2024 11:16:10 +0200 Subject: [PATCH 16/37] Add migration to move the close button as first child --- packages/migrations/src/migrations/bootstrap/chip/index.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/migrations/src/migrations/bootstrap/chip/index.ts b/packages/migrations/src/migrations/bootstrap/chip/index.ts index b5ed0c5a41..687d5acd65 100644 --- a/packages/migrations/src/migrations/bootstrap/chip/index.ts +++ b/packages/migrations/src/migrations/bootstrap/chip/index.ts @@ -64,6 +64,12 @@ class BadgeToChipUpdate implements DomUpdate { if ($element.hasClass('bg-active')) { $element.removeClass('bg-active').addClass('active'); } + + // move the close button to be the first child + const $closeBtn = $element.children('.btn-close'); + if ($closeBtn && $closeBtn.is(':last-child')) { + $element.prepend($closeBtn); + } }); } } From 04fb5e069296eb5ef4a8d1345c1c525788877c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Tue, 2 Apr 2024 11:33:35 +0200 Subject: [PATCH 17/37] fix sass variable not defined --- packages/styles/src/placeholders/_badge.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/styles/src/placeholders/_badge.scss b/packages/styles/src/placeholders/_badge.scss index 8c187aeb71..a98cfd3afa 100644 --- a/packages/styles/src/placeholders/_badge.scss +++ b/packages/styles/src/placeholders/_badge.scss @@ -9,7 +9,7 @@ align-items: center; gap: badge.$badge-gap; padding: $badge-padding-y $badge-padding-x; - border: badge.$badge-border-width solid badge.$badge-border-color; + border: badge.$badge-border; height: badge.$badge-height; font-size: badge.$badge-font-size; font-weight: $badge-font-weight; From 07bd0aad5dc1228065858d8c21d6b3deb30e4e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Tue, 2 Apr 2024 14:21:42 +0200 Subject: [PATCH 18/37] Fix badges --- packages/styles/src/components/badge.scss | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/styles/src/components/badge.scss b/packages/styles/src/components/badge.scss index f202a4545a..7cc5e6a127 100644 --- a/packages/styles/src/components/badge.scss +++ b/packages/styles/src/components/badge.scss @@ -20,14 +20,15 @@ line-height: badge.$badge-line-height; font-size: badge.$badge-font-size; background-color: badge.$badge-bg; + background-clip: padding-box; color: badge.$badge-color; &:empty { --post-badge-height: #{badge.$badge-height-empty}; --post-badge-padding-x: #{badge.$badge-padding-x-empty}; } -} -.badge-sm { - @extend %badge-sm; + &.badge-sm { + @extend %badge-sm; + } } From a67c296b9b48e836809b193574d19ccf047f8f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Tue, 2 Apr 2024 17:29:13 +0200 Subject: [PATCH 19/37] Update badge.stories.ts --- .../documentation/src/stories/components/badge/badge.stories.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/documentation/src/stories/components/badge/badge.stories.ts b/packages/documentation/src/stories/components/badge/badge.stories.ts index fcd47d4381..ddd8177b3a 100644 --- a/packages/documentation/src/stories/components/badge/badge.stories.ts +++ b/packages/documentation/src/stories/components/badge/badge.stories.ts @@ -100,7 +100,7 @@ export const Colors: Story = { ${renderBadge({ ...args, background: 'bg-success' })} ${renderBadge({ ...args, background: 'bg-warning' })} ${renderBadge({ ...args, background: 'bg-yellow' })} - ${renderBadge({ ...args, background: 'bg-light' })} + ${renderBadge({ ...args, background: 'bg-gray' })} `, }; From 9ca74a7f4b95ad06490ee5214398b52067303b60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 4 Apr 2024 11:04:33 +0200 Subject: [PATCH 20/37] Update chip controls --- .../components/chip/chip.snapshot.stories.ts | 8 +- .../stories/components/chip/chip.stories.ts | 103 ++++++++---------- 2 files changed, 49 insertions(+), 62 deletions(-) diff --git a/packages/documentation/src/stories/components/chip/chip.snapshot.stories.ts b/packages/documentation/src/stories/components/chip/chip.snapshot.stories.ts index 63287d706a..225c700b7e 100644 --- a/packages/documentation/src/stories/components/chip/chip.snapshot.stories.ts +++ b/packages/documentation/src/stories/components/chip/chip.snapshot.stories.ts @@ -25,14 +25,14 @@ export const Chip: Story = { 'Contentus momentus vero siteos et accusam iretea et justo.', ], size: context.argTypes.size.options, - interactionType: context.argTypes.interactionType.options, + type: context.argTypes.type.options, badge: [false, true], - checked: [false, true], + active: [false, true], disabled: [false, true], dismissed: [false], }) - .filter(args => !(args.interactionType !== 'checkable' && args.checked === true)) - .filter(args => !(args.interactionType !== 'checkable' && args.disabled === true)) + .filter(args => !(args.type !== 'filter' && args.active === true)) + .filter(args => !(args.type !== 'filter' && args.disabled === true)) .map((args: Args) => meta.render?.({ ...context.args, ...args }, context))}
`, diff --git a/packages/documentation/src/stories/components/chip/chip.stories.ts b/packages/documentation/src/stories/components/chip/chip.stories.ts index 6da2fbb6f6..f25adb7b8a 100644 --- a/packages/documentation/src/stories/components/chip/chip.stories.ts +++ b/packages/documentation/src/stories/components/chip/chip.stories.ts @@ -10,14 +10,16 @@ const meta: MetaComponent = { tags: ['package:HTML'], render: renderChip, parameters: { - chips: [], + controls: { + exclude: ['dismissed'], + }, }, args: { text: 'Insigno', size: 'large', badge: false, - interactionType: 'none', - checked: false, + type: 'filter', + active: false, disabled: false, dismissed: false, }, @@ -32,6 +34,16 @@ const meta: MetaComponent = { category: 'Content', }, }, + badge: { + name: 'Nested Badge', + description: 'If `true`, a badge is displayed inside the chip.', + control: { + type: 'boolean', + }, + table: { + category: 'Content', + }, + }, size: { name: 'Size', description: 'The size of the chip.', @@ -47,73 +59,48 @@ const meta: MetaComponent = { category: 'General', }, }, - badge: { - name: 'Nested Badge', - description: 'If `true`, a badge is displayed inside the chip.', - control: { - type: 'boolean', - }, - table: { - category: 'General', - }, - }, - interactionType: { - name: 'Interaction Type', + type: { + name: 'Type', description: 'Defines how the chip can be interacted with.', control: { - type: 'inline-radio', + type: 'radio', labels: { - none: 'None', - checkable: 'Checkable', - dismissible: 'Dismissible', + filter: 'Filter Chip', + dismissible: 'Dismissible Chip', }, }, - options: ['none', 'checkable', 'dismissible'], + options: ['filter', 'dismissible'], table: { - category: 'Interactions', + category: 'General', }, }, - checked: { - name: 'Checked', - description: 'If `true`, the chip is checked otherwise it is unchecked.', + active: { + name: 'Active', + description: 'If `true`, the chip is active.', if: { - arg: 'interactionType', - eq: 'checkable', + arg: 'type', + eq: 'filter', }, control: { type: 'boolean', }, table: { - category: 'Interactions', + category: 'General', }, }, disabled: { name: 'Disabled', description: - 'If `true`, the badge is disabled.
There are accessibility concerns with the disabled state.
Please read our disabled state accessibility guide.
', - if: { - arg: 'interactionType', - eq: 'checkable', - }, - control: { - type: 'boolean', - }, - table: { - category: 'Interactions', - }, - }, - dismissed: { - name: 'Dismissed', - description: 'If `true`, the chip is removed from the page otherwise it is displayed.', + 'If `true`, the chip is disabled.
There are accessibility concerns with the disabled state.
Please read our disabled state accessibility guide.
', if: { - arg: 'interactionType', - eq: 'dismissible', + arg: 'type', + eq: 'filter', }, control: { type: 'boolean', }, table: { - category: 'Interactions', + category: 'General', }, }, }, @@ -149,7 +136,7 @@ function getDefaultContent(args: Args) { } let index = 0; -function getCheckableContent(args: Args, updateArgs: (args: Args) => void, context: StoryContext) { +function getFilterContent(args: Args, updateArgs: (args: Args) => void, context: StoryContext) { index++; const checkboxId = `chip-example--${context.name.replace(/ /g, '-').toLowerCase()}` + index; @@ -159,7 +146,7 @@ function getCheckableContent(args: Args, updateArgs: (args: Args) => void, conte }); const handleChange = (e: Event) => { - updateArgs({ checked: !args.checked }); + updateArgs({ active: !args.active }); if (document.activeElement === e.target) { setTimeout(() => { @@ -175,7 +162,7 @@ function getCheckableContent(args: Args, updateArgs: (args: Args) => void, conte name="${checkboxId}" class="chip-check-input" type="checkbox" - ?checked="${args.checked}" + ?checked="${args.active}" ?disabled="${args.disabled}" @change="${handleChange}" /> @@ -196,19 +183,19 @@ function renderChip(args: Args, context: StoryContext) { if (args.dismissed) return html` ${nothing} `; - const isCheckable = args.interactionType === 'checkable'; - const isDismissible = args.interactionType === 'dismissible'; + const isFilter = args.type === 'filter'; + const isDismissible = args.type === 'dismissible'; const chipClasses = mapClasses({ - 'chip': !isCheckable, - 'chip-check': isCheckable, - [args.size]: args.size !== 'large' && !isCheckable, + 'chip': !isFilter, + 'chip-check': isFilter, + [args.size]: args.size !== 'large' && !isFilter, }); return html`
${isDismissible ? getDismissButton(updateArgs) : nothing} - ${isCheckable ? getCheckableContent(args, updateArgs, context) : getDefaultContent(args)} + ${isFilter ? getFilterContent(args, updateArgs, context) : getDefaultContent(args)}
`; } @@ -221,16 +208,16 @@ export const Default: Story = { }; export const FilterChip: Story = { - render: ({ checked, ...args }, context) => html` + render: ({ active, ...args }, context) => html`
- ${renderChip({ ...args, checked: true, text: 'Ĉiuj' }, context)} + ${renderChip({ ...args, active: true, text: 'Ĉiuj' }, context)} ${renderChip({ ...args, text: 'Filtru unu' }, context)} ${renderChip({ ...args, text: 'Filtrilo du' }, context)} ${renderChip({ ...args, text: 'Filtrilo tri' }, context)}
`, args: { - interactionType: 'checkable', + type: 'filter', }, }; @@ -244,6 +231,6 @@ export const Dismissible: Story = { `, args: { - interactionType: 'dismissible', + type: 'dismissible', }, }; From 67fd6c388884f93bbbc63b85b9c04daa0e0c17e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 4 Apr 2024 11:05:49 +0200 Subject: [PATCH 21/37] Add .chip-text class --- .../documentation/src/stories/components/chip/chip.stories.ts | 2 +- packages/styles/src/placeholders/_chip.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/documentation/src/stories/components/chip/chip.stories.ts b/packages/documentation/src/stories/components/chip/chip.stories.ts index f25adb7b8a..a108e82035 100644 --- a/packages/documentation/src/stories/components/chip/chip.stories.ts +++ b/packages/documentation/src/stories/components/chip/chip.stories.ts @@ -130,7 +130,7 @@ function externalControl(story: any, { args }: StoryContext) { // RENDERER function getDefaultContent(args: Args) { return html` - ${args.text} + ${args.text} ${args.badge ? html` 1 ` : nothing} `; } diff --git a/packages/styles/src/placeholders/_chip.scss b/packages/styles/src/placeholders/_chip.scss index cb2411dc7e..ae635cc174 100644 --- a/packages/styles/src/placeholders/_chip.scss +++ b/packages/styles/src/placeholders/_chip.scss @@ -22,7 +22,7 @@ background-color: chip.$chip-bg; transition: chip.$chip-transition; - > span { + > .chip-text { text-overflow: ellipsis; overflow: hidden; white-space: nowrap; From 3849047b0a8287f7a6ddd8d9d0f6c28263180697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 4 Apr 2024 11:06:50 +0200 Subject: [PATCH 22/37] Rename "chip-check" to "chip-filter" --- .../src/stories/components/chip/chip.stories.ts | 6 +++--- .../src/migrations/bootstrap/chip/index.ts | 8 ++++---- packages/styles/src/components/chip.scss | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/documentation/src/stories/components/chip/chip.stories.ts b/packages/documentation/src/stories/components/chip/chip.stories.ts index a108e82035..a2aa4837a9 100644 --- a/packages/documentation/src/stories/components/chip/chip.stories.ts +++ b/packages/documentation/src/stories/components/chip/chip.stories.ts @@ -141,7 +141,7 @@ function getFilterContent(args: Args, updateArgs: (args: Args) => void, context: const checkboxId = `chip-example--${context.name.replace(/ /g, '-').toLowerCase()}` + index; const labelClasses = mapClasses({ - 'chip-check-label': true, + 'chip-filter-label': true, [args.size]: args.size !== 'large', }); @@ -160,7 +160,7 @@ function getFilterContent(args: Args, updateArgs: (args: Args) => void, context: { const $element = $(element); - $element.removeClass('badge-check').addClass('chip-check'); + $element.removeClass('badge-check').addClass('chip-filter'); const $label = $element.children('.badge-check-label'); - if ($label) $label.removeClass('badge-check-label').addClass('chip-check-label'); + if ($label) $label.removeClass('badge-check-label').addClass('chip-filter-label'); const $input = $element.children('.badge-check-input'); - if ($input) $input.removeClass('badge-check-input').addClass('chip-check-input'); + if ($input) $input.removeClass('badge-check-input').addClass('chip-filter-input'); }); } } @@ -33,7 +33,7 @@ class BadgeToChipUpdate implements DomUpdate { // do not update nested badges const $parent = $element.parent(); - if ($parent.hasClass('chip') || $parent.hasClass('chip-check-label')) { + if ($parent.hasClass('chip') || $parent.hasClass('chip-filter-label')) { return; } diff --git a/packages/styles/src/components/chip.scss b/packages/styles/src/components/chip.scss index 0990f0d888..d068e81d54 100644 --- a/packages/styles/src/components/chip.scss +++ b/packages/styles/src/components/chip.scss @@ -40,18 +40,18 @@ button { } } -.chip-check { +.chip-filter { &-label { @extend %chip; cursor: pointer; } &-input:checked { - + .chip-check-label { + + .chip-filter-label { @include chip-mx.chip-active-state; } - @include utilities.disabled-style-custom('+ .chip-check-label') { + @include utilities.disabled-style-custom('+ .chip-filter-label') { background-color: chip.$chip-disabled-active-bg; } } @@ -62,16 +62,16 @@ button { &-input { @include utilities.visuallyhidden; - @include utilities.focus-style('+ .chip-check-label'); - @include utilities.disabled-style('+ .chip-check-label'); - @include utilities.disabled-style-custom('+ .chip-check-label') { + @include utilities.focus-style('+ .chip-filter-label'); + @include utilities.disabled-style('+ .chip-filter-label'); + @include utilities.disabled-style-custom('+ .chip-filter-label') { background-color: chip.$chip-disabled-bg; } } } @include utilities.high-contrast-mode() { - .chip-check { + .chip-filter { &-input:focus-visible + &-label { border-color: Highlight; outline-color: Highlight; @@ -86,7 +86,7 @@ button { button.chip, a.chip, - .chip-check-label { + .chip-filter-label { transition: none; } } From f80117526e6fc2fe915f4aea0f404c7bc886f2d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 4 Apr 2024 11:13:03 +0200 Subject: [PATCH 23/37] Update focus-style for form check and form range --- packages/styles/src/components/form-check.scss | 3 +-- packages/styles/src/components/form-range.scss | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/styles/src/components/form-check.scss b/packages/styles/src/components/form-check.scss index c89f83fd74..f170586bc2 100644 --- a/packages/styles/src/components/form-check.scss +++ b/packages/styles/src/components/form-check.scss @@ -15,8 +15,7 @@ row-gap: form-check.$form-check-row-gap; margin-bottom: form-check.$form-check-margin-bottom; - @include utility-mx.focus-style(); - @include utility-mx.focus-style-custom() { + @include utility-mx.focus-style() { border-radius: commons.$border-radius !important; } diff --git a/packages/styles/src/components/form-range.scss b/packages/styles/src/components/form-range.scss index efcdf46908..b1754e3f39 100644 --- a/packages/styles/src/components/form-range.scss +++ b/packages/styles/src/components/form-range.scss @@ -15,16 +15,14 @@ $webkit-progress-height-adjustment: 2px; $webkit-thumb-width: 32px; :has(> .form-range) { - @include utilities.focus-style(); - @include utilities.focus-style-custom() { + @include utilities.focus-style() { border-radius: commons.$border-radius !important; } } @supports not selector(:has(> .form-range)) { .form-range { - @include utilities.focus-style(); - @include utilities.focus-style-custom() { + @include utilities.focus-style() { border-radius: commons.$border-radius !important; } } From c49ba14403ef80b0df2d874208f20bcdccb571b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 4 Apr 2024 11:18:53 +0200 Subject: [PATCH 24/37] Update disabled-style mixin --- packages/styles/src/components/chip.scss | 14 +++++------ packages/styles/src/mixins/_utilities.scss | 29 +++++++++++----------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/packages/styles/src/components/chip.scss b/packages/styles/src/components/chip.scss index d068e81d54..9ac023139c 100644 --- a/packages/styles/src/components/chip.scss +++ b/packages/styles/src/components/chip.scss @@ -16,13 +16,13 @@ a, button { &.chip { - @include utilities.focus-style; + @include utilities.focus-style(); background-color: transparent; - text-decoration: none; &:is(:active, .active) { @include chip-mx.chip-active-state; - @include utilities.disabled-style-custom { + + &:disabled { background-color: chip.$chip-disabled-active-bg; } } @@ -33,8 +33,7 @@ button { } } - @include utilities.disabled-style; - @include utilities.disabled-style-custom { + @include utilities.disabled-style($text-selector: '> .chip-text') { background-color: chip.$chip-disabled-bg; } } @@ -51,7 +50,7 @@ button { @include chip-mx.chip-active-state; } - @include utilities.disabled-style-custom('+ .chip-filter-label') { + &:disabled + .chip-filter-label { background-color: chip.$chip-disabled-active-bg; } } @@ -63,8 +62,7 @@ button { &-input { @include utilities.visuallyhidden; @include utilities.focus-style('+ .chip-filter-label'); - @include utilities.disabled-style('+ .chip-filter-label'); - @include utilities.disabled-style-custom('+ .chip-filter-label') { + @include utilities.disabled-style('+ .chip-filter-label', $text-selector: '> .chip-text') { background-color: chip.$chip-disabled-bg; } } diff --git a/packages/styles/src/mixins/_utilities.scss b/packages/styles/src/mixins/_utilities.scss index 86bc670b3c..090d8fa25d 100644 --- a/packages/styles/src/mixins/_utilities.scss +++ b/packages/styles/src/mixins/_utilities.scss @@ -87,8 +87,8 @@ outline: none; } -@mixin focus-style($vendor-prefix: '') { - &#{$vendor-prefix} { +@mixin focus-style($additional-selector: '') { + &#{$additional-selector} { outline-style: none; outline-offset: spacing.$size-line; outline-width: spacing.$size-line; @@ -96,7 +96,7 @@ } // :has(:focus-visible) mimic a focus-visible-within pseudo-class - &:is(:focus-visible, :has(:focus-visible), .pretend-focus)#{$vendor-prefix} { + &:is(:focus-visible, :has(:focus-visible), .pretend-focus)#{$additional-selector} { outline-style: solid; @include high-contrast-mode() { @@ -109,7 +109,7 @@ // When a browser doesn't support :has, use focus-within as a fallback. This means that focus state is displayed on focus and not on focus-visible only (except some browsers like Safari). @supports not selector(:has(:focus-visible)) { - &:is(:focus-visible, :focus-within, .pretend-focus)#{$vendor-prefix} { + &:is(:focus-visible, :focus-within, .pretend-focus)#{$additional-selector} { outline-style: solid; @include high-contrast-mode() { @@ -122,32 +122,33 @@ } } -@mixin focus-style-custom($vendor-prefix: '') { +@mixin focus-style-custom($additional-selector: '') { // :has(:focus-visible) mimic a focus-visible-within pseudo-class - &:is(:focus-visible, :has(:focus-visible), .pretend-focus)#{$vendor-prefix} { + &:is(:focus-visible, :has(:focus-visible), .pretend-focus)#{$additional-selector} { @content; } // When a browser doesn't support :has, use focus-within as a fallback. This means that focus state is displayed on focus and not on focus-visible only (except some browsers like Safari). @supports not selector(:has(:focus-visible)) { - &:is(:focus-visible, :focus-within, .pretend-focus)#{$vendor-prefix} { + &:is(:focus-visible, :focus-within, .pretend-focus)#{$additional-selector} { @content; } } } -@mixin disabled-style($selector: '') { - &:is(:disabled, .disabled)#{$selector} { +@mixin disabled-style($additional-selector: '', $text-selector: '') { + &:disabled#{$additional-selector} { pointer-events: none; - text-decoration: line-through; color: var(--post-gray-40); border-color: var(--post-gray-40); border-style: dashed; - } -} + background-clip: padding-box; -@mixin disabled-style-custom($selector: '') { - &:is(:disabled, .disabled)#{$selector} { + // In case rules need to be slightly adjusted @content; } + + &:disabled#{$additional-selector}#{$text-selector} { + text-decoration: line-through; + } } From bddd331abe497edcf97ac0367780f9c6fcb8d8fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 4 Apr 2024 16:04:42 +0200 Subject: [PATCH 25/37] Rename default chip to chip-dismissible --- .../stories/components/chip/chip.stories.ts | 24 +++------ packages/styles/src/components/chip.scss | 51 +++++++++---------- 2 files changed, 30 insertions(+), 45 deletions(-) diff --git a/packages/documentation/src/stories/components/chip/chip.stories.ts b/packages/documentation/src/stories/components/chip/chip.stories.ts index a2aa4837a9..e5aad2f75b 100644 --- a/packages/documentation/src/stories/components/chip/chip.stories.ts +++ b/packages/documentation/src/stories/components/chip/chip.stories.ts @@ -16,7 +16,7 @@ const meta: MetaComponent = { }, args: { text: 'Insigno', - size: 'large', + size: 'Large', badge: false, type: 'filter', active: false, @@ -49,12 +49,8 @@ const meta: MetaComponent = { description: 'The size of the chip.', control: { type: 'radio', - labels: { - 'large': 'Large', - 'chip-sm': 'Small', - }, }, - options: ['large', 'chip-sm'], + options: ['Large', 'Small'], table: { category: 'General', }, @@ -140,10 +136,6 @@ function getFilterContent(args: Args, updateArgs: (args: Args) => void, context: index++; const checkboxId = `chip-example--${context.name.replace(/ /g, '-').toLowerCase()}` + index; - const labelClasses = mapClasses({ - 'chip-filter-label': true, - [args.size]: args.size !== 'large', - }); const handleChange = (e: Event) => { updateArgs({ active: !args.active }); @@ -166,7 +158,9 @@ function getFilterContent(args: Args, updateArgs: (args: Args) => void, context: ?disabled="${args.disabled}" @change="${handleChange}" /> - + `; } @@ -186,14 +180,8 @@ function renderChip(args: Args, context: StoryContext) { const isFilter = args.type === 'filter'; const isDismissible = args.type === 'dismissible'; - const chipClasses = mapClasses({ - 'chip': !isFilter, - 'chip-filter': isFilter, - [args.size]: args.size !== 'large' && !isFilter, - }); - return html` -
+
${isDismissible ? getDismissButton(updateArgs) : nothing} ${isFilter ? getFilterContent(args, updateArgs, context) : getDefaultContent(args)}
diff --git a/packages/styles/src/components/chip.scss b/packages/styles/src/components/chip.scss index 9ac023139c..6cdb253585 100644 --- a/packages/styles/src/components/chip.scss +++ b/packages/styles/src/components/chip.scss @@ -10,12 +10,9 @@ @use './../functions/icons' as icons-fn; .chip { - @extend %chip; -} + &-dismissible { + @extend %chip; -a, -button { - &.chip { @include utilities.focus-style(); background-color: transparent; @@ -37,33 +34,33 @@ button { background-color: chip.$chip-disabled-bg; } } -} - -.chip-filter { - &-label { - @extend %chip; - cursor: pointer; - } - &-input:checked { - + .chip-filter-label { - @include chip-mx.chip-active-state; + &-filter { + &-label { + @extend %chip; + cursor: pointer; } - &:disabled + .chip-filter-label { - background-color: chip.$chip-disabled-active-bg; - } - } + &-input { + &:checked { + + .chip-filter-label { + @include chip-mx.chip-active-state; + } - &-input:not(:checked) + &-label:hover { - @include chip-mx.chip-hover-state; - } + &:disabled + .chip-filter-label { + background-color: chip.$chip-disabled-active-bg; + } + } - &-input { - @include utilities.visuallyhidden; - @include utilities.focus-style('+ .chip-filter-label'); - @include utilities.disabled-style('+ .chip-filter-label', $text-selector: '> .chip-text') { - background-color: chip.$chip-disabled-bg; + &:not(:checked) + .chip-filter-label:hover { + @include chip-mx.chip-hover-state; + } + + @include utilities.visuallyhidden; + @include utilities.focus-style('+ .chip-filter-label'); + @include utilities.disabled-style('+ .chip-filter-label', $text-selector: '> .chip-text') { + background-color: chip.$chip-disabled-bg; + } } } } From 3a8bac5e9b265872c0b81b5c45315383876f4acc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 4 Apr 2024 16:11:03 +0200 Subject: [PATCH 26/37] Move the .chip-sm class to the container instead of the label --- .../stories/components/chip/chip.stories.ts | 6 ++-- packages/styles/src/components/chip.scss | 10 ++++++ packages/styles/src/placeholders/_chip.scss | 32 +++++++++---------- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/packages/documentation/src/stories/components/chip/chip.stories.ts b/packages/documentation/src/stories/components/chip/chip.stories.ts index e5aad2f75b..d917b8e82b 100644 --- a/packages/documentation/src/stories/components/chip/chip.stories.ts +++ b/packages/documentation/src/stories/components/chip/chip.stories.ts @@ -158,9 +158,7 @@ function getFilterContent(args: Args, updateArgs: (args: Args) => void, context: ?disabled="${args.disabled}" @change="${handleChange}" /> - + `; } @@ -181,7 +179,7 @@ function renderChip(args: Args, context: StoryContext) { const isDismissible = args.type === 'dismissible'; return html` -
+
${isDismissible ? getDismissButton(updateArgs) : nothing} ${isFilter ? getFilterContent(args, updateArgs, context) : getDefaultContent(args)}
diff --git a/packages/styles/src/components/chip.scss b/packages/styles/src/components/chip.scss index 6cdb253585..ee842756d4 100644 --- a/packages/styles/src/components/chip.scss +++ b/packages/styles/src/components/chip.scss @@ -65,6 +65,16 @@ } } +.chip-sm { + &.chip-dismissible { + @extend %chip-sm; + } + + &.chip-filter > .chip-filter-label { + @extend %chip-sm; + } +} + @include utilities.high-contrast-mode() { .chip-filter { &-input:focus-visible + &-label { diff --git a/packages/styles/src/placeholders/_chip.scss b/packages/styles/src/placeholders/_chip.scss index ae635cc174..37a13ba020 100644 --- a/packages/styles/src/placeholders/_chip.scss +++ b/packages/styles/src/placeholders/_chip.scss @@ -52,25 +52,25 @@ } } - &.chip-sm { - height: chip.$chip-height-sm; - font-size: chip.$chip-font-size-sm; - gap: chip.$chip-gap-sm; - padding-inline: chip.$chip-padding-x-sm; - - > .badge { - @extend %badge-sm; - } - - > .btn-close::before { - height: badge.$badge-height-sm; - width: badge.$badge-height-sm; - } - } - // Quick fix for badges in buttons .btn & { position: relative; top: -1px; } } + +%chip-sm { + height: chip.$chip-height-sm; + font-size: chip.$chip-font-size-sm; + gap: chip.$chip-gap-sm; + padding-inline: chip.$chip-padding-x-sm; + + > .badge { + @extend %badge-sm; + } + + > .btn-close::before { + height: badge.$badge-height-sm; + width: badge.$badge-height-sm; + } +} From a99abe1603ed7f673006e0a194cb86d6ca6835c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 4 Apr 2024 17:08:21 +0200 Subject: [PATCH 27/37] Update dismissible chip structure --- .../components/chip/chip.snapshot.stories.ts | 2 +- .../stories/components/chip/chip.stories.ts | 58 ++++++++----------- packages/styles/src/components/chip.scss | 1 - 3 files changed, 26 insertions(+), 35 deletions(-) diff --git a/packages/documentation/src/stories/components/chip/chip.snapshot.stories.ts b/packages/documentation/src/stories/components/chip/chip.snapshot.stories.ts index 225c700b7e..6763721904 100644 --- a/packages/documentation/src/stories/components/chip/chip.snapshot.stories.ts +++ b/packages/documentation/src/stories/components/chip/chip.snapshot.stories.ts @@ -32,7 +32,7 @@ export const Chip: Story = { dismissed: [false], }) .filter(args => !(args.type !== 'filter' && args.active === true)) - .filter(args => !(args.type !== 'filter' && args.disabled === true)) + .filter(args => !(args.type !== 'filter' && args.badge === true)) .map((args: Args) => meta.render?.({ ...context.args, ...args }, context))}
`, diff --git a/packages/documentation/src/stories/components/chip/chip.stories.ts b/packages/documentation/src/stories/components/chip/chip.stories.ts index d917b8e82b..8e146247fe 100644 --- a/packages/documentation/src/stories/components/chip/chip.stories.ts +++ b/packages/documentation/src/stories/components/chip/chip.stories.ts @@ -88,10 +88,6 @@ const meta: MetaComponent = { name: 'Disabled', description: 'If `true`, the chip is disabled.
There are accessibility concerns with the disabled state.
Please read our disabled state accessibility guide.
', - if: { - arg: 'type', - eq: 'filter', - }, control: { type: 'boolean', }, @@ -124,15 +120,8 @@ function externalControl(story: any, { args }: StoryContext) { } // RENDERER -function getDefaultContent(args: Args) { - return html` - ${args.text} - ${args.badge ? html` 1 ` : nothing} - `; -} - let index = 0; -function getFilterContent(args: Args, updateArgs: (args: Args) => void, context: StoryContext) { +function getFilterChip(args: Args, updateArgs: (args: Args) => void, context: StoryContext) { index++; const checkboxId = `chip-example--${context.name.replace(/ /g, '-').toLowerCase()}` + index; @@ -149,23 +138,32 @@ function getFilterContent(args: Args, updateArgs: (args: Args) => void, context: }; return html` - - +
+ + +
`; } -function getDismissButton(updateArgs: (args: Args) => void) { +function getDismissibleChip(args: Args, updateArgs: (args: Args) => void) { return html` - `; } @@ -175,15 +173,9 @@ function renderChip(args: Args, context: StoryContext) { if (args.dismissed) return html` ${nothing} `; - const isFilter = args.type === 'filter'; - const isDismissible = args.type === 'dismissible'; + if (args.type === 'dismissible') return getDismissibleChip(args, updateArgs); - return html` -
- ${isDismissible ? getDismissButton(updateArgs) : nothing} - ${isFilter ? getFilterContent(args, updateArgs, context) : getDefaultContent(args)} -
- `; + return getFilterChip(args, updateArgs, context); } // STORIES diff --git a/packages/styles/src/components/chip.scss b/packages/styles/src/components/chip.scss index ee842756d4..cfdce0020d 100644 --- a/packages/styles/src/components/chip.scss +++ b/packages/styles/src/components/chip.scss @@ -14,7 +14,6 @@ @extend %chip; @include utilities.focus-style(); - background-color: transparent; &:is(:active, .active) { @include chip-mx.chip-active-state; From 4c4e79824d3328bc7774e3d235f2b6ff463dc5c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 4 Apr 2024 17:25:37 +0200 Subject: [PATCH 28/37] Update dismissible badge styles --- packages/styles/src/components/chip.scss | 52 ++++++++++++++----- packages/styles/src/placeholders/_chip.scss | 22 -------- packages/styles/src/variables/_commons.scss | 1 + .../src/variables/components/_chip.scss | 6 +++ 4 files changed, 46 insertions(+), 35 deletions(-) diff --git a/packages/styles/src/components/chip.scss b/packages/styles/src/components/chip.scss index cfdce0020d..d3a8c387b1 100644 --- a/packages/styles/src/components/chip.scss +++ b/packages/styles/src/components/chip.scss @@ -6,32 +6,48 @@ @use './../variables/color'; @use './../mixins/utilities'; @use './../mixins/chip' as chip-mx; +@use './../mixins/icons' as icons-mx; @use './../placeholders/chip' as chip-ph; @use './../functions/icons' as icons-fn; .chip { &-dismissible { @extend %chip; + position: relative; + + &::before, + &::after { + content: ''; + display: inline-block; + flex: 0 0 auto; + height: chip.$chip-close-button-height; + width: chip.$chip-close-button-height; + transition: chip.$chip-transition; + } - @include utilities.focus-style(); - - &:is(:active, .active) { - @include chip-mx.chip-active-state; + &::after { + @include icons-mx.icon(chip.$chip-close-button-icon); + position: absolute; + top: 50%; + left: chip.$chip-padding-x; + transform: translateY(-50%); + } - &:disabled { - background-color: chip.$chip-disabled-active-bg; - } + &::before { + border-radius: chip.$chip-close-button-border-radius; } - &:not(:active, .active) { - @include utilities.not-disabled-focus-hover { - @include chip-mx.chip-hover-state; - } + &:hover::before { + background-color: chip.$chip-hover-bg; } - @include utilities.disabled-style($text-selector: '> .chip-text') { - background-color: chip.$chip-disabled-bg; + // set the focus ring on the close button only + @include utilities.focus-style-none(); + @include utilities.focus-style('::before') { + background-color: chip.$chip-hover-bg; } + + @include utilities.disabled-style($text-selector: '> .chip-text'); } &-filter { @@ -67,6 +83,16 @@ .chip-sm { &.chip-dismissible { @extend %chip-sm; + + &::before, + &::after { + height: chip.$chip-close-button-height-sm; + width: chip.$chip-close-button-height-sm; + } + + &::after { + left: chip.$chip-padding-x-sm; + } } &.chip-filter > .chip-filter-label { diff --git a/packages/styles/src/placeholders/_chip.scss b/packages/styles/src/placeholders/_chip.scss index 37a13ba020..19d98c2ed5 100644 --- a/packages/styles/src/placeholders/_chip.scss +++ b/packages/styles/src/placeholders/_chip.scss @@ -35,23 +35,6 @@ transition: chip.$chip-transition; } - > .btn-close { - &:not(:disabled) { - color: chip.$chip-color; - border-radius: commons.$border-radius-pill; - - &:hover { - color: chip.$chip-hover-color; - background-color: chip.$chip-hover-bg; - } - } - - &::before { - height: badge.$badge-height; - width: badge.$badge-height; - } - } - // Quick fix for badges in buttons .btn & { position: relative; @@ -68,9 +51,4 @@ > .badge { @extend %badge-sm; } - - > .btn-close::before { - height: badge.$badge-height-sm; - width: badge.$badge-height-sm; - } } diff --git a/packages/styles/src/variables/_commons.scss b/packages/styles/src/variables/_commons.scss index b1cd334994..e8ed38d95e 100644 --- a/packages/styles/src/variables/_commons.scss +++ b/packages/styles/src/variables/_commons.scss @@ -12,6 +12,7 @@ $border-radius-sm: $border-radius !default; $border-radius-rg: $border-radius !default; $border-radius-lg: $border-radius !default; $border-radius-pill: 50rem !default; +$border-radius-round: 50% !default; $box-shadow-sm: 0 0 4px 0 rgba(color.$black, 0.4) !default; $box-shadow: 0 0 5px 0 rgba(color.$black, 0.3) !default; diff --git a/packages/styles/src/variables/components/_chip.scss b/packages/styles/src/variables/components/_chip.scss index 4c0d638d3f..51cb852fa3 100644 --- a/packages/styles/src/variables/components/_chip.scss +++ b/packages/styles/src/variables/components/_chip.scss @@ -40,3 +40,9 @@ $chip-active-bg: color.$yellow; $chip-disabled-bg: color.$white; $chip-disabled-active-bg: color.$gray-background; + + +$chip-close-button-icon: 2043; +$chip-close-button-border-radius: commons.$border-radius-round; +$chip-close-button-height: spacing.$size-large; +$chip-close-button-height-sm: spacing.$size-regular; From d9a0265405fb093890d2a5610f3eee6d726b296c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Thu, 4 Apr 2024 17:40:19 +0200 Subject: [PATCH 29/37] Update chip-filter styles --- .../stories/components/chip/chip.stories.ts | 36 ++++++----- packages/styles/src/components/chip.scss | 62 ++++++++++++------- packages/styles/src/placeholders/_chip.scss | 11 ---- 3 files changed, 59 insertions(+), 50 deletions(-) diff --git a/packages/documentation/src/stories/components/chip/chip.stories.ts b/packages/documentation/src/stories/components/chip/chip.stories.ts index 8e146247fe..0fb867b061 100644 --- a/packages/documentation/src/stories/components/chip/chip.stories.ts +++ b/packages/documentation/src/stories/components/chip/chip.stories.ts @@ -17,10 +17,10 @@ const meta: MetaComponent = { args: { text: 'Insigno', size: 'Large', - badge: false, type: 'filter', - active: false, disabled: false, + active: false, + badge: false, dismissed: false, }, argTypes: { @@ -34,16 +34,6 @@ const meta: MetaComponent = { category: 'Content', }, }, - badge: { - name: 'Nested Badge', - description: 'If `true`, a badge is displayed inside the chip.', - control: { - type: 'boolean', - }, - table: { - category: 'Content', - }, - }, size: { name: 'Size', description: 'The size of the chip.', @@ -70,6 +60,17 @@ const meta: MetaComponent = { category: 'General', }, }, + disabled: { + name: 'Disabled', + description: + 'If `true`, the chip is disabled.
There are accessibility concerns with the disabled state.
Please read our disabled state accessibility guide.
', + control: { + type: 'boolean', + }, + table: { + category: 'General', + }, + }, active: { name: 'Active', description: 'If `true`, the chip is active.', @@ -84,10 +85,13 @@ const meta: MetaComponent = { category: 'General', }, }, - disabled: { - name: 'Disabled', - description: - 'If `true`, the chip is disabled.
There are accessibility concerns with the disabled state.
Please read our disabled state accessibility guide.
', + badge: { + name: 'Nested Badge', + description: 'If `true`, a badge is displayed inside the chip.', + if: { + arg: 'type', + eq: 'filter', + }, control: { type: 'boolean', }, diff --git a/packages/styles/src/components/chip.scss b/packages/styles/src/components/chip.scss index d3a8c387b1..4b7cd5e40f 100644 --- a/packages/styles/src/components/chip.scss +++ b/packages/styles/src/components/chip.scss @@ -8,6 +8,7 @@ @use './../mixins/chip' as chip-mx; @use './../mixins/icons' as icons-mx; @use './../placeholders/chip' as chip-ph; +@use './../placeholders/badge' as badge-ph; @use './../functions/icons' as icons-fn; .chip { @@ -54,12 +55,35 @@ &-label { @extend %chip; cursor: pointer; + + > .badge { + color: chip.$chip-hover-color; + background-color: chip.$chip-hover-bg; + border-color: transparent; + transition: chip.$chip-transition; + } } &-input { + @include utilities.visuallyhidden; + &:checked { + .chip-filter-label { - @include chip-mx.chip-active-state; + color: chip.$chip-active-color; + background-color: chip.$chip-active-bg; + border-color: transparent; + + > .badge { + background-color: chip.$chip-bg; + } + + > .chip-text { + text-decoration: underline; + } + + &:hover > .chip-text { + text-decoration: none; + } } &:disabled + .chip-filter-label { @@ -68,11 +92,20 @@ } &:not(:checked) + .chip-filter-label:hover { - @include chip-mx.chip-hover-state; + color: chip.$chip-hover-color; + background-color: chip.$chip-hover-bg; + + > .badge { + background-color: chip.$chip-bg; + } + } + + @include utilities.focus-style('+ .chip-filter-label') { + > .chip-text { + text-decoration: none; + } } - @include utilities.visuallyhidden; - @include utilities.focus-style('+ .chip-filter-label'); @include utilities.disabled-style('+ .chip-filter-label', $text-selector: '> .chip-text') { background-color: chip.$chip-disabled-bg; } @@ -97,26 +130,9 @@ &.chip-filter > .chip-filter-label { @extend %chip-sm; - } -} -@include utilities.high-contrast-mode() { - .chip-filter { - &-input:focus-visible + &-label { - border-color: Highlight; - outline-color: Highlight; + > .badge { + @extend %badge-sm; } - - &-input:checked + &-label { - &:hover { - @include chip-mx.chip-hover-state; - } - } - } - - button.chip, - a.chip, - .chip-filter-label { - transition: none; } } diff --git a/packages/styles/src/placeholders/_chip.scss b/packages/styles/src/placeholders/_chip.scss index 19d98c2ed5..6e593c39a4 100644 --- a/packages/styles/src/placeholders/_chip.scss +++ b/packages/styles/src/placeholders/_chip.scss @@ -28,13 +28,6 @@ white-space: nowrap; } - > .badge { - color: chip.$chip-hover-color; - background-color: chip.$chip-hover-bg; - border-color: transparent; - transition: chip.$chip-transition; - } - // Quick fix for badges in buttons .btn & { position: relative; @@ -47,8 +40,4 @@ font-size: chip.$chip-font-size-sm; gap: chip.$chip-gap-sm; padding-inline: chip.$chip-padding-x-sm; - - > .badge { - @extend %badge-sm; - } } From 359e74ee7d0d637642430329bcfb94275245f731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Fri, 5 Apr 2024 09:33:56 +0200 Subject: [PATCH 30/37] Use mixins instead of placeholders --- packages/styles/src/components/chip.scss | 13 ++--- packages/styles/src/mixins/_chip.scss | 53 ++++++++++---------- packages/styles/src/placeholders/_chip.scss | 43 ---------------- packages/styles/src/placeholders/_index.scss | 1 - 4 files changed, 31 insertions(+), 79 deletions(-) delete mode 100644 packages/styles/src/placeholders/_chip.scss diff --git a/packages/styles/src/components/chip.scss b/packages/styles/src/components/chip.scss index 4b7cd5e40f..9f222ad382 100644 --- a/packages/styles/src/components/chip.scss +++ b/packages/styles/src/components/chip.scss @@ -1,19 +1,14 @@ @forward './../variables/options'; @use './../variables/components/chip'; -@use './../variables/components/forms'; -@use './../variables/components/form-check'; -@use './../variables/color'; @use './../mixins/utilities'; @use './../mixins/chip' as chip-mx; @use './../mixins/icons' as icons-mx; -@use './../placeholders/chip' as chip-ph; @use './../placeholders/badge' as badge-ph; -@use './../functions/icons' as icons-fn; .chip { &-dismissible { - @extend %chip; + @include chip-mx.chip-styles(); position: relative; &::before, @@ -53,7 +48,7 @@ &-filter { &-label { - @extend %chip; + @include chip-mx.chip-styles(); cursor: pointer; > .badge { @@ -115,7 +110,7 @@ .chip-sm { &.chip-dismissible { - @extend %chip-sm; + @include chip-mx.chip-styles-sm(); &::before, &::after { @@ -129,7 +124,7 @@ } &.chip-filter > .chip-filter-label { - @extend %chip-sm; + @include chip-mx.chip-styles-sm(); > .badge { @extend %badge-sm; diff --git a/packages/styles/src/mixins/_chip.scss b/packages/styles/src/mixins/_chip.scss index ccf38df2f7..1e5751aaa7 100644 --- a/packages/styles/src/mixins/_chip.scss +++ b/packages/styles/src/mixins/_chip.scss @@ -1,35 +1,36 @@ +@use './../lic/bootstrap-license'; +@use './../themes/bootstrap/core' as *; + @use './../variables/components/badge'; @use './../variables/components/chip'; @use './../mixins/utilities'; -@mixin chip-hover-state { - color: chip.$chip-hover-color; - background-color: chip.$chip-hover-bg; - - > .badge { - background-color: chip.$chip-bg; - } +@mixin chip-styles { + @include border-radius(chip.$chip-border-radius); + display: inline-flex; + align-items: center; + height: chip.$chip-height; + max-width: chip.$chip-max-width; + padding-inline: chip.$chip-padding-x; + border: chip.$chip-border-width solid chip.$chip-border-color; + gap: chip.$chip-gap; + line-height: chip.$chip-line-height; + font-size: chip.$chip-font-size; + font-weight: chip.$chip-font-weight; + color: chip.$chip-color; + background-color: chip.$chip-bg; + transition: chip.$chip-transition; - @include utilities.high-contrast-mode() { - background-color: Highlight; - border-color: Highlight; - color: HighlightText; - forced-color-adjust: none; // Disable "readability backplate" on blink browser that interferes with the colors on this case + > .chip-text { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; } } -@mixin chip-active-state { - color: chip.$chip-active-color; - background-color: chip.$chip-active-bg; - border-color: transparent; - - > .badge { - background-color: chip.$chip-bg; - } - - @include utilities.high-contrast-mode() { - background-color: SelectedItem; - color: SelectedItemText; - forced-color-adjust: none; // Disable "readability backplate" on blink browser that interferes with the colors on this case - } +@mixin chip-styles-sm { + height: chip.$chip-height-sm; + font-size: chip.$chip-font-size-sm; + gap: chip.$chip-gap-sm; + padding-inline: chip.$chip-padding-x-sm; } diff --git a/packages/styles/src/placeholders/_chip.scss b/packages/styles/src/placeholders/_chip.scss deleted file mode 100644 index 6e593c39a4..0000000000 --- a/packages/styles/src/placeholders/_chip.scss +++ /dev/null @@ -1,43 +0,0 @@ -@use './../themes/bootstrap/core' as *; - -@use './../variables/commons'; -@use './../variables/spacing'; -@use './../variables/components/badge'; -@use './../variables/components/chip'; -@use './../placeholders/badge' as badge-ph; - -%chip { - @include border-radius(chip.$chip-border-radius); - display: inline-flex; - align-items: center; - height: chip.$chip-height; - max-width: chip.$chip-max-width; - padding-inline: chip.$chip-padding-x; - border: chip.$chip-border-width solid chip.$chip-border-color; - gap: chip.$chip-gap; - line-height: chip.$chip-line-height; - font-size: chip.$chip-font-size; - font-weight: chip.$chip-font-weight; - color: chip.$chip-color; - background-color: chip.$chip-bg; - transition: chip.$chip-transition; - - > .chip-text { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - } - - // Quick fix for badges in buttons - .btn & { - position: relative; - top: -1px; - } -} - -%chip-sm { - height: chip.$chip-height-sm; - font-size: chip.$chip-font-size-sm; - gap: chip.$chip-gap-sm; - padding-inline: chip.$chip-padding-x-sm; -} diff --git a/packages/styles/src/placeholders/_index.scss b/packages/styles/src/placeholders/_index.scss index 1e55b7c161..639bb6ad75 100644 --- a/packages/styles/src/placeholders/_index.scss +++ b/packages/styles/src/placeholders/_index.scss @@ -1,6 +1,5 @@ @use './badge'; @use './button'; -@use './chip'; @use './close'; @use './color'; @use './dropdown'; From 399e82db01cb01c8dd079e959f54f4c43b4d741f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Fri, 5 Apr 2024 10:18:26 +0200 Subject: [PATCH 31/37] Improve HCM styles --- packages/styles/src/components/chip.scss | 54 ++++++++++++++----- packages/styles/src/mixins/_utilities.scss | 12 +++-- .../src/variables/components/_chip.scss | 1 + 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/packages/styles/src/components/chip.scss b/packages/styles/src/components/chip.scss index 9f222ad382..34ea754a93 100644 --- a/packages/styles/src/components/chip.scss +++ b/packages/styles/src/components/chip.scss @@ -43,7 +43,7 @@ background-color: chip.$chip-hover-bg; } - @include utilities.disabled-style($text-selector: '> .chip-text'); + @include utilities.disabled-style(); } &-filter { @@ -72,17 +72,42 @@ background-color: chip.$chip-bg; } - > .chip-text { - text-decoration: underline; - } - - &:hover > .chip-text { - text-decoration: none; + @include utilities.high-contrast-mode() { + border-color: Highlight; } } &:disabled + .chip-filter-label { background-color: chip.$chip-disabled-active-bg; + + @include utilities.high-contrast-mode() { + > .chip-text { + text-decoration: underline; + } + } + } + + &:not(:disabled) { + + .chip-filter-label { + > .chip-text { + text-decoration: underline; + transition: text-decoration 150ms cubic-bezier(0.4, 0, 0.2, 1); + } + + &:hover > .chip-text { + text-decoration-color: transparent; + + @include utilities.high-contrast-mode() { + text-decoration-color: initial; + } + } + } + + @include utilities.focus-style('+ .chip-filter-label') { + > .chip-text { + text-decoration-color: transparent; + } + } } } @@ -95,14 +120,15 @@ } } - @include utilities.focus-style('+ .chip-filter-label') { - > .chip-text { - text-decoration: none; - } - } - - @include utilities.disabled-style('+ .chip-filter-label', $text-selector: '> .chip-text') { + @include utilities.disabled-style('+ .chip-filter-label') { background-color: chip.$chip-disabled-bg; + + @include utilities.high-contrast-mode() { + > .badge { + color: GrayText; + border-color: GrayText; + } + } } } } diff --git a/packages/styles/src/mixins/_utilities.scss b/packages/styles/src/mixins/_utilities.scss index 090d8fa25d..b28b1d2ae9 100644 --- a/packages/styles/src/mixins/_utilities.scss +++ b/packages/styles/src/mixins/_utilities.scss @@ -136,19 +136,21 @@ } } -@mixin disabled-style($additional-selector: '', $text-selector: '') { +@mixin disabled-style($additional-selector: '') { &:disabled#{$additional-selector} { pointer-events: none; color: var(--post-gray-40); border-color: var(--post-gray-40); border-style: dashed; background-clip: padding-box; + text-decoration: line-through; + + @include high-contrast-mode() { + color: GrayText; + border-color: GrayText; + } // In case rules need to be slightly adjusted @content; } - - &:disabled#{$additional-selector}#{$text-selector} { - text-decoration: line-through; - } } diff --git a/packages/styles/src/variables/components/_chip.scss b/packages/styles/src/variables/components/_chip.scss index 51cb852fa3..7ad87d0e6d 100644 --- a/packages/styles/src/variables/components/_chip.scss +++ b/packages/styles/src/variables/components/_chip.scss @@ -41,6 +41,7 @@ $chip-active-bg: color.$yellow; $chip-disabled-bg: color.$white; $chip-disabled-active-bg: color.$gray-background; +$chip-text-transition: text-decoration animation.$transition-time-simple animation.$transition-easing-default; $chip-close-button-icon: 2043; $chip-close-button-border-radius: commons.$border-radius-round; From 301205345b5a84f9c60161de49b5e77097f37784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Fri, 5 Apr 2024 12:16:00 +0200 Subject: [PATCH 32/37] Add radio filter chip story --- .../src/stories/components/chip/chip.docs.mdx | 6 +- .../stories/components/chip/chip.stories.ts | 93 ++++++++++++++----- packages/styles/src/components/chip.scss | 2 + 3 files changed, 76 insertions(+), 25 deletions(-) diff --git a/packages/documentation/src/stories/components/chip/chip.docs.mdx b/packages/documentation/src/stories/components/chip/chip.docs.mdx index ea35a40e7f..b34e119fd4 100644 --- a/packages/documentation/src/stories/components/chip/chip.docs.mdx +++ b/packages/documentation/src/stories/components/chip/chip.docs.mdx @@ -25,7 +25,11 @@ import StylesPackageImport from '../../../shared/styles-package-import.mdx'; Filter chips provide a simple means to refine content or search results based on specific attributes. They are personalized checkboxes, allowing users to toggle them to filter content effectively. - + + +Alternatively, filter chips may be used with radio inputs when a single filter selection is needed. + + ### Dismissible Chip diff --git a/packages/documentation/src/stories/components/chip/chip.stories.ts b/packages/documentation/src/stories/components/chip/chip.stories.ts index 0fb867b061..f3edd63f74 100644 --- a/packages/documentation/src/stories/components/chip/chip.stories.ts +++ b/packages/documentation/src/stories/components/chip/chip.stories.ts @@ -11,7 +11,7 @@ const meta: MetaComponent = { render: renderChip, parameters: { controls: { - exclude: ['dismissed'], + exclude: ['dismissed', 'number', 'radio'], }, }, args: { @@ -22,6 +22,8 @@ const meta: MetaComponent = { active: false, badge: false, dismissed: false, + number: 1, + radio: false, }, argTypes: { text: { @@ -124,18 +126,21 @@ function externalControl(story: any, { args }: StoryContext) { } // RENDERER -let index = 0; -function getFilterChip(args: Args, updateArgs: (args: Args) => void, context: StoryContext) { - index++; - - const checkboxId = `chip-example--${context.name.replace(/ /g, '-').toLowerCase()}` + index; +function getFilterChip( + args: Args, + updateArgs: (args: Args) => void, + context: StoryContext, + index?: number, +) { + const inputName = `chip-example--${context.name.replace(/ /g, '-').toLowerCase()}`; + const inputId = typeof index !== 'undefined' ? `${inputName}-${index}` : inputName; const handleChange = (e: Event) => { updateArgs({ active: !args.active }); if (document.activeElement === e.target) { setTimeout(() => { - const element: HTMLInputElement | null = document.querySelector(`#${checkboxId}`); + const element: HTMLInputElement | null = document.querySelector(`#${inputId}`); if (element) element.focus(); }, 25); } @@ -144,17 +149,17 @@ function getFilterChip(args: Args, updateArgs: (args: Args) => void, context: St return html`
-
`; @@ -172,14 +177,14 @@ function getDismissibleChip(args: Args, updateArgs: (args: Args) => void) { `; } -function renderChip(args: Args, context: StoryContext) { +function renderChip(args: Args, context: StoryContext, index?: number) { const [_, updateArgs] = useArgs(); if (args.dismissed) return html` ${nothing} `; if (args.type === 'dismissible') return getDismissibleChip(args, updateArgs); - return getFilterChip(args, updateArgs, context); + return getFilterChip(args, updateArgs, context, index); } // STORIES @@ -189,23 +194,63 @@ export const Default: Story = { decorators: [externalControl], }; -export const FilterChip: Story = { - render: ({ active, ...args }, context) => html` -
- ${renderChip({ ...args, active: true, text: 'Ĉiuj' }, context)} - ${renderChip({ ...args, text: 'Filtru unu' }, context)} - ${renderChip({ ...args, text: 'Filtrilo du' }, context)} - ${renderChip({ ...args, text: 'Filtrilo tri' }, context)} -
- `, +export const FilterCheckboxChip: Story = { + render: ({ active, ...args }, context) => { + const checkboxChips = [ + { text: 'Aventuro', active: true }, + { text: 'Familio' }, + { text: 'Vidoj' }, + ]; + + return html` +
+ Migrandaj Itineroj +
+ ${checkboxChips.map(({ text, active }, index) => + renderChip({ ...args, text, active }, context, index), + )} +
+
+ `; + }, + decorators: [story => html`
${story()}
`], + args: { + type: 'filter', + }, +}; + +export const FilterRadioChip: Story = { + render: ({ active, ...args }, context) => { + const radioChips = [ + { number: 253, text: 'Ĉiuj' }, + { number: 12, text: 'Artikoloj', active: true }, + { number: 5, text: 'Iloj' }, + { number: 236, text: 'Dokumentoj' }, + ]; + + return html` +
+ Serĉrezultoj +
+ ${radioChips.map(({ text, number, active }, index) => + renderChip({ ...args, text, number, active }, context, index), + )} +
+
+ `; + }, + decorators: [story => html`
${story()}
`], args: { type: 'filter', + radio: true, + size: 'Small', + badge: true, }, }; export const Dismissible: Story = { render: ({ dismissed, ...args }, context) => html` -
+
${renderChip({ ...args, text: 'Unua uzanta enigo' }, context)} ${renderChip({ ...args, text: 'Dua uzanta enigo' }, context)} ${renderChip({ ...args, text: 'Tria uzanta enigo' }, context)} diff --git a/packages/styles/src/components/chip.scss b/packages/styles/src/components/chip.scss index 34ea754a93..206fcdba7e 100644 --- a/packages/styles/src/components/chip.scss +++ b/packages/styles/src/components/chip.scss @@ -47,6 +47,8 @@ } &-filter { + display: inline-block; + &-label { @include chip-mx.chip-styles(); cursor: pointer; From d7134db496decc90936ba025ed9f6117334cfedf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Fri, 5 Apr 2024 16:40:53 +0200 Subject: [PATCH 33/37] Add dismiss label on dismissible chips --- .../documentation/src/stories/components/chip/chip.docs.mdx | 2 +- .../documentation/src/stories/components/chip/chip.stories.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/documentation/src/stories/components/chip/chip.docs.mdx b/packages/documentation/src/stories/components/chip/chip.docs.mdx index b34e119fd4..1a6de376b9 100644 --- a/packages/documentation/src/stories/components/chip/chip.docs.mdx +++ b/packages/documentation/src/stories/components/chip/chip.docs.mdx @@ -36,7 +36,7 @@ Alternatively, filter chips may be used with radio inputs when a single filter s Dismissible chips represent pieces of information entered by a user. Each chip includes a close button, enabling users to conveniently remove them from view. -It's important to note that the close button lacks visible text. +It's important to note that the close icon lacks visible text. Therefore, it's imperative to include a visually hidden label to ensure accessibility for users relying on assistive technologies. diff --git a/packages/documentation/src/stories/components/chip/chip.stories.ts b/packages/documentation/src/stories/components/chip/chip.stories.ts index f3edd63f74..142775d49d 100644 --- a/packages/documentation/src/stories/components/chip/chip.stories.ts +++ b/packages/documentation/src/stories/components/chip/chip.stories.ts @@ -172,6 +172,7 @@ function getDismissibleChip(args: Args, updateArgs: (args: Args) => void) { @click="${() => updateArgs({ dismissed: true })}" ?disabled="${args.disabled}" > + Dismiss ${args.text} `; From 0a5f455070184639ed4194f02c9edbc492d9c58b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Fri, 5 Apr 2024 16:46:54 +0200 Subject: [PATCH 34/37] Update migrations --- packages/migrations/src/migrations.json | 6 +- .../src/migrations/v7/badge/index.ts | 106 ++++++++++++++++++ 2 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 packages/migrations/src/migrations/v7/badge/index.ts diff --git a/packages/migrations/src/migrations.json b/packages/migrations/src/migrations.json index 9fd7f27714..2c0eb03364 100644 --- a/packages/migrations/src/migrations.json +++ b/packages/migrations/src/migrations.json @@ -101,10 +101,10 @@ "description": "Improves the post stepper accessibility.", "factory": "./migrations/post/stepper" }, - "migration-bootstrap-chip": { + "migration-badge-to-chip-or-tag": { "version": "7.0.0", - "description": "Renames badges to chips.", - "factory": "./migrations/bootstrap/chip" + "description": "Migrates badges to chip or tag depending on the content.", + "factory": "./migrations/v7/badge" } } } diff --git a/packages/migrations/src/migrations/v7/badge/index.ts b/packages/migrations/src/migrations/v7/badge/index.ts new file mode 100644 index 0000000000..bb10137f16 --- /dev/null +++ b/packages/migrations/src/migrations/v7/badge/index.ts @@ -0,0 +1,106 @@ +import { Rule } from '@angular-devkit/schematics'; +import type { AnyNode, Cheerio, CheerioAPI } from 'cheerio'; +import { DomUpdate, getDomMigrationRule } from '../../../utils/dom-migration'; +import { themeColors } from '../../../utils/constants'; + +export default function (): Rule { + return getDomMigrationRule( + new BadgeCheckToChipFilterUpdate(), + new BadgeToChipDismissibleUpdate(), + new BadgeToTagUpdate(), + ); +} + +class BadgeCheckToChipFilterUpdate implements DomUpdate { + selector = '.badge-check'; + + update($elements: Cheerio, $: CheerioAPI) { + $elements.each((_i, element) => { + const $element = $(element); + + $element.removeClass('badge-check').addClass('chip-filter'); + + const $input = $element.children('.badge-check-input'); + if ($input) $input.removeClass('badge-check-input').addClass('chip-filter-input'); + + const $label = $element.children('.badge-check-label'); + if ($label) $label.removeClass('badge-check-label').addClass('chip-filter-label'); + + addChipTextClass($label); + }); + } +} + +class BadgeToChipDismissibleUpdate implements DomUpdate { + selector = '.badge'; + + update($elements: Cheerio, $: CheerioAPI) { + $elements.each((_i, element) => { + const $element = $(element); + + // only update badge with close button + const $closeBtn = $element.children('.btn-close'); + if (!$closeBtn.length) { + return; + } + + addChipTextClass($element); + + $closeBtn.removeAttr('class').addClass('chip chip-dismissible'); + + const ariaLabel = $closeBtn.attr('aria-label'); + if (ariaLabel) { + $closeBtn.removeAttr('aria-label'); + $closeBtn.append(`${ariaLabel}`); + } + + $closeBtn.append($element.children()).data($element.data()); + + $element.replaceWith($closeBtn); + }); + } +} + +class BadgeToTagUpdate implements DomUpdate { + selector = '.badge'; + + bgClassRegex: RegExp = new RegExp(`^bg-(${themeColors.join('|')})$`); + + update($elements: Cheerio, $: CheerioAPI) { + $elements.each((_i, element) => { + const $element = $(element); + + // do not update nested badges + const $parent = $element.parent(); + if ($parent.hasClass('tag')) { + return; + } + + $element.removeClass('badge').addClass('tag'); + + if ($element.hasClass('badge-sm')) $element.removeClass('badge-sm').addClass('tag-sm'); + + $element + .attr('class') + ?.split(' ') + .forEach(cssClass => { + const [_, bgColor] = cssClass.match(this.bgClassRegex) ?? []; + + if (!bgColor) return; + + if (bgColor === 'active' || bgColor === 'yellow') $element.addClass('tag-yellow'); + if (bgColor === 'white') $element.addClass('tag-white'); + if (bgColor === 'info') $element.addClass('tag-info'); + if (bgColor === 'success') $element.addClass('tag-success'); + if (bgColor === 'danger') $element.addClass('tag-danger'); + if (bgColor === 'warning') $element.addClass('tag-warning'); + + $element.removeClass(cssClass); + }); + }); + } +} + +function addChipTextClass($element: Cheerio) { + $element.children('span:not(.badge)').addClass('chip-text'); +} From 0bbd2329dad31611b75ff102d2e3a9c62c6c60d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Fri, 5 Apr 2024 16:48:07 +0200 Subject: [PATCH 35/37] Fix code smell --- .../documentation/src/stories/components/chip/chip.stories.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/documentation/src/stories/components/chip/chip.stories.ts b/packages/documentation/src/stories/components/chip/chip.stories.ts index 142775d49d..36a3122ddb 100644 --- a/packages/documentation/src/stories/components/chip/chip.stories.ts +++ b/packages/documentation/src/stories/components/chip/chip.stories.ts @@ -1,7 +1,6 @@ import { useArgs } from '@storybook/preview-api'; import type { Args, StoryContext, StoryObj } from '@storybook/web-components'; import { html, nothing } from 'lit'; -import { mapClasses } from '../../../utils'; import { MetaComponent } from '../../../../types'; const meta: MetaComponent = { From fc13c129e5cf989fbeb00cce6d3920eb08c4934c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Mon, 8 Apr 2024 13:26:49 +0200 Subject: [PATCH 36/37] fix styles linting --- packages/styles/src/components/chip.scss | 180 +++++++++--------- .../src/variables/components/_chip.scss | 3 +- 2 files changed, 90 insertions(+), 93 deletions(-) diff --git a/packages/styles/src/components/chip.scss b/packages/styles/src/components/chip.scss index 206fcdba7e..fa0c61e98f 100644 --- a/packages/styles/src/components/chip.scss +++ b/packages/styles/src/components/chip.scss @@ -6,130 +6,126 @@ @use './../mixins/icons' as icons-mx; @use './../placeholders/badge' as badge-ph; -.chip { - &-dismissible { - @include chip-mx.chip-styles(); - position: relative; +.chip-dismissible { + @include chip-mx.chip-styles(); + position: relative; - &::before, - &::after { - content: ''; - display: inline-block; - flex: 0 0 auto; - height: chip.$chip-close-button-height; - width: chip.$chip-close-button-height; - transition: chip.$chip-transition; - } - - &::after { - @include icons-mx.icon(chip.$chip-close-button-icon); - position: absolute; - top: 50%; - left: chip.$chip-padding-x; - transform: translateY(-50%); - } + &::before, + &::after { + content: ''; + display: inline-block; + flex: 0 0 auto; + height: chip.$chip-close-button-height; + width: chip.$chip-close-button-height; + transition: chip.$chip-transition; + } - &::before { - border-radius: chip.$chip-close-button-border-radius; - } + &::before { + border-radius: chip.$chip-close-button-border-radius; + } - &:hover::before { - background-color: chip.$chip-hover-bg; - } + &:hover::before { + background-color: chip.$chip-hover-bg; + } - // set the focus ring on the close button only - @include utilities.focus-style-none(); - @include utilities.focus-style('::before') { - background-color: chip.$chip-hover-bg; - } + &::after { + @include icons-mx.icon(chip.$chip-close-button-icon); + position: absolute; + top: 50%; + left: chip.$chip-padding-x; + transform: translateY(-50%); + } - @include utilities.disabled-style(); + // set the focus ring on the close button only + @include utilities.focus-style-none(); + @include utilities.focus-style('::before') { + background-color: chip.$chip-hover-bg; } - &-filter { - display: inline-block; + @include utilities.disabled-style(); +} - &-label { - @include chip-mx.chip-styles(); - cursor: pointer; +.chip-filter { + display: inline-block; - > .badge { - color: chip.$chip-hover-color; - background-color: chip.$chip-hover-bg; - border-color: transparent; - transition: chip.$chip-transition; - } + &-label { + @include chip-mx.chip-styles(); + cursor: pointer; + + > .badge { + color: chip.$chip-hover-color; + background-color: chip.$chip-hover-bg; + border-color: transparent; + transition: chip.$chip-transition; } + } - &-input { - @include utilities.visuallyhidden; + &-input { + @include utilities.visuallyhidden; - &:checked { - + .chip-filter-label { - color: chip.$chip-active-color; - background-color: chip.$chip-active-bg; - border-color: transparent; + &:checked { + + .chip-filter-label { + color: chip.$chip-active-color; + background-color: chip.$chip-active-bg; + border-color: transparent; - > .badge { - background-color: chip.$chip-bg; - } + > .badge { + background-color: chip.$chip-bg; + } - @include utilities.high-contrast-mode() { - border-color: Highlight; - } + @include utilities.high-contrast-mode() { + border-color: Highlight; } + } - &:disabled + .chip-filter-label { - background-color: chip.$chip-disabled-active-bg; + &:disabled + .chip-filter-label { + background-color: chip.$chip-disabled-active-bg; - @include utilities.high-contrast-mode() { - > .chip-text { - text-decoration: underline; - } + @include utilities.high-contrast-mode() { + > .chip-text { + text-decoration: underline; } } + } - &:not(:disabled) { - + .chip-filter-label { - > .chip-text { - text-decoration: underline; - transition: text-decoration 150ms cubic-bezier(0.4, 0, 0.2, 1); - } + &:not(:disabled) { + + .chip-filter-label > .chip-text { + text-decoration: underline; + transition: text-decoration 150ms cubic-bezier(0.4, 0, 0.2, 1); + } - &:hover > .chip-text { - text-decoration-color: transparent; + + .chip-filter-label:hover > .chip-text { + text-decoration-color: transparent; - @include utilities.high-contrast-mode() { - text-decoration-color: initial; - } - } + @include utilities.high-contrast-mode() { + text-decoration-color: initial; } + } - @include utilities.focus-style('+ .chip-filter-label') { - > .chip-text { - text-decoration-color: transparent; - } + @include utilities.focus-style('+ .chip-filter-label') { + > .chip-text { + text-decoration-color: transparent; } } } + } - &:not(:checked) + .chip-filter-label:hover { - color: chip.$chip-hover-color; - background-color: chip.$chip-hover-bg; + &:not(:checked) + .chip-filter-label:hover { + color: chip.$chip-hover-color; + background-color: chip.$chip-hover-bg; - > .badge { - background-color: chip.$chip-bg; - } + > .badge { + background-color: chip.$chip-bg; } + } - @include utilities.disabled-style('+ .chip-filter-label') { - background-color: chip.$chip-disabled-bg; + @include utilities.disabled-style('+ .chip-filter-label') { + background-color: chip.$chip-disabled-bg; - @include utilities.high-contrast-mode() { - > .badge { - color: GrayText; - border-color: GrayText; - } + @include utilities.high-contrast-mode() { + > .badge { + color: GrayText; + border-color: GrayText; } } } diff --git a/packages/styles/src/variables/components/_chip.scss b/packages/styles/src/variables/components/_chip.scss index bd2f838537..57fca6157c 100644 --- a/packages/styles/src/variables/components/_chip.scss +++ b/packages/styles/src/variables/components/_chip.scss @@ -41,7 +41,8 @@ $chip-active-bg: color.$yellow; $chip-disabled-bg: color.$white; $chip-disabled-active-bg: color.$gray; -$chip-text-transition: text-decoration animation.$transition-time-simple animation.$transition-easing-default; +$chip-text-transition: text-decoration animation.$transition-time-simple + animation.$transition-easing-default; $chip-close-button-icon: 2043; $chip-close-button-border-radius: commons.$border-radius-round; From 421e4c09d0e064ec23b3ed83995aa1116b38221d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Mon, 8 Apr 2024 13:27:48 +0200 Subject: [PATCH 37/37] Update chip.stories.ts --- .../documentation/src/stories/components/chip/chip.stories.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/documentation/src/stories/components/chip/chip.stories.ts b/packages/documentation/src/stories/components/chip/chip.stories.ts index 36a3122ddb..13acc113be 100644 --- a/packages/documentation/src/stories/components/chip/chip.stories.ts +++ b/packages/documentation/src/stories/components/chip/chip.stories.ts @@ -171,8 +171,8 @@ function getDismissibleChip(args: Args, updateArgs: (args: Args) => void) { @click="${() => updateArgs({ dismissed: true })}" ?disabled="${args.disabled}" > - Dismiss ${args.text} + Dismiss `; }