From eb8515fcc5e2e365c8690b9c4e52f6c149bc2625 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Julien=20D=C3=A9ramond?= Date: Mon, 9 Jan 2023 23:08:08 +0100 Subject: [PATCH] Add chip component --- scss/_chip.scss | 106 ++++++++++ scss/_variables.scss | 32 +++ scss/bootstrap.scss | 1 + scss/forms/_form-check.scss | 26 +++ site/content/docs/5.3/components/chip.md | 207 ++++++++++++++++++++ site/content/docs/5.3/customize/overview.md | 1 + site/data/sidebar.yml | 1 + 7 files changed, 374 insertions(+) create mode 100644 scss/_chip.scss create mode 100644 site/content/docs/5.3/components/chip.md diff --git a/scss/_chip.scss b/scss/_chip.scss new file mode 100644 index 0000000000..c3f677a664 --- /dev/null +++ b/scss/_chip.scss @@ -0,0 +1,106 @@ +// stylelint-disable function-disallowed-list + +// Base class +// + +.chip { + // scss-docs-start chip-css-vars + --#{$prefix}chip-gap: #{$chip-gap}; + --#{$prefix}chip-padding-x: #{$chip-padding-x}; + --#{$prefix}chip-padding-y: #{$chip-padding-y}; + @include rfs($chip-font-size, --#{$prefix}chip-font-size); + --#{$prefix}chip-font-shift: #{$chip-font-shift}; + --#{$prefix}chip-font-weight: #{$chip-font-weight}; + --#{$prefix}chip-icon-size: #{$chip-icon-size}; + --#{$prefix}chip-icon-margin-start: #{$chip-icon-margin-start}; + --#{$prefix}chip-close-size: .5rem; + --#{$prefix}chip-close-margin-end: #{$chip-close-margin-end}; + --#{$prefix}chip-close-margin-start: #{$chip-close-margin-start}; + --#{$prefix}chip-border-width: #{$chip-border-width}; + --#{$prefix}chip-border-radius: #{$chip-border-radius}; + --#{$prefix}chip-border-color: #{$chip-border-color}; + --#{$prefix}chip-active-color: #{$chip-active-color}; + --#{$prefix}chip-active-decoration-color: #{$chip-active-decoration-color}; + --#{$prefix}chip-disabled-color: #{$chip-disabled-color}; + --#{$prefix}chip-outline-color: var(--#{$prefix}link-hover-color); + // scss-docs-end chip-css-vars + + display: inline-flex; + gap: var(--#{$prefix}chip-gap); + align-items: center; + padding: subtract(var(--#{$prefix}chip-padding-y), calc(var(--#{$prefix}chip-font-shift) * .5)) var(--#{$prefix}chip-padding-x) add(var(--#{$prefix}chip-padding-y), calc(var(--#{$prefix}chip-font-shift) * .5)); + @include font-size(var(--#{$prefix}chip-font-size)); + font-weight: var(--#{$prefix}chip-font-weight); + line-height: add(var(--#{$prefix}chip-font-size), .125rem); + color: inherit; + background-color: transparent; + border: var(--#{$prefix}chip-border-width) solid var(--#{$prefix}chip-border-color); + @include border-radius(var(--#{$prefix}chip-border-radius)); + + img, + svg { + width: var(--#{$prefix}chip-icon-size); + min-width: var(--#{$prefix}chip-icon-size); // Here to avoid weird behavior on wrap + height: var(--#{$prefix}chip-icon-size); + margin: add(calc(-.5 * var(--#{$prefix}chip-icon-size)), var(--#{$prefix}chip-font-shift)) 0 calc(-.5 * var(--#{$prefix}chip-icon-size)) var(--#{$prefix}chip-icon-margin-start); + } + + > .btn-close { + width: var(--#{$prefix}chip-close-size); + height: var(--#{$prefix}chip-close-size); + padding: .25em; + } + + &[disabled], + &.disabled { + color: var(--#{$prefix}chip-disabled-color); + pointer-events: none; + border-color: var(--#{$prefix}chip-disabled-color); + } +} + +// stylelint-disable selector-no-qualifying-type +a.chip, +button.chip, +label.chip { + color: inherit; + text-decoration: none; + cursor: pointer; + // outline-offset: $outline-offset; + + &:hover { + border-color: var(--#{$prefix}chip-active-decoration-color); + } + + /* &:focus[data-focus-visible-added] { + outline: $outline-width * 1.5 solid var(--#{$prefix}chip-outline-color); + outline-offset: $outline-offset; + } */ + + &.active, + &:active { + color: var(--#{$prefix}chip-active-color); + background-color: var(--#{$prefix}chip-active-decoration-color); + border-color: var(--#{$prefix}chip-active-decoration-color); + + &[disabled], + &.disabled { + background-color: var(--#{$prefix}chip-disabled-color); + border-color: var(--#{$prefix}chip-disabled-color); + } + } +} +// stylelint-enable selector-no-qualifying-type + +.chip-sm { + // scss-docs-start chip-sm-css-vars + --#{$prefix}chip-padding-x: #{$chip-padding-x-sm}; + --#{$prefix}chip-padding-y: #{$chip-padding-y-sm}; + --#{$prefix}chip-font-size: #{$chip-font-size-sm}; + --#{$prefix}chip-icon-size: #{$chip-icon-size-sm}; + --#{$prefix}chip-icon-margin-start: #{$chip-icon-margin-start-sm}; + --#{$prefix}chip-close-margin-end: #{$chip-close-margin-end-sm}; + --#{$prefix}chip-close-margin-start: #{$chip-close-margin-start-sm}; + // scss-docs-end chip-sm-css-vars +} + diff --git a/scss/_variables.scss b/scss/_variables.scss index 038d347324..5f5b0531b7 100644 --- a/scss/_variables.scss +++ b/scss/_variables.scss @@ -1461,6 +1461,38 @@ $badge-padding-x: .65em !default; $badge-border-radius: $border-radius !default; // scss-docs-end badge-variables +// Chips + +// scss-docs-start chip-variables +$chip-gap: map-get($spacers, 1) !default; +$chip-font-shift: $spacer * .1 !default; +$chip-font-weight: $font-weight-normal !default; +$chip-border-width: $border-width !default; +$chip-border-radius: $border-radius !default; + +$chip-padding-x: $spacer * .65 !default; +$chip-padding-y: $spacer * .45 !default; +$chip-icon-size: $spacer * 1.2 !default; +$chip-icon-margin-start: -$spacer * .35 !default; +$chip-close-margin-end: -$spacer * .3 !default; +$chip-close-margin-start: $spacer * .2 !default; +$chip-font-size: $font-size-base !default; + +$chip-active-color: $component-active-color !default; +$chip-disabled-color: $gray-500 !default; +$chip-border-color: $gray-500 !default; +$chip-active-decoration-color: $component-active-bg !default; +// scss-docs-end chip-variables + +// scss-docs-start chip-sm-variables +$chip-padding-x-sm: $spacer * .4 !default; +$chip-padding-y-sm: $spacer * .25 !default; +$chip-icon-size-sm: $spacer !default; +$chip-icon-margin-start-sm: -$spacer * .1 !default; +$chip-close-margin-end-sm: -$spacer * .25 !default; +$chip-close-margin-start-sm: 0 !default; +$chip-font-size-sm: $font-size-sm !default; +// scss-docs-end chip-sm-variables // Modals diff --git a/scss/bootstrap.scss b/scss/bootstrap.scss index 449d704878..e94368d083 100644 --- a/scss/bootstrap.scss +++ b/scss/bootstrap.scss @@ -43,6 +43,7 @@ @import "spinners"; @import "offcanvas"; @import "placeholders"; +@import "chip"; // Helpers @import "helpers"; diff --git a/scss/forms/_form-check.scss b/scss/forms/_form-check.scss index 83aacba2ed..41bbb63ae8 100644 --- a/scss/forms/_form-check.scss +++ b/scss/forms/_form-check.scss @@ -176,6 +176,32 @@ filter: none; opacity: $form-check-btn-check-disabled-opacity; } + + + .chip { + color: var(--#{$prefix}chip-disabled-color); + pointer-events: none; + border-color: var(--#{$prefix}chip-disabled-color); + } + + &:checked + .chip { + color: var(--#{$prefix}chip-active-color); + background-color: var(--#{$prefix}chip-disabled-color); + } + } + + &:checked { + + .chip { + color: var(--bs-chip-active-color); + background-color: var(--bs-chip-active-decoration-color); + border-color: var(--bs-chip-active-decoration-color); + } + } + + &:focus-visible { + + .chip { + outline: 1px * 1.5 solid var(--#{$prefix}chip-outline-color); + outline-offset: .125rem; + } } } diff --git a/site/content/docs/5.3/components/chip.md b/site/content/docs/5.3/components/chip.md new file mode 100644 index 0000000000..1d12b259de --- /dev/null +++ b/site/content/docs/5.3/components/chip.md @@ -0,0 +1,207 @@ +--- +layout: docs +title: Chips +description: Use chips to convey information, apply filters or display a selection of items. +group: components +toc: true +added: "5.3" +--- + +## Examples + +A chip is basically a `` that can contain text, and optionally an image and/or a close button. Please **adapt the HTML** to be semantically correct. + +{{< callout warning >}} +You shouldn't mix the different chips versions in the same area since they look the same and have different behaviors. +{{< /callout >}} + +### Informative + +Informative chips are built on top of `` and are usually used to display categories. They have no specific interaction. + +For a list of chips of an article, for example, add a heading (`

