@empathyco/x-components 3.0.0-alpha.103 → 3.0.0-alpha.104
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/design-system/full-theme.css +86 -85
- package/docs/API-reference/api/x-components.editablenumberrangefilter.md +2 -0
- package/docs/API-reference/api/x-components.editablenumberrangefilter.rangefiltermax.md +11 -0
- package/docs/API-reference/api/x-components.editablenumberrangefilter.rangefiltermin.md +11 -0
- package/docs/API-reference/api/x-components.filterssearch.filterssearchinputmessage.md +11 -0
- package/docs/API-reference/api/x-components.filterssearch.md +1 -0
- package/docs/API-reference/api/x-components.searchinput.md +1 -0
- package/docs/API-reference/api/x-components.searchinput.searchinputmessage.md +11 -0
- package/docs/API-reference/components/facets/x-components.lists/filters-search.md +1 -1
- package/js/components/base-dropdown.vue.js +3 -2
- package/js/components/base-dropdown.vue.js.map +1 -1
- package/js/components/base-dropdown.vue_rollup-plugin-vue_script.vue.js +2 -1
- package/js/components/base-dropdown.vue_rollup-plugin-vue_script.vue.js.map +1 -1
- package/js/components/modals/base-modal.vue.js +6 -3
- package/js/components/modals/base-modal.vue.js.map +1 -1
- package/js/components/modals/base-modal.vue_rollup-plugin-vue_script.vue.js.map +1 -1
- package/js/x-modules/facets/components/filters/editable-number-range-filter.vue.js +3 -3
- package/js/x-modules/facets/components/filters/editable-number-range-filter.vue.js.map +1 -1
- package/js/x-modules/facets/components/filters/editable-number-range-filter.vue_rollup-plugin-vue_script.vue.js +2 -0
- package/js/x-modules/facets/components/filters/editable-number-range-filter.vue_rollup-plugin-vue_script.vue.js.map +1 -1
- package/js/x-modules/facets/components/lists/filters-search.vue.js +3 -3
- package/js/x-modules/facets/components/lists/filters-search.vue.js.map +1 -1
- package/js/x-modules/facets/components/lists/filters-search.vue_rollup-plugin-vue_script.vue.js +1 -0
- package/js/x-modules/facets/components/lists/filters-search.vue_rollup-plugin-vue_script.vue.js.map +1 -1
- package/js/x-modules/search-box/components/search-input.vue.js +3 -3
- package/js/x-modules/search-box/components/search-input.vue.js.map +1 -1
- package/js/x-modules/search-box/components/search-input.vue_rollup-plugin-vue_script.vue.js +4 -0
- package/js/x-modules/search-box/components/search-input.vue_rollup-plugin-vue_script.vue.js.map +1 -1
- package/package.json +2 -2
- package/report/x-components.api.json +108 -0
- package/report/x-components.api.md +8 -0
- package/types/components/base-dropdown.vue.d.ts +2 -1
- package/types/components/base-dropdown.vue.d.ts.map +1 -1
- package/types/components/modals/base-modal.vue.d.ts.map +1 -1
- package/types/x-modules/facets/components/filters/editable-number-range-filter.vue.d.ts +2 -0
- package/types/x-modules/facets/components/filters/editable-number-range-filter.vue.d.ts.map +1 -1
- package/types/x-modules/facets/components/lists/filters-search.vue.d.ts +1 -0
- package/types/x-modules/facets/components/lists/filters-search.vue.d.ts.map +1 -1
- package/types/x-modules/search-box/components/search-input.vue.d.ts +1 -0
- package/types/x-modules/search-box/components/search-input.vue.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,19 @@
|
|
|
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.104](https://github.com/empathyco/x/compare/@empathyco/x-components@3.0.0-alpha.103...@empathyco/x-components@3.0.0-alpha.104) (2022-06-07)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- fix rest of warnings for accessibility
|
|
11
|
+
([553d5ba](https://github.com/empathyco/x/commit/553d5bac9256871e69de2c3b87dfc99a993d0f1f)),
|
|
12
|
+
closes [EX-6149](https://searchbroker.atlassian.net/browse/EX-6149)
|
|
13
|
+
|
|
14
|
+
# Change Log
|
|
15
|
+
|
|
16
|
+
All notable changes to this project will be documented in this file. See
|
|
17
|
+
[Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
18
|
+
|
|
6
19
|
## [3.0.0-alpha.103](https://github.com/empathyco/x/compare/@empathyco/x-components@3.0.0-alpha.102...@empathyco/x-components@3.0.0-alpha.103) (2022-05-25)
|
|
7
20
|
|
|
8
21
|
### Documentation
|
|
@@ -2746,91 +2746,6 @@
|
|
|
2746
2746
|
--x-size-font-message-default: var(--x-size-font-title3);
|
|
2747
2747
|
--x-number-font-weight-message-default: var(--x-number-font-weight-title3);
|
|
2748
2748
|
}
|
|
2749
|
-
.x-option-list--bottom.x-option-list,
|
|
2750
|
-
.x-option-list--bottom .x-option-list {
|
|
2751
|
-
--x-color-text-option-list-button-default: var(--x-color-text-option-list-button-bottom);
|
|
2752
|
-
--x-color-text-option-list-button-default-hover: var(
|
|
2753
|
-
--x-color-text-option-list-button-bottom-hover
|
|
2754
|
-
);
|
|
2755
|
-
--x-color-border-option-list-item-default: var(--x-color-border-option-list-item-bottom);
|
|
2756
|
-
--x-color-border-top-option-list-item-default: var(--x-color-border-top-option-list-item-bottom);
|
|
2757
|
-
--x-color-border-right-option-list-item-default: var(
|
|
2758
|
-
--x-color-border-top-option-list-item-bottom
|
|
2759
|
-
);
|
|
2760
|
-
--x-color-border-bottom-option-list-item-default: var(
|
|
2761
|
-
--x-color-border-top-option-list-item-bottom
|
|
2762
|
-
);
|
|
2763
|
-
--x-color-border-left-option-list-item-default: var(--x-color-border-top-option-list-item-bottom);
|
|
2764
|
-
--x-size-border-width-option-list-item-default: var(
|
|
2765
|
-
--x-size-border-width-option-list-item-bottom
|
|
2766
|
-
);
|
|
2767
|
-
--x-size-border-width-top-option-list-item-default: var(
|
|
2768
|
-
--x-size-border-width-top-option-list-item-bottom
|
|
2769
|
-
);
|
|
2770
|
-
--x-size-border-width-right-option-list-item-default: var(
|
|
2771
|
-
--x-size-border-width-right-option-list-item-bottom
|
|
2772
|
-
);
|
|
2773
|
-
--x-size-border-width-bottom-option-list-item-default: var(
|
|
2774
|
-
--x-size-border-width-bottom-option-list-item-bottom
|
|
2775
|
-
);
|
|
2776
|
-
--x-size-border-width-left-option-list-item-default: var(
|
|
2777
|
-
--x-size-border-width-left-option-list-item-bottom
|
|
2778
|
-
);
|
|
2779
|
-
--x-font-decoration-option-list-button-default-hover: var(
|
|
2780
|
-
--x-font-decoration-option-list-button-bottom-hover
|
|
2781
|
-
);
|
|
2782
|
-
--x-size-font-option-list-button-default: var(--x-size-font-option-list-button-bottom);
|
|
2783
|
-
--x-number-font-weight-option-list-button-default: var(
|
|
2784
|
-
--x-number-font-weight-option-list-button-bottom
|
|
2785
|
-
);
|
|
2786
|
-
}
|
|
2787
|
-
.x-option-list--bottom.x-option-list .x-option-list__item.x-option-list__item--is-selected,
|
|
2788
|
-
.x-option-list--bottom .x-option-list .x-option-list__item.x-option-list__item--is-selected {
|
|
2789
|
-
--x-color-text-option-list-button-default-selected: var(
|
|
2790
|
-
--x-color-text-option-list-button-bottom-selected
|
|
2791
|
-
);
|
|
2792
|
-
--x-color-text-option-list-button-default-selected-hover: var(
|
|
2793
|
-
--x-color-text-option-list-button-bottom-selected-hover
|
|
2794
|
-
);
|
|
2795
|
-
--x-color-border-option-list-item-default-selected: var(
|
|
2796
|
-
--x-color-border-option-list-item-bottom-selected
|
|
2797
|
-
);
|
|
2798
|
-
--x-color-border-top-option-list-item-default-selected: var(
|
|
2799
|
-
--x-color-border-top-option-list-item-bottom-selected
|
|
2800
|
-
);
|
|
2801
|
-
--x-color-border-right-option-list-item-default-selected: var(
|
|
2802
|
-
--x-color-border-top-option-list-item-bottom-selected
|
|
2803
|
-
);
|
|
2804
|
-
--x-color-border-bottom-option-list-item-default-selected: var(
|
|
2805
|
-
--x-color-border-bottom-option-list-item-bottom-selected
|
|
2806
|
-
);
|
|
2807
|
-
--x-color-border-left-option-list-item-default-selected: var(
|
|
2808
|
-
--x-color-border-top-option-list-item-bottom-selected
|
|
2809
|
-
);
|
|
2810
|
-
--x-size-border-width-top-option-list-item-default: var(
|
|
2811
|
-
--x-size-border-width-top-option-list-item-bottom-selected
|
|
2812
|
-
);
|
|
2813
|
-
--x-size-border-width-right-option-list-item-default: var(
|
|
2814
|
-
--x-size-border-width-right-option-list-item-bottom-selected
|
|
2815
|
-
);
|
|
2816
|
-
--x-size-border-width-bottom-option-list-item-default: var(
|
|
2817
|
-
--x-size-border-width-bottom-option-list-item-bottom-selected
|
|
2818
|
-
);
|
|
2819
|
-
--x-size-border-width-left-option-list-item-default: var(
|
|
2820
|
-
--x-size-border-width-left-option-list-item-bottom-selected
|
|
2821
|
-
);
|
|
2822
|
-
--x-number-font-weight-option-list-button-default-selected: var(
|
|
2823
|
-
--x-number-font-weight-option-list-button-bottom-selected
|
|
2824
|
-
);
|
|
2825
|
-
}
|
|
2826
|
-
.x-option-list--bottom.x-option-list .x-option-list__item:last-child,
|
|
2827
|
-
.x-option-list--bottom .x-option-list .x-option-list__item:last-child {
|
|
2828
|
-
--x-size-border-width-option-list-item-default: inherit;
|
|
2829
|
-
--x-size-border-width-top-option-list-item-default: inherit;
|
|
2830
|
-
--x-size-border-width-right-option-list-item-default: inherit;
|
|
2831
|
-
--x-size-border-width-bottom-option-list-item-default: inherit;
|
|
2832
|
-
--x-size-border-width-left-option-list-item-default: inherit;
|
|
2833
|
-
}
|
|
2834
2749
|
:root {
|
|
2835
2750
|
--x-color-text-option-list-button-bottom-hover: var(--x-color-base-neutral-10);
|
|
2836
2751
|
--x-color-text-option-list-button-bottom-selected-hover: var(
|
|
@@ -7566,3 +7481,89 @@
|
|
|
7566
7481
|
.x-normal-case {
|
|
7567
7482
|
text-transform: none;
|
|
7568
7483
|
}
|
|
7484
|
+
|
|
7485
|
+
.x-option-list--bottom.x-option-list,
|
|
7486
|
+
.x-option-list--bottom .x-option-list {
|
|
7487
|
+
--x-color-text-option-list-button-default: var(--x-color-text-option-list-button-bottom);
|
|
7488
|
+
--x-color-text-option-list-button-default-hover: var(
|
|
7489
|
+
--x-color-text-option-list-button-bottom-hover
|
|
7490
|
+
);
|
|
7491
|
+
--x-color-border-option-list-item-default: var(--x-color-border-option-list-item-bottom);
|
|
7492
|
+
--x-color-border-top-option-list-item-default: var(--x-color-border-top-option-list-item-bottom);
|
|
7493
|
+
--x-color-border-right-option-list-item-default: var(
|
|
7494
|
+
--x-color-border-top-option-list-item-bottom
|
|
7495
|
+
);
|
|
7496
|
+
--x-color-border-bottom-option-list-item-default: var(
|
|
7497
|
+
--x-color-border-top-option-list-item-bottom
|
|
7498
|
+
);
|
|
7499
|
+
--x-color-border-left-option-list-item-default: var(--x-color-border-top-option-list-item-bottom);
|
|
7500
|
+
--x-size-border-width-option-list-item-default: var(
|
|
7501
|
+
--x-size-border-width-option-list-item-bottom
|
|
7502
|
+
);
|
|
7503
|
+
--x-size-border-width-top-option-list-item-default: var(
|
|
7504
|
+
--x-size-border-width-top-option-list-item-bottom
|
|
7505
|
+
);
|
|
7506
|
+
--x-size-border-width-right-option-list-item-default: var(
|
|
7507
|
+
--x-size-border-width-right-option-list-item-bottom
|
|
7508
|
+
);
|
|
7509
|
+
--x-size-border-width-bottom-option-list-item-default: var(
|
|
7510
|
+
--x-size-border-width-bottom-option-list-item-bottom
|
|
7511
|
+
);
|
|
7512
|
+
--x-size-border-width-left-option-list-item-default: var(
|
|
7513
|
+
--x-size-border-width-left-option-list-item-bottom
|
|
7514
|
+
);
|
|
7515
|
+
--x-font-decoration-option-list-button-default-hover: var(
|
|
7516
|
+
--x-font-decoration-option-list-button-bottom-hover
|
|
7517
|
+
);
|
|
7518
|
+
--x-size-font-option-list-button-default: var(--x-size-font-option-list-button-bottom);
|
|
7519
|
+
--x-number-font-weight-option-list-button-default: var(
|
|
7520
|
+
--x-number-font-weight-option-list-button-bottom
|
|
7521
|
+
);
|
|
7522
|
+
}
|
|
7523
|
+
.x-option-list--bottom.x-option-list .x-option-list__item.x-option-list__item--is-selected,
|
|
7524
|
+
.x-option-list--bottom .x-option-list .x-option-list__item.x-option-list__item--is-selected {
|
|
7525
|
+
--x-color-text-option-list-button-default-selected: var(
|
|
7526
|
+
--x-color-text-option-list-button-bottom-selected
|
|
7527
|
+
);
|
|
7528
|
+
--x-color-text-option-list-button-default-selected-hover: var(
|
|
7529
|
+
--x-color-text-option-list-button-bottom-selected-hover
|
|
7530
|
+
);
|
|
7531
|
+
--x-color-border-option-list-item-default-selected: var(
|
|
7532
|
+
--x-color-border-option-list-item-bottom-selected
|
|
7533
|
+
);
|
|
7534
|
+
--x-color-border-top-option-list-item-default-selected: var(
|
|
7535
|
+
--x-color-border-top-option-list-item-bottom-selected
|
|
7536
|
+
);
|
|
7537
|
+
--x-color-border-right-option-list-item-default-selected: var(
|
|
7538
|
+
--x-color-border-top-option-list-item-bottom-selected
|
|
7539
|
+
);
|
|
7540
|
+
--x-color-border-bottom-option-list-item-default-selected: var(
|
|
7541
|
+
--x-color-border-bottom-option-list-item-bottom-selected
|
|
7542
|
+
);
|
|
7543
|
+
--x-color-border-left-option-list-item-default-selected: var(
|
|
7544
|
+
--x-color-border-top-option-list-item-bottom-selected
|
|
7545
|
+
);
|
|
7546
|
+
--x-size-border-width-top-option-list-item-default: var(
|
|
7547
|
+
--x-size-border-width-top-option-list-item-bottom-selected
|
|
7548
|
+
);
|
|
7549
|
+
--x-size-border-width-right-option-list-item-default: var(
|
|
7550
|
+
--x-size-border-width-right-option-list-item-bottom-selected
|
|
7551
|
+
);
|
|
7552
|
+
--x-size-border-width-bottom-option-list-item-default: var(
|
|
7553
|
+
--x-size-border-width-bottom-option-list-item-bottom-selected
|
|
7554
|
+
);
|
|
7555
|
+
--x-size-border-width-left-option-list-item-default: var(
|
|
7556
|
+
--x-size-border-width-left-option-list-item-bottom-selected
|
|
7557
|
+
);
|
|
7558
|
+
--x-number-font-weight-option-list-button-default-selected: var(
|
|
7559
|
+
--x-number-font-weight-option-list-button-bottom-selected
|
|
7560
|
+
);
|
|
7561
|
+
}
|
|
7562
|
+
.x-option-list--bottom.x-option-list .x-option-list__item:last-child,
|
|
7563
|
+
.x-option-list--bottom .x-option-list .x-option-list__item:last-child {
|
|
7564
|
+
--x-size-border-width-option-list-item-default: inherit;
|
|
7565
|
+
--x-size-border-width-top-option-list-item-default: inherit;
|
|
7566
|
+
--x-size-border-width-right-option-list-item-default: inherit;
|
|
7567
|
+
--x-size-border-width-bottom-option-list-item-default: inherit;
|
|
7568
|
+
--x-size-border-width-left-option-list-item-default: inherit;
|
|
7569
|
+
}
|
|
@@ -26,4 +26,6 @@ export default class EditableNumberRangeFilter extends Vue
|
|
|
26
26
|
| [filter](./x-components.editablenumberrangefilter.filter.md) | | EditableNumberRangeFilterModel | The filter data to render and edit. |
|
|
27
27
|
| [hasClearButton](./x-components.editablenumberrangefilter.hasclearbutton.md) | | boolean | If <code>clear</code> prop is true, clear button, which sets to null component min and max values, is rendered. True by default. |
|
|
28
28
|
| [isInstant](./x-components.editablenumberrangefilter.isinstant.md) | | boolean | If <code>instant</code> prop is true, the needed events are emitted immediately; else, apply button is rendered to confirm to do it. False by default. |
|
|
29
|
+
| [rangeFilterMax](./x-components.editablenumberrangefilter.rangefiltermax.md) | | string | |
|
|
30
|
+
| [rangeFilterMin](./x-components.editablenumberrangefilter.rangefiltermin.md) | | string | |
|
|
29
31
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
|
2
|
+
|
|
3
|
+
[Home](./index.md) > [@empathyco/x-components](./x-components.md) > [EditableNumberRangeFilter](./x-components.editablenumberrangefilter.md) > [rangeFilterMax](./x-components.editablenumberrangefilter.rangefiltermax.md)
|
|
4
|
+
|
|
5
|
+
## EditableNumberRangeFilter.rangeFilterMax property
|
|
6
|
+
|
|
7
|
+
<b>Signature:</b>
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
protected rangeFilterMax: string;
|
|
11
|
+
```
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
|
2
|
+
|
|
3
|
+
[Home](./index.md) > [@empathyco/x-components](./x-components.md) > [EditableNumberRangeFilter](./x-components.editablenumberrangefilter.md) > [rangeFilterMin](./x-components.editablenumberrangefilter.rangefiltermin.md)
|
|
4
|
+
|
|
5
|
+
## EditableNumberRangeFilter.rangeFilterMin property
|
|
6
|
+
|
|
7
|
+
<b>Signature:</b>
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
protected rangeFilterMin: string;
|
|
11
|
+
```
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
|
2
|
+
|
|
3
|
+
[Home](./index.md) > [@empathyco/x-components](./x-components.md) > [FiltersSearch](./x-components.filterssearch.md) > [filtersSearchInputMessage](./x-components.filterssearch.filterssearchinputmessage.md)
|
|
4
|
+
|
|
5
|
+
## FiltersSearch.filtersSearchInputMessage property
|
|
6
|
+
|
|
7
|
+
<b>Signature:</b>
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
protected filtersSearchInputMessage: string;
|
|
11
|
+
```
|
|
@@ -18,6 +18,7 @@ export default class FiltersSearch extends FiltersSearch_base
|
|
|
18
18
|
| Property | Modifiers | Type | Description |
|
|
19
19
|
| --- | --- | --- | --- |
|
|
20
20
|
| [debounceInMs](./x-components.filterssearch.debounceinms.md) | | number | The debounce time for applying the filter sifting. |
|
|
21
|
+
| [filtersSearchInputMessage](./x-components.filterssearch.filterssearchinputmessage.md) | | string | |
|
|
21
22
|
| [query](./x-components.filterssearch.query.md) | | string | |
|
|
22
23
|
| [setQueryDebounced](./x-components.filterssearch.setquerydebounced.md) | | [DebouncedFunction](./x-components.debouncedfunction.md)<!-- --><\[string\]> | |
|
|
23
24
|
|
|
@@ -26,6 +26,7 @@ export default class SearchInput extends Vue
|
|
|
26
26
|
| [instantDebounceInMs](./x-components.searchinput.instantdebounceinms.md) | | number | Debounce time for the instant. |
|
|
27
27
|
| [maxLength](./x-components.searchinput.maxlength.md) | | number | Maximum characters allowed in the input search. |
|
|
28
28
|
| [query](./x-components.searchinput.query.md) | | string | |
|
|
29
|
+
| [searchInputMessage](./x-components.searchinput.searchinputmessage.md) | | string | |
|
|
29
30
|
|
|
30
31
|
## Methods
|
|
31
32
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
|
2
|
+
|
|
3
|
+
[Home](./index.md) > [@empathyco/x-components](./x-components.md) > [SearchInput](./x-components.searchinput.md) > [searchInputMessage](./x-components.searchinput.searchinputmessage.md)
|
|
4
|
+
|
|
5
|
+
## SearchInput.searchInputMessage property
|
|
6
|
+
|
|
7
|
+
<b>Signature:</b>
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
protected searchInputMessage: string;
|
|
11
|
+
```
|
|
@@ -73,7 +73,7 @@ Replacing search triggering:
|
|
|
73
73
|
@input="setQuery($event.target.value)"
|
|
74
74
|
:value="query"
|
|
75
75
|
class="x-input x-filters-search__input"
|
|
76
|
-
aria-label="
|
|
76
|
+
:aria-label="filtersSearchInputMessage"/>
|
|
77
77
|
<button @click="clearQuery">X</button>
|
|
78
78
|
</template>
|
|
79
79
|
<template #default="{ siftedFilters }">
|
|
@@ -101,6 +101,7 @@ var __vue_render__ = function () {
|
|
|
101
101
|
attrs: {
|
|
102
102
|
"aria-expanded": _vm.isOpen.toString(),
|
|
103
103
|
role: "listbox",
|
|
104
|
+
tabIndex: "0",
|
|
104
105
|
},
|
|
105
106
|
on: {
|
|
106
107
|
keydown: [
|
|
@@ -215,11 +216,11 @@ __vue_render__._withStripped = true;
|
|
|
215
216
|
/* style */
|
|
216
217
|
const __vue_inject_styles__ = function (inject) {
|
|
217
218
|
if (!inject) return
|
|
218
|
-
inject("data-v-
|
|
219
|
+
inject("data-v-7f6f2f40_0", { source: ".x-dropdown[data-v-7f6f2f40] {\n position: relative;\n}\n.x-dropdown__items-list[data-v-7f6f2f40] {\n z-index: 1;\n list-style: none;\n position: absolute;\n padding: 0;\n margin: 0;\n top: calc(100% + var(--x-size-gap-dropdown-default, 0));\n}", map: undefined, media: undefined });
|
|
219
220
|
|
|
220
221
|
};
|
|
221
222
|
/* scoped */
|
|
222
|
-
const __vue_scope_id__ = "data-v-
|
|
223
|
+
const __vue_scope_id__ = "data-v-7f6f2f40";
|
|
223
224
|
/* module identifier */
|
|
224
225
|
const __vue_module_identifier__ = undefined;
|
|
225
226
|
/* functional template */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-dropdown.vue.js","sources":["../../../src/components/base-dropdown.vue"],"sourcesContent":["<template>\n <div\n @keydown=\"updateSearchBuffer\"\n @keydown.down.prevent=\"highlightNextItem\"\n @keydown.up.prevent=\"highlightPreviousItem\"\n :class=\"dropdownCSSClasses\"\n class=\"x-dropdown\"\n >\n <button\n @click=\"toggle\"\n @keydown.up.down.prevent.stop=\"open\"\n aria-haspopup=\"listbox\"\n class=\"x-dropdown__toggle\"\n data-test=\"dropdown-toggle\"\n >\n <!--\n @slot Used to render the contents of the dropdown toggle button. If not provided, it uses\n the item slot as fallback.\n @binding {string|number|Identifiable} item - The item data to render.\n @binding {boolean} isOpen - True if the dropdown is opened, and false if it is closed.\n -->\n <slot v-if=\"$scopedSlots.toggle\" :isOpen=\"isOpen\" :item=\"value\" name=\"toggle\">\n {{ value }}\n </slot>\n <slot v-else :item=\"value\" name=\"item\">{{ value }}</slot>\n </button>\n\n <component :is=\"animation\">\n <ul\n v-if=\"isOpen\"\n @keydown.end=\"highlightLastItem\"\n @keydown.esc=\"close\"\n @keydown.home=\"highlightFirstItem\"\n :aria-expanded=\"isOpen.toString()\"\n class=\"x-dropdown__items-list\"\n role=\"listbox\"\n >\n <li v-for=\"(item, index) in items\" :key=\"item.id || item\" class=\"x-dropdown__list-item\">\n <button\n ref=\"itemButtons\"\n @click=\"emitSelectedItemChanged(item)\"\n :aria-selected=\"(index === highlightedItemIndex).toString()\"\n :aria-current=\"(item === value).toString()\"\n :class=\"itemsCSSClasses[index]\"\n class=\"x-dropdown__item\"\n data-test=\"dropdown-item\"\n role=\"option\"\n tabindex=\"-1\"\n >\n <!--\n @slot (required) Used to render each one of the items content, and as fallback\n for the toggle button content slot if it is not provided.\n @binding {string|number|Identifiable} item - Item to render\n @binding {boolean} isHighlighted - True when the item has the focus.\n @binding {boolean} isSelected - True when the item is selected.\n -->\n <slot\n :isHighlighted=\"index === highlightedItemIndex\"\n :isSelected=\"item === value\"\n :item=\"item\"\n name=\"item\"\n >\n {{ item }}\n </slot>\n </button>\n </li>\n </ul>\n </component>\n </div>\n</template>\n\n<script lang=\"ts\">\n import { Identifiable } from '@empathyco/x-types';\n import { Component, Prop, Watch } from 'vue-property-decorator';\n import Vue from 'vue';\n import { normalizeString } from '../utils/normalize';\n import { isInRange } from '../utils/number';\n import { debounce } from '../utils/debounce';\n import { VueCSSClasses } from '../utils/types';\n import { NoElement } from './no-element';\n\n type DropdownItem = string | number | Identifiable;\n\n /**\n * Dropdown component that mimics a Select element behavior, but with the option\n * to customize the toggle button and each item contents.\n *\n * @public\n */\n @Component({\n components: {\n NoElement\n },\n model: {\n event: 'change'\n }\n })\n export default class BaseDropdown extends Vue {\n /**\n * List of items to display.\n *\n * @public\n */\n @Prop({ required: true })\n public items!: DropdownItem[];\n\n /**\n * The selected item.\n *\n * @public\n */\n @Prop({ required: true })\n public value!: DropdownItem | null;\n\n /**\n * Animation component to use for expanding the dropdown. This is a single element animation,\n * so only `<transition>` components are allowed.\n *\n * @public\n */\n @Prop({ default: 'NoElement' })\n public animation!: typeof Vue | string;\n\n /**\n * Time to wait without receiving any keystroke before resetting the items search query.\n *\n * @public\n */\n @Prop({ default: 1000 })\n public searchTimeoutMs!: number;\n\n public $refs!: {\n /** Array containing the dropdown list buttons HTMLElements. */\n itemButtons: HTMLButtonElement[];\n };\n\n /**\n * Property to track whether the dropdown is expanded and displaying the full\n * list of items, or closed.\n *\n * @internal\n */\n protected isOpen = false;\n\n /**\n * Index of the element that has the focus in the list. -1 means no element has focus.\n *\n * @internal\n */\n protected highlightedItemIndex = -1;\n\n /**\n * String to search for the first element that starts with it.\n *\n * @internal\n */\n protected searchBuffer = '';\n\n /**\n * Resets the search buffer after a certain time has passed.\n *\n * @internal\n */\n protected restartResetSearchTimeout!: () => void;\n\n /**\n * Dynamic CSS classes to add to the dropdown root element.\n *\n * @returns An object containing the CSS classes to add to the dropdown root element.\n * @internal\n */\n protected get dropdownCSSClasses(): VueCSSClasses {\n return {\n 'x-dropdown--is-open': this.isOpen\n };\n }\n\n /**\n * Dynamic CSS classes to add to each one of the items.\n *\n * @returns An object containing the CSS classes to add to each item.\n * @internal\n */\n protected get itemsCSSClasses(): VueCSSClasses[] {\n return this.items.map((item, index) => {\n return {\n 'x-dropdown__item--is-selected': this.value === item,\n 'x-dropdown__item--is-highlighted': this.highlightedItemIndex === index\n };\n });\n }\n\n /**\n * If the dropdown is destroyed before removing the document listeners, it ensures that they\n * are removed too.\n *\n * @internal\n */\n protected beforeDestroy(): void {\n this.removeDocumentCloseListeners();\n }\n\n /**\n * Opens the dropdown.\n *\n * @internal\n */\n protected open(): void {\n this.isOpen = true;\n }\n\n /**\n * Closes the dropdown.\n *\n * @internal\n */\n protected close(): void {\n this.isOpen = false;\n }\n\n /**\n * If the dropdown is opened it closes it. If it is closed it opens it.\n *\n * @internal\n */\n protected toggle(): void {\n this.isOpen = !this.isOpen;\n }\n\n /**\n * Emits the event that the selected item has changed.\n *\n * @param item - The new selected item.\n * @internal\n */\n protected emitSelectedItemChanged(item: DropdownItem): void {\n this.$emit('change', item);\n this.close();\n }\n\n /**\n * Highlights the item after the one that is currently highlighted.\n *\n * @internal\n */\n protected highlightNextItem(): void {\n this.open();\n this.highlightedItemIndex = (this.highlightedItemIndex + 1) % this.items.length;\n }\n\n /**\n * Highlights the item before the one that is currently highlighted.\n *\n * @internal\n */\n protected highlightPreviousItem(): void {\n this.open();\n this.highlightedItemIndex =\n this.highlightedItemIndex > 0 ? this.highlightedItemIndex - 1 : this.items.length - 1;\n }\n\n /**\n * Highlights the first of the provided items.\n *\n * @internal\n */\n protected highlightFirstItem(): void {\n this.highlightedItemIndex = 0;\n }\n\n /**\n * Highlights the last of the provided items.\n *\n * @internal\n */\n protected highlightLastItem(): void {\n this.highlightedItemIndex = this.items.length - 1;\n }\n\n /**\n * Updates the variable that is used to search in the filters.\n *\n * @param event - The event coming from the user typing.\n * @internal\n */\n protected updateSearchBuffer(event: KeyboardEvent): void {\n if (/^\\w$/.test(event.key)) {\n const key = event.key;\n this.searchBuffer += key;\n this.restartResetSearchTimeout();\n }\n }\n\n /**\n * Highlights the item that matches the search buffer. To do so it checks the list buttons\n * text content. It highlights items folowing this priority:\n * - If an element is already highlighted, it starts searching from that element.\n * - If no element is found starting from the previously highlighted, it returns the first one.\n * - If no element is found matching the search query it highlights the first element.\n *\n * @param search - The search string to find in the HTML.\n * @internal\n */\n @Watch('searchBuffer')\n protected highlightMatchingItem(search: string): void {\n if (search) {\n const normalizedSearch = normalizeString(search);\n const matchingIndices = this.$refs.itemButtons.reduce<number[]>(\n (matchingIndices, button, index) => {\n const safeButtonWordCharacters = button.textContent!.replace(/[^\\w]/g, '');\n const normalizedButtonText = normalizeString(safeButtonWordCharacters);\n if (normalizedButtonText.startsWith(normalizedSearch)) {\n matchingIndices.push(index);\n }\n return matchingIndices;\n },\n []\n );\n this.highlightedItemIndex =\n // First matching item starting to search from the current highlighted element\n matchingIndices.find(index => index >= this.highlightedItemIndex) ??\n // First matching item\n matchingIndices[0] ??\n // First item\n 0;\n }\n }\n\n /**\n * Resets the search buffer.\n *\n * @internal\n */\n protected resetSearch(): void {\n this.searchBuffer = '';\n }\n\n /** Updates the debounced function to reset the search.\n *\n * @param searchTimeoutMs - The new milliseconds that have to pass without typing before\n * resetting the search.\n * @internal\n */\n @Watch('searchTimeoutMs', { immediate: true })\n protected updateSearchTimeout(searchTimeoutMs: number): void {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.restartResetSearchTimeout = debounce(this.resetSearch, searchTimeoutMs);\n }\n\n /**\n * Focuses the DOM element which matches the `highlightedItemIndex`.\n *\n * @param highlightedItemIndex - The index of the HTML element to focus.\n * @internal\n */\n @Watch('highlightedItemIndex', { immediate: true })\n protected focusHighlightedItem(highlightedItemIndex: number): void {\n this.$nextTick(() => {\n if (this.$refs.itemButtons && isInRange(highlightedItemIndex, [0, this.items.length - 1])) {\n const newItem = this.$refs.itemButtons[this.highlightedItemIndex];\n newItem.focus();\n }\n });\n }\n\n /**\n * When the dropdown is open it sets the focused element to the one that is selected.\n *\n * @param isOpen - True if the dropdown is open, false otherwise.\n * @internal\n */\n @Watch('isOpen')\n protected updateHighlightedItem(isOpen: boolean): void {\n if (isOpen) {\n this.highlightedItemIndex = this.value === null ? 0 : this.items.indexOf(this.value);\n } else {\n this.highlightedItemIndex = -1;\n }\n }\n\n /**\n * Adds and removes listeners to close the dropdown when it loses the focus.\n *\n * @param isOpen - True if the dropdown is open, false otherwise.\n * @internal\n */\n @Watch('isOpen')\n protected syncCloseListeners(isOpen: boolean): void {\n /*\n * Because there is an issue with Firefox in macOS and Safari that doesn't focus the target\n * element of the `mousedown` events, the `focusout` event `relatedTarget` property can't be\n * used to detect whether or not the user has blurred the dropdown. The hack here is to use\n * document listeners that have the side effect of losing the focus.\n */\n if (isOpen) {\n this.addDocumentCloseListeners();\n } else {\n this.removeDocumentCloseListeners();\n }\n }\n\n /**\n * Adds listeners to the document element to detect if the focus has moved out from the\n * dropdown.\n *\n * @internal\n */\n protected addDocumentCloseListeners(): void {\n /* eslint-disable @typescript-eslint/unbound-method */\n document.addEventListener('mousedown', this.closeIfEventIsOutOfDropdown);\n document.addEventListener('touchstart', this.closeIfEventIsOutOfDropdown);\n document.addEventListener('focusin', this.closeIfEventIsOutOfDropdown);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Removes the listeners of the document element to detect if the focus has moved out from the\n * dropdown.\n *\n * @internal\n */\n protected removeDocumentCloseListeners(): void {\n /* eslint-disable @typescript-eslint/unbound-method */\n document.removeEventListener('mousedown', this.closeIfEventIsOutOfDropdown);\n document.removeEventListener('touchstart', this.closeIfEventIsOutOfDropdown);\n document.removeEventListener('focusin', this.closeIfEventIsOutOfDropdown);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Closes the dropdown if the passed event has happened on an element out of the dropdown.\n *\n * @param event - The event to check if it has happen out of the dropdown component.\n */\n protected closeIfEventIsOutOfDropdown(event: MouseEvent | TouchEvent | FocusEvent): void {\n if (!this.$el.contains(event.target as HTMLElement)) {\n this.close();\n }\n }\n }\n</script>\n\n<style lang=\"scss\" scoped>\n .x-dropdown {\n position: relative;\n\n &__items-list {\n z-index: 1;\n list-style: none;\n position: absolute;\n padding: 0;\n margin: 0;\n top: calc(100% + var(--x-size-gap-dropdown-default, 0));\n }\n }\n</style>\n\n<docs lang=\"mdx\">\n## Example\n\nThe `Dropdown` component is a simple yet customizable select component. The component needs to work\nthe list of items available to select, which are passed using the `items` prop, and the selected\nitem, which is passed in using the `value` prop.\n\nThe supported items must be an array that can contain unique strings, unique numbers, or objects\nwith a unique `id` property.\n\nThe content of each item can be customized using the `item` slot, which apart from the data of the\nitem, it also receives via prop if the element is selected or highlighted.\n\nThere `toggle` slot can be used to customize the button that opens the dropdown. If this is not\nprovided, the `item` slot will be used for that.\n\n```vue\n<template>\n <BaseDropdown :items=\"items\" v-model=\"value\">\n <template #toggle=\"{ item, isOpen }\">{{ item }} {{ isOpen ? '🔼' : '🔽' }}️</template>\n\n <template #item=\"{ item, isSelected, isHighlighted }\">\n <span v-if=\"isHighlighted\">🟢</span>\n <span v-if=\"isSelected\">✅</span>\n <span>{{ item }}</span>\n </template>\n </BaseDropdown>\n</template>\n\n<script>\n import { BaseDropdown } from '@empathyco/x-components';\n\n export default {\n name: 'DropdownTest',\n components: {\n BaseDropdown\n },\n data() {\n return {\n items: ['a', 2, { id: '3' }],\n value: ['a']\n };\n }\n };\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"base-dropdown.vue.js","sources":["../../../src/components/base-dropdown.vue"],"sourcesContent":["<template>\n <div\n @keydown=\"updateSearchBuffer\"\n @keydown.down.prevent=\"highlightNextItem\"\n @keydown.up.prevent=\"highlightPreviousItem\"\n :class=\"dropdownCSSClasses\"\n class=\"x-dropdown\"\n >\n <button\n @click=\"toggle\"\n @keydown.up.down.prevent.stop=\"open\"\n aria-haspopup=\"listbox\"\n class=\"x-dropdown__toggle\"\n data-test=\"dropdown-toggle\"\n >\n <!--\n @slot Used to render the contents of the dropdown toggle button. If not provided, it uses\n the item slot as fallback.\n @binding {string|number|Identifiable} item - The item data to render.\n @binding {boolean} isOpen - True if the dropdown is opened, and false if it is closed.\n -->\n <slot v-if=\"$scopedSlots.toggle\" :isOpen=\"isOpen\" :item=\"value\" name=\"toggle\">\n {{ value }}\n </slot>\n <slot v-else :item=\"value\" name=\"item\">{{ value }}</slot>\n </button>\n\n <component :is=\"animation\">\n <ul\n v-if=\"isOpen\"\n @keydown.end=\"highlightLastItem\"\n @keydown.esc=\"close\"\n @keydown.home=\"highlightFirstItem\"\n :aria-expanded=\"isOpen.toString()\"\n class=\"x-dropdown__items-list\"\n role=\"listbox\"\n tabIndex=\"0\"\n >\n <li v-for=\"(item, index) in items\" :key=\"item.id || item\" class=\"x-dropdown__list-item\">\n <button\n ref=\"itemButtons\"\n @click=\"emitSelectedItemChanged(item)\"\n :aria-selected=\"(index === highlightedItemIndex).toString()\"\n :aria-current=\"(item === value).toString()\"\n :class=\"itemsCSSClasses[index]\"\n class=\"x-dropdown__item\"\n data-test=\"dropdown-item\"\n role=\"option\"\n tabindex=\"-1\"\n >\n <!--\n @slot (required) Used to render each one of the items content, and as fallback\n for the toggle button content slot if it is not provided.\n @binding {string|number|Identifiable} item - Item to render\n @binding {boolean} isHighlighted - True when the item has the focus.\n @binding {boolean} isSelected - True when the item is selected.\n -->\n <slot\n :isHighlighted=\"index === highlightedItemIndex\"\n :isSelected=\"item === value\"\n :item=\"item\"\n name=\"item\"\n >\n {{ item }}\n </slot>\n </button>\n </li>\n </ul>\n </component>\n </div>\n</template>\n\n<script lang=\"ts\">\n import { Identifiable } from '@empathyco/x-types';\n import { Component, Prop, Watch } from 'vue-property-decorator';\n import Vue from 'vue';\n import { normalizeString } from '../utils/normalize';\n import { isInRange } from '../utils/number';\n import { debounce } from '../utils/debounce';\n import { VueCSSClasses } from '../utils/types';\n import { NoElement } from './no-element';\n\n type DropdownItem = string | number | Identifiable;\n\n /**\n * Dropdown component that mimics a Select element behavior, but with the option\n * to customize the toggle button and each item contents.\n *\n * @public\n */\n @Component({\n components: {\n NoElement\n },\n model: {\n event: 'change'\n }\n })\n export default class BaseDropdown extends Vue {\n /**\n * List of items to display.\n *\n * @public\n */\n @Prop({ required: true })\n public items!: DropdownItem[];\n\n /**\n * The selected item.\n *\n * @public\n */\n @Prop({ required: true })\n public value!: DropdownItem | null;\n\n /**\n * Animation component to use for expanding the dropdown. This is a single element animation,\n * so only `<transition>` components are allowed.\n *\n * @public\n */\n @Prop({ default: 'NoElement' })\n public animation!: typeof Vue | string;\n\n /**\n * Time to wait without receiving any keystroke before resetting the items search query.\n *\n * @public\n */\n @Prop({ default: 1000 })\n public searchTimeoutMs!: number;\n\n public $refs!: {\n /** Array containing the dropdown list buttons HTMLElements. */\n itemButtons: HTMLButtonElement[];\n };\n\n /**\n * Property to track whether the dropdown is expanded and displaying the full\n * list of items, or closed.\n *\n * @internal\n */\n protected isOpen = false;\n\n /**\n * Index of the element that has the focus in the list. -1 means no element has focus.\n *\n * @internal\n */\n protected highlightedItemIndex = -1;\n\n /**\n * String to search for the first element that starts with it.\n *\n * @internal\n */\n protected searchBuffer = '';\n\n /**\n * Resets the search buffer after a certain time has passed.\n *\n * @internal\n */\n protected restartResetSearchTimeout!: () => void;\n\n /**\n * Dynamic CSS classes to add to the dropdown root element.\n *\n * @returns An object containing the CSS classes to add to the dropdown root element.\n * @internal\n */\n protected get dropdownCSSClasses(): VueCSSClasses {\n return {\n 'x-dropdown--is-open': this.isOpen\n };\n }\n\n /**\n * Dynamic CSS classes to add to each one of the items.\n *\n * @returns An object containing the CSS classes to add to each item.\n * @internal\n */\n protected get itemsCSSClasses(): VueCSSClasses[] {\n return this.items.map((item, index) => {\n return {\n 'x-dropdown__item--is-selected': this.value === item,\n 'x-dropdown__item--is-highlighted': this.highlightedItemIndex === index\n };\n });\n }\n\n /**\n * If the dropdown is destroyed before removing the document listeners, it ensures that they\n * are removed too.\n *\n * @internal\n */\n protected beforeDestroy(): void {\n this.removeDocumentCloseListeners();\n }\n\n /**\n * Opens the dropdown.\n *\n * @internal\n */\n protected open(): void {\n this.isOpen = true;\n }\n\n /**\n * Closes the dropdown.\n *\n * @internal\n */\n protected close(): void {\n this.isOpen = false;\n }\n\n /**\n * If the dropdown is opened it closes it. If it is closed it opens it.\n *\n * @internal\n */\n protected toggle(): void {\n this.isOpen = !this.isOpen;\n }\n\n /**\n * Emits the event that the selected item has changed.\n *\n * @param item - The new selected item.\n * @internal\n */\n protected emitSelectedItemChanged(item: DropdownItem): void {\n this.$emit('change', item);\n this.close();\n }\n\n /**\n * Highlights the item after the one that is currently highlighted.\n *\n * @internal\n */\n protected highlightNextItem(): void {\n this.open();\n this.highlightedItemIndex = (this.highlightedItemIndex + 1) % this.items.length;\n }\n\n /**\n * Highlights the item before the one that is currently highlighted.\n *\n * @internal\n */\n protected highlightPreviousItem(): void {\n this.open();\n this.highlightedItemIndex =\n this.highlightedItemIndex > 0 ? this.highlightedItemIndex - 1 : this.items.length - 1;\n }\n\n /**\n * Highlights the first of the provided items.\n *\n * @internal\n */\n protected highlightFirstItem(): void {\n this.highlightedItemIndex = 0;\n }\n\n /**\n * Highlights the last of the provided items.\n *\n * @internal\n */\n protected highlightLastItem(): void {\n this.highlightedItemIndex = this.items.length - 1;\n }\n\n /**\n * Updates the variable that is used to search in the filters.\n *\n * @param event - The event coming from the user typing.\n * @internal\n */\n protected updateSearchBuffer(event: KeyboardEvent): void {\n if (/^\\w$/.test(event.key)) {\n const key = event.key;\n this.searchBuffer += key;\n this.restartResetSearchTimeout();\n }\n }\n\n /**\n * Highlights the item that matches the search buffer. To do so it checks the list buttons\n * text content. It highlights items folowing this priority:\n * - If an element is already highlighted, it starts searching from that element.\n * - If no element is found starting from the previously highlighted, it returns the first one.\n * - If no element is found matching the search query it highlights the first element.\n *\n * @param search - The search string to find in the HTML.\n * @internal\n */\n @Watch('searchBuffer')\n protected highlightMatchingItem(search: string): void {\n if (search) {\n const normalizedSearch = normalizeString(search);\n const matchingIndices = this.$refs.itemButtons.reduce<number[]>(\n (matchingIndices, button, index) => {\n const safeButtonWordCharacters = button.textContent!.replace(/[^\\w]/g, '');\n const normalizedButtonText = normalizeString(safeButtonWordCharacters);\n if (normalizedButtonText.startsWith(normalizedSearch)) {\n matchingIndices.push(index);\n }\n return matchingIndices;\n },\n []\n );\n this.highlightedItemIndex =\n // First matching item starting to search from the current highlighted element\n matchingIndices.find(index => index >= this.highlightedItemIndex) ??\n // First matching item\n matchingIndices[0] ??\n // First item\n 0;\n }\n }\n\n /**\n * Resets the search buffer.\n *\n * @internal\n */\n protected resetSearch(): void {\n this.searchBuffer = '';\n }\n\n /**\n * Updates the debounced function to reset the search.\n *\n * @param searchTimeoutMs - The new milliseconds that have to pass without typing before\n * resetting the search.\n * @internal\n */\n @Watch('searchTimeoutMs', { immediate: true })\n protected updateSearchTimeout(searchTimeoutMs: number): void {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.restartResetSearchTimeout = debounce(this.resetSearch, searchTimeoutMs);\n }\n\n /**\n * Focuses the DOM element which matches the `highlightedItemIndex`.\n *\n * @param highlightedItemIndex - The index of the HTML element to focus.\n * @internal\n */\n @Watch('highlightedItemIndex', { immediate: true })\n protected focusHighlightedItem(highlightedItemIndex: number): void {\n this.$nextTick(() => {\n if (this.$refs.itemButtons && isInRange(highlightedItemIndex, [0, this.items.length - 1])) {\n const newItem = this.$refs.itemButtons[this.highlightedItemIndex];\n newItem.focus();\n }\n });\n }\n\n /**\n * When the dropdown is open it sets the focused element to the one that is selected.\n *\n * @param isOpen - True if the dropdown is open, false otherwise.\n * @internal\n */\n @Watch('isOpen')\n protected updateHighlightedItem(isOpen: boolean): void {\n if (isOpen) {\n this.highlightedItemIndex = this.value === null ? 0 : this.items.indexOf(this.value);\n } else {\n this.highlightedItemIndex = -1;\n }\n }\n\n /**\n * Adds and removes listeners to close the dropdown when it loses the focus.\n *\n * @param isOpen - True if the dropdown is open, false otherwise.\n * @internal\n */\n @Watch('isOpen')\n protected syncCloseListeners(isOpen: boolean): void {\n /*\n * Because there is an issue with Firefox in macOS and Safari that doesn't focus the target\n * element of the `mousedown` events, the `focusout` event `relatedTarget` property can't be\n * used to detect whether or not the user has blurred the dropdown. The hack here is to use\n * document listeners that have the side effect of losing the focus.\n */\n if (isOpen) {\n this.addDocumentCloseListeners();\n } else {\n this.removeDocumentCloseListeners();\n }\n }\n\n /**\n * Adds listeners to the document element to detect if the focus has moved out from the\n * dropdown.\n *\n * @internal\n */\n protected addDocumentCloseListeners(): void {\n /* eslint-disable @typescript-eslint/unbound-method */\n document.addEventListener('mousedown', this.closeIfEventIsOutOfDropdown);\n document.addEventListener('touchstart', this.closeIfEventIsOutOfDropdown);\n document.addEventListener('focusin', this.closeIfEventIsOutOfDropdown);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Removes the listeners of the document element to detect if the focus has moved out from the\n * dropdown.\n *\n * @internal\n */\n protected removeDocumentCloseListeners(): void {\n /* eslint-disable @typescript-eslint/unbound-method */\n document.removeEventListener('mousedown', this.closeIfEventIsOutOfDropdown);\n document.removeEventListener('touchstart', this.closeIfEventIsOutOfDropdown);\n document.removeEventListener('focusin', this.closeIfEventIsOutOfDropdown);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Closes the dropdown if the passed event has happened on an element out of the dropdown.\n *\n * @param event - The event to check if it has happen out of the dropdown component.\n */\n protected closeIfEventIsOutOfDropdown(event: MouseEvent | TouchEvent | FocusEvent): void {\n if (!this.$el.contains(event.target as HTMLElement)) {\n this.close();\n }\n }\n }\n</script>\n\n<style lang=\"scss\" scoped>\n .x-dropdown {\n position: relative;\n\n &__items-list {\n z-index: 1;\n list-style: none;\n position: absolute;\n padding: 0;\n margin: 0;\n top: calc(100% + var(--x-size-gap-dropdown-default, 0));\n }\n }\n</style>\n\n<docs lang=\"mdx\">\n## Example\n\nThe `Dropdown` component is a simple yet customizable select component. The component needs to work\nthe list of items available to select, which are passed using the `items` prop, and the selected\nitem, which is passed in using the `value` prop.\n\nThe supported items must be an array that can contain unique strings, unique numbers, or objects\nwith a unique `id` property.\n\nThe content of each item can be customized using the `item` slot, which apart from the data of the\nitem, it also receives via prop if the element is selected or highlighted.\n\nThere `toggle` slot can be used to customize the button that opens the dropdown. If this is not\nprovided, the `item` slot will be used for that.\n\n```vue\n<template>\n <BaseDropdown :items=\"items\" v-model=\"value\">\n <template #toggle=\"{ item, isOpen }\">{{ item }} {{ isOpen ? '🔼' : '🔽' }}️</template>\n\n <template #item=\"{ item, isSelected, isHighlighted }\">\n <span v-if=\"isHighlighted\">🟢</span>\n <span v-if=\"isSelected\">✅</span>\n <span>{{ item }}</span>\n </template>\n </BaseDropdown>\n</template>\n\n<script>\n import { BaseDropdown } from '@empathyco/x-components';\n\n export default {\n name: 'DropdownTest',\n components: {\n BaseDropdown\n },\n data() {\n return {\n items: ['a', 2, { id: '3' }],\n value: ['a']\n };\n }\n };\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -189,7 +189,8 @@ let BaseDropdown = class BaseDropdown extends Vue {
|
|
|
189
189
|
resetSearch() {
|
|
190
190
|
this.searchBuffer = '';
|
|
191
191
|
}
|
|
192
|
-
/**
|
|
192
|
+
/**
|
|
193
|
+
* Updates the debounced function to reset the search.
|
|
193
194
|
*
|
|
194
195
|
* @param searchTimeoutMs - The new milliseconds that have to pass without typing before
|
|
195
196
|
* resetting the search.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-dropdown.vue_rollup-plugin-vue_script.vue.js","sources":["../../../src/components/base-dropdown.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\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\n\n\n\n\n\n\n\n\n\n\n\nimport { Identifiable } from '@empathyco/x-types';\nimport { Component, Prop, Watch } from 'vue-property-decorator';\nimport Vue from 'vue';\nimport { normalizeString } from '../utils/normalize';\nimport { isInRange } from '../utils/number';\nimport { debounce } from '../utils/debounce';\nimport { VueCSSClasses } from '../utils/types';\nimport { NoElement } from './no-element';\n\ntype DropdownItem = string | number | Identifiable;\n\n/**\n * Dropdown component that mimics a Select element behavior, but with the option\n * to customize the toggle button and each item contents.\n *\n * @public\n */\n@Component({\n components: {\n NoElement\n },\n model: {\n event: 'change'\n }\n})\nexport default class BaseDropdown extends Vue {\n /**\n * List of items to display.\n *\n * @public\n */\n @Prop({ required: true })\n public items!: DropdownItem[];\n\n /**\n * The selected item.\n *\n * @public\n */\n @Prop({ required: true })\n public value!: DropdownItem | null;\n\n /**\n * Animation component to use for expanding the dropdown. This is a single element animation,\n * so only `<transition>` components are allowed.\n *\n * @public\n */\n @Prop({ default: 'NoElement' })\n public animation!: typeof Vue | string;\n\n /**\n * Time to wait without receiving any keystroke before resetting the items search query.\n *\n * @public\n */\n @Prop({ default: 1000 })\n public searchTimeoutMs!: number;\n\n public $refs!: {\n /** Array containing the dropdown list buttons HTMLElements. */\n itemButtons: HTMLButtonElement[];\n };\n\n /**\n * Property to track whether the dropdown is expanded and displaying the full\n * list of items, or closed.\n *\n * @internal\n */\n protected isOpen = false;\n\n /**\n * Index of the element that has the focus in the list. -1 means no element has focus.\n *\n * @internal\n */\n protected highlightedItemIndex = -1;\n\n /**\n * String to search for the first element that starts with it.\n *\n * @internal\n */\n protected searchBuffer = '';\n\n /**\n * Resets the search buffer after a certain time has passed.\n *\n * @internal\n */\n protected restartResetSearchTimeout!: () => void;\n\n /**\n * Dynamic CSS classes to add to the dropdown root element.\n *\n * @returns An object containing the CSS classes to add to the dropdown root element.\n * @internal\n */\n protected get dropdownCSSClasses(): VueCSSClasses {\n return {\n 'x-dropdown--is-open': this.isOpen\n };\n }\n\n /**\n * Dynamic CSS classes to add to each one of the items.\n *\n * @returns An object containing the CSS classes to add to each item.\n * @internal\n */\n protected get itemsCSSClasses(): VueCSSClasses[] {\n return this.items.map((item, index) => {\n return {\n 'x-dropdown__item--is-selected': this.value === item,\n 'x-dropdown__item--is-highlighted': this.highlightedItemIndex === index\n };\n });\n }\n\n /**\n * If the dropdown is destroyed before removing the document listeners, it ensures that they\n * are removed too.\n *\n * @internal\n */\n protected beforeDestroy(): void {\n this.removeDocumentCloseListeners();\n }\n\n /**\n * Opens the dropdown.\n *\n * @internal\n */\n protected open(): void {\n this.isOpen = true;\n }\n\n /**\n * Closes the dropdown.\n *\n * @internal\n */\n protected close(): void {\n this.isOpen = false;\n }\n\n /**\n * If the dropdown is opened it closes it. If it is closed it opens it.\n *\n * @internal\n */\n protected toggle(): void {\n this.isOpen = !this.isOpen;\n }\n\n /**\n * Emits the event that the selected item has changed.\n *\n * @param item - The new selected item.\n * @internal\n */\n protected emitSelectedItemChanged(item: DropdownItem): void {\n this.$emit('change', item);\n this.close();\n }\n\n /**\n * Highlights the item after the one that is currently highlighted.\n *\n * @internal\n */\n protected highlightNextItem(): void {\n this.open();\n this.highlightedItemIndex = (this.highlightedItemIndex + 1) % this.items.length;\n }\n\n /**\n * Highlights the item before the one that is currently highlighted.\n *\n * @internal\n */\n protected highlightPreviousItem(): void {\n this.open();\n this.highlightedItemIndex =\n this.highlightedItemIndex > 0 ? this.highlightedItemIndex - 1 : this.items.length - 1;\n }\n\n /**\n * Highlights the first of the provided items.\n *\n * @internal\n */\n protected highlightFirstItem(): void {\n this.highlightedItemIndex = 0;\n }\n\n /**\n * Highlights the last of the provided items.\n *\n * @internal\n */\n protected highlightLastItem(): void {\n this.highlightedItemIndex = this.items.length - 1;\n }\n\n /**\n * Updates the variable that is used to search in the filters.\n *\n * @param event - The event coming from the user typing.\n * @internal\n */\n protected updateSearchBuffer(event: KeyboardEvent): void {\n if (/^\\w$/.test(event.key)) {\n const key = event.key;\n this.searchBuffer += key;\n this.restartResetSearchTimeout();\n }\n }\n\n /**\n * Highlights the item that matches the search buffer. To do so it checks the list buttons\n * text content. It highlights items folowing this priority:\n * - If an element is already highlighted, it starts searching from that element.\n * - If no element is found starting from the previously highlighted, it returns the first one.\n * - If no element is found matching the search query it highlights the first element.\n *\n * @param search - The search string to find in the HTML.\n * @internal\n */\n @Watch('searchBuffer')\n protected highlightMatchingItem(search: string): void {\n if (search) {\n const normalizedSearch = normalizeString(search);\n const matchingIndices = this.$refs.itemButtons.reduce<number[]>(\n (matchingIndices, button, index) => {\n const safeButtonWordCharacters = button.textContent!.replace(/[^\\w]/g, '');\n const normalizedButtonText = normalizeString(safeButtonWordCharacters);\n if (normalizedButtonText.startsWith(normalizedSearch)) {\n matchingIndices.push(index);\n }\n return matchingIndices;\n },\n []\n );\n this.highlightedItemIndex =\n // First matching item starting to search from the current highlighted element\n matchingIndices.find(index => index >= this.highlightedItemIndex) ??\n // First matching item\n matchingIndices[0] ??\n // First item\n 0;\n }\n }\n\n /**\n * Resets the search buffer.\n *\n * @internal\n */\n protected resetSearch(): void {\n this.searchBuffer = '';\n }\n\n /** Updates the debounced function to reset the search.\n *\n * @param searchTimeoutMs - The new milliseconds that have to pass without typing before\n * resetting the search.\n * @internal\n */\n @Watch('searchTimeoutMs', { immediate: true })\n protected updateSearchTimeout(searchTimeoutMs: number): void {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.restartResetSearchTimeout = debounce(this.resetSearch, searchTimeoutMs);\n }\n\n /**\n * Focuses the DOM element which matches the `highlightedItemIndex`.\n *\n * @param highlightedItemIndex - The index of the HTML element to focus.\n * @internal\n */\n @Watch('highlightedItemIndex', { immediate: true })\n protected focusHighlightedItem(highlightedItemIndex: number): void {\n this.$nextTick(() => {\n if (this.$refs.itemButtons && isInRange(highlightedItemIndex, [0, this.items.length - 1])) {\n const newItem = this.$refs.itemButtons[this.highlightedItemIndex];\n newItem.focus();\n }\n });\n }\n\n /**\n * When the dropdown is open it sets the focused element to the one that is selected.\n *\n * @param isOpen - True if the dropdown is open, false otherwise.\n * @internal\n */\n @Watch('isOpen')\n protected updateHighlightedItem(isOpen: boolean): void {\n if (isOpen) {\n this.highlightedItemIndex = this.value === null ? 0 : this.items.indexOf(this.value);\n } else {\n this.highlightedItemIndex = -1;\n }\n }\n\n /**\n * Adds and removes listeners to close the dropdown when it loses the focus.\n *\n * @param isOpen - True if the dropdown is open, false otherwise.\n * @internal\n */\n @Watch('isOpen')\n protected syncCloseListeners(isOpen: boolean): void {\n /*\n * Because there is an issue with Firefox in macOS and Safari that doesn't focus the target\n * element of the `mousedown` events, the `focusout` event `relatedTarget` property can't be\n * used to detect whether or not the user has blurred the dropdown. The hack here is to use\n * document listeners that have the side effect of losing the focus.\n */\n if (isOpen) {\n this.addDocumentCloseListeners();\n } else {\n this.removeDocumentCloseListeners();\n }\n }\n\n /**\n * Adds listeners to the document element to detect if the focus has moved out from the\n * dropdown.\n *\n * @internal\n */\n protected addDocumentCloseListeners(): void {\n /* eslint-disable @typescript-eslint/unbound-method */\n document.addEventListener('mousedown', this.closeIfEventIsOutOfDropdown);\n document.addEventListener('touchstart', this.closeIfEventIsOutOfDropdown);\n document.addEventListener('focusin', this.closeIfEventIsOutOfDropdown);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Removes the listeners of the document element to detect if the focus has moved out from the\n * dropdown.\n *\n * @internal\n */\n protected removeDocumentCloseListeners(): void {\n /* eslint-disable @typescript-eslint/unbound-method */\n document.removeEventListener('mousedown', this.closeIfEventIsOutOfDropdown);\n document.removeEventListener('touchstart', this.closeIfEventIsOutOfDropdown);\n document.removeEventListener('focusin', this.closeIfEventIsOutOfDropdown);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Closes the dropdown if the passed event has happened on an element out of the dropdown.\n *\n * @param event - The event to check if it has happen out of the dropdown component.\n */\n protected closeIfEventIsOutOfDropdown(event: MouseEvent | TouchEvent | FocusEvent): void {\n if (!this.$el.contains(event.target as HTMLElement)) {\n this.close();\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base-dropdown.vue_rollup-plugin-vue_script.vue.js","sources":["../../../src/components/base-dropdown.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\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\n\n\n\n\n\n\n\n\n\n\n\n\nimport { Identifiable } from '@empathyco/x-types';\nimport { Component, Prop, Watch } from 'vue-property-decorator';\nimport Vue from 'vue';\nimport { normalizeString } from '../utils/normalize';\nimport { isInRange } from '../utils/number';\nimport { debounce } from '../utils/debounce';\nimport { VueCSSClasses } from '../utils/types';\nimport { NoElement } from './no-element';\n\ntype DropdownItem = string | number | Identifiable;\n\n/**\n * Dropdown component that mimics a Select element behavior, but with the option\n * to customize the toggle button and each item contents.\n *\n * @public\n */\n@Component({\n components: {\n NoElement\n },\n model: {\n event: 'change'\n }\n})\nexport default class BaseDropdown extends Vue {\n /**\n * List of items to display.\n *\n * @public\n */\n @Prop({ required: true })\n public items!: DropdownItem[];\n\n /**\n * The selected item.\n *\n * @public\n */\n @Prop({ required: true })\n public value!: DropdownItem | null;\n\n /**\n * Animation component to use for expanding the dropdown. This is a single element animation,\n * so only `<transition>` components are allowed.\n *\n * @public\n */\n @Prop({ default: 'NoElement' })\n public animation!: typeof Vue | string;\n\n /**\n * Time to wait without receiving any keystroke before resetting the items search query.\n *\n * @public\n */\n @Prop({ default: 1000 })\n public searchTimeoutMs!: number;\n\n public $refs!: {\n /** Array containing the dropdown list buttons HTMLElements. */\n itemButtons: HTMLButtonElement[];\n };\n\n /**\n * Property to track whether the dropdown is expanded and displaying the full\n * list of items, or closed.\n *\n * @internal\n */\n protected isOpen = false;\n\n /**\n * Index of the element that has the focus in the list. -1 means no element has focus.\n *\n * @internal\n */\n protected highlightedItemIndex = -1;\n\n /**\n * String to search for the first element that starts with it.\n *\n * @internal\n */\n protected searchBuffer = '';\n\n /**\n * Resets the search buffer after a certain time has passed.\n *\n * @internal\n */\n protected restartResetSearchTimeout!: () => void;\n\n /**\n * Dynamic CSS classes to add to the dropdown root element.\n *\n * @returns An object containing the CSS classes to add to the dropdown root element.\n * @internal\n */\n protected get dropdownCSSClasses(): VueCSSClasses {\n return {\n 'x-dropdown--is-open': this.isOpen\n };\n }\n\n /**\n * Dynamic CSS classes to add to each one of the items.\n *\n * @returns An object containing the CSS classes to add to each item.\n * @internal\n */\n protected get itemsCSSClasses(): VueCSSClasses[] {\n return this.items.map((item, index) => {\n return {\n 'x-dropdown__item--is-selected': this.value === item,\n 'x-dropdown__item--is-highlighted': this.highlightedItemIndex === index\n };\n });\n }\n\n /**\n * If the dropdown is destroyed before removing the document listeners, it ensures that they\n * are removed too.\n *\n * @internal\n */\n protected beforeDestroy(): void {\n this.removeDocumentCloseListeners();\n }\n\n /**\n * Opens the dropdown.\n *\n * @internal\n */\n protected open(): void {\n this.isOpen = true;\n }\n\n /**\n * Closes the dropdown.\n *\n * @internal\n */\n protected close(): void {\n this.isOpen = false;\n }\n\n /**\n * If the dropdown is opened it closes it. If it is closed it opens it.\n *\n * @internal\n */\n protected toggle(): void {\n this.isOpen = !this.isOpen;\n }\n\n /**\n * Emits the event that the selected item has changed.\n *\n * @param item - The new selected item.\n * @internal\n */\n protected emitSelectedItemChanged(item: DropdownItem): void {\n this.$emit('change', item);\n this.close();\n }\n\n /**\n * Highlights the item after the one that is currently highlighted.\n *\n * @internal\n */\n protected highlightNextItem(): void {\n this.open();\n this.highlightedItemIndex = (this.highlightedItemIndex + 1) % this.items.length;\n }\n\n /**\n * Highlights the item before the one that is currently highlighted.\n *\n * @internal\n */\n protected highlightPreviousItem(): void {\n this.open();\n this.highlightedItemIndex =\n this.highlightedItemIndex > 0 ? this.highlightedItemIndex - 1 : this.items.length - 1;\n }\n\n /**\n * Highlights the first of the provided items.\n *\n * @internal\n */\n protected highlightFirstItem(): void {\n this.highlightedItemIndex = 0;\n }\n\n /**\n * Highlights the last of the provided items.\n *\n * @internal\n */\n protected highlightLastItem(): void {\n this.highlightedItemIndex = this.items.length - 1;\n }\n\n /**\n * Updates the variable that is used to search in the filters.\n *\n * @param event - The event coming from the user typing.\n * @internal\n */\n protected updateSearchBuffer(event: KeyboardEvent): void {\n if (/^\\w$/.test(event.key)) {\n const key = event.key;\n this.searchBuffer += key;\n this.restartResetSearchTimeout();\n }\n }\n\n /**\n * Highlights the item that matches the search buffer. To do so it checks the list buttons\n * text content. It highlights items folowing this priority:\n * - If an element is already highlighted, it starts searching from that element.\n * - If no element is found starting from the previously highlighted, it returns the first one.\n * - If no element is found matching the search query it highlights the first element.\n *\n * @param search - The search string to find in the HTML.\n * @internal\n */\n @Watch('searchBuffer')\n protected highlightMatchingItem(search: string): void {\n if (search) {\n const normalizedSearch = normalizeString(search);\n const matchingIndices = this.$refs.itemButtons.reduce<number[]>(\n (matchingIndices, button, index) => {\n const safeButtonWordCharacters = button.textContent!.replace(/[^\\w]/g, '');\n const normalizedButtonText = normalizeString(safeButtonWordCharacters);\n if (normalizedButtonText.startsWith(normalizedSearch)) {\n matchingIndices.push(index);\n }\n return matchingIndices;\n },\n []\n );\n this.highlightedItemIndex =\n // First matching item starting to search from the current highlighted element\n matchingIndices.find(index => index >= this.highlightedItemIndex) ??\n // First matching item\n matchingIndices[0] ??\n // First item\n 0;\n }\n }\n\n /**\n * Resets the search buffer.\n *\n * @internal\n */\n protected resetSearch(): void {\n this.searchBuffer = '';\n }\n\n /**\n * Updates the debounced function to reset the search.\n *\n * @param searchTimeoutMs - The new milliseconds that have to pass without typing before\n * resetting the search.\n * @internal\n */\n @Watch('searchTimeoutMs', { immediate: true })\n protected updateSearchTimeout(searchTimeoutMs: number): void {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.restartResetSearchTimeout = debounce(this.resetSearch, searchTimeoutMs);\n }\n\n /**\n * Focuses the DOM element which matches the `highlightedItemIndex`.\n *\n * @param highlightedItemIndex - The index of the HTML element to focus.\n * @internal\n */\n @Watch('highlightedItemIndex', { immediate: true })\n protected focusHighlightedItem(highlightedItemIndex: number): void {\n this.$nextTick(() => {\n if (this.$refs.itemButtons && isInRange(highlightedItemIndex, [0, this.items.length - 1])) {\n const newItem = this.$refs.itemButtons[this.highlightedItemIndex];\n newItem.focus();\n }\n });\n }\n\n /**\n * When the dropdown is open it sets the focused element to the one that is selected.\n *\n * @param isOpen - True if the dropdown is open, false otherwise.\n * @internal\n */\n @Watch('isOpen')\n protected updateHighlightedItem(isOpen: boolean): void {\n if (isOpen) {\n this.highlightedItemIndex = this.value === null ? 0 : this.items.indexOf(this.value);\n } else {\n this.highlightedItemIndex = -1;\n }\n }\n\n /**\n * Adds and removes listeners to close the dropdown when it loses the focus.\n *\n * @param isOpen - True if the dropdown is open, false otherwise.\n * @internal\n */\n @Watch('isOpen')\n protected syncCloseListeners(isOpen: boolean): void {\n /*\n * Because there is an issue with Firefox in macOS and Safari that doesn't focus the target\n * element of the `mousedown` events, the `focusout` event `relatedTarget` property can't be\n * used to detect whether or not the user has blurred the dropdown. The hack here is to use\n * document listeners that have the side effect of losing the focus.\n */\n if (isOpen) {\n this.addDocumentCloseListeners();\n } else {\n this.removeDocumentCloseListeners();\n }\n }\n\n /**\n * Adds listeners to the document element to detect if the focus has moved out from the\n * dropdown.\n *\n * @internal\n */\n protected addDocumentCloseListeners(): void {\n /* eslint-disable @typescript-eslint/unbound-method */\n document.addEventListener('mousedown', this.closeIfEventIsOutOfDropdown);\n document.addEventListener('touchstart', this.closeIfEventIsOutOfDropdown);\n document.addEventListener('focusin', this.closeIfEventIsOutOfDropdown);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Removes the listeners of the document element to detect if the focus has moved out from the\n * dropdown.\n *\n * @internal\n */\n protected removeDocumentCloseListeners(): void {\n /* eslint-disable @typescript-eslint/unbound-method */\n document.removeEventListener('mousedown', this.closeIfEventIsOutOfDropdown);\n document.removeEventListener('touchstart', this.closeIfEventIsOutOfDropdown);\n document.removeEventListener('focusin', this.closeIfEventIsOutOfDropdown);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Closes the dropdown if the passed event has happened on an element out of the dropdown.\n *\n * @param event - The event to check if it has happen out of the dropdown component.\n */\n protected closeIfEventIsOutOfDropdown(event: MouseEvent | TouchEvent | FocusEvent): void {\n if (!this.$el.contains(event.target as HTMLElement)) {\n this.close();\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -44,7 +44,10 @@ var __vue_render__ = function () {
|
|
|
44
44
|
staticClass: "x-modal__overlay",
|
|
45
45
|
class: { "x-modal__overlay--is-visible": _vm.showOverlay },
|
|
46
46
|
attrs: { "data-test": "modal-overlay" },
|
|
47
|
-
on: {
|
|
47
|
+
on: {
|
|
48
|
+
click: _vm.emitOverlayClicked,
|
|
49
|
+
keydown: _vm.emitOverlayClicked,
|
|
50
|
+
},
|
|
48
51
|
}),
|
|
49
52
|
]
|
|
50
53
|
)
|
|
@@ -58,11 +61,11 @@ __vue_render__._withStripped = true;
|
|
|
58
61
|
/* style */
|
|
59
62
|
const __vue_inject_styles__ = function (inject) {
|
|
60
63
|
if (!inject) return
|
|
61
|
-
inject("data-v-
|
|
64
|
+
inject("data-v-389f85a8_0", { source: ".x-modal[data-v-389f85a8] {\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-389f85a8] {\n z-index: 1;\n}\n.x-modal__overlay[data-v-389f85a8] {\n width: 100%;\n height: 100%;\n position: fixed;\n background-color: rgba(0, 0, 0, 0.7);\n opacity: 0;\n}\n.x-modal__overlay--is-visible[data-v-389f85a8] {\n transition: opacity 0.3s ease-out;\n opacity: 1;\n}", map: undefined, media: undefined });
|
|
62
65
|
|
|
63
66
|
};
|
|
64
67
|
/* scoped */
|
|
65
|
-
const __vue_scope_id__ = "data-v-
|
|
68
|
+
const __vue_scope_id__ = "data-v-389f85a8";
|
|
66
69
|
/* module identifier */
|
|
67
70
|
const __vue_module_identifier__ = undefined;
|
|
68
71
|
/* functional template */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-modal.vue.js","sources":["../../../../src/components/modals/base-modal.vue"],"sourcesContent":["<template>\n <component :is=\"animation\" @beforeEnter=\"showOverlay = false\" @afterEnter=\"showOverlay = true\">\n <div v-if=\"open\" class=\"x-modal\" data-test=\"modal\">\n <div ref=\"modal\" class=\"x-modal__content x-list\" data-test=\"modal-content\" role=\"dialog\">\n <!-- @slot (Required) Modal container content -->\n <slot />\n </div>\n <div\n @click=\"emitOverlayClicked\"\n class=\"x-modal__overlay\"\n :class=\"{ 'x-modal__overlay--is-visible': showOverlay }\"\n data-test=\"modal-overlay\"\n />\n </div>\n </component>\n</template>\n\n<script lang=\"ts\">\n import Vue from 'vue';\n import { Component, Prop } from 'vue-property-decorator';\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.\n */\n @Prop({ default: () => NoElement })\n public animation!: 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 /** To animate the overlay opacity after and before the animation. */\n protected showOverlay = true;\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, { immediate: true });\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 document.body.style.overflow = document.documentElement.style.overflow = '';\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\n display: flex;\n align-items: flex-start;\n justify-content: flex-start;\n width: 100%;\n height: 100%;\n\n z-index: 1;\n\n &__content {\n z-index: 1;\n }\n\n &__overlay {\n width: 100%;\n height: 100%;\n position: fixed;\n background-color: rgba(0, 0, 0, 0.7);\n opacity: 0;\n\n &--is-visible {\n transition: opacity 0.3s ease-out;\n opacity: 1;\n }\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 <component :is=\"animation\" @beforeEnter=\"showOverlay = false\" @afterEnter=\"showOverlay = true\">\n <div v-if=\"open\" class=\"x-modal\" data-test=\"modal\">\n <div ref=\"modal\" class=\"x-modal__content x-list\" data-test=\"modal-content\" role=\"dialog\">\n <!-- @slot (Required) Modal container content -->\n <slot />\n </div>\n <div\n @click=\"emitOverlayClicked\"\n @keydown=\"emitOverlayClicked\"\n class=\"x-modal__overlay\"\n :class=\"{ 'x-modal__overlay--is-visible': showOverlay }\"\n data-test=\"modal-overlay\"\n />\n </div>\n </component>\n</template>\n\n<script lang=\"ts\">\n import Vue from 'vue';\n import { Component, Prop } from 'vue-property-decorator';\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.\n */\n @Prop({ default: () => NoElement })\n public animation!: 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 /** To animate the overlay opacity after and before the animation. */\n protected showOverlay = true;\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, { immediate: true });\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 document.body.style.overflow = document.documentElement.style.overflow = '';\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\n display: flex;\n align-items: flex-start;\n justify-content: flex-start;\n width: 100%;\n height: 100%;\n\n z-index: 1;\n\n &__content {\n z-index: 1;\n }\n\n &__overlay {\n width: 100%;\n height: 100%;\n position: fixed;\n background-color: rgba(0, 0, 0, 0.7);\n opacity: 0;\n\n &--is-visible {\n transition: opacity 0.3s ease-out;\n opacity: 1;\n }\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 +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\nimport Vue from 'vue';\nimport { Component, Prop } from 'vue-property-decorator';\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.\n */\n @Prop({ default: () => NoElement })\n public animation!: 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 /** To animate the overlay opacity after and before the animation. */\n protected showOverlay = true;\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, { immediate: true });\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 document.body.style.overflow = document.documentElement.style.overflow = '';\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":[],"mappings":";;;;;
|
|
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\nimport Vue from 'vue';\nimport { Component, Prop } from 'vue-property-decorator';\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.\n */\n @Prop({ default: () => NoElement })\n public animation!: 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 /** To animate the overlay opacity after and before the animation. */\n protected showOverlay = true;\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, { immediate: true });\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 document.body.style.overflow = document.documentElement.style.overflow = '';\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":[],"mappings":";;;;;AAuBA;;;;;;AAOA,IAAqB,SAAS,GAA9B,MAAqB,SAAU,SAAQ,GAAG;IAA1C;;;QAcY,yBAAoB,GAAG,EAAE,CAAC;;QAE1B,yBAAoB,GAAG,EAAE,CAAC;;QAE1B,gBAAW,GAAG,IAAI,CAAC;KAqG9B;IA/FW,OAAO;;;QAGf,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;KACzD;;;;;;;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;QACpE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC;KAC7E;;;;;;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;AAlHC;IADC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,CAAC;4CACH;AAMhC;IADC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;uCACH;AAXH,SAAS;IAD7B,SAAS;GACW,SAAS,CAuH7B;aAvHoB,SAAS;;;;"}
|
|
@@ -29,7 +29,7 @@ var __vue_render__ = function () {
|
|
|
29
29
|
name: "min",
|
|
30
30
|
type: "number",
|
|
31
31
|
"data-test": "range-min",
|
|
32
|
-
"aria-label":
|
|
32
|
+
"aria-label": _vm.rangeFilterMin,
|
|
33
33
|
},
|
|
34
34
|
domProps: { value: _vm.min },
|
|
35
35
|
on: {
|
|
@@ -46,7 +46,7 @@ var __vue_render__ = function () {
|
|
|
46
46
|
name: "max",
|
|
47
47
|
type: "number",
|
|
48
48
|
"data-test": "range-max",
|
|
49
|
-
"aria-label":
|
|
49
|
+
"aria-label": _vm.rangeFilterMax,
|
|
50
50
|
},
|
|
51
51
|
domProps: { value: _vm.max },
|
|
52
52
|
on: {
|
|
@@ -117,7 +117,7 @@ __vue_render__._withStripped = true;
|
|
|
117
117
|
/* style */
|
|
118
118
|
const __vue_inject_styles__ = function (inject) {
|
|
119
119
|
if (!inject) return
|
|
120
|
-
inject("data-v-
|
|
120
|
+
inject("data-v-9aa789ba_0", { source: ".x-editable-number-range-filter--error .x-editable-number-range-filter__input {\n border-color: red;\n}", map: undefined, media: undefined });
|
|
121
121
|
|
|
122
122
|
};
|
|
123
123
|
/* scoped */
|