diff --git a/packages/controllers/src/signal/base_controller.ts b/packages/controllers/src/signal/base_controller.ts index ba64b777..64057310 100644 --- a/packages/controllers/src/signal/base_controller.ts +++ b/packages/controllers/src/signal/base_controller.ts @@ -1,6 +1,6 @@ import { BaseController, EventBus } from "@stimulus-library/utilities"; import { SignalPayload } from "./signal_input_controller"; -import { extractPredicates } from "./expressions"; +import { extractExpressions, extractPredicates } from "./expressions"; import { signalConnectEvent, signalValueEvent } from "./events"; import { useEventBus } from "@stimulus-library/mixins"; @@ -12,11 +12,6 @@ export abstract class SignalBaseController extends BaseController { declare nameValue: string; - connect() { - EventBus.emit(signalConnectEvent(this.nameValue)); - useEventBus(this, signalValueEvent(this.nameValue), this._onSignal); - } - get predicateString() { return ""; } @@ -25,8 +20,21 @@ export abstract class SignalBaseController extends BaseController { return extractPredicates(this.predicateString); } - allPredicatesMatch(value: SignalPayload["value"]): boolean { - return this._predicates.every(predicate => predicate(value)); + get _expressions(): Array { + return extractExpressions(this.predicateString); + } + + connect() { + EventBus.emit(signalConnectEvent(this.nameValue)); + useEventBus(this, signalValueEvent(this.nameValue), this._onSignal); + } + + predicatesMatch(value: SignalPayload["value"]): boolean { + if (this.predicateString.includes("||")) { + return this._predicates.some(predicate => predicate(value)); + } else { + return this._predicates.every(predicate => predicate(value)); + } } abstract _onSignal(payload: SignalPayload): void; diff --git a/packages/controllers/src/signal/expressions.ts b/packages/controllers/src/signal/expressions.ts index 5b035795..051b4970 100644 --- a/packages/controllers/src/signal/expressions.ts +++ b/packages/controllers/src/signal/expressions.ts @@ -1,3 +1,8 @@ +export function extractExpressions(expressionString: string): Array { + const andExpression = expressionString.includes("&&"); + return expressionString.split(andExpression ? "&&" : "||"); +} + export function extractPredicates(expressionString: string): Array<(val: string | number) => boolean> { expressionString = expressionString.trim(); @@ -13,7 +18,8 @@ export function extractPredicates(expressionString: string): Array<(val: string throw new Error("Cannot have logical groupings `(>3 && <= 9) || (>1 && <2)` in the expression. Only supports simple expressions like `>1 && <3`"); } - const expressions = expressionString.split(andExpression ? "&&" : "||"); + const expressions = extractExpressions(expressionString); + if (andExpression) { return expressions.map(ex => _predicateForExpression(ex)); } else if (orExpression) { diff --git a/packages/controllers/src/signal/signal_action_controller.ts b/packages/controllers/src/signal/signal_action_controller.ts index 9384c4df..01b4f3c0 100644 --- a/packages/controllers/src/signal/signal_action_controller.ts +++ b/packages/controllers/src/signal/signal_action_controller.ts @@ -24,10 +24,28 @@ export class SignalActionController extends SignalBaseController { this.dispatchEvent(this.el, signalEventName(this.nameValue, "match")); return; } - if (this.allPredicatesMatch(value)) { - this.dispatchEvent(this.el, signalEventName(this.nameValue, "match"), {detail: {element: this.el, value}}); + if (this.predicatesMatch(value)) { + this.dispatchEvent( + this.el, + signalEventName(this.nameValue, "match"), + { + detail: { + element: this.el, + value, + }, + }, + ); } else { - this.dispatchEvent(this.el, signalEventName(this.nameValue, "no-match"), {detail: {element: this.el, value}}); + this.dispatchEvent( + this.el, + signalEventName(this.nameValue, "no-match"), + { + detail: { + element: this.el, + value, + }, + }, + ); } } diff --git a/packages/controllers/src/signal/signal_disable_controller.ts b/packages/controllers/src/signal/signal_disable_controller.ts index 9b80413a..da84c736 100644 --- a/packages/controllers/src/signal/signal_disable_controller.ts +++ b/packages/controllers/src/signal/signal_disable_controller.ts @@ -34,19 +34,29 @@ export class SignalDisableController extends SignalBaseController { } return; } - if (this.allPredicatesMatch(value)) { - this.dispatchEvent(this.el, signalEventName(this.nameValue, "disable"), { - detail: { - predicate: this.whenValue, value, + if (this.predicatesMatch(value)) { + this.dispatchEvent( + this.el, + signalEventName(this.nameValue, "disable"), + { + detail: { + predicate: this.whenValue, + value, + }, }, - }); + ); this.disable(); } else { - this.dispatchEvent(this.el, signalEventName(this.nameValue, "enable"), { - detail: { - predicate: this.whenValue, value, + this.dispatchEvent( + this.el, + signalEventName(this.nameValue, "enable"), + { + detail: { + predicate: this.whenValue, + value, + }, }, - }); + ); this.enable(); } } diff --git a/packages/controllers/src/signal/signal_enable_controller.ts b/packages/controllers/src/signal/signal_enable_controller.ts index 1aaa9a07..3971de11 100644 --- a/packages/controllers/src/signal/signal_enable_controller.ts +++ b/packages/controllers/src/signal/signal_enable_controller.ts @@ -34,7 +34,7 @@ export class SignalEnableController extends SignalBaseController { } return; } - if (this.allPredicatesMatch(value)) { + if (this.predicatesMatch(value)) { this.dispatchEvent(this.el, signalEventName(this.nameValue, "enable"), { detail: { predicate: this.whenValue, diff --git a/packages/controllers/src/signal/signal_visibility_controller.ts b/packages/controllers/src/signal/signal_visibility_controller.ts index 15be39f8..0bbdbec6 100644 --- a/packages/controllers/src/signal/signal_visibility_controller.ts +++ b/packages/controllers/src/signal/signal_visibility_controller.ts @@ -40,11 +40,29 @@ export class SignalVisibilityController extends SignalBaseController { } return; } - if (this.allPredicatesMatch(value)) { - this.dispatchEvent(this.el, signalVisibilityEvent(this.nameValue, "show"), {detail: {predicate: this.showValue, value}}); + if (this.predicatesMatch(value)) { + this.dispatchEvent( + this.el, + signalVisibilityEvent(this.nameValue, "show"), + { + detail: { + predicate: this.showValue, + value + } + } + ); this.removeHideClasses(this.el); } else { - this.dispatchEvent(this.el, signalVisibilityEvent(this.nameValue, "hide"), {detail: {predicate: this.showValue, value}}); + this.dispatchEvent( + this.el, + signalVisibilityEvent(this.nameValue, "hide"), + { + detail: { + predicate: this.showValue, + value + } + } + ); this.addHideClasses(this.el); } }