–

`) to explain that we are in a chips list and use `
    ` or `
      ` depending on the use case. + +{{< example >}} +
        +
      • Bird
      • +
      • + + + Twitter + +
      • +
      +{{< /example >}} + +### Filter + +A chip can be actionable either when built on top of a ` +
    1. + +
    2. +
+{{< /example >}} + +### Navigation + +Another way to build actionable chips is to build them on top of ``. These kind of chips are usually used as anchor links. + +Put an explicit heading to add semantics. The text of the link must be clear enough to explain the destination of the chip. +Most of the time, chips must be inside a list (`
    ` or `
      `). + +{{< example >}} +
        +
      1. 1. Introduction
      2. +
      3. 2. Exposure
      4. +
      +{{< /example >}} + +### Input + +This kind of chips are built on ``. + +For a list of selected items use `
        ` or `
          `. + +{{< example class="d-flex gap-2 align-items-center" >}} +
            +
          • + Dismissible chip + +
          • +
          • + + Dismissible chip + +
          • +
          +{{< /example >}} + +## Sizes + +{{< callout info >}} +We add an extra `

          ` around the `` here for accessibility concerns. +{{< /callout >}} + +Add `.chip-sm` to the `.chip` for a small variant. + +{{< example class="d-flex gap-2 align-items-center" >}} +

          Small chip variant

          +

          Informative

          + +Navigation +

          + + + Input + +

          +{{< /example >}} + +## Disabled state + +{{< callout info >}} +We add an extra `

          ` around the `` here for accessibility concerns. +{{< /callout >}} + +Add `.disabled` to the `.chip` for a disabled variant. Don't forget to add `aria-disabled` to `` and `disabled` attribute to ` +Navigation +

          + + Input + +

          +{{< /example >}} + +## Rounded chips + +Use the `.rounded-pill` utility class to make chips more rounded with a larger `border-radius`. + +{{< example class="d-flex gap-2 align-items-center" >}} +

          Rounded chip variant

          +

          Informative

          + +Navigation +

          + + Input + +

          +{{< /example >}} + +## CSS + +### Variables + +Values for the CSS variables are set via Sass, so Sass customization is still supported, too. + +{{< scss-docs name="chip-css-vars" file="scss/_chip.scss" >}} + +Customization through CSS variables can be seen on the `.chip-sm` class where we override specific values without adding duplicate CSS selectors. + +{{< scss-docs name="chip-sm-css-vars" file="scss/_chip.scss" >}} + +### Sass Variables + +Variables for all chips: + +{{< scss-docs name="chip-variables" file="scss/_variables.scss" >}} + +Variables for the [small chip](#sizes): + +{{< scss-docs name="chip-sm-variables" file="scss/_variables.scss" >}} diff --git a/site/content/docs/5.3/customize/overview.md b/site/content/docs/5.3/customize/overview.md index 25c31bdb6c..b708b88ccb 100644 --- a/site/content/docs/5.3/customize/overview.md +++ b/site/content/docs/5.3/customize/overview.md @@ -47,5 +47,6 @@ Several Bootstrap components include embedded SVGs in our CSS to style component - [Form validation icons]({{< docsref "/forms/validation#server-side" >}}) - [Navbar toggle buttons]({{< docsref "/components/navbar#responsive-behaviors" >}}) - [Select menus]({{< docsref "/forms/select" >}}) +- [Chips]({{< docsref "/components/chip" >}}) Based on [community conversation](https://github.com/twbs/bootstrap/issues/25394), some options for addressing this in your own codebase include [replacing the URLs with locally hosted assets]({{< docsref "/getting-started/webpack#extracting-svg-files" >}}), removing the images and using inline images (not possible in all components), and modifying your CSP. Our recommendation is to carefully review your own security policies and decide on the best path forward, if necessary. diff --git a/site/data/sidebar.yml b/site/data/sidebar.yml index dea26b401a..989dede353 100644 --- a/site/data/sidebar.yml +++ b/site/data/sidebar.yml @@ -80,6 +80,7 @@ - title: Button group - title: Card - title: Carousel + - title: Chip - title: Close button - title: Collapse - title: Dropdowns -- 2.47.2