@empathyco/x-components 3.0.0-alpha.183 → 3.0.0-alpha.185

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 (31) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/core/index.js +1 -0
  3. package/core/index.js.map +1 -1
  4. package/design-system/default-theme.css +73 -73
  5. package/design-system/full-theme.css +8 -8
  6. package/docs/API-reference/api/x-components.basemodal.focusonopen.md +13 -0
  7. package/docs/API-reference/api/x-components.basemodal.md +1 -0
  8. package/docs/API-reference/api/x-components.focusable_selectors.md +13 -0
  9. package/docs/API-reference/api/x-components.md +1 -0
  10. package/docs/API-reference/components/common/modals/x-components.base-modal.md +6 -5
  11. package/js/components/modals/base-modal.vue.js +1 -1
  12. package/js/components/modals/base-modal.vue.js.map +1 -1
  13. package/js/components/modals/base-modal.vue_rollup-plugin-vue_script.vue.js +18 -0
  14. package/js/components/modals/base-modal.vue_rollup-plugin-vue_script.vue.js.map +1 -1
  15. package/js/components/modals/base-modal.vue_rollup-plugin-vue_styles.0.vue.js +1 -1
  16. package/js/index.js +1 -0
  17. package/js/index.js.map +1 -1
  18. package/js/services/directional-focus-navigation.service.js +3 -2
  19. package/js/services/directional-focus-navigation.service.js.map +1 -1
  20. package/js/utils/focus.js +11 -0
  21. package/js/utils/focus.js.map +1 -0
  22. package/package.json +3 -3
  23. package/report/x-components.api.json +44 -0
  24. package/report/x-components.api.md +6 -0
  25. package/types/components/modals/base-modal.vue.d.ts +12 -0
  26. package/types/components/modals/base-modal.vue.d.ts.map +1 -1
  27. package/types/services/directional-focus-navigation.service.d.ts.map +1 -1
  28. package/types/utils/focus.d.ts +7 -0
  29. package/types/utils/focus.d.ts.map +1 -0
  30. package/types/utils/index.d.ts +1 -0
  31. package/types/utils/index.d.ts.map +1 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,30 @@
3
3
  All notable changes to this project will be documented in this file. See
