@stackoverflow/stacks 1.8.0 → 1.9.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 (137) hide show
  1. package/README.md +161 -153
  2. package/dist/{controllers/s-banner.d.ts → components/banner/banner.d.ts} +1 -1
  3. package/dist/{controllers/s-expandable-control.d.ts → components/expandable/expandable.d.ts} +1 -1
  4. package/dist/{controllers/s-modal.d.ts → components/modal/modal.d.ts} +1 -1
  5. package/dist/{controllers/s-navigation-tablist.d.ts → components/navigation/navigation.d.ts} +1 -1
  6. package/dist/{controllers/s-popover.d.ts → components/popover/popover.d.ts} +1 -1
  7. package/dist/{controllers/s-tooltip.d.ts → components/popover/tooltip.d.ts} +1 -1
  8. package/dist/components/table/table.d.ts +30 -0
  9. package/dist/{controllers/s-toast.d.ts → components/toast/toast.d.ts} +1 -1
  10. package/dist/{controllers/s-uploader.d.ts → components/uploader/uploader.d.ts} +1 -1
  11. package/dist/controllers.d.ts +9 -0
  12. package/dist/css/stacks.css +2063 -1994
  13. package/dist/css/stacks.min.css +1 -1
  14. package/dist/index.d.ts +1 -1
  15. package/dist/js/stacks.js +1465 -1436
  16. package/dist/js/stacks.min.js +1 -1
  17. package/lib/{css/atomic/borders.less → atomic/border.less} +397 -379
  18. package/lib/{css/atomic/colors.less → atomic/color.less} +210 -210
  19. package/lib/{css/atomic → atomic}/flex.less +426 -426
  20. package/lib/{css/atomic → atomic}/gap.less +44 -44
  21. package/lib/{css/atomic → atomic}/grid.less +139 -139
  22. package/lib/{css/atomic → atomic}/misc.less +343 -343
  23. package/lib/{css/atomic → atomic}/spacing.less +342 -342
  24. package/lib/{css/atomic → atomic}/typography.less +267 -267
  25. package/lib/{css/atomic → atomic}/width-height.less +194 -194
  26. package/lib/{css/base → base}/body.less +44 -44
  27. package/lib/{css/base → base}/configuration-static.less +61 -61
  28. package/lib/{css/base → base}/fieldset.less +5 -5
  29. package/lib/{css/base/icons.less → base/icon.less} +11 -20
  30. package/lib/{css/base/internals.less → base/internal.less} +220 -220
  31. package/lib/{css/base → base}/reset-meyer.less +64 -64
  32. package/lib/{css/base → base}/reset-normalize.less +449 -449
  33. package/lib/{css/base → base}/reset.less +20 -20
  34. package/lib/components/activity-indicator/activity-indicator.a11y.test.ts +21 -0
  35. package/lib/{css/components → components/activity-indicator}/activity-indicator.less +40 -40
  36. package/lib/components/activity-indicator/activity-indicator.visual.test.ts +23 -0
  37. package/lib/{css/components/anchors.less → components/anchor/anchor.less} +61 -61
  38. package/lib/components/avatar/avatar.a11y.test.ts +36 -0
  39. package/lib/{css/components/avatars.less → components/avatar/avatar.less} +108 -108
  40. package/lib/components/avatar/avatar.visual.test.ts +54 -0
  41. package/lib/components/award-bling/award-bling.a11y.test.ts +17 -0
  42. package/lib/{css/components → components/award-bling}/award-bling.less +31 -31
  43. package/lib/components/award-bling/award-bling.visual.test.ts +26 -0
  44. package/lib/{css/components/badges.less → components/badge/badge.less} +251 -251
  45. package/lib/components/banner/banner.a11y.test.ts +37 -0
  46. package/lib/components/banner/banner.less +51 -0
  47. package/lib/{test/s-banner.test.ts → components/banner/banner.test.ts} +73 -73
  48. package/lib/{ts/controllers/s-banner.ts → components/banner/banner.ts} +149 -149
  49. package/lib/components/banner/banner.visual.test.ts +37 -0
  50. package/lib/components/block-link/block-link.a11y.test.ts +68 -0
  51. package/lib/{css/components → components/block-link}/block-link.less +80 -80
  52. package/lib/components/block-link/block-link.visual.test.ts +61 -0
  53. package/lib/components/breadcrumbs/breadcrumbs.a11y.test.ts +37 -0
  54. package/lib/{css/components → components/breadcrumbs}/breadcrumbs.less +41 -41
  55. package/lib/components/breadcrumbs/breadcrumbs.visual.test.ts +37 -0
  56. package/lib/components/button/button.a11y.test.ts +32 -0
  57. package/lib/{css/components/buttons.less → components/button/button.less} +502 -501
  58. package/lib/components/button/button.visual.test.ts +52 -0
  59. package/lib/{css/components/button-groups.less → components/button-group/button-group.less} +83 -83
  60. package/lib/components/card/card.a11y.test.ts +13 -0
  61. package/lib/{css/components/cards.less → components/card/card.less} +29 -29
  62. package/lib/components/card/card.visual.test.ts +54 -0
  63. package/lib/components/check-control/check-control.less +17 -0
  64. package/lib/components/check-group/check-group.less +19 -0
  65. package/lib/{css/components/checkboxes-radios.less → components/checkbox_radio/checkbox_radio.less} +158 -158
  66. package/lib/{css/components/code-blocks.less → components/code-block/code-block.less} +116 -116
  67. package/lib/{css/components → components/description}/description.less +9 -9
  68. package/lib/{css/components/empty-states.less → components/empty-state/empty-state.less} +16 -16
  69. package/lib/{css/components → components/expandable}/expandable.less +118 -115
  70. package/lib/components/expandable/expandable.test.ts +51 -0
  71. package/lib/{ts/controllers/s-expandable-control.ts → components/expandable/expandable.ts} +238 -238
  72. package/lib/components/input-fill/input-fill.less +35 -0
  73. package/lib/components/input-icon/input-icon.less +45 -0
  74. package/lib/components/input-message/input-message.less +48 -0
  75. package/lib/{css/components/inputs.less → components/input_textarea/input_textarea.less} +166 -297
  76. package/lib/{css/components/labels.less → components/label/label.less} +111 -111
  77. package/lib/{css/components → components/link}/link.less +119 -119
  78. package/lib/{css/components/link-previews.less → components/link-preview/link-preview.less} +139 -139
  79. package/lib/{css/components → components/menu}/menu.less +41 -41
  80. package/lib/{css/components/modals.less → components/modal/modal.less} +113 -113
  81. package/lib/{ts/controllers/s-modal.ts → components/modal/modal.ts} +379 -379
  82. package/lib/{css/components → components/navigation}/navigation.less +134 -134
  83. package/lib/{ts/controllers/s-navigation-tablist.ts → components/navigation/navigation.ts} +128 -128
  84. package/lib/{css/components/notices.less → components/notice/notice.less} +203 -292
  85. package/lib/{css/components/page-titles.less → components/page-title/page-title.less} +51 -51
  86. package/lib/{css/components → components/pagination}/pagination.less +52 -52
  87. package/lib/{css/components/popovers.less → components/popover/popover.less} +148 -147
  88. package/lib/{ts/controllers/s-popover.ts → components/popover/popover.ts} +651 -651
  89. package/lib/{test/s-tooltip.test.ts → components/popover/tooltip.test.ts} +62 -62
  90. package/lib/{ts/controllers/s-tooltip.ts → components/popover/tooltip.ts} +343 -343
  91. package/lib/{test/s-tooltip.visual.test.ts → components/popover/tooltip.visual.test.ts} +31 -31
  92. package/lib/{css/components → components/post-summary}/post-summary.less +415 -415
  93. package/lib/{css/components/progress-bars.less → components/progress-bar/progress-bar.less} +291 -291
  94. package/lib/{css/components → components/prose}/prose.less +452 -452
  95. package/lib/{css/components → components/select}/select.less +148 -148
  96. package/lib/{css/components/sidebar-widgets.less → components/sidebar-widget/sidebar-widget.less} +257 -259
  97. package/lib/{css/components → components/spinner}/spinner.less +103 -103
  98. package/lib/{css/components → components/table}/table.less +307 -297
  99. package/lib/components/table/table.test.ts +366 -0
  100. package/lib/{ts/controllers/s-table.ts → components/table/table.ts} +296 -263
  101. package/lib/components/table-container/table-container.less +4 -0
  102. package/lib/{css/components/tags.less → components/tag/tag.less} +213 -213
  103. package/lib/components/toast/toast.less +35 -0
  104. package/lib/{test/s-toast.test.ts → components/toast/toast.test.ts} +63 -63
  105. package/lib/{ts/controllers/s-toast.ts → components/toast/toast.ts} +357 -357
  106. package/lib/components/toast/toast.visual.test.ts +27 -0
  107. package/lib/{css/components/toggle-switches.less → components/toggle-switch/toggle-switch.less} +110 -110
  108. package/lib/{css/components → components/topbar}/topbar.less +436 -435
  109. package/lib/{css/components → components/uploader}/uploader.less +195 -195
  110. package/lib/{ts/controllers/s-uploader.ts → components/uploader/uploader.ts} +205 -205
  111. package/lib/{css/components/user-cards.less → components/user-card/user-card.less} +129 -129
  112. package/lib/controllers.ts +33 -0
  113. package/lib/{css/exports → exports}/constants-colors.less +1112 -1111
  114. package/lib/{css/exports → exports}/constants-helpers.less +108 -108
  115. package/lib/{css/exports → exports}/constants-type.less +153 -153
  116. package/lib/{css/exports → exports}/exports.less +15 -15
  117. package/lib/{css/exports → exports}/mixins.less +299 -299
  118. package/lib/{ts/index.ts → index.ts} +32 -32
  119. package/lib/{css/input-utils.less → input-utils.less} +44 -44
  120. package/lib/{css/stacks-dynamic.less → stacks-dynamic.less} +24 -25
  121. package/lib/stacks-static.less +93 -0
  122. package/lib/{css/stacks.less → stacks.less} +13 -13
  123. package/lib/{ts/stacks.ts → stacks.ts} +113 -113
  124. package/lib/test/open-wc-testing-patch.d.ts +26 -0
  125. package/lib/test/test-utils.ts +466 -0
  126. package/lib/tsconfig.build.json +4 -0
  127. package/lib/tsconfig.json +16 -13
  128. package/package.json +106 -105
  129. package/dist/controllers/index.d.ts +0 -9
  130. package/dist/controllers/s-table.d.ts +0 -8
  131. package/lib/css/stacks-static.less +0 -87
  132. package/lib/test/s-avatar.a11y.test.ts +0 -77
  133. package/lib/test/s-banner.visual.test.ts +0 -61
  134. package/lib/test/s-btn.a11y.test.ts +0 -123
  135. package/lib/test/s-btn.visual.test.ts +0 -16
  136. package/lib/test/s-toast.visual.test.ts +0 -48
  137. package/lib/ts/controllers/index.ts +0 -17
package/dist/js/stacks.js CHANGED
@@ -2488,7 +2488,7 @@ Controller.values = {};
2488
2488
 
2489
2489
 
2490
2490
 
2491
- ;// CONCATENATED MODULE: ./lib/ts/stacks.ts
2491
+ ;// CONCATENATED MODULE: ./lib/stacks.ts
2492
2492
 
