@stackoverflow/stacks 0.76.0 → 1.0.1

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.
Files changed (77) hide show
  1. package/LICENSE.MD +9 -9
  2. package/README.md +0 -0
  3. package/dist/controllers/index.d.ts +7 -7
  4. package/dist/controllers/s-expandable-control.d.ts +17 -17
  5. package/dist/controllers/s-modal.d.ts +97 -97
  6. package/dist/controllers/s-navigation-tablist.d.ts +36 -36
  7. package/dist/controllers/s-popover.d.ts +155 -155
  8. package/dist/controllers/s-table.d.ts +8 -8
  9. package/dist/controllers/s-tooltip.d.ts +82 -82
  10. package/dist/controllers/s-uploader.d.ts +48 -48
  11. package/dist/css/stacks.css +4354 -2560
  12. package/dist/css/stacks.min.css +1 -1
  13. package/dist/index.d.ts +3 -3
  14. package/dist/js/stacks.js +1978 -1978
  15. package/dist/js/stacks.min.js +1 -1
  16. package/dist/stacks.d.ts +21 -21
  17. package/lib/css/atomic/{_stacks-borders.less → borders.less} +30 -30
  18. package/lib/css/atomic/{_stacks-colors.less → colors.less} +0 -0
  19. package/lib/css/atomic/{_stacks-flex.less → flex.less} +14 -13
  20. package/lib/css/atomic/{_stacks-grid.less → grid.less} +11 -11
  21. package/lib/css/atomic/{_stacks-misc.less → misc.less} +22 -22
  22. package/lib/css/atomic/spacing.less +332 -0
  23. package/lib/css/atomic/{_stacks-typography.less → typography.less} +29 -29
  24. package/lib/css/atomic/width-height.less +194 -0
  25. package/lib/css/base/{_stacks-body.less → body.less} +2 -2
  26. package/lib/css/base/{_stacks-configuration-static.less → configuration-static.less} +3 -1
  27. package/lib/css/base/{_stacks-icons.less → icons.less} +0 -0
  28. package/lib/css/base/{_stacks-internals.less → internals.less} +0 -0
  29. package/lib/css/base/{_stacks-reset-meyer.less → reset-meyer.less} +0 -0
  30. package/lib/css/base/{_stacks-reset-normalize.less → reset-normalize.less} +0 -0
  31. package/lib/css/base/{_stacks-reset.less → reset.less} +2 -2
  32. package/lib/css/components/{_stacks-activity-indicator.less → activity-indicator.less} +9 -9
  33. package/lib/css/components/{_stacks-avatars.less → avatars.less} +40 -40
  34. package/lib/css/components/{_stacks-badges.less → badges.less} +11 -11
  35. package/lib/css/components/{_stacks-banners.less → banners.less} +5 -5
  36. package/lib/css/components/{_stacks-blank-states.less → blank-states.less} +2 -2
  37. package/lib/css/components/{_stacks-breadcrumbs.less → breadcrumbs.less} +7 -7
  38. package/lib/css/components/{_stacks-button-groups.less → button-groups.less} +2 -2
  39. package/lib/css/components/{_stacks-buttons.less → buttons.less} +46 -39
  40. package/lib/css/components/{_stacks-cards.less → cards.less} +2 -2
  41. package/lib/css/components/{_stacks-code-blocks.less → code-blocks.less} +8 -8
  42. package/lib/css/components/{_stacks-collapsible.less → collapsible.less} +0 -0
  43. package/lib/css/components/{_stacks-inputs.less → inputs.less} +41 -41
  44. package/lib/css/components/{_stacks-link-previews.less → link-previews.less} +17 -17
  45. package/lib/css/components/{_stacks-links.less → links.less} +4 -4
  46. package/lib/css/components/{_stacks-menu.less → menu.less} +5 -5
  47. package/lib/css/components/{_stacks-modals.less → modals.less} +20 -20
  48. package/lib/css/components/{_stacks-navigation.less → navigation.less} +12 -12
  49. package/lib/css/components/{_stacks-notices.less → notices.less} +12 -12
  50. package/lib/css/components/{_stacks-page-titles.less → page-titles.less} +9 -9
  51. package/lib/css/components/{_stacks-pagination.less → pagination.less} +8 -8
  52. package/lib/css/components/{_stacks-popovers.less → popovers.less} +17 -17
  53. package/lib/css/components/{_stacks-post-summary.less → post-summary.less} +35 -35
  54. package/lib/css/components/{_stacks-progress-bars.less → progress-bars.less} +29 -30
  55. package/lib/css/components/{_stacks-prose.less → prose.less} +31 -31
  56. package/lib/css/components/{_stacks-spinner.less → spinner.less} +14 -14
  57. package/lib/css/components/{_stacks-tables.less → tables.less} +10 -10
  58. package/lib/css/components/{_stacks-tags.less → tags.less} +24 -24
  59. package/lib/css/components/{_stacks-toggle-switches.less → toggle-switches.less} +5 -5
  60. package/lib/css/components/{_stacks-topbar.less → topbar.less} +22 -20
  61. package/lib/css/components/{_stacks-uploader.less → uploader.less} +18 -18
  62. package/lib/css/components/{_stacks-user-cards.less → user-cards.less} +14 -14
  63. package/lib/css/components/{_stacks-widget-dynamic.less → widget-dynamic.less} +1 -1
  64. package/lib/css/components/{_stacks-widget-static.less → widget-static.less} +39 -38
  65. package/lib/css/exports/{_stacks-constants-colors.less → constants-colors.less} +9 -29
  66. package/lib/css/exports/constants-helpers.less +108 -0
  67. package/lib/css/exports/constants-type.less +153 -0
  68. package/lib/css/exports/{_stacks-exports.less → exports.less} +4 -4
  69. package/lib/css/exports/{_stacks-mixins.less → mixins.less} +18 -1
  70. package/lib/css/stacks-dynamic.less +12 -12
  71. package/lib/css/stacks-static.less +38 -38
  72. package/lib/css/stacks.less +13 -13
  73. package/package.json +9 -9
  74. package/lib/css/atomic/_stacks-spacing.less +0 -168
  75. package/lib/css/atomic/_stacks-width-height.less +0 -195
  76. package/lib/css/exports/_stacks-constants-helpers.less +0 -139
  77. package/lib/css/exports/_stacks-constants-type.less +0 -152
package/dist/js/stacks.js CHANGED
@@ -7,7 +7,7 @@
7
7
  exports["Stacks"] = factory();
8
8
  else
9
9
  root["Stacks"] = factory();
