All files / actions add-class.ts

100% Statements 24/24
100% Branches 0/0
100% Functions 10/10
100% Lines 24/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134                94x   94x           94x                                           94x                                 188x   1x         2x 2x   2x 2x 2x                                               94x                                 188x   1x         2x 2x   2x 2x 2x           94x 4x 6x 6x 4x      
/**
 * @module Actions
 *
 * @categoryDescription Adding/removing class
 * {@link AddClass} and {@link RemoveClass} add or remove a list of CSS classes
 * to/from the given element.
 */
 
import * as MC from "@lisn/globals/minification-constants";
 
import {
  addClasses,
  removeClasses,
  toggleClasses,
} from "@lisn/utils/css-alter";
 
import { Action, registerAction } from "@lisn/actions/action";
 
/**
 * Adds or removes a list of CSS classes to/from the given element.
 *
 * **IMPORTANT:** When constructed, it removes all given classes from the
 * element as a form of initialization.
 *
 * -------
 *
 * To use with auto-widgets (HTML API) as part of a trigger specification:
 * - Action name: "add-class".
 * - Arguments (required): one or more CSS classes
 * - Options: none
 *
 * @example
 * ```html
 * <div data-lisn-on-view="@add-class: clsA, clsB"></div>
 * ```
 *
 * @category Adding/removing class
 */
export class AddClass implements Action {
  /**
   * Adds the classes given to the constructor.
   */
  readonly do: () => Promise<void>;
 
  /**
   * Removes the classes given to the constructor.
   */
  readonly undo: () => Promise<void>;
 
  /**
   * Toggles each class given to the constructor.
   */
  readonly toggle: () => Promise<void>;
 
  static register() {
    registerAction(
      "add-class",
      (element, classNames) => new AddClass(element, ...classNames),
    );
  }
 
  constructor(element: Element, ...classNames: string[]) {
    const { _add, _remove, _toggle } = getMethods(element, classNames);
    _remove(); // initial state
 
    this.do = _add;
    this.undo = _remove;
    this[MC.S_TOGGLE] = _toggle;
  }
}
 
/**
 * Removes or adds a list of CSS classes to/from the given element.
 *
 * **IMPORTANT:** When constructed, it adds all given classes from the element
 * as a form of initialization.
 *
 * -------
 *
 * To use with auto-widgets (HTML API) as part of a trigger specification:
 * - Action name: "remove-class".
 * - Arguments (required): one or more CSS classes
 * - Options: none
 *
 * @example
 * ```html
 * <div data-lisn-on-view="@remove-class: clsA, clsB"></div>
 * ```
 *
 * @category Adding/removing class
 */
export class RemoveClass implements Action {
  /**
   * Removes the classes given to the constructor.
   */
  readonly do: () => Promise<void>;
 
  /**
   * Adds the classes given to the constructor.
   */
  readonly undo: () => Promise<void>;
 
  /**
   * Toggles each class given to the constructor.
   */
  readonly toggle: () => Promise<void>;
 
  static register() {
    registerAction(
      "remove-class",
      (element, classNames) => new RemoveClass(element, ...classNames),
    );
  }
 
  constructor(element: Element, ...classNames: string[]) {
    const { _add, _remove, _toggle } = getMethods(element, classNames);
    _add(); // initial state
 
    this.do = _remove;
    this.undo = _add;
    this[MC.S_TOGGLE] = _toggle;
  }
}
 
// --------------------
 
const getMethods = (element: Element, classNames: string[]) => {
  return {
    _add: () => addClasses(element, ...classNames),
    _remove: () => removeClasses(element, ...classNames),
    _toggle: () => toggleClasses(element, ...classNames),
  };
};