2493
2493
  class StacksApplication extends Application {
2494
2494
  load(head, ...rest) {
@@ -2515,6 +2515,7 @@ class StacksApplication extends Application {
2515
2515
  }
2516
2516
  }
2517
2517
  StacksApplication._initializing = true;
2518
+
2518
2519
  const application = StacksApplication.start();
2519
2520
  class StacksController extends Controller {
2520
2521
  getElementData(element, key) {
@@ -2571,7 +2572,116 @@ function addController(name, controller) {
2571
2572
  application.register(name, createController(controller));
2572
2573
  }
2573
2574
 
2574
- ;// CONCATENATED MODULE: ./lib/ts/controllers/s-expandable-control.ts
2575
+ ;// CONCATENATED MODULE: ./lib/components/banner/banner.ts
2576
+
2577
+ class BannerController extends StacksController {
2578
+ /**
2579
+ * Toggles the visibility of the banner
2580
+ */
2581
+ toggle(dispatcher = null) {
2582
+ this._toggle(undefined, dispatcher);
2583
+ }
2584
+ /**
2585
+ * Shows the banner
2586
+ */
2587
+ show(dispatcher = null) {
2588
+ this._toggle(true, dispatcher);
2589
+ }
2590
+ /**
2591
+ * Hides the banner
2592
+ */
2593
+ hide(dispatcher = null) {
2594
+ this._toggle(false, dispatcher);
2595
+ }
2596
+ /**
2597
+ * Toggles the visibility of the banner element
2598
+ * @param show Optional parameter that force shows/hides the element or toggles it if left undefined
2599
+ */
2600
+ _toggle(show, dispatcher = null) {
2601
+ let toShow = show;
2602
+ const isVisible = this.bannerTarget.getAttribute("aria-hidden") === "false";
2603
+ // if we're letting the class toggle, we need to figure out if the banner is visible manually
2604
+ if (typeof toShow === "undefined") {
2605
+ toShow = !isVisible;
2606
+ }
2607
+ // if the state matches the disired state, return without changing anything
2608
+ if ((toShow && isVisible) || (!toShow && !isVisible)) {
2609
+ return;
2610
+ }
2611
+ const dispatchingElement = this.getDispatcher(dispatcher);
2612
+ // show/hide events trigger before toggling the class
2613
+ const triggeredEvent = this.triggerEvent(toShow ? "show" : "hide", {
2614
+ dispatcher: this.getDispatcher(dispatchingElement),
2615
+ }, this.bannerTarget);
2616
+ // if this pre-show/hide event was prevented, don't attempt to continue changing the banner state
2617
+ if (triggeredEvent.defaultPrevented) {
2618
+ return;
2619
+ }
2620
+ this.bannerTarget.setAttribute("aria-hidden", toShow ? "false" : "true");
2621
+ if (!toShow) {
2622
+ this.removeBannerOnHide();
2623
+ }
2624
+ this.triggerEvent(toShow ? "shown" : "hidden", {
2625
+ dispatcher: dispatchingElement,
2626
+ }, this.bannerTarget);
2627
+ }
2628
+ /**
2629
+ * Remove the element on hide if the `remove-when-hidden` flag is set
2630
+ */
2631
+ removeBannerOnHide() {
2632
+ if (this.data.get("remove-when-hidden") !== "true") {
2633
+ return;
2634
+ }
2635
+ this.bannerTarget.addEventListener("s-banner:hidden", () => {
2636
+ this.element.remove();
2637
+ }, { once: true });
2638
+ }
2639
+ /**
2640
+ * Determines the correct dispatching element from a potential input
2641
+ * @param dispatcher The event or element to get the dispatcher from
2642
+ */
2643
+ getDispatcher(dispatcher = null) {
2644
+ if (dispatcher instanceof Event) {
2645
+ return dispatcher.target;
2646
+ }
2647
+ else if (dispatcher instanceof Element) {
2648
+ return dispatcher;
2649
+ }
2650
+ else {
2651
+ return this.element;
2652
+ }
2653
+ }
2654
+ }
2655
+ BannerController.targets = ["banner"];
2656
+
2657
+ /**
2658
+ * Helper to manually show an s-banner element via external JS
2659
+ * @param element the element the `data-controller="s-banner"` attribute is on
2660
+ */
2661
+ function showBanner(element) {
2662
+ toggleBanner(element, true);
2663
+ }
2664
+ /**
2665
+ * Helper to manually hide an s-banner element via external JS
2666
+ * @param element the element the `data-controller="s-banner"` attribute is on
2667
+ */
2668
+ function hideBanner(element) {
2669
+ toggleBanner(element, false);
2670
+ }
2671
+ /**
2672
+ * Helper to manually show an s-banner element via external JS
2673
+ * @param element the element the `data-controller="s-banner"` attribute is on
2674
+ * @param show whether to force show/hide the banner; toggles the banner if left undefined
2675
+ */
2676
+ function toggleBanner(element, show) {
2677
+ const controller = application.getControllerForElementAndIdentifier(element, "s-banner");
2678
+ if (!controller) {
2679
+ throw "Unable to get s-banner controller from element";
2680
+ }
2681
+ show ? controller.show() : controller.hide();
2682
+ }
2683
+
2684
+ ;// CONCATENATED MODULE: ./lib/components/expandable/expandable.ts
2575
2685
 
2576
2686
  // Radio buttons only trigger a change event when they're *checked*, but not when
2577
2687
  // they're *unchecked*. Therefore, if we have an active `s-expandable-control` in
@@ -2765,7 +2875,7 @@ class ExpandableController extends StacksController {
2765
2875
  }
2766
2876
  }
2767
2877
 
2768
- ;// CONCATENATED MODULE: ./lib/ts/controllers/s-modal.ts
2878
+ ;// CONCATENATED MODULE: ./lib/components/modal/modal.ts
2769
2879
 
2770
2880
  class ModalController extends StacksController {
2771
2881
  connect() {
@@ -3019,6 +3129,7 @@ class ModalController extends StacksController {
3019
3129
  }
3020
3130
  }
3021
3131
  ModalController.targets = ["modal", "initialFocus"];
3132
+
3022
3133
  /**
3023
3134
  * Helper to manually show an s-modal element via external JS
3024
3135
  * @param element the element the `data-controller="s-modal"` attribute is on
@@ -3046,832 +3157,466 @@ function toggleModal(element, show) {
3046
3157
  show ? controller.show() : controller.hide();
3047
3158
  }
3048
3159
 
3049
- ;// CONCATENATED MODULE: ./lib/ts/controllers/s-banner.ts
3160
+ ;// CONCATENATED MODULE: ./lib/components/navigation/navigation.ts
3050
3161
 
3051
- class BannerController extends StacksController {
3052
- /**
3053
- * Toggles the visibility of the banner
3054
- */
3055
- toggle(dispatcher = null) {
3056
- this._toggle(undefined, dispatcher);
3162
+ class TabListController extends StacksController {
3163
+ connect() {
3164
+ super.connect();
3165
+ this.boundSelectTab = this.selectTab.bind(this);
3166
+ this.boundHandleKeydown = this.handleKeydown.bind(this);
3167
+ for (const tab of this.tabTargets) {
3168
+ tab.addEventListener("click", this.boundSelectTab);
3169
+ tab.addEventListener("keydown", this.boundHandleKeydown);
3170
+ }
3171
+ }
3172
+ disconnect() {
3173
+ super.disconnect();
3174
+ for (const tab of this.tabTargets) {
3175
+ tab.removeEventListener("click", this.boundSelectTab);
3176
+ tab.removeEventListener("keydown", this.boundHandleKeydown);
3177
+ }
3057
3178
  }
3058
3179
  /**
3059
- * Shows the banner
3180
+ * Gets all tabs within the controller.
3060
3181
  */
3061
- show(dispatcher = null) {
3062
- this._toggle(true, dispatcher);
3182
+ get tabTargets() {
3183
+ return Array.from(this.element.querySelectorAll("[role=tab]"));
3063
3184
  }
3064
3185
  /**
3065
- * Hides the banner
3186
+ * Handles click events on individual tabs, causing them to be selected.
3066
3187
  */
3067
- hide(dispatcher = null) {
3068
- this._toggle(false, dispatcher);
3188
+ selectTab(event) {
3189
+ this.switchToTab(event.currentTarget);
3069
3190
  }
3070
3191
  /**
3071
- * Toggles the visibility of the banner element
3072
- * @param show Optional parameter that force shows/hides the element or toggles it if left undefined
3192
+ * Handles left and right arrow keydown events on individual tabs,
3193
+ * selecting the adjacent tab corresponding to the event.
3073
3194
  */
3074
- _toggle(show, dispatcher = null) {
3075
- let toShow = show;
3076
- const isVisible = this.bannerTarget.getAttribute("aria-hidden") === "false";
3077
- // if we're letting the class toggle, we need to figure out if the banner is visible manually
3078
- if (typeof toShow === "undefined") {
3079
- toShow = !isVisible;
3195
+ handleKeydown(event) {
3196
+ var _a;
3197
+ let tabElement = event.currentTarget;
3198
+ const tabs = this.tabTargets;
3199
+ let tabIndex = tabs.indexOf(tabElement);
3200
+ if (event.key === "ArrowRight") {
3201
+ tabIndex++;
3080
3202
  }
3081
- // if the state matches the disired state, return without changing anything
3082
- if ((toShow && isVisible) || (!toShow && !isVisible)) {
3083
- return;
3203
+ else if (event.key === "ArrowLeft") {
3204
+ tabIndex--;
3084
3205
  }
3085
- const dispatchingElement = this.getDispatcher(dispatcher);
3086
- // show/hide events trigger before toggling the class
3087
- const triggeredEvent = this.triggerEvent(toShow ? "show" : "hide", {
3088
- dispatcher: this.getDispatcher(dispatchingElement),
3089
- }, this.bannerTarget);
3090
- // if this pre-show/hide event was prevented, don't attempt to continue changing the banner state
3091
- if (triggeredEvent.defaultPrevented) {
3206
+ else {
3092
3207
  return;
3093
3208
  }
3094
- this.bannerTarget.setAttribute("aria-hidden", toShow ? "false" : "true");
3095
- if (!toShow) {
3096
- this.removeBannerOnHide();
3209
+ // Use circular navigation when users go past the first or last tab.
3210
+ if (tabIndex < 0) {
3211
+ tabIndex = tabs.length - 1;
3097
3212
  }
3098
- this.triggerEvent(toShow ? "shown" : "hidden", {
3099
- dispatcher: dispatchingElement,
3100
- }, this.bannerTarget);
3213
+ if (tabIndex >= tabs.length) {
3214
+ tabIndex = 0;
3215
+ }
3216
+ tabElement = tabs[tabIndex];
3217
+ this.switchToTab(tabElement);
3218
+ // Focus the newly selected tab so it can receive keyboard events.
3219
+ (_a = this.selectedTab) === null || _a === void 0 ? void 0 : _a.focus();
3101
3220
  }
3102
3221
  /**
3103
- * Remove the element on hide if the `remove-when-hidden` flag is set
3222
+ * Attempts to switch to a new tab, doing nothing if the tab is already selected or
3223
+ * the s-navigation-tablist:select event is prevented.
3104
3224
  */
3105
- removeBannerOnHide() {
3106
- if (this.data.get("remove-when-hidden") !== "true") {
3225
+ switchToTab(newTab) {
3226
+ const oldTab = this.selectedTab;
3227
+ if (oldTab === newTab) {
3107
3228
  return;
3108
3229
  }
3109
- this.bannerTarget.addEventListener("s-banner:hidden", () => {
3110
- this.element.remove();
3111
- }, { once: true });
3230
+ if (this.triggerEvent("select", { oldTab, newTab }).defaultPrevented) {
3231
+ return;
3232
+ }
3233
+ this.selectedTab = newTab;
3234
+ this.triggerEvent("selected", { oldTab, newTab });
3112
3235
  }
3113
3236
  /**
3114
- * Determines the correct dispatching element from a potential input
3115
- * @param dispatcher The event or element to get the dispatcher from
3237
+ * Returns the currently selected tab or null if no tabs are selected.
3116
3238
  */
3117
- getDispatcher(dispatcher = null) {
3118
- if (dispatcher instanceof Event) {
3119
- return dispatcher.target;
3120
- }
3121
- else if (dispatcher instanceof Element) {
3122
- return dispatcher;
3123
- }
3124
- else {
3125
- return this.element;
3239
+ get selectedTab() {
3240
+ return (this.tabTargets.find((e) => e.getAttribute("aria-selected") === "true") || null);
3241
+ }
3242
+ /**
3243
+ * Switches the tablist to the provided tab, updating the tabs and panels
3244
+ * to reflect the change.
3245
+ * @param selectedTab The tab to select. If `null` is provided or the element
3246
+ * is not a valid tab, all tabs will be unselected.
3247
+ */
3248
+ set selectedTab(selectedTab) {
3249
+ for (const tab of this.tabTargets) {
3250
+ const panelId = tab.getAttribute("aria-controls");
3251
+ const panel = panelId ? document.getElementById(panelId) : null;
3252
+ if (tab === selectedTab) {
3253
+ tab.classList.add("is-selected");
3254
+ tab.setAttribute("aria-selected", "true");
3255
+ tab.removeAttribute("tabindex");
3256
+ panel === null || panel === void 0 ? void 0 : panel.classList.remove("d-none");
3257
+ }
3258
+ else {
3259
+ tab.classList.remove("is-selected");
3260
+ tab.setAttribute("aria-selected", "false");
3261
+ tab.setAttribute("tabindex", "-1");
3262
+ panel === null || panel === void 0 ? void 0 : panel.classList.add("d-none");
3263
+ }
3126
3264
  }
3127
3265
  }
3128
3266
  }
3129
- BannerController.targets = ["banner"];
3130
- /**
3131
- * Helper to manually show an s-banner element via external JS
3132
- * @param element the element the `data-controller="s-banner"` attribute is on
3133
- */
3134
- function showBanner(element) {
3135
- toggleBanner(element, true);
3136
- }
3137
- /**
3138
- * Helper to manually hide an s-banner element via external JS
3139
- * @param element the element the `data-controller="s-banner"` attribute is on
3140
- */
3141
- function hideBanner(element) {
3142
- toggleBanner(element, false);
3267
+
3268
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getWindow.js
3269
+ function getWindow(node) {
3270
+ if (node == null) {
3271
+ return window;
3272
+ }
3273
+
3274
+ if (node.toString() !== '[object Window]') {
3275
+ var ownerDocument = node.ownerDocument;
3276
+ return ownerDocument ? ownerDocument.defaultView || window : window;
3277
+ }
3278
+
3279
+ return node;
3143
3280
  }
3144
- /**
3145
- * Helper to manually show an s-banner element via external JS
3146
- * @param element the element the `data-controller="s-banner"` attribute is on
3147
- * @param show whether to force show/hide the banner; toggles the banner if left undefined
3148
- */
3149
- function toggleBanner(element, show) {
3150
- const controller = application.getControllerForElementAndIdentifier(element, "s-banner");
3151
- if (!controller) {
3152
- throw "Unable to get s-banner controller from element";
3153
- }
3154
- show ? controller.show() : controller.hide();
3281
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/instanceOf.js
3282
+
3283
+
3284
+ function isElement(node) {
3285
+ var OwnElement = getWindow(node).Element;
3286
+ return node instanceof OwnElement || node instanceof Element;
3287
+ }
3288
+
3289
+ function isHTMLElement(node) {
3290
+ var OwnElement = getWindow(node).HTMLElement;
3291
+ return node instanceof OwnElement || node instanceof HTMLElement;
3155
3292
  }
3156
3293
 
3157
- ;// CONCATENATED MODULE: ./lib/ts/controllers/s-toast.ts
3294
+ function isShadowRoot(node) {
3295
+ // IE 11 has no ShadowRoot
3296
+ if (typeof ShadowRoot === 'undefined') {
3297
+ return false;
3298
+ }
3158
3299
 
3159
- class ToastController extends StacksController {
3160
- connect() {
3161
- this.validate();
3162
- }
3163
- /**
3164
- * Disconnects all added event listeners on controller disconnect
3165
- */
3166
- disconnect() {
3167
- this.unbindDocumentEvents();
3168
- }
3169
- /**
3170
- * Toggles the visibility of the toast
3171
- */
3172
- toggle(dispatcher = null) {
3173
- this._toggle(undefined, dispatcher);
3174
- }
3175
- /**
3176
- * Shows the toast
3177
- */
3178
- show(dispatcher = null) {
3179
- this._toggle(true, dispatcher);
3300
+ var OwnElement = getWindow(node).ShadowRoot;
3301
+ return node instanceof OwnElement || node instanceof ShadowRoot;
3302
+ }
3303
+
3304
+
3305
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/utils/math.js
3306
+ var math_max = Math.max;
3307
+ var math_min = Math.min;
3308
+ var round = Math.round;
3309
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/utils/userAgent.js
3310
+ function getUAString() {
3311
+ var uaData = navigator.userAgentData;
3312
+
3313
+ if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) {
3314
+ return uaData.brands.map(function (item) {
3315
+ return item.brand + "/" + item.version;
3316
+ }).join(' ');
3317
+ }
3318
+
3319
+ return navigator.userAgent;
3320
+ }
3321
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js
3322
+
3323
+ function isLayoutViewport() {
3324
+ return !/^((?!chrome|android).)*safari/i.test(getUAString());
3325
+ }
3326
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js
3327
+
3328
+
3329
+
3330
+
3331
+ function getBoundingClientRect(element, includeScale, isFixedStrategy) {
3332
+ if (includeScale === void 0) {
3333
+ includeScale = false;
3334
+ }
3335
+
3336
+ if (isFixedStrategy === void 0) {
3337
+ isFixedStrategy = false;
3338
+ }
3339
+
3340
+ var clientRect = element.getBoundingClientRect();
3341
+ var scaleX = 1;
3342
+ var scaleY = 1;
3343
+
3344
+ if (includeScale && isHTMLElement(element)) {
3345
+ scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;
3346
+ scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;
3347
+ }
3348
+
3349
+ var _ref = isElement(element) ? getWindow(element) : window,
3350
+ visualViewport = _ref.visualViewport;
3351
+
3352
+ var addVisualOffsets = !isLayoutViewport() && isFixedStrategy;
3353
+ var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX;
3354
+ var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY;
3355
+ var width = clientRect.width / scaleX;
3356
+ var height = clientRect.height / scaleY;
3357
+ return {
3358
+ width: width,
3359
+ height: height,
3360
+ top: y,
3361
+ right: x + width,
3362
+ bottom: y + height,
3363
+ left: x,
3364
+ x: x,
3365
+ y: y
3366
+ };
3367
+ }
3368
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js
3369
+
3370
+ function getWindowScroll(node) {
3371
+ var win = getWindow(node);
3372
+ var scrollLeft = win.pageXOffset;
3373
+ var scrollTop = win.pageYOffset;
3374
+ return {
3375
+ scrollLeft: scrollLeft,
3376
+ scrollTop: scrollTop
3377
+ };
3378
+ }
3379
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js
3380
+ function getHTMLElementScroll(element) {
3381
+ return {
3382
+ scrollLeft: element.scrollLeft,
3383
+ scrollTop: element.scrollTop
3384
+ };
3385
+ }
3386
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js
3387
+
3388
+
3389
+
3390
+
3391
+ function getNodeScroll(node) {
3392
+ if (node === getWindow(node) || !isHTMLElement(node)) {
3393
+ return getWindowScroll(node);
3394
+ } else {
3395
+ return getHTMLElementScroll(node);
3396
+ }
3397
+ }
3398
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getNodeName.js
3399
+ function getNodeName(element) {
3400
+ return element ? (element.nodeName || '').toLowerCase() : null;
3401
+ }
3402
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js
3403
+
3404
+ function getDocumentElement(element) {
3405
+ // $FlowFixMe[incompatible-return]: assume body is always available
3406
+ return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing]
3407
+ element.document) || window.document).documentElement;
3408
+ }
3409
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js
3410
+
3411
+
3412
+
3413
+ function getWindowScrollBarX(element) {
3414
+ // If <html> has a CSS width greater than the viewport, then this will be
3415
+ // incorrect for RTL.
3416
+ // Popper 1 is broken in this case and never had a bug report so let's assume
3417
+ // it's not an issue. I don't think anyone ever specifies width on <html>
3418
+ // anyway.
3419
+ // Browsers where the left scrollbar doesn't cause an issue report `0` for
3420
+ // this (e.g. Edge 2019, IE11, Safari)
3421
+ return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;
3422
+ }
3423
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js
3424
+
3425
+ function getComputedStyle_getComputedStyle(element) {
3426
+ return getWindow(element).getComputedStyle(element);
3427
+ }
3428
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js
3429
+
3430
+ function isScrollParent(element) {
3431
+ // Firefox wants us to check `-x` and `-y` variations as well
3432
+ var _getComputedStyle = getComputedStyle_getComputedStyle(element),
3433
+ overflow = _getComputedStyle.overflow,
3434
+ overflowX = _getComputedStyle.overflowX,
3435
+ overflowY = _getComputedStyle.overflowY;
3436
+
3437
+ return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);
3438
+ }
3439
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js
3440
+
3441
+
3442
+
3443
+
3444
+
3445
+
3446
+
3447
+
3448
+
3449
+ function isElementScaled(element) {
3450
+ var rect = element.getBoundingClientRect();
3451
+ var scaleX = round(rect.width) / element.offsetWidth || 1;
3452
+ var scaleY = round(rect.height) / element.offsetHeight || 1;
3453
+ return scaleX !== 1 || scaleY !== 1;
3454
+ } // Returns the composite rect of an element relative to its offsetParent.
3455
+ // Composite means it takes into account transforms as well as layout.
3456
+
3457
+
3458
+ function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {
3459
+ if (isFixed === void 0) {
3460
+ isFixed = false;
3461
+ }
3462
+
3463
+ var isOffsetParentAnElement = isHTMLElement(offsetParent);
3464
+ var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);
3465
+ var documentElement = getDocumentElement(offsetParent);
3466
+ var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed);
3467
+ var scroll = {
3468
+ scrollLeft: 0,
3469
+ scrollTop: 0
3470
+ };
3471
+ var offsets = {
3472
+ x: 0,
3473
+ y: 0
3474
+ };
3475
+
3476
+ if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
3477
+ if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078
3478
+ isScrollParent(documentElement)) {
3479
+ scroll = getNodeScroll(offsetParent);
3180
3480
  }
3181
- /**
3182
- * Hides the toast
3183
- */
3184
- hide(dispatcher = null) {
3185
- this._toggle(false, dispatcher);
3481
+
3482
+ if (isHTMLElement(offsetParent)) {
3483
+ offsets = getBoundingClientRect(offsetParent, true);
3484
+ offsets.x += offsetParent.clientLeft;
3485
+ offsets.y += offsetParent.clientTop;
3486
+ } else if (documentElement) {
3487
+ offsets.x = getWindowScrollBarX(documentElement);
3186
3488
  }
3187
- /**
3188
- * Validates the toast settings and attempts to set necessary internal variables
3189
- */
3190
- validate() {
3191
- // check for returnElement support
3192
- const returnElementSelector = this.data.get("return-element");
3193
- if (returnElementSelector) {
3194
- this.returnElement = (document.querySelector(returnElementSelector));
3195
- if (!this.returnElement) {
3196
- throw ("Unable to find element by return-element selector: " +
3197
- returnElementSelector);
3198
- }
3199
- }
3200
- }
3201
- /**
3202
- * Toggles the visibility of the toast element
3203
- * @param show Optional parameter that force shows/hides the element or toggles it if left undefined
3204
- */
3205
- _toggle(show, dispatcher = null) {
3206
- let toShow = show;
3207
- const isVisible = this.toastTarget.getAttribute("aria-hidden") === "false";
3208
- // if we're letting the class toggle, we need to figure out if the toast is visible manually
3209
- if (typeof toShow === "undefined") {
3210
- toShow = !isVisible;
3211
- }
3212
- // if the state matches the disired state, return without changing anything
3213
- if ((toShow && isVisible) || (!toShow && !isVisible)) {
3214
- return;
3215
- }
3216
- const dispatchingElement = this.getDispatcher(dispatcher);
3217
- // show/hide events trigger before toggling the class
3218
- const triggeredEvent = this.triggerEvent(toShow ? "show" : "hide", {
3219
- returnElement: this.returnElement,
3220
- dispatcher: this.getDispatcher(dispatchingElement),
3221
- }, this.toastTarget);
3222
- // if this pre-show/hide event was prevented, don't attempt to continue changing the toast state
3223
- if (triggeredEvent.defaultPrevented) {
3224
- return;
3225
- }
3226
- this.returnElement = triggeredEvent.detail.returnElement;
3227
- this.toastTarget.setAttribute("aria-hidden", toShow ? "false" : "true");
3228
- if (toShow) {
3229
- this.bindDocumentEvents();
3230
- this.hideAfterTimeout();
3231
- if (this.data.get("prevent-focus-capture") !== "true") {
3232
- this.focusInsideToast();
3233
- }
3234
- }
3235
- else {
3236
- this.unbindDocumentEvents();
3237
- this.focusReturnElement();
3238
- this.removeToastOnHide();
3239
- this.clearActiveTimeout();
3240
- }
3241
- // check for transitionend support
3242
- const supportsTransitionEnd = this.toastTarget.ontransitionend !== undefined;
3243
- // shown/hidden events trigger after toggling the class
3244
- if (supportsTransitionEnd) {
3245
- // wait until after the toast finishes transitioning to fire the event
3246
- this.toastTarget.addEventListener("transitionend", () => {
3247
- //TODO this is firing waaay to soon?
3248
- this.triggerEvent(toShow ? "shown" : "hidden", {
3249
- dispatcher: dispatchingElement,
3250
- }, this.toastTarget);
3251
- }, { once: true });
3252
- }
3253
- else {
3254
- this.triggerEvent(toShow ? "shown" : "hidden", {
3255
- dispatcher: dispatchingElement,
3256
- }, this.toastTarget);
3257
- }
3258
- }
3259
- /**
3260
- * Listens for the s-toast:hidden event and focuses the returnElement when it is fired
3261
- */
3262
- focusReturnElement() {
3263
- if (!this.returnElement) {
3264
- return;
3265
- }
3266
- this.toastTarget.addEventListener("s-toast:hidden", () => {
3267
- // double check the element still exists when the event is called
3268
- if (this.returnElement &&
3269
- document.body.contains(this.returnElement)) {
3270
- this.returnElement.focus();
3271
- }
3272
- }, { once: true });
3273
- }
3274
- /**
3275
- * Remove the element on hide if the `remove-when-hidden` flag is set
3276
- */
3277
- removeToastOnHide() {
3278
- if (this.data.get("remove-when-hidden") !== "true") {
3279
- return;
3280
- }
3281
- this.toastTarget.addEventListener("s-toast:hidden", () => {
3282
- this.element.remove();
3283
- }, { once: true });
3284
- }
3285
- /**
3286
- * Hide the element after a delay
3287
- */
3288
- hideAfterTimeout() {
3289
- if (this.data.get("prevent-auto-hide") === "true" ||
3290
- this.data.get("hide-after-timeout") === "0") {
3291
- return;
3292
- }
3293
- const timeout = parseInt(this.data.get("hide-after-timeout"), 10) || 3000;
3294
- this.activeTimeout = window.setTimeout(() => this.hide(), timeout);
3295
- }
3296
- /**
3297
- * Cancels the activeTimeout
3298
- */
3299
- clearActiveTimeout() {
3300
- clearTimeout(this.activeTimeout);
3301
- }
3302
- /**
3303
- * Gets all elements within the toast that could receive keyboard focus.
3304
- */
3305
- getAllTabbables() {
3306
- return Array.from(this.toastTarget.querySelectorAll("[href], input, select, textarea, button, [tabindex]")).filter((el) => el.matches(":not([disabled]):not([tabindex='-1'])"));
3307
- }
3308
- /**
3309
- * Returns the first visible element in an array or `undefined` if no elements are visible.
3310
- */
3311
- firstVisible(elements) {
3312
- // https://stackoverflow.com/a/21696585
3313
- return elements === null || elements === void 0 ? void 0 : elements.find((el) => el.offsetParent !== null);
3314
- }
3315
- /**
3316
- * Attempts to shift keyboard focus into the toast.
3317
- * If elements with `data-s-toast-target="initialFocus"` are present and visible, one of those will be selected.
3318
- * Otherwise, the first visible focusable element will receive focus.
3319
- */
3320
- focusInsideToast() {
3321
- this.toastTarget.addEventListener("s-toast:shown", () => {
3322
- var _a;
3323
- const initialFocus = (_a = this.firstVisible(this.initialFocusTargets)) !== null && _a !== void 0 ? _a : this.firstVisible(this.getAllTabbables());
3324
- initialFocus === null || initialFocus === void 0 ? void 0 : initialFocus.focus();
3325
- }, { once: true });
3326
- }
3327
- /**
3328
- * Binds global events to the document for hiding toasts on user interaction
3329
- */
3330
- bindDocumentEvents() {
3331
- // in order for removeEventListener to remove the right event, this bound function needs a constant reference
3332
- this._boundClickFn =
3333
- this._boundClickFn || this.hideOnOutsideClick.bind(this);
3334
- this._boundKeypressFn =
3335
- this._boundKeypressFn || this.hideOnEscapePress.bind(this);
3336
- document.addEventListener("mousedown", this._boundClickFn);
3337
- document.addEventListener("keyup", this._boundKeypressFn);
3338
- }
3339
- /**
3340
- * Unbinds global events to the document for hiding toasts on user interaction
3341
- */
3342
- unbindDocumentEvents() {
3343
- document.removeEventListener("mousedown", this._boundClickFn);
3344
- document.removeEventListener("keyup", this._boundKeypressFn);
3345
- }
3346
- /**
3347
- * Forces the toast to hide if a user clicks outside of it or its reference element
3348
- */
3349
- hideOnOutsideClick(e) {
3350
- var _a;
3351
- const target = e.target;
3352
- // check if the document was clicked inside either the toggle element or the toast itself
3353
- // note: .contains also returns true if the node itself matches the target element
3354
- if (!((_a = this.toastTarget) === null || _a === void 0 ? void 0 : _a.contains(target)) &&
3355
- document.body.contains(target) &&
3356
- this.data.get("hide-on-outside-click") !== "false") {
3357
- this._toggle(false, e);
3358
- }
3359
- }
3360
- /**
3361
- * Forces the toast to hide if the user presses escape while it, one of its childen, or the reference element are focused
3362
- */
3363
- hideOnEscapePress(e) {
3364
- // if the ESC key (27) wasn't pressed or if no toasts are showing, return
3365
- if (e.which !== 27 ||
3366
- this.toastTarget.getAttribute("aria-hidden") === "true") {
3367
- return;
3368
- }
3369
- this._toggle(false, e);
3370
- }
3371
- /**
3372
- * Determines the correct dispatching element from a potential input
3373
- * @param dispatcher The event or element to get the dispatcher from
3374
- */
3375
- getDispatcher(dispatcher = null) {
3376
- if (dispatcher instanceof Event) {
3377
- return dispatcher.target;
3378
- }
3379
- else if (dispatcher instanceof Element) {
3380
- return dispatcher;
3381
- }
3382
- else {
3383
- return this.element;
3384
- }
3385
- }
3386
- }
3387
- ToastController.targets = ["toast", "initialFocus"];
3388
- /**
3389
- * Helper to manually show an s-toast element via external JS
3390
- * @param element the element the `data-controller="s-toast"` attribute is on
3391
- */
3392
- function showToast(element) {
3393
- toggleToast(element, true);
3394
- }
3395
- /**
3396
- * Helper to manually hide an s-toast element via external JS
3397
- * @param element the element the `data-controller="s-toast"` attribute is on
3398
- */
3399
- function hideToast(element) {
3400
- toggleToast(element, false);
3489
+ }
3490
+
3491
+ return {
3492
+ x: rect.left + scroll.scrollLeft - offsets.x,
3493
+ y: rect.top + scroll.scrollTop - offsets.y,
3494
+ width: rect.width,
3495
+ height: rect.height
3496
+ };
3401
3497
  }
3402
- /**
3403
- * Helper to manually show an s-toast element via external JS
3404
- * @param element the element the `data-controller="s-toast"` attribute is on
3405
- * @param show whether to force show/hide the toast; toggles the toast if left undefined
3406
- */
3407
- function toggleToast(element, show) {
3408
- const controller = application.getControllerForElementAndIdentifier(element, "s-toast");
3409
- if (!controller) {
3410
- throw "Unable to get s-toast controller from element";
3411
- }
3412
- show ? controller.show() : controller.hide();
3498
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js
3499
+ // Returns the layout rect of an element relative to its offsetParent. Layout
3500
+ // means it doesn't take into account transforms.
3501
+
3502
+ function getLayoutRect(element) {
3503
+ var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed.
3504
+ // Fixes https://github.com/popperjs/popper-core/issues/1223
3505
+
3506
+ var width = element.offsetWidth;
3507
+ var height = element.offsetHeight;
3508
+
3509
+ if (Math.abs(clientRect.width - width) <= 1) {
3510
+ width = clientRect.width;
3511
+ }
3512
+
3513
+ if (Math.abs(clientRect.height - height) <= 1) {
3514
+ height = clientRect.height;
3515
+ }
3516
+
3517
+ return {
3518
+ x: element.offsetLeft,
3519
+ y: element.offsetTop,
3520
+ width: width,
3521
+ height: height
3522
+ };
3413
3523
  }
3524
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getParentNode.js
3414
3525
 
3415
- ;// CONCATENATED MODULE: ./lib/ts/controllers/s-navigation-tablist.ts
3416
3526
 
3417
- class TabListController extends StacksController {
3418
- connect() {
3419
- super.connect();
3420
- this.boundSelectTab = this.selectTab.bind(this);
3421
- this.boundHandleKeydown = this.handleKeydown.bind(this);
3422
- for (const tab of this.tabTargets) {
3423
- tab.addEventListener("click", this.boundSelectTab);
3424
- tab.addEventListener("keydown", this.boundHandleKeydown);
3425
- }
3426
- }
3427
- disconnect() {
3428
- super.disconnect();
3429
- for (const tab of this.tabTargets) {
3430
- tab.removeEventListener("click", this.boundSelectTab);
3431
- tab.removeEventListener("keydown", this.boundHandleKeydown);
3432
- }
3433
- }
3434
- /**
3435
- * Gets all tabs within the controller.
3436
- */
3437
- get tabTargets() {
3438
- return Array.from(this.element.querySelectorAll("[role=tab]"));
3439
- }
3440
- /**
3441
- * Handles click events on individual tabs, causing them to be selected.
3442
- */
3443
- selectTab(event) {
3444
- this.switchToTab(event.currentTarget);
3445
- }
3446
- /**
3447
- * Handles left and right arrow keydown events on individual tabs,
3448
- * selecting the adjacent tab corresponding to the event.
3449
- */
3450
- handleKeydown(event) {
3451
- var _a;
3452
- let tabElement = event.currentTarget;
3453
- const tabs = this.tabTargets;
3454
- let tabIndex = tabs.indexOf(tabElement);
3455
- if (event.key === "ArrowRight") {
3456
- tabIndex++;
3457
- }
3458
- else if (event.key === "ArrowLeft") {
3459
- tabIndex--;
3460
- }
3461
- else {
3462
- return;
3463
- }
3464
- // Use circular navigation when users go past the first or last tab.
3465
- if (tabIndex < 0) {
3466
- tabIndex = tabs.length - 1;
3467
- }
3468
- if (tabIndex >= tabs.length) {
3469
- tabIndex = 0;
3470
- }
3471
- tabElement = tabs[tabIndex];
3472
- this.switchToTab(tabElement);
3473
- // Focus the newly selected tab so it can receive keyboard events.
3474
- (_a = this.selectedTab) === null || _a === void 0 ? void 0 : _a.focus();
3475
- }
3476
- /**
3477
- * Attempts to switch to a new tab, doing nothing if the tab is already selected or
3478
- * the s-navigation-tablist:select event is prevented.
3479
- */
3480
- switchToTab(newTab) {
3481
- const oldTab = this.selectedTab;
3482
- if (oldTab === newTab) {
3483
- return;
3484
- }
3485
- if (this.triggerEvent("select", { oldTab, newTab }).defaultPrevented) {
3486
- return;
3487
- }
3488
- this.selectedTab = newTab;
3489
- this.triggerEvent("selected", { oldTab, newTab });
3490
- }
3491
- /**
3492
- * Returns the currently selected tab or null if no tabs are selected.
3493
- */
3494
- get selectedTab() {
3495
- return (this.tabTargets.find((e) => e.getAttribute("aria-selected") === "true") || null);
3496
- }
3497
- /**
3498
- * Switches the tablist to the provided tab, updating the tabs and panels
3499
- * to reflect the change.
3500
- * @param selectedTab The tab to select. If `null` is provided or the element
3501
- * is not a valid tab, all tabs will be unselected.
3502
- */
3503
- set selectedTab(selectedTab) {
3504
- for (const tab of this.tabTargets) {
3505
- const panelId = tab.getAttribute("aria-controls");
3506
- const panel = panelId ? document.getElementById(panelId) : null;
3507
- if (tab === selectedTab) {
3508
- tab.classList.add("is-selected");
3509
- tab.setAttribute("aria-selected", "true");
3510
- tab.removeAttribute("tabindex");
3511
- panel === null || panel === void 0 ? void 0 : panel.classList.remove("d-none");
3512
- }
3513
- else {
3514
- tab.classList.remove("is-selected");
3515
- tab.setAttribute("aria-selected", "false");
3516
- tab.setAttribute("tabindex", "-1");
3517
- panel === null || panel === void 0 ? void 0 : panel.classList.add("d-none");
3518
- }
3519
- }
3520
- }
3521
- }
3522
3527
 
3523
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getWindow.js
3524
- function getWindow(node) {
3525
- if (node == null) {
3526
- return window;
3528
+ function getParentNode(element) {
3529
+ if (getNodeName(element) === 'html') {
3530
+ return element;
3527
3531
  }
3528
3532
 
3529
- if (node.toString() !== '[object Window]') {
3530
- var ownerDocument = node.ownerDocument;
3531
- return ownerDocument ? ownerDocument.defaultView || window : window;
3532
- }
3533
+ return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle
3534
+ // $FlowFixMe[incompatible-return]
3535
+ // $FlowFixMe[prop-missing]
3536
+ element.assignedSlot || // step into the shadow DOM of the parent of a slotted node
3537
+ element.parentNode || ( // DOM Element detected
3538
+ isShadowRoot(element) ? element.host : null) || // ShadowRoot detected
3539
+ // $FlowFixMe[incompatible-call]: HTMLElement is a Node
3540
+ getDocumentElement(element) // fallback
3533
3541
 
3534
- return node;
3542
+ );
3535
3543
  }
3536
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/instanceOf.js
3544
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js
3537
3545
 
3538
3546
 
3539
- function isElement(node) {
3540
- var OwnElement = getWindow(node).Element;
3541
- return node instanceof OwnElement || node instanceof Element;
3542
- }
3543
3547
 
3544
- function isHTMLElement(node) {
3545
- var OwnElement = getWindow(node).HTMLElement;
3546
- return node instanceof OwnElement || node instanceof HTMLElement;
3547
- }
3548
3548
 
3549
- function isShadowRoot(node) {
3550
- // IE 11 has no ShadowRoot
3551
- if (typeof ShadowRoot === 'undefined') {
3552
- return false;
3549
+ function getScrollParent(node) {
3550
+ if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {
3551
+ // $FlowFixMe[incompatible-return]: assume body is always available
3552
+ return node.ownerDocument.body;
3553
3553
  }
3554
3554
 
3555
- var OwnElement = getWindow(node).ShadowRoot;
3556
- return node instanceof OwnElement || node instanceof ShadowRoot;
3555
+ if (isHTMLElement(node) && isScrollParent(node)) {
3556
+ return node;
3557
+ }
3558
+
3559
+ return getScrollParent(getParentNode(node));
3557
3560
  }
3561
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js
3558
3562
 
3559
3563
 
3560
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/utils/math.js
3561
- var math_max = Math.max;
3562
- var math_min = Math.min;
3563
- var round = Math.round;
3564
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/utils/userAgent.js
3565
- function getUAString() {
3566
- var uaData = navigator.userAgentData;
3567
3564
 
3568
- if (uaData != null && uaData.brands) {
3569
- return uaData.brands.map(function (item) {
3570
- return item.brand + "/" + item.version;
3571
- }).join(' ');
3565
+
3566
+ /*
3567
+ given a DOM element, return the list of all scroll parents, up the list of ancesors
3568
+ until we get to the top window object. This list is what we attach scroll listeners
3569
+ to, because if any of these parent elements scroll, we'll need to re-calculate the
3570
+ reference element's position.
3571
+ */
3572
+
3573
+ function listScrollParents(element, list) {
3574
+ var _element$ownerDocumen;
3575
+
3576
+ if (list === void 0) {
3577
+ list = [];
3572
3578
  }
3573
3579
 
3574
- return navigator.userAgent;
3580
+ var scrollParent = getScrollParent(element);
3581
+ var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);
3582
+ var win = getWindow(scrollParent);
3583
+ var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;
3584
+ var updatedList = list.concat(target);
3585
+ return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here
3586
+ updatedList.concat(listScrollParents(getParentNode(target)));
3575
3587
  }
3576
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js
3588
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/isTableElement.js
3577
3589
 
3578
- function isLayoutViewport() {
3579
- return !/^((?!chrome|android).)*safari/i.test(getUAString());
3590
+ function isTableElement(element) {
3591
+ return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;
3580
3592
  }
3581
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js
3582
-
3593
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js
3583
3594
 
3584
3595
 
3585
3596
 
3586
- function getBoundingClientRect(element, includeScale, isFixedStrategy) {
3587
- if (includeScale === void 0) {
3588
- includeScale = false;
3589
- }
3590
3597
 
3591
- if (isFixedStrategy === void 0) {
3592
- isFixedStrategy = false;
3593
- }
3594
3598
 
3595
- var clientRect = element.getBoundingClientRect();
3596
- var scaleX = 1;
3597
- var scaleY = 1;
3598
3599
 
3599
- if (includeScale && isHTMLElement(element)) {
3600
- scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;
3601
- scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;
3602
- }
3603
3600
 
3604
- var _ref = isElement(element) ? getWindow(element) : window,
3605
- visualViewport = _ref.visualViewport;
3606
3601
 
3607
- var addVisualOffsets = !isLayoutViewport() && isFixedStrategy;
3608
- var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX;
3609
- var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY;
3610
- var width = clientRect.width / scaleX;
3611
- var height = clientRect.height / scaleY;
3612
- return {
3613
- width: width,
3614
- height: height,
3615
- top: y,
3616
- right: x + width,
3617
- bottom: y + height,
3618
- left: x,
3619
- x: x,
3620
- y: y
3621
- };
3622
- }
3623
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js
3602
+ function getTrueOffsetParent(element) {
3603
+ if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837
3604
+ getComputedStyle_getComputedStyle(element).position === 'fixed') {
3605
+ return null;
3606
+ }
3624
3607
 
3625
- function getWindowScroll(node) {
3626
- var win = getWindow(node);
3627
- var scrollLeft = win.pageXOffset;
3628
- var scrollTop = win.pageYOffset;
3629
- return {
3630
- scrollLeft: scrollLeft,
3631
- scrollTop: scrollTop
3632
- };
3633
- }
3634
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js
3635
- function getHTMLElementScroll(element) {
3636
- return {
3637
- scrollLeft: element.scrollLeft,
3638
- scrollTop: element.scrollTop
3639
- };
3640
- }
3641
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js
3608
+ return element.offsetParent;
3609
+ } // `.offsetParent` reports `null` for fixed elements, while absolute elements
3610
+ // return the containing block
3642
3611
 
3643
3612
 
3613
+ function getContainingBlock(element) {
3614
+ var isFirefox = /firefox/i.test(getUAString());
3615
+ var isIE = /Trident/i.test(getUAString());
3644
3616
 
3645
-
3646
- function getNodeScroll(node) {
3647
- if (node === getWindow(node) || !isHTMLElement(node)) {
3648
- return getWindowScroll(node);
3649
- } else {
3650
- return getHTMLElementScroll(node);
3651
- }
3652
- }
3653
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getNodeName.js
3654
- function getNodeName(element) {
3655
- return element ? (element.nodeName || '').toLowerCase() : null;
3656
- }
3657
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js
3658
-
3659
- function getDocumentElement(element) {
3660
- // $FlowFixMe[incompatible-return]: assume body is always available
3661
- return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing]
3662
- element.document) || window.document).documentElement;
3663
- }
3664
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js
3665
-
3666
-
3667
-
3668
- function getWindowScrollBarX(element) {
3669
- // If <html> has a CSS width greater than the viewport, then this will be
3670
- // incorrect for RTL.
3671
- // Popper 1 is broken in this case and never had a bug report so let's assume
3672
- // it's not an issue. I don't think anyone ever specifies width on <html>
3673
- // anyway.
3674
- // Browsers where the left scrollbar doesn't cause an issue report `0` for
3675
- // this (e.g. Edge 2019, IE11, Safari)
3676
- return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;
3677
- }
3678
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js
3679
-
3680
- function getComputedStyle_getComputedStyle(element) {
3681
- return getWindow(element).getComputedStyle(element);
3682
- }
3683
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js
3684
-
3685
- function isScrollParent(element) {
3686
- // Firefox wants us to check `-x` and `-y` variations as well
3687
- var _getComputedStyle = getComputedStyle_getComputedStyle(element),
3688
- overflow = _getComputedStyle.overflow,
3689
- overflowX = _getComputedStyle.overflowX,
3690
- overflowY = _getComputedStyle.overflowY;
3691
-
3692
- return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);
3693
- }
3694
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js
3695
-
3696
-
3697
-
3698
-
3699
-
3700
-
3701
-
3702
-
3703
-
3704
- function isElementScaled(element) {
3705
- var rect = element.getBoundingClientRect();
3706
- var scaleX = round(rect.width) / element.offsetWidth || 1;
3707
- var scaleY = round(rect.height) / element.offsetHeight || 1;
3708
- return scaleX !== 1 || scaleY !== 1;
3709
- } // Returns the composite rect of an element relative to its offsetParent.
3710
- // Composite means it takes into account transforms as well as layout.
3711
-
3712
-
3713
- function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {
3714
- if (isFixed === void 0) {
3715
- isFixed = false;
3716
- }
3717
-
3718
- var isOffsetParentAnElement = isHTMLElement(offsetParent);
3719
- var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);
3720
- var documentElement = getDocumentElement(offsetParent);
3721
- var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed);
3722
- var scroll = {
3723
- scrollLeft: 0,
3724
- scrollTop: 0
3725
- };
3726
- var offsets = {
3727
- x: 0,
3728
- y: 0
3729
- };
3730
-
3731
- if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
3732
- if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078
3733
- isScrollParent(documentElement)) {
3734
- scroll = getNodeScroll(offsetParent);
3735
- }
3736
-
3737
- if (isHTMLElement(offsetParent)) {
3738
- offsets = getBoundingClientRect(offsetParent, true);
3739
- offsets.x += offsetParent.clientLeft;
3740
- offsets.y += offsetParent.clientTop;
3741
- } else if (documentElement) {
3742
- offsets.x = getWindowScrollBarX(documentElement);
3743
- }
3744
- }
3745
-
3746
- return {
3747
- x: rect.left + scroll.scrollLeft - offsets.x,
3748
- y: rect.top + scroll.scrollTop - offsets.y,
3749
- width: rect.width,
3750
- height: rect.height
3751
- };
3752
- }
3753
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js
3754
- // Returns the layout rect of an element relative to its offsetParent. Layout
3755
- // means it doesn't take into account transforms.
3756
-
3757
- function getLayoutRect(element) {
3758
- var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed.
3759
- // Fixes https://github.com/popperjs/popper-core/issues/1223
3760
-
3761
- var width = element.offsetWidth;
3762
- var height = element.offsetHeight;
3763
-
3764
- if (Math.abs(clientRect.width - width) <= 1) {
3765
- width = clientRect.width;
3766
- }
3767
-
3768
- if (Math.abs(clientRect.height - height) <= 1) {
3769
- height = clientRect.height;
3770
- }
3771
-
3772
- return {
3773
- x: element.offsetLeft,
3774
- y: element.offsetTop,
3775
- width: width,
3776
- height: height
3777
- };
3778
- }
3779
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getParentNode.js
3780
-
3781
-
3782
-
3783
- function getParentNode(element) {
3784
- if (getNodeName(element) === 'html') {
3785
- return element;
3786
- }
3787
-
3788
- return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle
3789
- // $FlowFixMe[incompatible-return]
3790
- // $FlowFixMe[prop-missing]
3791
- element.assignedSlot || // step into the shadow DOM of the parent of a slotted node
3792
- element.parentNode || ( // DOM Element detected
3793
- isShadowRoot(element) ? element.host : null) || // ShadowRoot detected
3794
- // $FlowFixMe[incompatible-call]: HTMLElement is a Node
3795
- getDocumentElement(element) // fallback
3796
-
3797
- );
3798
- }
3799
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js
3800
-
3801
-
3802
-
3803
-
3804
- function getScrollParent(node) {
3805
- if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {
3806
- // $FlowFixMe[incompatible-return]: assume body is always available
3807
- return node.ownerDocument.body;
3808
- }
3809
-
3810
- if (isHTMLElement(node) && isScrollParent(node)) {
3811
- return node;
3812
- }
3813
-
3814
- return getScrollParent(getParentNode(node));
3815
- }
3816
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js
3817
-
3818
-
3819
-
3820
-
3821
- /*
3822
- given a DOM element, return the list of all scroll parents, up the list of ancesors
3823
- until we get to the top window object. This list is what we attach scroll listeners
3824
- to, because if any of these parent elements scroll, we'll need to re-calculate the
3825
- reference element's position.
3826
- */
3827
-
3828
- function listScrollParents(element, list) {
3829
- var _element$ownerDocumen;
3830
-
3831
- if (list === void 0) {
3832
- list = [];
3833
- }
3834
-
3835
- var scrollParent = getScrollParent(element);
3836
- var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);
3837
- var win = getWindow(scrollParent);
3838
- var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;
3839
- var updatedList = list.concat(target);
3840
- return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here
3841
- updatedList.concat(listScrollParents(getParentNode(target)));
3842
- }
3843
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/isTableElement.js
3844
-
3845
- function isTableElement(element) {
3846
- return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;
3847
- }
3848
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js
3849
-
3850
-
3851
-
3852
-
3853
-
3854
-
3855
-
3856
-
3857
- function getTrueOffsetParent(element) {
3858
- if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837
3859
- getComputedStyle_getComputedStyle(element).position === 'fixed') {
3860
- return null;
3861
- }
3862
-
3863
- return element.offsetParent;
3864
- } // `.offsetParent` reports `null` for fixed elements, while absolute elements
3865
- // return the containing block
3866
-
3867
-
3868
- function getContainingBlock(element) {
3869
- var isFirefox = /firefox/i.test(getUAString());
3870
- var isIE = /Trident/i.test(getUAString());
3871
-
3872
- if (isIE && isHTMLElement(element)) {
3873
- // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport
3874
- var elementCss = getComputedStyle_getComputedStyle(element);
3617
+ if (isIE && isHTMLElement(element)) {
3618
+ // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport
3619
+ var elementCss = getComputedStyle_getComputedStyle(element);
3875
3620
 
3876
3621
  if (elementCss.position === 'fixed') {
3877
3622
  return null;
@@ -4420,10 +4165,9 @@ var unsetSides = {
4420
4165
  // Zooming can change the DPR, but it seems to report a value that will
4421
4166
  // cleanly divide the values into the appropriate subpixels.
4422
4167
 
4423
- function roundOffsetsByDPR(_ref) {
4168
+ function roundOffsetsByDPR(_ref, win) {
4424
4169
  var x = _ref.x,
4425
4170
  y = _ref.y;
4426
- var win = window;
4427
4171
  var dpr = win.devicePixelRatio || 1;
4428
4172
  return {
4429
4173
  x: round(x * dpr) / dpr || 0,
@@ -4506,7 +4250,7 @@ function mapToStyles(_ref2) {
4506
4250
  var _ref4 = roundOffsets === true ? roundOffsetsByDPR({
4507
4251
  x: x,
4508
4252
  y: y
4509
- }) : {
4253
+ }, getWindow(popper)) : {
4510
4254
  x: x,
4511
4255
  y: y
4512
4256
  };
@@ -5455,767 +5199,1050 @@ function getSideOffsets(overflow, rect, preventedOffsets) {
5455
5199
  left: overflow.left - rect.width - preventedOffsets.x
5456
5200
  };
5457
5201
  }
5458
-
5459
- function isAnySideFullyClipped(overflow) {
5460
- return [enums_top, right, bottom, left].some(function (side) {
5461
- return overflow[side] >= 0;
5462
- });
5202
+
5203
+ function isAnySideFullyClipped(overflow) {
5204
+ return [enums_top, right, bottom, left].some(function (side) {
5205
+ return overflow[side] >= 0;
5206
+ });
5207
+ }
5208
+
5209
+ function hide(_ref) {
5210
+ var state = _ref.state,
5211
+ name = _ref.name;
5212
+ var referenceRect = state.rects.reference;
5213
+ var popperRect = state.rects.popper;
5214
+ var preventedOffsets = state.modifiersData.preventOverflow;
5215
+ var referenceOverflow = detectOverflow(state, {
5216
+ elementContext: 'reference'
5217
+ });
5218
+ var popperAltOverflow = detectOverflow(state, {
5219
+ altBoundary: true
5220
+ });
5221
+ var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);
5222
+ var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);
5223
+ var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);
5224
+ var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);
5225
+ state.modifiersData[name] = {
5226
+ referenceClippingOffsets: referenceClippingOffsets,
5227
+ popperEscapeOffsets: popperEscapeOffsets,
5228
+ isReferenceHidden: isReferenceHidden,
5229
+ hasPopperEscaped: hasPopperEscaped
5230
+ };
5231
+ state.attributes.popper = Object.assign({}, state.attributes.popper, {
5232
+ 'data-popper-reference-hidden': isReferenceHidden,
5233
+ 'data-popper-escaped': hasPopperEscaped
5234
+ });
5235
+ } // eslint-disable-next-line import/no-unused-modules
5236
+
5237
+
5238
+ /* harmony default export */ const modifiers_hide = ({
5239
+ name: 'hide',
5240
+ enabled: true,
5241
+ phase: 'main',
5242
+ requiresIfExists: ['preventOverflow'],
5243
+ fn: hide
5244
+ });
5245
+ ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/popper.js
5246
+
5247
+
5248
+
5249
+
5250
+
5251
+
5252
+
5253
+
5254
+
5255
+
5256
+ var defaultModifiers = [eventListeners, modifiers_popperOffsets, modifiers_computeStyles, modifiers_applyStyles, modifiers_offset, modifiers_flip, modifiers_preventOverflow, modifiers_arrow, modifiers_hide];
5257
+ var popper_createPopper = /*#__PURE__*/popperGenerator({
5258
+ defaultModifiers: defaultModifiers
5259
+ }); // eslint-disable-next-line import/no-unused-modules
5260
+
5261
+ // eslint-disable-next-line import/no-unused-modules
5262
+
5263
+ // eslint-disable-next-line import/no-unused-modules
5264
+
5265
+
5266
+ ;// CONCATENATED MODULE: ./lib/components/popover/popover.ts
5267
+
5268
+
5269
+ class BasePopoverController extends StacksController {
5270
+ /**
5271
+ * Returns true if the if the popover is currently visible.
5272
+ */
5273
+ get isVisible() {
5274
+ const popoverElement = this.popoverElement;
5275
+ return popoverElement
5276
+ ? popoverElement.classList.contains("is-visible")
5277
+ : false;
5278
+ }
5279
+ /**
5280
+ * Gets whether the element is visible in the browser's viewport.
5281
+ */
5282
+ get isInViewport() {
5283
+ const element = this.popoverElement;
5284
+ if (!this.isVisible || !element) {
5285
+ return false;
5286
+ }
5287
+ // From https://stackoverflow.com/a/5354536. Theoretically, this could be calculated using Popper's detectOverflow function,
5288
+ // but it's unclear how to access that with our current configuration.
5289
+ const rect = element.getBoundingClientRect();
5290
+ const viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
5291
+ const viewWidth = Math.max(document.documentElement.clientWidth, window.innerWidth);
5292
+ return (rect.bottom > 0 &&
5293
+ rect.top < viewHeight &&
5294
+ rect.right > 0 &&
5295
+ rect.left < viewWidth);
5296
+ }
5297
+ get shouldHideOnOutsideClick() {
5298
+ const hideBehavior = (this.data.get("hide-on-outside-click"));
5299
+ switch (hideBehavior) {
5300
+ case "after-dismissal":
5301
+ case "never":
5302
+ return false;
5303
+ case "if-in-viewport":
5304
+ return this.isInViewport;
5305
+ default:
5306
+ return true;
5307
+ }
5308
+ }
5309
+ /**
5310
+ * Initializes and validates controller variables
5311
+ */
5312
+ connect() {
5313
+ super.connect();
5314
+ this.validate();
5315
+ if (this.isVisible) {
5316
+ // just call initialize here, not show. This keeps already visible popovers from adding/firing document events
5317
+ this.initializePopper();
5318
+ }
5319
+ else if (this.data.get("auto-show") === "true") {
5320
+ this.show(null);
5321
+ }
5322
+ this.data.delete("auto-show");
5323
+ }
5324
+ /**
5325
+ * Cleans up popper.js elements and disconnects all added event listeners
5326
+ */
5327
+ disconnect() {
5328
+ this.hide();
5329
+ if (this.popper) {
5330
+ this.popper.destroy();
5331
+ // eslint-disable-next-line
5332
+ // @ts-ignore The operand of a 'delete' operator must be optional .ts(2790)
5333
+ delete this.popper;
5334
+ }
5335
+ super.disconnect();
5336
+ }
5337
+ /**
5338
+ * Toggles the visibility of the popover
5339
+ */
5340
+ toggle(dispatcher = null) {
5341
+ this.isVisible ? this.hide(dispatcher) : this.show(dispatcher);
5342
+ }
5343
+ /**
5344
+ * Shows the popover if not already visible
5345
+ */
5346
+ show(dispatcher = null) {
5347
+ if (this.isVisible) {
5348
+ return;
5349
+ }
5350
+ const dispatcherElement = this.getDispatcher(dispatcher);
5351
+ if (this.triggerEvent("show", {
5352
+ dispatcher: dispatcherElement,
5353
+ }).defaultPrevented) {
5354
+ return;
5355
+ }
5356
+ if (!this.popper) {
5357
+ this.initializePopper();
5358
+ }
5359
+ this.popoverElement.classList.add("is-visible");
5360
+ // ensure the popper has been positioned correctly
5361
+ this.scheduleUpdate();
5362
+ this.shown(dispatcherElement);
5363
+ }
5364
+ /**
5365
+ * Hides the popover if not already hidden
5366
+ */
5367
+ hide(dispatcher = null) {
5368
+ if (!this.isVisible) {
5369
+ return;
5370
+ }
5371
+ const dispatcherElement = this.getDispatcher(dispatcher);
5372
+ if (this.triggerEvent("hide", {
5373
+ dispatcher: dispatcherElement,
5374
+ }).defaultPrevented) {
5375
+ return;
5376
+ }
5377
+ this.popoverElement.classList.remove("is-visible");
5378
+ if (this.popper) {
5379
+ // completely destroy the popper on hide; this is in line with Popper.js's performance recommendations
5380
+ this.popper.destroy();
5381
+ // eslint-disable-next-line
5382
+ // @ts-ignore The operand of a 'delete' operator must be optional .ts(2790)
5383
+ delete this.popper;
5384
+ }
5385
+ // on first interaction, hide-on-outside-click with value "after-dismissal" reverts to the default behavior
5386
+ if (this.data.get("hide-on-outside-click") ===
5387
+ "after-dismissal") {
5388
+ this.data.delete("hide-on-outside-click");
5389
+ }
5390
+ this.hidden(dispatcherElement);
5391
+ }
5392
+ /**
5393
+ * Binds document events for this popover and fires the shown event
5394
+ */
5395
+ shown(dispatcher = null) {
5396
+ this.bindDocumentEvents();
5397
+ this.triggerEvent("shown", {
5398
+ dispatcher: dispatcher,
5399
+ });
5400
+ }
5401
+ /**
5402
+ * Unbinds document events for this popover and fires the hidden event
5403
+ */
5404
+ hidden(dispatcher = null) {
5405
+ this.unbindDocumentEvents();
5406
+ this.triggerEvent("hidden", {
5407
+ dispatcher: dispatcher,
5408
+ });
5409
+ }
5410
+ /**
5411
+ * Generates the popover if not found during initialization
5412
+ */
5413
+ generatePopover() {
5414
+ return null;
5415
+ }
5416
+ /**
5417
+ * Initializes the Popper for this instance
5418
+ */
5419
+ initializePopper() {
5420
+ this.popper = popper_createPopper(this.referenceElement, this.popoverElement, {
5421
+ placement: this.data.get("placement") || "bottom",
5422
+ modifiers: [
5423
+ {
5424
+ name: "offset",
5425
+ options: {
5426
+ offset: [0, 10], // The entire popover should be 10px away from the element
5427
+ },
5428
+ },
5429
+ {
5430
+ name: "arrow",
5431
+ options: {
5432
+ element: ".s-popover--arrow",
5433
+ },
5434
+ },
5435
+ ],
5436
+ });
5437
+ }
5438
+ /**
5439
+ * Validates the popover settings and attempts to set necessary internal variables
5440
+ */
5441
+ validate() {
5442
+ const referenceSelector = this.data.get("reference-selector");
5443
+ this.referenceElement = this.element;
5444
+ // if there is an alternative reference selector and that element exists, use it (and throw if it isn't found)
5445
+ if (referenceSelector) {
5446
+ this.referenceElement = (this.element.querySelector(referenceSelector));
5447
+ if (!this.referenceElement) {
5448
+ throw ("Unable to find element by reference selector: " +
5449
+ referenceSelector);
5450
+ }
5451
+ }
5452
+ const popoverId = this.referenceElement.getAttribute(this.popoverSelectorAttribute);
5453
+ let popoverElement = null;
5454
+ // if the popover is named, attempt to fetch it (and throw an error if it doesn't exist)
5455
+ if (popoverId) {
5456
+ popoverElement = document.getElementById(popoverId);
5457
+ if (!popoverElement) {
5458
+ throw `[${this.popoverSelectorAttribute}="{POPOVER_ID}"] required`;
5459
+ }
5460
+ }
5461
+ // if the popover isn't named, attempt to generate it
5462
+ else {
5463
+ popoverElement = this.generatePopover();
5464
+ }
5465
+ if (!popoverElement) {
5466
+ throw "unable to find or generate popover element";
5467
+ }
5468
+ this.popoverElement = popoverElement;
5469
+ }
5470
+ /**
5471
+ * Determines the correct dispatching element from a potential input
5472
+ * @param dispatcher The event or element to get the dispatcher from
5473
+ */
5474
+ getDispatcher(dispatcher = null) {
5475
+ if (dispatcher instanceof Event) {
5476
+ return dispatcher.target;
5477
+ }
5478
+ else if (dispatcher instanceof Element) {
5479
+ return dispatcher;
5480
+ }
5481
+ else {
5482
+ return this.element;
5483
+ }
5484
+ }
5485
+ /**
5486
+ * Schedules the popover to update on the next animation frame if visible
5487
+ */
5488
+ scheduleUpdate() {
5489
+ if (this.popper && this.isVisible) {
5490
+ void this.popper.update();
5491
+ }
5492
+ }
5493
+ }
5494
+ class PopoverController extends BasePopoverController {
5495
+ constructor() {
5496
+ super(...arguments);
5497
+ this.popoverSelectorAttribute = "aria-controls";
5498
+ }
5499
+ /**
5500
+ * Toggles optional classes and accessibility attributes in addition to BasePopoverController.shown
5501
+ */
5502
+ shown(dispatcher = null) {
5503
+ this.toggleOptionalClasses(true);
5504
+ this.toggleAccessibilityAttributes(true);
5505
+ super.shown(dispatcher);
5506
+ }
5507
+ /**
5508
+ * Toggles optional classes and accessibility attributes in addition to BasePopoverController.hidden
5509
+ */
5510
+ hidden(dispatcher = null) {
5511
+ this.toggleOptionalClasses(false);
5512
+ this.toggleAccessibilityAttributes(false);
5513
+ super.hidden(dispatcher);
5514
+ }
5515
+ /**
5516
+ * Initializes accessibility attributes in addition to BasePopoverController.connect
5517
+ */
5518
+ connect() {
5519
+ super.connect();
5520
+ this.toggleAccessibilityAttributes();
5521
+ }
5522
+ /**
5523
+ * Binds global events to the document for hiding popovers on user interaction
5524
+ */
5525
+ bindDocumentEvents() {
5526
+ this.boundHideOnOutsideClick =
5527
+ this.boundHideOnOutsideClick || this.hideOnOutsideClick.bind(this);
5528
+ this.boundHideOnEscapePress =
5529
+ this.boundHideOnEscapePress || this.hideOnEscapePress.bind(this);
5530
+ document.addEventListener("mousedown", this.boundHideOnOutsideClick);
5531
+ document.addEventListener("keyup", this.boundHideOnEscapePress);
5532
+ }
5533
+ /**
5534
+ * Unbinds global events to the document for hiding popovers on user interaction
5535
+ */
5536
+ unbindDocumentEvents() {
5537
+ document.removeEventListener("mousedown", this.boundHideOnOutsideClick);
5538
+ document.removeEventListener("keyup", this.boundHideOnEscapePress);
5539
+ }
5540
+ /**
5541
+ * Forces the popover to hide if a user clicks outside of it or its reference element
5542
+ * @param {Event} e - The document click event
5543
+ */
5544
+ hideOnOutsideClick(e) {
5545
+ const target = e.target;
5546
+ // check if the document was clicked inside either the reference element or the popover itself
5547
+ // note: .contains also returns true if the node itself matches the target element
5548
+ if (this.shouldHideOnOutsideClick &&
5549
+ !this.referenceElement.contains(target) &&
5550
+ !this.popoverElement.contains(target) &&
5551
+ document.body.contains(target)) {
5552
+ this.hide(e);
5553
+ }
5554
+ }
5555
+ /**
5556
+ * Forces the popover to hide if the user presses escape while it, one of its childen, or the reference element are focused
5557
+ * @param {Event} e - The document keyup event
5558
+ */
5559
+ hideOnEscapePress(e) {
5560
+ // if the ESC key (27) wasn't pressed or if no popovers are showing, return
5561
+ if (e.which !== 27 || !this.isVisible) {
5562
+ return;
5563
+ }
5564
+ // check if the target was inside the popover element and refocus the triggering element
5565
+ // note: .contains also returns true if the node itself matches the target element
5566
+ if (this.popoverElement.contains(e.target)) {
5567
+ this.referenceElement.focus();
5568
+ }
5569
+ this.hide(e);
5570
+ }
5571
+ /**
5572
+ * Toggles all classes on the originating element based on the `class-toggle` data
5573
+ * @param {boolean=} show - A boolean indicating whether this is being triggered by a show or hide.
5574
+ */
5575
+ toggleOptionalClasses(show) {
5576
+ if (!this.data.has("toggle-class")) {
5577
+ return;
5578
+ }
5579
+ const toggleClass = this.data.get("toggle-class") || "";
5580
+ const cl = this.referenceElement.classList;
5581
+ toggleClass.split(/\s+/).forEach(function (cls) {
5582
+ cl.toggle(cls, show);
5583
+ });
5584
+ }
5585
+ /**
5586
+ * Toggles accessibility attributes based on whether the popover is shown or not
5587
+ * @param {boolean=} show - A boolean indicating whether this is being triggered by a show or hide.
5588
+ */
5589
+ toggleAccessibilityAttributes(show) {
5590
+ const expandedValue = (show === null || show === void 0 ? void 0 : show.toString()) || this.referenceElement.ariaExpanded || "false";
5591
+ this.referenceElement.ariaExpanded = expandedValue;
5592
+ this.referenceElement.setAttribute("aria-expanded", expandedValue);
5593
+ }
5594
+ }
5595
+ PopoverController.targets = [];
5596
+
5597
+ /**
5598
+ * Helper to manually show an s-popover element via external JS
5599
+ * @param element the element the `data-controller="s-popover"` attribute is on
5600
+ */
5601
+ function showPopover(element) {
5602
+ const { isPopover, controller } = getPopover(element);
5603
+ if (controller) {
5604
+ controller.show();
5605
+ }
5606
+ else if (isPopover) {
5607
+ element.setAttribute("data-s-popover-auto-show", "true");
5608
+ }
5609
+ else {
5610
+ throw `element does not have data-controller="s-popover"`;
5611
+ }
5612
+ }
5613
+ /**
5614
+ * Helper to manually hide an s-popover element via external JS
5615
+ * @param element the element the `data-controller="s-popover"` attribute is on
5616
+ */
5617
+ function hidePopover(element) {
5618
+ const { isPopover, controller, popover } = getPopover(element);
5619
+ if (controller) {
5620
+ controller.hide();
5621
+ }
5622
+ else if (isPopover) {
5623
+ element.removeAttribute("data-s-popover-auto-show");
5624
+ if (popover) {
5625
+ popover.classList.remove("is-visible");
5626
+ }
5627
+ }
5628
+ else {
5629
+ throw `element does not have data-controller="s-popover"`;
5630
+ }
5631
+ }
5632
+ /**
5633
+ * Attaches a popover to an element and performs additional configuration.
5634
+ * @param element the element that will receive the `data-controller="s-popover"` attribute.
5635
+ * @param popover an element with the `.s-popover` class or HTML string containing a single element with the `.s-popover` class.
5636
+ * If the popover does not have a parent element, it will be inserted as a immediately after the reference element.
5637
+ * @param options an optional collection of options to use when configuring the popover.
5638
+ */
5639
+ function attachPopover(element, popover, options) {
5640
+ const { referenceElement, popover: existingPopover } = getPopover(element);
5641
+ if (existingPopover) {
5642
+ throw `element already has popover with id="${existingPopover.id}"`;
5643
+ }
5644
+ if (!referenceElement) {
5645
+ throw `element has invalid data-s-popover-reference-selector attribute`;
5646
+ }
5647
+ if (typeof popover === "string") {
5648
+ // eslint-disable-next-line no-unsanitized/method
5649
+ const elements = document
5650
+ .createRange()
5651
+ .createContextualFragment(popover).children;
5652
+ if (elements.length !== 1) {
5653
+ throw "popover should contain a single element";
5654
+ }
5655
+ popover = elements[0];
5656
+ }
5657
+ const existingId = referenceElement.getAttribute("aria-controls");
5658
+ let popoverId = popover.id;
5659
+ if (!popover.classList.contains("s-popover")) {
5660
+ throw `popover should have the "s-popover" class but had class="${popover.className}"`;
5661
+ }
5662
+ if (existingId && existingId !== popoverId) {
5663
+ throw `element has aria-controls="${existingId}" but popover has id="${popoverId}"`;
5664
+ }
5665
+ if (!popoverId) {
5666
+ popoverId =
5667
+ "--stacks-s-popover-" + Math.random().toString(36).substring(2, 10);
5668
+ popover.id = popoverId;
5669
+ }
5670
+ if (!existingId) {
5671
+ referenceElement.setAttribute("aria-controls", popoverId);
5672
+ }
5673
+ if (!popover.parentElement && element.parentElement) {
5674
+ referenceElement.insertAdjacentElement("afterend", popover);
5675
+ }
5676
+ toggleController(element, "s-popover", true);
5677
+ if (options) {
5678
+ if (options.toggleOnClick) {
5679
+ referenceElement.setAttribute("data-action", "click->s-popover#toggle");
5680
+ }
5681
+ if (options.placement) {
5682
+ element.setAttribute("data-s-popover-placement", options.placement);
5683
+ }
5684
+ if (options.autoShow) {
5685
+ element.setAttribute("data-s-popover-auto-show", "true");
5686
+ }
5687
+ }
5688
+ }
5689
+ /**
5690
+ * Removes the popover controller from an element and removes the popover from the DOM.
5691
+ * @param element the element that has the `data-controller="s-popover"` attribute.
5692
+ * @returns The popover that was attached to the element.
5693
+ */
5694
+ function detachPopover(element) {
5695
+ const { isPopover, controller, referenceElement, popover } = getPopover(element);
5696
+ // Hide the popover so its events fire.
5697
+ controller === null || controller === void 0 ? void 0 : controller.hide();
5698
+ // Remove the popover if it exists
5699
+ popover === null || popover === void 0 ? void 0 : popover.remove();
5700
+ // Remove the popover controller and the aria-controls attributes.
5701
+ if (isPopover) {
5702
+ toggleController(element, "s-popover", false);
5703
+ if (referenceElement) {
5704
+ referenceElement.removeAttribute("aria-controls");
5705
+ }
5706
+ }
5707
+ return popover;
5708
+ }
5709
+ /**
5710
+ * Gets the current state of an element that may be or is intended to be an s-popover controller
5711
+ * so it can be configured either directly or via the DOM.
5712
+ * @param element An element that may have `data-controller="s-popover"`.
5713
+ */
5714
+ function getPopover(element) {
5715
+ var _a;
5716
+ const isPopover = ((_a = element.getAttribute("data-controller")) === null || _a === void 0 ? void 0 : _a.includes("s-popover")) || false;
5717
+ const controller = application.getControllerForElementAndIdentifier(element, "s-popover");
5718
+ const referenceSelector = element.getAttribute("data-s-popover-reference-selector");
5719
+ const referenceElement = referenceSelector
5720
+ ? element.querySelector(referenceSelector)
5721
+ : element;
5722
+ const popoverId = referenceElement
5723
+ ? referenceElement.getAttribute("aria-controls")
5724
+ : null;
5725
+ const popover = popoverId ? document.getElementById(popoverId) : null;
5726
+ return { isPopover, controller, referenceElement, popover };
5727
+ }
5728
+ /**
5729
+ * Adds or removes the controller from an element's [data-controller] attribute without altering existing entries
5730
+ * @param el The element to alter
5731
+ * @param controllerName The name of the controller to add/remove
5732
+ * @param include Whether to add the controllerName value
5733
+ */
5734
+ function toggleController(el, controllerName, include) {
5735
+ var _a;
5736
+ const controllers = new Set((_a = el.getAttribute("data-controller")) === null || _a === void 0 ? void 0 : _a.split(/\s+/));
5737
+ if (include) {
5738
+ controllers.add(controllerName);
5739
+ }
5740
+ else {
5741
+ controllers.delete(controllerName);
5742
+ }
5743
+ el.setAttribute("data-controller", Array.from(controllers).join(" "));
5463
5744
  }
5464
5745
 
5465
- function hide(_ref) {
5466
- var state = _ref.state,
5467
- name = _ref.name;
5468
- var referenceRect = state.rects.reference;
5469
- var popperRect = state.rects.popper;
5470
- var preventedOffsets = state.modifiersData.preventOverflow;
5471
- var referenceOverflow = detectOverflow(state, {
5472
- elementContext: 'reference'
5473
- });
5474
- var popperAltOverflow = detectOverflow(state, {
5475
- altBoundary: true
5476
- });
5477
- var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);
5478
- var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);
5479
- var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);
5480
- var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);
5481
- state.modifiersData[name] = {
5482
- referenceClippingOffsets: referenceClippingOffsets,
5483
- popperEscapeOffsets: popperEscapeOffsets,
5484
- isReferenceHidden: isReferenceHidden,
5485
- hasPopperEscaped: hasPopperEscaped
5486
- };
5487
- state.attributes.popper = Object.assign({}, state.attributes.popper, {
5488
- 'data-popper-reference-hidden': isReferenceHidden,
5489
- 'data-popper-escaped': hasPopperEscaped
5490
- });
5491
- } // eslint-disable-next-line import/no-unused-modules
5492
-
5493
-
5494
- /* harmony default export */ const modifiers_hide = ({
5495
- name: 'hide',
5496
- enabled: true,
5497
- phase: 'main',
5498
- requiresIfExists: ['preventOverflow'],
5499
- fn: hide
5500
- });
5501
- ;// CONCATENATED MODULE: ./node_modules/@popperjs/core/lib/popper.js
5502
-
5503
-
5504
-
5505
-
5506
-
5507
-
5508
-
5509
-
5510
-
5511
-
5512
- var defaultModifiers = [eventListeners, modifiers_popperOffsets, modifiers_computeStyles, modifiers_applyStyles, modifiers_offset, modifiers_flip, modifiers_preventOverflow, modifiers_arrow, modifiers_hide];
5513
- var popper_createPopper = /*#__PURE__*/popperGenerator({
5514
- defaultModifiers: defaultModifiers
5515
- }); // eslint-disable-next-line import/no-unused-modules
5516
-
5517
- // eslint-disable-next-line import/no-unused-modules
5518
-
5519
- // eslint-disable-next-line import/no-unused-modules
5520
-
5521
-
5522
- ;// CONCATENATED MODULE: ./lib/ts/controllers/s-popover.ts
5523
-
5746
+ ;// CONCATENATED MODULE: ./lib/components/table/table.ts
5524
5747
 
5525
- class BasePopoverController extends StacksController {
5526
- /**
5527
- * Returns true if the if the popover is currently visible.
5528
- */
5529
- get isVisible() {
5530
- const popoverElement = this.popoverElement;
5531
- return popoverElement
5532
- ? popoverElement.classList.contains("is-visible")
5533
- : false;
5748
+ /**
5749
+ * The string values of these enumerations should correspond with `aria-sort` valid values.
5750
+ *
5751
+ * @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-sort#values
5752
+ */
5753
+ var SortOrder;
5754
+ (function (SortOrder) {
5755
+ SortOrder["Ascending"] = "ascending";
5756
+ SortOrder["Descending"] = "descending";
5757
+ SortOrder["None"] = "none";
5758
+ })(SortOrder || (SortOrder = {}));
5759
+ class TableController extends StacksController {
5760
+ constructor() {
5761
+ super(...arguments);
5762
+ this.updateSortedColumnStyles = (targetColumnHeader, direction) => {
5763
+ // Loop through all sortable columns and remove their sorting direction
5764
+ // (if any), and only leave/set a sorting on `targetColumnHeader`.
5765
+ this.columnTargets.forEach((header) => {
5766
+ const isCurrent = header === targetColumnHeader;
5767
+ const classSuffix = isCurrent
5768
+ ? direction === SortOrder.Ascending
5769
+ ? "asc"
5770
+ : "desc"
5771
+ : SortOrder.None;
5772
+ header.classList.toggle("is-sorted", isCurrent && direction !== SortOrder.None);
5773
+ header.querySelectorAll(".js-sorting-indicator").forEach((icon) => {
5774
+ icon.classList.toggle("d-none", !icon.classList.contains("js-sorting-indicator-" + classSuffix));
5775
+ });
5776
+ if (isCurrent) {
5777
+ header.setAttribute("aria-sort", direction);
5778
+ }
5779
+ else {
5780
+ header.removeAttribute("aria-sort");
5781
+ }
5782
+ });
5783
+ };
5534
5784
  }
5535
- /**
5536
- * Gets whether the element is visible in the browser's viewport.
5537
- */
5538
- get isInViewport() {
5539
- const element = this.popoverElement;
5540
- if (!this.isVisible || !element) {
5541
- return false;
5785
+ sort(evt) {
5786
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
5787
+ const controller = this;
5788
+ const sortTriggerEl = evt.currentTarget;
5789
+ // TODO: support *only* button as trigger in next major release
5790
+ const triggerIsButton = sortTriggerEl instanceof HTMLButtonElement;
5791
+ // the below conditional is here for backward compatibility with the old API
5792
+ // where we did not advise buttons as sortable column head triggers
5793
+ const colHead = (triggerIsButton ? sortTriggerEl.parentElement : sortTriggerEl);
5794
+ const table = this.element;
5795
+ const tbody = table.tBodies[0];
5796
+ // the column slot number of the clicked header
5797
+ const colno = getCellSlot(colHead);
5798
+ if (colno < 0) {
5799
+ // this shouldn't happen if the clicked element is actually a column head
5800
+ return;
5542
5801
  }
5543
- // From https://stackoverflow.com/a/5354536. Theoretically, this could be calculated using Popper's detectOverflow function,
5544
- // but it's unclear how to access that with our current configuration.
5545
- const rect = element.getBoundingClientRect();
5546
- const viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
5547
- const viewWidth = Math.max(document.documentElement.clientWidth, window.innerWidth);
5548
- return (rect.bottom > 0 &&
5549
- rect.top < viewHeight &&
5550
- rect.right > 0 &&
5551
- rect.left < viewWidth);
5802
+ // an index of the <tbody>, so we can find out for each row which <td> element is
5803
+ // in the same column slot as the header
5804
+ const slotIndex = buildIndex(tbody);
5805
+ // the default behavior when clicking a header is to sort by this column in ascending
5806
+ // direction, *unless* it is already sorted that way
5807
+ const direction = colHead.getAttribute("aria-sort") === SortOrder.Ascending ? -1 : 1;
5808
+ const rows = Array.from(table.tBodies[0].rows);
5809
+ // if this is still false after traversing the data, that means all values are integers (or empty)
5810
+ // and thus we'll sort numerically.
5811
+ let anyNonInt = false;
5812
+ // data will be a list of tuples [value, rowNum], where value is what we're sorting by
5813
+ const data = [];
5814
+ let firstBottomRow;
5815
+ rows.forEach(function (row, index) {
5816
+ var _a, _b;
5817
+ const force = controller.getElementData(row, "sort-to");
5818
+ if (force === "top") {
5819
+ return; // rows not added to the list will automatically end up at the top
5820
+ }
5821
+ else if (force === "bottom") {
5822
+ if (!firstBottomRow) {
5823
+ firstBottomRow = row;
5824
+ }
5825
+ return;
5826
+ }
5827
+ const cell = slotIndex[index][colno];
5828
+ if (!cell) {
5829
+ data.push(["", index]);
5830
+ return;
5831
+ }
5832
+ // unless the to-be-sorted-by value is explicitly provided on the element via this attribute,
5833
+ // the value we're using is the cell's text, trimmed of any whitespace
5834
+ const explicit = controller.getElementData(cell, "sort-val");
5835
+ const d = (_b = explicit !== null && explicit !== void 0 ? explicit : (_a = cell.textContent) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : "";
5836
+ if (d !== "" && `${parseInt(d, 10)}` !== d) {
5837
+ anyNonInt = true;
5838
+ }
5839
+ data.push([d, index]);
5840
+ });
5841
+ // If all values were integers (or empty cells), sort numerically, with empty cells treated as
5842
+ // having the lowest possible value (i.e. sorted to the top if ascending, bottom if descending)
5843
+ if (!anyNonInt) {
5844
+ data.forEach(function (tuple) {
5845
+ tuple[0] =
5846
+ tuple[0] === ""
5847
+ ? Number.MIN_VALUE
5848
+ : parseInt(tuple[0], 10);
5849
+ });
5850
+ }
5851
+ // We don't sort an array of <tr>, but instead an arrays of row *numbers*, because this way we
5852
+ // can enforce stable sorting, i.e. rows that compare equal are guaranteed to remain in the same
5853
+ // order (the JS standard does not gurantee this for sort()).
5854
+ data.sort(function (a, b) {
5855
+ // first compare the values (a[0])
5856
+ if (a[0] > b[0]) {
5857
+ return 1 * direction;
5858
+ }
5859
+ else if (a[0] < b[0]) {
5860
+ return -1 * direction;
5861
+ }
5862
+ else {
5863
+ // if the values are equal, compare the row numbers (a[1]) to guarantee stable sorting
5864
+ // (note that this comparison is independent of the sorting direction)
5865
+ return a[1] > b[1] ? 1 : -1;
5866
+ }
5867
+ });
5868
+ // this is the actual reordering of the table rows
5869
+ data.forEach(([_, rowIndex]) => {
5870
+ var _a;
5871
+ const row = rows[rowIndex];
5872
+ (_a = row.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(row);
5873
+ if (firstBottomRow) {
5874
+ tbody.insertBefore(row, firstBottomRow);
5875
+ }
5876
+ else {
5877
+ tbody.appendChild(row);
5878
+ }
5879
+ });
5880
+ // update the UI and set the `data-sort-direction` attribute if appropriate, so that the next click
5881
+ // will cause sorting in descending direction
5882
+ this.updateSortedColumnStyles(colHead, direction === 1 ? SortOrder.Ascending : SortOrder.Descending);
5883
+ }
5884
+ }
5885
+ TableController.targets = ["column"];
5886
+
5887
+ /**
5888
+ * @internal This function is exported for testing purposes but is not a part of our public API
5889
+ *
5890
+ * @param section
5891
+ */
5892
+ function buildIndex(section) {
5893
+ const result = buildIndexOrGetCellSlot(section);
5894
+ if (!Array.isArray(result)) {
5895
+ throw "shouldn't happen";
5552
5896
  }
5553
- get shouldHideOnOutsideClick() {
5554
- const hideBehavior = (this.data.get("hide-on-outside-click"));
5555
- switch (hideBehavior) {
5556
- case "after-dismissal":
5557
- case "never":
5558
- return false;
5559
- case "if-in-viewport":
5560
- return this.isInViewport;
5561
- default:
5562
- return true;
5897
+ return result;
5898
+ }
5899
+ /**
5900
+ * @internal This function is exported for testing purposes but is not a part of our public API
5901
+ *
5902
+ * @param cell
5903
+ */
5904
+ function getCellSlot(cell) {
5905
+ var _a;
5906
+ const tableElement = (_a = cell.parentElement) === null || _a === void 0 ? void 0 : _a.parentElement;
5907
+ if (!(tableElement instanceof HTMLTableSectionElement)) {
5908
+ throw "invalid table";
5909
+ }
5910
+ const result = buildIndexOrGetCellSlot(tableElement, cell);
5911
+ if (typeof result !== "number") {
5912
+ throw "shouldn't happen";
5913
+ }
5914
+ return result;
5915
+ }
5916
+ /**
5917
+ * Just because a <td> is the 4th *child* of its <tr> doesn't mean it belongs to the 4th *column*
5918
+ * of the table. Previous cells may have a colspan; cells in previous rows may have a rowspan.
5919
+ * Because we need to know which header cells and data cells belong together, we have to 1) find out
5920
+ * which column number (or "slot" as we call it here) the header cell has, and 2) for each row find
5921
+ * out which <td> cell corresponds to this slot (because those are the rows we're sorting by).
5922
+ *
5923
+ * That's what the following function does. If the second argument is not given, it returns an index
5924
+ * of the table, which is an array of arrays. Each of the sub-arrays corresponds to a table row. The
5925
+ * indices of the sub-array correspond to column slots; the values are the actual table cell elements.
5926
+ * For example index[4][3] is the <td> or <th> in row 4, column 3 of the table section (<tbody> or <thead>).
5927
+ * Note that this element is not necessarily even in the 4th (zero-based) <tr> -- if it has a rowSpan > 1,
5928
+ * it may also be in a previous <tr>.
5929
+ *
5930
+ * If the second argument is given, it's a <td> or <th> that we're trying to find, and the algorithm
5931
+ * stops as soon as it has found it and the function returns its slot number.
5932
+ */
5933
+ function buildIndexOrGetCellSlot(section, findCell) {
5934
+ const index = [];
5935
+ let curRow = section.children[0];
5936
+ // the elements of these two arrays are synchronized; the first array contains table cell elements,
5937
+ // the second one contains a number that indicates for how many more rows this elements will
5938
+ // exist (i.e. the value is initially one less than the cell's rowspan, and will be decreased for each row)
5939
+ const growing = [];
5940
+ const growingRowsLeft = [];
5941
+ // continue while we have actual <tr>'s left *or* we still have rowspan'ed elements that aren't done
5942
+ while (curRow || growingRowsLeft.some((e) => e !== 0)) {
5943
+ const curIndexRow = [];
5944
+ index.push(curIndexRow);
5945
+ let curSlot = 0;
5946
+ if (curRow) {
5947
+ for (let curCellIdx = 0; curCellIdx < curRow.children.length; curCellIdx++) {
5948
+ while (growingRowsLeft[curSlot]) {
5949
+ growingRowsLeft[curSlot]--;
5950
+ curIndexRow[curSlot] = growing[curSlot];
5951
+ curSlot++;
5952
+ }
5953
+ const cell = curRow.children[curCellIdx];
5954
+ if (!(cell instanceof HTMLTableCellElement)) {
5955
+ throw "invalid table";
5956
+ }
5957
+ if (getComputedStyle(cell).display === "none") {
5958
+ continue;
5959
+ }
5960
+ if (cell === findCell) {
5961
+ return curSlot;
5962
+ }
5963
+ const nextFreeSlot = curSlot + cell.colSpan;
5964
+ for (; curSlot < nextFreeSlot; curSlot++) {
5965
+ growingRowsLeft[curSlot] = cell.rowSpan - 1; // if any of these is already growing, the table is broken -- no guarantees of anything
5966
+ growing[curSlot] = cell;
5967
+ curIndexRow[curSlot] = cell;
5968
+ }
5969
+ }
5970
+ }
5971
+ while (curSlot < growing.length) {
5972
+ if (growingRowsLeft[curSlot]) {
5973
+ growingRowsLeft[curSlot]--;
5974
+ curIndexRow[curSlot] = growing[curSlot];
5975
+ }
5976
+ curSlot++;
5977
+ }
5978
+ if (curRow) {
5979
+ curRow = curRow.nextElementSibling;
5563
5980
  }
5564
5981
  }
5565
- /**
5566
- * Initializes and validates controller variables
5567
- */
5982
+ // if findCell was given, but we end up here, that means it isn't in this section
5983
+ return findCell ? -1 : index;
5984
+ }
5985
+
5986
+ ;// CONCATENATED MODULE: ./lib/components/toast/toast.ts
5987
+
5988
+ class ToastController extends StacksController {
5568
5989
  connect() {
5569
- super.connect();
5570
5990
  this.validate();
5571
- if (this.isVisible) {
5572
- // just call initialize here, not show. This keeps already visible popovers from adding/firing document events
5573
- this.initializePopper();
5574
- }
5575
- else if (this.data.get("auto-show") === "true") {
5576
- this.show(null);
5577
- }
5578
- this.data.delete("auto-show");
5579
5991
  }
5580
5992
  /**
5581
- * Cleans up popper.js elements and disconnects all added event listeners
5993
+ * Disconnects all added event listeners on controller disconnect
5582
5994
  */
5583
5995
  disconnect() {
5584
- this.hide();
5585
- if (this.popper) {
5586
- this.popper.destroy();
5587
- // eslint-disable-next-line
5588
- // @ts-ignore The operand of a 'delete' operator must be optional .ts(2790)
5589
- delete this.popper;
5590
- }
5591
- super.disconnect();
5996
+ this.unbindDocumentEvents();
5592
5997
  }
5593
5998
  /**
5594
- * Toggles the visibility of the popover
5999
+ * Toggles the visibility of the toast
5595
6000
  */
5596
6001
  toggle(dispatcher = null) {
5597
- this.isVisible ? this.hide(dispatcher) : this.show(dispatcher);
6002
+ this._toggle(undefined, dispatcher);
5598
6003
  }
5599
6004
  /**
5600
- * Shows the popover if not already visible
6005
+ * Shows the toast
5601
6006
  */
5602
6007
  show(dispatcher = null) {
5603
- if (this.isVisible) {
5604
- return;
5605
- }
5606
- const dispatcherElement = this.getDispatcher(dispatcher);
5607
- if (this.triggerEvent("show", {
5608
- dispatcher: dispatcherElement,
5609
- }).defaultPrevented) {
5610
- return;
5611
- }
5612
- if (!this.popper) {
5613
- this.initializePopper();
5614
- }
5615
- this.popoverElement.classList.add("is-visible");
5616
- // ensure the popper has been positioned correctly
5617
- this.scheduleUpdate();
5618
- this.shown(dispatcherElement);
6008
+ this._toggle(true, dispatcher);
5619
6009
  }
5620
6010
  /**
5621
- * Hides the popover if not already hidden
6011
+ * Hides the toast
5622
6012
  */
5623
6013
  hide(dispatcher = null) {
5624
- if (!this.isVisible) {
5625
- return;
5626
- }
5627
- const dispatcherElement = this.getDispatcher(dispatcher);
5628
- if (this.triggerEvent("hide", {
5629
- dispatcher: dispatcherElement,
5630
- }).defaultPrevented) {
5631
- return;
5632
- }
5633
- this.popoverElement.classList.remove("is-visible");
5634
- if (this.popper) {
5635
- // completely destroy the popper on hide; this is in line with Popper.js's performance recommendations
5636
- this.popper.destroy();
5637
- // eslint-disable-next-line
5638
- // @ts-ignore The operand of a 'delete' operator must be optional .ts(2790)
5639
- delete this.popper;
5640
- }
5641
- // on first interaction, hide-on-outside-click with value "after-dismissal" reverts to the default behavior
5642
- if (this.data.get("hide-on-outside-click") ===
5643
- "after-dismissal") {
5644
- this.data.delete("hide-on-outside-click");
5645
- }
5646
- this.hidden(dispatcherElement);
5647
- }
5648
- /**
5649
- * Binds document events for this popover and fires the shown event
5650
- */
5651
- shown(dispatcher = null) {
5652
- this.bindDocumentEvents();
5653
- this.triggerEvent("shown", {
5654
- dispatcher: dispatcher,
5655
- });
5656
- }
5657
- /**
5658
- * Unbinds document events for this popover and fires the hidden event
5659
- */
5660
- hidden(dispatcher = null) {
5661
- this.unbindDocumentEvents();
5662
- this.triggerEvent("hidden", {
5663
- dispatcher: dispatcher,
5664
- });
5665
- }
5666
- /**
5667
- * Generates the popover if not found during initialization
5668
- */
5669
- generatePopover() {
5670
- return null;
6014
+ this._toggle(false, dispatcher);
5671
6015
  }
5672
6016
  /**
5673
- * Initializes the Popper for this instance
6017
+ * Validates the toast settings and attempts to set necessary internal variables
5674
6018
  */
5675
- initializePopper() {
5676
- this.popper = popper_createPopper(this.referenceElement, this.popoverElement, {
5677
- placement: this.data.get("placement") || "bottom",
5678
- modifiers: [
5679
- {
5680
- name: "offset",
5681
- options: {
5682
- offset: [0, 10], // The entire popover should be 10px away from the element
5683
- },
5684
- },
5685
- {
5686
- name: "arrow",
5687
- options: {
5688
- element: ".s-popover--arrow",
5689
- },
5690
- },
5691
- ],
5692
- });
6019
+ validate() {
6020
+ // check for returnElement support
6021
+ const returnElementSelector = this.data.get("return-element");
6022
+ if (returnElementSelector) {
6023
+ this.returnElement = (document.querySelector(returnElementSelector));
6024
+ if (!this.returnElement) {
6025
+ throw ("Unable to find element by return-element selector: " +
6026
+ returnElementSelector);
6027
+ }
6028
+ }
5693
6029
  }
5694
6030
  /**
5695
- * Validates the popover settings and attempts to set necessary internal variables
6031
+ * Toggles the visibility of the toast element
6032
+ * @param show Optional parameter that force shows/hides the element or toggles it if left undefined
5696
6033
  */
5697
- validate() {
5698
- const referenceSelector = this.data.get("reference-selector");
5699
- this.referenceElement = this.element;
5700
- // if there is an alternative reference selector and that element exists, use it (and throw if it isn't found)
5701
- if (referenceSelector) {
5702
- this.referenceElement = (this.element.querySelector(referenceSelector));
5703
- if (!this.referenceElement) {
5704
- throw ("Unable to find element by reference selector: " +
5705
- referenceSelector);
5706
- }
6034
+ _toggle(show, dispatcher = null) {
6035
+ let toShow = show;
6036
+ const isVisible = this.toastTarget.getAttribute("aria-hidden") === "false";
6037
+ // if we're letting the class toggle, we need to figure out if the toast is visible manually
6038
+ if (typeof toShow === "undefined") {
6039
+ toShow = !isVisible;
5707
6040
  }
5708
- const popoverId = this.referenceElement.getAttribute(this.popoverSelectorAttribute);
5709
- let popoverElement = null;
5710
- // if the popover is named, attempt to fetch it (and throw an error if it doesn't exist)
5711
- if (popoverId) {
5712
- popoverElement = document.getElementById(popoverId);
5713
- if (!popoverElement) {
5714
- throw `[${this.popoverSelectorAttribute}="{POPOVER_ID}"] required`;
6041
+ // if the state matches the disired state, return without changing anything
6042
+ if ((toShow && isVisible) || (!toShow && !isVisible)) {
6043
+ return;
6044
+ }
6045
+ const dispatchingElement = this.getDispatcher(dispatcher);
6046
+ // show/hide events trigger before toggling the class
6047
+ const triggeredEvent = this.triggerEvent(toShow ? "show" : "hide", {
6048
+ returnElement: this.returnElement,
6049
+ dispatcher: this.getDispatcher(dispatchingElement),
6050
+ }, this.toastTarget);
6051
+ // if this pre-show/hide event was prevented, don't attempt to continue changing the toast state
6052
+ if (triggeredEvent.defaultPrevented) {
6053
+ return;
6054
+ }
6055
+ this.returnElement = triggeredEvent.detail.returnElement;
6056
+ this.toastTarget.setAttribute("aria-hidden", toShow ? "false" : "true");
6057
+ if (toShow) {
6058
+ this.bindDocumentEvents();
6059
+ this.hideAfterTimeout();
6060
+ if (this.data.get("prevent-focus-capture") !== "true") {
6061
+ this.focusInsideToast();
5715
6062
  }
5716
6063
  }
5717
- // if the popover isn't named, attempt to generate it
5718
6064
  else {
5719
- popoverElement = this.generatePopover();
5720
- }
5721
- if (!popoverElement) {
5722
- throw "unable to find or generate popover element";
6065
+ this.unbindDocumentEvents();
6066
+ this.focusReturnElement();
6067
+ this.removeToastOnHide();
6068
+ this.clearActiveTimeout();
6069
+ }
6070
+ // check for transitionend support
6071
+ const supportsTransitionEnd = this.toastTarget.ontransitionend !== undefined;
6072
+ // shown/hidden events trigger after toggling the class
6073
+ if (supportsTransitionEnd) {
6074
+ // wait until after the toast finishes transitioning to fire the event
6075
+ this.toastTarget.addEventListener("transitionend", () => {
6076
+ //TODO this is firing waaay to soon?
6077
+ this.triggerEvent(toShow ? "shown" : "hidden", {
6078
+ dispatcher: dispatchingElement,
6079
+ }, this.toastTarget);
6080
+ }, { once: true });
6081
+ }
6082
+ else {
6083
+ this.triggerEvent(toShow ? "shown" : "hidden", {
6084
+ dispatcher: dispatchingElement,
6085
+ }, this.toastTarget);
5723
6086
  }
5724
- this.popoverElement = popoverElement;
5725
6087
  }
5726
6088
  /**
5727
- * Determines the correct dispatching element from a potential input
5728
- * @param dispatcher The event or element to get the dispatcher from
6089
+ * Listens for the s-toast:hidden event and focuses the returnElement when it is fired
5729
6090
  */
5730
- getDispatcher(dispatcher = null) {
5731
- if (dispatcher instanceof Event) {
5732
- return dispatcher.target;
5733
- }
5734
- else if (dispatcher instanceof Element) {
5735
- return dispatcher;
6091
+ focusReturnElement() {
6092
+ if (!this.returnElement) {
6093
+ return;
5736
6094
  }
5737
- else {
5738
- return this.element;
6095
+ this.toastTarget.addEventListener("s-toast:hidden", () => {
6096
+ // double check the element still exists when the event is called
6097
+ if (this.returnElement &&
6098
+ document.body.contains(this.returnElement)) {
6099
+ this.returnElement.focus();
6100
+ }
6101
+ }, { once: true });
6102
+ }
6103
+ /**
6104
+ * Remove the element on hide if the `remove-when-hidden` flag is set
6105
+ */
6106
+ removeToastOnHide() {
6107
+ if (this.data.get("remove-when-hidden") !== "true") {
6108
+ return;
5739
6109
  }
6110
+ this.toastTarget.addEventListener("s-toast:hidden", () => {
6111
+ this.element.remove();
6112
+ }, { once: true });
5740
6113
  }
5741
6114
  /**
5742
- * Schedules the popover to update on the next animation frame if visible
6115
+ * Hide the element after a delay
5743
6116
  */
5744
- scheduleUpdate() {
5745
- if (this.popper && this.isVisible) {
5746
- void this.popper.update();
6117
+ hideAfterTimeout() {
6118
+ if (this.data.get("prevent-auto-hide") === "true" ||
6119
+ this.data.get("hide-after-timeout") === "0") {
6120
+ return;
5747
6121
  }
6122
+ const timeout = parseInt(this.data.get("hide-after-timeout"), 10) || 3000;
6123
+ this.activeTimeout = window.setTimeout(() => this.hide(), timeout);
5748
6124
  }
5749
- }
5750
- class PopoverController extends BasePopoverController {
5751
- constructor() {
5752
- super(...arguments);
5753
- this.popoverSelectorAttribute = "aria-controls";
6125
+ /**
6126
+ * Cancels the activeTimeout
6127
+ */
6128
+ clearActiveTimeout() {
6129
+ clearTimeout(this.activeTimeout);
5754
6130
  }
5755
6131
  /**
5756
- * Toggles optional classes and accessibility attributes in addition to BasePopoverController.shown
6132
+ * Gets all elements within the toast that could receive keyboard focus.
5757
6133
  */
5758
- shown(dispatcher = null) {
5759
- this.toggleOptionalClasses(true);
5760
- this.toggleAccessibilityAttributes(true);
5761
- super.shown(dispatcher);
6134
+ getAllTabbables() {
6135
+ return Array.from(this.toastTarget.querySelectorAll("[href], input, select, textarea, button, [tabindex]")).filter((el) => el.matches(":not([disabled]):not([tabindex='-1'])"));
5762
6136
  }
5763
6137
  /**
5764
- * Toggles optional classes and accessibility attributes in addition to BasePopoverController.hidden
6138
+ * Returns the first visible element in an array or `undefined` if no elements are visible.
5765
6139
  */
5766
- hidden(dispatcher = null) {
5767
- this.toggleOptionalClasses(false);
5768
- this.toggleAccessibilityAttributes(false);
5769
- super.hidden(dispatcher);
6140
+ firstVisible(elements) {
6141
+ // https://stackoverflow.com/a/21696585
6142
+ return elements === null || elements === void 0 ? void 0 : elements.find((el) => el.offsetParent !== null);
5770
6143
  }
5771
6144
  /**
5772
- * Initializes accessibility attributes in addition to BasePopoverController.connect
6145
+ * Attempts to shift keyboard focus into the toast.
6146
+ * If elements with `data-s-toast-target="initialFocus"` are present and visible, one of those will be selected.
6147
+ * Otherwise, the first visible focusable element will receive focus.
5773
6148
  */
5774
- connect() {
5775
- super.connect();
5776
- this.toggleAccessibilityAttributes();
6149
+ focusInsideToast() {
6150
+ this.toastTarget.addEventListener("s-toast:shown", () => {
6151
+ var _a;
6152
+ const initialFocus = (_a = this.firstVisible(this.initialFocusTargets)) !== null && _a !== void 0 ? _a : this.firstVisible(this.getAllTabbables());
6153
+ initialFocus === null || initialFocus === void 0 ? void 0 : initialFocus.focus();
6154
+ }, { once: true });
5777
6155
  }
5778
6156
  /**
5779
- * Binds global events to the document for hiding popovers on user interaction
6157
+ * Binds global events to the document for hiding toasts on user interaction
5780
6158
  */
5781
6159
  bindDocumentEvents() {
5782
- this.boundHideOnOutsideClick =
5783
- this.boundHideOnOutsideClick || this.hideOnOutsideClick.bind(this);
5784
- this.boundHideOnEscapePress =
5785
- this.boundHideOnEscapePress || this.hideOnEscapePress.bind(this);
5786
- document.addEventListener("mousedown", this.boundHideOnOutsideClick);
5787
- document.addEventListener("keyup", this.boundHideOnEscapePress);
6160
+ // in order for removeEventListener to remove the right event, this bound function needs a constant reference
6161
+ this._boundClickFn =
6162
+ this._boundClickFn || this.hideOnOutsideClick.bind(this);
6163
+ this._boundKeypressFn =
6164
+ this._boundKeypressFn || this.hideOnEscapePress.bind(this);
6165
+ document.addEventListener("mousedown", this._boundClickFn);
6166
+ document.addEventListener("keyup", this._boundKeypressFn);
5788
6167
  }
5789
6168
  /**
5790
- * Unbinds global events to the document for hiding popovers on user interaction
6169
+ * Unbinds global events to the document for hiding toasts on user interaction
5791
6170
  */
5792
6171
  unbindDocumentEvents() {
5793
- document.removeEventListener("mousedown", this.boundHideOnOutsideClick);
5794
- document.removeEventListener("keyup", this.boundHideOnEscapePress);
6172
+ document.removeEventListener("mousedown", this._boundClickFn);
6173
+ document.removeEventListener("keyup", this._boundKeypressFn);
5795
6174
  }
5796
6175
  /**
5797
- * Forces the popover to hide if a user clicks outside of it or its reference element
5798
- * @param {Event} e - The document click event
6176
+ * Forces the toast to hide if a user clicks outside of it or its reference element
5799
6177
  */
5800
6178
  hideOnOutsideClick(e) {
6179
+ var _a;
5801
6180
  const target = e.target;
5802
- // check if the document was clicked inside either the reference element or the popover itself
6181
+ // check if the document was clicked inside either the toggle element or the toast itself
5803
6182
  // note: .contains also returns true if the node itself matches the target element
5804
- if (this.shouldHideOnOutsideClick &&
5805
- !this.referenceElement.contains(target) &&
5806
- !this.popoverElement.contains(target) &&
5807
- document.body.contains(target)) {
5808
- this.hide(e);
6183
+ if (!((_a = this.toastTarget) === null || _a === void 0 ? void 0 : _a.contains(target)) &&
6184
+ document.body.contains(target) &&
6185
+ this.data.get("hide-on-outside-click") !== "false") {
6186
+ this._toggle(false, e);
5809
6187
  }
5810
6188
  }
5811
6189
  /**
5812
- * Forces the popover to hide if the user presses escape while it, one of its childen, or the reference element are focused
5813
- * @param {Event} e - The document keyup event
6190
+ * Forces the toast to hide if the user presses escape while it, one of its childen, or the reference element are focused
5814
6191
  */
5815
6192
  hideOnEscapePress(e) {
5816
- // if the ESC key (27) wasn't pressed or if no popovers are showing, return
5817
- if (e.which !== 27 || !this.isVisible) {
5818
- return;
5819
- }
5820
- // check if the target was inside the popover element and refocus the triggering element
5821
- // note: .contains also returns true if the node itself matches the target element
5822
- if (this.popoverElement.contains(e.target)) {
5823
- this.referenceElement.focus();
5824
- }
5825
- this.hide(e);
5826
- }
5827
- /**
5828
- * Toggles all classes on the originating element based on the `class-toggle` data
5829
- * @param {boolean=} show - A boolean indicating whether this is being triggered by a show or hide.
5830
- */
5831
- toggleOptionalClasses(show) {
5832
- if (!this.data.has("toggle-class")) {
5833
- return;
5834
- }
5835
- const toggleClass = this.data.get("toggle-class") || "";
5836
- const cl = this.referenceElement.classList;
5837
- toggleClass.split(/\s+/).forEach(function (cls) {
5838
- cl.toggle(cls, show);
5839
- });
5840
- }
5841
- /**
5842
- * Toggles accessibility attributes based on whether the popover is shown or not
5843
- * @param {boolean=} show - A boolean indicating whether this is being triggered by a show or hide.
5844
- */
5845
- toggleAccessibilityAttributes(show) {
5846
- const expandedValue = (show === null || show === void 0 ? void 0 : show.toString()) || this.referenceElement.ariaExpanded || "false";
5847
- this.referenceElement.ariaExpanded = expandedValue;
5848
- this.referenceElement.setAttribute("aria-expanded", expandedValue);
5849
- }
5850
- }
5851
- PopoverController.targets = [];
5852
- /**
5853
- * Helper to manually show an s-popover element via external JS
5854
- * @param element the element the `data-controller="s-popover"` attribute is on
5855
- */
5856
- function showPopover(element) {
5857
- const { isPopover, controller } = getPopover(element);
5858
- if (controller) {
5859
- controller.show();
5860
- }
5861
- else if (isPopover) {
5862
- element.setAttribute("data-s-popover-auto-show", "true");
5863
- }
5864
- else {
5865
- throw `element does not have data-controller="s-popover"`;
5866
- }
5867
- }
5868
- /**
5869
- * Helper to manually hide an s-popover element via external JS
5870
- * @param element the element the `data-controller="s-popover"` attribute is on
5871
- */
5872
- function hidePopover(element) {
5873
- const { isPopover, controller, popover } = getPopover(element);
5874
- if (controller) {
5875
- controller.hide();
5876
- }
5877
- else if (isPopover) {
5878
- element.removeAttribute("data-s-popover-auto-show");
5879
- if (popover) {
5880
- popover.classList.remove("is-visible");
5881
- }
5882
- }
5883
- else {
5884
- throw `element does not have data-controller="s-popover"`;
5885
- }
5886
- }
5887
- /**
5888
- * Attaches a popover to an element and performs additional configuration.
5889
- * @param element the element that will receive the `data-controller="s-popover"` attribute.
5890
- * @param popover an element with the `.s-popover` class or HTML string containing a single element with the `.s-popover` class.
5891
- * If the popover does not have a parent element, it will be inserted as a immediately after the reference element.
5892
- * @param options an optional collection of options to use when configuring the popover.
5893
- */
5894
- function attachPopover(element, popover, options) {
5895
- const { referenceElement, popover: existingPopover } = getPopover(element);
5896
- if (existingPopover) {
5897
- throw `element already has popover with id="${existingPopover.id}"`;
5898
- }
5899
- if (!referenceElement) {
5900
- throw `element has invalid data-s-popover-reference-selector attribute`;
5901
- }
5902
- if (typeof popover === "string") {
5903
- // eslint-disable-next-line no-unsanitized/method
5904
- const elements = document
5905
- .createRange()
5906
- .createContextualFragment(popover).children;
5907
- if (elements.length !== 1) {
5908
- throw "popover should contain a single element";
5909
- }
5910
- popover = elements[0];
5911
- }
5912
- const existingId = referenceElement.getAttribute("aria-controls");
5913
- let popoverId = popover.id;
5914
- if (!popover.classList.contains("s-popover")) {
5915
- throw `popover should have the "s-popover" class but had class="${popover.className}"`;
5916
- }
5917
- if (existingId && existingId !== popoverId) {
5918
- throw `element has aria-controls="${existingId}" but popover has id="${popoverId}"`;
5919
- }
5920
- if (!popoverId) {
5921
- popoverId =
5922
- "--stacks-s-popover-" + Math.random().toString(36).substring(2, 10);
5923
- popover.id = popoverId;
5924
- }
5925
- if (!existingId) {
5926
- referenceElement.setAttribute("aria-controls", popoverId);
5927
- }
5928
- if (!popover.parentElement && element.parentElement) {
5929
- referenceElement.insertAdjacentElement("afterend", popover);
6193
+ // if the ESC key (27) wasn't pressed or if no toasts are showing, return
6194
+ if (e.which !== 27 ||
6195
+ this.toastTarget.getAttribute("aria-hidden") === "true") {
6196
+ return;
6197
+ }
6198
+ this._toggle(false, e);
5930
6199
  }
5931
- toggleController(element, "s-popover", true);
5932
- if (options) {
5933
- if (options.toggleOnClick) {
5934
- referenceElement.setAttribute("data-action", "click->s-popover#toggle");
6200
+ /**
6201
+ * Determines the correct dispatching element from a potential input
6202
+ * @param dispatcher The event or element to get the dispatcher from
6203
+ */
6204
+ getDispatcher(dispatcher = null) {
6205
+ if (dispatcher instanceof Event) {
6206
+ return dispatcher.target;
5935
6207
  }
5936
- if (options.placement) {
5937
- element.setAttribute("data-s-popover-placement", options.placement);
6208
+ else if (dispatcher instanceof Element) {
6209
+ return dispatcher;
5938
6210
  }
5939
- if (options.autoShow) {
5940
- element.setAttribute("data-s-popover-auto-show", "true");
6211
+ else {
6212
+ return this.element;
5941
6213
  }
5942
6214
  }
5943
6215
  }
6216
+ ToastController.targets = ["toast", "initialFocus"];
6217
+
5944
6218
  /**
5945
- * Removes the popover controller from an element and removes the popover from the DOM.
5946
- * @param element the element that has the `data-controller="s-popover"` attribute.
5947
- * @returns The popover that was attached to the element.
6219
+ * Helper to manually show an s-toast element via external JS
6220
+ * @param element the element the `data-controller="s-toast"` attribute is on
5948
6221
  */
5949
- function detachPopover(element) {
5950
- const { isPopover, controller, referenceElement, popover } = getPopover(element);
5951
- // Hide the popover so its events fire.
5952
- controller === null || controller === void 0 ? void 0 : controller.hide();
5953
- // Remove the popover if it exists
5954
- popover === null || popover === void 0 ? void 0 : popover.remove();
5955
- // Remove the popover controller and the aria-controls attributes.
5956
- if (isPopover) {
5957
- toggleController(element, "s-popover", false);
5958
- if (referenceElement) {
5959
- referenceElement.removeAttribute("aria-controls");
5960
- }
5961
- }
5962
- return popover;
6222
+ function showToast(element) {
6223
+ toggleToast(element, true);
5963
6224
  }
5964
6225
  /**
5965
- * Gets the current state of an element that may be or is intended to be an s-popover controller
5966
- * so it can be configured either directly or via the DOM.
5967
- * @param element An element that may have `data-controller="s-popover"`.
6226
+ * Helper to manually hide an s-toast element via external JS
6227
+ * @param element the element the `data-controller="s-toast"` attribute is on
5968
6228
  */
5969
- function getPopover(element) {
5970
- var _a;
5971
- const isPopover = ((_a = element.getAttribute("data-controller")) === null || _a === void 0 ? void 0 : _a.includes("s-popover")) || false;
5972
- const controller = application.getControllerForElementAndIdentifier(element, "s-popover");
5973
- const referenceSelector = element.getAttribute("data-s-popover-reference-selector");
5974
- const referenceElement = referenceSelector
5975
- ? element.querySelector(referenceSelector)
5976
- : element;
5977
- const popoverId = referenceElement
5978
- ? referenceElement.getAttribute("aria-controls")
5979
- : null;
5980
- const popover = popoverId ? document.getElementById(popoverId) : null;
5981
- return { isPopover, controller, referenceElement, popover };
6229
+ function hideToast(element) {
6230
+ toggleToast(element, false);
5982
6231
  }
5983
6232
  /**
5984
- * Adds or removes the controller from an element's [data-controller] attribute without altering existing entries
5985
- * @param el The element to alter
5986
- * @param controllerName The name of the controller to add/remove
5987
- * @param include Whether to add the controllerName value
6233
+ * Helper to manually show an s-toast element via external JS
6234
+ * @param element the element the `data-controller="s-toast"` attribute is on
6235
+ * @param show whether to force show/hide the toast; toggles the toast if left undefined
5988
6236
  */
5989
- function toggleController(el, controllerName, include) {
5990
- var _a;
5991
- const controllers = new Set((_a = el.getAttribute("data-controller")) === null || _a === void 0 ? void 0 : _a.split(/\s+/));
5992
- if (include) {
5993
- controllers.add(controllerName);
5994
- }
5995
- else {
5996
- controllers.delete(controllerName);
5997
- }
5998
- el.setAttribute("data-controller", Array.from(controllers).join(" "));
5999
- }
6000
-
6001
- ;// CONCATENATED MODULE: ./lib/ts/controllers/s-table.ts
6002
-
6003
- class TableController extends StacksController {
6004
- setCurrentSort(headElem, direction) {
6005
- if (["asc", "desc", "none"].indexOf(direction) < 0) {
6006
- throw "direction must be one of asc, desc, or none";
6007
- }
6008
- // eslint-disable-next-line @typescript-eslint/no-this-alias
6009
- const controller = this;
6010
- this.columnTargets.forEach(function (target) {
6011
- const isCurrrent = target === headElem;
6012
- target.classList.toggle("is-sorted", isCurrrent && direction !== "none");
6013
- target
6014
- .querySelectorAll(".js-sorting-indicator")
6015
- .forEach(function (icon) {
6016
- const visible = isCurrrent ? direction : "none";
6017
- icon.classList.toggle("d-none", !icon.classList.contains("js-sorting-indicator-" + visible));
6018
- });
6019
- if (!isCurrrent || direction === "none") {
6020
- controller.removeElementData(target, "sort-direction");
6021
- }
6022
- else {
6023
- controller.setElementData(target, "sort-direction", direction);
6024
- }
6025
- });
6026
- }
6027
- sort(evt) {
6028
- // eslint-disable-next-line @typescript-eslint/no-this-alias
6029
- const controller = this;
6030
- const colHead = evt.currentTarget;
6031
- if (!(colHead instanceof HTMLTableCellElement)) {
6032
- throw "invalid event target";
6033
- }
6034
- const table = this.element;
6035
- const tbody = table.tBodies[0];
6036
- // the column slot number of the clicked header
6037
- const colno = getCellSlot(colHead);
6038
- if (colno < 0) {
6039
- // this shouldn't happen if the clicked element is actually a column head
6040
- return;
6041
- }
6042
- // an index of the <tbody>, so we can find out for each row which <td> element is
6043
- // in the same column slot as the header
6044
- const slotIndex = buildIndex(tbody);
6045
- // the default behavior when clicking a header is to sort by this column in ascending
6046
- // direction, *unless* it is already sorted that way
6047
- const direction = this.getElementData(colHead, "sort-direction") === "asc" ? -1 : 1;
6048
- const rows = Array.from(table.tBodies[0].rows);
6049
- // if this is still false after traversing the data, that means all values are integers (or empty)
6050
- // and thus we'll sort numerically.
6051
- let anyNonInt = false;
6052
- // data will be a list of tuples [value, rowNum], where value is what we're sorting by
6053
- const data = [];
6054
- let firstBottomRow;
6055
- rows.forEach(function (row, index) {
6056
- var _a, _b;
6057
- const force = controller.getElementData(row, "sort-to");
6058
- if (force === "top") {
6059
- return; // rows not added to the list will automatically end up at the top
6060
- }
6061
- else if (force === "bottom") {
6062
- if (!firstBottomRow) {
6063
- firstBottomRow = row;
6064
- }
6065
- return;
6066
- }
6067
- const cell = slotIndex[index][colno];
6068
- if (!cell) {
6069
- data.push(["", index]);
6070
- return;
6071
- }
6072
- // unless the to-be-sorted-by value is explicitly provided on the element via this attribute,
6073
- // the value we're using is the cell's text, trimmed of any whitespace
6074
- const explicit = controller.getElementData(cell, "sort-val");
6075
- const d = typeof explicit === "string"
6076
- ? explicit
6077
- : (_b = (_a = cell.textContent) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : "";
6078
- if (d !== "" && `${parseInt(d, 10)}` !== d) {
6079
- anyNonInt = true;
6080
- }
6081
- data.push([d, index]);
6082
- });
6083
- // If all values were integers (or empty cells), sort numerically, with empty cells treated as
6084
- // having the lowest possible value (i.e. sorted to the top if ascending, bottom if descending)
6085
- if (!anyNonInt) {
6086
- data.forEach(function (tuple) {
6087
- tuple[0] =
6088
- tuple[0] === ""
6089
- ? Number.MIN_VALUE
6090
- : parseInt(tuple[0], 10);
6091
- });
6092
- }
6093
- // We don't sort an array of <tr>, but instead an arrays of row *numbers*, because this way we
6094
- // can enforce stable sorting, i.e. rows that compare equal are guaranteed to remain in the same
6095
- // order (the JS standard does not gurantee this for sort()).
6096
- data.sort(function (a, b) {
6097
- // first compare the values (a[0])
6098
- if (a[0] > b[0]) {
6099
- return 1 * direction;
6100
- }
6101
- else if (a[0] < b[0]) {
6102
- return -1 * direction;
6103
- }
6104
- else {
6105
- // if the values are equal, compare the row numbers (a[1]) to guarantee stable sorting
6106
- // (note that this comparison is independent of the sorting direction)
6107
- return a[1] > b[1] ? 1 : -1;
6108
- }
6109
- });
6110
- // this is the actual reordering of the table rows
6111
- data.forEach(function (tup) {
6112
- var _a;
6113
- const row = rows[tup[1]];
6114
- (_a = row.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(row);
6115
- if (firstBottomRow) {
6116
- tbody.insertBefore(row, firstBottomRow);
6117
- }
6118
- else {
6119
- tbody.appendChild(row);
6120
- }
6121
- });
6122
- // update the UI and set the `data-sort-direction` attribute if appropriate, so that the next click
6123
- // will cause sorting in descending direction
6124
- this.setCurrentSort(colHead, direction === 1 ? "asc" : "desc");
6125
- }
6126
- }
6127
- TableController.targets = ["column"];
6128
- function buildIndex(section) {
6129
- const result = buildIndexOrGetCellSlot(section);
6130
- if (!(result instanceof Array)) {
6131
- throw "shouldn't happen";
6132
- }
6133
- return result;
6134
- }
6135
- function getCellSlot(cell) {
6136
- if (!(cell.parentElement &&
6137
- cell.parentElement.parentElement instanceof HTMLTableSectionElement)) {
6138
- throw "invalid table";
6139
- }
6140
- const result = buildIndexOrGetCellSlot(cell.parentElement.parentElement, cell);
6141
- if (typeof result !== "number") {
6142
- throw "shouldn't happen";
6143
- }
6144
- return result;
6145
- }
6146
- // Just because a <td> is the 4th *child* of its <tr> doesn't mean it belongs to the 4th *column*
6147
- // of the table. Previous cells may have a colspan; cells in previous rows may have a rowspan.
6148
- // Because we need to know which header cells and data cells belong together, we have to 1) find out
6149
- // which column number (or "slot" as we call it here) the header cell has, and 2) for each row find
6150
- // out which <td> cell corresponds to this slot (because those are the rows we're sorting by).
6151
- //
6152
- // That's what the following function does. If the second argument is not given, it returns an index
6153
- // of the table, which is an array of arrays. Each of the sub-arrays corresponds to a table row. The
6154
- // indices of the sub-array correspond to column slots; the values are the actual table cell elements.
6155
- // For example index[4][3] is the <td> or <th> in row 4, column 3 of the table section (<tbody> or <thead>).
6156
- // Note that this element is not necessarily even in the 4th (zero-based) <tr> -- if it has a rowSpan > 1,
6157
- // it may also be in a previous <tr>.
6158
- //
6159
- // If the second argument is given, it's a <td> or <th> that we're trying to find, and the algorithm
6160
- // stops as soon as it has found it and the function returns its slot number.
6161
- function buildIndexOrGetCellSlot(section, findCell) {
6162
- const index = [];
6163
- let curRow = section.children[0];
6164
- // the elements of these two arrays are synchronized; the first array contains table cell elements,
6165
- // the second one contains a number that indicates for how many more rows this elements will
6166
- // exist (i.e. the value is initially one less than the cell's rowspan, and will be decreased for each row)
6167
- const growing = [];
6168
- const growingRowsLeft = [];
6169
- // continue while we have actual <tr>'s left *or* we still have rowspan'ed elements that aren't done
6170
- while (curRow ||
6171
- growingRowsLeft.some(function (e) {
6172
- return e !== 0;
6173
- })) {
6174
- const curIndexRow = [];
6175
- index.push(curIndexRow);
6176
- let curSlot = 0;
6177
- if (curRow) {
6178
- for (let curCellInd = 0; curCellInd < curRow.children.length; curCellInd++) {
6179
- while (growingRowsLeft[curSlot]) {
6180
- growingRowsLeft[curSlot]--;
6181
- curIndexRow[curSlot] = growing[curSlot];
6182
- curSlot++;
6183
- }
6184
- const cell = curRow.children[curCellInd];
6185
- if (!(cell instanceof HTMLTableCellElement)) {
6186
- throw "invalid table";
6187
- }
6188
- if (getComputedStyle(cell).display === "none") {
6189
- continue;
6190
- }
6191
- if (cell === findCell) {
6192
- return curSlot;
6193
- }
6194
- const nextFreeSlot = curSlot + cell.colSpan;
6195
- for (; curSlot < nextFreeSlot; curSlot++) {
6196
- growingRowsLeft[curSlot] = cell.rowSpan - 1; // if any of these is already growing, the table is broken -- no guarantees of anything
6197
- growing[curSlot] = cell;
6198
- curIndexRow[curSlot] = cell;
6199
- }
6200
- }
6201
- }
6202
- while (curSlot < growing.length) {
6203
- if (growingRowsLeft[curSlot]) {
6204
- growingRowsLeft[curSlot]--;
6205
- curIndexRow[curSlot] = growing[curSlot];
6206
- }
6207
- curSlot++;
6208
- }
6209
- if (curRow) {
6210
- curRow = curRow.nextElementSibling;
6211
- }
6237
+ function toggleToast(element, show) {
6238
+ const controller = application.getControllerForElementAndIdentifier(element, "s-toast");
6239
+ if (!controller) {
6240
+ throw "Unable to get s-toast controller from element";
6212
6241
  }
6213
- return findCell
6214
- ? -1
6215
- : index; /* if findCell was given but we end up here, that means it isn't in this section */
6242
+ show ? controller.show() : controller.hide();
6216
6243
  }
6217
6244
 
6218
- ;// CONCATENATED MODULE: ./lib/ts/controllers/s-tooltip.ts
6245
+ ;// CONCATENATED MODULE: ./lib/components/popover/tooltip.ts
6219
6246
 
6220
6247
 
6221
6248
  class TooltipController extends BasePopoverController {
@@ -6426,6 +6453,7 @@ class TooltipController extends BasePopoverController {
6426
6453
  }
6427
6454
  }
6428
6455
  TooltipController.targets = [];
6456
+
6429
6457
  /**
6430
6458
  * Adds or updates a Stacks tooltip on a given element, initializing the controller if necessary
6431
6459
  * @param element The element to add a tooltip to.
@@ -6467,7 +6495,7 @@ function applyOptionsAndTitleAttributes(element, options) {
6467
6495
  }
6468
6496
  }
6469
6497
 
6470
- ;// CONCATENATED MODULE: ./lib/ts/controllers/s-uploader.ts
6498
+ ;// CONCATENATED MODULE: ./lib/components/uploader/uploader.ts
6471
6499
 
6472
6500
  class UploaderController extends StacksController {
6473
6501
  connect() {
@@ -6631,7 +6659,8 @@ UploaderController.targets = ["input", "previews", "uploader"];
6631
6659
  UploaderController.FILE_DISPLAY_LIMIT = 10;
6632
6660
  UploaderController.MAX_FILE_SIZE = 1024 * 1024 * 10; // 10 MB
6633
6661
 
6634
- ;// CONCATENATED MODULE: ./lib/ts/controllers/index.ts
6662
+
6663
+ ;// CONCATENATED MODULE: ./lib/controllers.ts
6635
6664
  // export all controllers *with helpers* so they can be bulk re-exported by the package entry point
6636
6665
 
6637
6666
 
@@ -6643,7 +6672,7 @@ UploaderController.MAX_FILE_SIZE = 1024 * 1024 * 10; // 10 MB
6643
6672
 
6644
6673
 
6645
6674
 
6646
- ;// CONCATENATED MODULE: ./lib/ts/index.ts
6675
+ ;// CONCATENATED MODULE: ./lib/index.ts
6647
6676
 
6648
6677
 
6649
6678