import { addMeltEventListener, makeElement, createElHelpers, disabledAttr, kbd, omit, overridable, styleToString, toWritableStores, } from '../../internal/helpers/index.js'; import { writable } from 'svelte/store'; import { executeCallbacks } from '../../internal/helpers/callbacks.js'; const defaults = { defaultChecked: false, disabled: false, required: false, name: '', value: '', }; const { name } = createElHelpers('switch'); export function createSwitch(props) { const propsWithDefaults = { ...defaults, ...props }; const options = toWritableStores(omit(propsWithDefaults, 'checked')); const { disabled, required, name: nameStore, value } = options; const checkedWritable = propsWithDefaults.checked ?? writable(propsWithDefaults.defaultChecked); const checked = overridable(checkedWritable, propsWithDefaults?.onCheckedChange); function toggleSwitch() { if (disabled.get()) return; checked.update((prev) => !prev); } const root = makeElement(name(), { stores: [checked, disabled, required], returned: ([$checked, $disabled, $required]) => { return { 'data-disabled': disabledAttr($disabled), disabled: disabledAttr($disabled), 'data-state': $checked ? 'checked' : 'unchecked', type: 'button', role: 'switch', 'aria-checked': $checked ? 'true' : 'false', 'aria-required': $required ? 'true' : undefined, }; }, action(node) { const unsub = executeCallbacks(addMeltEventListener(node, 'click', () => { toggleSwitch(); }), addMeltEventListener(node, 'keydown', (e) => { if (e.key !== kbd.ENTER && e.key !== kbd.SPACE) return; e.preventDefault(); toggleSwitch(); })); return { destroy: unsub, }; }, }); const input = makeElement(name('input'), { stores: [checked, nameStore, required, disabled, value], returned: ([$checked, $name, $required, $disabled, $value]) => { return { type: 'checkbox', 'aria-hidden': true, hidden: true, tabindex: -1, name: $name, value: $value, checked: $checked, required: $required, disabled: disabledAttr($disabled), style: styleToString({ position: 'absolute', opacity: 0, 'pointer-events': 'none', margin: 0, transform: 'translateX(-100%)', }), }; }, }); return { elements: { root, input, }, states: { checked, }, options, }; }