component ButtonGroup { outputs { click(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object }) select(payload: { value: string | number | boolean | null | object; previousValue: string | number | boolean | null | object; item: string | number | boolean | null | object; index: number }) change(payload: { value: string | number | boolean | null | object; previousValue: string | number | boolean | null | object; item: string | number | boolean | null | object; index: number }) } props { items: unknown[] = [] value: string = "" size: string = "md" color: string = "primary" variant: string = "default" orientation: string = "horizontal" responsive: boolean = false attached: boolean = true selectable: boolean = false toolbar: boolean = false disabled: boolean = false ariaLabel: string = "Button group" class: string = "" } state selectedValue = value functions { shared function itemValue(item, index) { return item.value || item.label || String(index) } client function selectItem(item, index) { previousValue = selectedValue nextValue = itemValue(item, index) output.select({ value: nextValue, previousValue: previousValue, item: item, index: index }) if (selectable && previousValue !== nextValue) { selectedValue = nextValue output.change({ value: nextValue, previousValue: previousValue, item: item, index: index }) } } } view {
{#if items} {#each items as item, index} {/each} {/if}
} style { .wrn-next--button-group { display: inline-flex; align-items: stretch; width: fit-content; max-width: 100%; isolation: isolate; } .wrn-next--button-group[data-orientation="vertical"] { flex-direction: column; } .wrn-next--button-group[data-attached="false"] { gap: 0.5rem; } .wrn-next--button-group[data-disabled="true"] { cursor: not-allowed; opacity: 0.6; } .wrn-next--button-group[data-attached="true"] > :is(.wrn-btn, .wrn-action) { position: relative; margin: 0; } .wrn-next--button-group[data-attached="true"] > .wrn-action { display: flex; } .wrn-next--button-group[data-attached="true"] > :is(.wrn-btn, .wrn-action) :is(.wrn-btn) { height: 100%; } .wrn-next--button-group[data-attached="true"][data-orientation="horizontal"] > :is(.wrn-btn, .wrn-action):not(:first-child) { margin-inline-start: -1px; } .wrn-next--button-group[data-attached="true"][data-orientation="horizontal"] > .wrn-btn:not(:first-child):not(:last-child), .wrn-next--button-group[data-attached="true"][data-orientation="horizontal"] > .wrn-action:not(:first-child):not(:last-child) > .wrn-btn { border-radius: 0; } .wrn-next--button-group[data-attached="true"][data-orientation="horizontal"] > .wrn-btn:first-child:not(:last-child), .wrn-next--button-group[data-attached="true"][data-orientation="horizontal"] > .wrn-action:first-child:not(:last-child) > .wrn-btn { border-start-end-radius: 0; border-end-end-radius: 0; } .wrn-next--button-group[data-attached="true"][data-orientation="horizontal"] > .wrn-btn:last-child:not(:first-child), .wrn-next--button-group[data-attached="true"][data-orientation="horizontal"] > .wrn-action:last-child:not(:first-child) > .wrn-btn { border-start-start-radius: 0; border-end-start-radius: 0; } .wrn-next--button-group[data-attached="true"][data-orientation="vertical"] > :is(.wrn-btn, .wrn-action):not(:first-child) { margin-top: -1px; } .wrn-next--button-group[data-attached="true"][data-orientation="vertical"] > .wrn-btn:not(:first-child):not(:last-child), .wrn-next--button-group[data-attached="true"][data-orientation="vertical"] > .wrn-action:not(:first-child):not(:last-child) > .wrn-btn { border-radius: 0; } .wrn-next--button-group[data-attached="true"][data-orientation="vertical"] > .wrn-btn:first-child:not(:last-child), .wrn-next--button-group[data-attached="true"][data-orientation="vertical"] > .wrn-action:first-child:not(:last-child) > .wrn-btn { border-end-start-radius: 0; border-end-end-radius: 0; } .wrn-next--button-group[data-attached="true"][data-orientation="vertical"] > .wrn-btn:last-child:not(:first-child), .wrn-next--button-group[data-attached="true"][data-orientation="vertical"] > .wrn-action:last-child:not(:first-child) > .wrn-btn { border-start-start-radius: 0; border-start-end-radius: 0; } .wrn-next--button-group > :is(.wrn-btn, .wrn-action):focus-within, .wrn-next--button-group > .wrn-btn:focus-visible { z-index: 2; } .wrn-next--button-group[data-selectable="true"] > .wrn-btn[data-selected="true"] { z-index: 1; border-color: var(--wrn-component-color); background: color-mix(in srgb, var(--wrn-component-color) 16%, var(--wrn-color-surface)); color: var(--wrn-component-color); } @media (max-width: 480px) { .wrn-next--button-group[data-responsive="true"] > :is(.wrn-btn, .wrn-action) { display: flex; width: 100%; flex-direction: column; } .wrn-next--button-group[data-responsive="true"] > .wrn-action > .wrn-btn { width: 100%; } .wrn-next--button-group[data-responsive="true"][data-attached="true"] > :is(.wrn-btn, .wrn-action) { margin-top: -1px; margin-inline-start: 0; } .wrn-next--button-group[data-responsive="true"][data-attached="true"] > :is(.wrn-btn, .wrn-action):first-child { margin-top: 0; } .wrn-next--button-group[data-responsive="true"][data-attached="true"] > .wrn-btn, .wrn-next--button-group[data-responsive="true"][data-attached="true"] > .wrn-action > .wrn-btn { border-radius: 0; } .wrn-next--button-group[data-responsive="true"][data-attached="true"] > .wrn-btn:first-child, .wrn-next--button-group[data-responsive="true"][data-attached="true"] > .wrn-action:first-child > .wrn-btn { border-start-start-radius: var(--wrn-radius-sm); border-start-end-radius: var(--wrn-radius-sm); } .wrn-next--button-group[data-responsive="true"][data-attached="true"] > .wrn-btn:last-child, .wrn-next--button-group[data-responsive="true"][data-attached="true"] > .wrn-action:last-child > .wrn-btn { border-end-start-radius: var(--wrn-radius-sm); border-end-end-radius: var(--wrn-radius-sm); } } /* Shared component foundation. */ .wrn-component { --wrn-component-color: var(--wrn-color-primary); --wrn-component-scale: 1; margin: 0; color: var(--wrn-color-text); font-family: var(--wrn-font-sans, inherit); } .wrn-component--color-primary { --wrn-component-color: var(--wrn-color-primary); } .wrn-component--color-secondary { --wrn-component-color: var(--wrn-color-secondary); } .wrn-component--color-success { --wrn-component-color: var(--wrn-color-success); } .wrn-component--color-warning { --wrn-component-color: var(--wrn-color-warning); } .wrn-component--color-danger { --wrn-component-color: var(--wrn-color-danger); } .wrn-component--color-info { --wrn-component-color: var(--wrn-color-info); } .wrn-component--size-xs { --wrn-component-scale: 0.78; } .wrn-component--size-sm { --wrn-component-scale: 0.88; } .wrn-component--size-default, .wrn-component--size-md { --wrn-component-scale: 1; } .wrn-component--size-lg { --wrn-component-scale: 1.14; } .wrn-component--size-xl { --wrn-component-scale: 1.28; } .wrn-component:not(.wrn-btn) { font-size: calc(1em * var(--wrn-component-scale)); } .wrn-component :is(a, button, input, select, textarea):focus-visible { outline-color: var(--wrn-component-color); } .wrn-component p { margin: 0; color: var(--wrn-color-muted); line-height: 1.6; } } }