Conditionally forward MenuItem click events only if the MenuItem is not disabled
This is obviously a lot easier in React, but at any rate this mimics upstream behavior here.
This commit is contained in:
@@ -8,7 +8,9 @@
|
|||||||
import { forwardEventsBuilder } from "$lib/internal/forwardEventsBuilder";
|
import { forwardEventsBuilder } from "$lib/internal/forwardEventsBuilder";
|
||||||
import { get_current_component } from "svelte/internal";
|
import { get_current_component } from "svelte/internal";
|
||||||
import type { HTMLActionArray } from "$lib/hooks/use-actions";
|
import type { HTMLActionArray } from "$lib/hooks/use-actions";
|
||||||
const forwardEvents = forwardEventsBuilder(get_current_component());
|
const forwardEvents = forwardEventsBuilder(get_current_component(), [
|
||||||
|
{ name: "click", shouldExclude: () => disabled },
|
||||||
|
]);
|
||||||
export let as: SupportedAs = "a";
|
export let as: SupportedAs = "a";
|
||||||
export let use: HTMLActionArray = [];
|
export let use: HTMLActionArray = [];
|
||||||
export let disabled = false;
|
export let disabled = false;
|
||||||
|
|||||||
@@ -1,16 +1,22 @@
|
|||||||
// This is a modified version of code from hperrin/svelte-material-ui
|
// This is a modified version of code from hperrin/svelte-material-ui
|
||||||
import type { SvelteComponent } from 'svelte';
|
import type { SvelteComponent } from "svelte";
|
||||||
import {
|
import {
|
||||||
bubble,
|
bubble,
|
||||||
listen,
|
listen,
|
||||||
prevent_default,
|
prevent_default,
|
||||||
stop_propagation,
|
stop_propagation,
|
||||||
} from 'svelte/internal';
|
} from "svelte/internal";
|
||||||
|
|
||||||
const MODIFIER_DIVIDER = "!";
|
const MODIFIER_DIVIDER = "!";
|
||||||
const modifierRegex = new RegExp(`^[^${MODIFIER_DIVIDER}]+(?:${MODIFIER_DIVIDER}(?:preventDefault|stopPropagation|passive|nonpassive|capture|once|self))+$`);
|
const modifierRegex = new RegExp(
|
||||||
|
`^[^${MODIFIER_DIVIDER}]+(?:${MODIFIER_DIVIDER}(?:preventDefault|stopPropagation|passive|nonpassive|capture|once|self))+$`
|
||||||
|
);
|
||||||
|
|
||||||
export function forwardEventsBuilder(component: SvelteComponent, except: string[] = []) {
|
type ForwardException = string | { name: string; shouldExclude: () => boolean };
|
||||||
|
export function forwardEventsBuilder(
|
||||||
|
component: SvelteComponent,
|
||||||
|
except: ForwardException[] = []
|
||||||
|
) {
|
||||||
// This is our pseudo $on function. It is defined on component mount.
|
// This is our pseudo $on function. It is defined on component mount.
|
||||||
let $on: (eventType: string, callback: (event: any) => void) => () => void;
|
let $on: (eventType: string, callback: (event: any) => void) => () => void;
|
||||||
// This is a list of events bound before mount.
|
// This is a list of events bound before mount.
|
||||||
@@ -19,17 +25,30 @@ export function forwardEventsBuilder(component: SvelteComponent, except: string[
|
|||||||
// And we override the $on function to forward all bound events.
|
// And we override the $on function to forward all bound events.
|
||||||
component.$on = (fullEventType: string, callback: (event: any) => void) => {
|
component.$on = (fullEventType: string, callback: (event: any) => void) => {
|
||||||
let eventType = fullEventType;
|
let eventType = fullEventType;
|
||||||
let destructor = () => { };
|
let destructor = () => {};
|
||||||
if (except.includes(eventType)) {
|
for (let exception of except) {
|
||||||
|
if (typeof exception === "string" && exception === eventType) {
|
||||||
// Bail out of the event forwarding and run the normal Svelte $on() code
|
// Bail out of the event forwarding and run the normal Svelte $on() code
|
||||||
const callbacks = (component.$$.callbacks[eventType] || (component.$$.callbacks[eventType] = []));
|
const callbacks =
|
||||||
|
component.$$.callbacks[eventType] ||
|
||||||
|
(component.$$.callbacks[eventType] = []);
|
||||||
callbacks.push(callback);
|
callbacks.push(callback);
|
||||||
return () => {
|
return () => {
|
||||||
const index = callbacks.indexOf(callback);
|
const index = callbacks.indexOf(callback);
|
||||||
if (index !== -1)
|
if (index !== -1) callbacks.splice(index, 1);
|
||||||
callbacks.splice(index, 1);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (typeof exception === "object" && exception["name"] === eventType) {
|
||||||
|
let oldCallback = callback;
|
||||||
|
callback = (...props) => {
|
||||||
|
if (
|
||||||
|
!(typeof exception === "object" && exception["shouldExclude"]())
|
||||||
|
) {
|
||||||
|
oldCallback(...props);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
if ($on) {
|
if ($on) {
|
||||||
// The event was bound programmatically.
|
// The event was bound programmatically.
|
||||||
destructor = $on(eventType, callback);
|
destructor = $on(eventType, callback);
|
||||||
|
|||||||
Reference in New Issue
Block a user