@empathyco/x-components 6.0.0-alpha.32 → 6.0.0-alpha.33
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 +9 -0
- package/core/index.js +1 -0
- package/core/index.js.map +1 -1
- package/design-system/deprecated-full-theme.css +1270 -1270
- package/docs/API-reference/api/x-components.globalxbus.md +2 -0
- package/docs/API-reference/api/x-components.hierarchicalfilter.md +1 -0
- package/docs/API-reference/api/x-components.md +1 -0
- package/docs/API-reference/api/x-components.pageselector.md +80 -0
- package/docs/API-reference/api/x-components.searchconfig.md +1 -0
- package/docs/API-reference/api/x-components.searchconfig.pagemode.md +11 -0
- package/docs/API-reference/api/x-components.searchxevents.md +1 -0
- package/docs/API-reference/api/x-components.searchxevents.userselectedapage.md +13 -0
- package/docs/API-reference/api/x-components.simplefilter.md +1 -0
- package/docs/API-reference/api/x-components.snippetcallbacks.md +1 -0
- package/docs/API-reference/components/common/x-components.page-selector.md +151 -0
- package/js/components/page-selector.vue.js +78 -0
- package/js/components/page-selector.vue.js.map +1 -0
- package/js/components/page-selector.vue2.js +128 -0
- package/js/components/page-selector.vue2.js.map +1 -0
- package/js/components/page-selector.vue3.js +7 -0
- package/js/components/page-selector.vue3.js.map +1 -0
- package/js/index.js +1 -0
- package/js/index.js.map +1 -1
- package/js/x-modules/empathize/components/empathize.vue2.js +2 -0
- package/js/x-modules/empathize/components/empathize.vue2.js.map +1 -1
- package/js/x-modules/queries-preview/components/query-preview-button.vue2.js +2 -0
- package/js/x-modules/queries-preview/components/query-preview-button.vue2.js.map +1 -1
- package/js/x-modules/queries-preview/components/query-preview.vue2.js +2 -0
- package/js/x-modules/queries-preview/components/query-preview.vue2.js.map +1 -1
- package/js/x-modules/scroll/components/scroll-to-top.vue2.js +2 -0
- package/js/x-modules/scroll/components/scroll-to-top.vue2.js.map +1 -1
- package/js/x-modules/search/store/actions/fetch-and-save-search-response.action.js +10 -3
- package/js/x-modules/search/store/actions/fetch-and-save-search-response.action.js.map +1 -1
- package/js/x-modules/search/store/module.js +2 -1
- package/js/x-modules/search/store/module.js.map +1 -1
- package/js/x-modules/search/wiring.js +4 -0
- package/js/x-modules/search/wiring.js.map +1 -1
- package/package.json +2 -2
- package/report/x-components.api.json +388 -4
- package/report/x-components.api.md +87 -2
- package/types/components/global-x-bus.vue.d.ts +2 -0
- package/types/components/global-x-bus.vue.d.ts.map +1 -1
- package/types/components/index.d.ts +1 -0
- package/types/components/index.d.ts.map +1 -1
- package/types/components/page-selector.vue.d.ts +125 -0
- package/types/components/page-selector.vue.d.ts.map +1 -0
- package/types/components/snippet-callbacks.vue.d.ts +1 -0
- package/types/components/snippet-callbacks.vue.d.ts.map +1 -1
- package/types/types/page-mode.d.ts +2 -0
- package/types/types/page-mode.d.ts.map +1 -0
- package/types/x-modules/facets/components/filters/hierarchical-filter.vue.d.ts +1 -0
- package/types/x-modules/facets/components/filters/hierarchical-filter.vue.d.ts.map +1 -1
- package/types/x-modules/facets/components/filters/simple-filter.vue.d.ts +1 -0
- package/types/x-modules/facets/components/filters/simple-filter.vue.d.ts.map +1 -1
- package/types/x-modules/search/config.types.d.ts +2 -0
- package/types/x-modules/search/config.types.d.ts.map +1 -1
- package/types/x-modules/search/events.types.d.ts +4 -0
- package/types/x-modules/search/events.types.d.ts.map +1 -1
- package/types/x-modules/search/store/actions/fetch-and-save-search-response.action.d.ts.map +1 -1
- package/types/x-modules/search/store/module.d.ts.map +1 -1
- package/types/x-modules/search/wiring.d.ts +4 -0
- package/types/x-modules/search/wiring.d.ts.map +1 -1
|
@@ -154,6 +154,7 @@ _default: import("vue").DefineComponent<{
|
|
|
154
154
|
UserClickedAPromoted: (payload: import("@empathyco/x-types").Promoted, metadata: import("..").WireMetadata) => unknown;
|
|
155
155
|
UserClickedABanner: (payload: import("@empathyco/x-types").Banner, metadata: import("..").WireMetadata) => unknown;
|
|
156
156
|
UserClickedAbortARedirection: (payload: undefined, metadata: import("..").WireMetadata) => unknown;
|
|
157
|
+
UserSelectedAPage: (payload: number, metadata: import("..").WireMetadata) => unknown;
|
|
157
158
|
SemanticQueryRequestUpdated: (payload: import("@empathyco/x-types").SemanticQueriesRequest | null, metadata: import("..").WireMetadata) => unknown;
|
|
158
159
|
SemanticQueriesResponseChanged: (payload: import("@empathyco/x-types").SemanticQuery[], metadata: import("..").WireMetadata) => unknown;
|
|
159
160
|
UserSelectedASemanticQuery: (payload: import("@empathyco/x-types").SemanticQuery, metadata: import("..").WireMetadata) => unknown;
|
|
@@ -322,6 +323,7 @@ _default: import("vue").DefineComponent<{
|
|
|
322
323
|
UserClickedAPromoted: (payload: import("@empathyco/x-types").Promoted, metadata: import("..").WireMetadata) => unknown;
|
|
323
324
|
UserClickedABanner: (payload: import("@empathyco/x-types").Banner, metadata: import("..").WireMetadata) => unknown;
|
|
324
325
|
UserClickedAbortARedirection: (payload: undefined, metadata: import("..").WireMetadata) => unknown;
|
|
326
|
+
UserSelectedAPage: (payload: number, metadata: import("..").WireMetadata) => unknown;
|
|
325
327
|
SemanticQueryRequestUpdated: (payload: import("@empathyco/x-types").SemanticQueriesRequest | null, metadata: import("..").WireMetadata) => unknown;
|
|
326
328
|
SemanticQueriesResponseChanged: (payload: import("@empathyco/x-types").SemanticQuery[], metadata: import("..").WireMetadata) => unknown;
|
|
327
329
|
UserSelectedASemanticQuery: (payload: import("@empathyco/x-types").SemanticQuery, metadata: import("..").WireMetadata) => unknown;
|
|
@@ -166,6 +166,7 @@ _default: import("vue").DefineComponent<{
|
|
|
166
166
|
UserClickedAPromoted?: import("@empathyco/x-types").Promoted | undefined;
|
|
167
167
|
UserClickedABanner?: import("@empathyco/x-types").Banner | undefined;
|
|
168
168
|
UserClickedAbortARedirection?: void | undefined;
|
|
169
|
+
UserSelectedAPage?: number | undefined;
|
|
169
170
|
SemanticQueryRequestUpdated?: import("@empathyco/x-types").SemanticQueriesRequest | null | undefined;
|
|
170
171
|
SemanticQueriesResponseChanged?: import("@empathyco/x-types").SemanticQuery[] | undefined;
|
|
171
172
|
UserSelectedASemanticQuery?: import("@empathyco/x-types").SemanticQuery | undefined;
|
|
@@ -457,6 +457,7 @@ X-Components is a library usable everywhere not only for search experiences.
|
|
|
457
457
|
| [NumberRangeFilter](./x-components.numberrangefilter.md) | Renders a number range filter, emitting the needed events when clicked. |
|
|
458
458
|
| [OpenMainModal](./x-components.openmainmodal.md) | Button to open the [MainModal](./x-components.mainmodal.md)<!-- -->. |
|
|
459
459
|
| [PageLoaderButton](./x-components.pageloaderbutton.md) | Component that renders a text with the number of rendered results and the remaining ones and a <code><BaseEventButton></code> with the logic of emitting the event "UserReachedResultsListEnd" to load more results on click. |
|
|
460
|
+
| [PageSelector](./x-components.pageselector.md) | Component that renders a pagination control with buttons for navigating between pages. It displays the current page, allows selecting other pages, and emits events when a page is selected. |
|
|
460
461
|
| [PartialQueryButton](./x-components.partialquerybutton.md) | A button that when pressed emits the [XEventsTypes.UserAcceptedAQuery](./x-components.xeventstypes.useracceptedaquery.md) and [SearchXEvents.UserClickedPartialQuery](./x-components.searchxevents.userclickedpartialquery.md) events, expressing the user intention to set the partial query. |
|
|
461
462
|
| [PartialResultsList](./x-components.partialresultslist.md) | It renders a list of partial results from [SearchState.partialResults](./x-components.searchstate.partialresults.md) by default. It also provides the partial result slot to customize the item with the partial result bound. |
|
|
462
463
|
| [PopularSearch](./x-components.popularsearch.md) | Renders a popular search item which receives the suggestion that will be rendered as a prop. It exposes a default slot to change the popular search content. If the slot is not overridden, it will render the suggestion query by default. |
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
|
2
|
+
|
|
3
|
+
[Home](./index.md) > [@empathyco/x-components](./x-components.md) > [PageSelector](./x-components.pageselector.md)
|
|
4
|
+
|
|
5
|
+
## PageSelector variable
|
|
6
|
+
|
|
7
|
+
Component that renders a pagination control with buttons for navigating between pages. It displays the current page, allows selecting other pages, and emits events when a page is selected.
|
|
8
|
+
|
|
9
|
+
**Signature:**
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
_default: import("vue").DefineComponent<{
|
|
13
|
+
buttonClasses: {
|
|
14
|
+
type: PropType<(string | Dictionary<boolean>)[]>;
|
|
15
|
+
default: () => never[];
|
|
16
|
+
};
|
|
17
|
+
currentPage: {
|
|
18
|
+
type: NumberConstructor;
|
|
19
|
+
required: true;
|
|
20
|
+
};
|
|
21
|
+
hiddenPage: {
|
|
22
|
+
type: StringConstructor;
|
|
23
|
+
default: string;
|
|
24
|
+
};
|
|
25
|
+
itemClasses: {
|
|
26
|
+
type: PropType<(isSelected: boolean) => string | Dictionary<boolean> | (string | Dictionary<boolean>)[]>;
|
|
27
|
+
default: () => never[];
|
|
28
|
+
};
|
|
29
|
+
range: {
|
|
30
|
+
type: NumberConstructor;
|
|
31
|
+
default: number;
|
|
32
|
+
};
|
|
33
|
+
scrollTarget: {
|
|
34
|
+
type: StringConstructor;
|
|
35
|
+
default: string;
|
|
36
|
+
};
|
|
37
|
+
totalPages: {
|
|
38
|
+
type: NumberConstructor;
|
|
39
|
+
required: true;
|
|
40
|
+
};
|
|
41
|
+
}, {
|
|
42
|
+
visiblePages: import("vue").ComputedRef<PageItem[]>;
|
|
43
|
+
selectPage: (page: number | string) => void;
|
|
44
|
+
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
45
|
+
buttonClasses: {
|
|
46
|
+
type: PropType<(string | Dictionary<boolean>)[]>;
|
|
47
|
+
default: () => never[];
|
|
48
|
+
};
|
|
49
|
+
currentPage: {
|
|
50
|
+
type: NumberConstructor;
|
|
51
|
+
required: true;
|
|
52
|
+
};
|
|
53
|
+
hiddenPage: {
|
|
54
|
+
type: StringConstructor;
|
|
55
|
+
default: string;
|
|
56
|
+
};
|
|
57
|
+
itemClasses: {
|
|
58
|
+
type: PropType<(isSelected: boolean) => string | Dictionary<boolean> | (string | Dictionary<boolean>)[]>;
|
|
59
|
+
default: () => never[];
|
|
60
|
+
};
|
|
61
|
+
range: {
|
|
62
|
+
type: NumberConstructor;
|
|
63
|
+
default: number;
|
|
64
|
+
};
|
|
65
|
+
scrollTarget: {
|
|
66
|
+
type: StringConstructor;
|
|
67
|
+
default: string;
|
|
68
|
+
};
|
|
69
|
+
totalPages: {
|
|
70
|
+
type: NumberConstructor;
|
|
71
|
+
required: true;
|
|
72
|
+
};
|
|
73
|
+
}>>, {
|
|
74
|
+
buttonClasses: (string | Dictionary<boolean>)[];
|
|
75
|
+
hiddenPage: string;
|
|
76
|
+
itemClasses: (isSelected: boolean) => string | Dictionary<boolean> | (string | Dictionary<boolean>)[];
|
|
77
|
+
range: number;
|
|
78
|
+
scrollTarget: string;
|
|
79
|
+
}, {}>
|
|
80
|
+
```
|
|
@@ -16,5 +16,6 @@ export interface SearchConfig
|
|
|
16
16
|
|
|
17
17
|
| Property | Modifiers | Type | Description |
|
|
18
18
|
| --- | --- | --- | --- |
|
|
19
|
+
| [pageMode](./x-components.searchconfig.pagemode.md) | | PageMode | |
|
|
19
20
|
| [pageSize](./x-components.searchconfig.pagesize.md) | | number | Maximum number of results to request. |
|
|
20
21
|
|
|
@@ -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) > [SearchConfig](./x-components.searchconfig.md) > [pageMode](./x-components.searchconfig.pagemode.md)
|
|
4
|
+
|
|
5
|
+
## SearchConfig.pageMode property
|
|
6
|
+
|
|
7
|
+
**Signature:**
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
pageMode: PageMode;
|
|
11
|
+
```
|
|
@@ -34,4 +34,5 @@ export interface SearchXEvents
|
|
|
34
34
|
| [UserClickedASort](./x-components.searchxevents.userclickedasort.md) | | Sort | The user has clicked one of the sorts. Payload: The sort option that the user has selected. |
|
|
35
35
|
| [UserClickedPartialQuery](./x-components.searchxevents.userclickedpartialquery.md) | | string | Partial query has been set. Payload: The new query string. |
|
|
36
36
|
| [UserReachedResultsListEnd](./x-components.searchxevents.userreachedresultslistend.md) | | void | The user reached the limit of the scrollable content in a results list. |
|
|
37
|
+
| [UserSelectedAPage](./x-components.searchxevents.userselectedapage.md) | | number | The user has selected a page. |
|
|
37
38
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
|
2
|
+
|
|
3
|
+
[Home](./index.md) > [@empathyco/x-components](./x-components.md) > [SearchXEvents](./x-components.searchxevents.md) > [UserSelectedAPage](./x-components.searchxevents.userselectedapage.md)
|
|
4
|
+
|
|
5
|
+
## SearchXEvents.UserSelectedAPage property
|
|
6
|
+
|
|
7
|
+
The user has selected a page.
|
|
8
|
+
|
|
9
|
+
**Signature:**
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
UserSelectedAPage: number;
|
|
13
|
+
```
|
|
@@ -163,6 +163,7 @@ _default: import("vue").DefineComponent<{
|
|
|
163
163
|
UserClickedAPromoted?: import("@empathyco/x-types").Promoted | undefined;
|
|
164
164
|
UserClickedABanner?: import("@empathyco/x-types").Banner | undefined;
|
|
165
165
|
UserClickedAbortARedirection?: void | undefined;
|
|
166
|
+
UserSelectedAPage?: number | undefined;
|
|
166
167
|
SemanticQueryRequestUpdated?: import("@empathyco/x-types").SemanticQueriesRequest | null | undefined;
|
|
167
168
|
SemanticQueriesResponseChanged?: import("@empathyco/x-types").SemanticQuery[] | undefined;
|
|
168
169
|
UserSelectedASemanticQuery?: import("@empathyco/x-types").SemanticQuery | undefined;
|
|
@@ -153,6 +153,7 @@ _default: import("vue").DefineComponent<{}, {
|
|
|
153
153
|
UserClickedAPromoted: (payload: import("@empathyco/x-types").Promoted, metadata: WireMetadata) => unknown;
|
|
154
154
|
UserClickedABanner: (payload: import("@empathyco/x-types").Banner, metadata: WireMetadata) => unknown;
|
|
155
155
|
UserClickedAbortARedirection: (payload: undefined, metadata: WireMetadata) => unknown;
|
|
156
|
+
UserSelectedAPage: (payload: number, metadata: WireMetadata) => unknown;
|
|
156
157
|
SemanticQueryRequestUpdated: (payload: import("@empathyco/x-types").SemanticQueriesRequest | null, metadata: WireMetadata) => unknown;
|
|
157
158
|
SemanticQueriesResponseChanged: (payload: import("@empathyco/x-types").SemanticQuery[], metadata: WireMetadata) => unknown;
|
|
158
159
|
UserSelectedASemanticQuery: (payload: import("@empathyco/x-types").SemanticQuery, metadata: WireMetadata) => unknown;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
title: PageSelector
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# PageSelector
|
|
8
|
+
|
|
9
|
+
Component that renders a pagination control with buttons for navigating between pages. It displays
|
|
10
|
+
the current page, allows selecting other pages, and emits events when a page is selected.
|
|
11
|
+
|
|
12
|
+
## Props
|
|
13
|
+
|
|
14
|
+
| Name | Description | Type | Default |
|
|
15
|
+
| -------------------------- | --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------- |
|
|
16
|
+
| <code>buttonClasses</code> | CSS classes to customize the prev/next buttons. | <code>(string \| Dictionary<boolean>)[]</code> | <code>() => []</code> |
|
|
17
|
+
| <code>currentPage</code> | The current page number. | <code>number</code> | <code></code> |
|
|
18
|
+
| <code>hiddenPage</code> | The string content of the hidden pages. | <code>string</code> | <code>'...'</code> |
|
|
19
|
+
| <code>itemClasses</code> | CSS classes to customize the page items. | <code>(isSelected: boolean) => string \| Dictionary<boolean> \| (string \| Dictionary<boolean>)[]</code> | <code>() => []</code> |
|
|
20
|
+
| <code>range</code> | The number of pages to show before and after the current page. | <code>number</code> | <code>2</code> |
|
|
21
|
+
| <code>scrollTarget</code> | The class of the scroll container to scroll to top when a page is selected. | <code>string</code> | <code>'main-scroll'</code> |
|
|
22
|
+
| <code>totalPages</code> | The total number of pages. | <code>number</code> | <code></code> |
|
|
23
|
+
|
|
24
|
+
## Slots
|
|
25
|
+
|
|
26
|
+
| Name | Description | Bindings<br />(name - type - description) |
|
|
27
|
+
| --------------------------------- | ----------- | ----------------------------------------- |
|
|
28
|
+
| <code>previous-page-button</code> | | None |
|
|
29
|
+
| <code>page-button</code> | | <br /> |
|
|
30
|
+
| <code>next-page-button</code> | | None |
|
|
31
|
+
|
|
32
|
+
## Events
|
|
33
|
+
|
|
34
|
+
This component emits the "UserSelectedAPage" and the UserClickedScrollToTop events by default.
|
|
35
|
+
|
|
36
|
+
## See it in action
|
|
37
|
+
|
|
38
|
+
Basic example of how the component is rendered.
|
|
39
|
+
|
|
40
|
+
```vue live
|
|
41
|
+
<template>
|
|
42
|
+
<PageSelector :current-page="currentPage" :total-pages="totalPages" />
|
|
43
|
+
</template>
|
|
44
|
+
|
|
45
|
+
<script>
|
|
46
|
+
import { PageSelector } from '@empathyco/x-components';
|
|
47
|
+
|
|
48
|
+
export default {
|
|
49
|
+
name: 'PageSelectorDemo',
|
|
50
|
+
components: {
|
|
51
|
+
PageSelector
|
|
52
|
+
},
|
|
53
|
+
data() {
|
|
54
|
+
return {
|
|
55
|
+
page: 0,
|
|
56
|
+
totalPages: 10
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
computed: {
|
|
60
|
+
currentPage() {
|
|
61
|
+
return this.page;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
</script>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Customize the slots
|
|
69
|
+
|
|
70
|
+
This component allows to customise its content using slots.
|
|
71
|
+
|
|
72
|
+
```vue live
|
|
73
|
+
<template>
|
|
74
|
+
<PageSelector
|
|
75
|
+
:total-pages="totalPages"
|
|
76
|
+
:currentPage="currentPage"
|
|
77
|
+
:item-classes="
|
|
78
|
+
(isSelected: boolean) =>
|
|
79
|
+
isSelected
|
|
80
|
+
? 'x-button-lead x-text-neutral-10'
|
|
81
|
+
: 'x-text-neutral-90 x-button-outlined'
|
|
82
|
+
"
|
|
83
|
+
:buttonClasses="['x-rounded-md']"
|
|
84
|
+
>
|
|
85
|
+
<template #previous-page-button>
|
|
86
|
+
<span>Back</span>
|
|
87
|
+
</template>
|
|
88
|
+
<template #page-button="{ page, isSelected }">
|
|
89
|
+
<h2 :class="{ 'x-text1': !isSelected }">
|
|
90
|
+
{{ page }}
|
|
91
|
+
</h2>
|
|
92
|
+
</template>
|
|
93
|
+
<template #next-page-button>
|
|
94
|
+
<span>Forward</span>
|
|
95
|
+
</template>
|
|
96
|
+
</PageSelector>
|
|
97
|
+
</template>
|
|
98
|
+
|
|
99
|
+
<script>
|
|
100
|
+
import { PageSelector } from '@empathyco/x-components';
|
|
101
|
+
|
|
102
|
+
export default {
|
|
103
|
+
name: 'PageSelectorDemo',
|
|
104
|
+
components: {
|
|
105
|
+
PageSelector
|
|
106
|
+
},
|
|
107
|
+
data() {
|
|
108
|
+
return {
|
|
109
|
+
page: 2,
|
|
110
|
+
totalPages: 10
|
|
111
|
+
};
|
|
112
|
+
},
|
|
113
|
+
computed: {
|
|
114
|
+
currentPage() {
|
|
115
|
+
return this.page;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
</script>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Customize the number of pages to show before and after the current page by changing the range default value.
|
|
123
|
+
|
|
124
|
+
```vue live
|
|
125
|
+
<template>
|
|
126
|
+
<PageSelector :current-page="currentPage" :total-pages="totalPages" :range="range" />
|
|
127
|
+
</template>
|
|
128
|
+
|
|
129
|
+
<script>
|
|
130
|
+
import { PageSelector } from '@empathyco/x-components';
|
|
131
|
+
|
|
132
|
+
export default {
|
|
133
|
+
name: 'PageSelectorDemo',
|
|
134
|
+
components: {
|
|
135
|
+
PageSelector
|
|
136
|
+
},
|
|
137
|
+
data() {
|
|
138
|
+
return {
|
|
139
|
+
page: 6,
|
|
140
|
+
totalPages: 100,
|
|
141
|
+
range: 4
|
|
142
|
+
};
|
|
143
|
+
},
|
|
144
|
+
computed: {
|
|
145
|
+
currentPage() {
|
|
146
|
+
return this.page;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
</script>
|
|
151
|
+
```
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import _sfc_main from './page-selector.vue2.js';
|
|
2
|
+
import { openBlock, createElementBlock, createElementVNode, normalizeClass, renderSlot, createTextVNode, Fragment, renderList, toDisplayString, createCommentVNode } from 'vue';
|
|
3
|
+
import './page-selector.vue3.js';
|
|
4
|
+
import _export_sfc from '../_virtual/_plugin-vue_export-helper.js';
|
|
5
|
+
|
|
6
|
+
const _hoisted_1 = {
|
|
7
|
+
key: 0,
|
|
8
|
+
class: "x-page-selector",
|
|
9
|
+
"aria-label": "Pagination"
|
|
10
|
+
};
|
|
11
|
+
const _hoisted_2 = ["disabled", "aria-disabled"];
|
|
12
|
+
const _hoisted_3 = ["onClick", "data-test", "aria-label", "aria-current"];
|
|
13
|
+
const _hoisted_4 = ["disabled", "aria-disabled"];
|
|
14
|
+
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
15
|
+
return _ctx.visiblePages?.length > 1 ? (openBlock(), createElementBlock("nav", _hoisted_1, [
|
|
16
|
+
createElementVNode("button", {
|
|
17
|
+
onClick: _cache[0] || (_cache[0] = ($event) => _ctx.selectPage(_ctx.currentPage - 1)),
|
|
18
|
+
class: normalizeClass(["x-button", _ctx.buttonClasses]),
|
|
19
|
+
disabled: _ctx.currentPage === 1,
|
|
20
|
+
"data-test": "previous-page-button",
|
|
21
|
+
"aria-label": "Previous page",
|
|
22
|
+
"aria-disabled": _ctx.currentPage === 1
|
|
23
|
+
}, [
|
|
24
|
+
renderSlot(_ctx.$slots, "previous-page-button", {}, () => [
|
|
25
|
+
createTextVNode("Prev")
|
|
26
|
+
], true)
|
|
27
|
+
], 10, _hoisted_2),
|
|
28
|
+
(openBlock(true), createElementBlock(
|
|
29
|
+
Fragment,
|
|
30
|
+
null,
|
|
31
|
+
renderList(_ctx.visiblePages, (page) => {
|
|
32
|
+
return openBlock(), createElementBlock("button", {
|
|
33
|
+
key: page.value,
|
|
34
|
+
onClick: ($event) => _ctx.selectPage(page.value),
|
|
35
|
+
class: normalizeClass(["x-button x-page-selector__page", [
|
|
36
|
+
_ctx.itemClasses(page.isSelected),
|
|
37
|
+
{
|
|
38
|
+
"x-page-selector__page--current": page.isSelected,
|
|
39
|
+
"x-page-selector__page--hidden": page.value === _ctx.hiddenPage
|
|
40
|
+
}
|
|
41
|
+
]]),
|
|
42
|
+
"data-test": `page-button-${page.value}`,
|
|
43
|
+
"aria-label": `Page ${page.value}`,
|
|
44
|
+
"aria-current": page.isSelected ? "page" : void 0
|
|
45
|
+
}, [
|
|
46
|
+
renderSlot(_ctx.$slots, "page-button", {
|
|
47
|
+
page: page.value,
|
|
48
|
+
isSelected: page.isSelected
|
|
49
|
+
}, () => [
|
|
50
|
+
createTextVNode(
|
|
51
|
+
toDisplayString(page.value),
|
|
52
|
+
1
|
|
53
|
+
/* TEXT */
|
|
54
|
+
)
|
|
55
|
+
], true)
|
|
56
|
+
], 10, _hoisted_3);
|
|
57
|
+
}),
|
|
58
|
+
128
|
|
59
|
+
/* KEYED_FRAGMENT */
|
|
60
|
+
)),
|
|
61
|
+
createElementVNode("button", {
|
|
62
|
+
onClick: _cache[1] || (_cache[1] = ($event) => _ctx.selectPage(_ctx.currentPage + 1)),
|
|
63
|
+
class: normalizeClass(["x-button", _ctx.buttonClasses]),
|
|
64
|
+
disabled: _ctx.currentPage === _ctx.totalPages,
|
|
65
|
+
"data-test": "next-page-button",
|
|
66
|
+
"aria-label": "Next page",
|
|
67
|
+
"aria-disabled": _ctx.currentPage === _ctx.totalPages
|
|
68
|
+
}, [
|
|
69
|
+
renderSlot(_ctx.$slots, "next-page-button", {}, () => [
|
|
70
|
+
createTextVNode("Next")
|
|
71
|
+
], true)
|
|
72
|
+
], 10, _hoisted_4)
|
|
73
|
+
])) : createCommentVNode("v-if", true);
|
|
74
|
+
}
|
|
75
|
+
var pageSelector = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-b08cf95a"]]);
|
|
76
|
+
|
|
77
|
+
export { pageSelector as default };
|
|
78
|
+
//# sourceMappingURL=page-selector.vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-selector.vue.js","sources":["../../../src/components/page-selector.vue"],"sourcesContent":["<template>\n <nav v-if=\"visiblePages?.length > 1\" class=\"x-page-selector\" aria-label=\"Pagination\">\n <button\n @click=\"selectPage(currentPage - 1)\"\n class=\"x-button\"\n :class=\"buttonClasses\"\n :disabled=\"currentPage === 1\"\n data-test=\"previous-page-button\"\n aria-label=\"Previous page\"\n :aria-disabled=\"currentPage === 1\"\n >\n <slot name=\"previous-page-button\">Prev</slot>\n </button>\n\n <button\n v-for=\"page in visiblePages\"\n :key=\"page.value\"\n @click=\"selectPage(page.value)\"\n class=\"x-button x-page-selector__page\"\n :class=\"[\n itemClasses(page.isSelected),\n {\n 'x-page-selector__page--current': page.isSelected,\n 'x-page-selector__page--hidden': page.value === hiddenPage\n }\n ]\"\n :data-test=\"`page-button-${page.value}`\"\n :aria-label=\"`Page ${page.value}`\"\n :aria-current=\"page.isSelected ? 'page' : undefined\"\n >\n <slot name=\"page-button\" :page=\"page.value\" :is-selected=\"page.isSelected\">\n {{ page.value }}\n </slot>\n </button>\n\n <button\n @click=\"selectPage(currentPage + 1)\"\n class=\"x-button\"\n :class=\"buttonClasses\"\n :disabled=\"currentPage === totalPages\"\n data-test=\"next-page-button\"\n aria-label=\"Next page\"\n :aria-disabled=\"currentPage === totalPages\"\n >\n <slot name=\"next-page-button\">Next</slot>\n </button>\n </nav>\n</template>\n\n<script lang=\"ts\">\n import { defineComponent, computed, PropType } from 'vue';\n import { Dictionary } from '@empathyco/x-utils';\n import { useXBus } from '../composables';\n\n interface PageItem {\n value: number | string;\n isSelected: boolean;\n }\n\n /**\n * Component that renders a pagination control with buttons for navigating\n * between pages. It displays the current page, allows selecting other pages,\n * and emits events when a page is selected.\n *\n * @public\n */\n export default defineComponent({\n name: 'PageSelector',\n props: {\n /**\n * CSS classes to customize the prev/next buttons.\n */\n buttonClasses: {\n type: Array as PropType<(string | Dictionary<boolean>)[]>,\n default: () => []\n },\n /**\n * The current page number.\n */\n currentPage: {\n type: Number,\n required: true\n },\n /**\n * The string content of the hidden pages.\n */\n hiddenPage: {\n type: String,\n default: '...'\n },\n /**\n * CSS classes to customize the page items.\n */\n itemClasses: {\n type: Function as PropType<\n (isSelected: boolean) => string | Dictionary<boolean> | (string | Dictionary<boolean>)[]\n >,\n default: () => []\n },\n /**\n * The number of pages to show before and after the current page.\n */\n range: {\n type: Number,\n default: 2\n },\n /**\n * The class of the scroll container to scroll to top when a page is selected.\n */\n scrollTarget: {\n type: String,\n default: 'main-scroll'\n },\n /**\n * The total number of pages.\n */\n totalPages: {\n type: Number,\n required: true\n }\n },\n setup(props) {\n const bus = useXBus();\n\n const visiblePages = computed(() => {\n const start = Math.max(props.currentPage - props.range, 1);\n const end = Math.min(props.currentPage + props.range, props.totalPages);\n const pages: PageItem[] = Array.from({ length: end - start + 1 }, (_, i) => {\n const pageValue: string | number = start + i;\n return { value: pageValue, isSelected: pageValue === props.currentPage };\n });\n\n // Ensure first and last pages are always visible when needed\n if (start > 1) {\n pages.unshift({ value: 1, isSelected: 1 === props.currentPage });\n if (start > 2) {\n pages.splice(1, 0, { value: props.hiddenPage, isSelected: false });\n }\n }\n if (end < props.totalPages) {\n if (end < props.totalPages - 1) {\n pages.push({ value: props.hiddenPage, isSelected: false });\n }\n pages.push({\n value: props.totalPages,\n isSelected: props.totalPages === props.currentPage\n });\n }\n\n return pages;\n });\n\n /**\n * Handles the selection of a page.\n *\n * @param page - The page to select. Can be a number representing the page number or a string '...' indicating an ellipsis.\n */\n const selectPage = (page: number | string): void => {\n if (page === '...') {\n return;\n }\n if (typeof page === 'number' && page > 0 && page <= props.totalPages) {\n bus.emit('UserSelectedAPage', page);\n /**\n * Emits scroll to top to prevent keeping the position if there is more content\n * after results, as for example Next Queries Preview.\n */\n bus.emit('UserClickedScrollToTop', props.scrollTarget);\n }\n };\n\n return {\n visiblePages,\n selectPage\n };\n }\n });\n</script>\n\n<style scoped>\n .x-page-selector {\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 2px;\n }\n\n .x-page-selector__page--current,\n .x-page-selector__page--hidden {\n cursor: default;\n }\n</style>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits the \"UserSelectedAPage\" and the UserClickedScrollToTop events by default.\n\n## See it in action\n\nBasic example of how the component is rendered.\n\n```vue live\n<template>\n <PageSelector :current-page=\"currentPage\" :total-pages=\"totalPages\" />\n</template>\n\n<script>\n import { PageSelector } from '@empathyco/x-components';\n\n export default {\n name: 'PageSelectorDemo',\n components: {\n PageSelector\n },\n data() {\n return {\n page: 0,\n totalPages: 10\n };\n },\n computed: {\n currentPage() {\n return this.page;\n }\n }\n };\n</script>\n```\n\n### Customize the slots\n\nThis component allows to customise its content using slots.\n\n```vue live\n<template>\n <PageSelector\n :total-pages=\"totalPages\"\n :currentPage=\"currentPage\"\n :item-classes=\"\n (isSelected: boolean) =>\n isSelected\n ? 'x-button-lead x-text-neutral-10'\n : 'x-text-neutral-90 x-button-outlined'\n \"\n :buttonClasses=\"['x-rounded-md']\"\n >\n <template #previous-page-button>\n <span>Back</span>\n </template>\n <template #page-button=\"{ page, isSelected }\">\n <h2 :class=\"{ 'x-text1': !isSelected }\">\n {{ page }}\n </h2>\n </template>\n <template #next-page-button>\n <span>Forward</span>\n </template>\n </PageSelector>\n</template>\n\n<script>\n import { PageSelector } from '@empathyco/x-components';\n\n export default {\n name: 'PageSelectorDemo',\n components: {\n PageSelector\n },\n data() {\n return {\n page: 2,\n totalPages: 10\n };\n },\n computed: {\n currentPage() {\n return this.page;\n }\n }\n };\n</script>\n```\n\n### Customize the number of pages to show before and after the current page by changing the range default value.\n\n```vue live\n<template>\n <PageSelector :current-page=\"currentPage\" :total-pages=\"totalPages\" :range=\"range\" />\n</template>\n\n<script>\n import { PageSelector } from '@empathyco/x-components';\n\n export default {\n name: 'PageSelectorDemo',\n components: {\n PageSelector\n },\n data() {\n return {\n page: 6,\n totalPages: 100,\n range: 4\n };\n },\n computed: {\n currentPage() {\n return this.page;\n }\n }\n };\n</script>\n```\n</docs>\n"],"names":["selectPage","currentPage","_createTextVNode","_openBlock","_createElementBlock","_Fragment","_renderList","itemClasses","_normalizeClass","_renderSlot","_toDisplayString","_createElementVNode","totalPages","_createCommentVNode"],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { defineComponent, computed } from 'vue';
|
|
2
|
+
import '../composables/create-use-device.js';
|
|
3
|
+
import '@vue/devtools-api';
|
|
4
|
+
import '../plugins/devtools/timeline.devtools.js';
|
|
5
|
+
import '@empathyco/x-utils';
|
|
6
|
+
import 'rxjs/operators';
|
|
7
|
+
import 'rxjs';
|
|
8
|
+
import '../plugins/devtools/colors.utils.js';
|
|
9
|
+
import '../plugins/x-bus.js';
|
|
10
|
+
import '../plugins/x-plugin.js';
|
|
11
|
+
import 'vuex';
|
|
12
|
+
import { useXBus } from '../composables/use-x-bus.js';
|
|
13
|
+
import '@vueuse/core';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Component that renders a pagination control with buttons for navigating
|
|
17
|
+
* between pages. It displays the current page, allows selecting other pages,
|
|
18
|
+
* and emits events when a page is selected.
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
var _sfc_main = defineComponent({
|
|
23
|
+
name: 'PageSelector',
|
|
24
|
+
props: {
|
|
25
|
+
/**
|
|
26
|
+
* CSS classes to customize the prev/next buttons.
|
|
27
|
+
*/
|
|
28
|
+
buttonClasses: {
|
|
29
|
+
type: Array,
|
|
30
|
+
default: () => []
|
|
31
|
+
},
|
|
32
|
+
/**
|
|
33
|
+
* The current page number.
|
|
34
|
+
*/
|
|
35
|
+
currentPage: {
|
|
36
|
+
type: Number,
|
|
37
|
+
required: true
|
|
38
|
+
},
|
|
39
|
+
/**
|
|
40
|
+
* The string content of the hidden pages.
|
|
41
|
+
*/
|
|
42
|
+
hiddenPage: {
|
|
43
|
+
type: String,
|
|
44
|
+
default: '...'
|
|
45
|
+
},
|
|
46
|
+
/**
|
|
47
|
+
* CSS classes to customize the page items.
|
|
48
|
+
*/
|
|
49
|
+
itemClasses: {
|
|
50
|
+
type: Function,
|
|
51
|
+
default: () => []
|
|
52
|
+
},
|
|
53
|
+
/**
|
|
54
|
+
* The number of pages to show before and after the current page.
|
|
55
|
+
*/
|
|
56
|
+
range: {
|
|
57
|
+
type: Number,
|
|
58
|
+
default: 2
|
|
59
|
+
},
|
|
60
|
+
/**
|
|
61
|
+
* The class of the scroll container to scroll to top when a page is selected.
|
|
62
|
+
*/
|
|
63
|
+
scrollTarget: {
|
|
64
|
+
type: String,
|
|
65
|
+
default: 'main-scroll'
|
|
66
|
+
},
|
|
67
|
+
/**
|
|
68
|
+
* The total number of pages.
|
|
69
|
+
*/
|
|
70
|
+
totalPages: {
|
|
71
|
+
type: Number,
|
|
72
|
+
required: true
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
setup(props) {
|
|
76
|
+
const bus = useXBus();
|
|
77
|
+
const visiblePages = computed(() => {
|
|
78
|
+
const start = Math.max(props.currentPage - props.range, 1);
|
|
79
|
+
const end = Math.min(props.currentPage + props.range, props.totalPages);
|
|
80
|
+
const pages = Array.from({ length: end - start + 1 }, (_, i) => {
|
|
81
|
+
const pageValue = start + i;
|
|
82
|
+
return { value: pageValue, isSelected: pageValue === props.currentPage };
|
|
83
|
+
});
|
|
84
|
+
// Ensure first and last pages are always visible when needed
|
|
85
|
+
if (start > 1) {
|
|
86
|
+
pages.unshift({ value: 1, isSelected: 1 === props.currentPage });
|
|
87
|
+
if (start > 2) {
|
|
88
|
+
pages.splice(1, 0, { value: props.hiddenPage, isSelected: false });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (end < props.totalPages) {
|
|
92
|
+
if (end < props.totalPages - 1) {
|
|
93
|
+
pages.push({ value: props.hiddenPage, isSelected: false });
|
|
94
|
+
}
|
|
95
|
+
pages.push({
|
|
96
|
+
value: props.totalPages,
|
|
97
|
+
isSelected: props.totalPages === props.currentPage
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return pages;
|
|
101
|
+
});
|
|
102
|
+
/**
|
|
103
|
+
* Handles the selection of a page.
|
|
104
|
+
*
|
|
105
|
+
* @param page - The page to select. Can be a number representing the page number or a string '...' indicating an ellipsis.
|
|
106
|
+
*/
|
|
107
|
+
const selectPage = (page) => {
|
|
108
|
+
if (page === '...') {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (typeof page === 'number' && page > 0 && page <= props.totalPages) {
|
|
112
|
+
bus.emit('UserSelectedAPage', page);
|
|
113
|
+
/**
|
|
114
|
+
* Emits scroll to top to prevent keeping the position if there is more content
|
|
115
|
+
* after results, as for example Next Queries Preview.
|
|
116
|
+
*/
|
|
117
|
+
bus.emit('UserClickedScrollToTop', props.scrollTarget);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
return {
|
|
121
|
+
visiblePages,
|
|
122
|
+
selectPage
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
export { _sfc_main as default };
|
|
128
|
+
//# sourceMappingURL=page-selector.vue2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-selector.vue2.js","sources":["../../../src/components/page-selector.vue"],"sourcesContent":["<template>\n <nav v-if=\"visiblePages?.length > 1\" class=\"x-page-selector\" aria-label=\"Pagination\">\n <button\n @click=\"selectPage(currentPage - 1)\"\n class=\"x-button\"\n :class=\"buttonClasses\"\n :disabled=\"currentPage === 1\"\n data-test=\"previous-page-button\"\n aria-label=\"Previous page\"\n :aria-disabled=\"currentPage === 1\"\n >\n <slot name=\"previous-page-button\">Prev</slot>\n </button>\n\n <button\n v-for=\"page in visiblePages\"\n :key=\"page.value\"\n @click=\"selectPage(page.value)\"\n class=\"x-button x-page-selector__page\"\n :class=\"[\n itemClasses(page.isSelected),\n {\n 'x-page-selector__page--current': page.isSelected,\n 'x-page-selector__page--hidden': page.value === hiddenPage\n }\n ]\"\n :data-test=\"`page-button-${page.value}`\"\n :aria-label=\"`Page ${page.value}`\"\n :aria-current=\"page.isSelected ? 'page' : undefined\"\n >\n <slot name=\"page-button\" :page=\"page.value\" :is-selected=\"page.isSelected\">\n {{ page.value }}\n </slot>\n </button>\n\n <button\n @click=\"selectPage(currentPage + 1)\"\n class=\"x-button\"\n :class=\"buttonClasses\"\n :disabled=\"currentPage === totalPages\"\n data-test=\"next-page-button\"\n aria-label=\"Next page\"\n :aria-disabled=\"currentPage === totalPages\"\n >\n <slot name=\"next-page-button\">Next</slot>\n </button>\n </nav>\n</template>\n\n<script lang=\"ts\">\n import { defineComponent, computed, PropType } from 'vue';\n import { Dictionary } from '@empathyco/x-utils';\n import { useXBus } from '../composables';\n\n interface PageItem {\n value: number | string;\n isSelected: boolean;\n }\n\n /**\n * Component that renders a pagination control with buttons for navigating\n * between pages. It displays the current page, allows selecting other pages,\n * and emits events when a page is selected.\n *\n * @public\n */\n export default defineComponent({\n name: 'PageSelector',\n props: {\n /**\n * CSS classes to customize the prev/next buttons.\n */\n buttonClasses: {\n type: Array as PropType<(string | Dictionary<boolean>)[]>,\n default: () => []\n },\n /**\n * The current page number.\n */\n currentPage: {\n type: Number,\n required: true\n },\n /**\n * The string content of the hidden pages.\n */\n hiddenPage: {\n type: String,\n default: '...'\n },\n /**\n * CSS classes to customize the page items.\n */\n itemClasses: {\n type: Function as PropType<\n (isSelected: boolean) => string | Dictionary<boolean> | (string | Dictionary<boolean>)[]\n >,\n default: () => []\n },\n /**\n * The number of pages to show before and after the current page.\n */\n range: {\n type: Number,\n default: 2\n },\n /**\n * The class of the scroll container to scroll to top when a page is selected.\n */\n scrollTarget: {\n type: String,\n default: 'main-scroll'\n },\n /**\n * The total number of pages.\n */\n totalPages: {\n type: Number,\n required: true\n }\n },\n setup(props) {\n const bus = useXBus();\n\n const visiblePages = computed(() => {\n const start = Math.max(props.currentPage - props.range, 1);\n const end = Math.min(props.currentPage + props.range, props.totalPages);\n const pages: PageItem[] = Array.from({ length: end - start + 1 }, (_, i) => {\n const pageValue: string | number = start + i;\n return { value: pageValue, isSelected: pageValue === props.currentPage };\n });\n\n // Ensure first and last pages are always visible when needed\n if (start > 1) {\n pages.unshift({ value: 1, isSelected: 1 === props.currentPage });\n if (start > 2) {\n pages.splice(1, 0, { value: props.hiddenPage, isSelected: false });\n }\n }\n if (end < props.totalPages) {\n if (end < props.totalPages - 1) {\n pages.push({ value: props.hiddenPage, isSelected: false });\n }\n pages.push({\n value: props.totalPages,\n isSelected: props.totalPages === props.currentPage\n });\n }\n\n return pages;\n });\n\n /**\n * Handles the selection of a page.\n *\n * @param page - The page to select. Can be a number representing the page number or a string '...' indicating an ellipsis.\n */\n const selectPage = (page: number | string): void => {\n if (page === '...') {\n return;\n }\n if (typeof page === 'number' && page > 0 && page <= props.totalPages) {\n bus.emit('UserSelectedAPage', page);\n /**\n * Emits scroll to top to prevent keeping the position if there is more content\n * after results, as for example Next Queries Preview.\n */\n bus.emit('UserClickedScrollToTop', props.scrollTarget);\n }\n };\n\n return {\n visiblePages,\n selectPage\n };\n }\n });\n</script>\n\n<style scoped>\n .x-page-selector {\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 2px;\n }\n\n .x-page-selector__page--current,\n .x-page-selector__page--hidden {\n cursor: default;\n }\n</style>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits the \"UserSelectedAPage\" and the UserClickedScrollToTop events by default.\n\n## See it in action\n\nBasic example of how the component is rendered.\n\n```vue live\n<template>\n <PageSelector :current-page=\"currentPage\" :total-pages=\"totalPages\" />\n</template>\n\n<script>\n import { PageSelector } from '@empathyco/x-components';\n\n export default {\n name: 'PageSelectorDemo',\n components: {\n PageSelector\n },\n data() {\n return {\n page: 0,\n totalPages: 10\n };\n },\n computed: {\n currentPage() {\n return this.page;\n }\n }\n };\n</script>\n```\n\n### Customize the slots\n\nThis component allows to customise its content using slots.\n\n```vue live\n<template>\n <PageSelector\n :total-pages=\"totalPages\"\n :currentPage=\"currentPage\"\n :item-classes=\"\n (isSelected: boolean) =>\n isSelected\n ? 'x-button-lead x-text-neutral-10'\n : 'x-text-neutral-90 x-button-outlined'\n \"\n :buttonClasses=\"['x-rounded-md']\"\n >\n <template #previous-page-button>\n <span>Back</span>\n </template>\n <template #page-button=\"{ page, isSelected }\">\n <h2 :class=\"{ 'x-text1': !isSelected }\">\n {{ page }}\n </h2>\n </template>\n <template #next-page-button>\n <span>Forward</span>\n </template>\n </PageSelector>\n</template>\n\n<script>\n import { PageSelector } from '@empathyco/x-components';\n\n export default {\n name: 'PageSelectorDemo',\n components: {\n PageSelector\n },\n data() {\n return {\n page: 2,\n totalPages: 10\n };\n },\n computed: {\n currentPage() {\n return this.page;\n }\n }\n };\n</script>\n```\n\n### Customize the number of pages to show before and after the current page by changing the range default value.\n\n```vue live\n<template>\n <PageSelector :current-page=\"currentPage\" :total-pages=\"totalPages\" :range=\"range\" />\n</template>\n\n<script>\n import { PageSelector } from '@empathyco/x-components';\n\n export default {\n name: 'PageSelectorDemo',\n components: {\n PageSelector\n },\n data() {\n return {\n page: 6,\n totalPages: 100,\n range: 4\n };\n },\n computed: {\n currentPage() {\n return this.page;\n }\n }\n };\n</script>\n```\n</docs>\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import injectCss from '../../tools/inject-css.js';
|
|
2
|
+
|
|
3
|
+
var css = ".x-page-selector[data-v-b08cf95a]{align-items:center;display:flex;gap:2px;justify-content:center}.x-page-selector__page--current[data-v-b08cf95a],.x-page-selector__page--hidden[data-v-b08cf95a]{cursor:default}";
|
|
4
|
+
injectCss(css);
|
|
5
|
+
|
|
6
|
+
export { css, css as default };
|
|
7
|
+
//# sourceMappingURL=page-selector.vue3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-selector.vue3.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
|
package/js/index.js
CHANGED
|
@@ -139,6 +139,7 @@ export { default as LocationProvider } from './components/location-provider.vue.
|
|
|
139
139
|
export { default as SlidingPanel } from './components/sliding-panel.vue.js';
|
|
140
140
|
export { default as SnippetCallbacks } from './components/snippet-callbacks.vue.js';
|
|
141
141
|
export { default as PageLoaderButton } from './components/page-loader-button.vue.js';
|
|
142
|
+
export { default as PageSelector } from './components/page-selector.vue.js';
|
|
142
143
|
export { DISABLE_ANIMATIONS_KEY, HAS_MORE_ITEMS_KEY, LIST_ITEMS_KEY, QUERY_KEY, RESULT_WITH_VARIANTS_KEY, SELECTED_VARIANTS_KEY, SELECT_RESULT_VARIANT_KEY } from './components/decorators/injection.consts.js';
|
|
143
144
|
export { getRootXComponent, getXComponentXModuleName, isXComponent } from './components/x-component.utils.js';
|
|
144
145
|
export { createUseDevice } from './composables/create-use-device.js';
|
package/js/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -89,6 +89,8 @@ import '../../../components/sliding-panel.vue2.js';
|
|
|
89
89
|
import '../../../components/sliding-panel.vue3.js';
|
|
90
90
|
import '../../../components/snippet-callbacks.vue2.js';
|
|
91
91
|
import '../../../components/page-loader-button.vue2.js';
|
|
92
|
+
import '../../../components/page-selector.vue2.js';
|
|
93
|
+
import '../../../components/page-selector.vue3.js';
|
|
92
94
|
import '../../../composables/create-use-device.js';
|
|
93
95
|
import '@vue/devtools-api';
|
|
94
96
|
import '../../../plugins/devtools/timeline.devtools.js';
|