Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/react-components/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@ main {
display: flex;
flex-direction: row;
gap: var(--layout-margin-medium);
min-width: 0;
max-width: 100%;
}
.col {
display: flex;
flex-direction: column;
max-width: 100%;
width: 100%;
}
.menu {
display: flex;
Expand Down
197 changes: 149 additions & 48 deletions packages/react-components/src/components/Select/Select.css
Original file line number Diff line number Diff line change
@@ -1,55 +1,106 @@
.bcds-react-aria-Select {
display: flex;
flex: 1 1 0;
flex-direction: column;
align-items: flex-start;
align-items: stretch;
min-width: 0;
/* Hacks for `stretch`: https://caniuse.com/mdn-css_properties_max-width_stretch */
max-width: -moz-available;
max-width: -webkit-fill-available;
}

/* Label above select input */
.bcds-react-aria-Select--Label {
color: var(--typography-color-secondary);
font: var(--typography-regular-small-body);
padding: var(--layout-padding-xsmall) var(--layout-padding-none);
/* Scroll mode: single-select text truncation */
.bcds-react-aria-Select.scroll .bcds-react-aria-SelectValue {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.bcds-react-aria-Select[data-disabled] > .bcds-react-aria-Select--Label {
color: var(--typography-color-disabled);

/* Scroll mode: horizontally scrollable tag overlay.
overflow-x: auto forces overflow-y to also clip (per CSS spec), which
would clip tag focus rings. padding-block creates room for the outline
inside the scroll container's padding box, and matching negative
margin-block cancels it out so the overlay's outer box stays the same
size, preserving alignment with wrap mode. */
.bcds-react-aria-Select.scroll .bcds-react-aria-Select--TagOverlay {
overflow-x: auto;
pointer-events: auto;
scrollbar-width: none;
padding-block: calc(
var(--layout-border-width-medium) + var(--layout-margin-hair) + 1px
);
margin-block: calc(
-1 * (var(--layout-border-width-medium) + var(--layout-margin-hair) + 1px)
);
padding-inline: calc(
var(--layout-border-width-medium) + var(--layout-margin-hair) + 1px
);
margin-inline: calc(
-1 * (var(--layout-border-width-medium) + var(--layout-margin-hair) + 1px)
);
}
.bcds-react-aria-Select.scroll
.bcds-react-aria-Select--TagOverlay::-webkit-scrollbar {
display: none;
}

/* Text description below select input */
.bcds-react-aria-Select--Description {
font: var(--typography-regular-small-body);
color: var(--typography-color-secondary);
padding: var(--layout-padding-xsmall) var(--layout-padding-none);
/* Scroll mode: prevent tag list from wrapping */
.bcds-react-aria-Select.scroll .bcds-react-aria-TagList {
flex-wrap: nowrap;
width: max-content;
}

/* Error message */
.bcds-react-aria-Select--Error {
font: var(--typography-regular-small-body);
color: var(--typography-color-danger);
/* Scroll mode: prevent tags from shrinking or wrapping */
.bcds-react-aria-Select.scroll .bcds-react-aria-Tag {
flex-shrink: 0;
}
.bcds-react-aria-Select.scroll .bcds-react-aria-Tag--Label {
white-space: nowrap;
}

/* Error icon */
.bcds-react-aria-Select[data-invalid]
> .bcds-react-aria-Select--Button
> svg:not(:last-child) {
color: var(--icons-color-danger);
/* Sizing */
.bcds-react-aria-Select.small .bcds-react-aria-Select--Button {
min-height: 32px;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following up on the comments here, I think this value needs to change to accommodate the extra ~1px happening when we're in multi-select mode with one option selected.

What I suggest is adding a class on the Select to indicate that you're in multi-select mode, and then choosing one of these:

  1. To keep all of the fields the same height, you could start playing with the padding inside of the Select button to accommodate the extra ~1px of height the Tag causes.

  2. If you don't care if the overall height of the Select field in multi-select mode is slightly taller than other components, you can set this min-height to 40px and the equivalent medium min-height to 46px.

}
.bcds-react-aria-Select--ListBox.small .bcds-react-aria-Select--ListBoxItem {
padding: var(--layout-padding-xsmall);
}
.bcds-react-aria-Select.small .bcds-react-aria-SelectValue--Text,
.bcds-react-aria-Select--ListBox.small
.bcds-react-aria-Select--ListBoxItem-Text-label {
font: var(--typography-regular-small-body);
}
.bcds-react-aria-Select.medium .bcds-react-aria-Select--Button {
min-height: 40px;
}
.bcds-react-aria-Select--ListBox.medium .bcds-react-aria-Select--ListBoxItem {
padding: var(--layout-padding-small);
}
.bcds-react-aria-Select.medium .bcds-react-aria-SelectValue--Text,
.bcds-react-aria-Select--ListBox.medium
.bcds-react-aria-Select--ListBoxItem-Text-label {
font: var(--typography-regular-body);
}

/* Select input equivalent */
.bcds-react-aria-Select--Button {
background-color: var(--surface-color-forms-default);
border: 1px solid var(--surface-color-border-default);
border: var(--layout-border-width-small) solid
var(--surface-color-border-default);
border-radius: var(--layout-border-radius-medium);
cursor: pointer;
box-sizing: border-box;
display: flex;
justify-content: space-between;
gap: var(--layout-margin-small);
align-items: center;
padding: 0 12px;
padding: var(--layout-padding-small);
width: 100%;
min-width: 0;
max-width: 100%;
}
.bcds-react-aria-Select--Button[data-hovered] {
border-color: var(--surface-color-border-dark);
cursor: pointer;
}
.bcds-react-aria-Select--Button.invalid {
border-color: var(--support-border-color-danger);
}
Expand All @@ -60,9 +111,6 @@
background-color: var(--surface-color-forms-disabled);
cursor: not-allowed;
}
.bcds-react-aria-Select--Button[data-hovered] {
border-color: var(--surface-color-border-dark);
}
.bcds-react-aria-Select--Button[data-focused] {
border-color: var(--surface-color-border-active);
outline: solid var(--layout-border-width-medium)
Expand All @@ -72,27 +120,82 @@
.bcds-react-aria-Select--Button[data-pressed] {
border-color: var(--surface-color-border-active);
}
.bcds-react-aria-Select--Button.medium {
height: 40px;
}
.bcds-react-aria-Select--Button.small {
height: 32px;
}
.bcds-react-aria-Select--Button > .bcds-react-aria-SelectValue {
font: var(--typography-regular-body);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
flex: 1 1 auto;
overflow: visible;
white-space: normal;
text-align: left;
min-width: 0;
}
.bcds-react-aria-Select--Button > svg {
flex-shrink: 0;
flex: 0 0 auto;
}

/* Overlay for tags in multi-select mode */
.bcds-react-aria-Select--InputContainer {
display: grid;
width: 100%;
min-width: 0;
}
.bcds-react-aria-Select--InputContainer > .bcds-react-aria-Select--Button {
grid-area: 1 / 1;
align-self: stretch;
}
.bcds-react-aria-Select--TagOverlayContainer {
grid-area: 1 / 1;
min-width: 0;
display: flex;
align-items: center;
padding: var(--layout-padding-small);
padding-right: 2.5rem;
pointer-events: none;
}
.bcds-react-aria-Select--TagOverlay {
width: 100%;
min-width: 0;
pointer-events: none;
}
.bcds-react-aria-Select--TagOverlay .bcds-react-aria-Tag,
.bcds-react-aria-Select--TagOverlay .bcds-react-aria-Tag [slot="remove"],
.bcds-react-aria-Select--TagOverlay .bcds-react-aria-Tag button {
pointer-events: auto;
}

/* Label above select input */
.bcds-react-aria-Select--Label {
color: var(--typography-color-secondary);
font: var(--typography-regular-small-body);
padding: var(--layout-padding-xsmall) var(--layout-padding-none);
}
.bcds-react-aria-Select[data-disabled] > .bcds-react-aria-Select--Label {
color: var(--typography-color-disabled);
}

/* Text description below select input */
.bcds-react-aria-Select--Description {
font: var(--typography-regular-small-body);
color: var(--typography-color-secondary);
padding: var(--layout-padding-xsmall) var(--layout-padding-none);
}

/* Error message */
.bcds-react-aria-Select--Error {
font: var(--typography-regular-small-body);
color: var(--typography-color-danger);
}

/* Error icon */
.bcds-react-aria-Select[data-invalid]
.bcds-react-aria-Select--Button
svg:not(:last-child) {
color: var(--icons-color-danger);
}

/* Dropdown menu panel */
.bcds-react-aria-Select--Popover {
background-color: var(--surface-color-forms-default);
border: 1px solid var(--surface-color-border-default);
border: var(--layout-border-width-small) solid
var(--surface-color-border-default);
border-radius: var(--layout-border-radius-medium);
box-shadow: var(--surface-shadow-medium);
box-sizing: border-box;
Expand All @@ -106,9 +209,10 @@
outline: none;
}
.bcds-react-aria-Select--ListBox > .bcds-react-aria-Section:not(:first-child) {
border-top: 1px solid var(--surface-color-border-default);
border-top: var(--layout-border-width-small) solid
var(--surface-color-border-default);
margin-top: 1px;
padding-top: 2px;
padding-top: var(--layout-padding-hair);
}

/* Header label within Section of multi-section Select */
Expand All @@ -126,7 +230,6 @@
flex-direction: row;
align-items: center;
gap: var(--layout-margin-small);
padding: var(--layout-padding-small);
}
.bcds-react-aria-Select--ListBoxItem[data-focused],
.bcds-react-aria-Select--ListBoxItem[data-hovered] {
Expand All @@ -145,10 +248,8 @@
color: var(--typography-color-primary);
display: flex;
flex-direction: column;
flex-grow: 1;
}
.bcds-react-aria-Select--ListBoxItem-Text-label {
font: var(--typography-regular-body);
flex: 1 1 auto;
min-width: 0;
}
.bcds-react-aria-Select--ListBoxItem.destructive {
color: var(--surface-color-primary-danger-button-default);
Expand Down
Loading
Loading