Skip to content

Multiple select

Use multiple for multi-selection; the trigger reflects selected labels.

Code

The following example assumes that you have imported the component and set up the theme.

Multiple select
<div class="select-container">
<label for="teams-select">Assign Teams</label>
<sv-select class="teams-select" multiple>
<sv-flyout>
<!-- Select Trigger -->
<button id="teams-select" type="button" class="trigger" slot="trigger">
<!-- Visible when a value is selected -->
<span class="truncate" data-select-has-value>
<!-- Selected values labels injected here -->
<span data-select-label></span>
</span>
<!-- Visible when no value is selected -->
<span style="flex: 1; text-align: start" data-select-no-value>Select one or more teams</span>
<svg class="trigger-icon" aria-hidden="false" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg">
<path d="M480-360 280-560h400L480-360Z"></path>
</svg>
</button>
<!-- Options -->
41 collapsed lines
<button class="option" value="engineering">
<svg class="option-check-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg">
<path d="M382-240 154-468l57-57 171 171 367-367 57 57-424 424Z"></path>
</svg>
<span>Engineering</span>
</button>
<button class="option" value="design">
<svg class="option-check-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg">
<path d="M382-240 154-468l57-57 171 171 367-367 57 57-424 424Z"></path>
</svg>
<span>Design</span>
</button>
<button class="option" value="product">
<svg class="option-check-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg">
<path d="M382-240 154-468l57-57 171 171 367-367 57 57-424 424Z"></path>
</svg>
<span>Product</span>
</button>
<button class="option" value="qa">
<svg class="option-check-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg">
<path d="M382-240 154-468l57-57 171 171 367-367 57 57-424 424Z"></path>
</svg>
<span>QA</span>
</button>
<button class="option" disabled value="devops">
<svg class="option-check-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg">
<path d="M382-240 154-468l57-57 171 171 367-367 57 57-424 424Z"></path>
</svg>
<span>DevOps</span>
</button>
<button class="option" value="data">
<svg class="option-check-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg">
<path d="M382-240 154-468l57-57 171 171 367-367 57 57-424 424Z"></path>
</svg>
<span>Data</span>
</button>
</sv-flyout>
</sv-select>
</div>
<style>
.select-container {
5 collapsed lines
display: flex;
flex-direction: column;
gap: 0.5em;
max-inline-size: 350px;
margin: auto;
.option {
12 collapsed lines
display: flex;
gap: 0.5em;
align-items: center;
padding: 0.5em;
font-family: inherit;
font-size: 1rem;
color: var(--sv-gray-2);
cursor: pointer;
background-color: var(--sv-gray-7);
border: none;
border-radius: var(--sv-bdr-rad-md);
transition: background-color 200ms;
.option-check-icon {
3 collapsed lines
inline-size: 1em;
block-size: 1em;
fill: none;
}
&[aria-selected="true"] {
6 collapsed lines
color: var(--sv-accent-content);
background-color: var(--sv-accent);
.option-check-icon {
fill: var(--sv-accent-content);
}
}
&[disabled] {
cursor: not-allowed;
opacity: 0.5;
}
@media (hover: hover) and (pointer: fine) {
&:not([disabled], [aria-selected="true"]):hover {
background-color: var(--sv-gray-5);
}
}
}
.trigger {
21 collapsed lines
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 0.5em;
font-family: inherit;
font-size: 1rem;
color: var(--sv-gray-2);
cursor: pointer;
background-color: var(--sv-gray-6);
border: solid var(--sv-bdr-sz-sm) var(--sv-gray-5);
border-radius: var(--sv-bdr-rad-md);
transition: border-color 200ms ease;
.trigger-icon {
inline-size: 1.5em;
block-size: 1.5em;
fill: currentcolor;
rotate: 90deg;
transition: rotate 200ms ease;
}
}
sv-flyout::part(content) {
/* Match the flyout’s inline size to the anchor (trigger). */
inline-size: var(--sv-anchor-width);
/*
Define the smallest useful flyout for this list.
When a position has less space, the anchor tries the next fallback.
*/
min-block-size: 100px;
/* Let long content shrink and scroll so the current position can fit. */
max-block-size: var(--sv-anchor-available-height);
}
sv-flyout:state(--open) {
.trigger {
border: solid var(--sv-bdr-sz-sm) var(--sv-accent);
.trigger-icon {
rotate: 0deg;
}
}
}
.truncate {
4 collapsed lines
max-inline-size: 90%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
</style>