@viasat/beam-styles 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +150 -0
  2. package/all.scss +3 -0
  3. package/components/accordion.module.scss +166 -0
  4. package/components/accordion.vars.scss +3 -0
  5. package/components/actionList.module.scss +211 -0
  6. package/components/actionList.vars.scss +6 -0
  7. package/components/alert.module.scss +158 -0
  8. package/components/aspectRatio.module.scss +21 -0
  9. package/components/avatar.module.scss +204 -0
  10. package/components/badge.module.scss +166 -0
  11. package/components/badgeDot.module.scss +90 -0
  12. package/components/box.module.scss +127 -0
  13. package/components/breadcrumbs.module.scss +149 -0
  14. package/components/button.module.scss +179 -0
  15. package/components/button.vars.scss +129 -0
  16. package/components/card.module.scss +232 -0
  17. package/components/checkbox.module.scss +123 -0
  18. package/components/chip.module.scss +173 -0
  19. package/components/chipsGroup.module.scss +13 -0
  20. package/components/closeButton.module.scss +52 -0
  21. package/components/combobox.module.scss +243 -0
  22. package/components/dialog.module.scss +199 -0
  23. package/components/divider.module.scss +255 -0
  24. package/components/emptyState.module.scss +61 -0
  25. package/components/fileUpload.module.scss +282 -0
  26. package/components/flag.module.scss +11 -0
  27. package/components/floatingui.module.scss +40 -0
  28. package/components/header.module.scss +123 -0
  29. package/components/helperText.module.scss +86 -0
  30. package/components/icon.module.scss +46 -0
  31. package/components/icon.vars.scss +31 -0
  32. package/components/index.scss +40 -0
  33. package/components/inputChoiceGroup.module.scss +46 -0
  34. package/components/label.module.scss +67 -0
  35. package/components/link.module.scss +118 -0
  36. package/components/list.module.scss +204 -0
  37. package/components/logo.module.scss +11 -0
  38. package/components/menu.module.scss +13 -0
  39. package/components/nativeSelect.module.scss +139 -0
  40. package/components/navigation.module.scss +156 -0
  41. package/components/pageHeader.module.scss +93 -0
  42. package/components/pageLayout.module.scss +38 -0
  43. package/components/pagination.module.scss +71 -0
  44. package/components/popover.module.scss +71 -0
  45. package/components/progressBar.module.scss +107 -0
  46. package/components/radioButton.module.scss +115 -0
  47. package/components/segmentedControl.module.scss +212 -0
  48. package/components/sideNav.module.scss +355 -0
  49. package/components/slider.module.scss +240 -0
  50. package/components/spinner.module.scss +261 -0
  51. package/components/spinner.vars.scss +85 -0
  52. package/components/stepper.module.scss +255 -0
  53. package/components/switch.module.scss +194 -0
  54. package/components/tabs.module.scss +412 -0
  55. package/components/text.module.scss +112 -0
  56. package/components/textArea.module.scss +183 -0
  57. package/components/textField.module.scss +162 -0
  58. package/components/toast.module.scss +235 -0
  59. package/components/toastContainer.module.scss +68 -0
  60. package/components/tooltip.module.scss +112 -0
  61. package/package.json +47 -0
  62. package/styles.css +11719 -0
  63. package/styles.css.map +1 -0
  64. package/styles.min.css +20 -0
  65. package/styles.min.css.map +1 -0
  66. package/utils/animation.scss +13 -0
  67. package/utils/constants.scss +1 -0
  68. package/utils/cursors.scss +35 -0
  69. package/utils/globals.scss +17 -0
  70. package/utils/helpers.scss +14 -0
  71. package/utils/index.scss +10 -0
  72. package/utils/mixins.scss +93 -0
  73. package/utils/spacing.scss +82 -0
  74. package/utils/stateLayer.module.scss +55 -0
  75. package/utils/stateLayerVars.scss +75 -0
  76. package/utils/tokens.scss +14 -0