10
- })(globalThis, function() {
10
+ })(globalThis, () => {
11
11
  return /******/ (() => { // webpackBootstrap
12
12
  /******/ "use strict";
13
13
  /******/ var __webpack_modules__ = ({
@@ -4405,33 +4405,33 @@ var Controller = /** @class */ (function () {
4405
4405
  /***/ 470:
4406
4406
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
4407
4407
 
4408
-
4409
- Object.defineProperty(exports, "__esModule", ({ value: true }));
4410
- exports.UploaderController = exports.TooltipController = exports.setTooltipText = exports.setTooltipHtml = exports.TableController = exports.showPopover = exports.PopoverController = exports.BasePopoverController = exports.hidePopover = exports.detachPopover = exports.attachPopover = exports.TabListController = exports.showModal = exports.ModalController = exports.hideModal = exports.ExpandableController = void 0;
4411
- // export all controllers *with helpers* so they can be bulk re-exported by the package entry point
4412
- var s_expandable_control_1 = __webpack_require__(601);
4413
- Object.defineProperty(exports, "ExpandableController", ({ enumerable: true, get: function () { return s_expandable_control_1.ExpandableController; } }));
4414
- var s_modal_1 = __webpack_require__(181);
4415
- Object.defineProperty(exports, "hideModal", ({ enumerable: true, get: function () { return s_modal_1.hideModal; } }));
4416
- Object.defineProperty(exports, "ModalController", ({ enumerable: true, get: function () { return s_modal_1.ModalController; } }));
4417
- Object.defineProperty(exports, "showModal", ({ enumerable: true, get: function () { return s_modal_1.showModal; } }));
4418
- var s_navigation_tablist_1 = __webpack_require__(642);
4419
- Object.defineProperty(exports, "TabListController", ({ enumerable: true, get: function () { return s_navigation_tablist_1.TabListController; } }));
4420
- var s_popover_1 = __webpack_require__(388);
4421
- Object.defineProperty(exports, "attachPopover", ({ enumerable: true, get: function () { return s_popover_1.attachPopover; } }));
4422
- Object.defineProperty(exports, "detachPopover", ({ enumerable: true, get: function () { return s_popover_1.detachPopover; } }));
4423
- Object.defineProperty(exports, "hidePopover", ({ enumerable: true, get: function () { return s_popover_1.hidePopover; } }));
4424
- Object.defineProperty(exports, "BasePopoverController", ({ enumerable: true, get: function () { return s_popover_1.BasePopoverController; } }));
4425
- Object.defineProperty(exports, "PopoverController", ({ enumerable: true, get: function () { return s_popover_1.PopoverController; } }));
4426
- Object.defineProperty(exports, "showPopover", ({ enumerable: true, get: function () { return s_popover_1.showPopover; } }));
4427
- var s_table_1 = __webpack_require__(753);
4428
- Object.defineProperty(exports, "TableController", ({ enumerable: true, get: function () { return s_table_1.TableController; } }));
4429
- var s_tooltip_1 = __webpack_require__(355);
4430
- Object.defineProperty(exports, "setTooltipHtml", ({ enumerable: true, get: function () { return s_tooltip_1.setTooltipHtml; } }));
4431
- Object.defineProperty(exports, "setTooltipText", ({ enumerable: true, get: function () { return s_tooltip_1.setTooltipText; } }));
4432
- Object.defineProperty(exports, "TooltipController", ({ enumerable: true, get: function () { return s_tooltip_1.TooltipController; } }));
4433
- var s_uploader_1 = __webpack_require__(637);
4434
- Object.defineProperty(exports, "UploaderController", ({ enumerable: true, get: function () { return s_uploader_1.UploaderController; } }));
4408
+
4409
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
4410
+ exports.UploaderController = exports.TooltipController = exports.setTooltipText = exports.setTooltipHtml = exports.TableController = exports.showPopover = exports.PopoverController = exports.BasePopoverController = exports.hidePopover = exports.detachPopover = exports.attachPopover = exports.TabListController = exports.showModal = exports.ModalController = exports.hideModal = exports.ExpandableController = void 0;
4411
+ // export all controllers *with helpers* so they can be bulk re-exported by the package entry point
4412
+ var s_expandable_control_1 = __webpack_require__(601);
4413
+ Object.defineProperty(exports, "ExpandableController", ({ enumerable: true, get: function () { return s_expandable_control_1.ExpandableController; } }));
4414
+ var s_modal_1 = __webpack_require__(181);
4415
+ Object.defineProperty(exports, "hideModal", ({ enumerable: true, get: function () { return s_modal_1.hideModal; } }));
4416
+ Object.defineProperty(exports, "ModalController", ({ enumerable: true, get: function () { return s_modal_1.ModalController; } }));
4417
+ Object.defineProperty(exports, "showModal", ({ enumerable: true, get: function () { return s_modal_1.showModal; } }));
4418
+ var s_navigation_tablist_1 = __webpack_require__(642);
4419
+ Object.defineProperty(exports, "TabListController", ({ enumerable: true, get: function () { return s_navigation_tablist_1.TabListController; } }));
4420
+ var s_popover_1 = __webpack_require__(388);
4421
+ Object.defineProperty(exports, "attachPopover", ({ enumerable: true, get: function () { return s_popover_1.attachPopover; } }));
4422
+ Object.defineProperty(exports, "detachPopover", ({ enumerable: true, get: function () { return s_popover_1.detachPopover; } }));
4423
+ Object.defineProperty(exports, "hidePopover", ({ enumerable: true, get: function () { return s_popover_1.hidePopover; } }));
4424
+ Object.defineProperty(exports, "BasePopoverController", ({ enumerable: true, get: function () { return s_popover_1.BasePopoverController; } }));
4425
+ Object.defineProperty(exports, "PopoverController", ({ enumerable: true, get: function () { return s_popover_1.PopoverController; } }));
4426
+ Object.defineProperty(exports, "showPopover", ({ enumerable: true, get: function () { return s_popover_1.showPopover; } }));
4427
+ var s_table_1 = __webpack_require__(753);
4428
+ Object.defineProperty(exports, "TableController", ({ enumerable: true, get: function () { return s_table_1.TableController; } }));
4429
+ var s_tooltip_1 = __webpack_require__(355);
4430
+ Object.defineProperty(exports, "setTooltipHtml", ({ enumerable: true, get: function () { return s_tooltip_1.setTooltipHtml; } }));
4431
+ Object.defineProperty(exports, "setTooltipText", ({ enumerable: true, get: function () { return s_tooltip_1.setTooltipText; } }));
4432
+ Object.defineProperty(exports, "TooltipController", ({ enumerable: true, get: function () { return s_tooltip_1.TooltipController; } }));
4433
+ var s_uploader_1 = __webpack_require__(637);
4434
+ Object.defineProperty(exports, "UploaderController", ({ enumerable: true, get: function () { return s_uploader_1.UploaderController; } }));
4435
4435
 
4436
4436
 
4437
4437
  /***/ }),
@@ -4439,218 +4439,218 @@ Object.defineProperty(exports, "UploaderController", ({ enumerable: true, get: f
4439
4439
  /***/ 601:
4440
4440
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
4441
4441
 
4442
-
4443
- var __extends = (this && this.__extends) || (function () {
4444
- var extendStatics = function (d, b) {
4445
- extendStatics = Object.setPrototypeOf ||
4446
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
4447
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
4448
- return extendStatics(d, b);
4449
- };
4450
- return function (d, b) {
4451
- if (typeof b !== "function" && b !== null)
4452
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
4453
- extendStatics(d, b);
4454
- function __() { this.constructor = d; }
4455
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
4456
- };
4457
- })();
4458
- Object.defineProperty(exports, "__esModule", ({ value: true }));
4459
- exports.ExpandableController = void 0;
4460
- var Stacks = __webpack_require__(36);
4461
- // Radio buttons only trigger a change event when they're *checked*, but not when
4462
- // they're *unchecked*. Therefore, if we have an active `s-collapsible-control` in
4463
- // the document, we listen for change events on *all* radio buttons and find any
4464
- // other radio buttons in the same `name` group, triggering a custom event on all
4465
- // of them so the controller can re-evaluate.
4466
- //
4467
- // We're keeping a count of how many of these controllers are connected to the DOM,
4468
- // so only have this global listener when we actually need it.
4469
- var RADIO_OFF_EVENT = "s-expandable-control:radio-off";
4470
- function globalChangeListener(e) {
4471
- var target = e.target;
4472
- if (!(target instanceof HTMLInputElement) || target.nodeName !== "INPUT" || target.type !== "radio") {
4473
- return;
4474
- }
4475
- document.querySelectorAll('input[type="radio"][name="' + target.name + '"]')
4476
- .forEach(function (other) {
4477
- if (other === e.target) {
4478
- return;
4479
- }
4480
- var customEvent;
4481
- try {
4482
- customEvent = new Event(RADIO_OFF_EVENT);
4483
- }
4484
- catch (ex) {
4485
- // Internet Explorer
4486
- customEvent = document.createEvent("Event");
4487
- customEvent.initEvent(RADIO_OFF_EVENT, true, true);
4488
- }
4489
- other.dispatchEvent(customEvent);
4490
- });
4491
- }
4492
- var refCount = 0;
4493
- function globalChangeListenerRequired(required) {
4494
- if (required) {
4495
- refCount++;
4496
- if (refCount === 1) {
4497
- document.body.addEventListener("change", globalChangeListener);
4498
- }
4499
- }
4500
- else {
4501
- refCount--;
4502
- if (refCount === 0) {
4503
- document.body.removeEventListener("change", globalChangeListener);
4504
- }
4505
- }
4506
- }
4507
- var ExpandableController = /** @class */ (function (_super) {
4508
- __extends(ExpandableController, _super);
4509
- function ExpandableController() {
4510
- var _this = _super !== null && _super.apply(this, arguments) || this;
4511
- _this.lastKeydownClickTimestamp = 0;
4512
- return _this;
4513
- }
4514
- ExpandableController.prototype.initialize = function () {
4515
- if (this.element.nodeName === "INPUT" && ["radio", "checkbox"].indexOf(this.element.type) >= 0) {
4516
- this.isCollapsed = this._isCollapsedForCheckable;
4517
- this.events = ["change", RADIO_OFF_EVENT];
4518
- this.isCheckable = true;
4519
- this.isRadio = this.element.type === "radio";
4520
- }
4521
- else {
4522
- this.isCollapsed = this._isCollapsedForClickable;
4523
- this.events = ["click", "keydown"];
4524
- }
4525
- this.listener = this.listener.bind(this);
4526
- };
4527
- ;
4528
- // for non-checkable elements, the initial source of truth is the collapsed/expanded
4529
- // state of the controlled element (unless the element doesn't exist)
4530
- ExpandableController.prototype._isCollapsedForClickable = function () {
4531
- var cc = this.controlledCollapsibles;
4532
- // the element is considered collapsed if *any* target element is collapsed
4533
- return cc.length > 0 ? !cc.every(function (element) { return element.classList.contains("is-expanded"); }) : this.element.getAttribute("aria-expanded") === "false";
4534
- };
4535
- ;
4536
- // for checkable elements, the initial source of truth is the checked state
4537
- ExpandableController.prototype._isCollapsedForCheckable = function () {
4538
- return !this.element.checked;
4539
- };
4540
- ;
4541
- Object.defineProperty(ExpandableController.prototype, "controlledCollapsibles", {
4542
- get: function () {
4543
- var attr = this.element.getAttribute("aria-controls");
4544
- if (!attr) {
4545
- throw "[aria-controls=\"targetId1 ... targetIdN\"] attribute required";
4546
- }
4547
- var result = attr.split(/\s+/g)
4548
- .map(function (s) { return document.getElementById(s); })
4549
- .filter(function (e) { return !!e; });
4550
- if (!result.length) {
4551
- throw "couldn't find controls";
4552
- }
4553
- return result;
4554
- },
4555
- enumerable: false,
4556
- configurable: true
4557
- });
4558
- ;
4559
- ExpandableController.prototype._dispatchShowHideEvent = function (isShow) {
4560
- this.triggerEvent(isShow ? "show" : "hide");
4561
- };
4562
- ;
4563
- ExpandableController.prototype._toggleClass = function (doAdd) {
4564
- if (!this.data.has("toggle-class")) {
4565
- return;
4566
- }
4567
- var cl = this.element.classList;
4568
- var toggleClass = this.data.get("toggle-class");
4569
- if (!toggleClass) {
4570
- throw "couldn't find toggle class";
4571
- }
4572
- toggleClass.split(/\s+/).forEach(function (cls) {
4573
- cl.toggle(cls, !!doAdd);
4574
- });
4575
- };
4576
- ;
4577
- ExpandableController.prototype.listener = function (e) {
4578
- var newCollapsed;
4579
- if (this.isCheckable) {
4580
- newCollapsed = !this.element.checked;
4581
- }
4582
- else {
4583
- if (e.type == "keydown" && (e instanceof KeyboardEvent && e.keyCode != 13 && e.keyCode != 32)) {
4584
- return;
4585
- }
4586
- if (e.target !== e.currentTarget && ["A", "BUTTON"].indexOf(e.target.nodeName) >= 0) {
4587
- return;
4588
- }
4589
- e.preventDefault();
4590
- // Prevent "click" events from toggling the expandable within 300ms of "keydown".
4591
- // e.preventDefault() should have done the same, but https://bugzilla.mozilla.org/show_bug.cgi?id=1487102
4592
- // doesn't guarantee it.
4593
- if (e.type == "keydown") {
4594
- this.lastKeydownClickTimestamp = Date.now();
4595
- }
4596
- else if (e.type == "click" && Date.now() - this.lastKeydownClickTimestamp < 300) {
4597
- return;
4598
- }
4599
- newCollapsed = this.element.getAttribute("aria-expanded") === "true";
4600
- if (e.type === "click") {
4601
- this.element.blur();
4602
- }
4603
- }
4604
- this.element.setAttribute("aria-expanded", newCollapsed ? "false" : "true");
4605
- for (var _i = 0, _a = this.controlledCollapsibles; _i < _a.length; _i++) {
4606
- var controlledElement = _a[_i];
4607
- controlledElement.classList.toggle("is-expanded", !newCollapsed);
4608
- }
4609
- this._dispatchShowHideEvent(!newCollapsed);
4610
- this._toggleClass(!newCollapsed);
4611
- };
4612
- ;
4613
- ExpandableController.prototype.connect = function () {
4614
- var _this = this;
4615
- this.events.forEach(function (e) {
4616
- _this.element.addEventListener(e, _this.listener);
4617
- }, this);
4618
- if (this.isRadio) {
4619
- globalChangeListenerRequired(true);
4620
- }
4621
- // synchronize state -- in all cases, this means setting the correct `aria-expanded`
4622
- // attribute; for checkable controls this also means setting the `is-collapsed` class
4623
- this.element.setAttribute("aria-expanded", this.isCollapsed() ? "false" : "true");
4624
- if (this.isCheckable) {
4625
- var cc = this.controlledCollapsibles;
4626
- if (cc.length) {
4627
- var expected = !this.isCollapsed();
4628
- // if any element does not match the expected state, set them all to the expected state
4629
- if (cc.some(function (element) { return element.classList.contains("is-expanded") !== expected; })) {
4630
- for (var _i = 0, _a = this.controlledCollapsibles; _i < _a.length; _i++) {
4631
- var controlledElement = _a[_i];
4632
- controlledElement.classList.toggle("is-expanded", expected);
4633
- }
4634
- this._dispatchShowHideEvent(expected);
4635
- this._toggleClass(expected);
4636
- }
4637
- }
4638
- }
4639
- };
4640
- ;
4641
- ExpandableController.prototype.disconnect = function () {
4642
- var _this = this;
4643
- this.events.forEach(function (e) {
4644
- _this.element.removeEventListener(e, _this.listener);
4645
- }, this);
4646
- if (this.isRadio) {
4647
- globalChangeListenerRequired(false);
4648
- }
4649
- };
4650
- ;
4651
- return ExpandableController;
4652
- }(Stacks.StacksController));
4653
- exports.ExpandableController = ExpandableController;
4442
+
4443
+ var __extends = (this && this.__extends) || (function () {
4444
+ var extendStatics = function (d, b) {
4445
+ extendStatics = Object.setPrototypeOf ||
4446
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
4447
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
4448
+ return extendStatics(d, b);
4449
+ };
4450
+ return function (d, b) {
4451
+ if (typeof b !== "function" && b !== null)
4452
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
4453
+ extendStatics(d, b);
4454
+ function __() { this.constructor = d; }
4455
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
4456
+ };
4457
+ })();
4458
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
4459
+ exports.ExpandableController = void 0;
4460
+ var Stacks = __webpack_require__(36);
4461
+ // Radio buttons only trigger a change event when they're *checked*, but not when
4462
+ // they're *unchecked*. Therefore, if we have an active `s-collapsible-control` in
4463
+ // the document, we listen for change events on *all* radio buttons and find any
4464
+ // other radio buttons in the same `name` group, triggering a custom event on all
4465
+ // of them so the controller can re-evaluate.
4466
+ //
4467
+ // We're keeping a count of how many of these controllers are connected to the DOM,
4468
+ // so only have this global listener when we actually need it.
4469
+ var RADIO_OFF_EVENT = "s-expandable-control:radio-off";
4470
+ function globalChangeListener(e) {
4471
+ var target = e.target;
4472
+ if (!(target instanceof HTMLInputElement) || target.nodeName !== "INPUT" || target.type !== "radio") {
4473
+ return;
4474
+ }
4475
+ document.querySelectorAll('input[type="radio"][name="' + target.name + '"]')
4476
+ .forEach(function (other) {
4477
+ if (other === e.target) {
4478
+ return;
4479
+ }
4480
+ var customEvent;
4481
+ try {
4482
+ customEvent = new Event(RADIO_OFF_EVENT);
4483
+ }
4484
+ catch (ex) {
4485
+ // Internet Explorer
4486
+ customEvent = document.createEvent("Event");
4487
+ customEvent.initEvent(RADIO_OFF_EVENT, true, true);
4488
+ }
4489
+ other.dispatchEvent(customEvent);
4490
+ });
4491
+ }
4492
+ var refCount = 0;
4493
+ function globalChangeListenerRequired(required) {
4494
+ if (required) {
4495
+ refCount++;
4496
+ if (refCount === 1) {
4497
+ document.body.addEventListener("change", globalChangeListener);
4498
+ }
4499
+ }
4500
+ else {
4501
+ refCount--;
4502
+ if (refCount === 0) {
4503
+ document.body.removeEventListener("change", globalChangeListener);
4504
+ }
4505
+ }
4506
+ }
4507
+ var ExpandableController = /** @class */ (function (_super) {
4508
+ __extends(ExpandableController, _super);
4509
+ function ExpandableController() {
4510
+ var _this = _super !== null && _super.apply(this, arguments) || this;
4511
+ _this.lastKeydownClickTimestamp = 0;
4512
+ return _this;
4513
+ }
4514
+ ExpandableController.prototype.initialize = function () {
4515
+ if (this.element.nodeName === "INPUT" && ["radio", "checkbox"].indexOf(this.element.type) >= 0) {
4516
+ this.isCollapsed = this._isCollapsedForCheckable;
4517
+ this.events = ["change", RADIO_OFF_EVENT];
4518
+ this.isCheckable = true;
4519
+ this.isRadio = this.element.type === "radio";
4520
+ }
4521
+ else {
4522
+ this.isCollapsed = this._isCollapsedForClickable;
4523
+ this.events = ["click", "keydown"];
4524
+ }
4525
+ this.listener = this.listener.bind(this);
4526
+ };
4527
+ ;
4528
+ // for non-checkable elements, the initial source of truth is the collapsed/expanded
4529
+ // state of the controlled element (unless the element doesn't exist)
4530
+ ExpandableController.prototype._isCollapsedForClickable = function () {
4531
+ var cc = this.controlledCollapsibles;
4532
+ // the element is considered collapsed if *any* target element is collapsed
4533
+ return cc.length > 0 ? !cc.every(function (element) { return element.classList.contains("is-expanded"); }) : this.element.getAttribute("aria-expanded") === "false";
4534
+ };
4535
+ ;
4536
+ // for checkable elements, the initial source of truth is the checked state
4537
+ ExpandableController.prototype._isCollapsedForCheckable = function () {
4538
+ return !this.element.checked;
4539
+ };
4540
+ ;
4541
+ Object.defineProperty(ExpandableController.prototype, "controlledCollapsibles", {
4542
+ get: function () {
4543
+ var attr = this.element.getAttribute("aria-controls");
4544
+ if (!attr) {
4545
+ throw "[aria-controls=\"targetId1 ... targetIdN\"] attribute required";
4546
+ }
4547
+ var result = attr.split(/\s+/g)
4548
+ .map(function (s) { return document.getElementById(s); })
4549
+ .filter(function (e) { return !!e; });
4550
+ if (!result.length) {
4551
+ throw "couldn't find controls";
4552
+ }
4553
+ return result;
4554
+ },
4555
+ enumerable: false,
4556
+ configurable: true
4557
+ });
4558
+ ;
4559
+ ExpandableController.prototype._dispatchShowHideEvent = function (isShow) {
4560
+ this.triggerEvent(isShow ? "show" : "hide");
4561
+ };
4562
+ ;
4563
+ ExpandableController.prototype._toggleClass = function (doAdd) {
4564
+ if (!this.data.has("toggle-class")) {
4565
+ return;
4566
+ }
4567
+ var cl = this.element.classList;
4568
+ var toggleClass = this.data.get("toggle-class");
4569
+ if (!toggleClass) {
4570
+ throw "couldn't find toggle class";
4571
+ }
4572
+ toggleClass.split(/\s+/).forEach(function (cls) {
4573
+ cl.toggle(cls, !!doAdd);
4574
+ });
4575
+ };
4576
+ ;
4577
+ ExpandableController.prototype.listener = function (e) {
4578
+ var newCollapsed;
4579
+ if (this.isCheckable) {
4580
+ newCollapsed = !this.element.checked;
4581
+ }
4582
+ else {
4583
+ if (e.type == "keydown" && (e instanceof KeyboardEvent && e.keyCode != 13 && e.keyCode != 32)) {
4584
+ return;
4585
+ }
4586
+ if (e.target !== e.currentTarget && ["A", "BUTTON"].indexOf(e.target.nodeName) >= 0) {
4587
+ return;
4588
+ }
4589
+ e.preventDefault();
4590
+ // Prevent "click" events from toggling the expandable within 300ms of "keydown".
4591
+ // e.preventDefault() should have done the same, but https://bugzilla.mozilla.org/show_bug.cgi?id=1487102
4592
+ // doesn't guarantee it.
4593
+ if (e.type == "keydown") {
4594
+ this.lastKeydownClickTimestamp = Date.now();
4595
+ }
4596
+ else if (e.type == "click" && Date.now() - this.lastKeydownClickTimestamp < 300) {
4597
+ return;
4598
+ }
4599
+ newCollapsed = this.element.getAttribute("aria-expanded") === "true";
4600
+ if (e.type === "click") {
4601
+ this.element.blur();
4602
+ }
4603
+ }
4604
+ this.element.setAttribute("aria-expanded", newCollapsed ? "false" : "true");
4605
+ for (var _i = 0, _a = this.controlledCollapsibles; _i < _a.length; _i++) {
4606
+ var controlledElement = _a[_i];
4607
+ controlledElement.classList.toggle("is-expanded", !newCollapsed);
4608
+ }
4609
+ this._dispatchShowHideEvent(!newCollapsed);
4610
+ this._toggleClass(!newCollapsed);
4611
+ };
4612
+ ;
4613
+ ExpandableController.prototype.connect = function () {
4614
+ var _this = this;
4615
+ this.events.forEach(function (e) {
4616
+ _this.element.addEventListener(e, _this.listener);
4617
+ }, this);
4618
+ if (this.isRadio) {
4619
+ globalChangeListenerRequired(true);
4620
+ }
4621
+ // synchronize state -- in all cases, this means setting the correct `aria-expanded`
4622
+ // attribute; for checkable controls this also means setting the `is-collapsed` class
4623
+ this.element.setAttribute("aria-expanded", this.isCollapsed() ? "false" : "true");
4624
+ if (this.isCheckable) {
4625
+ var cc = this.controlledCollapsibles;
4626
+ if (cc.length) {
4627
+ var expected = !this.isCollapsed();
4628
+ // if any element does not match the expected state, set them all to the expected state
4629
+ if (cc.some(function (element) { return element.classList.contains("is-expanded") !== expected; })) {
4630
+ for (var _i = 0, _a = this.controlledCollapsibles; _i < _a.length; _i++) {
4631
+ var controlledElement = _a[_i];
4632
+ controlledElement.classList.toggle("is-expanded", expected);
4633
+ }
4634
+ this._dispatchShowHideEvent(expected);
4635
+ this._toggleClass(expected);
4636
+ }
4637
+ }
4638
+ }
4639
+ };
4640
+ ;
4641
+ ExpandableController.prototype.disconnect = function () {
4642
+ var _this = this;
4643
+ this.events.forEach(function (e) {
4644
+ _this.element.removeEventListener(e, _this.listener);
4645
+ }, this);
4646
+ if (this.isRadio) {
4647
+ globalChangeListenerRequired(false);
4648
+ }
4649
+ };
4650
+ ;
4651
+ return ExpandableController;
4652
+ }(Stacks.StacksController));
4653
+ exports.ExpandableController = ExpandableController;
4654
4654
 
4655
4655
 
4656
4656
  /***/ }),
@@ -4658,322 +4658,322 @@ exports.ExpandableController = ExpandableController;
4658
4658
  /***/ 181:
4659
4659
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
4660
4660
 
4661
-
4662
- var __extends = (this && this.__extends) || (function () {
4663
- var extendStatics = function (d, b) {
4664
- extendStatics = Object.setPrototypeOf ||
4665
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
4666
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
4667
- return extendStatics(d, b);
4668
- };
4669
- return function (d, b) {
4670
- if (typeof b !== "function" && b !== null)
4671
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
4672
- extendStatics(d, b);
4673
- function __() { this.constructor = d; }
4674
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
4675
- };
4676
- })();
4677
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
4678
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
4679
- if (ar || !(i in from)) {
4680
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
4681
- ar[i] = from[i];
4682
- }
4683
- }
4684
- return to.concat(ar || Array.prototype.slice.call(from));
4685
- };
4686
- Object.defineProperty(exports, "__esModule", ({ value: true }));
4687
- exports.hideModal = exports.showModal = exports.ModalController = void 0;
4688
- var Stacks = __webpack_require__(36);
4689
- var ModalController = /** @class */ (function (_super) {
4690
- __extends(ModalController, _super);
4691
- function ModalController() {
4692
- return _super !== null && _super.apply(this, arguments) || this;
4693
- }
4694
- ModalController.prototype.connect = function () {
4695
- this.validate();
4696
- };
4697
- /**
4698
- * Disconnects all added event listeners on controller disconnect
4699
- */
4700
- ModalController.prototype.disconnect = function () {
4701
- this.unbindDocumentEvents();
4702
- };
4703
- ;
4704
- /**
4705
- * Toggles the visibility of the modal
4706
- */
4707
- ModalController.prototype.toggle = function (dispatcher) {
4708
- if (dispatcher === void 0) { dispatcher = null; }
4709
- this._toggle(undefined, dispatcher);
4710
- };
4711
- /**
4712
- * Shows the modal
4713
- */
4714
- ModalController.prototype.show = function (dispatcher) {
4715
- if (dispatcher === void 0) { dispatcher = null; }
4716
- this._toggle(true, dispatcher);
4717
- };
4718
- /**
4719
- * Hides the modal
4720
- */
4721
- ModalController.prototype.hide = function (dispatcher) {
4722
- if (dispatcher === void 0) { dispatcher = null; }
4723
- this._toggle(false, dispatcher);
4724
- };
4725
- /**
4726
- * Validates the modal settings and attempts to set necessary internal variables
4727
- */
4728
- ModalController.prototype.validate = function () {
4729
- // check for returnElement support
4730
- var returnElementSelector = this.data.get("return-element");
4731
- if (returnElementSelector) {
4732
- this.returnElement = document.querySelector(returnElementSelector);
4733
- if (!this.returnElement) {
4734
- throw "Unable to find element by return-element selector: " + returnElementSelector;
4735
- }
4736
- }
4737
- };
4738
- /**
4739
- * Toggles the visibility of the modal element
4740
- * @param show Optional parameter that force shows/hides the element or toggles it if left undefined
4741
- */
4742
- ModalController.prototype._toggle = function (show, dispatcher) {
4743
- var _this = this;
4744
- if (dispatcher === void 0) { dispatcher = null; }
4745
- var toShow = show;
4746
- var isVisible = this.modalTarget.getAttribute("aria-hidden") === "false";
4747
- // if we're letting the class toggle, we need to figure out if the popover is visible manually
4748
- if (typeof toShow === "undefined") {
4749
- toShow = !isVisible;
4750
- }
4751
- // if the state matches the disired state, return without changing anything
4752
- if ((toShow && isVisible) || (!toShow && !isVisible)) {
4753
- return;
4754
- }
4755
- var dispatchingElement = this.getDispatcher(dispatcher);
4756
- // show/hide events trigger before toggling the class
4757
- var triggeredEvent = this.triggerEvent(toShow ? "show" : "hide", {
4758
- returnElement: this.returnElement,
4759
- dispatcher: this.getDispatcher(dispatchingElement)
4760
- }, this.modalTarget);
4761
- // if this pre-show/hide event was prevented, don't attempt to continue changing the modal state
4762
- if (triggeredEvent.defaultPrevented) {
4763
- return;
4764
- }
4765
- this.returnElement = triggeredEvent.detail.returnElement;
4766
- this.modalTarget.setAttribute("aria-hidden", toShow ? "false" : "true");
4767
- if (toShow) {
4768
- this.bindDocumentEvents();
4769
- this.focusInsideModal();
4770
- }
4771
- else {
4772
- this.unbindDocumentEvents();
4773
- this.focusReturnElement();
4774
- this.removeModalOnHide();
4775
- }
4776
- // check for transitionend support
4777
- var supportsTransitionEnd = this.modalTarget.ontransitionend !== undefined;
4778
- // shown/hidden events trigger after toggling the class
4779
- if (supportsTransitionEnd) {
4780
- // wait until after the modal finishes transitioning to fire the event
4781
- this.modalTarget.addEventListener("transitionend", function () {
4782
- //TODO this is firing waaay to soon?
4783
- _this.triggerEvent(toShow ? "shown" : "hidden", {
4784
- dispatcher: dispatchingElement
4785
- }, _this.modalTarget);
4786
- }, { once: true });
4787
- }
4788
- else {
4789
- this.triggerEvent(toShow ? "shown" : "hidden", {
4790
- dispatcher: dispatchingElement
4791
- }, this.modalTarget);
4792
- }
4793
- };
4794
- /**
4795
- * Listens for the s-modal:hidden event and focuses the returnElement when it is fired
4796
- */
4797
- ModalController.prototype.focusReturnElement = function () {
4798
- var _this = this;
4799
- if (!this.returnElement) {
4800
- return;
4801
- }
4802
- this.modalTarget.addEventListener("s-modal:hidden", function () {
4803
- // double check the element still exists when the event is called
4804
- if (_this.returnElement && document.body.contains(_this.returnElement)) {
4805
- _this.returnElement.focus();
4806
- }
4807
- }, { once: true });
4808
- };
4809
- /**
4810
- * Remove the element on hide if the `remove-when-hidden` flag is set
4811
- */
4812
- ModalController.prototype.removeModalOnHide = function () {
4813
- var _this = this;
4814
- if (this.data.get("remove-when-hidden") !== "true") {
4815
- return;
4816
- }
4817
- this.modalTarget.addEventListener("s-modal:hidden", function () {
4818
- _this.element.remove();
4819
- }, { once: true });
4820
- };
4821
- /**
4822
- * Gets all elements within the modal that could receive keyboard focus.
4823
- */
4824
- ModalController.prototype.getAllTabbables = function () {
4825
- return Array.from(this.modalTarget.querySelectorAll("[href], input, select, textarea, button, [tabindex]"))
4826
- .filter(function (el) { return el.matches(":not([disabled]):not([tabindex='-1'])"); });
4827
- };
4828
- /**
4829
- * Returns the first visible element in an array or `undefined` if no elements are visible.
4830
- */
4831
- ModalController.prototype.firstVisible = function (elements) {
4832
- // https://stackoverflow.com/a/21696585
4833
- return elements.find(function (el) { return el.offsetParent !== null; });
4834
- };
4835
- /**
4836
- * Returns the last visible element in an array or `undefined` if no elements are visible.
4837
- */
4838
- ModalController.prototype.lastVisible = function (elements) {
4839
- return this.firstVisible(__spreadArray([], elements, true).reverse());
4840
- };
4841
- /**
4842
- * Attempts to shift keyboard focus into the modal.
4843
- * If elements with `data-s-modal-target="initialFocus"` are present and visible, one of those will be selected.
4844
- * Otherwise, the first visible focusable element will receive focus.
4845
- */
4846
- ModalController.prototype.focusInsideModal = function () {
4847
- var _this = this;
4848
- this.modalTarget.addEventListener("s-modal:shown", function () {
4849
- var _a;
4850
- var initialFocus = (_a = _this.firstVisible(_this.initialFocusTargets)) !== null && _a !== void 0 ? _a : _this.firstVisible(_this.getAllTabbables());
4851
- initialFocus === null || initialFocus === void 0 ? void 0 : initialFocus.focus();
4852
- }, { once: true });
4853
- };
4854
- /**
4855
- * Returns keyboard focus to the modal if it has left or is about to leave.
4856
- */
4857
- ModalController.prototype.keepFocusWithinModal = function (e) {
4858
- // If somehow the user has tabbed out of the modal or if focus started outside the modal, push them to the first item.
4859
- if (!this.modalTarget.contains(e.target)) {
4860
- var focusTarget = this.firstVisible(this.getAllTabbables());
4861
- if (focusTarget) {
4862
- e.preventDefault();
4863
- focusTarget.focus();
4864
- }
4865
- return;
4866
- }
4867
- // If we observe a tab keydown and we're on an edge, cycle the focus to the other side.
4868
- if (e.key === "Tab") {
4869
- var tabbables = this.getAllTabbables();
4870
- var firstTabbable = this.firstVisible(tabbables);
4871
- var lastTabbable = this.lastVisible(tabbables);
4872
- if (firstTabbable && lastTabbable) {
4873
- if (firstTabbable === lastTabbable) {
4874
- e.preventDefault();
4875
- firstTabbable.focus();
4876
- }
4877
- else if (e.shiftKey && e.target === firstTabbable) {
4878
- e.preventDefault();
4879
- lastTabbable.focus();
4880
- }
4881
- else if (!e.shiftKey && e.target === lastTabbable) {
4882
- e.preventDefault();
4883
- firstTabbable.focus();
4884
- }
4885
- }
4886
- }
4887
- };
4888
- /**
4889
- * Binds global events to the document for hiding popovers on user interaction
4890
- */
4891
- ModalController.prototype.bindDocumentEvents = function () {
4892
- // in order for removeEventListener to remove the right event, this bound function needs a constant reference
4893
- this._boundClickFn = this._boundClickFn || this.hideOnOutsideClick.bind(this);
4894
- this._boundKeypressFn = this._boundKeypressFn || this.hideOnEscapePress.bind(this);
4895
- this._boundTabTrap = this._boundTabTrap || this.keepFocusWithinModal.bind(this);
4896
- document.addEventListener("mousedown", this._boundClickFn);
4897
- document.addEventListener("keyup", this._boundKeypressFn);
4898
- document.addEventListener("keydown", this._boundTabTrap);
4899
- };
4900
- /**
4901
- * Unbinds global events to the document for hiding popovers on user interaction
4902
- */
4903
- ModalController.prototype.unbindDocumentEvents = function () {
4904
- document.removeEventListener("mousedown", this._boundClickFn);
4905
- document.removeEventListener("keyup", this._boundKeypressFn);
4906
- document.removeEventListener("keydown", this._boundTabTrap);
4907
- };
4908
- /**
4909
- * Forces the popover to hide if a user clicks outside of it or its reference element
4910
- */
4911
- ModalController.prototype.hideOnOutsideClick = function (e) {
4912
- var target = e.target;
4913
- // check if the document was clicked inside either the toggle element or the modal itself
4914
- // note: .contains also returns true if the node itself matches the target element
4915
- if (!this.modalTarget.querySelector(".s-modal--dialog").contains(target) && document.body.contains(target)) {
4916
- this._toggle(false, e);
4917
- }
4918
- };
4919
- /**
4920
- * Forces the popover to hide if the user presses escape while it, one of its childen, or the reference element are focused
4921
- */
4922
- ModalController.prototype.hideOnEscapePress = function (e) {
4923
- // if the ESC key (27) wasn't pressed or if no popovers are showing, return
4924
- if (e.which !== 27 || this.modalTarget.getAttribute("aria-hidden") === "true") {
4925
- return;
4926
- }
4927
- this._toggle(false, e);
4928
- };
4929
- /**
4930
- * Determines the correct dispatching element from a potential input
4931
- * @param dispatcher The event or element to get the dispatcher from
4932
- */
4933
- ModalController.prototype.getDispatcher = function (dispatcher) {
4934
- if (dispatcher === void 0) { dispatcher = null; }
4935
- if (dispatcher instanceof Event) {
4936
- return dispatcher.target;
4937
- }
4938
- else if (dispatcher instanceof Element) {
4939
- return dispatcher;
4940
- }
4941
- else {
4942
- return this.element;
4943
- }
4944
- };
4945
- ModalController.targets = ["modal", "initialFocus"];
4946
- return ModalController;
4947
- }(Stacks.StacksController));
4948
- exports.ModalController = ModalController;
4949
- /**
4950
- * Helper to manually show an s-modal element via external JS
4951
- * @param element the element the `data-controller="s-modal"` attribute is on
4952
- */
4953
- function showModal(element) {
4954
- toggleModal(element, true);
4955
- }
4956
- exports.showModal = showModal;
4957
- /**
4958
- * Helper to manually hide an s-modal element via external JS
4959
- * @param element the element the `data-controller="s-modal"` attribute is on
4960
- */
4961
- function hideModal(element) {
4962
- toggleModal(element, false);
4963
- }
4964
- exports.hideModal = hideModal;
4965
- /**
4966
- * Helper to manually show an s-modal element via external JS
4967
- * @param element the element the `data-controller="s-modal"` attribute is on
4968
- * @param show whether to force show/hide the modal; toggles the modal if left undefined
4969
- */
4970
- function toggleModal(element, show) {
4971
- var controller = Stacks.application.getControllerForElementAndIdentifier(element, "s-modal");
4972
- if (!controller) {
4973
- throw "Unable to get s-modal controller from element";
4974
- }
4975
- show ? controller.show() : controller.hide();
4976
- }
4661
+
4662
+ var __extends = (this && this.__extends) || (function () {
4663
+ var extendStatics = function (d, b) {
4664
+ extendStatics = Object.setPrototypeOf ||
4665
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
4666
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
4667
+ return extendStatics(d, b);
4668
+ };
4669
+ return function (d, b) {
4670
+ if (typeof b !== "function" && b !== null)
4671
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
4672
+ extendStatics(d, b);
4673
+ function __() { this.constructor = d; }
4674
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
4675
+ };
4676
+ })();
4677
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
4678
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
4679
+ if (ar || !(i in from)) {
4680
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
4681
+ ar[i] = from[i];
4682
+ }
4683
+ }
4684
+ return to.concat(ar || Array.prototype.slice.call(from));
4685
+ };
4686
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
4687
+ exports.hideModal = exports.showModal = exports.ModalController = void 0;
4688
+ var Stacks = __webpack_require__(36);
4689
+ var ModalController = /** @class */ (function (_super) {
4690
+ __extends(ModalController, _super);
4691
+ function ModalController() {
4692
+ return _super !== null && _super.apply(this, arguments) || this;
4693
+ }
4694
+ ModalController.prototype.connect = function () {
4695
+ this.validate();
4696
+ };
4697
+ /**
4698
+ * Disconnects all added event listeners on controller disconnect
4699
+ */
4700
+ ModalController.prototype.disconnect = function () {
4701
+ this.unbindDocumentEvents();
4702
+ };
4703
+ ;
4704
+ /**
4705
+ * Toggles the visibility of the modal
4706
+ */
4707
+ ModalController.prototype.toggle = function (dispatcher) {
4708
+ if (dispatcher === void 0) { dispatcher = null; }
4709
+ this._toggle(undefined, dispatcher);
4710
+ };
4711
+ /**
4712
+ * Shows the modal
4713
+ */
4714
+ ModalController.prototype.show = function (dispatcher) {
4715
+ if (dispatcher === void 0) { dispatcher = null; }
4716
+ this._toggle(true, dispatcher);
4717
+ };
4718
+ /**
4719
+ * Hides the modal
4720
+ */
4721
+ ModalController.prototype.hide = function (dispatcher) {
4722
+ if (dispatcher === void 0) { dispatcher = null; }
4723
+ this._toggle(false, dispatcher);
4724
+ };
4725
+ /**
4726
+ * Validates the modal settings and attempts to set necessary internal variables
4727
+ */
4728
+ ModalController.prototype.validate = function () {
4729
+ // check for returnElement support
4730
+ var returnElementSelector = this.data.get("return-element");
4731
+ if (returnElementSelector) {
4732
+ this.returnElement = document.querySelector(returnElementSelector);
4733
+ if (!this.returnElement) {
4734
+ throw "Unable to find element by return-element selector: " + returnElementSelector;
4735
+ }
4736
+ }
4737
+ };
4738
+ /**
4739
+ * Toggles the visibility of the modal element
4740
+ * @param show Optional parameter that force shows/hides the element or toggles it if left undefined
4741
+ */
4742
+ ModalController.prototype._toggle = function (show, dispatcher) {
4743
+ var _this = this;
4744
+ if (dispatcher === void 0) { dispatcher = null; }
4745
+ var toShow = show;
4746
+ var isVisible = this.modalTarget.getAttribute("aria-hidden") === "false";
4747
+ // if we're letting the class toggle, we need to figure out if the popover is visible manually
4748
+ if (typeof toShow === "undefined") {
4749
+ toShow = !isVisible;
4750
+ }
4751
+ // if the state matches the disired state, return without changing anything
4752
+ if ((toShow && isVisible) || (!toShow && !isVisible)) {
4753
+ return;
4754
+ }
4755
+ var dispatchingElement = this.getDispatcher(dispatcher);
4756
+ // show/hide events trigger before toggling the class
4757
+ var triggeredEvent = this.triggerEvent(toShow ? "show" : "hide", {
4758
+ returnElement: this.returnElement,
4759
+ dispatcher: this.getDispatcher(dispatchingElement)
4760
+ }, this.modalTarget);
4761
+ // if this pre-show/hide event was prevented, don't attempt to continue changing the modal state
4762
+ if (triggeredEvent.defaultPrevented) {
4763
+ return;
4764
+ }
4765
+ this.returnElement = triggeredEvent.detail.returnElement;
4766
+ this.modalTarget.setAttribute("aria-hidden", toShow ? "false" : "true");
4767
+ if (toShow) {
4768
+ this.bindDocumentEvents();
4769
+ this.focusInsideModal();
4770
+ }
4771
+ else {
4772
+ this.unbindDocumentEvents();
4773
+ this.focusReturnElement();
4774
+ this.removeModalOnHide();
4775
+ }
4776
+ // check for transitionend support
4777
+ var supportsTransitionEnd = this.modalTarget.ontransitionend !== undefined;
4778
+ // shown/hidden events trigger after toggling the class
4779
+ if (supportsTransitionEnd) {
4780
+ // wait until after the modal finishes transitioning to fire the event
4781
+ this.modalTarget.addEventListener("transitionend", function () {
4782
+ //TODO this is firing waaay to soon?
4783
+ _this.triggerEvent(toShow ? "shown" : "hidden", {
4784
+ dispatcher: dispatchingElement
4785
+ }, _this.modalTarget);
4786
+ }, { once: true });
4787
+ }
4788
+ else {
4789
+ this.triggerEvent(toShow ? "shown" : "hidden", {
4790
+ dispatcher: dispatchingElement
4791
+ }, this.modalTarget);
4792
+ }
4793
+ };
4794
+ /**
4795
+ * Listens for the s-modal:hidden event and focuses the returnElement when it is fired
4796
+ */
4797
+ ModalController.prototype.focusReturnElement = function () {
4798
+ var _this = this;
4799
+ if (!this.returnElement) {
4800
+ return;
4801
+ }
4802
+ this.modalTarget.addEventListener("s-modal:hidden", function () {
4803
+ // double check the element still exists when the event is called
4804
+ if (_this.returnElement && document.body.contains(_this.returnElement)) {
4805
+ _this.returnElement.focus();
4806
+ }
4807
+ }, { once: true });
4808
+ };
4809
+ /**
4810
+ * Remove the element on hide if the `remove-when-hidden` flag is set
4811
+ */
4812
+ ModalController.prototype.removeModalOnHide = function () {
4813
+ var _this = this;
4814
+ if (this.data.get("remove-when-hidden") !== "true") {
4815
+ return;
4816
+ }
4817
+ this.modalTarget.addEventListener("s-modal:hidden", function () {
4818
+ _this.element.remove();
4819
+ }, { once: true });
4820
+ };
4821
+ /**
4822
+ * Gets all elements within the modal that could receive keyboard focus.
4823
+ */
4824
+ ModalController.prototype.getAllTabbables = function () {
4825
+ return Array.from(this.modalTarget.querySelectorAll("[href], input, select, textarea, button, [tabindex]"))
4826
+ .filter(function (el) { return el.matches(":not([disabled]):not([tabindex='-1'])"); });
4827
+ };
4828
+ /**
4829
+ * Returns the first visible element in an array or `undefined` if no elements are visible.
4830
+ */
4831
+ ModalController.prototype.firstVisible = function (elements) {
4832
+ // https://stackoverflow.com/a/21696585
4833
+ return elements.find(function (el) { return el.offsetParent !== null; });
4834
+ };
4835
+ /**
4836
+ * Returns the last visible element in an array or `undefined` if no elements are visible.
4837
+ */
4838
+ ModalController.prototype.lastVisible = function (elements) {
4839
+ return this.firstVisible(__spreadArray([], elements, true).reverse());
4840
+ };
4841
+ /**
4842
+ * Attempts to shift keyboard focus into the modal.
4843
+ * If elements with `data-s-modal-target="initialFocus"` are present and visible, one of those will be selected.
4844
+ * Otherwise, the first visible focusable element will receive focus.
4845
+ */
4846
+ ModalController.prototype.focusInsideModal = function () {
4847
+ var _this = this;
4848
+ this.modalTarget.addEventListener("s-modal:shown", function () {
4849
+ var _a;
4850
+ var initialFocus = (_a = _this.firstVisible(_this.initialFocusTargets)) !== null && _a !== void 0 ? _a : _this.firstVisible(_this.getAllTabbables());
4851
+ initialFocus === null || initialFocus === void 0 ? void 0 : initialFocus.focus();
4852
+ }, { once: true });
4853
+ };
4854
+ /**
4855
+ * Returns keyboard focus to the modal if it has left or is about to leave.
4856
+ */
4857
+ ModalController.prototype.keepFocusWithinModal = function (e) {
4858
+ // If somehow the user has tabbed out of the modal or if focus started outside the modal, push them to the first item.
4859
+ if (!this.modalTarget.contains(e.target)) {
4860
+ var focusTarget = this.firstVisible(this.getAllTabbables());
4861
+ if (focusTarget) {
4862
+ e.preventDefault();
4863
+ focusTarget.focus();
4864
+ }
4865
+ return;
4866
+ }
4867
+ // If we observe a tab keydown and we're on an edge, cycle the focus to the other side.
4868
+ if (e.key === "Tab") {
4869
+ var tabbables = this.getAllTabbables();
4870
+ var firstTabbable = this.firstVisible(tabbables);
4871
+ var lastTabbable = this.lastVisible(tabbables);
4872
+ if (firstTabbable && lastTabbable) {
4873
+ if (firstTabbable === lastTabbable) {
4874
+ e.preventDefault();
4875
+ firstTabbable.focus();
4876
+ }
4877
+ else if (e.shiftKey && e.target === firstTabbable) {
4878
+ e.preventDefault();
4879
+ lastTabbable.focus();
4880
+ }
4881
+ else if (!e.shiftKey && e.target === lastTabbable) {
4882
+ e.preventDefault();
4883
+ firstTabbable.focus();
4884
+ }
4885
+ }
4886
+ }
4887
+ };
4888
+ /**
4889
+ * Binds global events to the document for hiding popovers on user interaction
4890
+ */
4891
+ ModalController.prototype.bindDocumentEvents = function () {
4892
+ // in order for removeEventListener to remove the right event, this bound function needs a constant reference
4893
+ this._boundClickFn = this._boundClickFn || this.hideOnOutsideClick.bind(this);
4894
+ this._boundKeypressFn = this._boundKeypressFn || this.hideOnEscapePress.bind(this);
4895
+ this._boundTabTrap = this._boundTabTrap || this.keepFocusWithinModal.bind(this);
4896
+ document.addEventListener("mousedown", this._boundClickFn);
4897
+ document.addEventListener("keyup", this._boundKeypressFn);
4898
+ document.addEventListener("keydown", this._boundTabTrap);
4899
+ };
4900
+ /**
4901
+ * Unbinds global events to the document for hiding popovers on user interaction
4902
+ */
4903
+ ModalController.prototype.unbindDocumentEvents = function () {
4904
+ document.removeEventListener("mousedown", this._boundClickFn);
4905
+ document.removeEventListener("keyup", this._boundKeypressFn);
4906
+ document.removeEventListener("keydown", this._boundTabTrap);
4907
+ };
4908
+ /**
4909
+ * Forces the popover to hide if a user clicks outside of it or its reference element
4910
+ */
4911
+ ModalController.prototype.hideOnOutsideClick = function (e) {
4912
+ var target = e.target;
4913
+ // check if the document was clicked inside either the toggle element or the modal itself
4914
+ // note: .contains also returns true if the node itself matches the target element
4915
+ if (!this.modalTarget.querySelector(".s-modal--dialog").contains(target) && document.body.contains(target)) {
4916
+ this._toggle(false, e);
4917
+ }
4918
+ };
4919
+ /**
4920
+ * Forces the popover to hide if the user presses escape while it, one of its childen, or the reference element are focused
4921
+ */
4922
+ ModalController.prototype.hideOnEscapePress = function (e) {
4923
+ // if the ESC key (27) wasn't pressed or if no popovers are showing, return
4924
+ if (e.which !== 27 || this.modalTarget.getAttribute("aria-hidden") === "true") {
4925
+ return;
4926
+ }
4927
+ this._toggle(false, e);
4928
+ };
4929
+ /**
4930
+ * Determines the correct dispatching element from a potential input
4931
+ * @param dispatcher The event or element to get the dispatcher from
4932
+ */
4933
+ ModalController.prototype.getDispatcher = function (dispatcher) {
4934
+ if (dispatcher === void 0) { dispatcher = null; }
4935
+ if (dispatcher instanceof Event) {
4936
+ return dispatcher.target;
4937
+ }
4938
+ else if (dispatcher instanceof Element) {
4939
+ return dispatcher;
4940
+ }
4941
+ else {
4942
+ return this.element;
4943
+ }
4944
+ };
4945
+ ModalController.targets = ["modal", "initialFocus"];
4946
+ return ModalController;
4947
+ }(Stacks.StacksController));
4948
+ exports.ModalController = ModalController;
4949
+ /**
4950
+ * Helper to manually show an s-modal element via external JS
4951
+ * @param element the element the `data-controller="s-modal"` attribute is on
4952
+ */
4953
+ function showModal(element) {
4954
+ toggleModal(element, true);
4955
+ }
4956
+ exports.showModal = showModal;
4957
+ /**
4958
+ * Helper to manually hide an s-modal element via external JS
4959
+ * @param element the element the `data-controller="s-modal"` attribute is on
4960
+ */
4961
+ function hideModal(element) {
4962
+ toggleModal(element, false);
4963
+ }
4964
+ exports.hideModal = hideModal;
4965
+ /**
4966
+ * Helper to manually show an s-modal element via external JS
4967
+ * @param element the element the `data-controller="s-modal"` attribute is on
4968
+ * @param show whether to force show/hide the modal; toggles the modal if left undefined
4969
+ */
4970
+ function toggleModal(element, show) {
4971
+ var controller = Stacks.application.getControllerForElementAndIdentifier(element, "s-modal");
4972
+ if (!controller) {
4973
+ throw "Unable to get s-modal controller from element";
4974
+ }
4975
+ show ? controller.show() : controller.hide();
4976
+ }
4977
4977
 
4978
4978
 
4979
4979
  /***/ }),
@@ -4981,147 +4981,147 @@ function toggleModal(element, show) {
4981
4981
  /***/ 642:
4982
4982
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
4983
4983
 
4984
-
4985
- var __extends = (this && this.__extends) || (function () {
4986
- var extendStatics = function (d, b) {
4987
- extendStatics = Object.setPrototypeOf ||
4988
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
4989
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
4990
- return extendStatics(d, b);
4991
- };
4992
- return function (d, b) {
4993
- if (typeof b !== "function" && b !== null)
4994
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
4995
- extendStatics(d, b);
4996
- function __() { this.constructor = d; }
4997
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
4998
- };
4999
- })();
5000
- Object.defineProperty(exports, "__esModule", ({ value: true }));
5001
- exports.TabListController = void 0;
5002
- var Stacks = __webpack_require__(36);
5003
- var TabListController = /** @class */ (function (_super) {
5004
- __extends(TabListController, _super);
5005
- function TabListController() {
5006
- return _super !== null && _super.apply(this, arguments) || this;
5007
- }
5008
- TabListController.prototype.connect = function () {
5009
- _super.prototype.connect.call(this);
5010
- this.boundSelectTab = this.selectTab.bind(this);
5011
- this.boundHandleKeydown = this.handleKeydown.bind(this);
5012
- for (var _i = 0, _a = this.tabTargets; _i < _a.length; _i++) {
5013
- var tab = _a[_i];
5014
- tab.addEventListener("click", this.boundSelectTab);
5015
- tab.addEventListener("keydown", this.boundHandleKeydown);
5016
- }
5017
- };
5018
- TabListController.prototype.disconnect = function () {
5019
- _super.prototype.disconnect.call(this);
5020
- for (var _i = 0, _a = this.tabTargets; _i < _a.length; _i++) {
5021
- var tab = _a[_i];
5022
- tab.removeEventListener("click", this.boundSelectTab);
5023
- tab.removeEventListener("keydown", this.boundHandleKeydown);
5024
- }
5025
- };
5026
- Object.defineProperty(TabListController.prototype, "tabTargets", {
5027
- /**
5028
- * Gets all tabs within the controller.
5029
- */
5030
- get: function () {
5031
- return Array.from(this.element.querySelectorAll("[role=tab]"));
5032
- },
5033
- enumerable: false,
5034
- configurable: true
5035
- });
5036
- /**
5037
- * Handles click events on individual tabs, causing them to be selected.
5038
- */
5039
- TabListController.prototype.selectTab = function (event) {
5040
- this.switchToTab(event.currentTarget);
5041
- };
5042
- /**
5043
- * Handles left and right arrow keydown events on individual tabs,
5044
- * selecting the adjacent tab corresponding to the event.
5045
- */
5046
- TabListController.prototype.handleKeydown = function (event) {
5047
- var _a;
5048
- var tabElement = event.currentTarget;
5049
- var tabs = this.tabTargets;
5050
- var tabIndex = tabs.indexOf(tabElement);
5051
- if (event.key === "ArrowRight") {
5052
- tabIndex++;
5053
- }
5054
- else if (event.key === "ArrowLeft") {
5055
- tabIndex--;
5056
- }
5057
- else {
5058
- return;
5059
- }
5060
- // Use circular navigation when users go past the first or last tab.
5061
- if (tabIndex < 0) {
5062
- tabIndex = tabs.length - 1;
5063
- }
5064
- if (tabIndex >= tabs.length) {
5065
- tabIndex = 0;
5066
- }
5067
- tabElement = tabs[tabIndex];
5068
- this.switchToTab(tabElement);
5069
- // Focus the newly selected tab so it can receive keyboard events.
5070
- (_a = this.selectedTab) === null || _a === void 0 ? void 0 : _a.focus();
5071
- };
5072
- /**
5073
- * Attempts to switch to a new tab, doing nothing if the tab is already selected or
5074
- * the s-navigation-tablist:select event is prevented.
5075
- */
5076
- TabListController.prototype.switchToTab = function (newTab) {
5077
- var oldTab = this.selectedTab;
5078
- if (oldTab === newTab) {
5079
- return;
5080
- }
5081
- if (this.triggerEvent("select", { oldTab: oldTab, newTab: newTab }).defaultPrevented) {
5082
- return;
5083
- }
5084
- this.selectedTab = newTab;
5085
- this.triggerEvent("selected", { oldTab: oldTab, newTab: newTab });
5086
- };
5087
- Object.defineProperty(TabListController.prototype, "selectedTab", {
5088
- /**
5089
- * Returns the currently selected tab or null if no tabs are selected.
5090
- */
5091
- get: function () {
5092
- return this.tabTargets.find(function (e) { return e.getAttribute("aria-selected") === "true"; }) || null;
5093
- },
5094
- /**
5095
- * Switches the tablist to the provided tab, updating the tabs and panels
5096
- * to reflect the change.
5097
- * @param selectedTab The tab to select. If `null` is provided or the element
5098
- * is not a valid tab, all tabs will be unselected.
5099
- */
5100
- set: function (selectedTab) {
5101
- for (var _i = 0, _a = this.tabTargets; _i < _a.length; _i++) {
5102
- var tab = _a[_i];
5103
- var panelId = tab.getAttribute('aria-controls');
5104
- var panel = panelId ? document.getElementById(panelId) : null;
5105
- if (tab === selectedTab) {
5106
- tab.classList.add('is-selected');
5107
- tab.setAttribute('aria-selected', 'true');
5108
- tab.removeAttribute('tabindex');
5109
- panel === null || panel === void 0 ? void 0 : panel.classList.remove('d-none');
5110
- }
5111
- else {
5112
- tab.classList.remove('is-selected');
5113
- tab.setAttribute('aria-selected', 'false');
5114
- tab.setAttribute('tabindex', '-1');
5115
- panel === null || panel === void 0 ? void 0 : panel.classList.add('d-none');
5116
- }
5117
- }
5118
- },
5119
- enumerable: false,
5120
- configurable: true
5121
- });
5122
- return TabListController;
5123
- }(Stacks.StacksController));
5124
- exports.TabListController = TabListController;
4984
+
4985
+ var __extends = (this && this.__extends) || (function () {
4986
+ var extendStatics = function (d, b) {
4987
+ extendStatics = Object.setPrototypeOf ||
4988
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
4989
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
4990
+ return extendStatics(d, b);
4991
+ };
4992
+ return function (d, b) {
4993
+ if (typeof b !== "function" && b !== null)
4994
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
4995
+ extendStatics(d, b);
4996
+ function __() { this.constructor = d; }
4997
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
4998
+ };
4999
+ })();
5000
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
5001
+ exports.TabListController = void 0;
5002
+ var Stacks = __webpack_require__(36);
5003
+ var TabListController = /** @class */ (function (_super) {
5004
+ __extends(TabListController, _super);
5005
+ function TabListController() {
5006
+ return _super !== null && _super.apply(this, arguments) || this;
5007
+ }
5008
+ TabListController.prototype.connect = function () {
5009
+ _super.prototype.connect.call(this);
5010
+ this.boundSelectTab = this.selectTab.bind(this);
5011
+ this.boundHandleKeydown = this.handleKeydown.bind(this);
5012
+ for (var _i = 0, _a = this.tabTargets; _i < _a.length; _i++) {
5013
+ var tab = _a[_i];
5014
+ tab.addEventListener("click", this.boundSelectTab);
5015
+ tab.addEventListener("keydown", this.boundHandleKeydown);
5016
+ }
5017
+ };
5018
+ TabListController.prototype.disconnect = function () {
5019
+ _super.prototype.disconnect.call(this);
5020
+ for (var _i = 0, _a = this.tabTargets; _i < _a.length; _i++) {
5021
+ var tab = _a[_i];
5022
+ tab.removeEventListener("click", this.boundSelectTab);
5023
+ tab.removeEventListener("keydown", this.boundHandleKeydown);
5024
+ }
5025
+ };
5026
+ Object.defineProperty(TabListController.prototype, "tabTargets", {
5027
+ /**
5028
+ * Gets all tabs within the controller.
5029
+ */
5030
+ get: function () {
5031
+ return Array.from(this.element.querySelectorAll("[role=tab]"));
5032
+ },
5033
+ enumerable: false,
5034
+ configurable: true
5035
+ });
5036
+ /**
5037
+ * Handles click events on individual tabs, causing them to be selected.
5038
+ */
5039
+ TabListController.prototype.selectTab = function (event) {
5040
+ this.switchToTab(event.currentTarget);
5041
+ };
5042
+ /**
5043
+ * Handles left and right arrow keydown events on individual tabs,
5044
+ * selecting the adjacent tab corresponding to the event.
5045
+ */
5046
+ TabListController.prototype.handleKeydown = function (event) {
5047
+ var _a;
5048
+ var tabElement = event.currentTarget;
5049
+ var tabs = this.tabTargets;
5050
+ var tabIndex = tabs.indexOf(tabElement);
5051
+ if (event.key === "ArrowRight") {
5052
+ tabIndex++;
5053
+ }
5054
+ else if (event.key === "ArrowLeft") {
5055
+ tabIndex--;
5056
+ }
5057
+ else {
5058
+ return;
5059
+ }
5060
+ // Use circular navigation when users go past the first or last tab.
5061
+ if (tabIndex < 0) {
5062
+ tabIndex = tabs.length - 1;
5063
+ }
5064
+ if (tabIndex >= tabs.length) {
5065
+ tabIndex = 0;
5066
+ }
5067
+ tabElement = tabs[tabIndex];
5068
+ this.switchToTab(tabElement);
5069
+ // Focus the newly selected tab so it can receive keyboard events.
5070
+ (_a = this.selectedTab) === null || _a === void 0 ? void 0 : _a.focus();
5071
+ };
5072
+ /**
5073
+ * Attempts to switch to a new tab, doing nothing if the tab is already selected or
5074
+ * the s-navigation-tablist:select event is prevented.
5075
+ */
5076
+ TabListController.prototype.switchToTab = function (newTab) {
5077
+ var oldTab = this.selectedTab;
5078
+ if (oldTab === newTab) {
5079
+ return;
5080
+ }
5081
+ if (this.triggerEvent("select", { oldTab: oldTab, newTab: newTab }).defaultPrevented) {
5082
+ return;
5083
+ }
5084
+ this.selectedTab = newTab;
5085
+ this.triggerEvent("selected", { oldTab: oldTab, newTab: newTab });
5086
+ };
5087
+ Object.defineProperty(TabListController.prototype, "selectedTab", {
5088
+ /**
5089
+ * Returns the currently selected tab or null if no tabs are selected.
5090
+ */
5091
+ get: function () {
5092
+ return this.tabTargets.find(function (e) { return e.getAttribute("aria-selected") === "true"; }) || null;
5093
+ },
5094
+ /**
5095
+ * Switches the tablist to the provided tab, updating the tabs and panels
5096
+ * to reflect the change.
5097
+ * @param selectedTab The tab to select. If `null` is provided or the element
5098
+ * is not a valid tab, all tabs will be unselected.
5099
+ */
5100
+ set: function (selectedTab) {
5101
+ for (var _i = 0, _a = this.tabTargets; _i < _a.length; _i++) {
5102
+ var tab = _a[_i];
5103
+ var panelId = tab.getAttribute('aria-controls');
5104
+ var panel = panelId ? document.getElementById(panelId) : null;
5105
+ if (tab === selectedTab) {
5106
+ tab.classList.add('is-selected');
5107
+ tab.setAttribute('aria-selected', 'true');
5108
+ tab.removeAttribute('tabindex');
5109
+ panel === null || panel === void 0 ? void 0 : panel.classList.remove('d-none');
5110
+ }
5111
+ else {
5112
+ tab.classList.remove('is-selected');
5113
+ tab.setAttribute('aria-selected', 'false');
5114
+ tab.setAttribute('tabindex', '-1');
5115
+ panel === null || panel === void 0 ? void 0 : panel.classList.add('d-none');
5116
+ }
5117
+ }
5118
+ },
5119
+ enumerable: false,
5120
+ configurable: true
5121
+ });
5122
+ return TabListController;
5123
+ }(Stacks.StacksController));
5124
+ exports.TabListController = TabListController;
5125
5125
 
5126
5126
 
5127
5127
  /***/ }),
