diff --git a/js/src/nav-overflow.js b/js/src/nav-overflow.js index a443c2007b93..a6fa1d103642 100644 --- a/js/src/nav-overflow.js +++ b/js/src/nav-overflow.js @@ -242,20 +242,25 @@ class NavOverflow extends BaseComponent { const overflowWidth = overflowItem?.offsetWidth || 0 + // Keep items are always visible; subtract their widths so the threshold + // reflects actual available space for non-keep items. + const keepWidth = this._items + .filter(item => item.classList.contains(CLASS_NAME_KEEP)) + .reduce((sum, item) => sum + item.offsetWidth, 0) + let usedWidth = 0 const itemsToOverflow = [] - const overflowThreshold = navWidth - overflowWidth - 10 // 10px buffer + const overflowThreshold = navWidth - overflowWidth - keepWidth - 10 // 10px buffer // Calculate which items need to overflow (skip items with keep class) for (const item of this._items) { - const itemWidth = item.offsetWidth - usedWidth += itemWidth - // Never overflow items with the keep class if (item.classList.contains(CLASS_NAME_KEEP)) { continue } + usedWidth += item.offsetWidth + if (usedWidth > overflowThreshold) { itemsToOverflow.push(item) } diff --git a/scss/_accordion.scss b/scss/_accordion.scss index a1cce3fd7694..b95606603d01 100644 --- a/scss/_accordion.scss +++ b/scss/_accordion.scss @@ -19,7 +19,7 @@ $accordion-tokens: defaults( --accordion-transition: var(--accordion-transition-property) var(--accordion-timing), --accordion-border-color: var(--border-color), --accordion-border-width: var(--border-width), - --accordion-border-radius: var(--accordion-radius, var(--border-radius-lg)), + --accordion-border-radius: var(--accordion-radius, var(--radius-7)), --accordion-btn-color: var(--fg-2), --accordion-btn-bg: var(--bg-body), --accordion-btn-icon-width: 1rem, diff --git a/scss/_alert.scss b/scss/_alert.scss index 1094ee18f36b..10077c8b98aa 100644 --- a/scss/_alert.scss +++ b/scss/_alert.scss @@ -16,7 +16,7 @@ $alert-tokens: defaults( --alert-color: var(--theme-fg, inherit), --alert-border-color: var(--theme-border, var(--border-color)), --alert-border: var(--border-width) solid var(--alert-border-color), - --alert-border-radius: var(--border-radius), + --alert-border-radius: var(--radius-5), --alert-link-color: inherit, --hr-border-color: var(--theme-border, var(--border-color)), ), diff --git a/scss/_badge.scss b/scss/_badge.scss index b57ed0464246..7fdb38d88503 100644 --- a/scss/_badge.scss +++ b/scss/_badge.scss @@ -16,7 +16,7 @@ $badge-tokens: defaults( --badge-bg: var(--bg-2), --badge-border-width: var(--border-width), --badge-border-color: transparent, - --badge-border-radius: var(--border-radius-lg), + --badge-border-radius: var(--radius-7), ), $badge-tokens ); diff --git a/scss/_breadcrumb.scss b/scss/_breadcrumb.scss index 1f49d6b020e8..499d352310ab 100644 --- a/scss/_breadcrumb.scss +++ b/scss/_breadcrumb.scss @@ -12,7 +12,7 @@ $breadcrumb-tokens: defaults( --breadcrumb-margin-bottom: 1rem, --breadcrumb-font-size: inherit, --breadcrumb-bg: transparent, - --breadcrumb-border-radius: var(--border-radius), + --breadcrumb-border-radius: var(--radius-5), --breadcrumb-divider-color: var(--fg-4), --breadcrumb-link-padding-x: .75rem, --breadcrumb-link-padding-y: .25rem, @@ -20,7 +20,7 @@ $breadcrumb-tokens: defaults( --breadcrumb-link-hover-color: var(--fg-2), --breadcrumb-link-hover-bg: var(--bg-1), --breadcrumb-link-active-color: var(--fg-1), - --breadcrumb-link-border-radius: var(--border-radius-lg), + --breadcrumb-link-border-radius: var(--radius-7), ), $breadcrumb-tokens ); diff --git a/scss/_card.scss b/scss/_card.scss index 406696168d04..97aa9c9bbb75 100644 --- a/scss/_card.scss +++ b/scss/_card.scss @@ -16,9 +16,9 @@ $card-tokens: defaults( --card-subtitle-color: inherit, --card-border-width: var(--border-width), --card-border-color: var(--border-color-translucent), - --card-border-radius: var(--border-radius-lg), + --card-border-radius: var(--radius-7), --card-box-shadow: none, - --card-inner-border-radius: calc(var(--border-radius-lg) - var(--border-width)), + --card-inner-border-radius: calc(var(--radius-7) - var(--border-width)), --card-cap-padding-y: var(--spacer-3), --card-cap-padding-x: var(--spacer), --card-cap-bg: var(--bg-1), diff --git a/scss/_chip.scss b/scss/_chip.scss index 2b354b92f054..9f618ba1a2cf 100644 --- a/scss/_chip.scss +++ b/scss/_chip.scss @@ -13,7 +13,7 @@ $chip-tokens: defaults( --chip-height: 1.75rem, --chip-padding-x: .625rem, --chip-gap: .3125rem, - --chip-border-radius: var(--border-radius-pill), + --chip-border-radius: var(--radius-pill), --chip-img-size: 1.25rem, --chip-icon-size: 1rem, --chip-dismiss-size: 1rem, diff --git a/scss/_config.scss b/scss/_config.scss index 81c0f17bb9c8..cdab5f393d56 100644 --- a/scss/_config.scss +++ b/scss/_config.scss @@ -69,17 +69,31 @@ $negative-spacers: ( $sizes: ( 1: $spacer, - 2: calc($spacer * 2), - 3: calc($spacer * 3), - 4: calc($spacer * 4), - 5: calc($spacer * 5), - 6: calc($spacer * 6), - 7: calc($spacer * 7), - 8: calc($spacer * 8), - 9: calc($spacer * 9), - 10: calc($spacer * 10), - 11: calc($spacer * 11), - 12: calc($spacer * 12), + 2: $spacer * 2, + 3: $spacer * 3, + 4: $spacer * 4, + 5: $spacer * 5, + 6: $spacer * 6, + 7: $spacer * 7, + 8: $spacer * 8, + 9: $spacer * 9, + 10: $spacer * 10, + 11: $spacer * 11, + 12: $spacer * 12, +) !default; + +$radius: .5rem !default; +$radii: ( + 0: 0, + 1: $radius * .25, + 2: $radius * .375, + 3: $radius * .5, + 4: $radius * .75, + 5: $radius, + 6: $radius * 1.25, + 7: $radius * 1.5, + 8: $radius * 2, + 9: $radius * 3, ) !default; // Breakpoints diff --git a/scss/_datepicker.scss b/scss/_datepicker.scss index 784949551420..ae8c9adec664 100644 --- a/scss/_datepicker.scss +++ b/scss/_datepicker.scss @@ -17,7 +17,7 @@ $datepicker-tokens: defaults( --datepicker-color: var(--fg-body), --datepicker-border-color: var(--border-color-translucent), --datepicker-border-width: var(--border-width), - --datepicker-border-radius: var(--border-radius-lg), + --datepicker-border-radius: var(--radius-7), --datepicker-box-shadow: var(--box-shadow), --datepicker-font-size: var(--font-size-sm), --datepicker-min-width: 280px, @@ -107,7 +107,7 @@ $datepicker-tokens: defaults( cursor: pointer; background-color: transparent; border: 0; - @include border-radius(var(--border-radius)); + @include border-radius(var(--radius-5)); &::before { position: absolute; @@ -191,7 +191,7 @@ $datepicker-tokens: defaults( // cursor: pointer; background-color: transparent; border: 0; - @include border-radius(var(--border-radius)); + @include border-radius(var(--radius-5)); &:disabled { color: var(--datepicker-day-disabled-color); @@ -240,7 +240,7 @@ $datepicker-tokens: defaults( cursor: pointer; background-color: transparent; border: 0; - @include border-radius(var(--border-radius)); + @include border-radius(var(--radius-5)); &:disabled { color: var(--datepicker-day-disabled-color); @@ -338,7 +338,7 @@ $datepicker-tokens: defaults( cursor: pointer; background-color: transparent; border: 0; - border-radius: var(--border-radius); + border-radius: var(--radius-5); &:hover { background-color: var(--datepicker-day-hover-bg); @@ -370,17 +370,17 @@ $datepicker-tokens: defaults( } [data-vc-date-hover="first"] [data-vc-date-btn] { - border-start-start-radius: var(--border-radius); - border-end-start-radius: var(--border-radius); + border-start-start-radius: var(--radius-5); + border-end-start-radius: var(--radius-5); } [data-vc-date-hover="last"] [data-vc-date-btn] { - border-start-end-radius: var(--border-radius); - border-end-end-radius: var(--border-radius); + border-start-end-radius: var(--radius-5); + border-end-end-radius: var(--radius-5); } [data-vc-date-hover="first-and-last"] [data-vc-date-btn] { - border-radius: var(--border-radius); + border-radius: var(--radius-5); } [data-vc-date-selected="middle"] [data-vc-date-btn] { @@ -396,20 +396,20 @@ $datepicker-tokens: defaults( } [data-vc-date-selected="first"] [data-vc-date-btn] { - border-top-left-radius: var(--border-radius); + border-top-left-radius: var(--radius-5); border-top-right-radius: 0; border-bottom-right-radius: 0; - border-bottom-left-radius: var(--border-radius); + border-bottom-left-radius: var(--radius-5); } [data-vc-date-selected="last"] [data-vc-date-btn] { border-top-left-radius: 0; - border-top-right-radius: var(--border-radius); - border-bottom-right-radius: var(--border-radius); + border-top-right-radius: var(--radius-5); + border-bottom-right-radius: var(--radius-5); border-bottom-left-radius: 0; } [data-vc-date-selected="first-and-last"] [data-vc-date-btn] { - border-radius: var(--border-radius); + border-radius: var(--radius-5); } } diff --git a/scss/_dialog.scss b/scss/_dialog.scss index b67288c94aad..a9b268362920 100644 --- a/scss/_dialog.scss +++ b/scss/_dialog.scss @@ -26,7 +26,7 @@ $dialog-tokens: defaults( --dialog-bg: var(--bg-body), --dialog-border-color: var(--border-color-translucent), --dialog-border-width: var(--border-width), - --dialog-border-radius: var(--border-radius-lg), + --dialog-border-radius: var(--radius-7), --dialog-box-shadow: var(--box-shadow-lg), --dialog-transition-duration: .3s, --dialog-transition-timing: cubic-bezier(.22, 1, .36, 1), diff --git a/scss/_drawer.scss b/scss/_drawer.scss index 4fc813b4125e..7c9edeac837e 100644 --- a/scss/_drawer.scss +++ b/scss/_drawer.scss @@ -24,7 +24,7 @@ $drawer-tokens: defaults( --drawer-bg: var(--bg-body), --drawer-border-width: var(--border-width), --drawer-border-color: var(--border-color-translucent), - --drawer-border-radius: var(--border-radius-lg), + --drawer-border-radius: var(--radius-7), --drawer-box-shadow: var(--box-shadow-lg), --drawer-transition-duration: .3s, --drawer-transition-timing: cubic-bezier(.22, 1, .36, 1), diff --git a/scss/_list-group.scss b/scss/_list-group.scss index 8052ccfb2e0e..52b0e4b424ce 100644 --- a/scss/_list-group.scss +++ b/scss/_list-group.scss @@ -15,7 +15,7 @@ $list-group-tokens: defaults( --list-group-bg: var(--bg-body), --list-group-border-color: var(--border-color), --list-group-border-width: var(--border-width), - --list-group-border-radius: var(--border-radius), + --list-group-border-radius: var(--radius-5), --list-group-item-padding-x: var(--spacer), --list-group-item-padding-y: var(--spacer-2), --list-group-action-color: var(--fg-2), diff --git a/scss/_menu.scss b/scss/_menu.scss index ed12970911a5..b988cd716f25 100644 --- a/scss/_menu.scss +++ b/scss/_menu.scss @@ -21,7 +21,7 @@ $menu-tokens: defaults( --menu-color: var(--fg-body), --menu-bg: var(--bg-body), // --menu-border-color: var(--border-color-translucent), - // --menu-border-radius: var(--border-radius-lg), + // --menu-border-radius: var(--radius-7), // --menu-border-width: var(--border-width), --menu-box-shadow: var(--box-shadow), // --menu-max-height: none, @@ -37,7 +37,7 @@ $menu-tokens: defaults( --menu-item-gap: .5rem, --menu-item-padding-x: .75rem, --menu-item-padding-y: .25rem, - --menu-item-border-radius: var(--border-radius), + --menu-item-border-radius: var(--radius-5), --menu-icon-size: 1rem, --menu-image-size: 1.5rem, --menu-description-font-size: var(--font-size-xs), @@ -76,7 +76,7 @@ $menu-tokens: defaults( background-color: var(--menu-bg); background-clip: padding-box; border: var(--menu-border-width, var(--border-width)) solid var(--menu-border-color, var(--border-color-translucent)); - @include border-radius(var(--menu-border-radius, var(--border-radius-lg))); + @include border-radius(var(--menu-border-radius, var(--radius-7))); @include box-shadow(var(--menu-box-shadow)); opacity: 0; transform: scale(.95); @@ -206,7 +206,7 @@ $menu-tokens: defaults( width: var(--menu-image-size); height: var(--menu-image-size); object-fit: cover; - @include border-radius(var(--border-radius-sm)); + @include border-radius(var(--radius-5)); } .menu-item-content { diff --git a/scss/_nav-overflow.scss b/scss/_nav-overflow.scss index 28b34c5e0899..0b810a351e16 100644 --- a/scss/_nav-overflow.scss +++ b/scss/_nav-overflow.scss @@ -9,6 +9,18 @@ min-width: 0; // Allow flex child to shrink below content width } + // Pills use inline-flex by default; override so the nav fills its container + // and the ResizeObserver can detect width changes. + .nav-pills.nav-overflow { + display: flex; + } + + // Inside a navbar the nav is a flex child that sizes to content by default; + // grow it so it fills remaining space and shrinks with the container. + .navbar-nav.nav-overflow { + flex: 1 1 0; + } + // Container item for overflow .nav-overflow-item { flex-shrink: 0; diff --git a/scss/_nav.scss b/scss/_nav.scss index 8958d20202f3..7ea73d6f59bb 100644 --- a/scss/_nav.scss +++ b/scss/_nav.scss @@ -41,7 +41,7 @@ $nav-tabs-tokens: defaults( ( --nav-tabs-border-width: var(--border-width), --nav-tabs-border-color: var(--border-color), - --nav-tabs-border-radius: var(--border-radius), + --nav-tabs-border-radius: var(--radius-5), --nav-tabs-link-hover-border-color: var(--border-subtle), --nav-tabs-link-active-color: var(--fg-color), --nav-tabs-link-active-bg: var(--bg-body), @@ -59,8 +59,10 @@ $nav-pills-tokens: defaults( ( --nav-pills-bg: var(--bg-1), --nav-pills-padding: .25rem, + --nav-pills-border-radius: var(--radius-9), --nav-pills-link-active-color: var(--primary-contrast), --nav-pills-link-active-bg: var(--primary-bg), + --nav-pills-link-border-radius: var(--radius-9), ), $nav-pills-tokens ); @@ -114,7 +116,7 @@ $nav-underline-tokens: defaults( white-space: nowrap; background: none; border: var(--nav-link-border-width) solid transparent; - @include border-radius(var(--border-radius)); + @include border-radius(var(--radius-5)); @include transition(var(--nav-link-transition)); &:hover, @@ -192,10 +194,10 @@ $nav-underline-tokens: defaults( display: inline-flex; padding: var(--nav-pills-padding); background-color: var(--nav-pills-bg); - @include border-radius(var(--border-radius-pill)); + @include border-radius(var(--nav-pills-border-radius)); .nav-link { - @include border-radius(var(--border-radius-pill)); + @include border-radius(var(--nav-pills-link-border-radius)); } .nav-link.active, @@ -205,6 +207,16 @@ $nav-underline-tokens: defaults( } } + .nav-pills-vertical { + flex-direction: column; + align-items: stretch; + + .nav-item, + .nav-link { + width: 100%; + } + } + // // Underline // diff --git a/scss/_navbar.scss b/scss/_navbar.scss index 7dc0012c4ba5..7c30a57a20e8 100644 --- a/scss/_navbar.scss +++ b/scss/_navbar.scss @@ -38,7 +38,7 @@ $navbar-tokens: defaults( --navbar-toggler-padding-x: .75rem, --navbar-toggler-font-size: var(--font-size-lg), --navbar-toggler-border-color: color-mix(in oklch, var(--fg-body) 15%, transparent), - --navbar-toggler-border-radius: var(--border-radius), + --navbar-toggler-border-radius: var(--radius-5), --navbar-toggler-transition: box-shadow .15s ease-in-out, ), $navbar-tokens diff --git a/scss/_popover.scss b/scss/_popover.scss index c3b6334e3a8d..9377f5f03ec2 100644 --- a/scss/_popover.scss +++ b/scss/_popover.scss @@ -17,8 +17,8 @@ $popover-tokens: defaults( --popover-bg: var(--bg-body), --popover-border-width: var(--border-width), --popover-border-color: var(--border-color-translucent), - --popover-border-radius: var(--border-radius-lg), - --popover-inner-border-radius: calc(var(--border-radius-lg) - var(--border-width)), + --popover-border-radius: var(--radius-7), + --popover-inner-border-radius: calc(var(--radius-7) - var(--border-width)), --popover-box-shadow: var(--box-shadow), --popover-header-padding-x: var(--spacer), --popover-header-padding-y: var(--spacer-3), diff --git a/scss/_progress.scss b/scss/_progress.scss index 7e905fad5db0..4d042e23bd9c 100644 --- a/scss/_progress.scss +++ b/scss/_progress.scss @@ -15,7 +15,7 @@ $progress-tokens: defaults( --progress-height: 1rem, --progress-font-size: var(--font-size-sm), --progress-bg: var(--bg-2), - --progress-border-radius: var(--border-radius), + --progress-border-radius: var(--radius-5), --progress-box-shadow: var(--box-shadow-inset), --progress-bar-color: var(--white), --progress-bar-bg: var(--primary-bg), diff --git a/scss/_root.scss b/scss/_root.scss index 4abe148b66b8..1eca05d7a2f5 100644 --- a/scss/_root.scss +++ b/scss/_root.scss @@ -54,16 +54,6 @@ $root-tokens: defaults( --border-color-translucent: color-mix(in oklch, var(--fg-body) 15%, transparent), // scss-docs-end root-border-var - // scss-docs-start root-border-radius-var - --border-radius: .5rem, - --border-radius-xs: .375rem, - --border-radius-sm: .5rem, - --border-radius-lg: .75rem, - --border-radius-xl: 1rem, - --border-radius-2xl: 2rem, - --border-radius-pill: 50rem, - // scss-docs-end root-border-radius-var - // scss-docs-start root-box-shadow-variables --box-shadow: 0 .5rem 1rem rgb(0 0 0 / 15%), --box-shadow-sm: 0 .125rem .25rem rgb(0 0 0 / 7.5%), @@ -96,28 +86,28 @@ $root-tokens: defaults( --btn-input-padding-x: .75rem, --btn-input-font-size: var(--font-size-base), --btn-input-line-height: var(--line-height-base), - --btn-input-border-radius: var(--border-radius), + --btn-input-border-radius: var(--radius-5), --btn-input-xs-min-height: 1.5rem, --btn-input-xs-padding-y: .125rem, --btn-input-xs-padding-x: .5rem, --btn-input-xs-font-size: var(--font-size-xs), --btn-input-xs-line-height: 1.125, - --btn-input-xs-border-radius: var(--border-radius-xs), + --btn-input-xs-border-radius: var(--radius-5), --btn-input-sm-min-height: 2rem, --btn-input-sm-padding-y: .25rem, --btn-input-sm-padding-x: .625rem, --btn-input-sm-font-size: var(--font-size-sm), --btn-input-sm-line-height: var(--line-height-sm), - --btn-input-sm-border-radius: var(--border-radius-sm), + --btn-input-sm-border-radius: var(--radius-5), --btn-input-lg-min-height: 2.75rem, --btn-input-lg-padding-y: .5rem, --btn-input-lg-padding-x: 1rem, --btn-input-lg-font-size: var(--font-size-md), --btn-input-lg-line-height: var(--line-height-md), - --btn-input-lg-border-radius: var(--border-radius-lg), + --btn-input-lg-border-radius: var(--radius-7), // scss-docs-end root-form-variables ), $root-tokens @@ -163,9 +153,20 @@ $root-tokens: defaults( } // Generate spacer tokens +// scss-docs-start root-spacer-loop @each $key, $value in $spacers { $root-tokens: map.set($root-tokens, --spacer-#{$key}, $value); } +// scss-docs-end root-spacer-loop + +// Generate radius tokens +// scss-docs-start root-radius-loop +@each $key, $value in $radii { + $root-tokens: map.set($root-tokens, --radius-#{$key}, $value); +} +// stylelint-disable-next-line scss/dollar-variable-default +$root-tokens: map.set($root-tokens, --radius-pill, 50rem); +// scss-docs-end root-radius-loop :root { @include tokens($root-tokens); diff --git a/scss/_toasts.scss b/scss/_toasts.scss index 97aba6950d77..6b6359ea5267 100644 --- a/scss/_toasts.scss +++ b/scss/_toasts.scss @@ -47,7 +47,7 @@ $toast-tokens: defaults( background-clip: padding-box; border: var(--toast-border-width) solid var(--theme-border, var(--toast-border-color)); box-shadow: var(--toast-box-shadow); - @include border-radius(var(--toast-border-radius, var(--border-radius-lg))); + @include border-radius(var(--toast-border-radius, var(--radius-7))); &.showing { opacity: 0; diff --git a/scss/_tooltip.scss b/scss/_tooltip.scss index 6a88e44e4e79..ccbb6bb0bdbd 100644 --- a/scss/_tooltip.scss +++ b/scss/_tooltip.scss @@ -17,7 +17,7 @@ $tooltip-tokens: defaults( --tooltip-font-size: var(--font-size-sm), --tooltip-color: var(--bg-body), --tooltip-bg: var(--fg-body), - --tooltip-border-radius: var(--border-radius), + --tooltip-border-radius: var(--radius-5), --tooltip-opacity: .95, --tooltip-arrow-width: .8rem, --tooltip-arrow-height: .4rem, diff --git a/scss/_utilities.scss b/scss/_utilities.scss index 2779b25daf5a..5b6adb4bbd3b 100644 --- a/scss/_utilities.scss +++ b/scss/_utilities.scss @@ -872,76 +872,61 @@ $utilities: map.merge( "border-radius": ( property: border-radius, class: rounded, - values: ( - null: var(--border-radius), - 0: 0, - 1: var(--border-radius-sm), - 2: var(--border-radius), - 3: var(--border-radius-lg), - 4: var(--border-radius-xl), - 5: var(--border-radius-2xl), - circle: 50%, - pill: var(--border-radius-pill) + values: map.merge( + $radii, + ( + null: map.get($radii, 5), + circle: 50%, + pill: var(--radius-pill) + ) ) ), "rounded-top": ( property: border-start-start-radius border-start-end-radius, class: rounded-top, - values: ( - null: var(--border-radius), - 0: 0, - 1: var(--border-radius-sm), - 2: var(--border-radius), - 3: var(--border-radius-lg), - 4: var(--border-radius-xl), - 5: var(--border-radius-2xl), - circle: 50%, - pill: var(--border-radius-pill) + values: map.merge( + $radii, + ( + null: map.get($radii, 5), + circle: 50%, + pill: var(--radius-pill) + ) ) ), "rounded-end": ( property: border-end-end-radius border-end-start-radius, class: rounded-end, - values: ( - null: var(--border-radius), - 0: 0, - 1: var(--border-radius-sm), - 2: var(--border-radius), - 3: var(--border-radius-lg), - 4: var(--border-radius-xl), - 5: var(--border-radius-2xl), - circle: 50%, - pill: var(--border-radius-pill) + values: map.merge( + $radii, + ( + null: map.get($radii, 5), + circle: 50%, + pill: var(--radius-pill) + ) ) ), "rounded-bottom": ( property: border-end-end-radius border-end-start-radius, class: rounded-bottom, - values: ( - null: var(--border-radius), - 0: 0, - 1: var(--border-radius-sm), - 2: var(--border-radius), - 3: var(--border-radius-lg), - 4: var(--border-radius-xl), - 5: var(--border-radius-2xl), - circle: 50%, - pill: var(--border-radius-pill) + values: map.merge( + $radii, + ( + null: map.get($radii, 5), + circle: 50%, + pill: var(--radius-pill) + ) ) ), "rounded-start": ( property: border-start-start-radius border-start-end-radius, class: rounded-start, - values: ( - null: var(--border-radius), - 0: 0, - 1: var(--border-radius-sm), - 2: var(--border-radius), - 3: var(--border-radius-lg), - 4: var(--border-radius-xl), - 5: var(--border-radius-2xl), - circle: 50%, - pill: var(--border-radius-pill) + values: map.merge( + $radii, + ( + null: map.get($radii, 5), + circle: 50%, + pill: var(--radius-pill) + ) ) ), // scss-docs-end utils-border-radius diff --git a/scss/buttons/_button.scss b/scss/buttons/_button.scss index 3653ffaafbc9..a778c09a7dd7 100644 --- a/scss/buttons/_button.scss +++ b/scss/buttons/_button.scss @@ -27,7 +27,7 @@ $button-tokens: defaults( --btn-white-space: nowrap, --btn-border-width: var(--border-width), --btn-border-color: transparent, - --btn-border-radius: var(--border-radius), + --btn-border-radius: var(--radius-5), --btn-hover-border-color: transparent, --btn-disabled-opacity: .65, --btn-transition-timing: .15s ease-in-out, diff --git a/scss/buttons/_close.scss b/scss/buttons/_close.scss index f1fc957d0be1..98c653eba0a6 100644 --- a/scss/buttons/_close.scss +++ b/scss/buttons/_close.scss @@ -35,7 +35,7 @@ $btn-close-tokens: defaults( color: var(--btn-close-color); background: transparent; // for button elements border: 0; // for button elements - @include border-radius(var(--border-radius-sm)); + @include border-radius(var(--radius-5)); opacity: var(--btn-close-opacity); > svg { diff --git a/scss/content/_images.scss b/scss/content/_images.scss index efad765dde2c..c1f17212dc0f 100644 --- a/scss/content/_images.scss +++ b/scss/content/_images.scss @@ -14,7 +14,7 @@ $thumbnail-tokens: defaults( --thumbnail-bg: var(--bg-body), --thumbnail-border-width: var(--border-width), --thumbnail-border-color: var(--border-color), - --thumbnail-border-radius: var(--border-radius), + --thumbnail-border-radius: var(--radius-5), --thumbnail-box-shadow: var(--box-shadow-sm), ), $thumbnail-tokens diff --git a/scss/content/_reboot.scss b/scss/content/_reboot.scss index 806e7b02e195..7feb7b1cf2c5 100644 --- a/scss/content/_reboot.scss +++ b/scss/content/_reboot.scss @@ -17,7 +17,7 @@ $reboot-kbd-tokens: defaults( --kbd-font-size: var(--font-size-xs), --kbd-color: var(--bg-body), --kbd-bg: var(--fg-2), - --kbd-border-radius: var(--border-radius-sm), + --kbd-border-radius: var(--radius-5), ), $reboot-kbd-tokens ); diff --git a/scss/forms/_chip-input.scss b/scss/forms/_chip-input.scss index edfbff244047..7236c0d0bdf1 100644 --- a/scss/forms/_chip-input.scss +++ b/scss/forms/_chip-input.scss @@ -17,7 +17,7 @@ $chip-input-tokens: defaults( --control-bg: var(--btn-input-bg), --control-border-width: var(--border-width), --control-border-color: var(--border-color), - --control-border-radius: var(--border-radius), + --control-border-radius: var(--radius-5), ), $chip-input-tokens ); @@ -56,58 +56,14 @@ $chip-input-tokens: defaults( // Disabled state &.disabled, &:has(.form-ghost:disabled) { + cursor: not-allowed; background-color: var(--bg-2); opacity: 1; > .chip { + pointer-events: none; opacity: var(--control-disabled-opacity); - - .chip-dismiss { - pointer-events: none; - } - } - - > .form-ghost { - cursor: not-allowed; } } } - - // Theme cascade: .chip-input.theme-* passes theme to child chips - // Chips inherit theme variables from parent - // @each $color-name, $theme-props in $theme-map { - // .chip-input.theme-#{$color-name} > .chip { - // // Subtle default state - // --chip-color: var(--theme-fg); - // --chip-bg: var(--theme-bg-subtle); - - // // Selected/active solid state - // --chip-selected-color: var(--theme-contrast); - // --chip-selected-bg: var(--theme-bg); - // --chip-selected-border-color: var(--theme-bg); - // } - // } - - // // Sizing variants - // .chip-input-sm { - // --control-min-height: #{$control-min-height-sm}; - // --control-padding-y: #{$control-padding-y-sm}; - // --control-padding-x: #{$control-padding-x-sm}; - // --control-font-size: #{$control-font-size-sm}; - // --control-line-height: #{$control-line-height-sm}; - // --control-border-radius: #{$control-border-radius-sm}; - // --chip-input-gap: .25rem; - // --chip-input-chip-font-size: .8125em; - // } - - // .chip-input-lg { - // --control-min-height: #{$control-min-height-lg}; - // --control-padding-y: #{$control-padding-y-lg}; - // --control-padding-x: #{$control-padding-x-lg}; - // --control-font-size: #{$control-font-size-lg}; - // --control-line-height: #{$control-line-height-lg}; - // --control-border-radius: #{$control-border-radius-lg}; - // --chip-input-gap: .5rem; - // --chip-input-chip-font-size: .9375em; - // } } diff --git a/scss/forms/_form-control.scss b/scss/forms/_form-control.scss index 6c501426a191..9ae6ab9bf862 100644 --- a/scss/forms/_form-control.scss +++ b/scss/forms/_form-control.scss @@ -21,7 +21,7 @@ $form-control-tokens: defaults( --control-bg: var(--btn-input-bg), --control-border-width: var(--border-width), --control-border-color: var(--border-color), - --control-border-radius: var(--border-radius), + --control-border-radius: var(--radius-5), --control-box-shadow: var(--box-shadow-inset), --control-action-bg: var(--bg-1), --control-action-hover-bg: var(--bg-2), @@ -239,12 +239,12 @@ $form-control-sizes: defaults( &::-moz-color-swatch { border: 0 !important; // stylelint-disable-line declaration-no-important - @include border-radius(var(--border-radius-sm)); + @include border-radius(var(--radius-5)); } &::-webkit-color-swatch { border: 0 !important; // stylelint-disable-line declaration-no-important - @include border-radius(var(--border-radius-sm)); + @include border-radius(var(--radius-5)); } } diff --git a/scss/forms/_form-field.scss b/scss/forms/_form-field.scss index 68cc79e9eb11..3f58835f513a 100644 --- a/scss/forms/_form-field.scss +++ b/scss/forms/_form-field.scss @@ -46,7 +46,7 @@ padding: calc(var(--spacer) * .75); cursor: pointer; border: var(--border-width) solid transparent; - @include border-radius(var(--border-radius-lg)); + @include border-radius(var(--radius-7)); &:hover { background-color: var(--bg-1); diff --git a/scss/forms/_otp-input.scss b/scss/forms/_otp-input.scss index 25a12f73a71e..2e42960619ec 100644 --- a/scss/forms/_otp-input.scss +++ b/scss/forms/_otp-input.scss @@ -1,8 +1,6 @@ @use "../functions" as *; -@use "../mixins/border-radius" as *; @use "../mixins/tokens" as *; -// stylelint-disable custom-property-no-missing-var-function $otp-tokens: () !default; // scss-docs-start otp-tokens @@ -16,7 +14,6 @@ $otp-tokens: defaults( $otp-tokens ); // scss-docs-end otp-tokens -// stylelint-enable custom-property-no-missing-var-function // scss-docs-start otp-sizes $otp-sizes: () !default; @@ -42,7 +39,6 @@ $otp-sizes: defaults( font-weight: 500; line-height: 1; text-align: center; - @include border-radius(var(--otp-border-radius, var(--btn-input-border-radius))); // Remove default number spinners &::-webkit-outer-spin-button, @@ -80,12 +76,4 @@ $otp-sizes: defaults( color: var(--fg-4); user-select: none; } - - @each $size, $_ in $otp-sizes { - .otp-#{$size} { - --otp-size: var(--btn-input-#{$size}-min-height); - --otp-font-size: var(--btn-input-#{$size}-font-size); - --otp-border-radius: var(--btn-input-#{$size}-border-radius); - } - } } diff --git a/scss/forms/_strength.scss b/scss/forms/_strength.scss index 61b2f1482177..a414023425c9 100644 --- a/scss/forms/_strength.scss +++ b/scss/forms/_strength.scss @@ -14,7 +14,7 @@ $strength-tokens: defaults( --strength-height: .375rem, --strength-gap: .25rem, --strength-margin-top: .25rem, - --strength-border-radius: var(--border-radius-pill), + --strength-border-radius: var(--radius-pill), --strength-bg: var(--bg-2), --strength-color: var(--bg-2), --strength-weak-color: var(--danger-bg), diff --git a/scss/mixins/_border-radius.scss b/scss/mixins/_border-radius.scss index 69de12ff0353..6dd7e6175dc1 100644 --- a/scss/mixins/_border-radius.scss +++ b/scss/mixins/_border-radius.scss @@ -20,7 +20,7 @@ } // scss-docs-start border-radius-mixins -@mixin border-radius($radius: var(--border-radius), $fallback-border-radius: false) { +@mixin border-radius($radius: var(--radius-5), $fallback-border-radius: false) { @if $enable-rounded { border-radius: valid-radius($radius); } @@ -29,53 +29,53 @@ } } -@mixin border-top-radius($radius: var(--border-radius)) { +@mixin border-top-radius($radius: var(--radius-5)) { @if $enable-rounded { border-start-start-radius: valid-radius($radius); border-start-end-radius: valid-radius($radius); } } -@mixin border-end-radius($radius: var(--border-radius)) { +@mixin border-end-radius($radius: var(--radius-5)) { @if $enable-rounded { border-start-end-radius: valid-radius($radius); border-end-end-radius: valid-radius($radius); } } -@mixin border-bottom-radius($radius: var(--border-radius)) { +@mixin border-bottom-radius($radius: var(--radius-5)) { @if $enable-rounded { border-end-start-radius: valid-radius($radius); border-end-end-radius: valid-radius($radius); } } -@mixin border-start-radius($radius: var(--border-radius)) { +@mixin border-start-radius($radius: var(--radius-5)) { @if $enable-rounded { border-start-start-radius: valid-radius($radius); border-end-start-radius: valid-radius($radius); } } -@mixin border-top-start-radius($radius: var(--border-radius)) { +@mixin border-top-start-radius($radius: var(--radius-5)) { @if $enable-rounded { border-start-start-radius: valid-radius($radius); } } -@mixin border-top-end-radius($radius: var(--border-radius)) { +@mixin border-top-end-radius($radius: var(--radius-5)) { @if $enable-rounded { border-start-end-radius: valid-radius($radius); } } -@mixin border-bottom-end-radius($radius: var(--border-radius)) { +@mixin border-bottom-end-radius($radius: var(--radius-5)) { @if $enable-rounded { border-end-end-radius: valid-radius($radius); } } -@mixin border-bottom-start-radius($radius: var(--border-radius)) { +@mixin border-bottom-start-radius($radius: var(--radius-5)) { @if $enable-rounded { border-end-start-radius: valid-radius($radius); } diff --git a/scss/tests/modules/_configuration.test.scss b/scss/tests/modules/_configuration.test.scss index 94c3bd5231a6..1fc7b974c7d1 100644 --- a/scss/tests/modules/_configuration.test.scss +++ b/scss/tests/modules/_configuration.test.scss @@ -10,7 +10,7 @@ --alert-color: var(--theme-fg, inherit), --alert-border-color: var(--theme-border, var(--border-color)), --alert-border: var(--border-width) solid var(--alert-border-color), - --alert-border-radius: var(--border-radius), + --alert-border-radius: var(--radius-2), --alert-link-color: #0a58ca, --hr-border-color: var(--theme-border, var(--border-color)), ) @@ -52,7 +52,7 @@ $true-terminal-output: false; padding-y: 1rem; padding-x: 1rem; // stylelint-disable-next-line property-disallowed-list - border-radius: var(--border-radius); + border-radius: var(--radius-2); } } } diff --git a/scss/tests/modules/_root-tokens-bootstrap.test.scss b/scss/tests/modules/_root-tokens-bootstrap.test.scss index 45a818678076..ed3523c9d4fb 100644 --- a/scss/tests/modules/_root-tokens-bootstrap.test.scss +++ b/scss/tests/modules/_root-tokens-bootstrap.test.scss @@ -19,7 +19,7 @@ // Customize menu tokens $menu-tokens: ( --menu-bg: var(--bg-2), - --menu-item-border-radius: var(--border-radius-xl), + --menu-item-border-radius: var(--radius-4), --menu-padding-x: 1rem, --menu-padding-y: 1rem, ) diff --git a/site/src/components/shortcodes/ButtonPlayground.astro b/site/src/components/shortcodes/ButtonPlayground.astro index 212db94df925..87e7e2192894 100644 --- a/site/src/components/shortcodes/ButtonPlayground.astro +++ b/site/src/components/shortcodes/ButtonPlayground.astro @@ -135,14 +135,14 @@ const rounded = ['default', 'pill', 'square'] class="d-flex flex-wrap align-items-start gap-2" code={` diff --git a/site/src/content/docs/components/nav.mdx b/site/src/content/docs/components/nav.mdx index c50cdae0b35e..24d3159468a3 100644 --- a/site/src/content/docs/components/nav.mdx +++ b/site/src/content/docs/components/nav.mdx @@ -48,7 +48,7 @@ Where appropriate, you can also use ` + `} /> -## Sizing - -Use `.otp-sm` or `.otp-lg` for different sizes. Don’t use the input group size classes on the `.otp` container as we override specific CSS variables for sizing. - - - - - - - - - - -
- - - - - - -
- -
- - - - - - -
`} /> - ## Disabled Add the `disabled` attribute to each input to prevent interaction. @@ -239,7 +208,7 @@ otpInput.clear() | Event | Description | | --- | --- | -| `complete.bs.otp` | Fired when all inputs are filled. The event’s `value` property contains the complete code. | +| `complete.bs.otp` | Fired when all inputs are filled. The event's `value` property contains the complete code. | | `input.bs.otp` | Fired on each input change. Includes `value` (current combined value) and `index` (changed input index). | diff --git a/site/src/content/docs/guides/migration.mdx b/site/src/content/docs/guides/migration.mdx index ade4f48637e9..1007b97b77a6 100644 --- a/site/src/content/docs/guides/migration.mdx +++ b/site/src/content/docs/guides/migration.mdx @@ -319,20 +319,42 @@ Bootstrap 6 is a major release with many breaking changes to modernize our codeb | — | — | `.fs-6xl` | `clamp(3.75rem, …, 5rem)` | -- **Border radius scale updated.** The underlying CSS custom property values have increased, and the utility mapping has shifted: +- **Border radius tokens replaced with a numeric scale.** The named `$border-radius-*` Sass variables and `--border-radius-*` CSS custom properties (`-xs`, `-sm`, default, `-lg`, `-xl`, `-2xl`) have been removed in favor of a numeric `$radii` Sass map (keyed `0`–`9`) that generates `--radius-0` through `--radius-9` tokens, plus `--radius-pill`. The scale is driven by a single `$radius: .5rem` base, so all steps move together when the base changes. To migrate any custom Sass or CSS that referenced the old tokens directly: -| Utility class | v5 variable | v5 value | v6 variable | v6 value | -|---|---|---|---|---| -| `.rounded` | `$border-radius` | `0.375rem` | `--border-radius` | `0.5rem` | -| `.rounded-0` | — | `0` | — | `0` | -| `.rounded-1` | `$border-radius-sm` | `0.25rem` | `--border-radius-sm` | `0.5rem` | -| `.rounded-2` | `$border-radius` | `0.375rem` | `--border-radius` | `0.5rem` | -| `.rounded-3` | `$border-radius-lg` | `0.5rem` | `--border-radius-lg` | `0.75rem` | -| `.rounded-4` | `$border-radius-xl` | `1rem` | `--border-radius-xl` | `1rem` | -| `.rounded-5` | `$border-radius-xxl` | `2rem` | `--border-radius-2xl` | `2rem` | +| v5 variable | v5 value | v6 token | v6 value | +|---|---|---|---| +| `$border-radius-xs` / `--border-radius-xs` | `0.25rem` | `--radius-3` | `0.25rem` | +| `$border-radius-sm` / `--border-radius-sm` | `0.25rem` | `--radius-3` | `0.25rem` | +| `$border-radius` / `--border-radius` | `0.375rem` | `--radius-4` | `0.375rem` | +| `$border-radius-lg` / `--border-radius-lg` | `0.5rem` | `--radius-5` | `0.5rem` | +| `$border-radius-xl` / `--border-radius-xl` | `1rem` | `--radius-8` | `1rem` | +| `$border-radius-xxl` / `--border-radius-2xl` | `2rem` | — (closest: `--radius-9` `1.5rem`) | +| `$border-radius-pill` / `--border-radius-pill` | `50rem` | `--radius-pill` | `50rem` | +- **Border radius utilities expanded and remapped.** `.rounded-*` is now generated from the `$radii` map, so the scale spans `.rounded-0` through `.rounded-9` (previously `.rounded-0` through `.rounded-5`). The default `.rounded` still resolves to `0.5rem`, but the numbered classes now map to different values than v5: + + +| Utility class | v5 value | v6 value | v6 token | +|---|---|---|---| +| `.rounded` | `0.375rem` | `0.5rem` | `var(--radius-5)` | +| `.rounded-0` | `0` | `0` | `var(--radius-0)` | +| `.rounded-1` | `0.25rem` | `0.125rem` | `var(--radius-1)` | +| `.rounded-2` | `0.375rem` | `0.1875rem` | `var(--radius-2)` | +| `.rounded-3` | `0.5rem` | `0.25rem` | `var(--radius-3)` | +| `.rounded-4` | `1rem` | `0.375rem` | `var(--radius-4)` | +| `.rounded-5` | `2rem` | `0.5rem` | `var(--radius-5)` | +| `.rounded-6` | — | `0.625rem` | `var(--radius-6)` | +| `.rounded-7` | — | `0.75rem` | `var(--radius-7)` | +| `.rounded-8` | — | `1rem` | `var(--radius-8)` | +| `.rounded-9` | — | `1.5rem` | `var(--radius-9)` | +| `.rounded-circle` | `50%` | `50%` | — | +| `.rounded-pill` | `50rem` | `50rem` | `var(--radius-pill)` | + + + To preserve v5 visual roundness, shift class numbers up the scale (e.g. `.rounded-1` → `.rounded-3`, `.rounded-2` → `.rounded-4`, `.rounded-3` → `.rounded-5`, `.rounded-4` → `.rounded-8`, `.rounded-5` → `.rounded-9`). The `.rounded-{top,end,bottom,start}-*` directional variants follow the same scale. + - **Font weight additions.** Added `.fw-medium` (`500`) and `.fw-semibold` (`600`) utilities. v5 only had `lighter`, `light` (`300`), `normal` (`400`), `bold` (`700`), and `bolder`. - **Negative margins limited.** Negative spacers are reduced to only `-1` (`-0.25rem`) and `-2` (`-0.5rem`), and only applied to `margin-inline-start` (`.ms-n1`, `.ms-n2`) and `margin-inline-end` (`.me--1`, `.me--2`). The v5 full negative margin utilities across all sides have been removed. - **Spacing and border utilities now use CSS logical properties.** `margin-top` → `margin-block-start`, `margin-right` → `margin-inline-end`, `padding-left` → `padding-inline-start`, `border-right` → `border-inline-end`, etc. Class names (`.mt-*`, `.me-*`, `.ps-*`, `.border-end`) remain the same, but the underlying CSS properties are now logical, improving RTL and writing-mode support. diff --git a/site/src/content/docs/utilities/border-radius.mdx b/site/src/content/docs/utilities/border-radius.mdx index a983fabbf617..bbcb41098ab7 100644 --- a/site/src/content/docs/utilities/border-radius.mdx +++ b/site/src/content/docs/utilities/border-radius.mdx @@ -46,7 +46,9 @@ Use the scaling classes for larger or smaller rounded corners. Sizes range from ### Variables - +Radius tokens are generated from the `$spacers` map in `scss/_root.scss`. [Learn how to use the root tokens.]([[docsref:/utilities/api#using-root-tokens]]) + + ### Sass maps diff --git a/site/src/layouts/DocsLayout.astro b/site/src/layouts/DocsLayout.astro index ffdde814be73..be15cc43cd0f 100644 --- a/site/src/layouts/DocsLayout.astro +++ b/site/src/layouts/DocsLayout.astro @@ -173,11 +173,14 @@ if (currentPageIndex < allPages.length - 1) { -