@refinitiv-ui/elements 5.12.0-dev.0 → 5.12.0
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 +24 -0
- package/lib/collapse/custom-elements.json +4 -2
- package/lib/collapse/custom-elements.md +1 -1
- package/lib/collapse/index.d.ts +20 -16
- package/lib/collapse/index.js +78 -48
- package/lib/collapse/themes/halo/dark/index.js +1 -1
- package/lib/collapse/themes/halo/light/index.js +1 -1
- package/lib/collapse/themes/solar/charcoal/index.js +1 -1
- package/lib/collapse/themes/solar/pearl/index.js +1 -1
- package/lib/dialog/custom-elements.json +11 -0
- package/lib/dialog/custom-elements.md +4 -3
- package/lib/dialog/index.d.ts +17 -0
- package/lib/dialog/index.js +30 -5
- package/lib/radio-button/index.d.ts +2 -2
- package/lib/radio-button/index.js +3 -3
- package/lib/slider/index.js +10 -0
- package/lib/tab/custom-elements.json +13 -0
- package/lib/tab/custom-elements.md +1 -0
- package/lib/tab/index.d.ts +32 -14
- package/lib/tab/index.js +61 -33
- package/lib/tab-bar/custom-elements.json +12 -0
- package/lib/tab-bar/custom-elements.md +7 -0
- package/lib/tab-bar/index.d.ts +97 -7
- package/lib/tab-bar/index.js +247 -37
- package/lib/version.js +1 -1
- package/package.json +12 -20
package/lib/tab-bar/index.js
CHANGED
|
@@ -5,14 +5,18 @@ import { property } from '@refinitiv-ui/core/lib/decorators/property.js';
|
|
|
5
5
|
import { query } from '@refinitiv-ui/core/lib/decorators/query.js';
|
|
6
6
|
import { VERSION } from '../version.js';
|
|
7
7
|
import { tweenAnimate } from './helpers/animate.js';
|
|
8
|
+
import { Tab } from '../tab/index.js';
|
|
8
9
|
import '../button/index.js';
|
|
9
10
|
const BAR_TRAVEL_DISTANCE = 150; // scroll distance
|
|
10
11
|
/**
|
|
11
12
|
* Container for tabs
|
|
13
|
+
*
|
|
14
|
+
* @fires value-changed - Fired when the `value` changes.
|
|
12
15
|
*/
|
|
13
16
|
let TabBar = class TabBar extends ResponsiveElement {
|
|
14
17
|
constructor() {
|
|
15
18
|
super(...arguments);
|
|
19
|
+
this.defaultRole = 'tablist';
|
|
16
20
|
/**
|
|
17
21
|
* Specify tab's horizontal alignment
|
|
18
22
|
*/
|
|
@@ -25,6 +29,11 @@ let TabBar = class TabBar extends ResponsiveElement {
|
|
|
25
29
|
* Use to switch from horizontal to vertical layout.
|
|
26
30
|
*/
|
|
27
31
|
this.vertical = false;
|
|
32
|
+
/**
|
|
33
|
+
* Internal value of tab bar.
|
|
34
|
+
* Controlled by public setter and getter
|
|
35
|
+
*/
|
|
36
|
+
this._value = '';
|
|
28
37
|
}
|
|
29
38
|
/**
|
|
30
39
|
* Element version number
|
|
@@ -52,6 +61,23 @@ let TabBar = class TabBar extends ResponsiveElement {
|
|
|
52
61
|
}
|
|
53
62
|
`;
|
|
54
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Value of tab-bar, derived from value of an active tab.
|
|
66
|
+
* @param value Element value
|
|
67
|
+
* @default -
|
|
68
|
+
*/
|
|
69
|
+
set value(value) {
|
|
70
|
+
value = typeof value === 'string' ? value : String(value);
|
|
71
|
+
const oldValue = this._value;
|
|
72
|
+
if (value !== oldValue && this.isValidValue(value)) {
|
|
73
|
+
this._value = value;
|
|
74
|
+
this.activateTab(value);
|
|
75
|
+
this.requestUpdate('value', oldValue);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
get value() {
|
|
79
|
+
return this._value;
|
|
80
|
+
}
|
|
55
81
|
/**
|
|
56
82
|
* Called after the element’s DOM has been updated the first time.
|
|
57
83
|
* register scroll event on content element to toggle scroll button
|
|
@@ -68,6 +94,8 @@ let TabBar = class TabBar extends ResponsiveElement {
|
|
|
68
94
|
this.toggleScrollButton(this.content.clientWidth);
|
|
69
95
|
}, 66); // equal 15 fps for compatibility
|
|
70
96
|
});
|
|
97
|
+
this.addEventListener('tap', this.onTap);
|
|
98
|
+
this.addEventListener('keydown', this.onKeyDown);
|
|
71
99
|
}
|
|
72
100
|
/**
|
|
73
101
|
* Called when the element’s DOM has been updated and rendered
|
|
@@ -75,16 +103,9 @@ let TabBar = class TabBar extends ResponsiveElement {
|
|
|
75
103
|
* @returns {void}
|
|
76
104
|
*/
|
|
77
105
|
updated(changedProperties) {
|
|
78
|
-
/* istanbul ignore else */
|
|
79
106
|
if (changedProperties.has('level')) {
|
|
80
107
|
this.setLevel();
|
|
81
108
|
}
|
|
82
|
-
if (changedProperties.has('vertical')) {
|
|
83
|
-
// if tab bar changed from horizontal to vertical
|
|
84
|
-
if (this.vertical) {
|
|
85
|
-
this.hideScrollButtons();
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
109
|
super.updated(changedProperties);
|
|
89
110
|
}
|
|
90
111
|
/**
|
|
@@ -100,54 +121,132 @@ let TabBar = class TabBar extends ResponsiveElement {
|
|
|
100
121
|
}
|
|
101
122
|
}
|
|
102
123
|
/**
|
|
103
|
-
*
|
|
104
|
-
* @
|
|
124
|
+
* Return true if incoming value matches one of the existing tabs
|
|
125
|
+
* @param value Value to check
|
|
126
|
+
* @returns true if incoming value matches one of the existing tabs
|
|
105
127
|
*/
|
|
106
|
-
|
|
107
|
-
this.
|
|
108
|
-
this.
|
|
128
|
+
isValidValue(value) {
|
|
129
|
+
const tabList = this.getFocusableTabs();
|
|
130
|
+
return tabList.some(tab => this.getTabValue(tab) === value);
|
|
109
131
|
}
|
|
110
132
|
/**
|
|
111
|
-
*
|
|
112
|
-
* @param elementWidth width of element
|
|
133
|
+
* When the slot changes, set the level, toggle the scroll button, and set the value
|
|
113
134
|
* @returns {void}
|
|
114
135
|
*/
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
if (
|
|
136
|
+
onSlotChange() {
|
|
137
|
+
const tabList = this.getFocusableTabs();
|
|
138
|
+
if (tabList.length < 1) {
|
|
118
139
|
return;
|
|
119
140
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
141
|
+
this.setLevel();
|
|
142
|
+
// get tab value from active tab
|
|
143
|
+
const activeTab = tabList.find(tab => tab.active) || tabList[0];
|
|
144
|
+
if (activeTab) {
|
|
145
|
+
this.value = this.getTabValue(activeTab);
|
|
146
|
+
}
|
|
147
|
+
this.manageTabIndex();
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Mark tab as active
|
|
151
|
+
* @param value value of tab to select
|
|
152
|
+
* @returns {void}
|
|
153
|
+
*/
|
|
154
|
+
activateTab(value) {
|
|
155
|
+
if (!value) {
|
|
156
|
+
return;
|
|
123
157
|
}
|
|
124
|
-
|
|
125
|
-
|
|
158
|
+
let hasActiveTab = false;
|
|
159
|
+
const tabList = this.getTabElements(); // get all tab elements include disabled tab
|
|
160
|
+
tabList.forEach(tab => {
|
|
161
|
+
const tabValue = this.getTabValue(tab);
|
|
162
|
+
// only mark tab as active once
|
|
163
|
+
if (tabValue === value && !hasActiveTab && !tab.disabled) {
|
|
164
|
+
tab.active = true;
|
|
165
|
+
hasActiveTab = true;
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
tab.active = false;
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Set tab value and fires `tab-changed` event
|
|
174
|
+
* @param event - Event
|
|
175
|
+
* @returns {void}
|
|
176
|
+
*/
|
|
177
|
+
onTap(event) {
|
|
178
|
+
if (event.defaultPrevented) {
|
|
179
|
+
return;
|
|
126
180
|
}
|
|
127
|
-
|
|
128
|
-
if (
|
|
129
|
-
this.
|
|
181
|
+
const element = event.target;
|
|
182
|
+
if (element instanceof Tab) {
|
|
183
|
+
const tabValue = this.getTabValue(element);
|
|
184
|
+
if (tabValue !== this.value) {
|
|
185
|
+
this.value = this.getTabValue(element);
|
|
186
|
+
this.notifyPropertyChange('value', tabValue);
|
|
187
|
+
}
|
|
130
188
|
}
|
|
131
|
-
|
|
132
|
-
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Get the value of a tab
|
|
192
|
+
* @param tab - The tab element.
|
|
193
|
+
* @returns The value of the tab.
|
|
194
|
+
*/
|
|
195
|
+
getTabValue(tab) {
|
|
196
|
+
return tab.value || (tab.hasAttribute('value') ? '' : this.getTabLabel(tab));
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Return the tab's label, or its textContent, or an empty string
|
|
200
|
+
* @param tab - The tab element.
|
|
201
|
+
* @returns The tab label.
|
|
202
|
+
*/
|
|
203
|
+
getTabLabel(tab) {
|
|
204
|
+
return tab.label || tab.textContent || '';
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Get Tab elements from slot
|
|
208
|
+
* @returns the array of Tab
|
|
209
|
+
*/
|
|
210
|
+
getTabElements() {
|
|
211
|
+
const tabs = [];
|
|
212
|
+
for (const child of this.children) {
|
|
213
|
+
if (child instanceof Tab) {
|
|
214
|
+
tabs.push(child);
|
|
215
|
+
}
|
|
133
216
|
}
|
|
217
|
+
return tabs;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Get focusable tab elements
|
|
221
|
+
* @returns the array of focusable tab
|
|
222
|
+
*/
|
|
223
|
+
getFocusableTabs() {
|
|
224
|
+
return this.getTabElements().filter(tab => !tab.disabled);
|
|
134
225
|
}
|
|
135
226
|
/**
|
|
136
227
|
* Set tab level attribute accordingly
|
|
137
228
|
* @returns {void}
|
|
138
229
|
*/
|
|
139
230
|
setLevel() {
|
|
140
|
-
const tabList = this.
|
|
141
|
-
tabList.forEach((tab) => {
|
|
231
|
+
const tabList = this.getTabElements(); // get all tab elements include disabled tab
|
|
232
|
+
tabList === null || tabList === void 0 ? void 0 : tabList.forEach((tab) => {
|
|
142
233
|
tab.level = this.level;
|
|
143
234
|
});
|
|
144
235
|
}
|
|
145
236
|
/**
|
|
146
|
-
*
|
|
237
|
+
* Hide/Show scroll button when element is overflow.
|
|
238
|
+
* @param elementWidth width of element
|
|
147
239
|
* @returns {void}
|
|
148
240
|
*/
|
|
149
|
-
|
|
150
|
-
this.
|
|
241
|
+
toggleScrollButton(elementWidth) {
|
|
242
|
+
if (this.vertical) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const { scrollLeft, scrollWidth } = this.content;
|
|
246
|
+
const leftBtnStyle = scrollLeft > 0 ? 'flex' : 'none';
|
|
247
|
+
const rightBtnStyle = scrollWidth - scrollLeft - elementWidth > 1 ? 'flex' : 'none';
|
|
248
|
+
this.leftBtn.style.setProperty('display', leftBtnStyle);
|
|
249
|
+
this.rightBtn.style.setProperty('display', rightBtnStyle);
|
|
151
250
|
}
|
|
152
251
|
/**
|
|
153
252
|
* Update scroll position when clicked on left button
|
|
@@ -177,6 +276,114 @@ let TabBar = class TabBar extends ResponsiveElement {
|
|
|
177
276
|
}
|
|
178
277
|
tweenAnimate({ target: this.content, startPosition: scrollLeft, endPosition });
|
|
179
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* Focus and set active to tab
|
|
281
|
+
* @param tab - The element that was clicked.
|
|
282
|
+
* @return {void}
|
|
283
|
+
*/
|
|
284
|
+
focusAndSetActiveTab(tab) {
|
|
285
|
+
tab.focus();
|
|
286
|
+
tab.scrollIntoView({ block: 'nearest' });
|
|
287
|
+
this.value = this.getTabValue(tab);
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Navigate to first focusable tab of the tab bar
|
|
291
|
+
* @returns {void}
|
|
292
|
+
*/
|
|
293
|
+
first() {
|
|
294
|
+
const tabList = this.getFocusableTabs();
|
|
295
|
+
if (tabList.length <= 0) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
this.focusAndSetActiveTab(tabList[0]);
|
|
299
|
+
this.rovingTabIndex(tabList[0], tabList);
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Navigate to last focusable tab of the tab bar
|
|
303
|
+
* @returns {void}
|
|
304
|
+
*/
|
|
305
|
+
last() {
|
|
306
|
+
const tabList = this.getFocusableTabs();
|
|
307
|
+
if (tabList.length <= 0) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
const lastTab = tabList[tabList.length - 1];
|
|
311
|
+
this.focusAndSetActiveTab(lastTab);
|
|
312
|
+
this.rovingTabIndex(lastTab, tabList);
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Navigate to next or previous focusable tab
|
|
316
|
+
* @param direction up/next; down/previous
|
|
317
|
+
* @returns {void}
|
|
318
|
+
*/
|
|
319
|
+
navigateToSibling(direction) {
|
|
320
|
+
const tabList = this.getFocusableTabs();
|
|
321
|
+
if (tabList.length <= 0) {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
const focusedTabIndex = tabList.findIndex(tab => tab === document.activeElement);
|
|
325
|
+
const nextTab = direction === 'next'
|
|
326
|
+
? tabList[focusedTabIndex + 1] || tabList[0]
|
|
327
|
+
: tabList[focusedTabIndex - 1] || tabList[tabList.length - 1];
|
|
328
|
+
this.focusAndSetActiveTab(nextTab);
|
|
329
|
+
this.rovingTabIndex(nextTab, tabList);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Handles key down event
|
|
333
|
+
* @param event Key down event object
|
|
334
|
+
* @returns {void}
|
|
335
|
+
*/
|
|
336
|
+
onKeyDown(event) {
|
|
337
|
+
if (event.defaultPrevented) {
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
switch (event.key) {
|
|
341
|
+
case 'Right':
|
|
342
|
+
case 'Down':
|
|
343
|
+
case 'ArrowRight':
|
|
344
|
+
case 'ArrowDown':
|
|
345
|
+
this.navigateToSibling('next');
|
|
346
|
+
break;
|
|
347
|
+
case 'Left':
|
|
348
|
+
case 'Up':
|
|
349
|
+
case 'ArrowLeft':
|
|
350
|
+
case 'ArrowUp':
|
|
351
|
+
this.navigateToSibling('previous');
|
|
352
|
+
break;
|
|
353
|
+
case 'Home':
|
|
354
|
+
this.first();
|
|
355
|
+
break;
|
|
356
|
+
case 'End':
|
|
357
|
+
this.last();
|
|
358
|
+
break;
|
|
359
|
+
default:
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
event.preventDefault();
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Sets the tabindex to -1 for all tabs except the active tab.
|
|
366
|
+
* @param target the tab to be focused
|
|
367
|
+
* @param tabList Array of tabs that contains target
|
|
368
|
+
* @returns {void}
|
|
369
|
+
*/
|
|
370
|
+
rovingTabIndex(target, tabList) {
|
|
371
|
+
tabList.forEach((tab) => {
|
|
372
|
+
tab.tabIndex = -1;
|
|
373
|
+
});
|
|
374
|
+
target.tabIndex = 0;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Set tabIndex to all tabs
|
|
378
|
+
* @returns {void}
|
|
379
|
+
*/
|
|
380
|
+
manageTabIndex() {
|
|
381
|
+
const tabList = this.getFocusableTabs();
|
|
382
|
+
if (tabList && tabList.length > 0) {
|
|
383
|
+
const focusedTabIndex = tabList.findIndex(tab => tab.active);
|
|
384
|
+
this.rovingTabIndex(tabList[focusedTabIndex], tabList);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
180
387
|
/**
|
|
181
388
|
* A `TemplateResult` that will be used
|
|
182
389
|
* to render the updated internal template.
|
|
@@ -184,11 +391,11 @@ let TabBar = class TabBar extends ResponsiveElement {
|
|
|
184
391
|
*/
|
|
185
392
|
render() {
|
|
186
393
|
return html `
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
394
|
+
${!this.vertical ? html `<ef-button tabIndex="-1" icon="left" part="left-btn" @tap=${this.handleScrollLeft}></ef-button>` : null}
|
|
395
|
+
<div part="content">
|
|
396
|
+
<slot @slotchange=${this.onSlotChange}></slot>
|
|
397
|
+
</div>
|
|
398
|
+
${!this.vertical ? html `<ef-button tabIndex="-1" icon="right" part="right-btn" @tap=${this.handleScrollRight}></ef-button>` : null}
|
|
192
399
|
`;
|
|
193
400
|
}
|
|
194
401
|
};
|
|
@@ -201,6 +408,9 @@ __decorate([
|
|
|
201
408
|
__decorate([
|
|
202
409
|
property({ type: Boolean, reflect: true })
|
|
203
410
|
], TabBar.prototype, "vertical", void 0);
|
|
411
|
+
__decorate([
|
|
412
|
+
property({ type: String, attribute: false })
|
|
413
|
+
], TabBar.prototype, "value", null);
|
|
204
414
|
__decorate([
|
|
205
415
|
query('[part="content"')
|
|
206
416
|
], TabBar.prototype, "content", void 0);
|
package/lib/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '5.12.0
|
|
1
|
+
export const VERSION = '5.12.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@refinitiv-ui/elements",
|
|
3
|
-
"version": "5.12.0
|
|
3
|
+
"version": "5.12.0",
|
|
4
4
|
"description": "Element Framework Elements",
|
|
5
5
|
"author": "Refinitiv",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -590,13 +590,17 @@
|
|
|
590
590
|
"lint": "node cli lint",
|
|
591
591
|
"lint:fix": "node cli lint --fix",
|
|
592
592
|
"prepublishOnly": "node scripts/release",
|
|
593
|
-
"api-analyzer": "node ../../scripts/release/api-analyzer.js"
|
|
594
|
-
"version": "node ../../scripts/version"
|
|
593
|
+
"api-analyzer": "node ../../scripts/release/api-analyzer.js"
|
|
595
594
|
},
|
|
596
595
|
"dependencies": {
|
|
597
596
|
"@refinitiv-ui/browser-sparkline": "1.1.7",
|
|
598
|
-
"@refinitiv-ui/
|
|
599
|
-
"@refinitiv-ui/
|
|
597
|
+
"@refinitiv-ui/core": "^5.4.1",
|
|
598
|
+
"@refinitiv-ui/halo-theme": "^5.5.0",
|
|
599
|
+
"@refinitiv-ui/i18n": "^5.2.6",
|
|
600
|
+
"@refinitiv-ui/phrasebook": "^5.4.1",
|
|
601
|
+
"@refinitiv-ui/solar-theme": "^5.7.0",
|
|
602
|
+
"@refinitiv-ui/translate": "^5.3.1",
|
|
603
|
+
"@refinitiv-ui/utils": "^5.1.2",
|
|
600
604
|
"@types/chart.js": "^2.9.31",
|
|
601
605
|
"chart.js": "~2.9.4",
|
|
602
606
|
"d3-interpolate": "^3.0.1",
|
|
@@ -605,24 +609,12 @@
|
|
|
605
609
|
"tslib": "^2.3.1"
|
|
606
610
|
},
|
|
607
611
|
"devDependencies": {
|
|
608
|
-
"@refinitiv-ui/
|
|
609
|
-
"@refinitiv-ui/
|
|
610
|
-
"@refinitiv-ui/i18n": "^5.2.7-dev.0",
|
|
611
|
-
"@refinitiv-ui/phrasebook": "^5.4.2-dev.0",
|
|
612
|
-
"@refinitiv-ui/test-helpers": "^5.1.3-dev.0",
|
|
613
|
-
"@refinitiv-ui/translate": "^5.3.1-dev.0",
|
|
614
|
-
"@refinitiv-ui/utils": "^5.1.2-dev.0",
|
|
612
|
+
"@refinitiv-ui/demo-block": "^5.1.8",
|
|
613
|
+
"@refinitiv-ui/test-helpers": "^5.1.2",
|
|
615
614
|
"@types/d3-interpolate": "^3.0.1"
|
|
616
615
|
},
|
|
617
|
-
"peerDependencies": {
|
|
618
|
-
"@refinitiv-ui/core": "^5.4.1-dev.0",
|
|
619
|
-
"@refinitiv-ui/i18n": "^5.2.7-dev.0",
|
|
620
|
-
"@refinitiv-ui/phrasebook": "^5.4.2-dev.0",
|
|
621
|
-
"@refinitiv-ui/translate": "^5.3.1-dev.0",
|
|
622
|
-
"@refinitiv-ui/utils": "^5.1.2-dev.0"
|
|
623
|
-
},
|
|
624
616
|
"publishConfig": {
|
|
625
617
|
"access": "public"
|
|
626
618
|
},
|
|
627
|
-
"gitHead": "
|
|
619
|
+
"gitHead": "5ee75ad2727753f4fc973377a008d6228de3aab9"
|
|
628
620
|
}
|