@@ -5129,495 +5129,495 @@ exports.TabListController = TabListController;
5129
5129
  /***/ 388:
5130
5130
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
5131
5131
 
5132
-
5133
- var __extends = (this && this.__extends) || (function () {
5134
- var extendStatics = function (d, b) {
5135
- extendStatics = Object.setPrototypeOf ||
5136
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5137
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
5138
- return extendStatics(d, b);
5139
- };
5140
- return function (d, b) {
5141
- if (typeof b !== "function" && b !== null)
5142
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
5143
- extendStatics(d, b);
5144
- function __() { this.constructor = d; }
5145
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5146
- };
5147
- })();
5148
- Object.defineProperty(exports, "__esModule", ({ value: true }));
5149
- exports.detachPopover = exports.attachPopover = exports.hidePopover = exports.showPopover = exports.PopoverController = exports.BasePopoverController = void 0;
5150
- var core_1 = __webpack_require__(750);
5151
- var Stacks = __webpack_require__(36);
5152
- var BasePopoverController = /** @class */ (function (_super) {
5153
- __extends(BasePopoverController, _super);
5154
- function BasePopoverController() {
5155
- return _super !== null && _super.apply(this, arguments) || this;
5156
- }
5157
- Object.defineProperty(BasePopoverController.prototype, "isVisible", {
5158
- /**
5159
- * Returns true if the if the popover is currently visible.
5160
- */
5161
- get: function () {
5162
- var popoverElement = this.popoverElement;
5163
- return popoverElement ? popoverElement.classList.contains("is-visible") : false;
5164
- },
5165
- enumerable: false,
5166
- configurable: true
5167
- });
5168
- Object.defineProperty(BasePopoverController.prototype, "isInViewport", {
5169
- /**
5170
- * Gets whether the element is visible in the browser's viewport.
5171
- */
5172
- get: function () {
5173
- var element = this.popoverElement;
5174
- if (!this.isVisible || !element) {
5175
- return false;
5176
- }
5177
- // From https://stackoverflow.com/a/5354536. Theoretically, this could be calculated using Popper's detectOverflow function,
5178
- // but it's unclear how to access that with our current configuration.
5179
- var rect = element.getBoundingClientRect();
5180
- var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
5181
- var viewWidth = Math.max(document.documentElement.clientWidth, window.innerWidth);
5182
- return rect.bottom > 0 && rect.top < viewHeight && rect.right > 0 && rect.left < viewWidth;
5183
- },
5184
- enumerable: false,
5185
- configurable: true
5186
- });
5187
- Object.defineProperty(BasePopoverController.prototype, "shouldHideOnOutsideClick", {
5188
- get: function () {
5189
- var hideBehavior = this.data.get("hide-on-outside-click");
5190
- switch (hideBehavior) {
5191
- case "after-dismissal":
5192
- case "never":
5193
- return false;
5194
- case "if-in-viewport":
5195
- return this.isInViewport;
5196
- default:
5197
- return true;
5198
- }
5199
- },
5200
- enumerable: false,
5201
- configurable: true
5202
- });
5203
- /**
5204
- * Initializes and validates controller variables
5205
- */
5206
- BasePopoverController.prototype.connect = function () {
5207
- _super.prototype.connect.call(this);
5208
- this.validate();
5209
- if (this.isVisible) {
5210
- // just call initialize here, not show. This keeps already visible popovers from adding/firing document events
5211
- this.initializePopper();
5212
- }
5213
- else if (this.data.get("auto-show") === "true") {
5214
- this.show(null);
5215
- }
5216
- this.data.delete("auto-show");
5217
- };
5218
- /**
5219
- * Cleans up popper.js elements and disconnects all added event listeners
5220
- */
5221
- BasePopoverController.prototype.disconnect = function () {
5222
- this.hide();
5223
- if (this.popper) {
5224
- this.popper.destroy();
5225
- delete this.popper;
5226
- }
5227
- _super.prototype.disconnect.call(this);
5228
- };
5229
- /**
5230
- * Toggles the visibility of the popover
5231
- */
5232
- BasePopoverController.prototype.toggle = function (dispatcher) {
5233
- if (dispatcher === void 0) { dispatcher = null; }
5234
- this.isVisible ? this.hide(dispatcher) : this.show(dispatcher);
5235
- };
5236
- /**
5237
- * Shows the popover if not already visible
5238
- */
5239
- BasePopoverController.prototype.show = function (dispatcher) {
5240
- if (dispatcher === void 0) { dispatcher = null; }
5241
- if (this.isVisible) {
5242
- return;
5243
- }
5244
- var dispatcherElement = this.getDispatcher(dispatcher);
5245
- if (this.triggerEvent("show", {
5246
- dispatcher: dispatcherElement
5247
- }).defaultPrevented) {
5248
- return;
5249
- }
5250
- if (!this.popper) {
5251
- this.initializePopper();
5252
- }
5253
- this.popoverElement.classList.add("is-visible");
5254
- // ensure the popper has been positioned correctly
5255
- this.scheduleUpdate();
5256
- this.shown(dispatcherElement);
5257
- };
5258
- /**
5259
- * Hides the popover if not already hidden
5260
- */
5261
- BasePopoverController.prototype.hide = function (dispatcher) {
5262
- if (dispatcher === void 0) { dispatcher = null; }
5263
- if (!this.isVisible) {
5264
- return;
5265
- }
5266
- var dispatcherElement = this.getDispatcher(dispatcher);
5267
- if (this.triggerEvent("hide", {
5268
- dispatcher: dispatcherElement
5269
- }).defaultPrevented) {
5270
- return;
5271
- }
5272
- this.popoverElement.classList.remove("is-visible");
5273
- if (this.popper) {
5274
- // completely destroy the popper on hide; this is in line with Popper.js's performance recommendations
5275
- this.popper.destroy();
5276
- delete this.popper;
5277
- }
5278
- // on first interaction, hide-on-outside-click with value "after-dismissal" reverts to the default behavior
5279
- if (this.data.get("hide-on-outside-click") === "after-dismissal") {
5280
- this.data.delete("hide-on-outside-click");
5281
- }
5282
- this.hidden(dispatcherElement);
5283
- };
5284
- /**
5285
- * Binds document events for this popover and fires the shown event
5286
- */
5287
- BasePopoverController.prototype.shown = function (dispatcher) {
5288
- if (dispatcher === void 0) { dispatcher = null; }
5289
- this.bindDocumentEvents();
5290
- this.triggerEvent("shown", {
5291
- dispatcher: dispatcher
5292
- });
5293
- };
5294
- /**
5295
- * Unbinds document events for this popover and fires the hidden event
5296
- */
5297
- BasePopoverController.prototype.hidden = function (dispatcher) {
5298
- if (dispatcher === void 0) { dispatcher = null; }
5299
- this.unbindDocumentEvents();
5300
- this.triggerEvent("hidden", {
5301
- dispatcher: dispatcher
5302
- });
5303
- };
5304
- /**
5305
- * Generates the popover if not found during initialization
5306
- */
5307
- BasePopoverController.prototype.generatePopover = function () {
5308
- return null;
5309
- };
5310
- /**
5311
- * Initializes the Popper for this instance
5312
- */
5313
- BasePopoverController.prototype.initializePopper = function () {
5314
- // @ts-ignore
5315
- this.popper = (0, core_1.createPopper)(this.referenceElement, this.popoverElement, {
5316
- placement: this.data.get("placement") || "bottom",
5317
- modifiers: [
5318
- {
5319
- name: "offset",
5320
- options: {
5321
- offset: [0, 10], // The entire popover should be 10px away from the element
5322
- }
5323
- },
5324
- {
5325
- name: "arrow",
5326
- options: {
5327
- element: ".s-popover--arrow"
5328
- },
5329
- },
5330
- ]
5331
- });
5332
- };
5333
- /**
5334
- * Validates the popover settings and attempts to set necessary internal variables
5335
- */
5336
- BasePopoverController.prototype.validate = function () {
5337
- var referenceSelector = this.data.get("reference-selector");
5338
- this.referenceElement = this.element;
5339
- // if there is an alternative reference selector and that element exists, use it (and throw if it isn't found)
5340
- if (referenceSelector) {
5341
- this.referenceElement = this.element.querySelector(referenceSelector);
5342
- if (!this.referenceElement) {
5343
- throw "Unable to find element by reference selector: " + referenceSelector;
5344
- }
5345
- }
5346
- var popoverId = this.referenceElement.getAttribute(this.popoverSelectorAttribute);
5347
- var popoverElement = null;
5348
- // if the popover is named, attempt to fetch it (and throw an error if it doesn't exist)
5349
- if (popoverId) {
5350
- popoverElement = document.getElementById(popoverId);
5351
- if (!popoverElement) {
5352
- throw "[".concat(this.popoverSelectorAttribute, "=\"{POPOVER_ID}\"] required");
5353
- }
5354
- }
5355
- // if the popover isn't named, attempt to generate it
5356
- else {
5357
- popoverElement = this.generatePopover();
5358
- }
5359
- if (!popoverElement) {
5360
- throw "unable to find or generate popover element";
5361
- }
5362
- this.popoverElement = popoverElement;
5363
- };
5364
- /**
5365
- * Determines the correct dispatching element from a potential input
5366
- * @param dispatcher The event or element to get the dispatcher from
5367
- */
5368
- BasePopoverController.prototype.getDispatcher = function (dispatcher) {
5369
- if (dispatcher === void 0) { dispatcher = null; }
5370
- if (dispatcher instanceof Event) {
5371
- return dispatcher.target;
5372
- }
5373
- else if (dispatcher instanceof Element) {
5374
- return dispatcher;
5375
- }
5376
- else {
5377
- return this.element;
5378
- }
5379
- };
5380
- /**
5381
- * Schedules the popover to update on the next animation frame if visible
5382
- */
5383
- BasePopoverController.prototype.scheduleUpdate = function () {
5384
- if (this.popper && this.isVisible) {
5385
- this.popper.update();
5386
- }
5387
- };
5388
- return BasePopoverController;
5389
- }(Stacks.StacksController));
5390
- exports.BasePopoverController = BasePopoverController;
5391
- var PopoverController = /** @class */ (function (_super) {
5392
- __extends(PopoverController, _super);
5393
- function PopoverController() {
5394
- var _this = _super !== null && _super.apply(this, arguments) || this;
5395
- _this.popoverSelectorAttribute = "aria-controls";
5396
- return _this;
5397
- }
5398
- /**
5399
- * Toggles optional classes in addition to BasePopoverController.shown
5400
- */
5401
- PopoverController.prototype.shown = function (dispatcher) {
5402
- if (dispatcher === void 0) { dispatcher = null; }
5403
- this.toggleOptionalClasses(true);
5404
- _super.prototype.shown.call(this, dispatcher);
5405
- };
5406
- /**
5407
- * Toggles optional classes in addition to BasePopoverController.hidden
5408
- */
5409
- PopoverController.prototype.hidden = function (dispatcher) {
5410
- if (dispatcher === void 0) { dispatcher = null; }
5411
- this.toggleOptionalClasses(false);
5412
- _super.prototype.hidden.call(this, dispatcher);
5413
- };
5414
- /**
5415
- * Binds global events to the document for hiding popovers on user interaction
5416
- */
5417
- PopoverController.prototype.bindDocumentEvents = function () {
5418
- this.boundHideOnOutsideClick = this.boundHideOnOutsideClick || this.hideOnOutsideClick.bind(this);
5419
- this.boundHideOnEscapePress = this.boundHideOnEscapePress || this.hideOnEscapePress.bind(this);
5420
- document.addEventListener("mousedown", this.boundHideOnOutsideClick);
5421
- document.addEventListener("keyup", this.boundHideOnEscapePress);
5422
- };
5423
- /**
5424
- * Unbinds global events to the document for hiding popovers on user interaction
5425
- */
5426
- PopoverController.prototype.unbindDocumentEvents = function () {
5427
- document.removeEventListener("mousedown", this.boundHideOnOutsideClick);
5428
- document.removeEventListener("keyup", this.boundHideOnEscapePress);
5429
- };
5430
- /**
5431
- * Forces the popover to hide if a user clicks outside of it or its reference element
5432
- * @param {Event} e - The document click event
5433
- */
5434
- PopoverController.prototype.hideOnOutsideClick = function (e) {
5435
- var target = e.target;
5436
- // check if the document was clicked inside either the reference element or the popover itself
5437
- // note: .contains also returns true if the node itself matches the target element
5438
- if (this.shouldHideOnOutsideClick && !this.referenceElement.contains(target) && !this.popoverElement.contains(target) && document.body.contains(target)) {
5439
- this.hide(e);
5440
- }
5441
- };
5442
- ;
5443
- /**
5444
- * Forces the popover to hide if the user presses escape while it, one of its childen, or the reference element are focused
5445
- * @param {Event} e - The document keyup event
5446
- */
5447
- PopoverController.prototype.hideOnEscapePress = function (e) {
5448
- // if the ESC key (27) wasn't pressed or if no popovers are showing, return
5449
- if (e.which !== 27 || !this.isVisible) {
5450
- return;
5451
- }
5452
- // check if the target was inside the popover element and refocus the triggering element
5453
- // note: .contains also returns true if the node itself matches the target element
5454
- if (this.popoverElement.contains(e.target)) {
5455
- this.referenceElement.focus();
5456
- }
5457
- this.hide(e);
5458
- };
5459
- ;
5460
- /**
5461
- * Toggles all classes on the originating element based on the `class-toggle` data
5462
- * @param {boolean=} show - A boolean indicating whether this is being triggered by a show or hide.
5463
- */
5464
- PopoverController.prototype.toggleOptionalClasses = function (show) {
5465
- if (!this.data.has("toggle-class")) {
5466
- return;
5467
- }
5468
- var cl = this.referenceElement.classList;
5469
- this.data.get("toggle-class").split(/\s+/).forEach(function (cls) {
5470
- cl.toggle(cls, show);
5471
- });
5472
- };
5473
- PopoverController.targets = [];
5474
- return PopoverController;
5475
- }(BasePopoverController));
5476
- exports.PopoverController = PopoverController;
5477
- /**
5478
- * Helper to manually show an s-popover element via external JS
5479
- * @param element the element the `data-controller="s-popover"` attribute is on
5480
- */
5481
- function showPopover(element) {
5482
- var _a = getPopover(element), isPopover = _a.isPopover, controller = _a.controller;
5483
- if (controller) {
5484
- controller.show();
5485
- }
5486
- else if (isPopover) {
5487
- element.setAttribute("data-s-popover-auto-show", "true");
5488
- }
5489
- else {
5490
- throw "element does not have data-controller=\"s-popover\"";
5491
- }
5492
- }
5493
- exports.showPopover = showPopover;
5494
- /**
5495
- * Helper to manually hide an s-popover element via external JS
5496
- * @param element the element the `data-controller="s-popover"` attribute is on
5497
- */
5498
- function hidePopover(element) {
5499
- var _a = getPopover(element), isPopover = _a.isPopover, controller = _a.controller, popover = _a.popover;
5500
- if (controller) {
5501
- controller.hide();
5502
- }
5503
- else if (isPopover) {
5504
- element.removeAttribute("data-s-popover-auto-show");
5505
- if (popover) {
5506
- popover.classList.remove("is-visible");
5507
- }
5508
- }
5509
- else {
5510
- throw "element does not have data-controller=\"s-popover\"";
5511
- }
5512
- }
5513
- exports.hidePopover = hidePopover;
5514
- /**
5515
- * Attaches a popover to an element and performs additional configuration.
5516
- * @param element the element that will receive the `data-controller="s-popover"` attribute.
5517
- * @param popover an element with the `.s-popover` class or HTML string containing a single element with the `.s-popover` class.
5518
- * If the popover does not have a parent element, it will be inserted as a immediately after the reference element.
5519
- * @param options an optional collection of options to use when configuring the popover.
5520
- */
5521
- function attachPopover(element, popover, options) {
5522
- var _a = getPopover(element), referenceElement = _a.referenceElement, existingPopover = _a.popover;
5523
- if (existingPopover) {
5524
- throw "element already has popover with id=\"".concat(existingPopover.id, "\"");
5525
- }
5526
- if (!referenceElement) {
5527
- throw "element has invalid data-s-popover-reference-selector attribute";
5528
- }
5529
- if (typeof popover === 'string') {
5530
- var elements = document.createRange().createContextualFragment(popover).children;
5531
- if (elements.length !== 1) {
5532
- throw "popover should contain a single element";
5533
- }
5534
- popover = elements[0];
5535
- }
5536
- var existingId = referenceElement.getAttribute("aria-controls");
5537
- var popoverId = popover.id;
5538
- if (!popover.classList.contains('s-popover')) {
5539
- throw "popover should have the \"s-popover\" class but had class=\"".concat(popover.className, "\"");
5540
- }
5541
- if (existingId && existingId !== popoverId) {
5542
- throw "element has aria-controls=\"".concat(existingId, "\" but popover has id=\"").concat(popoverId, "\"");
5543
- }
5544
- if (!popoverId) {
5545
- popoverId = "--stacks-s-popover-" + Math.random().toString(36).substring(2, 10);
5546
- popover.id = popoverId;
5547
- }
5548
- if (!existingId) {
5549
- referenceElement.setAttribute("aria-controls", popoverId);
5550
- }
5551
- if (!popover.parentElement && element.parentElement) {
5552
- referenceElement.insertAdjacentElement("afterend", popover);
5553
- }
5554
- toggleController(element, "s-popover", true);
5555
- if (options) {
5556
- if (options.toggleOnClick) {
5557
- referenceElement.setAttribute("data-action", "click->s-popover#toggle");
5558
- }
5559
- if (options.placement) {
5560
- element.setAttribute("data-s-popover-placement", options.placement);
5561
- }
5562
- if (options.autoShow) {
5563
- element.setAttribute("data-s-popover-auto-show", "true");
5564
- }
5565
- }
5566
- }
5567
- exports.attachPopover = attachPopover;
5568
- /**
5569
- * Removes the popover controller from an element and removes the popover from the DOM.
5570
- * @param element the element that has the `data-controller="s-popover"` attribute.
5571
- * @returns The popover that was attached to the element.
5572
- */
5573
- function detachPopover(element) {
5574
- var _a = getPopover(element), isPopover = _a.isPopover, controller = _a.controller, referenceElement = _a.referenceElement, popover = _a.popover;
5575
- // Hide the popover so its events fire.
5576
- controller === null || controller === void 0 ? void 0 : controller.hide();
5577
- // Remove the popover if it exists
5578
- popover === null || popover === void 0 ? void 0 : popover.remove();
5579
- // Remove the popover controller and the aria-controls attributes.
5580
- if (isPopover) {
5581
- toggleController(element, "s-popover", false);
5582
- if (referenceElement) {
5583
- referenceElement.removeAttribute("aria-controls");
5584
- }
5585
- }
5586
- return popover;
5587
- }
5588
- exports.detachPopover = detachPopover;
5589
- /**
5590
- * Gets the current state of an element that may be or is intended to be an s-popover controller
5591
- * so it can be configured either directly or via the DOM.
5592
- * @param element An element that may have `data-controller="s-popover"`.
5593
- */
5594
- function getPopover(element) {
5595
- var _a;
5596
- var isPopover = ((_a = element.getAttribute("data-controller")) === null || _a === void 0 ? void 0 : _a.includes("s-popover")) || false;
5597
- var controller = Stacks.application.getControllerForElementAndIdentifier(element, "s-popover");
5598
- var referenceSelector = element.getAttribute("data-s-popover-reference-selector");
5599
- var referenceElement = referenceSelector ? element.querySelector(referenceSelector) : element;
5600
- var popoverId = referenceElement ? referenceElement.getAttribute("aria-controls") : null;
5601
- var popover = popoverId ? document.getElementById(popoverId) : null;
5602
- return { isPopover: isPopover, controller: controller, referenceElement: referenceElement, popover: popover };
5603
- }
5604
- /**
5605
- * Adds or removes the controller from an element's [data-controller] attribute without altering existing entries
5606
- * @param el The element to alter
5607
- * @param controllerName The name of the controller to add/remove
5608
- * @param include Whether to add the controllerName value
5609
- */
5610
- function toggleController(el, controllerName, include) {
5611
- var _a;
5612
- var controllers = new Set((_a = el.getAttribute('data-controller')) === null || _a === void 0 ? void 0 : _a.split(/\s+/));
5613
- if (include) {
5614
- controllers.add(controllerName);
5615
- }
5616
- else {
5617
- controllers.delete(controllerName);
5618
- }
5619
- el.setAttribute('data-controller', Array.from(controllers).join(' '));
5620
- }
5132
+
5133
+ var __extends = (this && this.__extends) || (function () {
5134
+ var extendStatics = function (d, b) {
5135
+ extendStatics = Object.setPrototypeOf ||
5136
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5137
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
5138
+ return extendStatics(d, b);
5139
+ };
5140
+ return function (d, b) {
5141
+ if (typeof b !== "function" && b !== null)
5142
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
5143
+ extendStatics(d, b);
5144
+ function __() { this.constructor = d; }
5145
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5146
+ };
5147
+ })();
5148
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
5149
+ exports.detachPopover = exports.attachPopover = exports.hidePopover = exports.showPopover = exports.PopoverController = exports.BasePopoverController = void 0;
5150
+ var core_1 = __webpack_require__(750);
5151
+ var Stacks = __webpack_require__(36);
5152
+ var BasePopoverController = /** @class */ (function (_super) {
5153
+ __extends(BasePopoverController, _super);
5154
+ function BasePopoverController() {
5155
+ return _super !== null && _super.apply(this, arguments) || this;
5156
+ }
5157
+ Object.defineProperty(BasePopoverController.prototype, "isVisible", {
5158
+ /**
5159
+ * Returns true if the if the popover is currently visible.
5160
+ */
5161
+ get: function () {
5162
+ var popoverElement = this.popoverElement;
5163
+ return popoverElement ? popoverElement.classList.contains("is-visible") : false;
5164
+ },
5165
+ enumerable: false,
5166
+ configurable: true
5167
+ });
5168
+ Object.defineProperty(BasePopoverController.prototype, "isInViewport", {
5169
+ /**
5170
+ * Gets whether the element is visible in the browser's viewport.
5171
+ */
5172
+ get: function () {
5173
+ var element = this.popoverElement;
5174
+ if (!this.isVisible || !element) {
5175
+ return false;
5176
+ }
5177
+ // From https://stackoverflow.com/a/5354536. Theoretically, this could be calculated using Popper's detectOverflow function,
5178
+ // but it's unclear how to access that with our current configuration.
5179
+ var rect = element.getBoundingClientRect();
5180
+ var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
5181
+ var viewWidth = Math.max(document.documentElement.clientWidth, window.innerWidth);
5182
+ return rect.bottom > 0 && rect.top < viewHeight && rect.right > 0 && rect.left < viewWidth;
5183
+ },
5184
+ enumerable: false,
5185
+ configurable: true
5186
+ });
5187
+ Object.defineProperty(BasePopoverController.prototype, "shouldHideOnOutsideClick", {
5188
+ get: function () {
5189
+ var hideBehavior = this.data.get("hide-on-outside-click");
5190
+ switch (hideBehavior) {
5191
+ case "after-dismissal":
5192
+ case "never":
5193
+ return false;
5194
+ case "if-in-viewport":
5195
+ return this.isInViewport;
5196
+ default:
5197
+ return true;
5198
+ }
5199
+ },
5200
+ enumerable: false,
5201
+ configurable: true
5202
+ });
5203
+ /**
5204
+ * Initializes and validates controller variables
5205
+ */
5206
+ BasePopoverController.prototype.connect = function () {
5207
+ _super.prototype.connect.call(this);
5208
+ this.validate();
5209
+ if (this.isVisible) {
5210
+ // just call initialize here, not show. This keeps already visible popovers from adding/firing document events
5211
+ this.initializePopper();
5212
+ }
5213
+ else if (this.data.get("auto-show") === "true") {
5214
+ this.show(null);
5215
+ }
5216
+ this.data.delete("auto-show");
5217
+ };
5218
+ /**
5219
+ * Cleans up popper.js elements and disconnects all added event listeners
5220
+ */
5221
+ BasePopoverController.prototype.disconnect = function () {
5222
+ this.hide();
5223
+ if (this.popper) {
5224
+ this.popper.destroy();
5225
+ delete this.popper;
5226
+ }
5227
+ _super.prototype.disconnect.call(this);
5228
+ };
5229
+ /**
5230
+ * Toggles the visibility of the popover
5231
+ */
5232
+ BasePopoverController.prototype.toggle = function (dispatcher) {
5233
+ if (dispatcher === void 0) { dispatcher = null; }
5234
+ this.isVisible ? this.hide(dispatcher) : this.show(dispatcher);
5235
+ };
5236
+ /**
5237
+ * Shows the popover if not already visible
5238
+ */
5239
+ BasePopoverController.prototype.show = function (dispatcher) {
5240
+ if (dispatcher === void 0) { dispatcher = null; }
5241
+ if (this.isVisible) {
5242
+ return;
5243
+ }
5244
+ var dispatcherElement = this.getDispatcher(dispatcher);
5245
+ if (this.triggerEvent("show", {
5246
+ dispatcher: dispatcherElement
5247
+ }).defaultPrevented) {
5248
+ return;
5249
+ }
5250
+ if (!this.popper) {
5251
+ this.initializePopper();
5252
+ }
5253
+ this.popoverElement.classList.add("is-visible");
5254
+ // ensure the popper has been positioned correctly
5255
+ this.scheduleUpdate();
5256
+ this.shown(dispatcherElement);
5257
+ };
5258
+ /**
5259
+ * Hides the popover if not already hidden
5260
+ */
5261
+ BasePopoverController.prototype.hide = function (dispatcher) {
5262
+ if (dispatcher === void 0) { dispatcher = null; }
5263
+ if (!this.isVisible) {
5264
+ return;
5265
+ }
5266
+ var dispatcherElement = this.getDispatcher(dispatcher);
5267
+ if (this.triggerEvent("hide", {
5268
+ dispatcher: dispatcherElement
5269
+ }).defaultPrevented) {
5270
+ return;
5271
+ }
5272
+ this.popoverElement.classList.remove("is-visible");
5273
+ if (this.popper) {
5274
+ // completely destroy the popper on hide; this is in line with Popper.js's performance recommendations
5275
+ this.popper.destroy();
5276
+ delete this.popper;
5277
+ }
5278
+ // on first interaction, hide-on-outside-click with value "after-dismissal" reverts to the default behavior
5279
+ if (this.data.get("hide-on-outside-click") === "after-dismissal") {
5280
+ this.data.delete("hide-on-outside-click");
5281
+ }
5282
+ this.hidden(dispatcherElement);
5283
+ };
5284
+ /**
5285
+ * Binds document events for this popover and fires the shown event
5286
+ */
5287
+ BasePopoverController.prototype.shown = function (dispatcher) {
5288
+ if (dispatcher === void 0) { dispatcher = null; }
5289
+ this.bindDocumentEvents();
5290
+ this.triggerEvent("shown", {
5291
+ dispatcher: dispatcher
5292
+ });
5293
+ };
5294
+ /**
5295
+ * Unbinds document events for this popover and fires the hidden event
5296
+ */
5297
+ BasePopoverController.prototype.hidden = function (dispatcher) {
5298
+ if (dispatcher === void 0) { dispatcher = null; }
5299
+ this.unbindDocumentEvents();
5300
+ this.triggerEvent("hidden", {
5301
+ dispatcher: dispatcher
5302
+ });
5303
+ };
5304
+ /**
5305
+ * Generates the popover if not found during initialization
5306
+ */
5307
+ BasePopoverController.prototype.generatePopover = function () {
5308
+ return null;
5309
+ };
5310
+ /**
5311
+ * Initializes the Popper for this instance
5312
+ */
5313
+ BasePopoverController.prototype.initializePopper = function () {
5314
+ // @ts-ignore
5315
+ this.popper = (0, core_1.createPopper)(this.referenceElement, this.popoverElement, {
5316
+ placement: this.data.get("placement") || "bottom",
5317
+ modifiers: [
5318
+ {
5319
+ name: "offset",
5320
+ options: {
5321
+ offset: [0, 10], // The entire popover should be 10px away from the element
5322
+ }
5323
+ },
5324
+ {
5325
+ name: "arrow",
5326
+ options: {
5327
+ element: ".s-popover--arrow"
5328
+ },
5329
+ },
5330
+ ]
5331
+ });
5332
+ };
5333
+ /**
5334
+ * Validates the popover settings and attempts to set necessary internal variables
5335
+ */
5336
+ BasePopoverController.prototype.validate = function () {
5337
+ var referenceSelector = this.data.get("reference-selector");
5338
+ this.referenceElement = this.element;
5339
+ // if there is an alternative reference selector and that element exists, use it (and throw if it isn't found)
5340
+ if (referenceSelector) {
5341
+ this.referenceElement = this.element.querySelector(referenceSelector);
5342
+ if (!this.referenceElement) {
5343
+ throw "Unable to find element by reference selector: " + referenceSelector;
5344
+ }
5345
+ }
5346
+ var popoverId = this.referenceElement.getAttribute(this.popoverSelectorAttribute);
5347
+ var popoverElement = null;
5348
+ // if the popover is named, attempt to fetch it (and throw an error if it doesn't exist)
5349
+ if (popoverId) {
5350
+ popoverElement = document.getElementById(popoverId);
5351
+ if (!popoverElement) {
5352
+ throw "[".concat(this.popoverSelectorAttribute, "=\"{POPOVER_ID}\"] required");
5353
+ }
5354
+ }
5355
+ // if the popover isn't named, attempt to generate it
5356
+ else {
5357
+ popoverElement = this.generatePopover();
5358
+ }
5359
+ if (!popoverElement) {
5360
+ throw "unable to find or generate popover element";
5361
+ }
5362
+ this.popoverElement = popoverElement;
5363
+ };
5364
+ /**
5365
+ * Determines the correct dispatching element from a potential input
5366
+ * @param dispatcher The event or element to get the dispatcher from
5367
+ */
5368
+ BasePopoverController.prototype.getDispatcher = function (dispatcher) {
5369
+ if (dispatcher === void 0) { dispatcher = null; }
5370
+ if (dispatcher instanceof Event) {
5371
+ return dispatcher.target;
5372
+ }
5373
+ else if (dispatcher instanceof Element) {
5374
+ return dispatcher;
5375
+ }
5376
+ else {
5377
+ return this.element;
5378
+ }
5379
+ };
5380
+ /**
5381
+ * Schedules the popover to update on the next animation frame if visible
5382
+ */
5383
+ BasePopoverController.prototype.scheduleUpdate = function () {
5384
+ if (this.popper && this.isVisible) {
5385
+ this.popper.update();
5386
+ }
5387
+ };
5388
+ return BasePopoverController;
5389
+ }(Stacks.StacksController));
5390
+ exports.BasePopoverController = BasePopoverController;
5391
+ var PopoverController = /** @class */ (function (_super) {
5392
+ __extends(PopoverController, _super);
5393
+ function PopoverController() {
5394
+ var _this = _super !== null && _super.apply(this, arguments) || this;
5395
+ _this.popoverSelectorAttribute = "aria-controls";
5396
+ return _this;
5397
+ }
5398
+ /**
5399
+ * Toggles optional classes in addition to BasePopoverController.shown
5400
+ */
5401
+ PopoverController.prototype.shown = function (dispatcher) {
5402
+ if (dispatcher === void 0) { dispatcher = null; }
5403
+ this.toggleOptionalClasses(true);
5404
+ _super.prototype.shown.call(this, dispatcher);
5405
+ };
5406
+ /**
5407
+ * Toggles optional classes in addition to BasePopoverController.hidden
5408
+ */
5409
+ PopoverController.prototype.hidden = function (dispatcher) {
5410
+ if (dispatcher === void 0) { dispatcher = null; }
5411
+ this.toggleOptionalClasses(false);
5412
+ _super.prototype.hidden.call(this, dispatcher);
5413
+ };
5414
+ /**
5415
+ * Binds global events to the document for hiding popovers on user interaction
5416
+ */
5417
+ PopoverController.prototype.bindDocumentEvents = function () {
5418
+ this.boundHideOnOutsideClick = this.boundHideOnOutsideClick || this.hideOnOutsideClick.bind(this);
5419
+ this.boundHideOnEscapePress = this.boundHideOnEscapePress || this.hideOnEscapePress.bind(this);
5420
+ document.addEventListener("mousedown", this.boundHideOnOutsideClick);
5421
+ document.addEventListener("keyup", this.boundHideOnEscapePress);
5422
+ };
5423
+ /**
5424
+ * Unbinds global events to the document for hiding popovers on user interaction
5425
+ */
5426
+ PopoverController.prototype.unbindDocumentEvents = function () {
5427
+ document.removeEventListener("mousedown", this.boundHideOnOutsideClick);
5428
+ document.removeEventListener("keyup", this.boundHideOnEscapePress);
5429
+ };
5430
+ /**
5431
+ * Forces the popover to hide if a user clicks outside of it or its reference element
5432
+ * @param {Event} e - The document click event
5433
+ */
5434
+ PopoverController.prototype.hideOnOutsideClick = function (e) {
5435
+ var target = e.target;
5436
+ // check if the document was clicked inside either the reference element or the popover itself
5437
+ // note: .contains also returns true if the node itself matches the target element
5438
+ if (this.shouldHideOnOutsideClick && !this.referenceElement.contains(target) && !this.popoverElement.contains(target) && document.body.contains(target)) {
5439
+ this.hide(e);
5440
+ }
5441
+ };
5442
+ ;
5443
+ /**
5444
+ * Forces the popover to hide if the user presses escape while it, one of its childen, or the reference element are focused
5445
+ * @param {Event} e - The document keyup event
5446
+ */
5447
+ PopoverController.prototype.hideOnEscapePress = function (e) {
5448
+ // if the ESC key (27) wasn't pressed or if no popovers are showing, return
5449
+ if (e.which !== 27 || !this.isVisible) {
5450
+ return;
5451
+ }
5452
+ // check if the target was inside the popover element and refocus the triggering element
5453
+ // note: .contains also returns true if the node itself matches the target element
5454
+ if (this.popoverElement.contains(e.target)) {
5455
+ this.referenceElement.focus();
5456
+ }
5457
+ this.hide(e);
5458
+ };
5459
+ ;
5460
+ /**
5461
+ * Toggles all classes on the originating element based on the `class-toggle` data
5462
+ * @param {boolean=} show - A boolean indicating whether this is being triggered by a show or hide.
5463
+ */
5464
+ PopoverController.prototype.toggleOptionalClasses = function (show) {
5465
+ if (!this.data.has("toggle-class")) {
5466
+ return;
5467
+ }
5468
+ var cl = this.referenceElement.classList;
5469
+ this.data.get("toggle-class").split(/\s+/).forEach(function (cls) {
5470
+ cl.toggle(cls, show);
5471
+ });
5472
+ };
5473
+ PopoverController.targets = [];
5474
+ return PopoverController;
5475
+ }(BasePopoverController));
5476
+ exports.PopoverController = PopoverController;
5477
+ /**
5478
+ * Helper to manually show an s-popover element via external JS
5479
+ * @param element the element the `data-controller="s-popover"` attribute is on
5480
+ */
5481
+ function showPopover(element) {
5482
+ var _a = getPopover(element), isPopover = _a.isPopover, controller = _a.controller;
5483
+ if (controller) {
5484
+ controller.show();
5485
+ }
5486
+ else if (isPopover) {
5487
+ element.setAttribute("data-s-popover-auto-show", "true");
5488
+ }
5489
+ else {
5490
+ throw "element does not have data-controller=\"s-popover\"";
5491
+ }
5492
+ }
5493
+ exports.showPopover = showPopover;
5494
+ /**
5495
+ * Helper to manually hide an s-popover element via external JS
5496
+ * @param element the element the `data-controller="s-popover"` attribute is on
5497
+ */
5498
+ function hidePopover(element) {
5499
+ var _a = getPopover(element), isPopover = _a.isPopover, controller = _a.controller, popover = _a.popover;
5500
+ if (controller) {
5501
+ controller.hide();
5502
+ }
5503
+ else if (isPopover) {
5504
+ element.removeAttribute("data-s-popover-auto-show");
5505
+ if (popover) {
5506
+ popover.classList.remove("is-visible");
5507
+ }
5508
+ }
5509
+ else {
5510
+ throw "element does not have data-controller=\"s-popover\"";
5511
+ }
5512
+ }
5513
+ exports.hidePopover = hidePopover;
5514
+ /**
5515
+ * Attaches a popover to an element and performs additional configuration.
5516
+ * @param element the element that will receive the `data-controller="s-popover"` attribute.
5517
+ * @param popover an element with the `.s-popover` class or HTML string containing a single element with the `.s-popover` class.
5518
+ * If the popover does not have a parent element, it will be inserted as a immediately after the reference element.
5519
+ * @param options an optional collection of options to use when configuring the popover.
5520
+ */
5521
+ function attachPopover(element, popover, options) {
5522
+ var _a = getPopover(element), referenceElement = _a.referenceElement, existingPopover = _a.popover;
5523
+ if (existingPopover) {
5524
+ throw "element already has popover with id=\"".concat(existingPopover.id, "\"");
5525
+ }
5526
+ if (!referenceElement) {
5527
+ throw "element has invalid data-s-popover-reference-selector attribute";
5528
+ }
5529
+ if (typeof popover === 'string') {
5530
+ var elements = document.createRange().createContextualFragment(popover).children;
5531
+ if (elements.length !== 1) {
5532
+ throw "popover should contain a single element";
5533
+ }
5534
+ popover = elements[0];
5535
+ }
5536
+ var existingId = referenceElement.getAttribute("aria-controls");
5537
+ var popoverId = popover.id;
5538
+ if (!popover.classList.contains('s-popover')) {
5539
+ throw "popover should have the \"s-popover\" class but had class=\"".concat(popover.className, "\"");
5540
+ }
5541
+ if (existingId && existingId !== popoverId) {
5542
+ throw "element has aria-controls=\"".concat(existingId, "\" but popover has id=\"").concat(popoverId, "\"");
5543
+ }
5544
+ if (!popoverId) {
5545
+ popoverId = "--stacks-s-popover-" + Math.random().toString(36).substring(2, 10);
5546
+ popover.id = popoverId;
5547
+ }
5548
+ if (!existingId) {
5549
+ referenceElement.setAttribute("aria-controls", popoverId);
5550
+ }
5551
+ if (!popover.parentElement && element.parentElement) {
5552
+ referenceElement.insertAdjacentElement("afterend", popover);
5553
+ }
5554
+ toggleController(element, "s-popover", true);
5555
+ if (options) {
5556
+ if (options.toggleOnClick) {
5557
+ referenceElement.setAttribute("data-action", "click->s-popover#toggle");
5558
+ }
5559
+ if (options.placement) {
5560
+ element.setAttribute("data-s-popover-placement", options.placement);
5561
+ }
5562
+ if (options.autoShow) {
5563
+ element.setAttribute("data-s-popover-auto-show", "true");
5564
+ }
5565
+ }
5566
+ }
5567
+ exports.attachPopover = attachPopover;
5568
+ /**
5569
+ * Removes the popover controller from an element and removes the popover from the DOM.
5570
+ * @param element the element that has the `data-controller="s-popover"` attribute.
5571
+ * @returns The popover that was attached to the element.
5572
+ */
5573
+ function detachPopover(element) {
5574
+ var _a = getPopover(element), isPopover = _a.isPopover, controller = _a.controller, referenceElement = _a.referenceElement, popover = _a.popover;
5575
+ // Hide the popover so its events fire.
5576
+ controller === null || controller === void 0 ? void 0 : controller.hide();
5577
+ // Remove the popover if it exists
5578
+ popover === null || popover === void 0 ? void 0 : popover.remove();
5579
+ // Remove the popover controller and the aria-controls attributes.
5580
+ if (isPopover) {
5581
+ toggleController(element, "s-popover", false);
5582
+ if (referenceElement) {
5583
+ referenceElement.removeAttribute("aria-controls");
5584
+ }
5585
+ }
5586
+ return popover;
5587
+ }
5588
+ exports.detachPopover = detachPopover;
5589
+ /**
5590
+ * Gets the current state of an element that may be or is intended to be an s-popover controller
5591
+ * so it can be configured either directly or via the DOM.
5592
+ * @param element An element that may have `data-controller="s-popover"`.
5593
+ */
5594
+ function getPopover(element) {
5595
+ var _a;
5596
+ var isPopover = ((_a = element.getAttribute("data-controller")) === null || _a === void 0 ? void 0 : _a.includes("s-popover")) || false;
5597
+ var controller = Stacks.application.getControllerForElementAndIdentifier(element, "s-popover");
5598
+ var referenceSelector = element.getAttribute("data-s-popover-reference-selector");
5599
+ var referenceElement = referenceSelector ? element.querySelector(referenceSelector) : element;
5600
+ var popoverId = referenceElement ? referenceElement.getAttribute("aria-controls") : null;
5601
+ var popover = popoverId ? document.getElementById(popoverId) : null;
5602
+ return { isPopover: isPopover, controller: controller, referenceElement: referenceElement, popover: popover };
5603
+ }
5604
+ /**
5605
+ * Adds or removes the controller from an element's [data-controller] attribute without altering existing entries
5606
+ * @param el The element to alter
5607
+ * @param controllerName The name of the controller to add/remove
5608
+ * @param include Whether to add the controllerName value
5609
+ */
5610
+ function toggleController(el, controllerName, include) {
5611
+ var _a;
5612
+ var controllers = new Set((_a = el.getAttribute('data-controller')) === null || _a === void 0 ? void 0 : _a.split(/\s+/));
5613
+ if (include) {
5614
+ controllers.add(controllerName);
5615
+ }
5616
+ else {
5617
+ controllers.delete(controllerName);
5618
+ }
5619
+ el.setAttribute('data-controller', Array.from(controllers).join(' '));
5620
+ }
5621
5621
 
