@hashicorp/design-system-components 2.14.1 → 2.14.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,13 @@
|
|
|
1
1
|
# @hashicorp/design-system-components
|
|
2
2
|
|
|
3
|
+
## 2.14.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1724](https://github.com/hashicorp/design-system/pull/1724) [`65ebe6dde`](https://github.com/hashicorp/design-system/commit/65ebe6ddeb477ebc74ad6db353aaf19e1dfb06b1) Thanks [@didoo](https://github.com/didoo)! - `Pagination` - updated the logic for “Compact” variant to expose `@currentPageSize` and handle controlled/uncontrolled changes
|
|
8
|
+
|
|
9
|
+
- [#1716](https://github.com/hashicorp/design-system/pull/1716) [`cde67bc7f`](https://github.com/hashicorp/design-system/commit/cde67bc7fc32c1025ddd22de6d0f9baeabf43961) Thanks [@didoo](https://github.com/didoo)! - `Tabs` - replace `assert` with `warn` in `setIndicator` function
|
|
10
|
+
|
|
3
11
|
## 2.14.1
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import Component from '@glimmer/component';
|
|
7
|
+
import { tracked } from '@glimmer/tracking';
|
|
7
8
|
import { action } from '@ember/object';
|
|
8
9
|
import { assert } from '@ember/debug';
|
|
9
10
|
import { inject as service } from '@ember/service';
|
|
@@ -15,6 +16,18 @@ export const DEFAULT_PAGE_SIZES = [10, 30, 50];
|
|
|
15
16
|
export default class HdsPaginationCompactIndexComponent extends Component {
|
|
16
17
|
@service router;
|
|
17
18
|
|
|
19
|
+
// This private variable is used to differentiate between
|
|
20
|
+
// "uncontrolled" component (where the state is handled internally) and
|
|
21
|
+
// "controlled" component (where the state is handled externally, by the consumer's code).
|
|
22
|
+
// In the first case, the variable stores the internal state of the component at any moment,
|
|
23
|
+
// and its value is updated internally according to the user's interaction with the component.
|
|
24
|
+
// In the second case, the variable stores *only* the initial state of the component (coming from the arguments)
|
|
25
|
+
// at rendering time, but from that moment on it's not updated anymore, no matter what interaction the user
|
|
26
|
+
// has with the component (the state is controlled externally, eg. via query parameters)
|
|
27
|
+
@tracked _currentPageSize = this.args.currentPageSize ?? this.pageSizes[0];
|
|
28
|
+
@tracked isControlled;
|
|
29
|
+
|
|
30
|
+
showLabels = this.args.showLabels ?? true; // if the labels for the "prev/next" controls are visible
|
|
18
31
|
showSizeSelector = this.args.showSizeSelector ?? false; // if the "size selector" block is visible
|
|
19
32
|
|
|
20
33
|
constructor() {
|
|
@@ -31,28 +44,16 @@ export default class HdsPaginationCompactIndexComponent extends Component {
|
|
|
31
44
|
// initialized and updated using the arguments passed to it.
|
|
32
45
|
|
|
33
46
|
if (queryFunction === undefined) {
|
|
34
|
-
this.
|
|
47
|
+
this.isControlled = false;
|
|
35
48
|
} else {
|
|
36
49
|
assert(
|
|
37
50
|
'@queryFunction for "Hds::Pagination::Numbered" must be a function',
|
|
38
51
|
typeof queryFunction === 'function'
|
|
39
52
|
);
|
|
40
|
-
this.
|
|
53
|
+
this.isControlled = true;
|
|
41
54
|
}
|
|
42
55
|
}
|
|
43
56
|
|
|
44
|
-
/**
|
|
45
|
-
* @param showLabels
|
|
46
|
-
* @type {boolean}
|
|
47
|
-
* @default true
|
|
48
|
-
* @description Show the labels for the "prev/next" controls
|
|
49
|
-
*/
|
|
50
|
-
get showLabels() {
|
|
51
|
-
let { showLabels = true } = this.args;
|
|
52
|
-
|
|
53
|
-
return showLabels;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
57
|
/**
|
|
57
58
|
* @param ariaLabel
|
|
58
59
|
* @type {string}
|
|
@@ -62,6 +63,35 @@ export default class HdsPaginationCompactIndexComponent extends Component {
|
|
|
62
63
|
return this.args.ariaLabel ?? 'Pagination';
|
|
63
64
|
}
|
|
64
65
|
|
|
66
|
+
// This very specific `get/set` pattern is used to handle the two different use cases of the component
|
|
67
|
+
// being "controlled" (when it has routing, meaning it needs to support pagination controls as links/`LinkTo`)
|
|
68
|
+
// vs being "uncontrolled" (see comments above for details).
|
|
69
|
+
//
|
|
70
|
+
// If it has routing (and so it's "controlled"), than the value ("state") of the `currentPageSize` variable
|
|
71
|
+
// is *always* determined by the controller via arguments (most of the times, connected to query parameters in the URL).
|
|
72
|
+
// For this reason the "get" method always returns the value from the `args`,
|
|
73
|
+
// while the "set" method never updates the private internal state (_variable).
|
|
74
|
+
//
|
|
75
|
+
// If instead it doesn't have routing (and so it's "uncontrolled") than the value ("state") of the `currentPageSize` variables
|
|
76
|
+
// is *always* determined by the component's internal logic (and updated according to the user interaction with it).
|
|
77
|
+
// For this reason the "get" and "set" methods always read from or write to the private internal state (_variable).
|
|
78
|
+
|
|
79
|
+
get currentPageSize() {
|
|
80
|
+
if (this.isControlled) {
|
|
81
|
+
return this.args.currentPageSize;
|
|
82
|
+
} else {
|
|
83
|
+
return this._currentPageSize;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
set currentPageSize(value) {
|
|
88
|
+
if (this.isControlled) {
|
|
89
|
+
// noop
|
|
90
|
+
} else {
|
|
91
|
+
this._currentPageSize = value;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
65
95
|
/**
|
|
66
96
|
* @param pageSizes
|
|
67
97
|
* @type {array of numbers}
|
|
@@ -83,9 +113,9 @@ export default class HdsPaginationCompactIndexComponent extends Component {
|
|
|
83
113
|
return this.router.currentRoute?.queryParams || {};
|
|
84
114
|
}
|
|
85
115
|
|
|
86
|
-
buildQueryParamsObject(page) {
|
|
87
|
-
if (this.
|
|
88
|
-
return this.args.queryFunction(page,
|
|
116
|
+
buildQueryParamsObject(page, pageSize) {
|
|
117
|
+
if (this.isControlled) {
|
|
118
|
+
return this.args.queryFunction(page, pageSize);
|
|
89
119
|
} else {
|
|
90
120
|
return {};
|
|
91
121
|
}
|
|
@@ -100,9 +130,15 @@ export default class HdsPaginationCompactIndexComponent extends Component {
|
|
|
100
130
|
};
|
|
101
131
|
|
|
102
132
|
// the "query" is dynamic and needs to be calculated
|
|
103
|
-
if (this.
|
|
104
|
-
routing.queryPrev = this.buildQueryParamsObject(
|
|
105
|
-
|
|
133
|
+
if (this.isControlled) {
|
|
134
|
+
routing.queryPrev = this.buildQueryParamsObject(
|
|
135
|
+
'prev',
|
|
136
|
+
this.currentPageSize
|
|
137
|
+
);
|
|
138
|
+
routing.queryNext = this.buildQueryParamsObject(
|
|
139
|
+
'next',
|
|
140
|
+
this.currentPageSize
|
|
141
|
+
);
|
|
106
142
|
} else {
|
|
107
143
|
routing.queryPrev = undefined;
|
|
108
144
|
routing.queryNext = undefined;
|
|
@@ -121,4 +157,23 @@ export default class HdsPaginationCompactIndexComponent extends Component {
|
|
|
121
157
|
onPageChange(newPage);
|
|
122
158
|
}
|
|
123
159
|
}
|
|
160
|
+
|
|
161
|
+
@action
|
|
162
|
+
onPageSizeChange(newPageSize) {
|
|
163
|
+
let { onPageSizeChange } = this.args;
|
|
164
|
+
|
|
165
|
+
// we need to manually update the query parameters in the route (it's not a link!)
|
|
166
|
+
if (this.isControlled) {
|
|
167
|
+
// we pass `null` as value for the `page` argument, so consumers can handle this condition accordingly (probably will just change the side of the data/array slice)
|
|
168
|
+
const queryParams = this.buildQueryParamsObject(null, newPageSize);
|
|
169
|
+
this.router.transitionTo({ queryParams });
|
|
170
|
+
} else {
|
|
171
|
+
this.currentPageSize = newPageSize;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// invoke the callback function
|
|
175
|
+
if (typeof onPageSizeChange === 'function') {
|
|
176
|
+
onPageSizeChange(newPageSize);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
124
179
|
}
|
|
@@ -85,6 +85,7 @@ export default class HdsPaginationNumberedIndexComponent extends Component {
|
|
|
85
85
|
// has with the component (the state is controlled externally, eg. via query parameters)
|
|
86
86
|
@tracked _currentPage = this.args.currentPage ?? 1;
|
|
87
87
|
@tracked _currentPageSize = this.args.currentPageSize ?? this.pageSizes[0];
|
|
88
|
+
@tracked isControlled;
|
|
88
89
|
|
|
89
90
|
showInfo = this.args.showInfo ?? true; // if the "info" block is visible
|
|
90
91
|
showLabels = this.args.showLabels ?? false; // if the labels for the "prev/next" controls are visible
|
|
@@ -107,7 +108,7 @@ export default class HdsPaginationNumberedIndexComponent extends Component {
|
|
|
107
108
|
// initialized and updated using the arguments passed to it.
|
|
108
109
|
|
|
109
110
|
if (queryFunction === undefined) {
|
|
110
|
-
this.
|
|
111
|
+
this.isControlled = false;
|
|
111
112
|
} else {
|
|
112
113
|
assert(
|
|
113
114
|
'@queryFunction for "Hds::Pagination::Numbered" must be a function',
|
|
@@ -118,7 +119,7 @@ export default class HdsPaginationNumberedIndexComponent extends Component {
|
|
|
118
119
|
typeof this.args.currentPageSize === 'number' &&
|
|
119
120
|
typeof this.args.currentPage === 'number'
|
|
120
121
|
);
|
|
121
|
-
this.
|
|
122
|
+
this.isControlled = true;
|
|
122
123
|
}
|
|
123
124
|
|
|
124
125
|
assert(
|
|
@@ -137,7 +138,7 @@ export default class HdsPaginationNumberedIndexComponent extends Component {
|
|
|
137
138
|
}
|
|
138
139
|
|
|
139
140
|
// This very specific `get/set` pattern is used to handle the two different use cases of the component
|
|
140
|
-
// being "controlled" (when it has routing, meaning it needs to support
|
|
141
|
+
// being "controlled" (when it has routing, meaning it needs to support pagination controls as links/`LinkTo`)
|
|
141
142
|
// vs being "uncontrolled" (see comments above for details).
|
|
142
143
|
//
|
|
143
144
|
// If it has routing (and so it's "controlled"), than the value ("state") of the `currentPage/currentPageSize` variables
|
|
@@ -150,7 +151,7 @@ export default class HdsPaginationNumberedIndexComponent extends Component {
|
|
|
150
151
|
// For this reason the "get" and "set" methods always read from or write to the private internal state (_variable).
|
|
151
152
|
|
|
152
153
|
get currentPage() {
|
|
153
|
-
if (this.
|
|
154
|
+
if (this.isControlled) {
|
|
154
155
|
return this.args.currentPage;
|
|
155
156
|
} else {
|
|
156
157
|
return this._currentPage;
|
|
@@ -158,7 +159,7 @@ export default class HdsPaginationNumberedIndexComponent extends Component {
|
|
|
158
159
|
}
|
|
159
160
|
|
|
160
161
|
set currentPage(value) {
|
|
161
|
-
if (this.
|
|
162
|
+
if (this.isControlled) {
|
|
162
163
|
// noop
|
|
163
164
|
} else {
|
|
164
165
|
this._currentPage = value;
|
|
@@ -166,7 +167,7 @@ export default class HdsPaginationNumberedIndexComponent extends Component {
|
|
|
166
167
|
}
|
|
167
168
|
|
|
168
169
|
get currentPageSize() {
|
|
169
|
-
if (this.
|
|
170
|
+
if (this.isControlled) {
|
|
170
171
|
return this.args.currentPageSize;
|
|
171
172
|
} else {
|
|
172
173
|
return this._currentPageSize;
|
|
@@ -174,7 +175,7 @@ export default class HdsPaginationNumberedIndexComponent extends Component {
|
|
|
174
175
|
}
|
|
175
176
|
|
|
176
177
|
set currentPageSize(value) {
|
|
177
|
-
if (this.
|
|
178
|
+
if (this.isControlled) {
|
|
178
179
|
// noop
|
|
179
180
|
} else {
|
|
180
181
|
this._currentPageSize = value;
|
|
@@ -242,7 +243,7 @@ export default class HdsPaginationNumberedIndexComponent extends Component {
|
|
|
242
243
|
}
|
|
243
244
|
|
|
244
245
|
buildQueryParamsObject(page, pageSize) {
|
|
245
|
-
if (this.
|
|
246
|
+
if (this.isControlled) {
|
|
246
247
|
return this.args.queryFunction(page, pageSize);
|
|
247
248
|
} else {
|
|
248
249
|
return {};
|
|
@@ -258,7 +259,7 @@ export default class HdsPaginationNumberedIndexComponent extends Component {
|
|
|
258
259
|
};
|
|
259
260
|
|
|
260
261
|
// the "query" is dynamic and needs to be calculated
|
|
261
|
-
if (this.
|
|
262
|
+
if (this.isControlled) {
|
|
262
263
|
routing.queryPrev = this.buildQueryParamsObject(
|
|
263
264
|
this.currentPage - 1,
|
|
264
265
|
this.currentPageSize
|
|
@@ -323,10 +324,9 @@ export default class HdsPaginationNumberedIndexComponent extends Component {
|
|
|
323
324
|
let { onPageSizeChange } = this.args;
|
|
324
325
|
|
|
325
326
|
// we need to manually update the query parameters in the route (it's not a link!)
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
queryParams = this.buildQueryParamsObject(1, newPageSize);
|
|
327
|
+
if (this.isControlled) {
|
|
328
|
+
// notice: we agreed to reset the pagination to the first element (any alternative would result in an unpredictable UX)
|
|
329
|
+
const queryParams = this.buildQueryParamsObject(1, newPageSize);
|
|
330
330
|
this.router.transitionTo({ queryParams });
|
|
331
331
|
} else {
|
|
332
332
|
this.currentPage = 1;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import Component from '@glimmer/component';
|
|
7
7
|
import { tracked } from '@glimmer/tracking';
|
|
8
8
|
import { action } from '@ember/object';
|
|
9
|
-
import { assert } from '@ember/debug';
|
|
9
|
+
import { assert, warn } from '@ember/debug';
|
|
10
10
|
import { next, schedule } from '@ember/runloop';
|
|
11
11
|
|
|
12
12
|
export default class HdsTabsIndexComponent extends Component {
|
|
@@ -188,13 +188,23 @@ export default class HdsTabsIndexComponent extends Component {
|
|
|
188
188
|
);
|
|
189
189
|
}
|
|
190
190
|
} else {
|
|
191
|
-
|
|
192
|
-
|
|
191
|
+
let message;
|
|
192
|
+
message +=
|
|
193
|
+
'"Hds::Tabs" has tried to set the indicator for an element that doesn\'t exist';
|
|
194
|
+
if (this.tabNodes.length === 0) {
|
|
195
|
+
message +=
|
|
196
|
+
' (the array `this.tabNodes` is empty, there are no tabs, probably already destroyed)';
|
|
197
|
+
} else {
|
|
198
|
+
message += ` (the value ${
|
|
193
199
|
this.selectedTabIndex
|
|
194
|
-
} of \`this.selectedTabIndex\` is out of bound for the array \`this.tabNodes\`, whose index range is [0
|
|
200
|
+
} of \`this.selectedTabIndex\` is out of bound for the array \`this.tabNodes\`, whose index range is [0 - ${
|
|
195
201
|
this.tabNodes.length - 1
|
|
196
|
-
}])
|
|
197
|
-
|
|
202
|
+
}])`;
|
|
203
|
+
}
|
|
204
|
+
// https://api.emberjs.com/ember/5.3/classes/@ember%2Fdebug/methods/warn?anchor=warn
|
|
205
|
+
warn(message, true, {
|
|
206
|
+
id: 'hds-debug.tabs.setTabIndicator-tabElem-not-available',
|
|
207
|
+
});
|
|
198
208
|
}
|
|
199
209
|
});
|
|
200
210
|
}
|