diff --git a/src/components/ui/menu/MenuCheckboxItem.svelte b/src/components/ui/menu/MenuCheckboxItem.svelte index 9591e8a..1385317 100644 --- a/src/components/ui/menu/MenuCheckboxItem.svelte +++ b/src/components/ui/menu/MenuCheckboxItem.svelte @@ -13,6 +13,8 @@ oninput?: FormEventHandler; } + let checkboxElement: HTMLInputElement; + let { checked = $bindable(), name = undefined, @@ -23,14 +25,48 @@ oninput, }: MenuCheckboxItemProps = $props(); + /** + * Prevent clicks from getting sent to the menu link if user clicked directly on the checkbox. + * @param originalEvent + */ function stopPropagationAndPassCallback(originalEvent: MouseEvent) { originalEvent.stopPropagation(); onclick?.(originalEvent as MouseEvent & { currentTarget: HTMLInputElement }); } + + /** + * Check and try to toggle checkbox if href was not provided for the menu item. + */ + function maybeToggleCheckboxOnOuterLinkClicked() { + // When menu link does not contain any link, we should just treat clicks on it as toggle action on checkbox. + if (!href) { + checked = !checked; + + // Since we've toggled it using the `checked` property and input does not trigger `onclick` when we do something + // programmatically, we should create valid event and send it back to the parent component so it will handle + // whatever it wants. + if (oninput) { + // Uhh, not sure if this is how it should be done, but we need `currentTarget` to point on the checkbox. Without + // dispatching the event, we can't fill it normally. Also, input element does not return us untrusted input + // events automatically. Probably should make the util function later in case I'd need something similar. + checkboxElement.addEventListener('input', (inputEvent: Event) => { + oninput(inputEvent as Event & { currentTarget: HTMLInputElement }); + }, { once: true }) + + checkboxElement.dispatchEvent(new InputEvent('input')); + } + } + } - - + + {@render children?.()}