5622
5622
 
5623
5623
  /***/ }),
@@ -5625,228 +5625,228 @@ function toggleController(el, controllerName, include) {
5625
5625
  /***/ 753:
5626
5626
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
5627
5627
 
5628
-
5629
- var __extends = (this && this.__extends) || (function () {
5630
- var extendStatics = function (d, b) {
5631
- extendStatics = Object.setPrototypeOf ||
5632
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5633
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
5634
- return extendStatics(d, b);
5635
- };
5636
- return function (d, b) {
5637
- if (typeof b !== "function" && b !== null)
5638
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
5639
- extendStatics(d, b);
5640
- function __() { this.constructor = d; }
5641
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5642
- };
5643
- })();
5644
- Object.defineProperty(exports, "__esModule", ({ value: true }));
5645
- exports.TableController = void 0;
5646
- var Stacks = __webpack_require__(36);
5647
- var TableController = /** @class */ (function (_super) {
5648
- __extends(TableController, _super);
5649
- function TableController() {
5650
- return _super !== null && _super.apply(this, arguments) || this;
5651
- }
5652
- TableController.prototype.setCurrentSort = function (headElem, direction) {
5653
- if (["asc", "desc", "none"].indexOf(direction) < 0) {
5654
- throw "direction must be one of asc, desc, or none";
5655
- }
5656
- var controller = this;
5657
- this.columnTargets.forEach(function (target) {
5658
- var isCurrrent = target === headElem;
5659
- target.classList.toggle("is-sorted", isCurrrent && direction !== "none");
5660
- target.querySelectorAll(".js-sorting-indicator").forEach(function (icon) {
5661
- var visible = isCurrrent ? direction : "none";
5662
- icon.classList.toggle("d-none", !icon.classList.contains("js-sorting-indicator-" + visible));
5663
- });
5664
- if (!isCurrrent || direction === "none") {
5665
- controller.removeElementData(target, "sort-direction");
5666
- }
5667
- else {
5668
- controller.setElementData(target, "sort-direction", direction);
5669
- }
5670
- });
5671
- };
5672
- ;
5673
- TableController.prototype.sort = function (evt) {
5674
- var controller = this;
5675
- var colHead = evt.currentTarget;
5676
- if (!(colHead instanceof HTMLTableCellElement)) {
5677
- throw "invalid event target";
5678
- }
5679
- var table = this.element;
5680
- var tbody = table.tBodies[0];
5681
- // the column slot number of the clicked header
5682
- var colno = getCellSlot(colHead);
5683
- if (colno < 0) { // this shouldn't happen if the clicked element is actually a column head
5684
- return;
5685
- }
5686
- // an index of the <tbody>, so we can find out for each row which <td> element is
5687
- // in the same column slot as the header
5688
- var slotIndex = buildIndex(tbody);
5689
- // the default behavior when clicking a header is to sort by this column in ascending
5690
- // direction, *unless* it is already sorted that way
5691
- var direction = this.getElementData(colHead, "sort-direction") === "asc" ? -1 : 1;
5692
- var rows = Array.from(table.tBodies[0].rows);
5693
- // if this is still false after traversing the data, that means all values are integers (or empty)
5694
- // and thus we'll sort numerically.
5695
- var anyNonInt = false;
5696
- // data will be a list of tuples [value, rowNum], where value is what we're sorting by
5697
- var data = [];
5698
- var firstBottomRow;
5699
- rows.forEach(function (row, index) {
5700
- var force = controller.getElementData(row, "sort-to");
5701
- if (force === "top") {
5702
- return; // rows not added to the list will automatically end up at the top
5703
- }
5704
- else if (force === "bottom") {
5705
- if (!firstBottomRow) {
5706
- firstBottomRow = row;
5707
- }
5708
- return;
5709
- }
5710
- var cell = slotIndex[index][colno];
5711
- if (!cell) {
5712
- data.push(["", index]);
5713
- return;
5714
- }
5715
- // unless the to-be-sorted-by value is explicitly provided on the element via this attribute,
5716
- // the value we're using is the cell's text, trimmed of any whitespace
5717
- var explicit = controller.getElementData(cell, "sort-val");
5718
- var d = typeof explicit === "string" ? explicit : cell.textContent.trim();
5719
- if ((d !== "") && (parseInt(d, 10) + "" !== d)) {
5720
- anyNonInt = true;
5721
- }
5722
- data.push([d, index]);
5723
- });
5724
- // If all values were integers (or empty cells), sort numerically, with empty cells treated as
5725
- // having the lowest possible value (i.e. sorted to the top if ascending, bottom if descending)
5726
- if (!anyNonInt) {
5727
- data.forEach(function (tuple) {
5728
- tuple[0] = tuple[0] === "" ? Number.MIN_VALUE : parseInt(tuple[0], 10);
5729
- });
5730
- }
5731
- // We don't sort an array of <tr>, but instead an arrays of row *numbers*, because this way we
5732
- // can enforce stable sorting, i.e. rows that compare equal are guaranteed to remain in the same
5733
- // order (the JS standard does not gurantee this for sort()).
5734
- data.sort(function (a, b) {
5735
- // first compare the values (a[0])
5736
- if (a[0] > b[0]) {
5737
- return 1 * direction;
5738
- }
5739
- else if (a[0] < b[0]) {
5740
- return -1 * direction;
5741
- }
5742
- else {
5743
- // if the values are equal, compare the row numbers (a[1]) to guarantee stable sorting
5744
- // (note that this comparison is independent of the sorting direction)
5745
- return a[1] > b[1] ? 1 : -1;
5746
- }
5747
- });
5748
- // this is the actual reordering of the table rows
5749
- data.forEach(function (tup) {
5750
- var row = rows[tup[1]];
5751
- row.parentElement.removeChild(row);
5752
- if (firstBottomRow) {
5753
- tbody.insertBefore(row, firstBottomRow);
5754
- }
5755
- else {
5756
- tbody.appendChild(row);
5757
- }
5758
- });
5759
- // update the UI and set the `data-sort-direction` attribute if appropriate, so that the next click
5760
- // will cause sorting in descending direction
5761
- this.setCurrentSort(colHead, direction === 1 ? "asc" : "desc");
5762
- };
5763
- TableController.targets = ["column"];
5764
- return TableController;
5765
- }(Stacks.StacksController));
5766
- exports.TableController = TableController;
5767
- function buildIndex(section) {
5768
- var result = buildIndexOrGetCellSlot(section);
5769
- if (!(result instanceof Array)) {
5770
- throw "shouldn't happen";
5771
- }
5772
- return result;
5773
- }
5774
- function getCellSlot(cell) {
5775
- if (!(cell.parentElement && cell.parentElement.parentElement instanceof HTMLTableSectionElement)) {
5776
- throw "invalid table";
5777
- }
5778
- var result = buildIndexOrGetCellSlot(cell.parentElement.parentElement, cell);
5779
- if (typeof result !== "number") {
5780
- throw "shouldn't happen";
5781
- }
5782
- return result;
5783
- }
5784
- // Just because a <td> is the 4th *child* of its <tr> doesn't mean it belongs to the 4th *column*
5785
- // of the table. Previous cells may have a colspan; cells in previous rows may have a rowspan.
5786
- // Because we need to know which header cells and data cells belong together, we have to 1) find out
5787
- // which column number (or "slot" as we call it here) the header cell has, and 2) for each row find
5788
- // out which <td> cell corresponds to this slot (because those are the rows we're sorting by).
5789
- //
5790
- // That's what the following function does. If the second argument is not given, it returns an index
5791
- // of the table, which is an array of arrays. Each of the sub-arrays corresponds to a table row. The
5792
- // indices of the sub-array correspond to column slots; the values are the actual table cell elements.
5793
- // For example index[4][3] is the <td> or <th> in row 4, column 3 of the table section (<tbody> or <thead>).
5794
- // Note that this element is not necessarily even in the 4th (zero-based) <tr> -- if it has a rowSpan > 1,
5795
- // it may also be in a previous <tr>.
5796
- //
5797
- // If the second argument is given, it's a <td> or <th> that we're trying to find, and the algorithm
5798
- // stops as soon as it has found it and the function returns its slot number.
5799
- function buildIndexOrGetCellSlot(section, findCell) {
5800
- var index = [];
5801
- var curRow = section.children[0];
5802
- // the elements of these two arrays are synchronized; the first array contains table cell elements,
5803
- // the second one contains a number that indicates for how many more rows this elements will
5804
- // exist (i.e. the value is initially one less than the cell's rowspan, and will be decreased for each row)
5805
- var growing = [];
5806
- var growingRowsLeft = [];
5807
- // continue while we have actual <tr>'s left *or* we still have rowspan'ed elements that aren't done
5808
- while (curRow || growingRowsLeft.some(function (e) { return e !== 0; })) {
5809
- var curIndexRow = [];
5810
- index.push(curIndexRow);
5811
- var curSlot = 0;
5812
- if (curRow) {
5813
- for (var curCellInd = 0; curCellInd < curRow.children.length; curCellInd++) {
5814
- while (growingRowsLeft[curSlot]) {
5815
- growingRowsLeft[curSlot]--;
5816
- curIndexRow[curSlot] = growing[curSlot];
5817
- curSlot++;
5818
- }
5819
- var cell = curRow.children[curCellInd];
5820
- if (!(cell instanceof HTMLTableCellElement)) {
5821
- throw "invalid table";
5822
- }
5823
- if (getComputedStyle(cell).display === "none") {
5824
- continue;
5825
- }
5826
- if (cell === findCell) {
5827
- return curSlot;
5828
- }
5829
- var nextFreeSlot = curSlot + cell.colSpan;
5830
- for (; curSlot < nextFreeSlot; curSlot++) {
5831
- growingRowsLeft[curSlot] = cell.rowSpan - 1; // if any of these is already growing, the table is broken -- no guarantees of anything
5832
- growing[curSlot] = cell;
5833
- curIndexRow[curSlot] = cell;
5834
- }
5835
- }
5836
- }
5837
- while (curSlot < growing.length) {
5838
- if (growingRowsLeft[curSlot]) {
5839
- growingRowsLeft[curSlot]--;
5840
- curIndexRow[curSlot] = growing[curSlot];
5841
- }
5842
- curSlot++;
5843
- }
5844
- if (curRow) {
5845
- curRow = curRow.nextElementSibling;
5846
- }
5847
- }
5848
- return findCell ? -1 : index; /* if findCell was given but we end up here, that means it isn't in this section */
5849
- }
5628
+
5629
+ var __extends = (this && this.__extends) || (function () {
5630
+ var extendStatics = function (d, b) {
5631
+ extendStatics = Object.setPrototypeOf ||
5632
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5633
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
5634
+ return extendStatics(d, b);
5635
+ };
5636
+ return function (d, b) {
5637
+ if (typeof b !== "function" && b !== null)
5638
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
5639
+ extendStatics(d, b);
5640
+ function __() { this.constructor = d; }
5641
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5642
+ };
5643
+ })();
5644
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
5645
+ exports.TableController = void 0;
5646
+ var Stacks = __webpack_require__(36);
5647
+ var TableController = /** @class */ (function (_super) {
5648
+ __extends(TableController, _super);
5649
+ function TableController() {
5650
+ return _super !== null && _super.apply(this, arguments) || this;
5651
+ }
5652
+ TableController.prototype.setCurrentSort = function (headElem, direction) {
5653
+ if (["asc", "desc", "none"].indexOf(direction) < 0) {
5654
+ throw "direction must be one of asc, desc, or none";
5655
+ }
5656
+ var controller = this;
5657
+ this.columnTargets.forEach(function (target) {
5658
+ var isCurrrent = target === headElem;
5659
+ target.classList.toggle("is-sorted", isCurrrent && direction !== "none");
5660
+ target.querySelectorAll(".js-sorting-indicator").forEach(function (icon) {
5661
+ var visible = isCurrrent ? direction : "none";
5662
+ icon.classList.toggle("d-none", !icon.classList.contains("js-sorting-indicator-" + visible));
5663
+ });
5664
+ if (!isCurrrent || direction === "none") {
5665
+ controller.removeElementData(target, "sort-direction");
5666
+ }
5667
+ else {
5668
+ controller.setElementData(target, "sort-direction", direction);
5669
+ }
5670
+ });
5671
+ };
5672
+ ;
5673
+ TableController.prototype.sort = function (evt) {
5674
+ var controller = this;
5675
+ var colHead = evt.currentTarget;
5676
+ if (!(colHead instanceof HTMLTableCellElement)) {
5677
+ throw "invalid event target";
5678
+ }
5679
+ var table = this.element;
5680
+ var tbody = table.tBodies[0];
5681
+ // the column slot number of the clicked header
5682
+ var colno = getCellSlot(colHead);
5683
+ if (colno < 0) { // this shouldn't happen if the clicked element is actually a column head
5684
+ return;
5685
+ }
5686
+ // an index of the <tbody>, so we can find out for each row which <td> element is
5687
+ // in the same column slot as the header
5688
+ var slotIndex = buildIndex(tbody);
5689
+ // the default behavior when clicking a header is to sort by this column in ascending
5690
+ // direction, *unless* it is already sorted that way
5691
+ var direction = this.getElementData(colHead, "sort-direction") === "asc" ? -1 : 1;
5692
+ var rows = Array.from(table.tBodies[0].rows);
5693
+ // if this is still false after traversing the data, that means all values are integers (or empty)
5694
+ // and thus we'll sort numerically.
5695
+ var anyNonInt = false;
5696
+ // data will be a list of tuples [value, rowNum], where value is what we're sorting by
5697
+ var data = [];
5698
+ var firstBottomRow;
5699
+ rows.forEach(function (row, index) {
5700
+ var force = controller.getElementData(row, "sort-to");
5701
+ if (force === "top") {
5702
+ return; // rows not added to the list will automatically end up at the top
5703
+ }
5704
+ else if (force === "bottom") {
5705
+ if (!firstBottomRow) {
5706
+ firstBottomRow = row;
5707
+ }
5708
+ return;
5709
+ }
5710
+ var cell = slotIndex[index][colno];
5711
+ if (!cell) {
5712
+ data.push(["", index]);
5713
+ return;
5714
+ }
5715
+ // unless the to-be-sorted-by value is explicitly provided on the element via this attribute,
5716
+ // the value we're using is the cell's text, trimmed of any whitespace
5717
+ var explicit = controller.getElementData(cell, "sort-val");
5718
+ var d = typeof explicit === "string" ? explicit : cell.textContent.trim();
5719
+ if ((d !== "") && (parseInt(d, 10) + "" !== d)) {
5720
+ anyNonInt = true;
5721
+ }
5722
+ data.push([d, index]);
5723
+ });
5724
+ // If all values were integers (or empty cells), sort numerically, with empty cells treated as
5725
+ // having the lowest possible value (i.e. sorted to the top if ascending, bottom if descending)
5726
+ if (!anyNonInt) {
5727
+ data.forEach(function (tuple) {
5728
+ tuple[0] = tuple[0] === "" ? Number.MIN_VALUE : parseInt(tuple[0], 10);
5729
+ });
5730
+ }
5731
+ // We don't sort an array of <tr>, but instead an arrays of row *numbers*, because this way we
5732
+ // can enforce stable sorting, i.e. rows that compare equal are guaranteed to remain in the same
5733
+ // order (the JS standard does not gurantee this for sort()).
5734
+ data.sort(function (a, b) {
5735
+ // first compare the values (a[0])
5736
+ if (a[0] > b[0]) {
5737
+ return 1 * direction;
5738
+ }
5739
+ else if (a[0] < b[0]) {
5740
+ return -1 * direction;
5741
+ }
5742
+ else {
5743
+ // if the values are equal, compare the row numbers (a[1]) to guarantee stable sorting
5744
+ // (note that this comparison is independent of the sorting direction)
5745
+ return a[1] > b[1] ? 1 : -1;
5746
+ }
5747
+ });
5748
+ // this is the actual reordering of the table rows
5749
+ data.forEach(function (tup) {
5750
+ var row = rows[tup[1]];
5751
+ row.parentElement.removeChild(row);
5752
+ if (firstBottomRow) {
5753
+ tbody.insertBefore(row, firstBottomRow);
5754
+ }
5755
+ else {
5756
+ tbody.appendChild(row);
5757
+ }
5758
+ });
5759
+ // update the UI and set the `data-sort-direction` attribute if appropriate, so that the next click
5760
+ // will cause sorting in descending direction
5761
+ this.setCurrentSort(colHead, direction === 1 ? "asc" : "desc");
5762
+ };
5763
+ TableController.targets = ["column"];
5764
+ return TableController;
5765
+ }(Stacks.StacksController));
5766
+ exports.TableController = TableController;
5767
+ function buildIndex(section) {
5768
+ var result = buildIndexOrGetCellSlot(section);
5769
+ if (!(result instanceof Array)) {
5770
+ throw "shouldn't happen";
5771
+ }
5772
+ return result;
5773
+ }
5774
+ function getCellSlot(cell) {
5775
+ if (!(cell.parentElement && cell.parentElement.parentElement instanceof HTMLTableSectionElement)) {
5776
+ throw "invalid table";
5777
+ }
5778
+ var result = buildIndexOrGetCellSlot(cell.parentElement.parentElement, cell);
5779
+ if (typeof result !== "number") {
5780
+ throw "shouldn't happen";
5781
+ }
5782
+ return result;
5783
+ }
5784
+ // Just because a <td> is the 4th *child* of its <tr> doesn't mean it belongs to the 4th *column*
5785
+ // of the table. Previous cells may have a colspan; cells in previous rows may have a rowspan.
5786
+ // Because we need to know which header cells and data cells belong together, we have to 1) find out
5787
+ // which column number (or "slot" as we call it here) the header cell has, and 2) for each row find
5788
+ // out which <td> cell corresponds to this slot (because those are the rows we're sorting by).
5789
+ //
5790
+ // That's what the following function does. If the second argument is not given, it returns an index
5791
+ // of the table, which is an array of arrays. Each of the sub-arrays corresponds to a table row. The
5792
+ // indices of the sub-array correspond to column slots; the values are the actual table cell elements.
5793
+ // For example index[4][3] is the <td> or <th> in row 4, column 3 of the table section (<tbody> or <thead>).
5794
+ // Note that this element is not necessarily even in the 4th (zero-based) <tr> -- if it has a rowSpan > 1,
5795
+ // it may also be in a previous <tr>.
5796
+ //
5797
+ // If the second argument is given, it's a <td> or <th> that we're trying to find, and the algorithm
5798
+ // stops as soon as it has found it and the function returns its slot number.
5799
+ function buildIndexOrGetCellSlot(section, findCell) {
5800
+ var index = [];
5801
+ var curRow = section.children[0];
5802
+ // the elements of these two arrays are synchronized; the first array contains table cell elements,
5803
+ // the second one contains a number that indicates for how many more rows this elements will
5804
+ // exist (i.e. the value is initially one less than the cell's rowspan, and will be decreased for each row)
5805
+ var growing = [];
5806
+ var growingRowsLeft = [];
5807
+ // continue while we have actual <tr>'s left *or* we still have rowspan'ed elements that aren't done
5808
+ while (curRow || growingRowsLeft.some(function (e) { return e !== 0; })) {
5809
+ var curIndexRow = [];
5810
+ index.push(curIndexRow);
5811
+ var curSlot = 0;
5812
+ if (curRow) {
5813
+ for (var curCellInd = 0; curCellInd < curRow.children.length; curCellInd++) {
5814
+ while (growingRowsLeft[curSlot]) {
5815
+ growingRowsLeft[curSlot]--;
5816
+ curIndexRow[curSlot] = growing[curSlot];
5817
+ curSlot++;
5818
+ }
5819
+ var cell = curRow.children[curCellInd];
5820
+ if (!(cell instanceof HTMLTableCellElement)) {
5821
+ throw "invalid table";
5822
+ }
5823
+ if (getComputedStyle(cell).display === "none") {
5824
+ continue;
5825
+ }
5826
+ if (cell === findCell) {
5827
+ return curSlot;
5828
+ }
5829
+ var nextFreeSlot = curSlot + cell.colSpan;
5830
+ for (; curSlot < nextFreeSlot; curSlot++) {
5831
+ growingRowsLeft[curSlot] = cell.rowSpan - 1; // if any of these is already growing, the table is broken -- no guarantees of anything
5832
+ growing[curSlot] = cell;
5833
+ curIndexRow[curSlot] = cell;
5834
+ }
5835
+ }
5836
+ }
5837
+ while (curSlot < growing.length) {
5838
+ if (growingRowsLeft[curSlot]) {
5839
+ growingRowsLeft[curSlot]--;
5840
+ curIndexRow[curSlot] = growing[curSlot];
5841
+ }
5842
+ curSlot++;
5843
+ }
5844
+ if (curRow) {
5845
+ curRow = curRow.nextElementSibling;
5846
+ }
5847
+ }
5848
+ return findCell ? -1 : index; /* if findCell was given but we end up here, that means it isn't in this section */
5849
+ }
5850
5850
 
5851
5851
 
5852
5852
  /***/ }),
