@melt-ui/svelte
Version:

74 lines (73 loc) • 2.9 kB
JavaScript
import { createElHelpers, makeElement } from '../../internal/helpers/makeElement.js';
import { readable } from 'svelte/store';
import { styleToString } from '../../internal/helpers/style.js';
import { toReadableStores } from '../../internal/helpers/store/toReadableStores.js';
import { omit } from '../../internal/helpers/object.js';
import { removeUndefined } from '../../internal/helpers/object.js';
import { withGet } from '../../internal/helpers/withGet.js';
import { executeCallbacks } from '../../internal/helpers/callbacks.js';
const defaults = {
prefix: '',
disabled: readable(false),
required: readable(false),
name: readable(undefined),
type: readable(undefined),
checked: undefined,
};
export function createHiddenInput(props) {
const withDefaults = {
...defaults,
...removeUndefined(props),
};
const { name: elName } = createElHelpers(withDefaults.prefix);
const { value, name, disabled, required, type, checked } = toReadableStores(omit(withDefaults, 'prefix'));
const nameStore = name; // TODO: Remove this cast when types are fixed
const actualChecked = withGet.derived([checked, type], ([$checked, $type]) => {
if ($type === 'checkbox') {
return ($checked === 'indeterminate' ? false : $checked);
}
return undefined;
});
const hiddenInput = makeElement(elName('hidden-input'), {
stores: [value, nameStore, disabled, required, type, actualChecked],
returned: ([$value, $name, $disabled, $required, $type, $checked]) => {
return {
name: $name,
value: $value?.toString(),
'aria-hidden': 'true',
hidden: true,
disabled: $disabled,
required: $required,
tabIndex: -1,
type: $type,
checked: $checked,
style: styleToString({
position: 'absolute',
opacity: 0,
'pointer-events': 'none',
margin: 0,
transform: 'translateX(-100%)',
}),
};
},
action: (node) => {
// When value changes, emit a change event
const unsub = executeCallbacks(value.subscribe((newValue) => {
if (type.get() === 'checkbox') {
return;
}
node.value = newValue;
node.dispatchEvent(new Event('change', { bubbles: true }));
}), actualChecked.subscribe(() => {
if (type.get() !== 'checkbox') {
return;
}
node.dispatchEvent(new Event('change', { bubbles: true }));
}));
return {
destroy: unsub,
};
},
});
return hiddenInput;
}