@1024pix/pix-ui 13.3.4 → 13.4.2

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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # Pix-UI Changelog
2
2
 
3
+ ## v13.4.2 (07/04/2022)
4
+
5
+
6
+ ### :building_construction: Tech
7
+ - [#208](https://github.com/1024pix/pix-ui/pull/208) [TECH] Suppression de la margin dans Pix-Pagination (PIX-4733)
8
+
9
+ ## v13.4.1 (05/04/2022)
10
+
11
+
12
+ ### :rocket: Amélioration
13
+ - [#207](https://github.com/1024pix/pix-ui/pull/207) [FEATURE] Permettre à pix-pagination d'avoir une version condensée (PIX-4715)
14
+
15
+ ## v13.4.0 (25/03/2022)
16
+
17
+
18
+ ### :rocket: Amélioration
19
+ - [#206](https://github.com/1024pix/pix-ui/pull/206) [FEATURE] Composant de pagination (PIX-4511)
20
+
3
21
  ## v13.3.4 (21/03/2022)
4
22
 
5
23
 
@@ -0,0 +1,48 @@
1
+ <footer class={{this.isCondensed}}>
2
+ <section class="pix-pagination__size">
3
+ <span class="pagination-size__label">{{this.beforeResultsPerPage}}</span>
4
+ <PixSelect
5
+ aria-label={{this.selectPageSizeLabel}}
6
+ class="pagination-size__choice"
7
+ @selectedOption={{this.pageSize}}
8
+ @onChange={{this.changePageSize}}
9
+ @options={{this.pageOptions}}
10
+ />
11
+ </section>
12
+ <section class="pix-pagination__navigation">
13
+ <span>
14
+ {{#if (eq this.pageCount 1)}}
15
+ {{this.pageResults}}
16
+ {{else}}
17
+ {{this.pageInfo}}
18
+ {{/if}}
19
+ </span>
20
+ <div class="pix-pagination-navigation__action">
21
+ <PixIconButton
22
+ class="pix-pagination-navigation__action-button"
23
+ @icon="arrow-left"
24
+ aria-label={{this.previousPageLabel}}
25
+ @triggerAction={{this.goToPreviousPage}}
26
+ @withBackground={{false}}
27
+ @size="big"
28
+ @color="dark-grey"
29
+ disabled={{this.isPreviousPageDisabled}}
30
+ aria-disabled="{{this.isPreviousPageDisabled}}"
31
+ />
32
+ <span>
33
+ {{this.pageNumber}}
34
+ </span>
35
+ <PixIconButton
36
+ class="pix-pagination-navigation__action-button"
37
+ @icon="arrow-right"
38
+ aria-label={{this.nextPageLabel}}
39
+ @triggerAction={{this.goToNextPage}}
40
+ @withBackground={{false}}
41
+ @size="big"
42
+ @color="dark-grey"
43
+ disabled={{this.isNextPageDisabled}}
44
+ aria-disabled="{{this.isNextPageDisabled}}"
45
+ />
46
+ </div>
47
+ </section>
48
+ </footer>
@@ -0,0 +1,121 @@
1
+ import { action } from '@ember/object';
2
+ import { inject as service } from '@ember/service';
3
+ import Component from '@glimmer/component';
4
+ import { formatMessage } from '../translations';
5
+
6
+ const DEFAULT_PAGE_OPTIONS = [
7
+ { label: '10', value: 10 },
8
+ { label: '25', value: 25 },
9
+ { label: '50', value: 50 },
10
+ { label: '100', value: 100 },
11
+ ];
12
+
13
+ export default class PixPagination extends Component {
14
+ @service router;
15
+
16
+ get isCondensed() {
17
+ return this.args.isCondensed ? 'pix-pagination-condensed' : 'pix-pagination';
18
+ }
19
+
20
+ get beforeResultsPerPage() {
21
+ return this.formatMessage('beforeResultsPerPage');
22
+ }
23
+
24
+ get previousPageLabel() {
25
+ return this.formatMessage('previousPageLabel');
26
+ }
27
+
28
+ get nextPageLabel() {
29
+ return this.formatMessage('nextPageLabel');
30
+ }
31
+
32
+ get pageNumber() {
33
+ return this.formatMessage('pageNumber', {
34
+ total: this.pageCount,
35
+ current: this.currentPage,
36
+ });
37
+ }
38
+ get pageInfo() {
39
+ return this.formatMessage('pageInfo', {
40
+ total: this.resultsCount,
41
+ start: this.firstItemPosition,
42
+ end: this.lastItemPosition,
43
+ });
44
+ }
45
+
46
+ get pageOptions() {
47
+ return this.args.pageOptions ? this.args.pageOptions : DEFAULT_PAGE_OPTIONS;
48
+ }
49
+
50
+ get selectPageSizeLabel() {
51
+ return this.formatMessage('selectPageSizeLabel');
52
+ }
53
+
54
+ get pageResults() {
55
+ return this.formatMessage('pageResults', { total: this.args.pagination.rowCount });
56
+ }
57
+
58
+ formatMessage(message, values) {
59
+ return formatMessage(this.args.locale ?? 'fr', `pagination.${message}`, values);
60
+ }
61
+
62
+ get currentPage() {
63
+ return this.args.pagination ? this.args.pagination.page : 1;
64
+ }
65
+
66
+ get pageCount() {
67
+ if (!this.args.pagination) return 0;
68
+ if (this.args.pagination.pageCount === 0) return 1;
69
+ return this.args.pagination.pageCount;
70
+ }
71
+
72
+ get pageSize() {
73
+ return this.args.pagination ? this.args.pagination.pageSize : this.args.pageOptions[0];
74
+ }
75
+
76
+ get isNextPageDisabled() {
77
+ return this.currentPage === this.pageCount || this.pageCount === 0;
78
+ }
79
+
80
+ get nextPage() {
81
+ return Math.min(this.currentPage + 1, this.pageCount);
82
+ }
83
+
84
+ get isPreviousPageDisabled() {
85
+ return this.currentPage === 1 || this.pageCount === 0;
86
+ }
87
+
88
+ get previousPage() {
89
+ return Math.max(this.currentPage - 1, 1);
90
+ }
91
+
92
+ get resultsCount() {
93
+ return this.args.pagination ? this.args.pagination.rowCount : 0;
94
+ }
95
+
96
+ get firstItemPosition() {
97
+ if (!this.args.pagination) return 0;
98
+ return (this.currentPage - 1) * this.pageSize + 1;
99
+ }
100
+
101
+ get lastItemPosition() {
102
+ if (!this.args.pagination) return 0;
103
+ const { rowCount } = this.args.pagination;
104
+ return Math.min(rowCount, this.firstItemPosition + this.pageSize - 1);
105
+ }
106
+
107
+ @action
108
+ changePageSize(event) {
109
+ this.router.replaceWith({ queryParams: { pageSize: event.target.value, pageNumber: 1 } });
110
+ }
111
+
112
+ @action
113
+ goToNextPage() {
114
+ this.router.replaceWith({ queryParams: { pageNumber: this.nextPage } });
115
+ }
116
+
117
+ @action
118
+ goToPreviousPage() {
119
+ this.router.replaceWith({ queryParams: { pageNumber: this.previousPage } });
120
+ }
121
+ }
@@ -0,0 +1,58 @@
1
+ .pix-pagination, .pix-pagination-condensed {
2
+ display: flex;
3
+ justify-content: center;
4
+ color: $grey-60;
5
+ font-size: 0.875rem;
6
+
7
+ &__size {
8
+ display: none;
9
+ align-items: center;
10
+ padding: 0;
11
+
12
+ .pagination-size__label {
13
+ margin-right: 16px;
14
+ }
15
+
16
+ select.pagination__choice {
17
+ height: 36px;
18
+ font-size: 0.8rem;
19
+ padding-left: 8px;
20
+ padding-right: 24px;
21
+ }
22
+ }
23
+
24
+ &__navigation {
25
+ display: flex;
26
+ align-items: center;
27
+ padding: 0;
28
+ gap: 12px;
29
+ flex-direction: column-reverse;
30
+ }
31
+ }
32
+
33
+ .pix-pagination-navigation {
34
+ &__action {
35
+ display: flex;
36
+ align-items: center;
37
+
38
+ &-button {
39
+ margin: 0 8px;
40
+ }
41
+ }
42
+ }
43
+
44
+ @include device-is('tablet') {
45
+ .pix-pagination {
46
+ justify-content: space-between;
47
+ }
48
+ .pix-pagination > .pix-pagination {
49
+ &__size {
50
+ display: flex;
51
+ }
52
+
53
+ &__navigation {
54
+ gap: initial;
55
+ flex-direction: initial;
56
+ }
57
+ }
58
+ }
@@ -29,6 +29,7 @@
29
29
  @import 'pix-input-code';
30
30
  @import 'pix-selectable-tag';
31
31
  @import 'pix-dropdown';
32
+ @import 'pix-pagination';
32
33
 
33
34
  html {
34
35
  font-size: 16px;
@@ -0,0 +1,12 @@
1
+ export default {
2
+ pagination: {
3
+ beforeResultsPerPage: 'See',
4
+ selectPageSizeLabel: 'Select the number of items by page',
5
+ pageResults: '{total, plural, =0 {0 items} =1 {1 item} other {{total, number} items}}',
6
+ pageInfo:
7
+ '{start, number}-{end, number} of {total, plural, =0 {0 items} =1 {1 item} other {{total, number} items}}',
8
+ previousPageLabel: 'Go to previous page',
9
+ pageNumber: 'Page {current, number} / {total, number}',
10
+ nextPageLabel: 'Go to next page',
11
+ },
12
+ };
@@ -0,0 +1,12 @@
1
+ export default {
2
+ pagination: {
3
+ beforeResultsPerPage: 'Voir',
4
+ selectPageSizeLabel: "Nombre d'élément à afficher par page",
5
+ pageResults: '{total, plural, =0 {0 élément} =1 {1 élément} other {{total, number} éléments}}',
6
+ pageInfo:
7
+ '{start, number}-{end, number} sur {total, plural, =0 {0 élément} =1 {1 élément} other {{total, number} éléments}}',
8
+ previousPageLabel: 'Aller à la page précédente',
9
+ pageNumber: 'Page {current, number} / {total, number}',
10
+ nextPageLabel: 'Aller à la page suivante',
11
+ },
12
+ };
@@ -0,0 +1,32 @@
1
+ import { createIntl } from '@formatjs/intl';
2
+ import en from './en';
3
+ import fr from './fr';
4
+
5
+ export function formatMessage(locale, message, values) {
6
+ return locales[locale].formatMessage({ id: message }, values);
7
+ }
8
+
9
+ const locales = {
10
+ fr: createIntl({
11
+ locale: 'fr',
12
+ messages: flattenObject(fr),
13
+ }),
14
+ en: createIntl({
15
+ locale: 'en',
16
+ messages: flattenObject(en),
17
+ }),
18
+ };
19
+
20
+ export function flattenObject(object) {
21
+ const entries = Object.entries(object);
22
+
23
+ const flatEntries = entries.flatMap(([key, value]) => {
24
+ if (typeof value !== 'object') return [[key, value]];
25
+
26
+ const childEntries = Object.entries(flattenObject(value));
27
+
28
+ return childEntries.map(([childKey, childValue]) => [`${key}.${childKey}`, childValue]);
29
+ });
30
+
31
+ return Object.fromEntries(flatEntries);
32
+ }
@@ -0,0 +1,4 @@
1
+ // WORKAROUND: necessary for storybook to resolve the import
2
+ import '@formatjs/intl';
3
+
4
+ export { default } from '@1024pix/pix-ui/components/pix-pagination';
@@ -0,0 +1,146 @@
1
+ import { hbs } from 'ember-cli-htmlbars';
2
+
3
+ export const Template = (args) => {
4
+ return {
5
+ template: hbs`
6
+ <PixPagination
7
+ @pagination={{pagination}}
8
+ @locale = {{locale}}
9
+ @pageOptions= {{pageOptions}}
10
+ @isCondensed= {{isCondensed}}
11
+ />
12
+ `,
13
+ context: args,
14
+ };
15
+ };
16
+
17
+ export const French = Template.bind({});
18
+ French.args = {
19
+ pagination: {
20
+ page: 1,
21
+ pageSize: 5,
22
+ rowCount: 12,
23
+ pageCount: 3,
24
+ },
25
+ locale: 'fr',
26
+ };
27
+
28
+ export const English = Template.bind({});
29
+ English.args = {
30
+ pagination: {
31
+ page: 2,
32
+ pageSize: 10,
33
+ rowCount: 12,
34
+ pageCount: 2,
35
+ },
36
+ pageOptions: [
37
+ { label: '10', value: 10 },
38
+ { label: '20', value: 20 },
39
+ { label: '50', value: 50 },
40
+ { label: '100', value: 100 },
41
+ ],
42
+ locale: 'en',
43
+ };
44
+
45
+ export const OnePage = Template.bind({});
46
+ OnePage.args = {
47
+ pagination: {
48
+ page: 1,
49
+ pageSize: 10,
50
+ rowCount: 2,
51
+ pageCount: 1,
52
+ },
53
+ locale: 'fr',
54
+ };
55
+
56
+ export const Condensed = Template.bind({});
57
+ Condensed.args = {
58
+ pagination: {
59
+ page: 1,
60
+ pageSize: 10,
61
+ rowCount: 2,
62
+ pageCount: 1,
63
+ },
64
+ locale: 'fr',
65
+ isCondensed: true,
66
+ };
67
+
68
+ // select attribute data type from https://storybook.js.org/docs/react/essentials/controls
69
+ export const argTypes = {
70
+ pagination: {
71
+ name: 'pagination',
72
+ description:
73
+ "Un objet de pagination tel que l'on en trouve au retour de `knex-utils.fetchPage`",
74
+ type: { name: 'object', required: true },
75
+ },
76
+ pageOptions: {
77
+ name: 'pageOptions',
78
+ description: "Un tableau d'objet `options` pour configurer le select",
79
+ type: { name: 'array', required: false },
80
+ control: {
81
+ type: 'array',
82
+ value: [
83
+ {
84
+ label: '10',
85
+ value: 10,
86
+ },
87
+ {
88
+ label: '25',
89
+ value: 25,
90
+ },
91
+ {
92
+ label: '50',
93
+ value: 50,
94
+ },
95
+ {
96
+ label: '100',
97
+ value: 100,
98
+ },
99
+ ],
100
+ },
101
+ table: {
102
+ type: { summary: 'array' },
103
+ defaultValue: {
104
+ summary: JSON.stringify([
105
+ {
106
+ label: '10',
107
+ value: 10,
108
+ },
109
+ {
110
+ label: '25',
111
+ value: 25,
112
+ },
113
+ {
114
+ label: '50',
115
+ value: 50,
116
+ },
117
+ {
118
+ label: '100',
119
+ value: 100,
120
+ },
121
+ ]),
122
+ },
123
+ },
124
+ },
125
+ locale: {
126
+ name: 'locale',
127
+ description: "La langue de l'utilisateur",
128
+ type: { name: 'string', required: false },
129
+ control: { type: 'select', options: ['fr', 'en'] },
130
+ table: {
131
+ type: { summary: 'string' },
132
+ defaultValue: { summary: 'fr' },
133
+ },
134
+ },
135
+ isCondensed: {
136
+ name: 'isCondensed',
137
+ description:
138
+ "En desktop, retire le contrôle du nombre d'élèments par page pour simplifier l'usage",
139
+ type: { name: 'boolean', required: false },
140
+ control: { type: 'boolean' },
141
+ table: {
142
+ type: { summary: 'boolean' },
143
+ defaultValue: { summary: 'false' },
144
+ },
145
+ },
146
+ };
@@ -0,0 +1,65 @@
1
+ import { Meta, Story, Canvas, ArgsTable } from '@storybook/addon-docs/blocks';
2
+ import centered from '@storybook/addon-centered/ember';
3
+
4
+ import * as stories from './pix-pagination.stories.js';
5
+
6
+ <Meta
7
+ title='Basics/Pagination'
8
+ component='PixPagination'
9
+ argTypes={stories.argTypes}
10
+ />
11
+
12
+ # PixPagination
13
+
14
+ PixPagination est un élément permettant de trigger le changement de page dans l'élément parent.
15
+
16
+ > ** ⚠️ Pour utiliser ce composant, il est recommandé d'ajouter cette config dans les routes où tu l'utiliseras.**
17
+ >
18
+ > ** Cela permettra de reload le `model` si les queryParams `pageNumber` & `pageSize` ont été modifiés.**
19
+ > ```javascript
20
+ > queryParams = { pageNumber: { refreshModel: true }, pageSize: { refreshModel: true }, };
21
+ >```
22
+ >
23
+ >** Installer la dépendance `@formatjs/intl` sur votre projet.**
24
+
25
+ Le paramètre `pageOptions` n'est pas requis et possède une valeur par défaut.
26
+
27
+ ** ⚠ Si vous voulez utiliser des options différentes, il ne faut pas oublier que l'API fait le premier call avec un pageSize
28
+ à 10 par défaut.**
29
+
30
+ Sur mobile, le select qui permet de choisir le nombre d'élément à afficher sur la page est retiré.
31
+
32
+ ## En français avec paramètres par défaut
33
+ <Canvas>
34
+ <Story name='French' story={stories.French} height={110}/>
35
+ </Canvas>
36
+
37
+ ## En anglais avec le paramètre `pageOptions` custom
38
+ <Canvas>
39
+ <Story name='English' story={stories.English} height={110} />
40
+ </Canvas>
41
+
42
+ ## Avec une seule page
43
+ <Canvas>
44
+ <Story name='OnePage' story={stories.OnePage} height={110} />
45
+ </Canvas>
46
+
47
+ ## Version condensée
48
+ <Canvas>
49
+ <Story name='Condensed' story={stories.Condensed} height={140} />
50
+ </Canvas>
51
+
52
+ ## Usage
53
+
54
+ ```html
55
+ <PixPagination
56
+ @pagination={{pagination}}
57
+ @locale = {{locale}}
58
+ @pageOptions = {{pageOptions}
59
+ @isCondensed = {{isCondensed}
60
+ />
61
+ ```
62
+
63
+ ## Arguments
64
+
65
+ <ArgsTable story="French" />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1024pix/pix-ui",
3
- "version": "13.3.4",
3
+ "version": "13.4.2",
4
4
  "description": "Pix-UI is the implementation of Pix design principles and guidelines for its products.",
5
5
  "keywords": [
6
6
  "ember-addon"
@@ -53,6 +53,7 @@
53
53
  "@1024pix/ember-testing-library": "^0.5.0",
54
54
  "@ember/optional-features": "^2.0.0",
55
55
  "@ember/test-helpers": "^2.6.0",
56
+ "@formatjs/intl": "^2.1.0",
56
57
  "@fortawesome/ember-fontawesome": "^0.2.3",
57
58
  "@fortawesome/free-regular-svg-icons": "^5.15.4",
58
59
  "@fortawesome/free-solid-svg-icons": "^5.15.4",