@@ -5854,241 +5854,241 @@ function buildIndexOrGetCellSlot(section, findCell) {
5854
5854
  /***/ 355:
5855
5855
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
5856
5856
 
5857
-
5858
- var __extends = (this && this.__extends) || (function () {
5859
- var extendStatics = function (d, b) {
5860
- extendStatics = Object.setPrototypeOf ||
5861
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5862
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
5863
- return extendStatics(d, b);
5864
- };
5865
- return function (d, b) {
5866
- if (typeof b !== "function" && b !== null)
5867
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
5868
- extendStatics(d, b);
5869
- function __() { this.constructor = d; }
5870
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5871
- };
5872
- })();
5873
- Object.defineProperty(exports, "__esModule", ({ value: true }));
5874
- exports.setTooltipText = exports.setTooltipHtml = exports.TooltipController = void 0;
5875
- var Stacks = __webpack_require__(36);
5876
- var s_popover_1 = __webpack_require__(388);
5877
- var TooltipController = /** @class */ (function (_super) {
5878
- __extends(TooltipController, _super);
5879
- function TooltipController() {
5880
- var _this = _super !== null && _super.apply(this, arguments) || this;
5881
- _this.popoverSelectorAttribute = "aria-describedby";
5882
- return _this;
5883
- }
5884
- /**
5885
- * Binds mouseover and mouseout events in addition to BasePopoverController.connect
5886
- */
5887
- TooltipController.prototype.connect = function () {
5888
- _super.prototype.connect.call(this);
5889
- // Only bind to mouse events if the pointer device supports hover behavior.
5890
- // Otherwise we run into issues with mobile browser showing popovers for
5891
- // click events and not being able to hide them.
5892
- if (window.matchMedia("(hover: hover)").matches) {
5893
- this.bindMouseEvents();
5894
- }
5895
- };
5896
- /**
5897
- * Unbinds mouse events in addition to BasePopoverController.disconnect
5898
- */
5899
- TooltipController.prototype.disconnect = function () {
5900
- this.unbindMouseEvents();
5901
- _super.prototype.disconnect.call(this);
5902
- };
5903
- /**
5904
- * Attempts to show the tooltip popover so long as no other Stacks-managed popover is
5905
- * present on the page.
5906
- */
5907
- TooltipController.prototype.show = function (dispatcher) {
5908
- if (dispatcher === void 0) { dispatcher = null; }
5909
- // check and see if this controller coexists with a popover
5910
- var controller = Stacks.application.getControllerForElementAndIdentifier(this.element, "s-popover");
5911
- // if the controller exists and already has a visible popover, don't show the tooltip
5912
- if (controller && controller.isVisible) {
5913
- return;
5914
- }
5915
- _super.prototype.show.call(this, dispatcher);
5916
- };
5917
- /**
5918
- * Sets up a tooltip popover show after a delay.
5919
- */
5920
- TooltipController.prototype.scheduleShow = function (dispatcher) {
5921
- var _this = this;
5922
- if (dispatcher === void 0) { dispatcher = null; }
5923
- window.clearTimeout(this.activeTimeout);
5924
- this.activeTimeout = window.setTimeout(function () { return _this.show(dispatcher); }, 300);
5925
- };
5926
- /**
5927
- * Cancels the scheduled tooltip popover display and hides it if already displayed
5928
- */
5929
- TooltipController.prototype.hide = function (dispatcher) {
5930
- if (dispatcher === void 0) { dispatcher = null; }
5931
- window.clearTimeout(this.activeTimeout);
5932
- this.activeTimeout = null;
5933
- _super.prototype.hide.call(this, dispatcher);
5934
- };
5935
- /**
5936
- * Applies data-s-tooltip-html-title and title attributes.
5937
- */
5938
- TooltipController.prototype.applyTitleAttributes = function () {
5939
- var content;
5940
- var htmlTitle = this.data.get("html-title");
5941
- if (htmlTitle) {
5942
- content = document.createRange().createContextualFragment(htmlTitle);
5943
- }
5944
- else {
5945
- var plainTitle = this.element.getAttribute("title");
5946
- if (plainTitle) {
5947
- content = document.createTextNode(plainTitle);
5948
- }
5949
- else {
5950
- return null;
5951
- }
5952
- }
5953
- this.data.delete("html-title");
5954
- this.element.removeAttribute("title");
5955
- var popoverId = this.element.getAttribute("aria-describedby");
5956
- if (!popoverId) {
5957
- popoverId = TooltipController.generateId();
5958
- this.element.setAttribute("aria-describedby", popoverId);
5959
- }
5960
- var popover = document.getElementById(popoverId);
5961
- if (!popover) {
5962
- popover = document.createElement("div");
5963
- popover.id = popoverId;
5964
- popover.className = "s-popover s-popover__tooltip pe-none";
5965
- popover.setAttribute("aria-hidden", "true");
5966
- popover.setAttribute("role", "tooltip");
5967
- var parentNode = this.element.parentNode;
5968
- if (parentNode) {
5969
- // insertBefore inserts at end if element.nextSibling is null.
5970
- parentNode.insertBefore(popover, this.element.nextSibling);
5971
- }
5972
- else {
5973
- document.body.appendChild(popover);
5974
- }
5975
- }
5976
- var arrow = popover.querySelector(".s-popover--arrow");
5977
- // clear and set the content of the popover
5978
- popover.innerHTML = "";
5979
- popover.appendChild(content);
5980
- // create the arrow if necessary
5981
- if (arrow) {
5982
- popover.appendChild(arrow);
5983
- }
5984
- else {
5985
- popover.insertAdjacentHTML("beforeend", "<div class=\"s-popover--arrow\"></div>");
5986
- }
5987
- this.scheduleUpdate();
5988
- return popover;
5989
- };
5990
- /**
5991
- * Automatically hides the tooltip popover when a Stacks popover is shown anywhere on
5992
- * the page.
5993
- */
5994
- TooltipController.prototype.bindDocumentEvents = function () {
5995
- this.boundHideIfWithin = this.boundHideIfWithin || this.hideIfWithin.bind(this);
5996
- document.addEventListener("s-popover:shown", this.boundHideIfWithin);
5997
- };
5998
- /**
5999
- * Unbinds all mouse events
6000
- */
6001
- TooltipController.prototype.unbindDocumentEvents = function () {
6002
- document.removeEventListener("s-popover:shown", this.boundHideIfWithin);
6003
- };
6004
- /**
6005
- * Attempts to generate a new tooltip popover from the title attribute if no popover
6006
- * was present when requested, otherwise throws an error.
6007
- */
6008
- TooltipController.prototype.generatePopover = function () {
6009
- return this.applyTitleAttributes();
6010
- };
6011
- /**
6012
- * Hides the tooltip if is or is within the event's target.
6013
- * @param event An event object from s-popover:shown
6014
- */
6015
- TooltipController.prototype.hideIfWithin = function (event) {
6016
- if (event.target.contains(this.referenceElement)) {
6017
- this.hide();
6018
- }
6019
- };
6020
- /**
6021
- * Binds mouse events to show/hide on reference element hover
6022
- */
6023
- TooltipController.prototype.bindMouseEvents = function () {
6024
- this.boundScheduleShow = this.boundScheduleShow || this.scheduleShow.bind(this);
6025
- this.boundHide = this.boundHide || this.hide.bind(this);
6026
- this.referenceElement.addEventListener("mouseover", this.boundScheduleShow);
6027
- this.referenceElement.addEventListener("mouseout", this.boundHide);
6028
- this.referenceElement.addEventListener("focus", this.boundScheduleShow);
6029
- this.referenceElement.addEventListener("blur", this.boundHide);
6030
- };
6031
- /**
6032
- * Unbinds all mouse events
6033
- */
6034
- TooltipController.prototype.unbindMouseEvents = function () {
6035
- this.referenceElement.removeEventListener("mouseover", this.boundScheduleShow);
6036
- this.referenceElement.removeEventListener("mouseout", this.boundHide);
6037
- this.referenceElement.removeEventListener("focus", this.boundScheduleShow);
6038
- this.referenceElement.removeEventListener("blur", this.boundHide);
6039
- };
6040
- /**
6041
- * Generates an ID for tooltips created with setTooltip.
6042
- */
6043
- TooltipController.generateId = function () {
6044
- // generate a random number, then convert to a well formatted string
6045
- return "--stacks-s-tooltip-" + Math.random().toString(36).substring(2, 10);
6046
- };
6047
- TooltipController.targets = [];
6048
- return TooltipController;
6049
- }(s_popover_1.BasePopoverController));
6050
- exports.TooltipController = TooltipController;
6051
- /**
6052
- * Adds or updates a Stacks tooltip on a given element, initializing the controller if necessary
6053
- * @param element The element to add a tooltip to.
6054
- * @param html An HTML string to populate the tooltip with.
6055
- * @param options Options for rendering the tooltip.
6056
- */
6057
- function setTooltipHtml(element, html, options) {
6058
- element.setAttribute("data-s-tooltip-html-title", html);
6059
- element.removeAttribute("title");
6060
- applyOptionsAndTitleAttributes(element, options);
6061
- }
6062
- exports.setTooltipHtml = setTooltipHtml;
6063
- /**
6064
- * Adds or updates a Stacks tooltip on a given element, initializing the controller if necessary
6065
- * @param element The element to add a tooltip to.
6066
- * @param text A plain text string to populate the tooltip with.
6067
- * @param options Options for rendering the tooltip.
6068
- */
6069
- function setTooltipText(element, text, options) {
6070
- element.setAttribute("title", text);
6071
- element.removeAttribute("data-s-tooltip-html-title");
6072
- applyOptionsAndTitleAttributes(element, options);
6073
- }
6074
- exports.setTooltipText = setTooltipText;
6075
- /**
6076
- * Shared helper for setTooltip* to initialize and set tooltip content
6077
- * @param element The element to add a tooltip to.
6078
- * @param options Options for rendering the tooltip.
6079
- */
6080
- function applyOptionsAndTitleAttributes(element, options) {
6081
- if (options && options.placement) {
6082
- element.setAttribute("data-s-tooltip-placement", options.placement);
6083
- }
6084
- var controller = Stacks.application.getControllerForElementAndIdentifier(element, "s-tooltip");
6085
- if (controller) {
6086
- controller.applyTitleAttributes();
6087
- }
6088
- else {
6089
- element.setAttribute("data-controller", element.getAttribute("data-controller") + " s-tooltip");
6090
- }
6091
- }
5857
+
5858
+ var __extends = (this && this.__extends) || (function () {
5859
+ var extendStatics = function (d, b) {
5860
+ extendStatics = Object.setPrototypeOf ||
5861
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5862
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
5863
+ return extendStatics(d, b);
5864
+ };
5865
+ return function (d, b) {
5866
+ if (typeof b !== "function" && b !== null)
5867
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
5868
+ extendStatics(d, b);
5869
+ function __() { this.constructor = d; }
5870
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5871
+ };
5872
+ })();
5873
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
5874
+ exports.setTooltipText = exports.setTooltipHtml = exports.TooltipController = void 0;
5875
+ var Stacks = __webpack_require__(36);
5876
+ var s_popover_1 = __webpack_require__(388);
5877
+ var TooltipController = /** @class */ (function (_super) {
5878
+ __extends(TooltipController, _super);
5879
+ function TooltipController() {
5880
+ var _this = _super !== null && _super.apply(this, arguments) || this;
5881
+ _this.popoverSelectorAttribute = "aria-describedby";
5882
+ return _this;
5883
+ }
5884
+ /**
5885
+ * Binds mouseover and mouseout events in addition to BasePopoverController.connect
5886
+ */
5887
+ TooltipController.prototype.connect = function () {
5888
+ _super.prototype.connect.call(this);
5889
+ // Only bind to mouse events if the pointer device supports hover behavior.
5890
+ // Otherwise we run into issues with mobile browser showing popovers for
5891
+ // click events and not being able to hide them.
5892
+ if (window.matchMedia("(hover: hover)").matches) {
5893
+ this.bindMouseEvents();
5894
+ }
5895
+ };
5896
+ /**
5897
+ * Unbinds mouse events in addition to BasePopoverController.disconnect
5898
+ */
5899
+ TooltipController.prototype.disconnect = function () {
5900
+ this.unbindMouseEvents();
5901
+ _super.prototype.disconnect.call(this);
5902
+ };
5903
+ /**
5904
+ * Attempts to show the tooltip popover so long as no other Stacks-managed popover is
5905
+ * present on the page.
5906
+ */
5907
+ TooltipController.prototype.show = function (dispatcher) {
5908
+ if (dispatcher === void 0) { dispatcher = null; }
5909
+ // check and see if this controller coexists with a popover
5910
+ var controller = Stacks.application.getControllerForElementAndIdentifier(this.element, "s-popover");
5911
+ // if the controller exists and already has a visible popover, don't show the tooltip
5912
+ if (controller && controller.isVisible) {
5913
+ return;
5914
+ }
5915
+ _super.prototype.show.call(this, dispatcher);
5916
+ };
5917
+ /**
5918
+ * Sets up a tooltip popover show after a delay.
5919
+ */
5920
+ TooltipController.prototype.scheduleShow = function (dispatcher) {
5921
+ var _this = this;
5922
+ if (dispatcher === void 0) { dispatcher = null; }
5923
+ window.clearTimeout(this.activeTimeout);
5924
+ this.activeTimeout = window.setTimeout(function () { return _this.show(dispatcher); }, 300);
5925
+ };
5926
+ /**
5927
+ * Cancels the scheduled tooltip popover display and hides it if already displayed
5928
+ */
5929
+ TooltipController.prototype.hide = function (dispatcher) {
5930
+ if (dispatcher === void 0) { dispatcher = null; }
5931
+ window.clearTimeout(this.activeTimeout);
5932
+ this.activeTimeout = null;
5933
+ _super.prototype.hide.call(this, dispatcher);
5934
+ };
5935
+ /**
5936
+ * Applies data-s-tooltip-html-title and title attributes.
5937
+ */
5938
+ TooltipController.prototype.applyTitleAttributes = function () {
5939
+ var content;
5940
+ var htmlTitle = this.data.get("html-title");
5941
+ if (htmlTitle) {
5942
+ content = document.createRange().createContextualFragment(htmlTitle);
5943
+ }
5944
+ else {
5945
+ var plainTitle = this.element.getAttribute("title");
5946
+ if (plainTitle) {
5947
+ content = document.createTextNode(plainTitle);
5948
+ }
5949
+ else {
5950
+ return null;
5951
+ }
5952
+ }
5953
+ this.data.delete("html-title");
5954
+ this.element.removeAttribute("title");
5955
+ var popoverId = this.element.getAttribute("aria-describedby");
5956
+ if (!popoverId) {
5957
+ popoverId = TooltipController.generateId();
5958
+ this.element.setAttribute("aria-describedby", popoverId);
5959
+ }
5960
+ var popover = document.getElementById(popoverId);
5961
+ if (!popover) {
5962
+ popover = document.createElement("div");
5963
+ popover.id = popoverId;
5964
+ popover.className = "s-popover s-popover__tooltip pe-none";
5965
+ popover.setAttribute("aria-hidden", "true");
5966
+ popover.setAttribute("role", "tooltip");
5967
+ var parentNode = this.element.parentNode;
5968
+ if (parentNode) {
5969
+ // insertBefore inserts at end if element.nextSibling is null.
5970
+ parentNode.insertBefore(popover, this.element.nextSibling);
5971
+ }
5972
+ else {
5973
+ document.body.appendChild(popover);
5974
+ }
5975
+ }
5976
+ var arrow = popover.querySelector(".s-popover--arrow");
5977
+ // clear and set the content of the popover
5978
+ popover.innerHTML = "";
5979
+ popover.appendChild(content);
5980
+ // create the arrow if necessary
5981
+ if (arrow) {
5982
+ popover.appendChild(arrow);
5983
+ }
5984
+ else {
5985
+ popover.insertAdjacentHTML("beforeend", "<div class=\"s-popover--arrow\"></div>");
5986
+ }
5987
+ this.scheduleUpdate();
5988
+ return popover;
5989
+ };
5990
+ /**
5991
+ * Automatically hides the tooltip popover when a Stacks popover is shown anywhere on
5992
+ * the page.
5993
+ */
5994
+ TooltipController.prototype.bindDocumentEvents = function () {
5995
+ this.boundHideIfWithin = this.boundHideIfWithin || this.hideIfWithin.bind(this);
5996
+ document.addEventListener("s-popover:shown", this.boundHideIfWithin);
5997
+ };
5998
+ /**
5999
+ * Unbinds all mouse events
6000
+ */
6001
+ TooltipController.prototype.unbindDocumentEvents = function () {
6002
+ document.removeEventListener("s-popover:shown", this.boundHideIfWithin);
6003
+ };
6004
+ /**
6005
+ * Attempts to generate a new tooltip popover from the title attribute if no popover
6006
+ * was present when requested, otherwise throws an error.
6007
+ */
6008
+ TooltipController.prototype.generatePopover = function () {
6009
+ return this.applyTitleAttributes();
6010
+ };
6011
+ /**
6012
+ * Hides the tooltip if is or is within the event's target.
6013
+ * @param event An event object from s-popover:shown
6014
+ */
6015
+ TooltipController.prototype.hideIfWithin = function (event) {
6016
+ if (event.target.contains(this.referenceElement)) {
6017
+ this.hide();
6018
+ }
6019
+ };
6020
+ /**
6021
+ * Binds mouse events to show/hide on reference element hover
6022
+ */
6023
+ TooltipController.prototype.bindMouseEvents = function () {
6024
+ this.boundScheduleShow = this.boundScheduleShow || this.scheduleShow.bind(this);
6025
+ this.boundHide = this.boundHide || this.hide.bind(this);
6026
+ this.referenceElement.addEventListener("mouseover", this.boundScheduleShow);
6027
+ this.referenceElement.addEventListener("mouseout", this.boundHide);
6028
+ this.referenceElement.addEventListener("focus", this.boundScheduleShow);
6029
+ this.referenceElement.addEventListener("blur", this.boundHide);
6030
+ };
6031
+ /**
6032
+ * Unbinds all mouse events
6033
+ */
6034
+ TooltipController.prototype.unbindMouseEvents = function () {
6035
+ this.referenceElement.removeEventListener("mouseover", this.boundScheduleShow);
6036
+ this.referenceElement.removeEventListener("mouseout", this.boundHide);
6037
+ this.referenceElement.removeEventListener("focus", this.boundScheduleShow);
6038
+ this.referenceElement.removeEventListener("blur", this.boundHide);
6039
+ };
6040
+ /**
6041
+ * Generates an ID for tooltips created with setTooltip.
6042
+ */
6043
+ TooltipController.generateId = function () {
6044
+ // generate a random number, then convert to a well formatted string
6045
+ return "--stacks-s-tooltip-" + Math.random().toString(36).substring(2, 10);
6046
+ };
6047
+ TooltipController.targets = [];
6048
+ return TooltipController;
6049
+ }(s_popover_1.BasePopoverController));
6050
+ exports.TooltipController = TooltipController;
6051
+ /**
6052
+ * Adds or updates a Stacks tooltip on a given element, initializing the controller if necessary
6053
+ * @param element The element to add a tooltip to.
6054
+ * @param html An HTML string to populate the tooltip with.
6055
+ * @param options Options for rendering the tooltip.
6056
+ */
6057
+ function setTooltipHtml(element, html, options) {
6058
+ element.setAttribute("data-s-tooltip-html-title", html);
6059
+ element.removeAttribute("title");
6060
+ applyOptionsAndTitleAttributes(element, options);
6061
+ }
6062
+ exports.setTooltipHtml = setTooltipHtml;
6063
+ /**
6064
+ * Adds or updates a Stacks tooltip on a given element, initializing the controller if necessary
6065
+ * @param element The element to add a tooltip to.
6066
+ * @param text A plain text string to populate the tooltip with.
6067
+ * @param options Options for rendering the tooltip.
6068
+ */
6069
+ function setTooltipText(element, text, options) {
6070
+ element.setAttribute("title", text);
6071
+ element.removeAttribute("data-s-tooltip-html-title");
6072
+ applyOptionsAndTitleAttributes(element, options);
6073
+ }
6074
+ exports.setTooltipText = setTooltipText;
6075
+ /**
6076
+ * Shared helper for setTooltip* to initialize and set tooltip content
6077
+ * @param element The element to add a tooltip to.
6078
+ * @param options Options for rendering the tooltip.
6079
+ */
6080
+ function applyOptionsAndTitleAttributes(element, options) {
6081
+ if (options && options.placement) {
6082
+ element.setAttribute("data-s-tooltip-placement", options.placement);
6083
+ }
6084
+ var controller = Stacks.application.getControllerForElementAndIdentifier(element, "s-tooltip");
6085
+ if (controller) {
6086
+ controller.applyTitleAttributes();
6087
+ }
6088
+ else {
6089
+ element.setAttribute("data-controller", element.getAttribute("data-controller") + " s-tooltip");
6090
+ }
6091
+ }
6092
6092
 
6093
6093
 
6094
6094
  /***/ }),
