Files
Clintchiz 2c960fc1dc
Quality / quality (ubuntu-latest) (push) Failing after 9m49s
Quality / quality (windows-latest) (push) Canceled after 0s
refactor: migrate legacy wire namespace to wrn
2026-08-12 18:51:15 +05:30

305 lines
9.9 KiB
Plaintext

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 {
<div
{...attrs}
class="wrn-component wrn-next--button-group {class}"
role="{toolbar ? 'toolbar' : 'group'}"
aria-label="{ariaLabel}"
aria-orientation="{orientation}"
data-size="{size}"
data-color="{color}"
data-variant="{variant}"
data-orientation="{orientation}"
data-responsive="{responsive}"
data-attached="{attached}"
data-selectable="{selectable}"
data-disabled="{disabled}"
>
{#if items}
{#each items as item, index}
<button
type="{item.type || 'button'}"
class="wrn-btn wrn-btn--variant-{item.variant || variant} wrn-btn--color-{item.color || color} wrn-btn--size-{item.size || size}"
disabled="{disabled || item.disabled}"
aria-label="{item.ariaLabel || item.label}"
aria-pressed="{selectable ? (selectedValue === (item.value || item.label || String(index)) ? 'true' : 'false') : ''}"
data-value="{item.value || item.label || String(index)}"
data-selected="{selectable && selectedValue === (item.value || item.label || String(index)) ? 'true' : 'false'}"
@click="selectItem(item, index)"
>
{#if item.icon}
<span class="wrn-btn__icon {item.icon}" aria-hidden="true"></span>
{/if}
<span class="wrn-btn__label">{item.label}</span>
</button>
{/each}
{/if}
<slot />
</div>
}
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;
}
}
}