@stackoverflow/stacks 1.7.1 → 1.9.0
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.
- package/README.md +1 -1
- package/dist/components/activity-indicator/activity-indicator.a11y.test.d.ts +1 -0
- package/dist/components/activity-indicator/activity-indicator.visual.test.d.ts +1 -0
- package/dist/components/avatar/avatar.a11y.test.d.ts +1 -0
- package/dist/components/avatar/avatar.visual.test.d.ts +1 -0
- package/dist/{controllers/s-banner.d.ts → components/banner/banner.d.ts} +1 -1
- package/dist/components/banner/banner.test.d.ts +1 -0
- package/dist/components/banner/banner.visual.test.d.ts +1 -0
- package/dist/components/button/button.a11y.test.d.ts +1 -0
- package/dist/components/button/button.visual.test.d.ts +1 -0
- package/dist/{controllers/s-expandable-control.d.ts → components/expandable/expandable.d.ts} +1 -1
- package/dist/components/expandable/expandable.test.d.ts +1 -0
- package/dist/{controllers/s-modal.d.ts → components/modal/modal.d.ts} +1 -1
- package/dist/{controllers/s-navigation-tablist.d.ts → components/navigation/navigation.d.ts} +1 -1
- package/dist/{controllers/s-popover.d.ts → components/popover/popover.d.ts} +1 -1
- package/dist/{controllers/s-tooltip.d.ts → components/popover/tooltip.d.ts} +1 -1
- package/dist/components/popover/tooltip.test.d.ts +1 -0
- package/dist/components/popover/tooltip.visual.test.d.ts +1 -0
- package/dist/{controllers/s-table.d.ts → components/table/table.d.ts} +1 -1
- package/dist/{controllers/s-toast.d.ts → components/toast/toast.d.ts} +1 -1
- package/dist/components/toast/toast.test.d.ts +1 -0
- package/dist/components/toast/toast.visual.test.d.ts +1 -0
- package/dist/{controllers/s-uploader.d.ts → components/uploader/uploader.d.ts} +1 -1
- package/dist/controllers.d.ts +9 -0
- package/dist/css/stacks.css +1351 -1171
- package/dist/css/stacks.min.css +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/js/stacks.js +545 -545
- package/dist/js/stacks.min.js +1 -1
- package/dist/test/test-utils.d.ts +136 -0
- package/lib/{css/atomic/borders.less → atomic/border.less} +18 -0
- package/lib/base/fieldset.less +5 -0
- package/lib/{css/base/icons.less → base/icon.less} +0 -9
- package/lib/components/activity-indicator/activity-indicator.a11y.test.ts +21 -0
- package/lib/components/activity-indicator/activity-indicator.visual.test.ts +23 -0
- package/lib/components/avatar/avatar.a11y.test.ts +36 -0
- package/lib/components/avatar/avatar.visual.test.ts +54 -0
- package/lib/components/banner/banner.less +51 -0
- package/lib/{test/s-banner.test.ts → components/banner/banner.test.ts} +7 -3
- package/lib/{ts/controllers/s-banner.ts → components/banner/banner.ts} +1 -1
- package/lib/components/banner/banner.visual.test.ts +36 -0
- package/lib/components/button/button.a11y.test.ts +32 -0
- package/lib/{css/components/buttons.less → components/button/button.less} +7 -6
- package/lib/components/button/button.visual.test.ts +52 -0
- package/lib/{css/components/cards.less → components/card/card.less} +1 -1
- package/lib/components/check-control/check-control.less +17 -0
- package/lib/components/check-group/check-group.less +19 -0
- package/lib/components/checkbox_radio/checkbox_radio.less +158 -0
- package/lib/components/description/description.less +9 -0
- package/lib/{css/components → components/expandable}/expandable.less +3 -0
- package/lib/components/expandable/expandable.test.ts +53 -0
- package/lib/{ts/controllers/s-expandable-control.ts → components/expandable/expandable.ts} +1 -1
- package/lib/components/input-fill/input-fill.less +35 -0
- package/lib/components/input-icon/input-icon.less +45 -0
- package/lib/components/input-message/input-message.less +48 -0
- package/lib/components/input_textarea/input_textarea.less +166 -0
- package/lib/{css/components/labels.less → components/label/label.less} +4 -4
- package/lib/{css/components → components/link}/link.less +9 -2
- package/lib/{ts/controllers/s-modal.ts → components/modal/modal.ts} +1 -1
- package/lib/{ts/controllers/s-navigation-tablist.ts → components/navigation/navigation.ts} +1 -1
- package/lib/{css/components/notices.less → components/notice/notice.less} +0 -89
- package/lib/{css/components/popovers.less → components/popover/popover.less} +1 -0
- package/lib/{ts/controllers/s-popover.ts → components/popover/popover.ts} +1 -1
- package/lib/{test/s-tooltip.test.ts → components/popover/tooltip.test.ts} +6 -2
- package/lib/{ts/controllers/s-tooltip.ts → components/popover/tooltip.ts} +2 -2
- package/lib/{test/s-tooltip.visual.test.ts → components/popover/tooltip.visual.test.ts} +2 -2
- package/lib/{css/components → components/post-summary}/post-summary.less +6 -2
- package/lib/components/select/select.less +148 -0
- package/lib/{css/components/sidebar-widgets.less → components/sidebar-widget/sidebar-widget.less} +0 -1
- package/lib/{css/components → components/table}/table.less +0 -5
- package/lib/{ts/controllers/s-table.ts → components/table/table.ts} +1 -1
- package/lib/components/table-container/table-container.less +4 -0
- package/lib/{css/components/tags.less → components/tag/tag.less} +3 -3
- package/lib/components/toast/toast.less +35 -0
- package/lib/{test/s-toast.test.ts → components/toast/toast.test.ts} +7 -3
- package/lib/{ts/controllers/s-toast.ts → components/toast/toast.ts} +1 -1
- package/lib/components/toast/toast.visual.test.ts +27 -0
- package/lib/{css/components/toggle-switches.less → components/toggle-switch/toggle-switch.less} +8 -0
- package/lib/{ts/controllers/s-uploader.ts → components/uploader/uploader.ts} +1 -1
- package/lib/controllers.ts +33 -0
- package/lib/{css/exports → exports}/mixins.less +73 -11
- package/lib/{ts/index.ts → index.ts} +1 -1
- package/lib/input-utils.less +44 -0
- package/lib/{css/stacks-dynamic.less → stacks-dynamic.less} +1 -2
- package/lib/stacks-static.less +93 -0
- package/lib/test/test-utils.ts +444 -0
- package/lib/tsconfig.json +1 -1
- package/package.json +26 -25
- package/dist/controllers/index.d.ts +0 -9
- package/lib/css/components/inputs.less +0 -666
- package/lib/css/stacks-static.less +0 -97
- package/lib/test/s-avatar.test.ts +0 -74
- package/lib/test/s-banner.visual.test.ts +0 -61
- package/lib/test/s-button.visual.test.ts +0 -12
- package/lib/test/s-toast.visual.test.ts +0 -48
- package/lib/ts/controllers/index.ts +0 -17
- /package/lib/{css/atomic/colors.less → atomic/color.less} +0 -0
- /package/lib/{css/atomic → atomic}/flex.less +0 -0
- /package/lib/{css/atomic → atomic}/gap.less +0 -0
- /package/lib/{css/atomic → atomic}/grid.less +0 -0
- /package/lib/{css/atomic → atomic}/misc.less +0 -0
- /package/lib/{css/atomic → atomic}/spacing.less +0 -0
- /package/lib/{css/atomic → atomic}/typography.less +0 -0
- /package/lib/{css/atomic → atomic}/width-height.less +0 -0
- /package/lib/{css/base → base}/body.less +0 -0
- /package/lib/{css/base → base}/configuration-static.less +0 -0
- /package/lib/{css/base/internals.less → base/internal.less} +0 -0
- /package/lib/{css/base → base}/reset-meyer.less +0 -0
- /package/lib/{css/base → base}/reset-normalize.less +0 -0
- /package/lib/{css/base → base}/reset.less +0 -0
- /package/lib/{css/components → components/activity-indicator}/activity-indicator.less +0 -0
- /package/lib/{css/components/anchors.less → components/anchor/anchor.less} +0 -0
- /package/lib/{css/components/avatars.less → components/avatar/avatar.less} +0 -0
- /package/lib/{css/components → components/award-bling}/award-bling.less +0 -0
- /package/lib/{css/components/badges.less → components/badge/badge.less} +0 -0
- /package/lib/{css/components → components/block-link}/block-link.less +0 -0
- /package/lib/{css/components → components/breadcrumbs}/breadcrumbs.less +0 -0
- /package/lib/{css/components/button-groups.less → components/button-group/button-group.less} +0 -0
- /package/lib/{css/components/code-blocks.less → components/code-block/code-block.less} +0 -0
- /package/lib/{css/components/empty-states.less → components/empty-state/empty-state.less} +0 -0
- /package/lib/{css/components/link-previews.less → components/link-preview/link-preview.less} +0 -0
- /package/lib/{css/components → components/menu}/menu.less +0 -0
- /package/lib/{css/components/modals.less → components/modal/modal.less} +0 -0
- /package/lib/{css/components → components/navigation}/navigation.less +0 -0
- /package/lib/{css/components/page-titles.less → components/page-title/page-title.less} +0 -0
- /package/lib/{css/components → components/pagination}/pagination.less +0 -0
- /package/lib/{css/components/progress-bars.less → components/progress-bar/progress-bar.less} +0 -0
- /package/lib/{css/components → components/prose}/prose.less +0 -0
- /package/lib/{css/components → components/spinner}/spinner.less +0 -0
- /package/lib/{css/components → components/topbar}/topbar.less +0 -0
- /package/lib/{css/components → components/uploader}/uploader.less +0 -0
- /package/lib/{css/components/user-cards.less → components/user-card/user-card.less} +0 -0
- /package/lib/{css/exports → exports}/constants-colors.less +0 -0
- /package/lib/{css/exports → exports}/constants-helpers.less +0 -0
- /package/lib/{css/exports → exports}/constants-type.less +0 -0
- /package/lib/{css/exports → exports}/exports.less +0 -0
- /package/lib/{css/stacks.less → stacks.less} +0 -0
- /package/lib/{ts/stacks.ts → stacks.ts} +0 -0
package/dist/js/stacks.js
CHANGED
|
@@ -2488,7 +2488,7 @@ Controller.values = {};
|
|
|
2488
2488
|
|
|
2489
2489
|
|
|
2490
2490
|
|
|
2491
|
-
;// CONCATENATED MODULE: ./lib/
|
|
2491
|
+
;// CONCATENATED MODULE: ./lib/stacks.ts
|
|
2492
2492
|
|
|
2493
2493
|
class StacksApplication extends Application {
|
|
2494
2494
|
load(head, ...rest) {
|
|
@@ -2571,7 +2571,115 @@ function addController(name, controller) {
|
|
|
2571
2571
|
application.register(name, createController(controller));
|
|
2572
2572
|
}
|
|
2573
2573
|
|
|
2574
|
-
;// CONCATENATED MODULE: ./lib/
|
|
2574
|
+
;// CONCATENATED MODULE: ./lib/components/banner/banner.ts
|
|
2575
|
+
|
|
2576
|
+
class BannerController extends StacksController {
|
|
2577
|
+
/**
|
|
2578
|
+
* Toggles the visibility of the banner
|
|
2579
|
+
*/
|
|
2580
|
+
toggle(dispatcher = null) {
|
|
2581
|
+
this._toggle(undefined, dispatcher);
|
|
2582
|
+
}
|
|
2583
|
+
/**
|
|
2584
|
+
* Shows the banner
|
|
2585
|
+
*/
|
|
2586
|
+
show(dispatcher = null) {
|
|
2587
|
+
this._toggle(true, dispatcher);
|
|
2588
|
+
}
|
|
2589
|
+
/**
|
|
2590
|
+
* Hides the banner
|
|
2591
|
+
*/
|
|
2592
|
+
hide(dispatcher = null) {
|
|
2593
|
+
this._toggle(false, dispatcher);
|
|
2594
|
+
}
|
|
2595
|
+
/**
|
|
2596
|
+
* Toggles the visibility of the banner element
|
|
2597
|
+
* @param show Optional parameter that force shows/hides the element or toggles it if left undefined
|
|
2598
|
+
*/
|
|
2599
|
+
_toggle(show, dispatcher = null) {
|
|
2600
|
+
let toShow = show;
|
|
2601
|
+
const isVisible = this.bannerTarget.getAttribute("aria-hidden") === "false";
|
|
2602
|
+
// if we're letting the class toggle, we need to figure out if the banner is visible manually
|
|
2603
|
+
if (typeof toShow === "undefined") {
|
|
2604
|
+
toShow = !isVisible;
|
|
2605
|
+
}
|
|
2606
|
+
// if the state matches the disired state, return without changing anything
|
|
2607
|
+
if ((toShow && isVisible) || (!toShow && !isVisible)) {
|
|
2608
|
+
return;
|
|
2609
|
+
}
|
|
2610
|
+
const dispatchingElement = this.getDispatcher(dispatcher);
|
|
2611
|
+
// show/hide events trigger before toggling the class
|
|
2612
|
+
const triggeredEvent = this.triggerEvent(toShow ? "show" : "hide", {
|
|
2613
|
+
dispatcher: this.getDispatcher(dispatchingElement),
|
|
2614
|
+
}, this.bannerTarget);
|
|
2615
|
+
// if this pre-show/hide event was prevented, don't attempt to continue changing the banner state
|
|
2616
|
+
if (triggeredEvent.defaultPrevented) {
|
|
2617
|
+
return;
|
|
2618
|
+
}
|
|
2619
|
+
this.bannerTarget.setAttribute("aria-hidden", toShow ? "false" : "true");
|
|
2620
|
+
if (!toShow) {
|
|
2621
|
+
this.removeBannerOnHide();
|
|
2622
|
+
}
|
|
2623
|
+
this.triggerEvent(toShow ? "shown" : "hidden", {
|
|
2624
|
+
dispatcher: dispatchingElement,
|
|
2625
|
+
}, this.bannerTarget);
|
|
2626
|
+
}
|
|
2627
|
+
/**
|
|
2628
|
+
* Remove the element on hide if the `remove-when-hidden` flag is set
|
|
2629
|
+
*/
|
|
2630
|
+
removeBannerOnHide() {
|
|
2631
|
+
if (this.data.get("remove-when-hidden") !== "true") {
|
|
2632
|
+
return;
|
|
2633
|
+
}
|
|
2634
|
+
this.bannerTarget.addEventListener("s-banner:hidden", () => {
|
|
2635
|
+
this.element.remove();
|
|
2636
|
+
}, { once: true });
|
|
2637
|
+
}
|
|
2638
|
+
/**
|
|
2639
|
+
* Determines the correct dispatching element from a potential input
|
|
2640
|
+
* @param dispatcher The event or element to get the dispatcher from
|
|
2641
|
+
*/
|
|
2642
|
+
getDispatcher(dispatcher = null) {
|
|
2643
|
+
if (dispatcher instanceof Event) {
|
|
2644
|
+
return dispatcher.target;
|
|
2645
|
+
}
|
|
2646
|
+
else if (dispatcher instanceof Element) {
|
|
2647
|
+
return dispatcher;
|
|
2648
|
+
}
|
|
2649
|
+
else {
|
|
2650
|
+
return this.element;
|
|
2651
|
+
}
|
|
2652
|
+
}
|
|
2653
|
+
}
|
|
2654
|
+
BannerController.targets = ["banner"];
|
|
2655
|
+
/**
|
|
2656
|
+
* Helper to manually show an s-banner element via external JS
|
|
2657
|
+
* @param element the element the `data-controller="s-banner"` attribute is on
|
|
2658
|
+
*/
|
|
2659
|
+
function showBanner(element) {
|
|
2660
|
+
toggleBanner(element, true);
|
|
2661
|
+
}
|
|
2662
|
+
/**
|
|
2663
|
+
* Helper to manually hide an s-banner element via external JS
|
|
2664
|
+
* @param element the element the `data-controller="s-banner"` attribute is on
|
|
2665
|
+
*/
|
|
2666
|
+
function hideBanner(element) {
|
|
2667
|
+
toggleBanner(element, false);
|
|
2668
|
+
}
|
|
2669
|
+
/**
|
|
2670
|
+
* Helper to manually show an s-banner element via external JS
|
|
2671
|
+
* @param element the element the `data-controller="s-banner"` attribute is on
|
|
2672
|
+
* @param show whether to force show/hide the banner; toggles the banner if left undefined
|
|
2673
|
+
*/
|
|
2674
|
+
function toggleBanner(element, show) {
|
|
2675
|
+
const controller = application.getControllerForElementAndIdentifier(element, "s-banner");
|
|
2676
|
+
if (!controller) {
|
|
2677
|
+
throw "Unable to get s-banner controller from element";
|
|
2678
|
+
}
|
|
2679
|
+
show ? controller.show() : controller.hide();
|
|
2680
|
+
}
|
|
2681
|
+
|
|
2682
|
+
;// CONCATENATED MODULE: ./lib/components/expandable/expandable.ts
|
|
2575
2683
|
|
|
2576
2684
|
// Radio buttons only trigger a change event when they're *checked*, but not when
|
|
2577
2685
|
// they're *unchecked*. Therefore, if we have an active `s-expandable-control` in
|
|
@@ -2765,7 +2873,7 @@ class ExpandableController extends StacksController {
|
|
|
2765
2873
|
}
|
|
2766
2874
|
}
|
|
2767
2875
|
|
|
2768
|
-
;// CONCATENATED MODULE: ./lib/
|
|
2876
|
+
;// CONCATENATED MODULE: ./lib/components/modal/modal.ts
|
|
2769
2877
|
|
|
2770
2878
|
class ModalController extends StacksController {
|
|
2771
2879
|
connect() {
|
|
@@ -3046,453 +3154,87 @@ function toggleModal(element, show) {
|
|
|
3046
3154
|
show ? controller.show() : controller.hide();
|
|
3047
3155
|
}
|
|
3048
3156
|
|
|
3049
|
-
;// CONCATENATED MODULE: ./lib/
|
|
3157
|
+
;// CONCATENATED MODULE: ./lib/components/navigation/navigation.ts
|
|
3050
3158
|
|
|
3051
|
-
class
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
this.
|
|
3159
|
+
class TabListController extends StacksController {
|
|
3160
|
+
connect() {
|
|
3161
|
+
super.connect();
|
|
3162
|
+
this.boundSelectTab = this.selectTab.bind(this);
|
|
3163
|
+
this.boundHandleKeydown = this.handleKeydown.bind(this);
|
|
3164
|
+
for (const tab of this.tabTargets) {
|
|
3165
|
+
tab.addEventListener("click", this.boundSelectTab);
|
|
3166
|
+
tab.addEventListener("keydown", this.boundHandleKeydown);
|
|
3167
|
+
}
|
|
3168
|
+
}
|
|
3169
|
+
disconnect() {
|
|
3170
|
+
super.disconnect();
|
|
3171
|
+
for (const tab of this.tabTargets) {
|
|
3172
|
+
tab.removeEventListener("click", this.boundSelectTab);
|
|
3173
|
+
tab.removeEventListener("keydown", this.boundHandleKeydown);
|
|
3174
|
+
}
|
|
3057
3175
|
}
|
|
3058
3176
|
/**
|
|
3059
|
-
*
|
|
3177
|
+
* Gets all tabs within the controller.
|
|
3060
3178
|
*/
|
|
3061
|
-
|
|
3062
|
-
this.
|
|
3179
|
+
get tabTargets() {
|
|
3180
|
+
return Array.from(this.element.querySelectorAll("[role=tab]"));
|
|
3063
3181
|
}
|
|
3064
3182
|
/**
|
|
3065
|
-
*
|
|
3183
|
+
* Handles click events on individual tabs, causing them to be selected.
|
|
3066
3184
|
*/
|
|
3067
|
-
|
|
3068
|
-
this.
|
|
3185
|
+
selectTab(event) {
|
|
3186
|
+
this.switchToTab(event.currentTarget);
|
|
3069
3187
|
}
|
|
3070
3188
|
/**
|
|
3071
|
-
*
|
|
3072
|
-
*
|
|
3189
|
+
* Handles left and right arrow keydown events on individual tabs,
|
|
3190
|
+
* selecting the adjacent tab corresponding to the event.
|
|
3073
3191
|
*/
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3192
|
+
handleKeydown(event) {
|
|
3193
|
+
var _a;
|
|
3194
|
+
let tabElement = event.currentTarget;
|
|
3195
|
+
const tabs = this.tabTargets;
|
|
3196
|
+
let tabIndex = tabs.indexOf(tabElement);
|
|
3197
|
+
if (event.key === "ArrowRight") {
|
|
3198
|
+
tabIndex++;
|
|
3080
3199
|
}
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
return;
|
|
3200
|
+
else if (event.key === "ArrowLeft") {
|
|
3201
|
+
tabIndex--;
|
|
3084
3202
|
}
|
|
3085
|
-
|
|
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) {
|
|
3203
|
+
else {
|
|
3092
3204
|
return;
|
|
3093
3205
|
}
|
|
3094
|
-
|
|
3095
|
-
if (
|
|
3096
|
-
|
|
3206
|
+
// Use circular navigation when users go past the first or last tab.
|
|
3207
|
+
if (tabIndex < 0) {
|
|
3208
|
+
tabIndex = tabs.length - 1;
|
|
3097
3209
|
}
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
}, this.bannerTarget);
|
|
3101
|
-
}
|
|
3102
|
-
/**
|
|
3103
|
-
* Remove the element on hide if the `remove-when-hidden` flag is set
|
|
3104
|
-
*/
|
|
3105
|
-
removeBannerOnHide() {
|
|
3106
|
-
if (this.data.get("remove-when-hidden") !== "true") {
|
|
3107
|
-
return;
|
|
3210
|
+
if (tabIndex >= tabs.length) {
|
|
3211
|
+
tabIndex = 0;
|
|
3108
3212
|
}
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3213
|
+
tabElement = tabs[tabIndex];
|
|
3214
|
+
this.switchToTab(tabElement);
|
|
3215
|
+
// Focus the newly selected tab so it can receive keyboard events.
|
|
3216
|
+
(_a = this.selectedTab) === null || _a === void 0 ? void 0 : _a.focus();
|
|
3112
3217
|
}
|
|
3113
3218
|
/**
|
|
3114
|
-
*
|
|
3115
|
-
*
|
|
3219
|
+
* Attempts to switch to a new tab, doing nothing if the tab is already selected or
|
|
3220
|
+
* the s-navigation-tablist:select event is prevented.
|
|
3116
3221
|
*/
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
else if (dispatcher instanceof Element) {
|
|
3122
|
-
return dispatcher;
|
|
3222
|
+
switchToTab(newTab) {
|
|
3223
|
+
const oldTab = this.selectedTab;
|
|
3224
|
+
if (oldTab === newTab) {
|
|
3225
|
+
return;
|
|
3123
3226
|
}
|
|
3124
|
-
|
|
3125
|
-
return
|
|
3227
|
+
if (this.triggerEvent("select", { oldTab, newTab }).defaultPrevented) {
|
|
3228
|
+
return;
|
|
3126
3229
|
}
|
|
3127
|
-
|
|
3128
|
-
}
|
|
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);
|
|
3143
|
-
}
|
|
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();
|
|
3155
|
-
}
|
|
3156
|
-
|
|
3157
|
-
;// CONCATENATED MODULE: ./lib/ts/controllers/s-toast.ts
|
|
3158
|
-
|
|
3159
|
-
class ToastController extends StacksController {
|
|
3160
|
-
connect() {
|
|
3161
|
-
this.validate();
|
|
3230
|
+
this.selectedTab = newTab;
|
|
3231
|
+
this.triggerEvent("selected", { oldTab, newTab });
|
|
3162
3232
|
}
|
|
3163
3233
|
/**
|
|
3164
|
-
*
|
|
3234
|
+
* Returns the currently selected tab or null if no tabs are selected.
|
|
3165
3235
|
*/
|
|
3166
|
-
|
|
3167
|
-
this.
|
|
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);
|
|
3180
|
-
}
|
|
3181
|
-
/**
|
|
3182
|
-
* Hides the toast
|
|
3183
|
-
*/
|
|
3184
|
-
hide(dispatcher = null) {
|
|
3185
|
-
this._toggle(false, dispatcher);
|
|
3186
|
-
}
|
|
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);
|
|
3401
|
-
}
|
|
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();
|
|
3413
|
-
}
|
|
3414
|
-
|
|
3415
|
-
;// CONCATENATED MODULE: ./lib/ts/controllers/s-navigation-tablist.ts
|
|
3416
|
-
|
|
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);
|
|
3236
|
+
get selectedTab() {
|
|
3237
|
+
return (this.tabTargets.find((e) => e.getAttribute("aria-selected") === "true") || null);
|
|
3496
3238
|
}
|
|
3497
3239
|
/**
|
|
3498
3240
|
* Switches the tablist to the provided tab, updating the tabs and panels
|
|
@@ -5519,7 +5261,7 @@ var popper_createPopper = /*#__PURE__*/popperGenerator({
|
|
|
5519
5261
|
// eslint-disable-next-line import/no-unused-modules
|
|
5520
5262
|
|
|
5521
5263
|
|
|
5522
|
-
;// CONCATENATED MODULE: ./lib/
|
|
5264
|
+
;// CONCATENATED MODULE: ./lib/components/popover/popover.ts
|
|
5523
5265
|
|
|
5524
5266
|
|
|
5525
5267
|
class BasePopoverController extends StacksController {
|
|
@@ -5998,7 +5740,7 @@ function toggleController(el, controllerName, include) {
|
|
|
5998
5740
|
el.setAttribute("data-controller", Array.from(controllers).join(" "));
|
|
5999
5741
|
}
|
|
6000
5742
|
|
|
6001
|
-
;// CONCATENATED MODULE: ./lib/
|
|
5743
|
+
;// CONCATENATED MODULE: ./lib/components/table/table.ts
|
|
6002
5744
|
|
|
6003
5745
|
class TableController extends StacksController {
|
|
6004
5746
|
setCurrentSort(headElem, direction) {
|
|
@@ -6090,132 +5832,390 @@ class TableController extends StacksController {
|
|
|
6090
5832
|
: parseInt(tuple[0], 10);
|
|
6091
5833
|
});
|
|
6092
5834
|
}
|
|
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;
|
|
5835
|
+
// We don't sort an array of <tr>, but instead an arrays of row *numbers*, because this way we
|
|
5836
|
+
// can enforce stable sorting, i.e. rows that compare equal are guaranteed to remain in the same
|
|
5837
|
+
// order (the JS standard does not gurantee this for sort()).
|
|
5838
|
+
data.sort(function (a, b) {
|
|
5839
|
+
// first compare the values (a[0])
|
|
5840
|
+
if (a[0] > b[0]) {
|
|
5841
|
+
return 1 * direction;
|
|
5842
|
+
}
|
|
5843
|
+
else if (a[0] < b[0]) {
|
|
5844
|
+
return -1 * direction;
|
|
5845
|
+
}
|
|
5846
|
+
else {
|
|
5847
|
+
// if the values are equal, compare the row numbers (a[1]) to guarantee stable sorting
|
|
5848
|
+
// (note that this comparison is independent of the sorting direction)
|
|
5849
|
+
return a[1] > b[1] ? 1 : -1;
|
|
5850
|
+
}
|
|
5851
|
+
});
|
|
5852
|
+
// this is the actual reordering of the table rows
|
|
5853
|
+
data.forEach(function (tup) {
|
|
5854
|
+
var _a;
|
|
5855
|
+
const row = rows[tup[1]];
|
|
5856
|
+
(_a = row.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(row);
|
|
5857
|
+
if (firstBottomRow) {
|
|
5858
|
+
tbody.insertBefore(row, firstBottomRow);
|
|
5859
|
+
}
|
|
5860
|
+
else {
|
|
5861
|
+
tbody.appendChild(row);
|
|
5862
|
+
}
|
|
5863
|
+
});
|
|
5864
|
+
// update the UI and set the `data-sort-direction` attribute if appropriate, so that the next click
|
|
5865
|
+
// will cause sorting in descending direction
|
|
5866
|
+
this.setCurrentSort(colHead, direction === 1 ? "asc" : "desc");
|
|
5867
|
+
}
|
|
5868
|
+
}
|
|
5869
|
+
TableController.targets = ["column"];
|
|
5870
|
+
function buildIndex(section) {
|
|
5871
|
+
const result = buildIndexOrGetCellSlot(section);
|
|
5872
|
+
if (!(result instanceof Array)) {
|
|
5873
|
+
throw "shouldn't happen";
|
|
5874
|
+
}
|
|
5875
|
+
return result;
|
|
5876
|
+
}
|
|
5877
|
+
function getCellSlot(cell) {
|
|
5878
|
+
if (!(cell.parentElement &&
|
|
5879
|
+
cell.parentElement.parentElement instanceof HTMLTableSectionElement)) {
|
|
5880
|
+
throw "invalid table";
|
|
5881
|
+
}
|
|
5882
|
+
const result = buildIndexOrGetCellSlot(cell.parentElement.parentElement, cell);
|
|
5883
|
+
if (typeof result !== "number") {
|
|
5884
|
+
throw "shouldn't happen";
|
|
5885
|
+
}
|
|
5886
|
+
return result;
|
|
5887
|
+
}
|
|
5888
|
+
// Just because a <td> is the 4th *child* of its <tr> doesn't mean it belongs to the 4th *column*
|
|
5889
|
+
// of the table. Previous cells may have a colspan; cells in previous rows may have a rowspan.
|
|
5890
|
+
// Because we need to know which header cells and data cells belong together, we have to 1) find out
|
|
5891
|
+
// which column number (or "slot" as we call it here) the header cell has, and 2) for each row find
|
|
5892
|
+
// out which <td> cell corresponds to this slot (because those are the rows we're sorting by).
|
|
5893
|
+
//
|
|
5894
|
+
// That's what the following function does. If the second argument is not given, it returns an index
|
|
5895
|
+
// of the table, which is an array of arrays. Each of the sub-arrays corresponds to a table row. The
|
|
5896
|
+
// indices of the sub-array correspond to column slots; the values are the actual table cell elements.
|
|
5897
|
+
// For example index[4][3] is the <td> or <th> in row 4, column 3 of the table section (<tbody> or <thead>).
|
|
5898
|
+
// Note that this element is not necessarily even in the 4th (zero-based) <tr> -- if it has a rowSpan > 1,
|
|
5899
|
+
// it may also be in a previous <tr>.
|
|
5900
|
+
//
|
|
5901
|
+
// If the second argument is given, it's a <td> or <th> that we're trying to find, and the algorithm
|
|
5902
|
+
// stops as soon as it has found it and the function returns its slot number.
|
|
5903
|
+
function buildIndexOrGetCellSlot(section, findCell) {
|
|
5904
|
+
const index = [];
|
|
5905
|
+
let curRow = section.children[0];
|
|
5906
|
+
// the elements of these two arrays are synchronized; the first array contains table cell elements,
|
|
5907
|
+
// the second one contains a number that indicates for how many more rows this elements will
|
|
5908
|
+
// exist (i.e. the value is initially one less than the cell's rowspan, and will be decreased for each row)
|
|
5909
|
+
const growing = [];
|
|
5910
|
+
const growingRowsLeft = [];
|
|
5911
|
+
// continue while we have actual <tr>'s left *or* we still have rowspan'ed elements that aren't done
|
|
5912
|
+
while (curRow ||
|
|
5913
|
+
growingRowsLeft.some(function (e) {
|
|
5914
|
+
return e !== 0;
|
|
5915
|
+
})) {
|
|
5916
|
+
const curIndexRow = [];
|
|
5917
|
+
index.push(curIndexRow);
|
|
5918
|
+
let curSlot = 0;
|
|
5919
|
+
if (curRow) {
|
|
5920
|
+
for (let curCellInd = 0; curCellInd < curRow.children.length; curCellInd++) {
|
|
5921
|
+
while (growingRowsLeft[curSlot]) {
|
|
5922
|
+
growingRowsLeft[curSlot]--;
|
|
5923
|
+
curIndexRow[curSlot] = growing[curSlot];
|
|
5924
|
+
curSlot++;
|
|
5925
|
+
}
|
|
5926
|
+
const cell = curRow.children[curCellInd];
|
|
5927
|
+
if (!(cell instanceof HTMLTableCellElement)) {
|
|
5928
|
+
throw "invalid table";
|
|
5929
|
+
}
|
|
5930
|
+
if (getComputedStyle(cell).display === "none") {
|
|
5931
|
+
continue;
|
|
5932
|
+
}
|
|
5933
|
+
if (cell === findCell) {
|
|
5934
|
+
return curSlot;
|
|
5935
|
+
}
|
|
5936
|
+
const nextFreeSlot = curSlot + cell.colSpan;
|
|
5937
|
+
for (; curSlot < nextFreeSlot; curSlot++) {
|
|
5938
|
+
growingRowsLeft[curSlot] = cell.rowSpan - 1; // if any of these is already growing, the table is broken -- no guarantees of anything
|
|
5939
|
+
growing[curSlot] = cell;
|
|
5940
|
+
curIndexRow[curSlot] = cell;
|
|
5941
|
+
}
|
|
5942
|
+
}
|
|
5943
|
+
}
|
|
5944
|
+
while (curSlot < growing.length) {
|
|
5945
|
+
if (growingRowsLeft[curSlot]) {
|
|
5946
|
+
growingRowsLeft[curSlot]--;
|
|
5947
|
+
curIndexRow[curSlot] = growing[curSlot];
|
|
5948
|
+
}
|
|
5949
|
+
curSlot++;
|
|
5950
|
+
}
|
|
5951
|
+
if (curRow) {
|
|
5952
|
+
curRow = curRow.nextElementSibling;
|
|
5953
|
+
}
|
|
5954
|
+
}
|
|
5955
|
+
return findCell
|
|
5956
|
+
? -1
|
|
5957
|
+
: index; /* if findCell was given but we end up here, that means it isn't in this section */
|
|
5958
|
+
}
|
|
5959
|
+
|
|
5960
|
+
;// CONCATENATED MODULE: ./lib/components/toast/toast.ts
|
|
5961
|
+
|
|
5962
|
+
class ToastController extends StacksController {
|
|
5963
|
+
connect() {
|
|
5964
|
+
this.validate();
|
|
5965
|
+
}
|
|
5966
|
+
/**
|
|
5967
|
+
* Disconnects all added event listeners on controller disconnect
|
|
5968
|
+
*/
|
|
5969
|
+
disconnect() {
|
|
5970
|
+
this.unbindDocumentEvents();
|
|
5971
|
+
}
|
|
5972
|
+
/**
|
|
5973
|
+
* Toggles the visibility of the toast
|
|
5974
|
+
*/
|
|
5975
|
+
toggle(dispatcher = null) {
|
|
5976
|
+
this._toggle(undefined, dispatcher);
|
|
5977
|
+
}
|
|
5978
|
+
/**
|
|
5979
|
+
* Shows the toast
|
|
5980
|
+
*/
|
|
5981
|
+
show(dispatcher = null) {
|
|
5982
|
+
this._toggle(true, dispatcher);
|
|
5983
|
+
}
|
|
5984
|
+
/**
|
|
5985
|
+
* Hides the toast
|
|
5986
|
+
*/
|
|
5987
|
+
hide(dispatcher = null) {
|
|
5988
|
+
this._toggle(false, dispatcher);
|
|
5989
|
+
}
|
|
5990
|
+
/**
|
|
5991
|
+
* Validates the toast settings and attempts to set necessary internal variables
|
|
5992
|
+
*/
|
|
5993
|
+
validate() {
|
|
5994
|
+
// check for returnElement support
|
|
5995
|
+
const returnElementSelector = this.data.get("return-element");
|
|
5996
|
+
if (returnElementSelector) {
|
|
5997
|
+
this.returnElement = (document.querySelector(returnElementSelector));
|
|
5998
|
+
if (!this.returnElement) {
|
|
5999
|
+
throw ("Unable to find element by return-element selector: " +
|
|
6000
|
+
returnElementSelector);
|
|
6001
|
+
}
|
|
6002
|
+
}
|
|
6003
|
+
}
|
|
6004
|
+
/**
|
|
6005
|
+
* Toggles the visibility of the toast element
|
|
6006
|
+
* @param show Optional parameter that force shows/hides the element or toggles it if left undefined
|
|
6007
|
+
*/
|
|
6008
|
+
_toggle(show, dispatcher = null) {
|
|
6009
|
+
let toShow = show;
|
|
6010
|
+
const isVisible = this.toastTarget.getAttribute("aria-hidden") === "false";
|
|
6011
|
+
// if we're letting the class toggle, we need to figure out if the toast is visible manually
|
|
6012
|
+
if (typeof toShow === "undefined") {
|
|
6013
|
+
toShow = !isVisible;
|
|
6014
|
+
}
|
|
6015
|
+
// if the state matches the disired state, return without changing anything
|
|
6016
|
+
if ((toShow && isVisible) || (!toShow && !isVisible)) {
|
|
6017
|
+
return;
|
|
6018
|
+
}
|
|
6019
|
+
const dispatchingElement = this.getDispatcher(dispatcher);
|
|
6020
|
+
// show/hide events trigger before toggling the class
|
|
6021
|
+
const triggeredEvent = this.triggerEvent(toShow ? "show" : "hide", {
|
|
6022
|
+
returnElement: this.returnElement,
|
|
6023
|
+
dispatcher: this.getDispatcher(dispatchingElement),
|
|
6024
|
+
}, this.toastTarget);
|
|
6025
|
+
// if this pre-show/hide event was prevented, don't attempt to continue changing the toast state
|
|
6026
|
+
if (triggeredEvent.defaultPrevented) {
|
|
6027
|
+
return;
|
|
6028
|
+
}
|
|
6029
|
+
this.returnElement = triggeredEvent.detail.returnElement;
|
|
6030
|
+
this.toastTarget.setAttribute("aria-hidden", toShow ? "false" : "true");
|
|
6031
|
+
if (toShow) {
|
|
6032
|
+
this.bindDocumentEvents();
|
|
6033
|
+
this.hideAfterTimeout();
|
|
6034
|
+
if (this.data.get("prevent-focus-capture") !== "true") {
|
|
6035
|
+
this.focusInsideToast();
|
|
6036
|
+
}
|
|
6037
|
+
}
|
|
6038
|
+
else {
|
|
6039
|
+
this.unbindDocumentEvents();
|
|
6040
|
+
this.focusReturnElement();
|
|
6041
|
+
this.removeToastOnHide();
|
|
6042
|
+
this.clearActiveTimeout();
|
|
6043
|
+
}
|
|
6044
|
+
// check for transitionend support
|
|
6045
|
+
const supportsTransitionEnd = this.toastTarget.ontransitionend !== undefined;
|
|
6046
|
+
// shown/hidden events trigger after toggling the class
|
|
6047
|
+
if (supportsTransitionEnd) {
|
|
6048
|
+
// wait until after the toast finishes transitioning to fire the event
|
|
6049
|
+
this.toastTarget.addEventListener("transitionend", () => {
|
|
6050
|
+
//TODO this is firing waaay to soon?
|
|
6051
|
+
this.triggerEvent(toShow ? "shown" : "hidden", {
|
|
6052
|
+
dispatcher: dispatchingElement,
|
|
6053
|
+
}, this.toastTarget);
|
|
6054
|
+
}, { once: true });
|
|
6055
|
+
}
|
|
6056
|
+
else {
|
|
6057
|
+
this.triggerEvent(toShow ? "shown" : "hidden", {
|
|
6058
|
+
dispatcher: dispatchingElement,
|
|
6059
|
+
}, this.toastTarget);
|
|
6060
|
+
}
|
|
6061
|
+
}
|
|
6062
|
+
/**
|
|
6063
|
+
* Listens for the s-toast:hidden event and focuses the returnElement when it is fired
|
|
6064
|
+
*/
|
|
6065
|
+
focusReturnElement() {
|
|
6066
|
+
if (!this.returnElement) {
|
|
6067
|
+
return;
|
|
6068
|
+
}
|
|
6069
|
+
this.toastTarget.addEventListener("s-toast:hidden", () => {
|
|
6070
|
+
// double check the element still exists when the event is called
|
|
6071
|
+
if (this.returnElement &&
|
|
6072
|
+
document.body.contains(this.returnElement)) {
|
|
6073
|
+
this.returnElement.focus();
|
|
6108
6074
|
}
|
|
6109
|
-
});
|
|
6110
|
-
|
|
6111
|
-
|
|
6075
|
+
}, { once: true });
|
|
6076
|
+
}
|
|
6077
|
+
/**
|
|
6078
|
+
* Remove the element on hide if the `remove-when-hidden` flag is set
|
|
6079
|
+
*/
|
|
6080
|
+
removeToastOnHide() {
|
|
6081
|
+
if (this.data.get("remove-when-hidden") !== "true") {
|
|
6082
|
+
return;
|
|
6083
|
+
}
|
|
6084
|
+
this.toastTarget.addEventListener("s-toast:hidden", () => {
|
|
6085
|
+
this.element.remove();
|
|
6086
|
+
}, { once: true });
|
|
6087
|
+
}
|
|
6088
|
+
/**
|
|
6089
|
+
* Hide the element after a delay
|
|
6090
|
+
*/
|
|
6091
|
+
hideAfterTimeout() {
|
|
6092
|
+
if (this.data.get("prevent-auto-hide") === "true" ||
|
|
6093
|
+
this.data.get("hide-after-timeout") === "0") {
|
|
6094
|
+
return;
|
|
6095
|
+
}
|
|
6096
|
+
const timeout = parseInt(this.data.get("hide-after-timeout"), 10) || 3000;
|
|
6097
|
+
this.activeTimeout = window.setTimeout(() => this.hide(), timeout);
|
|
6098
|
+
}
|
|
6099
|
+
/**
|
|
6100
|
+
* Cancels the activeTimeout
|
|
6101
|
+
*/
|
|
6102
|
+
clearActiveTimeout() {
|
|
6103
|
+
clearTimeout(this.activeTimeout);
|
|
6104
|
+
}
|
|
6105
|
+
/**
|
|
6106
|
+
* Gets all elements within the toast that could receive keyboard focus.
|
|
6107
|
+
*/
|
|
6108
|
+
getAllTabbables() {
|
|
6109
|
+
return Array.from(this.toastTarget.querySelectorAll("[href], input, select, textarea, button, [tabindex]")).filter((el) => el.matches(":not([disabled]):not([tabindex='-1'])"));
|
|
6110
|
+
}
|
|
6111
|
+
/**
|
|
6112
|
+
* Returns the first visible element in an array or `undefined` if no elements are visible.
|
|
6113
|
+
*/
|
|
6114
|
+
firstVisible(elements) {
|
|
6115
|
+
// https://stackoverflow.com/a/21696585
|
|
6116
|
+
return elements === null || elements === void 0 ? void 0 : elements.find((el) => el.offsetParent !== null);
|
|
6117
|
+
}
|
|
6118
|
+
/**
|
|
6119
|
+
* Attempts to shift keyboard focus into the toast.
|
|
6120
|
+
* If elements with `data-s-toast-target="initialFocus"` are present and visible, one of those will be selected.
|
|
6121
|
+
* Otherwise, the first visible focusable element will receive focus.
|
|
6122
|
+
*/
|
|
6123
|
+
focusInsideToast() {
|
|
6124
|
+
this.toastTarget.addEventListener("s-toast:shown", () => {
|
|
6112
6125
|
var _a;
|
|
6113
|
-
const
|
|
6114
|
-
|
|
6115
|
-
|
|
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");
|
|
6126
|
+
const initialFocus = (_a = this.firstVisible(this.initialFocusTargets)) !== null && _a !== void 0 ? _a : this.firstVisible(this.getAllTabbables());
|
|
6127
|
+
initialFocus === null || initialFocus === void 0 ? void 0 : initialFocus.focus();
|
|
6128
|
+
}, { once: true });
|
|
6125
6129
|
}
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6130
|
+
/**
|
|
6131
|
+
* Binds global events to the document for hiding toasts on user interaction
|
|
6132
|
+
*/
|
|
6133
|
+
bindDocumentEvents() {
|
|
6134
|
+
// in order for removeEventListener to remove the right event, this bound function needs a constant reference
|
|
6135
|
+
this._boundClickFn =
|
|
6136
|
+
this._boundClickFn || this.hideOnOutsideClick.bind(this);
|
|
6137
|
+
this._boundKeypressFn =
|
|
6138
|
+
this._boundKeypressFn || this.hideOnEscapePress.bind(this);
|
|
6139
|
+
document.addEventListener("mousedown", this._boundClickFn);
|
|
6140
|
+
document.addEventListener("keyup", this._boundKeypressFn);
|
|
6132
6141
|
}
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6142
|
+
/**
|
|
6143
|
+
* Unbinds global events to the document for hiding toasts on user interaction
|
|
6144
|
+
*/
|
|
6145
|
+
unbindDocumentEvents() {
|
|
6146
|
+
document.removeEventListener("mousedown", this._boundClickFn);
|
|
6147
|
+
document.removeEventListener("keyup", this._boundKeypressFn);
|
|
6139
6148
|
}
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6149
|
+
/**
|
|
6150
|
+
* Forces the toast to hide if a user clicks outside of it or its reference element
|
|
6151
|
+
*/
|
|
6152
|
+
hideOnOutsideClick(e) {
|
|
6153
|
+
var _a;
|
|
6154
|
+
const target = e.target;
|
|
6155
|
+
// check if the document was clicked inside either the toggle element or the toast itself
|
|
6156
|
+
// note: .contains also returns true if the node itself matches the target element
|
|
6157
|
+
if (!((_a = this.toastTarget) === null || _a === void 0 ? void 0 : _a.contains(target)) &&
|
|
6158
|
+
document.body.contains(target) &&
|
|
6159
|
+
this.data.get("hide-on-outside-click") !== "false") {
|
|
6160
|
+
this._toggle(false, e);
|
|
6161
|
+
}
|
|
6143
6162
|
}
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
//
|
|
6149
|
-
|
|
6150
|
-
|
|
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
|
-
}
|
|
6163
|
+
/**
|
|
6164
|
+
* Forces the toast to hide if the user presses escape while it, one of its childen, or the reference element are focused
|
|
6165
|
+
*/
|
|
6166
|
+
hideOnEscapePress(e) {
|
|
6167
|
+
// if the ESC key (27) wasn't pressed or if no toasts are showing, return
|
|
6168
|
+
if (e.which !== 27 ||
|
|
6169
|
+
this.toastTarget.getAttribute("aria-hidden") === "true") {
|
|
6170
|
+
return;
|
|
6201
6171
|
}
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6172
|
+
this._toggle(false, e);
|
|
6173
|
+
}
|
|
6174
|
+
/**
|
|
6175
|
+
* Determines the correct dispatching element from a potential input
|
|
6176
|
+
* @param dispatcher The event or element to get the dispatcher from
|
|
6177
|
+
*/
|
|
6178
|
+
getDispatcher(dispatcher = null) {
|
|
6179
|
+
if (dispatcher instanceof Event) {
|
|
6180
|
+
return dispatcher.target;
|
|
6208
6181
|
}
|
|
6209
|
-
if (
|
|
6210
|
-
|
|
6182
|
+
else if (dispatcher instanceof Element) {
|
|
6183
|
+
return dispatcher;
|
|
6184
|
+
}
|
|
6185
|
+
else {
|
|
6186
|
+
return this.element;
|
|
6211
6187
|
}
|
|
6212
6188
|
}
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6189
|
+
}
|
|
6190
|
+
ToastController.targets = ["toast", "initialFocus"];
|
|
6191
|
+
/**
|
|
6192
|
+
* Helper to manually show an s-toast element via external JS
|
|
6193
|
+
* @param element the element the `data-controller="s-toast"` attribute is on
|
|
6194
|
+
*/
|
|
6195
|
+
function showToast(element) {
|
|
6196
|
+
toggleToast(element, true);
|
|
6197
|
+
}
|
|
6198
|
+
/**
|
|
6199
|
+
* Helper to manually hide an s-toast element via external JS
|
|
6200
|
+
* @param element the element the `data-controller="s-toast"` attribute is on
|
|
6201
|
+
*/
|
|
6202
|
+
function hideToast(element) {
|
|
6203
|
+
toggleToast(element, false);
|
|
6204
|
+
}
|
|
6205
|
+
/**
|
|
6206
|
+
* Helper to manually show an s-toast element via external JS
|
|
6207
|
+
* @param element the element the `data-controller="s-toast"` attribute is on
|
|
6208
|
+
* @param show whether to force show/hide the toast; toggles the toast if left undefined
|
|
6209
|
+
*/
|
|
6210
|
+
function toggleToast(element, show) {
|
|
6211
|
+
const controller = application.getControllerForElementAndIdentifier(element, "s-toast");
|
|
6212
|
+
if (!controller) {
|
|
6213
|
+
throw "Unable to get s-toast controller from element";
|
|
6214
|
+
}
|
|
6215
|
+
show ? controller.show() : controller.hide();
|
|
6216
6216
|
}
|
|
6217
6217
|
|
|
6218
|
-
;// CONCATENATED MODULE: ./lib/
|
|
6218
|
+
;// CONCATENATED MODULE: ./lib/components/popover/tooltip.ts
|
|
6219
6219
|
|
|
6220
6220
|
|
|
6221
6221
|
class TooltipController extends BasePopoverController {
|
|
@@ -6467,7 +6467,7 @@ function applyOptionsAndTitleAttributes(element, options) {
|
|
|
6467
6467
|
}
|
|
6468
6468
|
}
|
|
6469
6469
|
|
|
6470
|
-
;// CONCATENATED MODULE: ./lib/
|
|
6470
|
+
;// CONCATENATED MODULE: ./lib/components/uploader/uploader.ts
|
|
6471
6471
|
|
|
6472
6472
|
class UploaderController extends StacksController {
|
|
6473
6473
|
connect() {
|
|
@@ -6631,7 +6631,7 @@ UploaderController.targets = ["input", "previews", "uploader"];
|
|
|
6631
6631
|
UploaderController.FILE_DISPLAY_LIMIT = 10;
|
|
6632
6632
|
UploaderController.MAX_FILE_SIZE = 1024 * 1024 * 10; // 10 MB
|
|
6633
6633
|
|
|
6634
|
-
;// CONCATENATED MODULE: ./lib/
|
|
6634
|
+
;// CONCATENATED MODULE: ./lib/controllers.ts
|
|
6635
6635
|
// export all controllers *with helpers* so they can be bulk re-exported by the package entry point
|
|
6636
6636
|
|
|
6637
6637
|
|
|
@@ -6643,7 +6643,7 @@ UploaderController.MAX_FILE_SIZE = 1024 * 1024 * 10; // 10 MB
|
|
|
6643
6643
|
|
|
6644
6644
|
|
|
6645
6645
|
|
|
6646
|
-
;// CONCATENATED MODULE: ./lib/
|
|
6646
|
+
;// CONCATENATED MODULE: ./lib/index.ts
|
|
6647
6647
|
|
|
6648
6648
|
|
|
6649
6649
|
|