File size: 2,998 Bytes
bc20498 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
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,
};
}
|