@@ -6096,179 +6096,179 @@ function applyOptionsAndTitleAttributes(element, options) {
6096
6096
  /***/ 637:
6097
6097
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
6098
6098
 
6099
-
6100
- var __extends = (this && this.__extends) || (function () {
6101
- var extendStatics = function (d, b) {
6102
- extendStatics = Object.setPrototypeOf ||
6103
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6104
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
6105
- return extendStatics(d, b);
6106
- };
6107
- return function (d, b) {
6108
- if (typeof b !== "function" && b !== null)
6109
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
6110
- extendStatics(d, b);
6111
- function __() { this.constructor = d; }
6112
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
6113
- };
6114
- })();
6115
- Object.defineProperty(exports, "__esModule", ({ value: true }));
6116
- exports.UploaderController = void 0;
6117
- var Stacks = __webpack_require__(36);
6118
- ;
6119
- var UploaderController = /** @class */ (function (_super) {
6120
- __extends(UploaderController, _super);
6121
- function UploaderController() {
6122
- return _super !== null && _super.apply(this, arguments) || this;
6123
- }
6124
- UploaderController.prototype.connect = function () {
6125
- _super.prototype.connect.call(this);
6126
- this.boundDragEnter = this.handleUploaderActive.bind(this, true);
6127
- this.boundDragLeave = this.handleUploaderActive.bind(this, false);
6128
- this.inputTarget.addEventListener("dragenter", this.boundDragEnter);
6129
- this.inputTarget.addEventListener("dragleave", this.boundDragLeave);
6130
- };
6131
- UploaderController.prototype.disconnect = function () {
6132
- this.inputTarget.removeEventListener("dragenter", this.boundDragEnter);
6133
- this.inputTarget.removeEventListener("dragleave", this.boundDragLeave);
6134
- _super.prototype.disconnect.call(this);
6135
- };
6136
- /**
6137
- * Handles rendering the file preview state on input change
6138
- */
6139
- UploaderController.prototype.handleInput = function () {
6140
- var _this = this;
6141
- this.previewsTarget.innerHTML = "";
6142
- if (!this.inputTarget.files) {
6143
- return;
6144
- }
6145
- var count = this.inputTarget.files.length;
6146
- this.getDataURLs(this.inputTarget.files, UploaderController.FILE_DISPLAY_LIMIT)
6147
- .then(function (res) {
6148
- _this.handleVisible(true);
6149
- var hasMultipleFiles = res.length > 1;
6150
- if (hasMultipleFiles) {
6151
- var headingElement = document.createElement("div");
6152
- headingElement.classList.add("s-uploader--previews-heading");
6153
- headingElement.innerText = res.length < count ?
6154
- "Showing ".concat(res.length, " of ").concat(count, " files") : "".concat(count, " items");
6155
- _this.previewsTarget.appendChild(headingElement);
6156
- _this.previewsTarget.classList.add("has-multiple");
6157
- }
6158
- else {
6159
- _this.previewsTarget.classList.remove("has-multiple");
6160
- }
6161
- res.forEach(function (file) { return _this.addFilePreview(file); });
6162
- _this.handleUploaderActive(true);
6163
- });
6164
- };
6165
- /**
6166
- * Resets the Uploader to initial state
6167
- */
6168
- UploaderController.prototype.reset = function () {
6169
- this.inputTarget.value = '';
6170
- this.previewsTarget.innerHTML = "";
6171
- this.handleVisible(false);
6172
- };
6173
- /**
6174
- * Set hide/show and disabled state on elements depending on preview state
6175
- * @param {boolean} shouldPreview - Uploader is entering a preview state
6176
- */
6177
- UploaderController.prototype.handleVisible = function (shouldPreview) {
6178
- var scope = this.targets.scope;
6179
- var hideElements = scope.findAllElements('[data-s-uploader-hide-on-input]');
6180
- var showElements = scope.findAllElements('[data-s-uploader-show-on-input]');
6181
- var enableElements = scope.findAllElements('[data-s-uploader-enable-on-input]');
6182
- if (shouldPreview) {
6183
- hideElements.map(function (el) { return el.classList.add("d-none"); });
6184
- showElements.map(function (el) { return el.classList.remove("d-none"); });
6185
- enableElements.map(function (el) { return el.removeAttribute("disabled"); });
6186
- }
6187
- else {
6188
- hideElements.map(function (el) { return el.classList.remove("d-none"); });
6189
- showElements.map(function (el) { return el.classList.add("d-none"); });
6190
- enableElements.map(function (el) { return el.setAttribute("disabled", "true"); });
6191
- this.handleUploaderActive(false);
6192
- }
6193
- };
6194
- /**
6195
- * Adds a DOM element to preview a selected file
6196
- * @param {FilePreview} file
6197
- */
6198
- UploaderController.prototype.addFilePreview = function (file) {
6199
- if (!file) {
6200
- return;
6201
- }
6202
- var previewElement = document.createElement("div");
6203
- var thumbElement;
6204
- if (file.type.match('image/*') && file.data) {
6205
- thumbElement = document.createElement("img");
6206
- thumbElement.src = file.data.toString();
6207
- thumbElement.alt = file.name;
6208
- }
6209
- else {
6210
- thumbElement = document.createElement("div");
6211
- thumbElement.innerText = file.name;
6212
- }
6213
- thumbElement.classList.add("s-uploader--preview-thumbnail");
6214
- previewElement.appendChild(thumbElement);
6215
- previewElement.classList.add("s-uploader--preview");
6216
- previewElement.setAttribute('data-filename', file.name);
6217
- this.previewsTarget.appendChild(previewElement);
6218
- };
6219
- /**
6220
- * Toggles display and disabled state for select elements on valid input
6221
- * @param {boolean} active - Uploader is in active state (typically on 'dragenter')
6222
- */
6223
- UploaderController.prototype.handleUploaderActive = function (active) {
6224
- this.uploaderTarget.classList.toggle("is-active", active);
6225
- };
6226
- /**
6227
- * Converts the file data into a data URL
6228
- * @param {File} file
6229
- * @returns an object containing a FilePreview object
6230
- */
6231
- UploaderController.prototype.fileToDataURL = function (file) {
6232
- var reader = new FileReader();
6233
- var name = file.name, size = file.size, type = file.type;
6234
- if (size < UploaderController.MAX_FILE_SIZE && type.indexOf("image") > -1) {
6235
- return new Promise(function (resolve, reject) {
6236
- reader.onload = function (evt) {
6237
- var _a;
6238
- var res = (_a = evt === null || evt === void 0 ? void 0 : evt.target) === null || _a === void 0 ? void 0 : _a.result;
6239
- if (res) {
6240
- resolve({ data: res, name: name, type: type });
6241
- }
6242
- else {
6243
- reject();
6244
- }
6245
- };
6246
- reader.readAsDataURL(file);
6247
- });
6248
- }
6249
- else {
6250
- return Promise.resolve({ name: name, type: type });
6251
- }
6252
- };
6253
- /**
6254
- * Gets an array of FilePreviews from a FileList
6255
- * @param {FileList|[]} files
6256
- * @returns an array of FilePreview objects from a FileList
6257
- */
6258
- UploaderController.prototype.getDataURLs = function (files, limit) {
6259
- var _this = this;
6260
- var promises = Array.from(files)
6261
- .slice(0, Math.min(limit, files.length))
6262
- .map(function (f) { return _this.fileToDataURL(f); });
6263
- return Promise.all(promises);
6264
- };
6265
- UploaderController.targets = ["input", "previews", "uploader"];
6266
- UploaderController.FILE_DISPLAY_LIMIT = 10;
6267
- UploaderController.MAX_FILE_SIZE = 1024 * 1024 * 10; // 10 MB
6268
- return UploaderController;
6269
- }(Stacks.StacksController));
6270
- exports.UploaderController = UploaderController;
6271
- ;
6099
+
6100
+ var __extends = (this && this.__extends) || (function () {
6101
+ var extendStatics = function (d, b) {
6102
+ extendStatics = Object.setPrototypeOf ||
6103
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6104
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
6105
+ return extendStatics(d, b);
6106
+ };
6107
+ return function (d, b) {
6108
+ if (typeof b !== "function" && b !== null)
6109
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
6110
+ extendStatics(d, b);
6111
+ function __() { this.constructor = d; }
6112
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
6113
+ };
6114
+ })();
6115
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
6116
+ exports.UploaderController = void 0;
6117
+ var Stacks = __webpack_require__(36);
6118
+ ;
6119
+ var UploaderController = /** @class */ (function (_super) {
6120
+ __extends(UploaderController, _super);
6121
+ function UploaderController() {
6122
+ return _super !== null && _super.apply(this, arguments) || this;
6123
+ }
6124
+ UploaderController.prototype.connect = function () {
6125
+ _super.prototype.connect.call(this);
6126
+ this.boundDragEnter = this.handleUploaderActive.bind(this, true);
6127
+ this.boundDragLeave = this.handleUploaderActive.bind(this, false);
6128
+ this.inputTarget.addEventListener("dragenter", this.boundDragEnter);
6129
+ this.inputTarget.addEventListener("dragleave", this.boundDragLeave);
6130
+ };
6131
+ UploaderController.prototype.disconnect = function () {
6132
+ this.inputTarget.removeEventListener("dragenter", this.boundDragEnter);
6133
+ this.inputTarget.removeEventListener("dragleave", this.boundDragLeave);
6134
+ _super.prototype.disconnect.call(this);
6135
+ };
6136
+ /**
6137
+ * Handles rendering the file preview state on input change
6138
+ */
6139
+ UploaderController.prototype.handleInput = function () {
6140
+ var _this = this;
6141
+ this.previewsTarget.innerHTML = "";
6142
+ if (!this.inputTarget.files) {
6143
+ return;
6144
+ }
6145
+ var count = this.inputTarget.files.length;
6146
+ this.getDataURLs(this.inputTarget.files, UploaderController.FILE_DISPLAY_LIMIT)
6147
+ .then(function (res) {
6148
+ _this.handleVisible(true);
6149
+ var hasMultipleFiles = res.length > 1;
6150
+ if (hasMultipleFiles) {
6151
+ var headingElement = document.createElement("div");
6152
+ headingElement.classList.add("s-uploader--previews-heading");
6153
+ headingElement.innerText = res.length < count ?
6154
+ "Showing ".concat(res.length, " of ").concat(count, " files") : "".concat(count, " items");
6155
+ _this.previewsTarget.appendChild(headingElement);
6156
+ _this.previewsTarget.classList.add("has-multiple");
6157
+ }
6158
+ else {
6159
+ _this.previewsTarget.classList.remove("has-multiple");
6160
+ }
6161
+ res.forEach(function (file) { return _this.addFilePreview(file); });
6162
+ _this.handleUploaderActive(true);
6163
+ });
6164
+ };
6165
+ /**
6166
+ * Resets the Uploader to initial state
6167
+ */
6168
+ UploaderController.prototype.reset = function () {
6169
+ this.inputTarget.value = '';
6170
+ this.previewsTarget.innerHTML = "";
6171
+ this.handleVisible(false);
6172
+ };
6173
+ /**
6174
+ * Set hide/show and disabled state on elements depending on preview state
6175
+ * @param {boolean} shouldPreview - Uploader is entering a preview state
6176
+ */
6177
+ UploaderController.prototype.handleVisible = function (shouldPreview) {
6178
+ var scope = this.targets.scope;
6179
+ var hideElements = scope.findAllElements('[data-s-uploader-hide-on-input]');
6180
+ var showElements = scope.findAllElements('[data-s-uploader-show-on-input]');
6181
+ var enableElements = scope.findAllElements('[data-s-uploader-enable-on-input]');
6182
+ if (shouldPreview) {
6183
+ hideElements.map(function (el) { return el.classList.add("d-none"); });
6184
+ showElements.map(function (el) { return el.classList.remove("d-none"); });
6185
+ enableElements.map(function (el) { return el.removeAttribute("disabled"); });
6186
+ }
6187
+ else {
6188
+ hideElements.map(function (el) { return el.classList.remove("d-none"); });
6189
+ showElements.map(function (el) { return el.classList.add("d-none"); });
6190
+ enableElements.map(function (el) { return el.setAttribute("disabled", "true"); });
6191
+ this.handleUploaderActive(false);
6192
+ }
6193
+ };
6194
+ /**
6195
+ * Adds a DOM element to preview a selected file
6196
+ * @param {FilePreview} file
6197
+ */
6198
+ UploaderController.prototype.addFilePreview = function (file) {
6199
+ if (!file) {
6200
+ return;
6201
+ }
6202
+ var previewElement = document.createElement("div");
6203
+ var thumbElement;
6204
+ if (file.type.match('image/*') && file.data) {
6205
+ thumbElement = document.createElement("img");
6206
+ thumbElement.src = file.data.toString();
6207
+ thumbElement.alt = file.name;
6208
+ }
6209
+ else {
6210
+ thumbElement = document.createElement("div");
6211
+ thumbElement.innerText = file.name;
6212
+ }
6213
+ thumbElement.classList.add("s-uploader--preview-thumbnail");
6214
+ previewElement.appendChild(thumbElement);
6215
+ previewElement.classList.add("s-uploader--preview");
6216
+ previewElement.setAttribute('data-filename', file.name);
6217
+ this.previewsTarget.appendChild(previewElement);
6218
+ };
6219
+ /**
6220
+ * Toggles display and disabled state for select elements on valid input
6221
+ * @param {boolean} active - Uploader is in active state (typically on 'dragenter')
6222
+ */
6223
+ UploaderController.prototype.handleUploaderActive = function (active) {
6224
+ this.uploaderTarget.classList.toggle("is-active", active);
6225
+ };
6226
+ /**
6227
+ * Converts the file data into a data URL
6228
+ * @param {File} file
6229
+ * @returns an object containing a FilePreview object
6230
+ */
6231
+ UploaderController.prototype.fileToDataURL = function (file) {
6232
+ var reader = new FileReader();
6233
+ var name = file.name, size = file.size, type = file.type;
6234
+ if (size < UploaderController.MAX_FILE_SIZE && type.indexOf("image") > -1) {
6235
+ return new Promise(function (resolve, reject) {
6236
+ reader.onload = function (evt) {
6237
+ var _a;
6238
+ var res = (_a = evt === null || evt === void 0 ? void 0 : evt.target) === null || _a === void 0 ? void 0 : _a.result;
6239
+ if (res) {
6240
+ resolve({ data: res, name: name, type: type });
6241
+ }
6242
+ else {
6243
+ reject();
6244
+ }
6245
+ };
6246
+ reader.readAsDataURL(file);
6247
+ });
6248
+ }
6249
+ else {
6250
+ return Promise.resolve({ name: name, type: type });
6251
+ }
6252
+ };
6253
+ /**
6254
+ * Gets an array of FilePreviews from a FileList
6255
+ * @param {FileList|[]} files
6256
+ * @returns an array of FilePreview objects from a FileList
6257
+ */
6258
+ UploaderController.prototype.getDataURLs = function (files, limit) {
6259
+ var _this = this;
6260
+ var promises = Array.from(files)
6261
+ .slice(0, Math.min(limit, files.length))
6262
+ .map(function (f) { return _this.fileToDataURL(f); });
6263
+ return Promise.all(promises);
6264
+ };
6265
+ UploaderController.targets = ["input", "previews", "uploader"];
6266
+ UploaderController.FILE_DISPLAY_LIMIT = 10;
6267
+ UploaderController.MAX_FILE_SIZE = 1024 * 1024 * 10; // 10 MB
6268
+ return UploaderController;
6269
+ }(Stacks.StacksController));
6270
+ exports.UploaderController = UploaderController;
6271
+ ;
6272
6272
 
6273
6273
 
6274
6274
  /***/ }),
