All files / widgets track-size.ts

95% Statements 19/20
100% Branches 2/2
100% Functions 5/5
94.73% Lines 18/19

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        94x   94x   94x   94x                                                                               94x   8x 8x 4x   4x       94x     3x 3x                 5x   5x                   5x                                                         94x     94x     94x        
/**
 * @module Widgets
 */
 
import * as MH from "@lisn/globals/minification-helpers";
 
import { validateNumber } from "@lisn/utils/validation";
 
import { SizeWatcher } from "@lisn/watchers/size-watcher";
 
import {
  Widget,
  WidgetConfigValidatorObject,
  registerWidget,
} from "@lisn/widgets/widget";
 
/**
 * This is a simple wrapper around the {@link SizeWatcher}. If you are using
 * the JavaScript API, you should use the {@link SizeWatcher} directly. The
 * purpose of this widget is to expose the watcher's ability to track size
 * and set relevant CSS properties via the HTML API. See
 * {@link SizeWatcher.trackSize}.
 *
 * -----
 *
 * To use with auto-widgets (HTML API) (see
 * {@link Settings.settings.autoWidgets | settings.autoWidgets}), the following
 * CSS classes or data attributes are recognized:
 * - `lisn-track-size` class or `data-lisn-track-size` attribute set on
 *   the element that constitutes the widget.
 *
 * This widget does not support configuration and uses the default
 * {@link SizeWatcher} configuration except for resize threshold equal to 0.
 *
 * @example
 * This will track the size of this element and set the relevant CSS
 * properties. It will use the default {@link SizeWatcher} options and resize
 * threshold of 0.
 *
 * ```html
 * <div class="lisn-track-size"></div>
 * ```
 *
 * @example
 * As above but with custom options
 *
 * ```html
 * <div data-lisn-track-size="threshold=0 | debounce-window=0"></div>
 * ```
 */
export class TrackSize extends Widget {
  static get(element: Element): TrackSize | null {
    const instance = super.get(element, DUMMY_ID);
    if (MH.isInstanceOf(instance, TrackSize)) {
      return instance;
    }
    return null;
  }
 
  static register() {
    registerWidget(
      WIDGET_NAME,
      (element, config) => {
        if (!TrackSize.get(element)) {
          return new TrackSize(element, config);
        }
        return null;
      },
      configValidator,
    );
  }
 
  constructor(element: Element, config?: TrackSizeConfig) {
    super(element, { id: DUMMY_ID });
 
    SizeWatcher.reuse().trackSize(
      null,
      MH.assign(
        {
          target: element,
        },
        config,
      ),
    );
 
    this.onDestroy(() => SizeWatcher.reuse().noTrackSize(null, element));
  }
}
 
/**
 * @interface
 *
 * @since v1.2.0
 */
export type TrackSizeConfig = {
  /**
   * Corresponds to
   * {@link Watchers/SizeWatcher.OnResizeOptions.threshold | OnResizeOptions.threshold}.
   *
   * @defaultValue undefined // SizeWatcher default
   */
  threshold?: number;
 
  /**
   * Corresponds to
   * {@link Watchers/SizeWatcher.OnResizeOptions.debounceWindow | OnResizeOptions.debounceWindow}.
   *
   * @defaultValue undefined // SizeWatcher default
   */
  debounceWindow?: number;
};
 
// --------------------
 
const WIDGET_NAME = "track-size";
// Only one TrackSize widget per element is allowed, but Widget requires a
// non-blank ID.
const DUMMY_ID = WIDGET_NAME;
 
// For HTML API only
const configValidator: WidgetConfigValidatorObject<TrackSizeConfig> = {
  threshold: validateNumber,
  debounceWindow: validateNumber,
};