Files
windmill/frontend/src/lib/components/common/toggleButton-v2/ToggleButtonGroup.svelte
T
2025-09-30 16:33:48 +01:00

83 lines
1.7 KiB
Svelte

<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { twMerge } from 'tailwind-merge'
import { createSync } from '@melt-ui/svelte'
const dispatch = createEventDispatcher()
import { createToggleGroup, melt } from '@melt-ui/svelte'
interface Props {
id?: string | null | undefined
selected?: string | string[] | undefined
noWFull?: boolean
disabled?: boolean
tabListClass?: string
allowEmpty?: boolean
class?: string
wrap?: boolean
children?: import('svelte').Snippet<[any]>
onSelected?: (value: any) => void
}
let {
id = undefined,
selected = $bindable(undefined),
noWFull = false,
disabled = false,
tabListClass = '',
allowEmpty = false,
class: className = '',
wrap = false,
onSelected,
children
}: Props = $props()
const {
elements: { root, item },
options: { disabled: disabledOption },
states
} = createToggleGroup({
type: 'single',
onValueChange: ({ curr, next }) => {
if (next === undefined && !allowEmpty) {
return curr
}
if (curr !== next && curr !== undefined) {
dispatch('selected', next)
onSelected?.(next)
}
return next
}
})
$effect(() => {
$disabledOption = disabled
})
const sync = createSync(states)
$effect(() => {
sync.value(selected, (v) => (selected = v))
})
</script>
<div
use:melt={$root}
class={twMerge(
`flex ${noWFull ? '' : 'w-full'} ${disabled ? 'disabled' : ''}`,
className,
'flex items-center data-[orientation="vertical"]:flex-col'
)}
aria-label="Toggle button group"
{id}
>
<div
class={twMerge(
'flex bg-surface-tertiary rounded-md h-full',
wrap ? 'flex-wrap' : '',
tabListClass
)}
>
{@render children?.({ item, disabled })}
</div>
</div>