@@ -6276,39 +6276,39 @@ exports.UploaderController = UploaderController;
6276
6276
  /***/ 603:
6277
6277
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
6278
6278
 
6279
-
6280
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6281
- if (k2 === undefined) k2 = k;
6282
- var desc = Object.getOwnPropertyDescriptor(m, k);
6283
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6284
- desc = { enumerable: true, get: function() { return m[k]; } };
6285
- }
6286
- Object.defineProperty(o, k2, desc);
6287
- }) : (function(o, m, k, k2) {
6288
- if (k2 === undefined) k2 = k;
6289
- o[k2] = m[k];
6290
- }));
6291
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
6292
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
6293
- };
6294
- Object.defineProperty(exports, "__esModule", ({ value: true }));
6295
- __webpack_require__(708);
6296
- var controllers_1 = __webpack_require__(470);
6297
- var stacks_1 = __webpack_require__(36);
6298
- // register all built-in controllers
6299
- stacks_1.application.register("s-expandable-control", controllers_1.ExpandableController);
6300
- stacks_1.application.register("s-modal", controllers_1.ModalController);
6301
- stacks_1.application.register("s-navigation-tablist", controllers_1.TabListController);
6302
- stacks_1.application.register("s-popover", controllers_1.PopoverController);
6303
- stacks_1.application.register("s-table", controllers_1.TableController);
6304
- stacks_1.application.register("s-tooltip", controllers_1.TooltipController);
6305
- stacks_1.application.register("s-uploader", controllers_1.UploaderController);
6306
- // finalize the application to guard our controller namespace
6307
- stacks_1.StacksApplication.finalize();
6308
- // export all controllers w/ helpers
6309
- __exportStar(__webpack_require__(470), exports);
6310
- // export the entirety of the contents of stacks.ts
6311
- __exportStar(__webpack_require__(36), exports);
6279
+
6280
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6281
+ if (k2 === undefined) k2 = k;
6282
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6283
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6284
+ desc = { enumerable: true, get: function() { return m[k]; } };
6285
+ }
6286
+ Object.defineProperty(o, k2, desc);
6287
+ }) : (function(o, m, k, k2) {
6288
+ if (k2 === undefined) k2 = k;
6289
+ o[k2] = m[k];
6290
+ }));
6291
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
6292
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
6293
+ };
6294
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
6295
+ __webpack_require__(708);
6296
+ var controllers_1 = __webpack_require__(470);
6297
+ var stacks_1 = __webpack_require__(36);
6298
+ // register all built-in controllers
6299
+ stacks_1.application.register("s-expandable-control", controllers_1.ExpandableController);
6300
+ stacks_1.application.register("s-modal", controllers_1.ModalController);
6301
+ stacks_1.application.register("s-navigation-tablist", controllers_1.TabListController);
6302
+ stacks_1.application.register("s-popover", controllers_1.PopoverController);
6303
+ stacks_1.application.register("s-table", controllers_1.TableController);
6304
+ stacks_1.application.register("s-tooltip", controllers_1.TooltipController);
6305
+ stacks_1.application.register("s-uploader", controllers_1.UploaderController);
6306
+ // finalize the application to guard our controller namespace
6307
+ stacks_1.StacksApplication.finalize();
6308
+ // export all controllers w/ helpers
6309
+ __exportStar(__webpack_require__(470), exports);
6310
+ // export the entirety of the contents of stacks.ts
6311
+ __exportStar(__webpack_require__(36), exports);
6312
6312
 