@@ -0,0 +1,93 @@
1
+ @use '../utils/constants.scss';
2
+ @use '../utils/tokens.scss' as tokens;
3
+
4
+ $pageHeaderBaseClass: '#{constants.$prefix}page-header';
5
+
6
+ $sizes: (
7
+ md: tokens.$bm-sem-typo-heading-lg,
8
+ lg: tokens.$bm-sem-typo-heading-2xl,
9
+ );
10
+
11
+ .#{$pageHeaderBaseClass} {
12
+ display: grid;
13
+ width: 100%;
14
+ grid-template-areas:
15
+ 'breadcrumb'
16
+ 'heading'
17
+ 'body'
18
+ 'tabs';
19
+ color: tokens.$bm-sem-color-text-primary;
20
+
21
+ &__breadcrumb {
22
+ grid-area: breadcrumb;
23
+ padding-bottom: tokens.$bm-sem-space-100;
24
+ }
25
+
26
+ &__heading {
27
+ grid-area: heading;
28
+ display: flex;
29
+ justify-content: space-between;
30
+ gap: tokens.$bm-sem-space-50;
31
+ flex-wrap: wrap;
32
+ }
33
+
34
+ &__heading-content {
35
+ order: 1;
36
+ display: flex;
37
+ gap: tokens.$bm-sem-space-50;
38
+
39
+ @each $size, $font in $sizes {
40
+ &--#{$size} {
41
+ font: $font;
42
+ }
43
+ }
44
+ }
45
+
46
+ &__heading-content-before {
47
+ order: 1;
48
+ gap: tokens.$bm-sem-space-50;
49
+ display: flex;
50
+ align-items: center;
51
+ height: 1lh;
52
+ }
53
+
54
+ &__heading-action {
55
+ order: -1;
56
+ }
57
+
58
+ &__heading-title {
59
+ order: 2;
60
+ overflow-wrap: break-word;
61
+ }
62
+
63
+ &__heading-content-after {
64
+ order: 3;
65
+ display: flex;
66
+ gap: tokens.$bm-sem-space-50;
67
+ height: 1lh;
68
+ align-items: center;
69
+
70
+ .#{$pageHeaderBaseClass}__heading-action {
71
+ order: 999;
72
+ }
73
+ }
74
+
75
+ &__actions {
76
+ display: flex;
77
+ flex-wrap: wrap;
78
+ min-width: 0;
79
+ gap: tokens.$bm-sem-space-50;
80
+ order: 2;
81
+ }
82
+
83
+ &__body {
84
+ grid-area: body;
85
+ padding-top: tokens.$bm-sem-space-25;
86
+ }
87
+
88
+ &__tabs {
89
+ grid-area: tabs;
90
+ padding-top: tokens.$bm-sem-space-150;
91
+ overflow-x: auto;
92
+ }
93
+ }
@@ -0,0 +1,38 @@
1
+ @use '../utils/constants.scss';
2
+ @use '../utils/tokens.scss' as tokens;
3
+
4
+ $pageLayoutBaseClass: '#{constants.$prefix}page-layout';
5
+
6
+ .#{$pageLayoutBaseClass} {
7
+ display: grid;
8
+ grid-template-areas:
9
+ 'header header'
10
+ 'aside main';
11
+ grid-template-rows: auto 1fr;
12
+ grid-template-columns: auto 1fr;
13
+ height: 100%;
14
+ width: 100%;
15
+ flex: 1;
16
+ }
17
+
18
+ .#{$pageLayoutBaseClass}__header {
19
+ grid-area: header;
20
+ width: 100%;
21
+ z-index: 1;
22
+ }
23
+
24
+ .#{$pageLayoutBaseClass}__aside {
25
+ grid-area: aside;
26
+ height: 100%;
27
+ min-height: 0;
28
+ z-index: 0;
29
+ display: flex;
30
+ }
31
+
32
+ .#{$pageLayoutBaseClass}__main {
33
+ grid-area: main;
34
+ height: 100%;
35
+ min-height: 0;
36
+ width: 100%;
37
+ overflow-y: auto;
38
+ }
@@ -0,0 +1,71 @@
1
+ @use '../utils/constants.scss';
2
+ @use '../utils/tokens.scss';
3
+ @use '../utils/stateLayerVars.scss' as state-layer;
4
+ @use '../utils/mixins.scss';
5
+
6
+ @import '../../../../tokens/src/lib/components/Pagination';
7
+
8
+ $paginationBaseClass: '#{constants.$prefix}pagination';
9
+ $buttonBaseClass: '#{constants.$prefix}button';
10
+
11
+ .#{$paginationBaseClass} {
12
+ display: flex;
13
+ align-items: center;
14
+ flex-wrap: wrap;
15
+
16
+ &--determinate {
17
+ gap: tokens.$bm-comp-pagination-space-controls-gap;
18
+ }
19
+
20
+ & &__chevrons {
21
+ display: flex;
22
+ flex-wrap: nowrap;
23
+ color: tokens.$bm-comp-pagination-color-text;
24
+
25
+ .#{state-layer.$stateLayerBaseClass} {
26
+ outline: none;
27
+ }
28
+
29
+ &:dir(rtl) {
30
+ transform: scale(-1);
31
+ }
32
+ }
33
+
34
+ & &__buttons {
35
+ font: tokens.$bm-sem-typo-label-md;
36
+ border-radius: tokens.$bm-comp-btn-radius-container;
37
+ color: tokens.$bm-comp-pagination-color-text;
38
+ background-color: transparent;
39
+ align-self: stretch;
40
+ padding: 0;
41
+ background: unset;
42
+
43
+ .#{state-layer.$stateLayerBaseClass} {
44
+ outline: none;
45
+ }
46
+
47
+ &:focus-visible {
48
+ @include mixins.simulated-inset-outline;
49
+ }
50
+
51
+ &--active {
52
+ color: tokens.$bm-comp-pagination-color-fg-selected;
53
+ border: tokens.$bm-comp-btn-border-width solid
54
+ tokens.$bm-comp-pagination-color-border-selected;
55
+ background: tokens.$bm-comp-pagination-color-bg-selected;
56
+ }
57
+ }
58
+
59
+ & &__truncation {
60
+ border: none;
61
+ appearance: none;
62
+ -webkit-appearance: none;
63
+ -moz-appearance: none;
64
+ text-align: center;
65
+ min-width: tokens.$bm-comp-btn-size-sm-width;
66
+ min-height: tokens.$bm-comp-btn-size-sm-height;
67
+ cursor: pointer;
68
+
69
+ @extend .#{$paginationBaseClass}__buttons;
70
+ }
71
+ }
@@ -0,0 +1,71 @@
1
+ @use '../utils/constants.scss';
2
+ @use '../utils/mixins.scss' as mixins;
3
+ @use '../utils/tokens.scss' as tokens;
4
+
5
+ @import '../../../../tokens/src/lib/components/Popover';
6
+
7
+ $popoverBaseClass: '#{constants.$prefix}popover';
8
+
9
+ $ARROW: url("data:image/svg+xml,%3Csvg width='21.544' height='9' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8.122 7.93 0 0h21.544l-8.121 7.93c-1.462 1.427-3.84 1.427-5.301 0z' fill='%23fff' style='fill:%231a1a1a;stroke:none'/%3E%3C/svg%3E");
10
+
11
+ .#{$popoverBaseClass} {
12
+ background-color: tokens.$bm-comp-popover-color-bg !important;
13
+ border: tokens.$bm-comp-popover-border-width solid
14
+ tokens.$bm-comp-popover-color-border;
15
+ border-radius: tokens.$bm-comp-popover-radius;
16
+ box-shadow: tokens.$bm-comp-popover-shadow;
17
+
18
+ // to prevent this token from being purged
19
+ offset: tokens.$bm-comp-popover-space-offset;
20
+
21
+ // override default Popover API styles
22
+ width: unset;
23
+
24
+ &:focus-visible {
25
+ outline: none;
26
+ }
27
+
28
+ padding: tokens.$bm-sem-space-100;
29
+
30
+ // SVG cannot be styled with tokens (unless we inline it in React, but then
31
+ // we would need to do css lookups, which isn't ideal)
32
+ // so instead, we use two pseudo-elements to create the arrow
33
+ // ::before acts as the border (stacked behind), ::after acts as the main arrow
34
+ &__arrow {
35
+ $OFFSET: 0.05rem;
36
+ width: tokens.$bm-comp-popover-size-beak-width;
37
+ height: tokens.$bm-comp-popover-size-beak-height;
38
+
39
+ &::after {
40
+ position: absolute;
41
+ content: '';
42
+ // raise arrow positioning (default arrow position is on the bottom of the popover content, pointing down)
43
+ // as bugs in some browser/zoom configurations causes the ::before psuedo-element to peek through
44
+ // the top of the arrow
45
+ top: -#{$OFFSET};
46
+ @include mixins.svg-icon($ARROW);
47
+ width: 100%;
48
+ height: 100%;
49
+ background-color: tokens.$bm-comp-popover-color-bg !important;
50
+ }
51
+
52
+ &::before {
53
+ position: absolute;
54
+ content: '';
55
+ right: 50%;
56
+ transform: translateX(50%);
57
+ @include mixins.svg-icon($ARROW);
58
+ background-color: tokens.$bm-comp-popover-color-border;
59
+
60
+ // increase the height of the arrow to cover the border. however, we've also moved the arrow (::after) up by $OFFSET
61
+ // (see comment above for reasoning) so a bit of ::before is already poking out.
62
+ // therefore we need to subtract that from the height
63
+ height: calc(
64
+ #{tokens.$bm-comp-popover-size-beak-height} + #{tokens.$bm-comp-popover-border-width} -
65
+ #{$OFFSET}
66
+ );
67
+ // height and width of the svg; see the $ARROW declaration above
68
+ aspect-ratio: 17.954 / 7.5;
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,107 @@
1
+ @use 'sass:map';
2
+ @use '../utils/constants.scss';
3
+ @use '../utils/tokens.scss' as tokens;
4
+
5
+ @import '../../../../tokens/src/lib/components/ProgressBar';
6
+
7
+ $progressBarBaseClass: '#{constants.$prefix}progress-bar';
8
+ $progressBarLabelClass: '#{$progressBarBaseClass}__label';
9
+ $progressBarTrackClass: '#{$progressBarBaseClass}__track';
10
+ $progressBarIndicatorClass: '#{$progressBarBaseClass}__indicator';
11
+ $progressBarStatusClass: '#{$progressBarBaseClass}__status';
12
+
13
+ $indicatorColorByState: (
14
+ 'active': tokens.$bm-comp-progress-bar-color-indicator-default,
15
+ 'success': tokens.$bm-comp-progress-bar-color-indicator-success,
16
+ 'error': tokens.$bm-comp-progress-bar-color-indicator-error,
17
+ );
18
+
19
+ .#{$progressBarBaseClass} {
20
+ display: flex;
21
+ align-items: stretch;
22
+ flex-direction: column;
23
+
24
+ .#{$progressBarLabelClass} {
25
+ margin-bottom: tokens.$bm-comp-progress-bar-space-label-bottom;
26
+ font: tokens.$bm-comp-progress-bar-typo-label;
27
+ color: tokens.$bm-comp-progress-bar-color-label;
28
+ }
29
+
30
+ .#{$progressBarTrackClass} {
31
+ height: tokens.$bm-comp-progress-bar-size-md-height;
32
+ border-radius: tokens.$bm-comp-progress-bar-radius;
33
+ background-color: tokens.$bm-comp-progress-bar-color-track;
34
+ display: flex;
35
+ overflow: hidden;
36
+ }
37
+
38
+ .#{$progressBarStatusClass} {
39
+ margin-top: tokens.$bm-comp-progress-bar-space-status-top;
40
+ }
41
+
42
+ &--sm {
43
+ .#{$progressBarTrackClass} {
44
+ height: tokens.$bm-comp-progress-bar-size-sm-height;
45
+ }
46
+ }
47
+
48
+ &--lg {
49
+ .#{$progressBarTrackClass} {
50
+ height: tokens.$bm-comp-progress-bar-size-lg-height;
51
+ }
52
+ }
53
+
54
+ &--full-width {
55
+ .#{$progressBarTrackClass} {
56
+ border-radius: 0;
57
+ }
58
+ }
59
+
60
+ @each $state, $indicatorColor in $indicatorColorByState {
61
+ &--#{$state} {
62
+ .#{$progressBarIndicatorClass} {
63
+ background-color: $indicatorColor;
64
+ }
65
+ }
66
+ }
67
+
68
+ &--determinate {
69
+ .#{$progressBarIndicatorClass} {
70
+ transition-property: width;
71
+ transition-duration: 300ms;
72
+ transition-timing-function: ease-out;
73
+ }
74
+ }
75
+
76
+ // Sass simply doesn't like & appearing after the beginning of the selector, but it doesn't mind it wrapped in #{}
77
+ // https://stackoverflow.com/a/47653943
78
+ &--indeterminate#{&}--active {
79
+ .#{$progressBarIndicatorClass} {
80
+ width: 100%;
81
+ mask-image: linear-gradient(
82
+ to right,
83
+ transparent calc(50% - 100% / 14.4),
84
+ black 50%,
85
+ transparent calc(50% + 100% / 14.4)
86
+ );
87
+ mask-size: 240%;
88
+ mask-repeat: no-repeat;
89
+ mask-position: center;
90
+ animation: 2s linear infinite bm-progress-bar-indeterminate-indicator-animation;
91
+
92
+ &:dir(rtl) {
93
+ animation-direction: reverse;
94
+ }
95
+ }
96
+ }
97
+ }
98
+
99
+ @keyframes bm-progress-bar-indeterminate-indicator-animation {
100
+ 0% {
101
+ mask-position: right;
102
+ }
103
+
104
+ 100% {
105
+ mask-position: left;
106
+ }
107
+ }
@@ -0,0 +1,115 @@
1
+ @use 'sass:map';
2
+ @use '../utils/constants.scss';
3
+ @use '../utils/mixins.scss' as mixins;
4
+ @use '../utils/tokens.scss' as tokens;
5
+ @use '../utils/cursors.scss' as cursors;
6
+
7
+ @import '../../../../tokens/src/lib/components/Input';
8
+
9
+ $radioButtonBaseClass: '#{constants.$prefix}radio-button';
10
+
11
+ $inputChoiceCursor: '--#{constants.$prefix}input-choice-cursor';
12
+ $inputChoiceLabelCursor: '--#{constants.$prefix}input-choice-label-cursor';
13
+ $inputChoiceLabelPointerEvents: '--#{constants.$prefix}input-choice-label-pointer-events';
14
+
15
+ $radioButtonStates: (
16
+ error: (
17
+ labelColor: tokens.$bm-comp-input-color-text,
18
+ borderColor: tokens.$bm-comp-input-color-border-error,
19
+ backgroundColor: tokens.$bm-comp-input-color-bg,
20
+ innerColor: tokens.$bm-comp-input-color-choice-radio-selected-inner-circle-error,
21
+ ),
22
+ read-only: (
23
+ labelColor: tokens.$bm-comp-input-color-text,
24
+ borderColor: tokens.$bm-comp-input-color-border-disabled,
25
+ backgroundColor: tokens.$bm-comp-input-color-bg-disabled,
26
+ innerColor: tokens.$bm-comp-input-color-icon,
27
+ ),
28
+ disabled: (
29
+ labelColor: tokens.$bm-comp-input-color-text-disabled,
30
+ borderColor: tokens.$bm-comp-input-color-border-disabled,
31
+ backgroundColor: tokens.$bm-comp-input-color-bg-disabled,
32
+ innerColor: tokens.$bm-comp-input-color-icon-disabled,
33
+ ),
34
+ );
35
+
36
+ .#{$radioButtonBaseClass} {
37
+ display: inline-flex;
38
+ @include cursors.applyChoiceCursors();
39
+
40
+ &__label {
41
+ display: inherit;
42
+ word-break: break-word;
43
+ color: tokens.$bm-comp-input-color-text;
44
+ font: tokens.$bm-comp-input-typo-default;
45
+ gap: tokens.$bm-comp-input-space-choice-gap-inside;
46
+ cursor: var(#{$inputChoiceLabelCursor}, pointer);
47
+ pointer-events: var(#{$inputChoiceLabelPointerEvents}, auto);
48
+ }
49
+
50
+ @each $state, $values in $radioButtonStates {
51
+ &--#{$state} &__label {
52
+ color: map.get($values, labelColor);
53
+ }
54
+
55
+ &--#{$state} &__label &__input {
56
+ &,
57
+ &:checked {
58
+ border-color: map.get($values, borderColor);
59
+ background-color: map.get($values, backgroundColor);
60
+ }
61
+
62
+ &:checked {
63
+ &:after {
64
+ background-color: map.get($values, innerColor);
65
+ }
66
+ }
67
+ }
68
+ }
69
+
70
+ &--with-label &__label &__input {
71
+ margin: tokens.$bm-comp-input-space-choice-nudge tokens.$bm-sem-space-0;
72
+ }
73
+
74
+ &__label &__input {
75
+ appearance: none;
76
+ -moz-appearance: none;
77
+ -webkit-appearance: none;
78
+
79
+ position: relative;
80
+ margin: tokens.$bm-sem-space-0;
81
+ flex-shrink: tokens.$bm-sem-space-0;
82
+ cursor: var(#{$inputChoiceCursor}, pointer);
83
+ width: tokens.$bm-comp-input-size-choice-radio;
84
+ height: tokens.$bm-comp-input-size-choice-radio;
85
+ background-color: tokens.$bm-comp-input-color-bg;
86
+
87
+ border-style: solid;
88
+ border-color: tokens.$bm-comp-input-color-border;
89
+ border-radius: tokens.$bm-comp-input-radius-choice-radio;
90
+ border-width: tokens.$bm-comp-input-border-width-field-default;
91
+
92
+ &:focus-visible {
93
+ @include mixins.simulated-inset-outline();
94
+ }
95
+
96
+ &:checked {
97
+ border-color: tokens.$bm-comp-input-color-choice-radio-selected-border;
98
+ background-color: tokens.$bm-comp-input-color-choice-radio-selected-bg;
99
+
100
+ &:after {
101
+ background-color: tokens.$bm-comp-input-color-choice-radio-selected-inner-circle;
102
+ }
103
+ }
104
+
105
+ &:after {
106
+ content: '';
107
+ position: absolute;
108
+ width: tokens.$bm-comp-input-size-choice-radio-inside;
109
+ height: tokens.$bm-comp-input-size-choice-radio-inside;
110
+ border-radius: tokens.$bm-comp-input-radius-choice-radio;
111
+ top: calc(50% - #{tokens.$bm-comp-input-size-choice-radio-inside} / 2);
112
+ left: calc(50% - #{tokens.$bm-comp-input-size-choice-radio-inside} / 2);
113
+ }
114
+ }
115
+ }
@@ -0,0 +1,212 @@
1
+ @use 'sass:map';
2
+ @use '../utils/constants.scss';
3
+ @use '../utils/tokens.scss' as tokens;
4
+ @use '../utils/stateLayerVars.scss' as state-layer;
5
+
6
+ @import '../../../../tokens/src/lib/components/SegmentedControl';
7
+ @import '../../../../tokens/src/lib/components/Button';
8
+
9
+ $scBaseClass: '#{constants.$prefix}segmented-control';
10
+
11
+ $border: tokens.$bm-comp-btn-border-width solid
12
+ tokens.$bm-comp-seg-control-color-border;
13
+
14
+ $sizes: (
15
+ 'sm': (
16
+ 'min-width': tokens.$bm-comp-btn-size-sm-width,
17
+ 'height': tokens.$bm-comp-btn-size-sm-height,
18
+ 'icon': tokens.$bm-comp-btn-size-sm-icon,
19
+ 'font': tokens.$bm-comp-btn-typo-sm,
20
+ 'padding': 0 tokens.$bm-comp-seg-control-space-sm-x,
21
+ ),
22
+ 'md': (
23
+ 'min-width': tokens.$bm-comp-btn-size-md-width,
24
+ 'height': tokens.$bm-comp-btn-size-md-height,
25
+ 'icon': tokens.$bm-comp-btn-size-md-icon,
26
+ 'font': tokens.$bm-comp-btn-typo-md,
27
+ 'padding': 0 tokens.$bm-comp-seg-control-space-md-x,
28
+ ),
29
+ 'lg': (
30
+ 'min-width': tokens.$bm-comp-btn-size-lg-width,
31
+ 'height': tokens.$bm-comp-btn-size-lg-height,
32
+ 'icon': tokens.$bm-comp-btn-size-lg-icon,
33
+ 'font': tokens.$bm-comp-btn-typo-lg,
34
+ 'padding': 0 tokens.$bm-comp-seg-control-space-lg-x,
35
+ ),
36
+ );
37
+
38
+ .#{$scBaseClass} {
39
+ box-shadow: tokens.$bm-comp-btn-shadow;
40
+
41
+ &--disabled {
42
+ opacity: tokens.$bm-sem-opacity-disabled;
43
+ cursor: not-allowed;
44
+ }
45
+ }
46
+
47
+ .#{$scBaseClass}__list {
48
+ position: relative;
49
+ display: inline-flex;
50
+ justify-content: center;
51
+ align-items: center;
52
+ user-select: none;
53
+ gap: 0;
54
+ max-width: 100%;
55
+ min-width: 0;
56
+
57
+ // Ensure direct slotted children/wrappers can shrink and don't overflow
58
+ // This styles is also mirrored in SegmentedControlItem.ts
59
+ // to ensure the overflow observer works when a wrapper is used
60
+ ::slotted(*) {
61
+ min-width: 0;
62
+ flex-shrink: 1;
63
+ }
64
+
65
+ &--fluid {
66
+ width: 100%;
67
+ display: flex;
68
+
69
+ // In fluid mode, let each slotted child grow to fill available space
70
+ ::slotted(*) {
71
+ flex: 1 1 auto;
72
+ }
73
+ }
74
+ }
75
+
76
+ .#{$scBaseClass}__item {
77
+ display: flex;
78
+ position: relative;
79
+ border: $border;
80
+ border-color: tokens.$bm-comp-seg-control-color-border;
81
+ margin-inline-start: -1px;
82
+ min-width: 0;
83
+ outline: none;
84
+
85
+ background: tokens.$bm-comp-seg-control-color-bg;
86
+ color: tokens.$bm-comp-seg-control-color-fg;
87
+ cursor: pointer;
88
+ justify-content: center;
89
+
90
+ &--fluid {
91
+ flex: 1 1 auto;
92
+ min-width: 0;
93
+
94
+ .#{$scBaseClass}__item__label {
95
+ width: 100%;
96
+ min-width: 0;
97
+ }
98
+ }
99
+
100
+ &--first {
101
+ border-radius: tokens.$bm-comp-seg-control-radius 0 0
102
+ tokens.$bm-comp-seg-control-radius;
103
+ border-inline-start-color: tokens.$bm-comp-seg-control-color-border;
104
+ margin-inline-start: 0;
105
+
106
+ [dir='rtl'] &,
107
+ :dir(rtl) & {
108
+ border-radius: 0 tokens.$bm-comp-seg-control-radius
109
+ tokens.$bm-comp-seg-control-radius 0;
110
+ }
111
+ }
112
+
113
+ &--last {
114
+ border-radius: 0 tokens.$bm-comp-seg-control-radius
115
+ tokens.$bm-comp-seg-control-radius 0;
116
+ border-inline-end-color: tokens.$bm-comp-seg-control-color-border;
117
+ margin-inline-end: 0;
118
+
119
+ [dir='rtl'] &,
120
+ :dir(rtl) & {
121
+ border-radius: tokens.$bm-comp-seg-control-radius 0 0
122
+ tokens.$bm-comp-seg-control-radius;
123
+ }
124
+ }
125
+
126
+ &__content {
127
+ display: flex;
128
+ align-items: center;
129
+ justify-content: center;
130
+ gap: tokens.$bm-comp-btn-space-gap;
131
+ cursor: inherit;
132
+ min-width: 0;
133
+ width: 100%;
134
+ }
135
+
136
+ &__controlText {
137
+ align-content: center;
138
+ height: 100%;
139
+ padding: 0 tokens.$bm-comp-btn-space-label-x;
140
+ text-overflow: ellipsis;
141
+ white-space: nowrap;
142
+ overflow: hidden;
143
+ }
144
+
145
+ &__icon,
146
+ ::slotted([slot='icon']) {
147
+ display: flex;
148
+ align-items: center;
149
+ flex-shrink: 0;
150
+ }
151
+
152
+ &--selected {
153
+ z-index: 1;
154
+ background: tokens.$bm-comp-seg-control-color-bg-selected;
155
+ border: tokens.$bm-comp-btn-border-width solid
156
+ tokens.$bm-comp-seg-control-color-border-selected;
157
+
158
+ .#{$scBaseClass}__item__controlText,
159
+ .#{$scBaseClass}__item__icon,
160
+ ::slotted([slot='icon']) {
161
+ color: tokens.$bm-comp-seg-control-color-fg-selected;
162
+ }
163
+
164
+ #{state-layer.getStateLayerSelector('&', 'hover')} {
165
+ #{state-layer.$background}: unset;
166
+ }
167
+ }
168
+
169
+ &__state-layer {
170
+ pointer-events: none;
171
+ cursor: pointer;
172
+ z-index: 2;
173
+ }
174
+
175
+ &:focus-visible .#{state-layer.$stateLayerBaseClass} {
176
+ #{state-layer.$outline-width}: tokens.$bm-sem-border-width-focus;
177
+ #{state-layer.$outline-color}: tokens.$bm-sem-color-border-focus;
178
+ #{state-layer.$outline-offset}: 0;
179
+ }
180
+
181
+ &--disabled {
182
+ opacity: tokens.$bm-sem-opacity-disabled;
183
+ cursor: not-allowed !important;
184
+ }
185
+
186
+ @each $size, $properties in $sizes {
187
+ &--#{$size} {
188
+ height: map.get($properties, 'height');
189
+ font: map.get($properties, 'font');
190
+ padding: map.get($properties, 'padding');
191
+
192
+ .#{$scBaseClass}__item__icon svg,
193
+ ::slotted([slot='icon']) {
194
+ width: map.get($properties, 'icon');
195
+ height: map.get($properties, 'icon');
196
+ }
197
+
198
+ &.#{$scBaseClass}__item--iconOnly {
199
+ padding: 0 !important;
200
+ min-width: map.get($properties, 'min-width');
201
+ }
202
+ }
203
+ }
204
+ }
205
+
206
+ .#{$scBaseClass}__panel {
207
+ display: none;
208
+
209
+ &--selected {
210
+ display: block;
211
+ }
212
+ }