4
4
  [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [3.0.0-alpha.185](https://github.com/empathyco/x/compare/@empathyco/x-components@3.0.0-alpha.184...@empathyco/x-components@3.0.0-alpha.185) (2022-09-30)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **base-modal:** add prop to allow the modal to move the focus to an element within it on open
11
+ (#748) ([0954926](https://github.com/empathyco/x/commit/0954926d7e95ab53e3a8fe263265b63f1a5f20d7))
12
+
13
+ # Change Log
14
+
15
+ All notable changes to this project will be documented in this file. See
16
+ [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
17
+
18
+ ## [3.0.0-alpha.184](https://github.com/empathyco/x/compare/@empathyco/x-components@3.0.0-alpha.183...@empathyco/x-components@3.0.0-alpha.184) (2022-09-30)
19
+
20
+ ### Continuous Integration
21
+
22
+ - silent jest and eslint warnings (#749)
23
+ ([1413677](https://github.com/empathyco/x/commit/14136776e6a616e21ecd4585a071cdee1569d1cb))
24
+
25
+ # Change Log
26
+
27
+ All notable changes to this project will be documented in this file. See
28
+ [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
29
+
6
30
  ## [3.0.0-alpha.183](https://github.com/empathyco/x/compare/@empathyco/x-components@3.0.0-alpha.182...@empathyco/x-components@3.0.0-alpha.183) (2022-09-29)
7
31
 
8
32
  ### Features
package/core/index.js CHANGED
@@ -143,6 +143,7 @@ export { clone } from '../js/utils/clone.js';
143
143
  export { currencyFormatter } from '../js/utils/currency-formatter.js';
144
144
  export { debounce as debounceFunction } from '../js/utils/debounce.js';
145
145
  export { areFiltersDifferent, createRawFilters } from '../js/utils/filters.js';
146
+ export { FOCUSABLE_SELECTORS } from '../js/utils/focus.js';
146
147
  export { noOp } from '../js/utils/function.js';
147
148
  export { getURLParameter } from '../js/utils/get-url-parameters.js';
148
149
  export { isElementEqualOrContained } from '../js/utils/html.js';
package/core/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -407,6 +407,79 @@
407
407
  [dir="rtl"] .x-dropdown--right .x-dropdown__items-list {
408
408
  left: 0;
409
409
  }
410
+ :root {
411
+ --x-size-border-radius-dropdown-default: var(--x-size-border-radius-base-none);
412
+ --x-size-border-radius-top-left-dropdown-default: var(--x-size-border-radius-dropdown-default);
413
+ --x-size-border-radius-top-right-dropdown-default: var(--x-size-border-radius-dropdown-default);
414
+ --x-size-border-radius-bottom-right-dropdown-default: var(
415
+ --x-size-border-radius-dropdown-default
416
+ );
417
+ --x-size-border-radius-bottom-left-dropdown-default: var(--x-size-border-radius-dropdown-default);
418
+ --x-size-border-width-dropdown-toggle-default: var(--x-size-border-width-base);
419
+ --x-size-border-width-top-dropdown-toggle-default: var(
420
+ --x-size-border-width-dropdown-toggle-default
421
+ );
422
+ --x-size-border-width-right-dropdown-toggle-default: var(
423
+ --x-size-border-width-dropdown-toggle-default
424
+ );
425
+ --x-size-border-width-bottom-dropdown-toggle-default: var(
426
+ --x-size-border-width-dropdown-toggle-default
427
+ );
428
+ --x-size-border-width-left-dropdown-toggle-default: var(
429
+ --x-size-border-width-dropdown-toggle-default
430
+ );
431
+ --x-size-border-width-dropdown-list-default: var(--x-size-border-width-base);
432
+ --x-size-border-width-top-dropdown-list-default: 0;
433
+ --x-size-border-width-right-dropdown-list-default: var(
434
+ --x-size-border-width-dropdown-list-default
435
+ );
436
+ --x-size-border-width-bottom-dropdown-list-default: var(
437
+ --x-size-border-width-dropdown-list-default
438
+ );
439
+ --x-size-border-width-left-dropdown-list-default: var(
440
+ --x-size-border-width-dropdown-list-default
441
+ );
442
+ --x-color-border-dropdown-toggle-default: var(--x-color-base-neutral-95);
443
+ --x-color-border-dropdown-list-default: var(--x-color-border-dropdown-toggle-default);
444
+ --x-color-background-dropdown-default: var(--x-color-base-neutral-100);
445
+ --x-color-background-dropdown-toggle-default: var(--x-color-base-neutral-100);
446
+ --x-color-background-dropdown-toggle-open-default: var(
447
+ --x-color-background-dropdown-toggle-default
448
+ );
449
+ --x-color-background-dropdown-item-default-selected: var(--x-color-base-neutral-95);
450
+ --x-color-background-dropdown-item-default-hover: var(--x-color-base-neutral-95);
451
+ --x-color-text-dropdown-default: var(--x-color-text-default);
452
+ --x-color-text-dropdown-toggle-default: var(--x-color-text-dropdown-default);
453
+ --x-color-text-dropdown-toggle-default-selected: var(--x-color-base-neutral-35);
454
+ --x-color-text-dropdown-item-default-hover: var(--x-color-base-neutral-35);
455
+ --x-color-text-dropdown-item-default-selected: var(--x-color-text-default);
456
+ --x-font-family-dropdown-default: var(--x-font-family-text);
457
+ --x-size-font-dropdown-default: var(--x-size-font-text);
458
+ --x-size-line-height-dropdown-default: var(--x-size-line-height-text);
459
+ --x-number-font-weight-dropdown-default: var(--x-number-font-weight-base-regular);
460
+ --x-number-font-weight-dropdown-item-default-hover: var(--x-number-font-weight-base-bold);
461
+ --x-number-font-weight-dropdown-item-default-selected: var(--x-number-font-weight-base-regular);
462
+ --x-font-decoration-dropdown-item-default-hover: none;
463
+ --x-font-decoration-dropdown-item-default-selected: none;
464
+ --x-size-width-dropdown-toggle-default: 100%;
465
+ --x-size-min-width-dropdown-list-default: 100%;
466
+ --x-size-gap-dropdown-default: 0;
467
+ --x-size-padding-top-dropdown-toggle-default: var(--x-size-padding-top-dropdown-item-default);
468
+ --x-size-padding-right-dropdown-toggle-default: var(--x-size-padding-right-dropdown-item-default);
469
+ --x-size-padding-bottom-dropdown-toggle-default: var(
470
+ --x-size-padding-bottom-dropdown-item-default
471
+ );
472
+ --x-size-padding-left-dropdown-toggle-default: var(--x-size-padding-left-dropdown-item-default);
473
+ --x-size-padding-vertical-dropdown-list-default: 0;
474
+ --x-size-padding-top-dropdown-item-default: var(--x-size-base-04);
475
+ --x-size-padding-right-dropdown-item-default: var(--x-size-base-05);
476
+ --x-size-padding-bottom-dropdown-item-default: var(--x-size-base-04);
477
+ --x-size-padding-left-dropdown-item-default: var(--x-size-base-05);
478
+ --x-size-gap-dropdown-item-default: var(--x-size-base-03);
479
+ --x-string-box-shadow-dropdown-default: none;
480
+ --x-string-overflow-dropdown-toggle-default: hidden;
481
+ --x-string-overflow-dropdown-list-default: hidden;
482
+ }
410
483
  :root {
411
484
  --x-color-background-facet-default: transparent;
412
485
  --x-color-border-facet-default: var(--x-color-background-facet-default);
@@ -2829,77 +2902,4 @@
2829
2902
  --x-size-line-height-base-s: 16px;
2830
2903
  --x-size-line-height-base-m: 24px;
2831
2904
  --x-size-line-height-base-l: 32px;
2832
- }
2833
- :root {
2834
- --x-size-border-radius-dropdown-default: var(--x-size-border-radius-base-none);
2835
- --x-size-border-radius-top-left-dropdown-default: var(--x-size-border-radius-dropdown-default);
2836
- --x-size-border-radius-top-right-dropdown-default: var(--x-size-border-radius-dropdown-default);
2837
- --x-size-border-radius-bottom-right-dropdown-default: var(
2838
- --x-size-border-radius-dropdown-default
2839
- );
2840
- --x-size-border-radius-bottom-left-dropdown-default: var(--x-size-border-radius-dropdown-default);
2841
- --x-size-border-width-dropdown-toggle-default: var(--x-size-border-width-base);
2842
- --x-size-border-width-top-dropdown-toggle-default: var(
2843
- --x-size-border-width-dropdown-toggle-default
2844
- );
2845
- --x-size-border-width-right-dropdown-toggle-default: var(
2846
- --x-size-border-width-dropdown-toggle-default
2847
- );
2848
- --x-size-border-width-bottom-dropdown-toggle-default: var(
2849
- --x-size-border-width-dropdown-toggle-default
2850
- );
2851
- --x-size-border-width-left-dropdown-toggle-default: var(
2852
- --x-size-border-width-dropdown-toggle-default
2853
- );
2854
- --x-size-border-width-dropdown-list-default: var(--x-size-border-width-base);
2855
- --x-size-border-width-top-dropdown-list-default: 0;
2856
- --x-size-border-width-right-dropdown-list-default: var(
2857
- --x-size-border-width-dropdown-list-default
2858
- );
2859
- --x-size-border-width-bottom-dropdown-list-default: var(
2860
- --x-size-border-width-dropdown-list-default
2861
- );
2862
- --x-size-border-width-left-dropdown-list-default: var(
2863
- --x-size-border-width-dropdown-list-default
2864
- );
2865
- --x-color-border-dropdown-toggle-default: var(--x-color-base-neutral-95);
2866
- --x-color-border-dropdown-list-default: var(--x-color-border-dropdown-toggle-default);
2867
- --x-color-background-dropdown-default: var(--x-color-base-neutral-100);
2868
- --x-color-background-dropdown-toggle-default: var(--x-color-base-neutral-100);
2869
- --x-color-background-dropdown-toggle-open-default: var(
2870
- --x-color-background-dropdown-toggle-default
2871
- );
2872
- --x-color-background-dropdown-item-default-selected: var(--x-color-base-neutral-95);
2873
- --x-color-background-dropdown-item-default-hover: var(--x-color-base-neutral-95);
2874
- --x-color-text-dropdown-default: var(--x-color-text-default);
2875
- --x-color-text-dropdown-toggle-default: var(--x-color-text-dropdown-default);
2876
- --x-color-text-dropdown-toggle-default-selected: var(--x-color-base-neutral-35);
2877
- --x-color-text-dropdown-item-default-hover: var(--x-color-base-neutral-35);
2878
- --x-color-text-dropdown-item-default-selected: var(--x-color-text-default);
2879
- --x-font-family-dropdown-default: var(--x-font-family-text);
2880
- --x-size-font-dropdown-default: var(--x-size-font-text);
2881
- --x-size-line-height-dropdown-default: var(--x-size-line-height-text);
2882
- --x-number-font-weight-dropdown-default: var(--x-number-font-weight-base-regular);
2883
- --x-number-font-weight-dropdown-item-default-hover: var(--x-number-font-weight-base-bold);
2884
- --x-number-font-weight-dropdown-item-default-selected: var(--x-number-font-weight-base-regular);
2885
- --x-font-decoration-dropdown-item-default-hover: none;
2886
- --x-font-decoration-dropdown-item-default-selected: none;
2887
- --x-size-width-dropdown-toggle-default: 100%;
2888
- --x-size-min-width-dropdown-list-default: 100%;
2889
- --x-size-gap-dropdown-default: 0;
2890
- --x-size-padding-top-dropdown-toggle-default: var(--x-size-padding-top-dropdown-item-default);
2891
- --x-size-padding-right-dropdown-toggle-default: var(--x-size-padding-right-dropdown-item-default);
2892
- --x-size-padding-bottom-dropdown-toggle-default: var(
2893
- --x-size-padding-bottom-dropdown-item-default
2894
- );
2895
- --x-size-padding-left-dropdown-toggle-default: var(--x-size-padding-left-dropdown-item-default);
2896
- --x-size-padding-vertical-dropdown-list-default: 0;
2897
- --x-size-padding-top-dropdown-item-default: var(--x-size-base-04);
2898
- --x-size-padding-right-dropdown-item-default: var(--x-size-base-05);
2899
- --x-size-padding-bottom-dropdown-item-default: var(--x-size-base-04);
2900
- --x-size-padding-left-dropdown-item-default: var(--x-size-base-05);
2901
- --x-size-gap-dropdown-item-default: var(--x-size-base-03);
2902
- --x-string-box-shadow-dropdown-default: none;
2903
- --x-string-overflow-dropdown-toggle-default: hidden;
2904
- --x-string-overflow-dropdown-list-default: hidden;
2905
2905
  }
@@ -1058,6 +1058,10 @@
1058
1058
  --x-size-padding-bottom-filter-children: 0;
1059
1059
  --x-size-padding-left-filter-children: var(--x-size-base-05);
1060
1060
  }
1061
+ .x-filter--justified.x-filter > *:last-child:not(.x-filter__label),
1062
+ .x-filter--justified .x-filter > *:last-child:not(.x-filter__label) {
1063
+ margin-left: auto;
1064
+ }
1061
1065
  .x-grid {
1062
1066
  margin: 0;
1063
1067
  display: grid;
@@ -2554,10 +2558,6 @@
2554
2558
  margin-right: var(--x-size-gap-list-13);
2555
2559
  }
2556
2560
  }
2557
- .x-filter--justified.x-filter > *:last-child:not(.x-filter__label),
2558
- .x-filter--justified .x-filter > *:last-child:not(.x-filter__label) {
2559
- margin-left: auto;
2560
- }
2561
2561
  /* @deprecated */
2562
2562
  :root {
2563
2563
  --x-size-padding-list-01: var(--x-size-base-01);
@@ -3063,10 +3063,6 @@
3063
3063
  --x-mix-blend-mode-picture-fallback-default: var(--x-mix-blend-mode-picture-default);
3064
3064
  --x-mix-blend-mode-picture-placeholder-default: var(--x-mix-blend-mode-picture-default);
3065
3065
  }
3066
- .x-picture--fixed-ratio.x-picture {
3067
- aspect-ratio: var(--x-number-aspect-ratio-picture);
3068
- width: 100%;
3069
- }
3070
3066
  :root {
3071
3067
  --x-number-aspect-ratio-picture: 1;
3072
3068
  }
@@ -3085,6 +3081,10 @@
3085
3081
  border-radius: var(--x-size-border-radius-progress-bar-default);
3086
3082
  background-color: var(--x-color-background-progress-bar-line-default);
3087
3083
  }
3084
+ .x-picture--fixed-ratio.x-picture {
3085
+ aspect-ratio: var(--x-number-aspect-ratio-picture);
3086
+ width: 100%;
3087
+ }
3088
3088
  :root {
3089
3089
  --x-size-height-progress-bar-line-default: var(--x-size-base-02);
3090
3090
  --x-size-width-progress-bar-line-default: var(--x-size-base-20);
@@ -0,0 +1,13 @@
1
+ <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
+
3
+ [Home](./index.md) &gt; [@empathyco/x-components](./x-components.md) &gt; [BaseModal](./x-components.basemodal.md) &gt; [focusOnOpen](./x-components.basemodal.focusonopen.md)
4
+
5
+ ## BaseModal.focusOnOpen property
6
+
7
+ Determines if the focused element changes to one inside the modal when it opens. Either the first element with a positive tabindex or just the first focusable element.
8
+
9
+ <b>Signature:</b>
10
+
11
+ ```typescript
12
+ focusOnOpen: boolean;
13
+ ```
@@ -19,6 +19,7 @@ export default class BaseModal extends Vue
19
19
  | --- | --- | --- | --- |
20
20
  | [$refs](./x-components.basemodal._refs.md) | | { modal: HTMLDivElement; } | |
21
21
  | [animation](./x-components.basemodal.animation.md) | | Vue \| string | Animation to use for opening/closing the modal. This animation only affects the content. |
22
+ | [focusOnOpen](./x-components.basemodal.focusonopen.md) | | boolean | Determines if the focused element changes to one inside the modal when it opens. Either the first element with a positive tabindex or just the first focusable element. |
22
23
  | [isWaitingForLeave](./x-components.basemodal.iswaitingforleave.md) | | boolean | Boolean to delay the leave animation until it has completed. |
23
24
  | [open](./x-components.basemodal.open.md) | | boolean | Determines if the modal is open or not. |
24
25
  | [overlayAnimation](./x-components.basemodal.overlayanimation.md) | | Vue \| string | Animation to use for the overlay (backdrop) part of the modal. By default, it uses a fade transition. |
@@ -0,0 +1,13 @@
1
+ <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
+
3
+ [Home](./index.md) &gt; [@empathyco/x-components](./x-components.md) &gt; [FOCUSABLE\_SELECTORS](./x-components.focusable_selectors.md)
4
+
5
+ ## FOCUSABLE\_SELECTORS variable
6
+
7
+ Comma separated list of common focusable selectors.
8
+
9
+ <b>Signature:</b>
10
+
11
+ ```typescript
12
+ FOCUSABLE_SELECTORS = "a[href], button:not([disabled]), details, input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])"
13
+ ```
@@ -451,6 +451,7 @@ X-Components is a library usable everywhere not only for search experiences.
451
451
  | [fetchRelatedTags](./x-components.fetchrelatedtags.md) | Default implementation for the [RelatedTagsActions.fetchRelatedTags()](./x-components.relatedtagsactions.fetchrelatedtags.md)<!-- -->. |
452
452
  | [fetchSearchResponse](./x-components.fetchsearchresponse.md) | Default implementation for the [SearchActions.fetchSearchResponse()](./x-components.searchactions.fetchsearchresponse.md)<!-- -->. |
453
453
  | [FiltersIcon](./x-components.filtersicon.md) | |
454
+ | [FOCUSABLE\_SELECTORS](./x-components.focusable_selectors.md) | Comma separated list of common focusable selectors. |
454
455
  | [getURLParameter](./x-components.geturlparameter.md) | Get one parameter value from the url. |
455
456
  | [Grid1ColIcon](./x-components.grid1colicon.md) | |
456
457
  | [Grid2ColIcon](./x-components.grid2colicon.md) | |
@@ -11,11 +11,12 @@ complex modals.
11
11
 
12
12
  ## Props
13
13
 
14
- | Name | Description | Type | Default |
15
- | ----------------------------- | ---------------------------------------------------------------------------------------------------------- | -------------------- | ---------------------------- |
16
- | <code>animation</code> | Animation to use for opening/closing the modal. This animation only affects the content. | <code>union</code> | <code>() => NoElement</code> |
17
- | <code>overlayAnimation</code> | Animation to use for the overlay (backdrop) part of the modal. By default, it uses<br />a fade transition. | <code>union</code> | <code>() => Fade</code> |
18
- | <code>open</code> | Determines if the modal is open or not. | <code>boolean</code> | <code></code> |
14
+ | Name | Description | Type | Default |
15
+ | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | ---------------------------- |
16
+ | <code>animation</code> | Animation to use for opening/closing the modal. This animation only affects the content. | <code>union</code> | <code>() => NoElement</code> |
17
+ | <code>overlayAnimation</code> | Animation to use for the overlay (backdrop) part of the modal. By default, it uses<br />a fade transition. | <code>union</code> | <code>() => Fade</code> |
18
+ | <code>open</code> | Determines if the modal is open or not. | <code>boolean</code> | <code></code> |
19
+ | <code>focusOnOpen</code> | Determines if the focused element changes to one inside the modal when it opens. Either the<br />first element with a positive tabindex or just the first focusable element. | <code>boolean</code> | <code>true</code> |
19
20
 
20
21
  ## Events
21
22
 
@@ -75,7 +75,7 @@ __vue_render__._withStripped = true;
75
75
  /* style */
76
76
  const __vue_inject_styles__ = undefined;
77
77
  /* scoped */
78
- const __vue_scope_id__ = "data-v-21dd0456";
78
+ const __vue_scope_id__ = "data-v-2b254d0a";
79
79
  /* module identifier */
80
80
  const __vue_module_identifier__ = undefined;
81
81
  /* functional template */
@@ -1 +1 @@
1
- {"version":3,"file":"base-modal.vue.js","sources":["../../../../src/components/modals/base-modal.vue"],"sourcesContent":["<template>\n <div v-show=\"isWaitingForLeave || open\" class=\"x-modal\" data-test=\"modal\">\n <component\n :is=\"animation\"\n @before-leave=\"isWaitingForLeave = true\"\n @after-leave=\"isWaitingForLeave = false\"\n >\n <div\n v-if=\"open\"\n ref=\"modal\"\n class=\"x-modal__content x-list\"\n data-test=\"modal-content\"\n role=\"dialog\"\n >\n <!-- @slot (Required) Modal container content -->\n <slot />\n </div>\n </component>\n <component :is=\"overlayAnimation\">\n <div\n v-if=\"open\"\n @click=\"emitOverlayClicked\"\n @keydown=\"emitOverlayClicked\"\n class=\"x-modal__overlay\"\n data-test=\"modal-overlay\"\n />\n </component>\n </div>\n</template>\n\n<script lang=\"ts\">\n import Vue from 'vue';\n import { Component, Prop } from 'vue-property-decorator';\n import Fade from '../animations/fade.vue';\n import { NoElement } from '../no-element';\n\n /**\n * Base component with no XPlugin dependencies that serves as a utility for constructing more\n * complex modals.\n *\n * @public\n */\n @Component\n export default class BaseModal extends Vue {\n /**\n * Animation to use for opening/closing the modal. This animation only affects the content.\n */\n @Prop({ default: () => NoElement })\n public animation!: Vue | string;\n\n /**\n * Animation to use for the overlay (backdrop) part of the modal. By default, it uses\n * a fade transition.\n */\n @Prop({ default: () => Fade })\n public overlayAnimation!: Vue | string;\n\n /**\n * Determines if the modal is open or not.\n */\n @Prop({ required: true })\n public open!: boolean;\n\n /** The previous value of the body overflow style. */\n protected previousBodyOverflow = '';\n /** The previous value of the HTML element overflow style. */\n protected previousHTMLOverflow = '';\n /** Boolean to delay the leave animation until it has completed. */\n protected isWaitingForLeave = false;\n\n public $refs!: {\n modal: HTMLDivElement;\n };\n\n protected mounted(): void {\n /* Watcher added after mount to prevent SSR from breaking */\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.$watch('open', this.syncBody);\n if (this.open) {\n this.syncBody(true);\n }\n }\n\n /**\n * Syncs the body to the open state of the modal, adding or removing styles and listeners.\n *\n * @param isOpen - True when the modal is opened.\n * @internal\n */\n protected syncBody(isOpen: boolean): void {\n if (isOpen) {\n this.disableScroll();\n this.addBodyListeners();\n /* eslint-disable @typescript-eslint/unbound-method */\n this.$on('hook:beforeDestroy', this.removeBodyListeners);\n this.$on('hook:beforeDestroy', this.enableScroll);\n /* eslint-enable @typescript-eslint/unbound-method */\n } else {\n this.enableScroll();\n this.removeBodyListeners();\n /* eslint-disable @typescript-eslint/unbound-method */\n this.$off('hook:beforeDestroy', this.removeBodyListeners);\n this.$off('hook:beforeDestroy', this.enableScroll);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n }\n\n /**\n * Disables the scroll of both the body and the window.\n *\n * @internal\n */\n protected disableScroll(): void {\n this.previousBodyOverflow = document.body.style.overflow;\n this.previousHTMLOverflow = document.documentElement.style.overflow;\n document.body.style.overflow = document.documentElement.style.overflow = 'hidden';\n }\n\n /**\n * Restores the scroll of both the body and the window.\n *\n * @internal\n */\n protected enableScroll(): void {\n document.body.style.overflow = this.previousBodyOverflow;\n document.documentElement.style.overflow = this.previousHTMLOverflow;\n }\n\n /**\n * Adds listeners to the body element ot detect if the modal should be closed.\n *\n * @internal\n */\n protected addBodyListeners(): void {\n /* eslint-disable @typescript-eslint/unbound-method */\n document.body.addEventListener('focusin', this.emitFocusInBody);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Removes the body listeners.\n *\n * @internal\n */\n protected removeBodyListeners(): void {\n /* eslint-disable @typescript-eslint/unbound-method */\n document.body.removeEventListener('focusin', this.emitFocusInBody);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Emits the `click:overlay` event if the click has been triggered in the overlay layer.\n *\n * @param event - The click event.\n * @internal\n */\n protected emitOverlayClicked(event: MouseEvent): void {\n this.$emit('click:overlay', event);\n }\n\n /**\n * Emits the `focusin:body` event if a focus event has been triggered outside the modal.\n *\n * @param event - The focusin event.\n * @internal\n */\n protected emitFocusInBody(event: FocusEvent): void {\n if (!this.$refs.modal.contains(event.target as HTMLElement)) {\n this.$emit('focusin:body', event);\n }\n }\n }\n</script>\n\n<style lang=\"scss\" scoped>\n .x-modal {\n position: fixed;\n top: 0;\n left: 0;\n display: flex;\n align-items: flex-start;\n justify-content: flex-start;\n width: 100%;\n height: 100%;\n z-index: 1;\n\n &__content {\n z-index: 1;\n }\n\n &__overlay {\n width: 100%;\n height: 100%;\n position: absolute;\n background-color: var(--x-modal-overlay-color, rgb(0, 0, 0));\n opacity: var(--x-modal-overlay-opacity, 0.7);\n }\n }\n</style>\n\n<docs lang=\"mdx\">\n## Examples\n\nThe `BaseModal` is a simple component that serves to create complex modals. Its open state has to be\npassed via prop. It also accepts an animation to use for opening & closing.\n\nIt emits a `click:overlay` event when any part out of the content is clicked, but only if the modal\nis open.\n\n```vue\n<template>\n <div>\n <button @click=\"open = true\">Open modal</button>\n <BaseModal animation=\"fadeAndSlide\" :open=\"open\" @click:overlay=\"open = false\">\n <h1>Hello</h1>\n <p>The modal is working</p>\n <button @click=\"open = false\">Close modal</button>\n </BaseModal>\n </div>\n</template>\n\n<script>\n import { BaseModal, FadeAndSlide } from '@empathyco/x-components';\n import Vue from 'vue';\n\n Vue.component('fadeAndSlide', FadeAndSlide);\n\n export default {\n components: {\n BaseModal\n },\n data() {\n return {\n open: false\n };\n }\n };\n</script>\n```\n\n## Vue Events\n\nA list of events that the component will emit:\n\n- `click:overlay`: the event is emitted after the user clicks any part out of the content but only\n if the modal is open. The event payload is the mouse event that triggers it.\n- `focusin:body`: the event is emitted after the user focus in any part out of the content but only\n if the modal is open. The event payload is the focus event that triggers it.\n</docs>\n"],"names":[],"mappings":";;;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"base-modal.vue.js","sources":["../../../../src/components/modals/base-modal.vue"],"sourcesContent":["<template>\n <div v-show=\"isWaitingForLeave || open\" class=\"x-modal\" data-test=\"modal\">\n <component\n :is=\"animation\"\n @before-leave=\"isWaitingForLeave = true\"\n @after-leave=\"isWaitingForLeave = false\"\n >\n <div\n v-if=\"open\"\n ref=\"modal\"\n class=\"x-modal__content x-list\"\n data-test=\"modal-content\"\n role=\"dialog\"\n >\n <!-- @slot (Required) Modal container content -->\n <slot />\n </div>\n </component>\n <component :is=\"overlayAnimation\">\n <div\n v-if=\"open\"\n @click=\"emitOverlayClicked\"\n @keydown=\"emitOverlayClicked\"\n class=\"x-modal__overlay\"\n data-test=\"modal-overlay\"\n />\n </component>\n </div>\n</template>\n\n<script lang=\"ts\">\n import Vue from 'vue';\n import { Component, Prop } from 'vue-property-decorator';\n import Fade from '../animations/fade.vue';\n import { NoElement } from '../no-element';\n import { FOCUSABLE_SELECTORS } from '../../utils/focus';\n\n /**\n * Base component with no XPlugin dependencies that serves as a utility for constructing more\n * complex modals.\n *\n * @public\n */\n @Component\n export default class BaseModal extends Vue {\n /**\n * Animation to use for opening/closing the modal. This animation only affects the content.\n */\n @Prop({ default: () => NoElement })\n public animation!: Vue | string;\n\n /**\n * Animation to use for the overlay (backdrop) part of the modal. By default, it uses\n * a fade transition.\n */\n @Prop({ default: () => Fade })\n public overlayAnimation!: Vue | string;\n\n /**\n * Determines if the modal is open or not.\n */\n @Prop({ required: true })\n public open!: boolean;\n\n /**\n * Determines if the focused element changes to one inside the modal when it opens. Either the\n * first element with a positive tabindex or just the first focusable element.\n */\n @Prop({ default: true })\n public focusOnOpen!: boolean;\n\n /** The previous value of the body overflow style. */\n protected previousBodyOverflow = '';\n /** The previous value of the HTML element overflow style. */\n protected previousHTMLOverflow = '';\n /** Boolean to delay the leave animation until it has completed. */\n protected isWaitingForLeave = false;\n\n public $refs!: {\n modal: HTMLDivElement;\n };\n\n protected mounted(): void {\n /* Watcher added after mount to prevent SSR from breaking */\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.$watch('open', this.syncBody);\n if (this.open) {\n this.syncBody(true);\n }\n }\n\n /**\n * Syncs the body to the open state of the modal, adding or removing styles and listeners.\n *\n * @param isOpen - True when the modal is opened.\n * @internal\n */\n protected syncBody(isOpen: boolean): void {\n if (isOpen) {\n this.disableScroll();\n this.addBodyListeners();\n /* eslint-disable @typescript-eslint/unbound-method */\n this.$on('hook:beforeDestroy', this.removeBodyListeners);\n this.$on('hook:beforeDestroy', this.enableScroll);\n /* eslint-enable @typescript-eslint/unbound-method */\n if (this.focusOnOpen) {\n this.setFocus();\n }\n } else {\n this.enableScroll();\n this.removeBodyListeners();\n /* eslint-disable @typescript-eslint/unbound-method */\n this.$off('hook:beforeDestroy', this.removeBodyListeners);\n this.$off('hook:beforeDestroy', this.enableScroll);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n }\n\n /**\n * Disables the scroll of both the body and the window.\n *\n * @internal\n */\n protected disableScroll(): void {\n this.previousBodyOverflow = document.body.style.overflow;\n this.previousHTMLOverflow = document.documentElement.style.overflow;\n document.body.style.overflow = document.documentElement.style.overflow = 'hidden';\n }\n\n /**\n * Restores the scroll of both the body and the window.\n *\n * @internal\n */\n protected enableScroll(): void {\n document.body.style.overflow = this.previousBodyOverflow;\n document.documentElement.style.overflow = this.previousHTMLOverflow;\n }\n\n /**\n * Adds listeners to the body element ot detect if the modal should be closed.\n *\n * @internal\n */\n protected addBodyListeners(): void {\n /* eslint-disable @typescript-eslint/unbound-method */\n document.body.addEventListener('focusin', this.emitFocusInBody);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Removes the body listeners.\n *\n * @internal\n */\n protected removeBodyListeners(): void {\n /* eslint-disable @typescript-eslint/unbound-method */\n document.body.removeEventListener('focusin', this.emitFocusInBody);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Emits the `click:overlay` event if the click has been triggered in the overlay layer.\n *\n * @param event - The click event.\n * @internal\n */\n protected emitOverlayClicked(event: MouseEvent): void {\n this.$emit('click:overlay', event);\n }\n\n /**\n * Emits the `focusin:body` event if a focus event has been triggered outside the modal.\n *\n * @param event - The focusin event.\n * @internal\n */\n protected emitFocusInBody(event: FocusEvent): void {\n if (!this.$refs.modal.contains(event.target as HTMLElement)) {\n this.$emit('focusin:body', event);\n }\n }\n\n /**\n * Sets the focused element to the first element either the first element with a positive\n * tabindex or, if there isn't any, the first focusable element inside the modal.\n *\n * @internal\n */\n protected setFocus(): void {\n const focusCandidates: HTMLElement[] = Array.from(\n this.$refs.modal.querySelectorAll(FOCUSABLE_SELECTORS)\n );\n\n const elementToFocus =\n focusCandidates.find(element => element.tabIndex) ?? focusCandidates[0];\n\n elementToFocus?.focus();\n }\n }\n</script>\n\n<style lang=\"scss\" scoped>\n .x-modal {\n position: fixed;\n top: 0;\n left: 0;\n display: flex;\n align-items: flex-start;\n justify-content: flex-start;\n width: 100%;\n height: 100%;\n z-index: 1;\n\n &__content {\n z-index: 1;\n }\n\n &__overlay {\n width: 100%;\n height: 100%;\n position: absolute;\n background-color: var(--x-modal-overlay-color, rgb(0, 0, 0));\n opacity: var(--x-modal-overlay-opacity, 0.7);\n }\n }\n</style>\n\n<docs lang=\"mdx\">\n## Examples\n\nThe `BaseModal` is a simple component that serves to create complex modals. Its open state has to be\npassed via prop. It also accepts an animation to use for opening & closing.\n\nIt emits a `click:overlay` event when any part out of the content is clicked, but only if the modal\nis open.\n\n```vue\n<template>\n <div>\n <button @click=\"open = true\">Open modal</button>\n <BaseModal animation=\"fadeAndSlide\" :open=\"open\" @click:overlay=\"open = false\">\n <h1>Hello</h1>\n <p>The modal is working</p>\n <button @click=\"open = false\">Close modal</button>\n </BaseModal>\n </div>\n</template>\n\n<script>\n import { BaseModal, FadeAndSlide } from '@empathyco/x-components';\n import Vue from 'vue';\n\n Vue.component('fadeAndSlide', FadeAndSlide);\n\n export default {\n components: {\n BaseModal\n },\n data() {\n return {\n open: false\n };\n }\n };\n</script>\n```\n\n## Vue Events\n\nA list of events that the component will emit:\n\n- `click:overlay`: the event is emitted after the user clicks any part out of the content but only\n if the modal is open. The event payload is the mouse event that triggers it.\n- `focusin:body`: the event is emitted after the user focus in any part out of the content but only\n if the modal is open. The event payload is the focus event that triggers it.\n</docs>\n"],"names":[],"mappings":";;;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -3,6 +3,7 @@ import Vue from 'vue';
3
3
  import { Prop, Component } from 'vue-property-decorator';
4
4
  import __vue_component__ from '../animations/fade.vue.js';
5
5
  import { NoElement } from '../no-element.js';
6
+ import { FOCUSABLE_SELECTORS } from '../../utils/focus.js';
6
7
 
7
8
  /**
8
9
  * Base component with no XPlugin dependencies that serves as a utility for constructing more
@@ -42,6 +43,9 @@ let BaseModal = class BaseModal extends Vue {
42
43
  this.$on('hook:beforeDestroy', this.removeBodyListeners);
43
44
  this.$on('hook:beforeDestroy', this.enableScroll);
44
45
  /* eslint-enable @typescript-eslint/unbound-method */
46
+ if (this.focusOnOpen) {
47
+ this.setFocus();
48
+ }
45
49
  }
46
50
  else {
47
51
  this.enableScroll();
@@ -111,6 +115,17 @@ let BaseModal = class BaseModal extends Vue {
111
115
  this.$emit('focusin:body', event);
112
116
  }
113
117
  }
118
+ /**
119
+ * Sets the focused element to the first element either the first element with a positive
120
+ * tabindex or, if there isn't any, the first focusable element inside the modal.
121
+ *
122
+ * @internal
123
+ */
124
+ setFocus() {
125
+ const focusCandidates = Array.from(this.$refs.modal.querySelectorAll(FOCUSABLE_SELECTORS));
126
+ const elementToFocus = focusCandidates.find(element => element.tabIndex) ?? focusCandidates[0];
127
+ elementToFocus?.focus();
128
+ }
114
129
  };
115
130
  __decorate([
116
131
  Prop({ default: () => NoElement })
@@ -121,6 +136,9 @@ __decorate([
121
136
  __decorate([
122
137
  Prop({ required: true })
123
138
  ], BaseModal.prototype, "open", void 0);
139
+ __decorate([
140
+ Prop({ default: true })
141
+ ], BaseModal.prototype, "focusOnOpen", void 0);
124
142
  BaseModal = __decorate([
125
143
  Component
126
144
  ], BaseModal);
@@ -1 +1 @@
1
- {"version":3,"file":"base-modal.vue_rollup-plugin-vue_script.vue.js","sources":["../../../../src/components/modals/base-modal.vue?rollup-plugin-vue=script.ts"],"sourcesContent":["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nimport Vue from 'vue';\nimport { Component, Prop } from 'vue-property-decorator';\nimport Fade from '../animations/fade.vue';\nimport { NoElement } from '../no-element';\n\n/**\n * Base component with no XPlugin dependencies that serves as a utility for constructing more\n * complex modals.\n *\n * @public\n */\n@Component\nexport default class BaseModal extends Vue {\n /**\n * Animation to use for opening/closing the modal. This animation only affects the content.\n */\n @Prop({ default: () => NoElement })\n public animation!: Vue | string;\n\n /**\n * Animation to use for the overlay (backdrop) part of the modal. By default, it uses\n * a fade transition.\n */\n @Prop({ default: () => Fade })\n public overlayAnimation!: Vue | string;\n\n /**\n * Determines if the modal is open or not.\n */\n @Prop({ required: true })\n public open!: boolean;\n\n /** The previous value of the body overflow style. */\n protected previousBodyOverflow = '';\n /** The previous value of the HTML element overflow style. */\n protected previousHTMLOverflow = '';\n /** Boolean to delay the leave animation until it has completed. */\n protected isWaitingForLeave = false;\n\n public $refs!: {\n modal: HTMLDivElement;\n };\n\n protected mounted(): void {\n /* Watcher added after mount to prevent SSR from breaking */\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.$watch('open', this.syncBody);\n if (this.open) {\n this.syncBody(true);\n }\n }\n\n /**\n * Syncs the body to the open state of the modal, adding or removing styles and listeners.\n *\n * @param isOpen - True when the modal is opened.\n * @internal\n */\n protected syncBody(isOpen: boolean): void {\n if (isOpen) {\n this.disableScroll();\n this.addBodyListeners();\n /* eslint-disable @typescript-eslint/unbound-method */\n this.$on('hook:beforeDestroy', this.removeBodyListeners);\n this.$on('hook:beforeDestroy', this.enableScroll);\n /* eslint-enable @typescript-eslint/unbound-method */\n } else {\n this.enableScroll();\n this.removeBodyListeners();\n /* eslint-disable @typescript-eslint/unbound-method */\n this.$off('hook:beforeDestroy', this.removeBodyListeners);\n this.$off('hook:beforeDestroy', this.enableScroll);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n }\n\n /**\n * Disables the scroll of both the body and the window.\n *\n * @internal\n */\n protected disableScroll(): void {\n this.previousBodyOverflow = document.body.style.overflow;\n this.previousHTMLOverflow = document.documentElement.style.overflow;\n document.body.style.overflow = document.documentElement.style.overflow = 'hidden';\n }\n\n /**\n * Restores the scroll of both the body and the window.\n *\n * @internal\n */\n protected enableScroll(): void {\n document.body.style.overflow = this.previousBodyOverflow;\n document.documentElement.style.overflow = this.previousHTMLOverflow;\n }\n\n /**\n * Adds listeners to the body element ot detect if the modal should be closed.\n *\n * @internal\n */\n protected addBodyListeners(): void {\n /* eslint-disable @typescript-eslint/unbound-method */\n document.body.addEventListener('focusin', this.emitFocusInBody);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Removes the body listeners.\n *\n * @internal\n */\n protected removeBodyListeners(): void {\n /* eslint-disable @typescript-eslint/unbound-method */\n document.body.removeEventListener('focusin', this.emitFocusInBody);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Emits the `click:overlay` event if the click has been triggered in the overlay layer.\n *\n * @param event - The click event.\n * @internal\n */\n protected emitOverlayClicked(event: MouseEvent): void {\n this.$emit('click:overlay', event);\n }\n\n /**\n * Emits the `focusin:body` event if a focus event has been triggered outside the modal.\n *\n * @param event - The focusin event.\n * @internal\n */\n protected emitFocusInBody(event: FocusEvent): void {\n if (!this.$refs.modal.contains(event.target as HTMLElement)) {\n this.$emit('focusin:body', event);\n }\n }\n}\n"],"names":["Fade"],"mappings":";;;;;;AAoCA;;;;;;AAOA,IAAqB,SAAS,GAA9B,MAAqB,SAAU,SAAQ,GAAG;IAA1C;;;QAqBY,yBAAoB,GAAG,EAAE,CAAC;;QAE1B,yBAAoB,GAAG,EAAE,CAAC;;QAE1B,sBAAiB,GAAG,KAAK,CAAC;KAuGrC;IAjGW,OAAO;;;QAGf,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,IAAI,CAAC,IAAI,EAAE;YACb,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;SACrB;KACF;;;;;;;IAQS,QAAQ,CAAC,MAAe;QAChC,IAAI,MAAM,EAAE;YACV,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,IAAI,CAAC,gBAAgB,EAAE,CAAC;;YAExB,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;YACzD,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;;SAEnD;aAAM;YACL,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,CAAC,mBAAmB,EAAE,CAAC;;YAE3B,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAC1D,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;;SAEpD;KACF;;;;;;IAOS,aAAa;QACrB,IAAI,CAAC,oBAAoB,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;QACzD,IAAI,CAAC,oBAAoB,GAAG,QAAQ,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC;QACpE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;KACnF;;;;;;IAOS,YAAY;QACpB,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC;QACzD,QAAQ,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC;KACrE;;;;;;IAOS,gBAAgB;;QAExB,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;;KAEjE;;;;;;IAOS,mBAAmB;;QAE3B,QAAQ,CAAC,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;;KAEpE;;;;;;;IAQS,kBAAkB,CAAC,KAAiB;QAC5C,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;KACpC;;;;;;;IAQS,eAAe,CAAC,KAAiB;QACzC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAqB,CAAC,EAAE;YAC3D,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;SACnC;KACF;CACF,CAAA;AA3HC;IADC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,CAAC;4CACH;AAOhC;IADC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAMA,iBAAI,EAAE,CAAC;mDACS;AAMvC;IADC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;uCACH;AAlBH,SAAS;IAD7B,SAAS;GACW,SAAS,CAgI7B;aAhIoB,SAAS;;;;"}
1
+ {"version":3,"file":"base-modal.vue_rollup-plugin-vue_script.vue.js","sources":["../../../../src/components/modals/base-modal.vue?rollup-plugin-vue=script.ts"],"sourcesContent":["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nimport Vue from 'vue';\nimport { Component, Prop } from 'vue-property-decorator';\nimport Fade from '../animations/fade.vue';\nimport { NoElement } from '../no-element';\nimport { FOCUSABLE_SELECTORS } from '../../utils/focus';\n\n/**\n * Base component with no XPlugin dependencies that serves as a utility for constructing more\n * complex modals.\n *\n * @public\n */\n@Component\nexport default class BaseModal extends Vue {\n /**\n * Animation to use for opening/closing the modal. This animation only affects the content.\n */\n @Prop({ default: () => NoElement })\n public animation!: Vue | string;\n\n /**\n * Animation to use for the overlay (backdrop) part of the modal. By default, it uses\n * a fade transition.\n */\n @Prop({ default: () => Fade })\n public overlayAnimation!: Vue | string;\n\n /**\n * Determines if the modal is open or not.\n */\n @Prop({ required: true })\n public open!: boolean;\n\n /**\n * Determines if the focused element changes to one inside the modal when it opens. Either the\n * first element with a positive tabindex or just the first focusable element.\n */\n @Prop({ default: true })\n public focusOnOpen!: boolean;\n\n /** The previous value of the body overflow style. */\n protected previousBodyOverflow = '';\n /** The previous value of the HTML element overflow style. */\n protected previousHTMLOverflow = '';\n /** Boolean to delay the leave animation until it has completed. */\n protected isWaitingForLeave = false;\n\n public $refs!: {\n modal: HTMLDivElement;\n };\n\n protected mounted(): void {\n /* Watcher added after mount to prevent SSR from breaking */\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.$watch('open', this.syncBody);\n if (this.open) {\n this.syncBody(true);\n }\n }\n\n /**\n * Syncs the body to the open state of the modal, adding or removing styles and listeners.\n *\n * @param isOpen - True when the modal is opened.\n * @internal\n */\n protected syncBody(isOpen: boolean): void {\n if (isOpen) {\n this.disableScroll();\n this.addBodyListeners();\n /* eslint-disable @typescript-eslint/unbound-method */\n this.$on('hook:beforeDestroy', this.removeBodyListeners);\n this.$on('hook:beforeDestroy', this.enableScroll);\n /* eslint-enable @typescript-eslint/unbound-method */\n if (this.focusOnOpen) {\n this.setFocus();\n }\n } else {\n this.enableScroll();\n this.removeBodyListeners();\n /* eslint-disable @typescript-eslint/unbound-method */\n this.$off('hook:beforeDestroy', this.removeBodyListeners);\n this.$off('hook:beforeDestroy', this.enableScroll);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n }\n\n /**\n * Disables the scroll of both the body and the window.\n *\n * @internal\n */\n protected disableScroll(): void {\n this.previousBodyOverflow = document.body.style.overflow;\n this.previousHTMLOverflow = document.documentElement.style.overflow;\n document.body.style.overflow = document.documentElement.style.overflow = 'hidden';\n }\n\n /**\n * Restores the scroll of both the body and the window.\n *\n * @internal\n */\n protected enableScroll(): void {\n document.body.style.overflow = this.previousBodyOverflow;\n document.documentElement.style.overflow = this.previousHTMLOverflow;\n }\n\n /**\n * Adds listeners to the body element ot detect if the modal should be closed.\n *\n * @internal\n */\n protected addBodyListeners(): void {\n /* eslint-disable @typescript-eslint/unbound-method */\n document.body.addEventListener('focusin', this.emitFocusInBody);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Removes the body listeners.\n *\n * @internal\n */\n protected removeBodyListeners(): void {\n /* eslint-disable @typescript-eslint/unbound-method */\n document.body.removeEventListener('focusin', this.emitFocusInBody);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Emits the `click:overlay` event if the click has been triggered in the overlay layer.\n *\n * @param event - The click event.\n * @internal\n */\n protected emitOverlayClicked(event: MouseEvent): void {\n this.$emit('click:overlay', event);\n }\n\n /**\n * Emits the `focusin:body` event if a focus event has been triggered outside the modal.\n *\n * @param event - The focusin event.\n * @internal\n */\n protected emitFocusInBody(event: FocusEvent): void {\n if (!this.$refs.modal.contains(event.target as HTMLElement)) {\n this.$emit('focusin:body', event);\n }\n }\n\n /**\n * Sets the focused element to the first element either the first element with a positive\n * tabindex or, if there isn't any, the first focusable element inside the modal.\n *\n * @internal\n */\n protected setFocus(): void {\n const focusCandidates: HTMLElement[] = Array.from(\n this.$refs.modal.querySelectorAll(FOCUSABLE_SELECTORS)\n );\n\n const elementToFocus =\n focusCandidates.find(element => element.tabIndex) ?? focusCandidates[0];\n\n elementToFocus?.focus();\n }\n}\n"],"names":["Fade"],"mappings":";;;;;;;AAqCA;;;;;;AAOA,IAAqB,SAAS,GAA9B,MAAqB,SAAU,SAAQ,GAAG;IAA1C;;;QA4BY,yBAAoB,GAAG,EAAE,CAAC;;QAE1B,yBAAoB,GAAG,EAAE,CAAC;;QAE1B,sBAAiB,GAAG,KAAK,CAAC;KA2HrC;IArHW,OAAO;;;QAGf,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,IAAI,CAAC,IAAI,EAAE;YACb,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;SACrB;KACF;;;;;;;IAQS,QAAQ,CAAC,MAAe;QAChC,IAAI,MAAM,EAAE;YACV,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,IAAI,CAAC,gBAAgB,EAAE,CAAC;;YAExB,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;YACzD,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;;YAElD,IAAI,IAAI,CAAC,WAAW,EAAE;gBACpB,IAAI,CAAC,QAAQ,EAAE,CAAC;aACjB;SACF;aAAM;YACL,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,CAAC,mBAAmB,EAAE,CAAC;;YAE3B,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAC1D,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;;SAEpD;KACF;;;;;;IAOS,aAAa;QACrB,IAAI,CAAC,oBAAoB,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;QACzD,IAAI,CAAC,oBAAoB,GAAG,QAAQ,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC;QACpE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;KACnF;;;;;;IAOS,YAAY;QACpB,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC;QACzD,QAAQ,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC;KACrE;;;;;;IAOS,gBAAgB;;QAExB,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;;KAEjE;;;;;;IAOS,mBAAmB;;QAE3B,QAAQ,CAAC,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;;KAEpE;;;;;;;IAQS,kBAAkB,CAAC,KAAiB;QAC5C,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;KACpC;;;;;;;IAQS,eAAe,CAAC,KAAiB;QACzC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAqB,CAAC,EAAE;YAC3D,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;SACnC;KACF;;;;;;;IAQS,QAAQ;QAChB,MAAM,eAAe,GAAkB,KAAK,CAAC,IAAI,CAC/C,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,CACvD,CAAC;QAEF,MAAM,cAAc,GAClB,eAAe,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,eAAe,CAAC,CAAC,CAAC,CAAC;QAE1E,cAAc,EAAE,KAAK,EAAE,CAAC;KACzB;CACF,CAAA;AAtJC;IADC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,CAAC;4CACH;AAOhC;IADC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAMA,iBAAI,EAAE,CAAC;mDACS;AAMvC;IADC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;uCACH;AAOtB;IADC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;8CACK;AAzBV,SAAS;IAD7B,SAAS;GACW,SAAS,CA2J7B;aA3JoB,SAAS;;;;"}
@@ -1,6 +1,6 @@
1
1
  import { createInjector, createInjectorSSR } from 'vue-runtime-helpers';
2
2
 
3
- var css = ".x-modal[data-v-21dd0456] {\n position: fixed;\n top: 0;\n left: 0;\n display: flex;\n align-items: flex-start;\n justify-content: flex-start;\n width: 100%;\n height: 100%;\n z-index: 1;\n}\n.x-modal__content[data-v-21dd0456] {\n z-index: 1;\n}\n.x-modal__overlay[data-v-21dd0456] {\n width: 100%;\n height: 100%;\n position: absolute;\n background-color: var(--x-modal-overlay-color, rgb(0, 0, 0));\n opacity: var(--x-modal-overlay-opacity, 0.7);\n}";
3
+ var css = ".x-modal[data-v-2b254d0a] {\n position: fixed;\n top: 0;\n left: 0;\n display: flex;\n align-items: flex-start;\n justify-content: flex-start;\n width: 100%;\n height: 100%;\n z-index: 1;\n}\n.x-modal__content[data-v-2b254d0a] {\n z-index: 1;\n}\n.x-modal__overlay[data-v-2b254d0a] {\n width: 100%;\n height: 100%;\n position: absolute;\n background-color: var(--x-modal-overlay-color, rgb(0, 0, 0));\n opacity: var(--x-modal-overlay-opacity, 0.7);\n}";
4
4
  const isBrowser = /*#__PURE__*/ (function () {
5
5
  return (
6
6
  Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) !==
package/js/index.js CHANGED
@@ -143,6 +143,7 @@ export { clone } from './utils/clone.js';
143
143
  export { currencyFormatter } from './utils/currency-formatter.js';
144
144
  export { debounce as debounceFunction } from './utils/debounce.js';
145
145
  export { areFiltersDifferent, createRawFilters } from './utils/filters.js';
146
+ export { FOCUSABLE_SELECTORS } from './utils/focus.js';
146
147
  export { noOp } from './utils/function.js';
147
148
  export { getURLParameter } from './utils/get-url-parameters.js';
148
149
  export { isElementEqualOrContained } from './utils/html.js';
package/js/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,3 +1,5 @@
1
+ import { FOCUSABLE_SELECTORS } from '../utils/focus.js';
2
+
1
3
  /**
2
4
  * Implementation of {@link SpatialNavigation} using directional focus.
3
5
  *
@@ -19,8 +21,7 @@ class DirectionalFocusNavigationService {
19
21
  /**
20
22
  * Comma separated focusable selectors to look up.
21
23
  */
22
- // eslint-disable-next-line max-len
23
- focusableSelectors = 'a, button, details, input, textarea, select, [tabindex]:not([tabindex="-1"])') {
24
+ focusableSelectors = FOCUSABLE_SELECTORS) {
24
25
  this.container = container;
25
26
  this.focusableSelectors = focusableSelectors;
26
27
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"directional-focus-navigation.service.js","sources":["../../../src/services/directional-focus-navigation.service.ts"],"sourcesContent":["import { ArrowKey } from '../utils/types';\nimport {\n AbsoluteDistances,\n Intersection,\n Point,\n Points,\n SpatialNavigation\n} from './services.types';\n\n/**\n * Implementation of {@link SpatialNavigation} using directional focus.\n *\n * @public\n */\nexport class DirectionalFocusNavigationService implements SpatialNavigation {\n /**\n * The HTMLElement that is currently on focus and used as reference to navigateTo from.\n */\n private origin!: HTMLElement;\n\n /**\n * The DOMRect of the origin Element.\n */\n private originRect!: DOMRect;\n\n /**\n * Direction of the navigation.\n */\n private direction!: ArrowKey;\n\n /**\n * Weight of the projected intersection area weight in the\n * {@link DirectionalFocusNavigationService.getDistanceScore | getDistanceScore} formula.\n */\n private readonly intersectionAreaWeight = 100;\n\n /**\n * Weight of the absolute distance on the orthogonal axis between to elements when navigating\n * left or right. Used to calculate the displacement in\n * {@link DirectionalFocusNavigationService.getDisplacementAndAlignment |\n * getDisplacementAndAlignment}.\n */\n private readonly orthogonalWeightHorizontal = 30;\n\n /**\n * Weight of the absolute distance on the orthogonal axis between to elements when navigating\n * up or down. Used to calculate the displacement in\n * {@link DirectionalFocusNavigationService.getDisplacementAndAlignment |\n * getDisplacementAndAlignment}.\n */\n private readonly orthogonalWeightVertical = 2;\n\n /**\n * Weight of the degree of alignment between two elements when calculating the alignment in\n * {@link DirectionalFocusNavigationService.getDisplacementAndAlignment |\n * getDisplacementAndAlignment}.\n */\n private readonly alignWeight = 5;\n\n /**\n * Set of functions to filter out candidates based on the navigation's direction.\n */\n private readonly filterFunction = {\n ArrowUp: (candidateRect: DOMRect) => this.isBelow(this.originRect, candidateRect),\n ArrowRight: (candidateRect: DOMRect) => this.isRightSide(candidateRect, this.originRect),\n ArrowDown: (candidateRect: DOMRect) => this.isBelow(candidateRect, this.originRect),\n ArrowLeft: (candidateRect: DOMRect) => this.isRightSide(this.originRect, candidateRect)\n };\n\n /**\n * Constructor for the {@link DirectionalFocusNavigationService}.\n *\n * @param container - The element that contains the navigable elements.\n * @param focusableSelectors - A comma separated string with the focusable selectors to look up.\n */\n public constructor(\n /**\n * The {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement | HTMLElement} that\n * contains the navigable elements.\n */\n private readonly container: HTMLElement,\n /**\n * Comma separated focusable selectors to look up.\n */\n // eslint-disable-next-line max-len\n private readonly focusableSelectors: string = 'a, button, details, input, textarea, select, [tabindex]:not([tabindex=\"-1\"])'\n ) {}\n\n /**\n * Get the element that would be the next one to be navigated to based on the direction of the\n * arrow key pressed. If there are no possible candidates the element to focus would be the one on\n * currently on focus or the first one in the container.\n *\n * @param arrowKey - The arrow key that was pressed.\n *\n * @returns The element to navigate to.\n */\n navigateTo(arrowKey: ArrowKey): HTMLElement {\n const rawCandidates = this.getFocusableElements();\n this.direction = arrowKey;\n this.updateOrigin();\n\n return this.getBestCandidate(rawCandidates);\n }\n\n /**\n * Gets focusable elements within the container.\n *\n * @returns List of focusable elements.\n * @internal\n */\n private getFocusableElements(): HTMLElement[] {\n return Array.from(this.container.querySelectorAll(this.focusableSelectors));\n }\n\n /**\n * Updates the origin with the current document active element.\n *\n * @remarks\n * This also covers cases when the user might have iterated through the DOM using the TAB or\n * SHIFT+TAB keys.\n */\n private updateOrigin(): void {\n const newOrigin = document.activeElement as HTMLElement;\n this.origin = newOrigin;\n this.originRect = newOrigin.getBoundingClientRect();\n }\n\n /**\n * Finds the closest candidate to the origin from a list of candidates.\n *\n * @remarks\n * If there are no candidates the origin will be retrieved as best candidate.\n *\n * @param rawCandidates - List of all candidates.\n *\n * @returns The closest candidate to the origin or origin if there's none.\n * @internal\n */\n private getBestCandidate(rawCandidates: HTMLElement[]): HTMLElement {\n const candidates = this.filterCandidates(rawCandidates);\n let bestCandidate = this.origin;\n\n candidates.reduce((bestCurrentScore: number, candidate) => {\n const bestScore = Math.min(bestCurrentScore, this.getDistanceScore(candidate));\n if (bestScore !== bestCurrentScore) {\n bestCandidate = candidate;\n }\n return bestScore;\n }, Number.MAX_SAFE_INTEGER);\n\n return bestCandidate;\n }\n\n /**\n * Filters out candidates that can't be candidates based on the direction of the navigation and\n * if they are visible and enabled.\n *\n * @param rawCandidates - List of all candidates.\n *\n * @returns List of filtered candidates.\n * @internal\n */\n private filterCandidates(rawCandidates: HTMLElement[]): HTMLElement[] {\n return rawCandidates.filter(candidate => this.isValidCandidate(candidate));\n }\n\n /**\n * Checks if the provided candidate is not the origin, is visible, enabled and in the correct\n * direction to be a valid candidate.\n *\n * @param candidate - The candidate element.\n * @returns If the candidate is valid for the navigation.\n * @internal\n */\n private isValidCandidate(candidate: HTMLElement): boolean {\n return (\n candidate !== this.origin &&\n this.isCandidateVisible(candidate) &&\n this.hasFocusCompatibleAttributes(candidate) &&\n this.isInNavigateDirection(candidate)\n );\n }\n\n /**\n * Checks if the provided candidate is visible.\n *\n * @param candidate - The candidate element.\n * @returns If the candidate is visible.\n * @internal\n */\n private isCandidateVisible(candidate: HTMLElement): boolean {\n const candidateStyle = window.getComputedStyle(candidate, null);\n\n return !!(\n candidate.offsetWidth &&\n candidate.offsetHeight &&\n candidateStyle.visibility === 'visible'\n );\n }\n\n /**\n * Checks if the provided candidate is disabled and if the tabindex allows the element to be\n * focused.\n *\n * @param candidate - The candidate element.\n * @returns If candidate's attributes allow it to be focused.\n * @internal\n */\n private hasFocusCompatibleAttributes(candidate: HTMLElement): boolean {\n return !candidate.getAttribute('disabled') && candidate.getAttribute('tabindex') !== '-1';\n }\n\n /**\n * Checks if the provided candidate is in the direction the navigation is going.\n *\n * @param candidate - The candidate element.\n * @returns If the candidate is in the correct direction.\n * @internal\n */\n private isInNavigateDirection(candidate: HTMLElement): boolean {\n return this.filterFunction[this.direction](candidate.getBoundingClientRect());\n }\n\n /**\n * Calculates the candidate's score for it to be the next element to navigateTo to based on a\n * formula that takes into account euclidean distance, displacement, alignment and\n * intersection area relative to the origin element.\n *\n * @param candidate - The candidate element.\n *\n * @returns The candidate score for best candidate.\n * @internal\n */\n private getDistanceScore(candidate: HTMLElement): number {\n const candidateRect = candidate.getBoundingClientRect();\n const { 0: candidatePoint, 1: originPoint } = this.getComparisionPoints(candidateRect);\n const absoluteDistances: AbsoluteDistances = {\n x: Math.abs(candidatePoint.x - originPoint.x),\n y: Math.abs(candidatePoint.y - originPoint.y)\n };\n const euclideanDistance = Math.sqrt(\n Math.pow(absoluteDistances.x, 2) + Math.pow(absoluteDistances.y, 2)\n );\n const intersection = this.getIntersection(this.originRect, candidateRect);\n const { displacement, alignment } = this.getDisplacementAndAlignment(\n candidateRect,\n intersection,\n absoluteDistances\n );\n const projectedArea = Math.sqrt(intersection.area) / this.intersectionAreaWeight;\n\n return euclideanDistance + displacement - alignment - projectedArea;\n }\n\n /**\n * Gets the closest point to origin within the candidate and to the candidate within the origin\n * based on the navigation direction.\n *\n * @param candidateRect - The DOMRect of the candidate.\n *\n * @returns The candidate's closest Points to the origin.\n * @internal\n */\n private getComparisionPoints(candidateRect: DOMRect): Points {\n const points: Points = [\n { x: 0, y: 0 },\n { x: 0, y: 0 }\n ];\n\n return {\n ...this.setParallelPointValues(points, candidateRect),\n ...this.setOrthogonalPointValues(points, candidateRect)\n };\n }\n\n /**\n * Set parallel values between candidate and origin based on the navigation direction and\n * returns them.\n *\n * @param points - Current values for the candidate and origin's points.\n * @param candidateRect - The DOMRect of the candidate.\n *\n * @returns Candidate and origin points with parallel values set.\n * @internal\n */\n private setParallelPointValues(\n { 0: candidatePoint, 1: originPoint }: Points,\n candidateRect: DOMRect\n ): Points {\n switch (this.direction) {\n case 'ArrowUp':\n candidatePoint.y = Math.min(candidateRect.bottom, this.originRect.top);\n originPoint.y = this.originRect.top;\n break;\n case 'ArrowDown':\n candidatePoint.y = Math.max(candidateRect.top, this.originRect.bottom);\n originPoint.y = this.originRect.bottom;\n break;\n case 'ArrowRight':\n candidatePoint.x = Math.max(candidateRect.left, this.originRect.right);\n originPoint.x = this.originRect.right;\n break;\n case 'ArrowLeft':\n candidatePoint.x = Math.min(candidateRect.right, this.originRect.left);\n originPoint.x = this.originRect.left;\n break;\n }\n\n return [candidatePoint, originPoint];\n }\n\n /**\n * Set orthogonal values between candidate and origin based on the navigation direction and\n * returns them.\n *\n * @param points - Current values for the candidate and origin's points.\n * @param candidateRect - The DOMRect of the candidate.\n *\n * @returns Candidate and origin points with orthogonal values set.\n * @internal\n */\n private setOrthogonalPointValues(\n { 0: candidatePoint, 1: originPoint }: Points,\n candidateRect: DOMRect\n ): Points {\n switch (this.direction) {\n case 'ArrowUp':\n case 'ArrowDown':\n if (this.isRightSide(this.originRect, candidateRect)) {\n candidatePoint.x = Math.min(candidateRect.right, this.originRect.left);\n originPoint.x = this.originRect.left;\n } else if (this.isRightSide(candidateRect, this.originRect)) {\n candidatePoint.x = Math.max(candidateRect.left, this.originRect.right);\n originPoint.x = this.originRect.right;\n } else {\n candidatePoint.x = Math.max(this.originRect.left, candidateRect.left);\n originPoint.x = candidatePoint.x;\n }\n break;\n\n case 'ArrowRight':\n case 'ArrowLeft':\n if (this.isBelow(this.originRect, candidateRect)) {\n candidatePoint.y = Math.min(candidateRect.bottom, this.originRect.top);\n originPoint.y = this.originRect.top;\n } else if (this.isBelow(candidateRect, this.originRect)) {\n candidatePoint.y = Math.max(candidateRect.top, this.originRect.bottom);\n originPoint.y = this.originRect.bottom;\n } else {\n candidatePoint.y = Math.max(this.originRect.top, candidateRect.top);\n originPoint.y = candidatePoint.y;\n }\n break;\n }\n\n return [candidatePoint, originPoint];\n }\n\n /**\n * Calculates the displacement and alignment values for the candidate relative to the origin.\n *\n * @param candidateRect - The DOMRect of the candidate.\n * @param intersection - Projected intersection between candidate and origin.\n * @param absoluteDistances - Absolute distances between candidate and origin points.\n *\n * @returns Displacement and alignment values.\n * @internal\n */\n private getDisplacementAndAlignment(\n candidateRect: DOMRect,\n intersection: Intersection,\n absoluteDistances: AbsoluteDistances\n ): { displacement: number; alignment: number } {\n const areAligned = this.areAligned(this.originRect, candidateRect);\n\n let alignBias = 0;\n let orthogonalBias = 0;\n let displacement = 0;\n\n switch (this.direction) {\n case 'ArrowUp':\n case 'ArrowDown':\n if (areAligned) {\n alignBias = Math.min(intersection.width / this.originRect.width, 1);\n } else {\n orthogonalBias = this.originRect.width / 2;\n }\n\n displacement = (absoluteDistances.x + orthogonalBias) * this.orthogonalWeightVertical;\n break;\n\n case 'ArrowRight':\n case 'ArrowLeft':\n if (areAligned) {\n alignBias = Math.min(intersection.height / this.originRect.height, 1);\n } else {\n orthogonalBias = this.originRect.height / 2;\n }\n\n displacement = (absoluteDistances.y + orthogonalBias) * this.orthogonalWeightHorizontal;\n break;\n }\n\n return { displacement, alignment: alignBias * this.alignWeight };\n }\n\n /**\n * Calculates the projected intersection between two\n * {@link https://developer.mozilla.org/en-US/docs/Web/API/DOMRect | rects}.\n *\n * @param rect1 - First {@link https://developer.mozilla.org/en-US/docs/Web/API/DOMRect | rect}.\n * @param rect2 - Second {@link https://developer.mozilla.org/en-US/docs/Web/API/DOMRect | rect}.\n *\n * @returns The intersection.\n * @internal\n */\n private getIntersection(rect1: DOMRect, rect2: DOMRect): Intersection {\n const intersection: Intersection = { width: 0, height: 0, area: 0 };\n\n const topLeftPoint: Point = {\n x: Math.max(rect1.left, rect2.left),\n y: Math.max(rect1.top, rect2.top)\n };\n const bottomRightPoint: Point = {\n x: Math.min(rect1.right, rect2.right),\n y: Math.min(rect1.bottom, rect2.bottom)\n };\n\n intersection.width = Math.abs(topLeftPoint.x - bottomRightPoint.x);\n intersection.height = Math.abs(topLeftPoint.y - bottomRightPoint.y);\n\n if (topLeftPoint.x < bottomRightPoint.x || topLeftPoint.y < bottomRightPoint.y) {\n intersection.area = intersection.width * intersection.height;\n }\n\n return intersection;\n }\n\n /**\n * Checks that both DOMRect are aligned based on the provided direction.\n *\n * @param rect1 - The first DOMRect.\n * @param rect2 - The DOMRect that the first one will be compared to.\n *\n * @returns If the DOMRect are aligned.\n * @internal\n */\n private areAligned(rect1: DOMRect, rect2: DOMRect): boolean {\n return this.direction === 'ArrowLeft' || this.direction === 'ArrowRight'\n ? rect1.bottom > rect2.top && rect1.top < rect2.bottom\n : rect1.right > rect2.left && rect1.left < rect2.right;\n }\n\n /**\n * Checks that the first DOMRect is below the second one.\n *\n * @param rect1 - The first DOMRect.\n * @param rect2 - The DOMRect that the first one will be compared to.\n *\n * @returns If it's below.\n * @internal\n */\n private isBelow(rect1: DOMRect, rect2: DOMRect): boolean {\n return (\n rect1.top >= rect2.bottom ||\n (rect1.top >= rect2.top &&\n rect1.bottom > rect2.bottom &&\n rect1.left < rect2.right &&\n rect1.right > rect2.left)\n );\n }\n\n /**\n * Checks that the first DOMRect is to the right side of the second one.\n *\n * @param rect1 - The first DOMRect.\n * @param rect2 - The DOMRect that the first one will be compared to.\n *\n * @returns If it's to the right side.\n * @internal\n */\n private isRightSide(rect1: DOMRect, rect2: DOMRect): boolean {\n return (\n rect1.left >= rect2.right ||\n (rect1.left >= rect2.left &&\n rect1.right > rect2.right &&\n rect1.bottom > rect2.top &&\n rect1.top < rect2.bottom)\n );\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"directional-focus-navigation.service.js","sources":["../../../src/services/directional-focus-navigation.service.ts"],"sourcesContent":["import { FOCUSABLE_SELECTORS } from '../utils/focus';\nimport { ArrowKey } from '../utils/types';\nimport {\n AbsoluteDistances,\n Intersection,\n Point,\n Points,\n SpatialNavigation\n} from './services.types';\n\n/**\n * Implementation of {@link SpatialNavigation} using directional focus.\n *\n * @public\n */\nexport class DirectionalFocusNavigationService implements SpatialNavigation {\n /**\n * The HTMLElement that is currently on focus and used as reference to navigateTo from.\n */\n private origin!: HTMLElement;\n\n /**\n * The DOMRect of the origin Element.\n */\n private originRect!: DOMRect;\n\n /**\n * Direction of the navigation.\n */\n private direction!: ArrowKey;\n\n /**\n * Weight of the projected intersection area weight in the\n * {@link DirectionalFocusNavigationService.getDistanceScore | getDistanceScore} formula.\n */\n private readonly intersectionAreaWeight = 100;\n\n /**\n * Weight of the absolute distance on the orthogonal axis between to elements when navigating\n * left or right. Used to calculate the displacement in\n * {@link DirectionalFocusNavigationService.getDisplacementAndAlignment |\n * getDisplacementAndAlignment}.\n */\n private readonly orthogonalWeightHorizontal = 30;\n\n /**\n * Weight of the absolute distance on the orthogonal axis between to elements when navigating\n * up or down. Used to calculate the displacement in\n * {@link DirectionalFocusNavigationService.getDisplacementAndAlignment |\n * getDisplacementAndAlignment}.\n */\n private readonly orthogonalWeightVertical = 2;\n\n /**\n * Weight of the degree of alignment between two elements when calculating the alignment in\n * {@link DirectionalFocusNavigationService.getDisplacementAndAlignment |\n * getDisplacementAndAlignment}.\n */\n private readonly alignWeight = 5;\n\n /**\n * Set of functions to filter out candidates based on the navigation's direction.\n */\n private readonly filterFunction = {\n ArrowUp: (candidateRect: DOMRect) => this.isBelow(this.originRect, candidateRect),\n ArrowRight: (candidateRect: DOMRect) => this.isRightSide(candidateRect, this.originRect),\n ArrowDown: (candidateRect: DOMRect) => this.isBelow(candidateRect, this.originRect),\n ArrowLeft: (candidateRect: DOMRect) => this.isRightSide(this.originRect, candidateRect)\n };\n\n /**\n * Constructor for the {@link DirectionalFocusNavigationService}.\n *\n * @param container - The element that contains the navigable elements.\n * @param focusableSelectors - A comma separated string with the focusable selectors to look up.\n */\n public constructor(\n /**\n * The {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement | HTMLElement} that\n * contains the navigable elements.\n */\n private readonly container: HTMLElement,\n /**\n * Comma separated focusable selectors to look up.\n */\n private readonly focusableSelectors = FOCUSABLE_SELECTORS\n ) {}\n\n /**\n * Get the element that would be the next one to be navigated to based on the direction of the\n * arrow key pressed. If there are no possible candidates the element to focus would be the one on\n * currently on focus or the first one in the container.\n *\n * @param arrowKey - The arrow key that was pressed.\n *\n * @returns The element to navigate to.\n */\n navigateTo(arrowKey: ArrowKey): HTMLElement {\n const rawCandidates = this.getFocusableElements();\n this.direction = arrowKey;\n this.updateOrigin();\n\n return this.getBestCandidate(rawCandidates);\n }\n\n /**\n * Gets focusable elements within the container.\n *\n * @returns List of focusable elements.\n * @internal\n */\n private getFocusableElements(): HTMLElement[] {\n return Array.from(this.container.querySelectorAll(this.focusableSelectors));\n }\n\n /**\n * Updates the origin with the current document active element.\n *\n * @remarks\n * This also covers cases when the user might have iterated through the DOM using the TAB or\n * SHIFT+TAB keys.\n */\n private updateOrigin(): void {\n const newOrigin = document.activeElement as HTMLElement;\n this.origin = newOrigin;\n this.originRect = newOrigin.getBoundingClientRect();\n }\n\n /**\n * Finds the closest candidate to the origin from a list of candidates.\n *\n * @remarks\n * If there are no candidates the origin will be retrieved as best candidate.\n *\n * @param rawCandidates - List of all candidates.\n *\n * @returns The closest candidate to the origin or origin if there's none.\n * @internal\n */\n private getBestCandidate(rawCandidates: HTMLElement[]): HTMLElement {\n const candidates = this.filterCandidates(rawCandidates);\n let bestCandidate = this.origin;\n\n candidates.reduce((bestCurrentScore: number, candidate) => {\n const bestScore = Math.min(bestCurrentScore, this.getDistanceScore(candidate));\n if (bestScore !== bestCurrentScore) {\n bestCandidate = candidate;\n }\n return bestScore;\n }, Number.MAX_SAFE_INTEGER);\n\n return bestCandidate;\n }\n\n /**\n * Filters out candidates that can't be candidates based on the direction of the navigation and\n * if they are visible and enabled.\n *\n * @param rawCandidates - List of all candidates.\n *\n * @returns List of filtered candidates.\n * @internal\n */\n private filterCandidates(rawCandidates: HTMLElement[]): HTMLElement[] {\n return rawCandidates.filter(candidate => this.isValidCandidate(candidate));\n }\n\n /**\n * Checks if the provided candidate is not the origin, is visible, enabled and in the correct\n * direction to be a valid candidate.\n *\n * @param candidate - The candidate element.\n * @returns If the candidate is valid for the navigation.\n * @internal\n */\n private isValidCandidate(candidate: HTMLElement): boolean {\n return (\n candidate !== this.origin &&\n this.isCandidateVisible(candidate) &&\n this.hasFocusCompatibleAttributes(candidate) &&\n this.isInNavigateDirection(candidate)\n );\n }\n\n /**\n * Checks if the provided candidate is visible.\n *\n * @param candidate - The candidate element.\n * @returns If the candidate is visible.\n * @internal\n */\n private isCandidateVisible(candidate: HTMLElement): boolean {\n const candidateStyle = window.getComputedStyle(candidate, null);\n\n return !!(\n candidate.offsetWidth &&\n candidate.offsetHeight &&\n candidateStyle.visibility === 'visible'\n );\n }\n\n /**\n * Checks if the provided candidate is disabled and if the tabindex allows the element to be\n * focused.\n *\n * @param candidate - The candidate element.\n * @returns If candidate's attributes allow it to be focused.\n * @internal\n */\n private hasFocusCompatibleAttributes(candidate: HTMLElement): boolean {\n return !candidate.getAttribute('disabled') && candidate.getAttribute('tabindex') !== '-1';\n }\n\n /**\n * Checks if the provided candidate is in the direction the navigation is going.\n *\n * @param candidate - The candidate element.\n * @returns If the candidate is in the correct direction.\n * @internal\n */\n private isInNavigateDirection(candidate: HTMLElement): boolean {\n return this.filterFunction[this.direction](candidate.getBoundingClientRect());\n }\n\n /**\n * Calculates the candidate's score for it to be the next element to navigateTo to based on a\n * formula that takes into account euclidean distance, displacement, alignment and\n * intersection area relative to the origin element.\n *\n * @param candidate - The candidate element.\n *\n * @returns The candidate score for best candidate.\n * @internal\n */\n private getDistanceScore(candidate: HTMLElement): number {\n const candidateRect = candidate.getBoundingClientRect();\n const { 0: candidatePoint, 1: originPoint } = this.getComparisionPoints(candidateRect);\n const absoluteDistances: AbsoluteDistances = {\n x: Math.abs(candidatePoint.x - originPoint.x),\n y: Math.abs(candidatePoint.y - originPoint.y)\n };\n const euclideanDistance = Math.sqrt(\n Math.pow(absoluteDistances.x, 2) + Math.pow(absoluteDistances.y, 2)\n );\n const intersection = this.getIntersection(this.originRect, candidateRect);\n const { displacement, alignment } = this.getDisplacementAndAlignment(\n candidateRect,\n intersection,\n absoluteDistances\n );\n const projectedArea = Math.sqrt(intersection.area) / this.intersectionAreaWeight;\n\n return euclideanDistance + displacement - alignment - projectedArea;\n }\n\n /**\n * Gets the closest point to origin within the candidate and to the candidate within the origin\n * based on the navigation direction.\n *\n * @param candidateRect - The DOMRect of the candidate.\n *\n * @returns The candidate's closest Points to the origin.\n * @internal\n */\n private getComparisionPoints(candidateRect: DOMRect): Points {\n const points: Points = [\n { x: 0, y: 0 },\n { x: 0, y: 0 }\n ];\n\n return {\n ...this.setParallelPointValues(points, candidateRect),\n ...this.setOrthogonalPointValues(points, candidateRect)\n };\n }\n\n /**\n * Set parallel values between candidate and origin based on the navigation direction and\n * returns them.\n *\n * @param points - Current values for the candidate and origin's points.\n * @param candidateRect - The DOMRect of the candidate.\n *\n * @returns Candidate and origin points with parallel values set.\n * @internal\n */\n private setParallelPointValues(\n { 0: candidatePoint, 1: originPoint }: Points,\n candidateRect: DOMRect\n ): Points {\n switch (this.direction) {\n case 'ArrowUp':\n candidatePoint.y = Math.min(candidateRect.bottom, this.originRect.top);\n originPoint.y = this.originRect.top;\n break;\n case 'ArrowDown':\n candidatePoint.y = Math.max(candidateRect.top, this.originRect.bottom);\n originPoint.y = this.originRect.bottom;\n break;\n case 'ArrowRight':\n candidatePoint.x = Math.max(candidateRect.left, this.originRect.right);\n originPoint.x = this.originRect.right;\n break;\n case 'ArrowLeft':\n candidatePoint.x = Math.min(candidateRect.right, this.originRect.left);\n originPoint.x = this.originRect.left;\n break;\n }\n\n return [candidatePoint, originPoint];\n }\n\n /**\n * Set orthogonal values between candidate and origin based on the navigation direction and\n * returns them.\n *\n * @param points - Current values for the candidate and origin's points.\n * @param candidateRect - The DOMRect of the candidate.\n *\n * @returns Candidate and origin points with orthogonal values set.\n * @internal\n */\n private setOrthogonalPointValues(\n { 0: candidatePoint, 1: originPoint }: Points,\n candidateRect: DOMRect\n ): Points {\n switch (this.direction) {\n case 'ArrowUp':\n case 'ArrowDown':\n if (this.isRightSide(this.originRect, candidateRect)) {\n candidatePoint.x = Math.min(candidateRect.right, this.originRect.left);\n originPoint.x = this.originRect.left;\n } else if (this.isRightSide(candidateRect, this.originRect)) {\n candidatePoint.x = Math.max(candidateRect.left, this.originRect.right);\n originPoint.x = this.originRect.right;\n } else {\n candidatePoint.x = Math.max(this.originRect.left, candidateRect.left);\n originPoint.x = candidatePoint.x;\n }\n break;\n\n case 'ArrowRight':\n case 'ArrowLeft':\n if (this.isBelow(this.originRect, candidateRect)) {\n candidatePoint.y = Math.min(candidateRect.bottom, this.originRect.top);\n originPoint.y = this.originRect.top;\n } else if (this.isBelow(candidateRect, this.originRect)) {\n candidatePoint.y = Math.max(candidateRect.top, this.originRect.bottom);\n originPoint.y = this.originRect.bottom;\n } else {\n candidatePoint.y = Math.max(this.originRect.top, candidateRect.top);\n originPoint.y = candidatePoint.y;\n }\n break;\n }\n\n return [candidatePoint, originPoint];\n }\n\n /**\n * Calculates the displacement and alignment values for the candidate relative to the origin.\n *\n * @param candidateRect - The DOMRect of the candidate.\n * @param intersection - Projected intersection between candidate and origin.\n * @param absoluteDistances - Absolute distances between candidate and origin points.\n *\n * @returns Displacement and alignment values.\n * @internal\n */\n private getDisplacementAndAlignment(\n candidateRect: DOMRect,\n intersection: Intersection,\n absoluteDistances: AbsoluteDistances\n ): { displacement: number; alignment: number } {\n const areAligned = this.areAligned(this.originRect, candidateRect);\n\n let alignBias = 0;\n let orthogonalBias = 0;\n let displacement = 0;\n\n switch (this.direction) {\n case 'ArrowUp':\n case 'ArrowDown':\n if (areAligned) {\n alignBias = Math.min(intersection.width / this.originRect.width, 1);\n } else {\n orthogonalBias = this.originRect.width / 2;\n }\n\n displacement = (absoluteDistances.x + orthogonalBias) * this.orthogonalWeightVertical;\n break;\n\n case 'ArrowRight':\n case 'ArrowLeft':\n if (areAligned) {\n alignBias = Math.min(intersection.height / this.originRect.height, 1);\n } else {\n orthogonalBias = this.originRect.height / 2;\n }\n\n displacement = (absoluteDistances.y + orthogonalBias) * this.orthogonalWeightHorizontal;\n break;\n }\n\n return { displacement, alignment: alignBias * this.alignWeight };\n }\n\n /**\n * Calculates the projected intersection between two\n * {@link https://developer.mozilla.org/en-US/docs/Web/API/DOMRect | rects}.\n *\n * @param rect1 - First {@link https://developer.mozilla.org/en-US/docs/Web/API/DOMRect | rect}.\n * @param rect2 - Second {@link https://developer.mozilla.org/en-US/docs/Web/API/DOMRect | rect}.\n *\n * @returns The intersection.\n * @internal\n */\n private getIntersection(rect1: DOMRect, rect2: DOMRect): Intersection {\n const intersection: Intersection = { width: 0, height: 0, area: 0 };\n\n const topLeftPoint: Point = {\n x: Math.max(rect1.left, rect2.left),\n y: Math.max(rect1.top, rect2.top)\n };\n const bottomRightPoint: Point = {\n x: Math.min(rect1.right, rect2.right),\n y: Math.min(rect1.bottom, rect2.bottom)\n };\n\n intersection.width = Math.abs(topLeftPoint.x - bottomRightPoint.x);\n intersection.height = Math.abs(topLeftPoint.y - bottomRightPoint.y);\n\n if (topLeftPoint.x < bottomRightPoint.x || topLeftPoint.y < bottomRightPoint.y) {\n intersection.area = intersection.width * intersection.height;\n }\n\n return intersection;\n }\n\n /**\n * Checks that both DOMRect are aligned based on the provided direction.\n *\n * @param rect1 - The first DOMRect.\n * @param rect2 - The DOMRect that the first one will be compared to.\n *\n * @returns If the DOMRect are aligned.\n * @internal\n */\n private areAligned(rect1: DOMRect, rect2: DOMRect): boolean {\n return this.direction === 'ArrowLeft' || this.direction === 'ArrowRight'\n ? rect1.bottom > rect2.top && rect1.top < rect2.bottom\n : rect1.right > rect2.left && rect1.left < rect2.right;\n }\n\n /**\n * Checks that the first DOMRect is below the second one.\n *\n * @param rect1 - The first DOMRect.\n * @param rect2 - The DOMRect that the first one will be compared to.\n *\n * @returns If it's below.\n * @internal\n */\n private isBelow(rect1: DOMRect, rect2: DOMRect): boolean {\n return (\n rect1.top >= rect2.bottom ||\n (rect1.top >= rect2.top &&\n rect1.bottom > rect2.bottom &&\n rect1.left < rect2.right &&\n rect1.right > rect2.left)\n );\n }\n\n /**\n * Checks that the first DOMRect is to the right side of the second one.\n *\n * @param rect1 - The first DOMRect.\n * @param rect2 - The DOMRect that the first one will be compared to.\n *\n * @returns If it's to the right side.\n * @internal\n */\n private isRightSide(rect1: DOMRect, rect2: DOMRect): boolean {\n return (\n rect1.left >= rect2.right ||\n (rect1.left >= rect2.left &&\n rect1.right > rect2.right &&\n rect1.bottom > rect2.top &&\n rect1.top < rect2.bottom)\n );\n }\n}\n"],"names":[],"mappings":";;AAUA;;;;;MAKa,iCAAiC;;;;;;;IA6D5C;;;;;IAKmB,SAAsB;;;;IAItB,qBAAqB,mBAAmB;QAJxC,cAAS,GAAT,SAAS,CAAa;QAItB,uBAAkB,GAAlB,kBAAkB,CAAsB;;;;;QAlD1C,2BAAsB,GAAG,GAAG,CAAC;;;;;;;QAQ7B,+BAA0B,GAAG,EAAE,CAAC;;;;;;;QAQhC,6BAAwB,GAAG,CAAC,CAAC;;;;;;QAO7B,gBAAW,GAAG,CAAC,CAAC;;;;QAKhB,mBAAc,GAAG;YAChC,OAAO,EAAE,CAAC,aAAsB,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC;YACjF,UAAU,EAAE,CAAC,aAAsB,KAAK,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;YACxF,SAAS,EAAE,CAAC,aAAsB,KAAK,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;YACnF,SAAS,EAAE,CAAC,aAAsB,KAAK,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC;SACxF,CAAC;KAkBE;;;;;;;;;;IAWJ,UAAU,CAAC,QAAkB;QAC3B,MAAM,aAAa,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAClD,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,IAAI,CAAC,YAAY,EAAE,CAAC;QAEpB,OAAO,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;KAC7C;;;;;;;IAQO,oBAAoB;QAC1B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC;KAC7E;;;;;;;;IASO,YAAY;QAClB,MAAM,SAAS,GAAG,QAAQ,CAAC,aAA4B,CAAC;QACxD,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC,qBAAqB,EAAE,CAAC;KACrD;;;;;;;;;;;;IAaO,gBAAgB,CAAC,aAA4B;QACnD,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;QACxD,IAAI,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC;QAEhC,UAAU,CAAC,MAAM,CAAC,CAAC,gBAAwB,EAAE,SAAS;YACpD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;YAC/E,IAAI,SAAS,KAAK,gBAAgB,EAAE;gBAClC,aAAa,GAAG,SAAS,CAAC;aAC3B;YACD,OAAO,SAAS,CAAC;SAClB,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;QAE5B,OAAO,aAAa,CAAC;KACtB;;;;;;;;;;IAWO,gBAAgB,CAAC,aAA4B;QACnD,OAAO,aAAa,CAAC,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;KAC5E;;;;;;;;;IAUO,gBAAgB,CAAC,SAAsB;QAC7C,QACE,SAAS,KAAK,IAAI,CAAC,MAAM;YACzB,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC;YAClC,IAAI,CAAC,4BAA4B,CAAC,SAAS,CAAC;YAC5C,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,EACrC;KACH;;;;;;;;IASO,kBAAkB,CAAC,SAAsB;QAC/C,MAAM,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAEhE,OAAO,CAAC,EACN,SAAS,CAAC,WAAW;YACrB,SAAS,CAAC,YAAY;YACtB,cAAc,CAAC,UAAU,KAAK,SAAS,CACxC,CAAC;KACH;;;;;;;;;IAUO,4BAA4B,CAAC,SAAsB;QACzD,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,SAAS,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;KAC3F;;;;;;;;IASO,qBAAqB,CAAC,SAAsB;QAClD,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,qBAAqB,EAAE,CAAC,CAAC;KAC/E;;;;;;;;;;;IAYO,gBAAgB,CAAC,SAAsB;QAC7C,MAAM,aAAa,GAAG,SAAS,CAAC,qBAAqB,EAAE,CAAC;QACxD,MAAM,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC;QACvF,MAAM,iBAAiB,GAAsB;YAC3C,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;YAC7C,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;SAC9C,CAAC;QACF,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CACjC,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,CACpE,CAAC;QACF,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAC1E,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,2BAA2B,CAClE,aAAa,EACb,YAAY,EACZ,iBAAiB,CAClB,CAAC;QACF,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,sBAAsB,CAAC;QAEjF,OAAO,iBAAiB,GAAG,YAAY,GAAG,SAAS,GAAG,aAAa,CAAC;KACrE;;;;;;;;;;IAWO,oBAAoB,CAAC,aAAsB;QACjD,MAAM,MAAM,GAAW;YACrB,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;YACd,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;SACf,CAAC;QAEF,OAAO;YACL,GAAG,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,aAAa,CAAC;YACrD,GAAG,IAAI,CAAC,wBAAwB,CAAC,MAAM,EAAE,aAAa,CAAC;SACxD,CAAC;KACH;;;;;;;;;;;IAYO,sBAAsB,CAC5B,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,WAAW,EAAU,EAC7C,aAAsB;QAEtB,QAAQ,IAAI,CAAC,SAAS;YACpB,KAAK,SAAS;gBACZ,cAAc,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;gBACvE,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBACpC,MAAM;YACR,KAAK,WAAW;gBACd,cAAc,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;gBACvE,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;gBACvC,MAAM;YACR,KAAK,YAAY;gBACf,cAAc,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;gBACvE,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;gBACtC,MAAM;YACR,KAAK,WAAW;gBACd,cAAc,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBACvE,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBACrC,MAAM;SACT;QAED,OAAO,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;KACtC;;;;;;;;;;;IAYO,wBAAwB,CAC9B,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,WAAW,EAAU,EAC7C,aAAsB;QAEtB,QAAQ,IAAI,CAAC,SAAS;YACpB,KAAK,SAAS,CAAC;YACf,KAAK,WAAW;gBACd,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,EAAE;oBACpD,cAAc,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;oBACvE,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;iBACtC;qBAAM,IAAI,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE;oBAC3D,cAAc,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;oBACvE,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;iBACvC;qBAAM;oBACL,cAAc,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;oBACtE,WAAW,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC;iBAClC;gBACD,MAAM;YAER,KAAK,YAAY,CAAC;YAClB,KAAK,WAAW;gBACd,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,EAAE;oBAChD,cAAc,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;oBACvE,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;iBACrC;qBAAM,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE;oBACvD,cAAc,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;oBACvE,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;iBACxC;qBAAM;oBACL,cAAc,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;oBACpE,WAAW,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC;iBAClC;gBACD,MAAM;SACT;QAED,OAAO,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;KACtC;;;;;;;;;;;IAYO,2BAA2B,CACjC,aAAsB,EACtB,YAA0B,EAC1B,iBAAoC;QAEpC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAEnE,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,IAAI,YAAY,GAAG,CAAC,CAAC;QAErB,QAAQ,IAAI,CAAC,SAAS;YACpB,KAAK,SAAS,CAAC;YACf,KAAK,WAAW;gBACd,IAAI,UAAU,EAAE;oBACd,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;iBACrE;qBAAM;oBACL,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC;iBAC5C;gBAED,YAAY,GAAG,CAAC,iBAAiB,CAAC,CAAC,GAAG,cAAc,IAAI,IAAI,CAAC,wBAAwB,CAAC;gBACtF,MAAM;YAER,KAAK,YAAY,CAAC;YAClB,KAAK,WAAW;gBACd,IAAI,UAAU,EAAE;oBACd,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;iBACvE;qBAAM;oBACL,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;iBAC7C;gBAED,YAAY,GAAG,CAAC,iBAAiB,CAAC,CAAC,GAAG,cAAc,IAAI,IAAI,CAAC,0BAA0B,CAAC;gBACxF,MAAM;SACT;QAED,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;KAClE;;;;;;;;;;;IAYO,eAAe,CAAC,KAAc,EAAE,KAAc;QACpD,MAAM,YAAY,GAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAEpE,MAAM,YAAY,GAAU;YAC1B,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;YACnC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC;SAClC,CAAC;QACF,MAAM,gBAAgB,GAAU;YAC9B,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;YACrC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;SACxC,CAAC;QAEF,YAAY,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;QACnE,YAAY,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;QAEpE,IAAI,YAAY,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,EAAE;YAC9E,YAAY,CAAC,IAAI,GAAG,YAAY,CAAC,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC;SAC9D;QAED,OAAO,YAAY,CAAC;KACrB;;;;;;;;;;IAWO,UAAU,CAAC,KAAc,EAAE,KAAc;QAC/C,OAAO,IAAI,CAAC,SAAS,KAAK,WAAW,IAAI,IAAI,CAAC,SAAS,KAAK,YAAY;cACpE,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM;cACpD,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;KAC1D;;;;;;;;;;IAWO,OAAO,CAAC,KAAc,EAAE,KAAc;QAC5C,QACE,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,MAAM;aACxB,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG;gBACrB,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;gBAC3B,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK;gBACxB,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,EAC3B;KACH;;;;;;;;;;IAWO,WAAW,CAAC,KAAc,EAAE,KAAc;QAChD,QACE,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,KAAK;aACxB,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;gBACvB,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK;gBACzB,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG;gBACxB,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,EAC3B;KACH;;;;;"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Comma separated list of common focusable selectors.
3
+ *
4
+ * @public
5
+ */
6
+ /* eslint-disable max-len */
7
+ const FOCUSABLE_SELECTORS = 'a[href], button:not([disabled]), details, input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
8
+ /* eslint-enable max-len */
9
+
10
+ export { FOCUSABLE_SELECTORS };
11
+ //# sourceMappingURL=focus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus.js","sources":["../../../src/utils/focus.ts"],"sourcesContent":["/**\n * Comma separated list of common focusable selectors.\n *\n * @public\n */\n/* eslint-disable max-len */\nexport const FOCUSABLE_SELECTORS =\n 'a[href], button:not([disabled]), details, input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n/* eslint-enable max-len */\n"],"names":[],"mappings":"AAAA;;;;;AAKA;MACa,mBAAmB,GAC9B,qJAAqJ;AACvJ;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empathyco/x-components",
3
- "version": "3.0.0-alpha.183",
3
+ "version": "3.0.0-alpha.185",
4
4
  "description": "Empathy X Components",
5
5
  "author": "Empathy Systems Corporation S.L.",
6
6
  "license": "Apache-2.0",
@@ -48,7 +48,7 @@
48
48
  "gen:component-docs": "vue-docgen",
49
49
  "postbuild": "npm pack ./dist",
50
50
  "prepublishOnly": "npm run build",
51
- "test:unit": "jest && npm run test:unit-cypress",
51
+ "test:unit": "jest --silent && npm run test:unit-cypress",
52
52
  "test:unit-jest": "jest",
53
53
  "test:unit-cypress": "cypress run-ct",
54
54
  "test:unit-coverage": "jest --coverage",
@@ -133,5 +133,5 @@
133
133
  "access": "public",
134
134
  "directory": "dist"
135
135
  },
136
- "gitHead": "300ddba51b9e2397d73d0598195349143777b209"
136
+ "gitHead": "ac54219a3782d821220347f48c51d33d0da5336b"
137
137
  }
@@ -4643,6 +4643,33 @@
4643
4643
  },
4644
4644
  "isStatic": false
4645
4645
  },
4646
+ {
4647
+ "kind": "Property",
4648
+ "canonicalReference": "@empathyco/x-components!BaseModal#focusOnOpen:member",
4649
+ "docComment": "/**\n * Determines if the focused element changes to one inside the modal when it opens. Either the first element with a positive tabindex or just the first focusable element.\n */\n",
4650
+ "excerptTokens": [
4651
+ {
4652
+ "kind": "Content",
4653
+ "text": "focusOnOpen: "
4654
+ },
4655
+ {
4656
+ "kind": "Content",
4657
+ "text": "boolean"
4658
+ },
4659
+ {
4660
+ "kind": "Content",
4661
+ "text": ";"
4662
+ }
4663
+ ],
4664
+ "isOptional": false,
4665
+ "releaseTag": "Public",
4666
+ "name": "focusOnOpen",
4667
+ "propertyTypeTokenRange": {
4668
+ "startIndex": 1,
4669
+ "endIndex": 2
4670
+ },
4671
+ "isStatic": false
4672
+ },
4646
4673
  {
4647
4674
  "kind": "Property",
4648
4675
  "canonicalReference": "@empathyco/x-components!BaseModal#isWaitingForLeave:member",
@@ -18067,6 +18094,23 @@
18067
18094
  ],
18068
18095
  "name": "flatHierarchicalFilters"
18069
18096
  },
18097
+ {
18098
+ "kind": "Variable",
18099
+ "canonicalReference": "@empathyco/x-components!FOCUSABLE_SELECTORS:var",
18100
+ "docComment": "/**\n * Comma separated list of common focusable selectors.\n *\n * @public\n */\n",
18101
+ "excerptTokens": [
18102
+ {
18103
+ "kind": "Content",
18104
+ "text": "FOCUSABLE_SELECTORS = \"a[href], button:not([disabled]), details, input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\\\"-1\\\"])\""
18105
+ }
18106
+ ],
18107
+ "releaseTag": "Public",
18108
+ "name": "FOCUSABLE_SELECTORS",
18109
+ "variableTypeTokenRange": {
18110
+ "startIndex": 0,
18111
+ "endIndex": 0
18112
+ }
18113
+ },
18070
18114
  {
18071
18115
  "kind": "Function",
18072
18116
  "canonicalReference": "@empathyco/x-components!getRootXComponent:function(1)",
@@ -445,6 +445,7 @@ export class BaseModal extends Vue_2 {
445
445
  protected emitOverlayClicked(event: MouseEvent): void;
446
446
  // @internal
447
447
  protected enableScroll(): void;
448
+ focusOnOpen: boolean;
448
449
  protected isWaitingForLeave: boolean;
449
450
  // (undocumented)
450
451
  protected mounted(): void;
@@ -455,6 +456,8 @@ export class BaseModal extends Vue_2 {
455
456
  // @internal
456
457
  protected removeBodyListeners(): void;
457
458
  // @internal
459
+ protected setFocus(): void;
460
+ // @internal
458
461
  protected syncBody(isOpen: boolean): void;
459
462
  }
460
463
 
@@ -1778,6 +1781,9 @@ export class FixedHeaderAndAsidesLayout extends FixedHeaderAndAsidesLayout_base
1778
1781
  // @public
1779
1782
  export function flatHierarchicalFilters(hierarchicalFilters: HierarchicalFilter_2[]): HierarchicalFilter_2[];
1780
1783
 
1784
+ // @public
1785
+ export const FOCUSABLE_SELECTORS = "a[href], button:not([disabled]), details, input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])";
1786
+
1781
1787
  // @internal
1782
1788
  export function getBusAPI(bus: XBus, component: PrivateExtendedVueComponent): XComponentBusAPI;
1783
1789
 
@@ -19,6 +19,11 @@ export default class BaseModal extends Vue {
19
19
  * Determines if the modal is open or not.
20
20
  */
21
21
  open: boolean;
22
+ /**
23
+ * Determines if the focused element changes to one inside the modal when it opens. Either the
24
+ * first element with a positive tabindex or just the first focusable element.
25
+ */
26
+ focusOnOpen: boolean;
22
27
  /** The previous value of the body overflow style. */
23
28
  protected previousBodyOverflow: string;
24
29
  /** The previous value of the HTML element overflow style. */
@@ -74,5 +79,12 @@ export default class BaseModal extends Vue {
74
79
  * @internal
75
80
  */
76
81
  protected emitFocusInBody(event: FocusEvent): void;
82
+ /**
83
+ * Sets the focused element to the first element either the first element with a positive
84
+ * tabindex or, if there isn't any, the first focusable element inside the modal.
85
+ *
86
+ * @internal
87
+ */
88
+ protected setFocus(): void;
77
89
  }
78
90
  //# sourceMappingURL=base-modal.vue?rollup-plugin-vue=script.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base-modal.vue?rollup-plugin-vue=script.d.ts","sourceRoot":"","sources":["../../../../src/components/modals/base-modal.vue?rollup-plugin-vue=script.ts"],"names":[],"mappings":"AA+BA,OAAO,GAAG,MAAM,KAAK,CAAC;AAKtB;;;;;GAKG;AAEH,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,GAAG;IACxC;;OAEG;IAEI,SAAS,EAAG,GAAG,GAAG,MAAM,CAAC;IAEhC;;;OAGG;IAEI,gBAAgB,EAAG,GAAG,GAAG,MAAM,CAAC;IAEvC;;OAEG;IAEI,IAAI,EAAG,OAAO,CAAC;IAEtB,qDAAqD;IACrD,SAAS,CAAC,oBAAoB,SAAM;IACpC,6DAA6D;IAC7D,SAAS,CAAC,oBAAoB,SAAM;IACpC,mEAAmE;IACnE,SAAS,CAAC,iBAAiB,UAAS;IAE7B,KAAK,EAAG;QACb,KAAK,EAAE,cAAc,CAAC;KACvB,CAAC;IAEF,SAAS,CAAC,OAAO,IAAI,IAAI;IASzB;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAkBzC;;;;OAIG;IACH,SAAS,CAAC,aAAa,IAAI,IAAI;IAM/B;;;;OAIG;IACH,SAAS,CAAC,YAAY,IAAI,IAAI;IAK9B;;;;OAIG;IACH,SAAS,CAAC,gBAAgB,IAAI,IAAI;IAMlC;;;;OAIG;IACH,SAAS,CAAC,mBAAmB,IAAI,IAAI;IAMrC;;;;;OAKG;IACH,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAIrD;;;;;OAKG;IACH,SAAS,CAAC,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;CAKnD"}
1
+ {"version":3,"file":"base-modal.vue?rollup-plugin-vue=script.d.ts","sourceRoot":"","sources":["../../../../src/components/modals/base-modal.vue?rollup-plugin-vue=script.ts"],"names":[],"mappings":"AA+BA,OAAO,GAAG,MAAM,KAAK,CAAC;AAMtB;;;;;GAKG;AAEH,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,GAAG;IACxC;;OAEG;IAEI,SAAS,EAAG,GAAG,GAAG,MAAM,CAAC;IAEhC;;;OAGG;IAEI,gBAAgB,EAAG,GAAG,GAAG,MAAM,CAAC;IAEvC;;OAEG;IAEI,IAAI,EAAG,OAAO,CAAC;IAEtB;;;OAGG;IAEI,WAAW,EAAG,OAAO,CAAC;IAE7B,qDAAqD;IACrD,SAAS,CAAC,oBAAoB,SAAM;IACpC,6DAA6D;IAC7D,SAAS,CAAC,oBAAoB,SAAM;IACpC,mEAAmE;IACnE,SAAS,CAAC,iBAAiB,UAAS;IAE7B,KAAK,EAAG;QACb,KAAK,EAAE,cAAc,CAAC;KACvB,CAAC;IAEF,SAAS,CAAC,OAAO,IAAI,IAAI;IASzB;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAqBzC;;;;OAIG;IACH,SAAS,CAAC,aAAa,IAAI,IAAI;IAM/B;;;;OAIG;IACH,SAAS,CAAC,YAAY,IAAI,IAAI;IAK9B;;;;OAIG;IACH,SAAS,CAAC,gBAAgB,IAAI,IAAI;IAMlC;;;;OAIG;IACH,SAAS,CAAC,mBAAmB,IAAI,IAAI;IAMrC;;;;;OAKG;IACH,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAIrD;;;;;OAKG;IACH,SAAS,CAAC,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAMlD;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,IAAI,IAAI;CAU3B"}
@@ -1 +1 @@
1
- {"version":3,"file":"directional-focus-navigation.service.d.ts","sourceRoot":"","sources":["../../../src/services/directional-focus-navigation.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAKL,iBAAiB,EAClB,MAAM,kBAAkB,CAAC;AAE1B;;;;GAIG;AACH,qBAAa,iCAAkC,YAAW,iBAAiB;IA8DvE;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B;;OAEG;IAEH,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAtErC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAe;IAE7B;;OAEG;IACH,OAAO,CAAC,UAAU,CAAW;IAE7B;;OAEG;IACH,OAAO,CAAC,SAAS,CAAY;IAE7B;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAO;IAE9C;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAM;IAEjD;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAK;IAE9C;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAK;IAEjC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CAK7B;IAEF;;;;;OAKG;;IAED;;;OAGG;IACc,SAAS,EAAE,WAAW;IACvC;;OAEG;IAEc,kBAAkB,GAAE,MAAuF;IAG9H;;;;;;;;OAQG;IACH,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW;IAQ3C;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAI5B;;;;;;OAMG;IACH,OAAO,CAAC,YAAY;IAMpB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,gBAAgB;IAexB;;;;;;;;OAQG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IASxB;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;;;;;;OAOG;IACH,OAAO,CAAC,4BAA4B;IAIpC;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAI7B;;;;;;;;;OASG;IACH,OAAO,CAAC,gBAAgB;IAqBxB;;;;;;;;OAQG;IACH,OAAO,CAAC,oBAAoB;IAY5B;;;;;;;;;OASG;IACH,OAAO,CAAC,sBAAsB;IA0B9B;;;;;;;;;OASG;IACH,OAAO,CAAC,wBAAwB;IAqChC;;;;;;;;;OASG;IACH,OAAO,CAAC,2BAA2B;IAsCnC;;;;;;;;;OASG;IACH,OAAO,CAAC,eAAe;IAsBvB;;;;;;;;OAQG;IACH,OAAO,CAAC,UAAU;IAMlB;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO;IAUf;;;;;;;;OAQG;IACH,OAAO,CAAC,WAAW;CASpB"}
1
+ {"version":3,"file":"directional-focus-navigation.service.d.ts","sourceRoot":"","sources":["../../../src/services/directional-focus-navigation.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAKL,iBAAiB,EAClB,MAAM,kBAAkB,CAAC;AAE1B;;;;GAIG;AACH,qBAAa,iCAAkC,YAAW,iBAAiB;IA8DvE;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IArErC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAe;IAE7B;;OAEG;IACH,OAAO,CAAC,UAAU,CAAW;IAE7B;;OAEG;IACH,OAAO,CAAC,SAAS,CAAY;IAE7B;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAO;IAE9C;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAM;IAEjD;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAK;IAE9C;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAK;IAEjC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CAK7B;IAEF;;;;;OAKG;;IAED;;;OAGG;IACc,SAAS,EAAE,WAAW;IACvC;;OAEG;IACc,kBAAkB,SAAsB;IAG3D;;;;;;;;OAQG;IACH,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW;IAQ3C;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAI5B;;;;;;OAMG;IACH,OAAO,CAAC,YAAY;IAMpB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,gBAAgB;IAexB;;;;;;;;OAQG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IASxB;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;;;;;;OAOG;IACH,OAAO,CAAC,4BAA4B;IAIpC;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAI7B;;;;;;;;;OASG;IACH,OAAO,CAAC,gBAAgB;IAqBxB;;;;;;;;OAQG;IACH,OAAO,CAAC,oBAAoB;IAY5B;;;;;;;;;OASG;IACH,OAAO,CAAC,sBAAsB;IA0B9B;;;;;;;;;OASG;IACH,OAAO,CAAC,wBAAwB;IAqChC;;;;;;;;;OASG;IACH,OAAO,CAAC,2BAA2B;IAsCnC;;;;;;;;;OASG;IACH,OAAO,CAAC,eAAe;IAsBvB;;;;;;;;OAQG;IACH,OAAO,CAAC,UAAU;IAMlB;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO;IAUf;;;;;;;;OAQG;IACH,OAAO,CAAC,WAAW;CASpB"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Comma separated list of common focusable selectors.
3
+ *
4
+ * @public
5
+ */
6
+ export declare const FOCUSABLE_SELECTORS = "a[href], button:not([disabled]), details, input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])";
7
+ //# sourceMappingURL=focus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus.d.ts","sourceRoot":"","sources":["../../../src/utils/focus.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,mBAAmB,yJACsH,CAAC"}
@@ -4,6 +4,7 @@ export * from './clone';
4
4
  export * from './currency-formatter';
5
5
  export { debounce as debounceFunction } from './debounce';
6
6
  export * from './filters';
7
+ export * from './focus';
7
8
  export * from './function';
8
9
  export * from './get-url-parameters';
9
10
  export * from './html';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,uBAAuB,CAAC;AACtC,cAAc,SAAS,CAAC;AACxB,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC1D,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC1D,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,uBAAuB,CAAC;AACtC,cAAc,SAAS,CAAC;AACxB,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC1D,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC1D,cAAc,SAAS,CAAC"}