6313
6313
 
6314
6314
  /***/ }),
@@ -6316,135 +6316,135 @@ __exportStar(__webpack_require__(36), exports);
6316
6316
  /***/ 36:
6317
6317
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
6318
6318
 
6319
-
6320
- var __extends = (this && this.__extends) || (function () {
6321
- var extendStatics = function (d, b) {
6322
- extendStatics = Object.setPrototypeOf ||
6323
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6324
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
6325
- return extendStatics(d, b);
6326
- };
6327
- return function (d, b) {
6328
- if (typeof b !== "function" && b !== null)
6329
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
6330
- extendStatics(d, b);
6331
- function __() { this.constructor = d; }
6332
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
6333
- };
6334
- })();
6335
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
6336
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
6337
- if (ar || !(i in from)) {
6338
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
6339
- ar[i] = from[i];
6340
- }
6341
- }
6342
- return to.concat(ar || Array.prototype.slice.call(from));
6343
- };
6344
- Object.defineProperty(exports, "__esModule", ({ value: true }));
6345
- exports.addController = exports.createController = exports.StacksController = exports.application = exports.StacksApplication = void 0;
6346
- var Stimulus = __webpack_require__(931);
6347
- var StacksApplication = /** @class */ (function (_super) {
6348
- __extends(StacksApplication, _super);
6349
- function StacksApplication() {
6350
- return _super !== null && _super.apply(this, arguments) || this;
6351
- }
6352
- StacksApplication.prototype.load = function (head) {
6353
- var rest = [];
6354
- for (var _i = 1; _i < arguments.length; _i++) {
6355
- rest[_i - 1] = arguments[_i];
6356
- }
6357
- var definitions = Array.isArray(head) ? head : __spreadArray([head], rest, true);
6358
- for (var _a = 0, definitions_1 = definitions; _a < definitions_1.length; _a++) {
6359
- var definition = definitions_1[_a];
6360
- var hasPrefix = /^s-/.test(definition.identifier);
6361
- if (StacksApplication._initializing && !hasPrefix) {
6362
- throw "Stacks-created Stimulus controller names must start with \"s-\".";
6363
- }
6364
- if (!StacksApplication._initializing && hasPrefix) {
6365
- throw "The \"s-\" prefix on Stimulus controller names is reserved for Stacks-created controllers.";
6366
- }
6367
- }
6368
- _super.prototype.load.call(this, definitions);
6369
- };
6370
- StacksApplication.start = function (element, schema) {
6371
- var application = new StacksApplication(element, schema);
6372
- application.start();
6373
- return application;
6374
- };
6375
- StacksApplication.finalize = function () {
6376
- StacksApplication._initializing = false;
6377
- };
6378
- StacksApplication._initializing = true;
6379
- return StacksApplication;
6380
- }(Stimulus.Application));
6381
- exports.StacksApplication = StacksApplication;
6382
- exports.application = StacksApplication.start();
6383
- var StacksController = /** @class */ (function (_super) {
6384
- __extends(StacksController, _super);
6385
- function StacksController() {
6386
- return _super !== null && _super.apply(this, arguments) || this;
6387
- }
6388
- StacksController.prototype.getElementData = function (element, key) {
6389
- return element.getAttribute("data-" + this.identifier + "-" + key);
6390
- };
6391
- ;
6392
- StacksController.prototype.setElementData = function (element, key, value) {
6393
- element.setAttribute("data-" + this.identifier + "-" + key, value);
6394
- };
6395
- ;
6396
- StacksController.prototype.removeElementData = function (element, key) {
6397
- element.removeAttribute("data-" + this.identifier + "-" + key);
6398
- };
6399
- ;
6400
- StacksController.prototype.triggerEvent = function (eventName, detail, optionalElement) {
6401
- var namespacedName = this.identifier + ":" + eventName;
6402
- var event;
6403
- try {
6404
- event = new CustomEvent(namespacedName, { bubbles: true, cancelable: true, detail: detail });
6405
- }
6406
- catch (ex) {
6407
- // Internet Explorer
6408
- event = document.createEvent("CustomEvent");
6409
- event.initCustomEvent(namespacedName, true, true, detail);
6410
- }
6411
- (optionalElement || this.element).dispatchEvent(event);
6412
- return event;
6413
- };
6414
- ;
6415
- return StacksController;
6416
- }(Stimulus.Controller));
6417
- exports.StacksController = StacksController;
6418
- function createController(controllerDefinition) {
6419
- var _a;
6420
- var Controller = controllerDefinition.hasOwnProperty("targets")
6421
- ? (_a = /** @class */ (function (_super) {
6422
- __extends(Controller, _super);
6423
- function Controller() {
6424
- return _super !== null && _super.apply(this, arguments) || this;
6425
- }
6426
- return Controller;
6427
- }(StacksController)),
6428
- _a.targets = controllerDefinition.targets,
6429
- _a) : /** @class */ (function (_super) {
6430
- __extends(Controller, _super);
6431
- function Controller() {
6432
- return _super !== null && _super.apply(this, arguments) || this;
6433
- }
6434
- return Controller;
6435
- }(StacksController));
6436
- for (var prop in controllerDefinition) {
6437
- if (prop !== "targets" && controllerDefinition.hasOwnProperty(prop)) {
6438
- Object.defineProperty(Controller.prototype, prop, Object.getOwnPropertyDescriptor(controllerDefinition, prop));
6439
- }
6440
- }
6441
- return Controller;
6442
- }
6443
- exports.createController = createController;
6444
- function addController(name, controller) {
6445
- exports.application.register(name, createController(controller));
6446
- }
6447
- exports.addController = addController;
6319
+
6320
+ var __extends = (this && this.__extends) || (function () {
6321
+ var extendStatics = function (d, b) {
6322
+ extendStatics = Object.setPrototypeOf ||
6323
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6324
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
6325
+ return extendStatics(d, b);
6326
+ };
6327
+ return function (d, b) {
6328
+ if (typeof b !== "function" && b !== null)
6329
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
6330
+ extendStatics(d, b);
6331
+ function __() { this.constructor = d; }
6332
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
6333
+ };
6334
+ })();
6335
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
6336
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
6337
+ if (ar || !(i in from)) {
6338
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
6339
+ ar[i] = from[i];
6340
+ }
6341
+ }
6342
+ return to.concat(ar || Array.prototype.slice.call(from));
6343
+ };
6344
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
6345
+ exports.addController = exports.createController = exports.StacksController = exports.application = exports.StacksApplication = void 0;
6346
+ var Stimulus = __webpack_require__(931);
6347
+ var StacksApplication = /** @class */ (function (_super) {
6348
+ __extends(StacksApplication, _super);
6349
+ function StacksApplication() {
6350
+ return _super !== null && _super.apply(this, arguments) || this;
6351
+ }
6352
+ StacksApplication.prototype.load = function (head) {
6353
+ var rest = [];
6354
+ for (var _i = 1; _i < arguments.length; _i++) {
6355
+ rest[_i - 1] = arguments[_i];
6356
+ }
6357
+ var definitions = Array.isArray(head) ? head : __spreadArray([head], rest, true);
6358
+ for (var _a = 0, definitions_1 = definitions; _a < definitions_1.length; _a++) {
6359
+ var definition = definitions_1[_a];
6360
+ var hasPrefix = /^s-/.test(definition.identifier);
6361
+ if (StacksApplication._initializing && !hasPrefix) {
6362
+ throw "Stacks-created Stimulus controller names must start with \"s-\".";
6363
+ }
6364
+ if (!StacksApplication._initializing && hasPrefix) {
6365
+ throw "The \"s-\" prefix on Stimulus controller names is reserved for Stacks-created controllers.";
6366
+ }
6367
+ }
6368
+ _super.prototype.load.call(this, definitions);
6369
+ };
6370
+ StacksApplication.start = function (element, schema) {
6371
+ var application = new StacksApplication(element, schema);
6372
+ application.start();
6373
+ return application;
6374
+ };
6375
+ StacksApplication.finalize = function () {
6376
+ StacksApplication._initializing = false;
6377
+ };
6378
+ StacksApplication._initializing = true;
6379
+ return StacksApplication;
6380
+ }(Stimulus.Application));
6381
+ exports.StacksApplication = StacksApplication;
6382
+ exports.application = StacksApplication.start();
6383
+ var StacksController = /** @class */ (function (_super) {
6384
+ __extends(StacksController, _super);
6385
+ function StacksController() {
6386
+ return _super !== null && _super.apply(this, arguments) || this;
6387
+ }
6388
+ StacksController.prototype.getElementData = function (element, key) {
6389
+ return element.getAttribute("data-" + this.identifier + "-" + key);
6390
+ };
6391
+ ;
6392
+ StacksController.prototype.setElementData = function (element, key, value) {
6393
+ element.setAttribute("data-" + this.identifier + "-" + key, value);
6394
+ };
6395
+ ;
6396
+ StacksController.prototype.removeElementData = function (element, key) {
6397
+ element.removeAttribute("data-" + this.identifier + "-" + key);
6398
+ };
6399
+ ;
6400
+ StacksController.prototype.triggerEvent = function (eventName, detail, optionalElement) {
6401
+ var namespacedName = this.identifier + ":" + eventName;
6402
+ var event;
6403
+ try {
6404
+ event = new CustomEvent(namespacedName, { bubbles: true, cancelable: true, detail: detail });
6405
+ }
6406
+ catch (ex) {
6407
+ // Internet Explorer
6408
+ event = document.createEvent("CustomEvent");
6409
+ event.initCustomEvent(namespacedName, true, true, detail);
6410
+ }
6411
+ (optionalElement || this.element).dispatchEvent(event);
6412
+ return event;
6413
+ };
6414
+ ;
6415
+ return StacksController;
6416
+ }(Stimulus.Controller));
6417
+ exports.StacksController = StacksController;
6418
+ function createController(controllerDefinition) {
6419
+ var _a;
6420
+ var Controller = controllerDefinition.hasOwnProperty("targets")
6421
+ ? (_a = /** @class */ (function (_super) {
6422
+ __extends(Controller, _super);
6423
+ function Controller() {
6424
+ return _super !== null && _super.apply(this, arguments) || this;
6425
+ }
6426
+ return Controller;
6427
+ }(StacksController)),
6428
+ _a.targets = controllerDefinition.targets,
6429
+ _a) : /** @class */ (function (_super) {
6430
+ __extends(Controller, _super);
6431
+ function Controller() {
6432
+ return _super !== null && _super.apply(this, arguments) || this;
6433
+ }
6434
+ return Controller;
6435
+ }(StacksController));
6436
+ for (var prop in controllerDefinition) {
6437
+ if (prop !== "targets" && controllerDefinition.hasOwnProperty(prop)) {
6438
+ Object.defineProperty(Controller.prototype, prop, Object.getOwnPropertyDescriptor(controllerDefinition, prop));
6439
+ }
6440
+ }
6441
+ return Controller;
6442
+ }
6443
+ exports.createController = createController;
6444
+ function addController(name, controller) {
6445
+ exports.application.register(name, createController(controller));
6446
+ }
6447
+ exports.addController = addController;
6448
6448
 
6449
6449
 
6450
6450
  /***/ })