@unlk/keymaster 1.6.7 → 1.6.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Unlock Keymaster v1.6.7 (https://keymaster.unlock.com)
2
+ * Unlock Keymaster v1.6.8 (https://keymaster.unlock.com)
3
3
  * Copyright 2022-2026 Unlk Developers
4
4
  */
5
5
  (function (global, factory) {
@@ -7459,16 +7459,16 @@
7459
7459
  }
7460
7460
  }
7461
7461
 
7462
- const NAME$2 = 'datepicker';
7463
- const DATA_KEY = 'bs.datepicker';
7464
- const EVENT_KEY = `.${DATA_KEY}`;
7462
+ const NAME$3 = 'datepicker';
7463
+ const DATA_KEY$1 = 'bs.datepicker';
7464
+ const EVENT_KEY$1 = `.${DATA_KEY$1}`;
7465
7465
  const DATA_API_KEY = '.data-api';
7466
- const SELECTOR_INPUT = '[data-bs-toggle="datepicker"]';
7467
- const EVENT_FOCUS_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY}`;
7466
+ const SELECTOR_INPUT$1 = '[data-bs-toggle="datepicker"]';
7467
+ const EVENT_FOCUS_DATA_API = `focus${EVENT_KEY$1}${DATA_API_KEY}`;
7468
7468
  class Datepicker extends BaseComponent {
7469
7469
  // Getters
7470
7470
  static get NAME() {
7471
- return NAME$2;
7471
+ return NAME$3;
7472
7472
  }
7473
7473
 
7474
7474
  // Static
@@ -7485,8 +7485,8 @@
7485
7485
  /**
7486
7486
  * Data API implementation
7487
7487
  */
7488
- EventHandler.on(document, EVENT_FOCUS_DATA_API, SELECTOR_INPUT, event => {
7489
- const input = event.target.closest(SELECTOR_INPUT);
7488
+ EventHandler.on(document, EVENT_FOCUS_DATA_API, SELECTOR_INPUT$1, event => {
7489
+ const input = event.target.closest(SELECTOR_INPUT$1);
7490
7490
  if (isTouchDevice()) {
7491
7491
  const datePicker = input.cloneNode(true);
7492
7492
  datePicker.type = 'date';
@@ -7676,7 +7676,7 @@
7676
7676
  }
7677
7677
  });
7678
7678
 
7679
- const NAME$1 = 'videoModal';
7679
+ const NAME$2 = 'videoModal';
7680
7680
  const EVENT_SHOW = 'show.bs.modal';
7681
7681
  const EVENT_HIDDEN = 'hidden.bs.modal';
7682
7682
  const SELECTOR_MODAL = '.modal';
@@ -7794,7 +7794,7 @@
7794
7794
  return match ? match[1] : '';
7795
7795
  }
7796
7796
  static get NAME() {
7797
- return NAME$1;
7797
+ return NAME$2;
7798
7798
  }
7799
7799
  static jQueryInterface(config) {
7800
7800
  return this.each(function () {
@@ -7812,7 +7812,7 @@
7812
7812
  });
7813
7813
  defineJQueryPlugin(VideoModal);
7814
7814
 
7815
- const NAME = 'accordionScroll';
7815
+ const NAME$1 = 'accordionScroll';
7816
7816
  const EVENT_SHOWN = 'shown.bs.collapse';
7817
7817
  const SELECTOR_ACCORDION = '.accordion';
7818
7818
  const SELECTOR_ITEM = '.accordion-item';
@@ -7832,7 +7832,7 @@
7832
7832
  }
7833
7833
  }
7834
7834
  static get NAME() {
7835
- return NAME;
7835
+ return NAME$1;
7836
7836
  }
7837
7837
  static jQueryInterface(config) {
7838
7838
  return this.each(function () {
@@ -7845,6 +7845,175 @@
7845
7845
  });
7846
7846
  defineJQueryPlugin(AccordionScroll);
7847
7847
 
7848
+ const NAME = 'otpInput';
7849
+ const DATA_KEY = 'bs.otpInput';
7850
+ const EVENT_KEY = `.${DATA_KEY}`;
7851
+ const EVENT_INPUT = `input${EVENT_KEY}`;
7852
+ const EVENT_COMPLETE = `complete${EVENT_KEY}`;
7853
+ const SELECTOR_OTP = '[data-bs-otp]';
7854
+ const SELECTOR_INPUT = '.otp-input';
7855
+ const CLASS_SLOTS = 'otp-slots';
7856
+ const CLASS_GROUP = 'otp-group';
7857
+ const CLASS_SLOT = 'otp-slot';
7858
+ const CLASS_CHAR = 'otp-char';
7859
+ const CLASS_CURSOR = 'otp-cursor';
7860
+ const CLASS_SEPARATOR = 'otp-separator';
7861
+ const CLASS_SLOT_ACTIVE = 'otp-slot-active';
7862
+ const CLASS_SLOT_FILLED = 'otp-slot-filled';
7863
+ const CLASS_DISABLED = 'disabled';
7864
+ const PATTERNS = {
7865
+ numeric: /\D/g,
7866
+ alpha: /[^a-zA-Z]/g,
7867
+ alphanumeric: /[^a-zA-Z0-9]/g
7868
+ };
7869
+ const INPUT_PATTERNS = {
7870
+ numeric: '[0-9]',
7871
+ alpha: '[a-zA-Z]',
7872
+ alphanumeric: '[a-zA-Z0-9]'
7873
+ };
7874
+ class OtpInput extends BaseComponent {
7875
+ constructor(element, config) {
7876
+ super(element, config);
7877
+ this._input = SelectorEngine.findOne(SELECTOR_INPUT, this._element);
7878
+ if (!this._input) return;
7879
+ this._length = this._input.maxLength > 0 ? this._input.maxLength : 6;
7880
+ this._type = this._element.dataset.bsType || 'numeric';
7881
+ const charPattern = INPUT_PATTERNS[this._type] || INPUT_PATTERNS.numeric;
7882
+ this._input.pattern = `${charPattern}{${this._length}}`;
7883
+ this._mask = this._element.dataset.bsMask === 'true';
7884
+ this._groups = this._element.dataset.bsGroups ? String(this._element.dataset.bsGroups).split(',').map(Number) : [this._length];
7885
+ this._slots = [];
7886
+ this._buildSlots();
7887
+ this._bindEvents();
7888
+ this._render();
7889
+ }
7890
+
7891
+ // Public API
7892
+
7893
+ getValue() {
7894
+ return this._input.value;
7895
+ }
7896
+ setValue(value) {
7897
+ const pattern = PATTERNS[this._type] || PATTERNS.numeric;
7898
+ this._input.value = String(value).replace(pattern, '').slice(0, this._length);
7899
+ this._render();
7900
+ }
7901
+ clear() {
7902
+ this._input.value = '';
7903
+ this._render();
7904
+ this._input.focus();
7905
+ }
7906
+
7907
+ // Private
7908
+
7909
+ _buildSlots() {
7910
+ // Hide real input visually but keep it accessible
7911
+ this._input.style.cssText = 'position:absolute;opacity:0;pointer-events:none;width:1px;height:1px;overflow:hidden;white-space:nowrap;';
7912
+ const slotsWrapper = document.createElement('div');
7913
+ slotsWrapper.classList.add(CLASS_SLOTS);
7914
+ slotsWrapper.setAttribute('aria-hidden', 'true');
7915
+ let slotIndex = 0;
7916
+ for (const [gi, groupLen] of this._groups.entries()) {
7917
+ const groupEl = document.createElement('div');
7918
+ groupEl.classList.add(CLASS_GROUP);
7919
+ for (let i = 0; i < groupLen; i++) {
7920
+ const slot = document.createElement('div');
7921
+ slot.classList.add(CLASS_SLOT);
7922
+ slot.dataset.index = slotIndex;
7923
+ const char = document.createElement('span');
7924
+ char.classList.add(CLASS_CHAR);
7925
+ const cursor = document.createElement('span');
7926
+ cursor.classList.add(CLASS_CURSOR);
7927
+ slot.append(char, cursor);
7928
+ groupEl.append(slot);
7929
+ this._slots.push({
7930
+ slot,
7931
+ char
7932
+ });
7933
+ slotIndex++;
7934
+ }
7935
+ slotsWrapper.append(groupEl);
7936
+ if (gi < this._groups.length - 1) {
7937
+ const sep = document.createElement('span');
7938
+ sep.classList.add(CLASS_SEPARATOR);
7939
+ sep.textContent = '–';
7940
+ slotsWrapper.append(sep);
7941
+ }
7942
+ }
7943
+ this._element.append(slotsWrapper);
7944
+ this._slotsWrapper = slotsWrapper;
7945
+ }
7946
+ _bindEvents() {
7947
+ EventHandler.on(this._slotsWrapper, 'click', () => {
7948
+ if (this._input.disabled) return;
7949
+ this._input.focus();
7950
+ const len = this._input.value.length;
7951
+ this._input.setSelectionRange(len, len);
7952
+ });
7953
+ EventHandler.on(this._input, 'focus', () => this._render());
7954
+ EventHandler.on(this._input, 'blur', () => this._render());
7955
+ EventHandler.on(this._input, 'input', () => {
7956
+ const pattern = PATTERNS[this._type] || PATTERNS.numeric;
7957
+ this._input.value = this._input.value.replace(pattern, '').slice(0, this._length);
7958
+ this._render();
7959
+ EventHandler.trigger(this._element, EVENT_INPUT, {
7960
+ value: this._input.value
7961
+ });
7962
+ if (this._input.value.length === this._length) {
7963
+ EventHandler.trigger(this._element, EVENT_COMPLETE, {
7964
+ value: this._input.value
7965
+ });
7966
+ }
7967
+ });
7968
+ EventHandler.on(this._input, 'keydown', e => {
7969
+ if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
7970
+ requestAnimationFrame(() => this._render());
7971
+ }
7972
+ });
7973
+ }
7974
+ _render() {
7975
+ const val = this._input.value;
7976
+ const focused = document.activeElement === this._input;
7977
+ const activeIdx = focused ? Math.min(val.length, this._length - 1) : -1;
7978
+ const isDisabled = this._input.disabled;
7979
+ this._slotsWrapper.classList.toggle(CLASS_DISABLED, isDisabled);
7980
+ for (const [i, {
7981
+ slot,
7982
+ char
7983
+ }] of this._slots.entries()) {
7984
+ const ch = val[i] || '';
7985
+ char.textContent = this._mask && ch ? '•' : ch;
7986
+ slot.classList.toggle(CLASS_SLOT_ACTIVE, i === activeIdx && !isDisabled);
7987
+ slot.classList.toggle(CLASS_SLOT_FILLED, Boolean(ch));
7988
+ }
7989
+ }
7990
+
7991
+ // Static
7992
+
7993
+ static get NAME() {
7994
+ return NAME;
7995
+ }
7996
+ static jQueryInterface(config, ...args) {
7997
+ return this.each(function () {
7998
+ const data = OtpInput.getOrCreateInstance(this);
7999
+ if (typeof config === 'string') {
8000
+ if (typeof data[config] === 'undefined') {
8001
+ throw new TypeError(`No method named "${config}"`);
8002
+ }
8003
+ data[config](...args);
8004
+ }
8005
+ });
8006
+ }
8007
+ }
8008
+
8009
+ // Auto-init on DOMContentLoaded
8010
+ EventHandler.on(globalThis, 'load', () => {
8011
+ for (const el of SelectorEngine.find(SELECTOR_OTP)) {
8012
+ OtpInput.getOrCreateInstance(el);
8013
+ }
8014
+ });
8015
+ defineJQueryPlugin(OtpInput);
8016
+
7848
8017
  exports.AccordionScroll = AccordionScroll;
7849
8018
  exports.Alert = alert;
7850
8019
  exports.Button = button;
@@ -7856,6 +8025,7 @@
7856
8025
  exports.Dropdown = dropdown;
7857
8026
  exports.Modal = modal;
7858
8027
  exports.Offcanvas = offcanvas;
8028
+ exports.OtpInput = OtpInput;
7859
8029
  exports.Popover = popover;
7860
8030
  exports.Scrollspy = scrollspy;
7861
8031
  exports.Tab = tab;