@vaadin/tabs 24.1.1 → 24.2.0-alpha1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/tabs",
3
- "version": "24.1.1",
3
+ "version": "24.2.0-alpha1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -36,12 +36,12 @@
36
36
  ],
37
37
  "dependencies": {
38
38
  "@polymer/polymer": "^3.0.0",
39
- "@vaadin/a11y-base": "~24.1.1",
40
- "@vaadin/component-base": "~24.1.1",
41
- "@vaadin/item": "~24.1.1",
42
- "@vaadin/vaadin-lumo-styles": "~24.1.1",
43
- "@vaadin/vaadin-material-styles": "~24.1.1",
44
- "@vaadin/vaadin-themable-mixin": "~24.1.1"
39
+ "@vaadin/a11y-base": "24.2.0-alpha1",
40
+ "@vaadin/component-base": "24.2.0-alpha1",
41
+ "@vaadin/item": "24.2.0-alpha1",
42
+ "@vaadin/vaadin-lumo-styles": "24.2.0-alpha1",
43
+ "@vaadin/vaadin-material-styles": "24.2.0-alpha1",
44
+ "@vaadin/vaadin-themable-mixin": "24.2.0-alpha1"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@esm-bundle/chai": "^4.3.4",
@@ -52,5 +52,5 @@
52
52
  "web-types.json",
53
53
  "web-types.lit.json"
54
54
  ],
55
- "gitHead": "c3a3d904885bd37ebb07a84b09617a340b4fab7e"
55
+ "gitHead": "0dbb118320203ab6c0c07450a3e718815367589f"
56
56
  }
@@ -28,7 +28,7 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
28
28
  * `active` | Set when mousedown or enter/spacebar pressed | :host
29
29
  * `orientation` | Set to `horizontal` or `vertical` depending on the direction of items | :host
30
30
  *
31
- * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
31
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
32
32
  */
33
33
  declare class Tab extends ElementMixin(ThemableMixin(ItemMixin(ControllerMixin(HTMLElement)))) {}
34
34
 
package/src/vaadin-tab.js CHANGED
@@ -30,7 +30,7 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
30
30
  * `active` | Set when mousedown or enter/spacebar pressed | :host
31
31
  * `orientation` | Set to `horizontal` or `vertical` depending on the direction of items | :host
32
32
  *
33
- * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
33
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
34
34
  *
35
35
  * @extends HTMLElement
36
36
  * @mixes ControllerMixin
@@ -57,7 +57,7 @@ export interface TabsEventMap extends HTMLElementEventMap, TabsCustomEventMap {}
57
57
  * `orientation` | Tabs disposition, valid values are `horizontal` and `vertical`. | :host
58
58
  * `overflow` | It's set to `start`, `end`, none or both. | :host
59
59
  *
60
- * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
60
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
61
61
  *
62
62
  * @fires {CustomEvent} items-changed - Fired when the `items` property changes.
63
63
  * @fires {CustomEvent} selected-changed - Fired when the `selected` property changes.
@@ -41,7 +41,7 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
41
41
  * `orientation` | Tabs disposition, valid values are `horizontal` and `vertical`. | :host
42
42
  * `overflow` | It's set to `start`, `end`, none or both. | :host
43
43
  *
44
- * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
44
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
45
45
  *
46
46
  * @fires {CustomEvent} items-changed - Fired when the `items` property changes.
47
47
  * @fires {CustomEvent} selected-changed - Fired when the `selected` property changes.
@@ -236,12 +236,90 @@ class Tabs extends ResizeMixin(ElementMixin(ListMixin(ThemableMixin(PolymerEleme
236
236
 
237
237
  /** @private */
238
238
  _scrollForward() {
239
- this._scroll(-this.__direction * this._scrollOffset);
239
+ // Calculations here are performed in order to optimize the loop that checks item visibility.
240
+ const forwardButtonVisibleWidth = this._getNavigationButtonVisibleWidth('forward-button');
241
+ const backButtonVisibleWidth = this._getNavigationButtonVisibleWidth('back-button');
242
+ const scrollerRect = this._scrollerElement.getBoundingClientRect();
243
+ const itemToScrollTo = [...this.items]
244
+ .reverse()
245
+ .find((item) => this._isItemVisible(item, forwardButtonVisibleWidth, backButtonVisibleWidth, scrollerRect));
246
+ const itemRect = itemToScrollTo.getBoundingClientRect();
247
+ // This hard-coded number accounts for the width of the mask that covers a part of the visible items.
248
+ // A CSS variable can be introduced to get rid of this value.
249
+ const overflowIndicatorCompensation = 20;
250
+ const totalCompensation =
251
+ overflowIndicatorCompensation + this.shadowRoot.querySelector('[part="back-button"]').clientWidth;
252
+ let scrollOffset;
253
+ if (this.__isRTL) {
254
+ const scrollerRightEdge = scrollerRect.right - totalCompensation;
255
+ scrollOffset = itemRect.right - scrollerRightEdge;
256
+ } else {
257
+ const scrollerLeftEdge = scrollerRect.left + totalCompensation;
258
+ scrollOffset = itemRect.left - scrollerLeftEdge;
259
+ }
260
+ // It is possible that a scroll offset is calculated to be between 0 and 1. In this case, this offset
261
+ // can be rounded down to zero, rendering the button useless. It is also possible that the offset is
262
+ // calculated such that it results in scrolling backwards for a wide tab or edge cases. This is a
263
+ // workaround for such cases.
264
+ if (-this.__direction * scrollOffset < 1) {
265
+ scrollOffset = -this.__direction * (this._scrollOffset - totalCompensation);
266
+ }
267
+ this._scroll(scrollOffset);
240
268
  }
241
269
 
242
270
  /** @private */
243
271
  _scrollBack() {
244
- this._scroll(this.__direction * this._scrollOffset);
272
+ // Calculations here are performed in order to optimize the loop that checks item visibility.
273
+ const forwardButtonVisibleWidth = this._getNavigationButtonVisibleWidth('forward-button');
274
+ const backButtonVisibleWidth = this._getNavigationButtonVisibleWidth('back-button');
275
+ const scrollerRect = this._scrollerElement.getBoundingClientRect();
276
+ const itemToScrollTo = this.items.find((item) =>
277
+ this._isItemVisible(item, forwardButtonVisibleWidth, backButtonVisibleWidth, scrollerRect),
278
+ );
279
+ const itemRect = itemToScrollTo.getBoundingClientRect();
280
+ // This hard-coded number accounts for the width of the mask that covers a part of the visible items.
281
+ // A CSS variable can be introduced to get rid of this value.
282
+ const overflowIndicatorCompensation = 20;
283
+ const totalCompensation =
284
+ overflowIndicatorCompensation + this.shadowRoot.querySelector('[part="forward-button"]').clientWidth;
285
+ let scrollOffset;
286
+ if (this.__isRTL) {
287
+ const scrollerLeftEdge = scrollerRect.left + totalCompensation;
288
+ scrollOffset = itemRect.left - scrollerLeftEdge;
289
+ } else {
290
+ const scrollerRightEdge = scrollerRect.right - totalCompensation;
291
+ scrollOffset = itemRect.right - scrollerRightEdge;
292
+ }
293
+ // It is possible that a scroll offset is calculated to be between 0 and 1. In this case, this offset
294
+ // can be rounded down to zero, rendering the button useless. It is also possible that the offset is
295
+ // calculated such that it results in scrolling forward for a wide tab or edge cases. This is a
296
+ // workaround for such cases.
297
+ if (this.__direction * scrollOffset < 1) {
298
+ scrollOffset = this.__direction * (this._scrollOffset - totalCompensation);
299
+ }
300
+ this._scroll(scrollOffset);
301
+ }
302
+
303
+ /** @private */
304
+ _isItemVisible(item, forwardButtonVisibleWidth, backButtonVisibleWidth, scrollerRect) {
305
+ if (this._vertical) {
306
+ throw new Error('Visibility check is only supported for horizontal tabs.');
307
+ }
308
+ const buttonOnTheRightWidth = this.__isRTL ? backButtonVisibleWidth : forwardButtonVisibleWidth;
309
+ const buttonOnTheLeftWidth = this.__isRTL ? forwardButtonVisibleWidth : backButtonVisibleWidth;
310
+ const scrollerRightEdge = scrollerRect.right - buttonOnTheRightWidth;
311
+ const scrollerLeftEdge = scrollerRect.left + buttonOnTheLeftWidth;
312
+ const itemRect = item.getBoundingClientRect();
313
+ return scrollerRightEdge > Math.floor(itemRect.left) && scrollerLeftEdge < Math.ceil(itemRect.right);
314
+ }
315
+
316
+ /** @private */
317
+ _getNavigationButtonVisibleWidth(buttonPartName) {
318
+ const navigationButton = this.shadowRoot.querySelector(`[part="${buttonPartName}"]`);
319
+ if (window.getComputedStyle(navigationButton).opacity === '0') {
320
+ return 0;
321
+ }
322
+ return navigationButton.clientWidth;
245
323
  }
246
324
 
247
325
  /** @private */
@@ -45,10 +45,7 @@ registerStyles(
45
45
  :host::before {
46
46
  content: '';
47
47
  position: absolute;
48
- top: 0;
49
- right: 0;
50
- bottom: 0;
51
- left: 0;
48
+ inset: 0;
52
49
  background-color: var(--material-primary-color);
53
50
  opacity: 0;
54
51
  transition: opacity 0.1s linear;
package/web-types.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/tabs",
4
- "version": "24.1.1",
4
+ "version": "24.2.0-alpha1",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
8
8
  "elements": [
9
9
  {
10
10
  "name": "vaadin-tab",
11
- "description": "`<vaadin-tab>` is a Web Component providing an accessible and customizable tab.\n\n```\n <vaadin-tab>\n Tab 1\n </vaadin-tab>\n```\n\nThe following state attributes are available for styling:\n\nAttribute | Description | Part name\n-----------|-------------|------------\n`disabled` | Set to a disabled tab | :host\n`focused` | Set when the element is focused | :host\n`focus-ring` | Set when the element is keyboard focused | :host\n`selected` | Set when the tab is selected | :host\n`active` | Set when mousedown or enter/spacebar pressed | :host\n`orientation` | Set to `horizontal` or `vertical` depending on the direction of items | :host\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
11
+ "description": "`<vaadin-tab>` is a Web Component providing an accessible and customizable tab.\n\n```\n <vaadin-tab>\n Tab 1\n </vaadin-tab>\n```\n\nThe following state attributes are available for styling:\n\nAttribute | Description | Part name\n-----------|-------------|------------\n`disabled` | Set to a disabled tab | :host\n`focused` | Set when the element is focused | :host\n`focus-ring` | Set when the element is keyboard focused | :host\n`selected` | Set when the tab is selected | :host\n`active` | Set when mousedown or enter/spacebar pressed | :host\n`orientation` | Set to `horizontal` or `vertical` depending on the direction of items | :host\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
12
12
  "attributes": [
13
13
  {
14
14
  "name": "selected",
@@ -57,7 +57,7 @@
57
57
  },
58
58
  {
59
59
  "name": "vaadin-tabs",
60
- "description": "`<vaadin-tabs>` is a Web Component for organizing and grouping content into sections.\n\n```\n <vaadin-tabs selected=\"4\">\n <vaadin-tab>Page 1</vaadin-tab>\n <vaadin-tab>Page 2</vaadin-tab>\n <vaadin-tab>Page 3</vaadin-tab>\n <vaadin-tab>Page 4</vaadin-tab>\n </vaadin-tabs>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n------------------|--------------------------------------\n`back-button` | Button for moving the scroll back\n`tabs` | The tabs container\n`forward-button` | Button for moving the scroll forward\n\nThe following state attributes are available for styling:\n\nAttribute | Description | Part name\n-----------|-------------|------------\n`orientation` | Tabs disposition, valid values are `horizontal` and `vertical`. | :host\n`overflow` | It's set to `start`, `end`, none or both. | :host\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
60
+ "description": "`<vaadin-tabs>` is a Web Component for organizing and grouping content into sections.\n\n```\n <vaadin-tabs selected=\"4\">\n <vaadin-tab>Page 1</vaadin-tab>\n <vaadin-tab>Page 2</vaadin-tab>\n <vaadin-tab>Page 3</vaadin-tab>\n <vaadin-tab>Page 4</vaadin-tab>\n </vaadin-tabs>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n------------------|--------------------------------------\n`back-button` | Button for moving the scroll back\n`tabs` | The tabs container\n`forward-button` | Button for moving the scroll forward\n\nThe following state attributes are available for styling:\n\nAttribute | Description | Part name\n-----------|-------------|------------\n`orientation` | Tabs disposition, valid values are `horizontal` and `vertical`. | :host\n`overflow` | It's set to `start`, `end`, none or both. | :host\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
61
61
  "attributes": [
62
62
  {
63
63
  "name": "disabled",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/tabs",
4
- "version": "24.1.1",
4
+ "version": "24.2.0-alpha1",
5
5
  "description-markup": "markdown",
6
6
  "framework": "lit",
7
7
  "framework-config": {
@@ -16,7 +16,7 @@
16
16
  "elements": [
17
17
  {
18
18
  "name": "vaadin-tab",
19
- "description": "`<vaadin-tab>` is a Web Component providing an accessible and customizable tab.\n\n```\n <vaadin-tab>\n Tab 1\n </vaadin-tab>\n```\n\nThe following state attributes are available for styling:\n\nAttribute | Description | Part name\n-----------|-------------|------------\n`disabled` | Set to a disabled tab | :host\n`focused` | Set when the element is focused | :host\n`focus-ring` | Set when the element is keyboard focused | :host\n`selected` | Set when the tab is selected | :host\n`active` | Set when mousedown or enter/spacebar pressed | :host\n`orientation` | Set to `horizontal` or `vertical` depending on the direction of items | :host\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
19
+ "description": "`<vaadin-tab>` is a Web Component providing an accessible and customizable tab.\n\n```\n <vaadin-tab>\n Tab 1\n </vaadin-tab>\n```\n\nThe following state attributes are available for styling:\n\nAttribute | Description | Part name\n-----------|-------------|------------\n`disabled` | Set to a disabled tab | :host\n`focused` | Set when the element is focused | :host\n`focus-ring` | Set when the element is keyboard focused | :host\n`selected` | Set when the tab is selected | :host\n`active` | Set when mousedown or enter/spacebar pressed | :host\n`orientation` | Set to `horizontal` or `vertical` depending on the direction of items | :host\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
20
20
  "extension": true,
21
21
  "attributes": [
22
22
  {
@@ -37,7 +37,7 @@
37
37
  },
38
38
  {
39
39
  "name": "vaadin-tabs",
40
- "description": "`<vaadin-tabs>` is a Web Component for organizing and grouping content into sections.\n\n```\n <vaadin-tabs selected=\"4\">\n <vaadin-tab>Page 1</vaadin-tab>\n <vaadin-tab>Page 2</vaadin-tab>\n <vaadin-tab>Page 3</vaadin-tab>\n <vaadin-tab>Page 4</vaadin-tab>\n </vaadin-tabs>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n------------------|--------------------------------------\n`back-button` | Button for moving the scroll back\n`tabs` | The tabs container\n`forward-button` | Button for moving the scroll forward\n\nThe following state attributes are available for styling:\n\nAttribute | Description | Part name\n-----------|-------------|------------\n`orientation` | Tabs disposition, valid values are `horizontal` and `vertical`. | :host\n`overflow` | It's set to `start`, `end`, none or both. | :host\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
40
+ "description": "`<vaadin-tabs>` is a Web Component for organizing and grouping content into sections.\n\n```\n <vaadin-tabs selected=\"4\">\n <vaadin-tab>Page 1</vaadin-tab>\n <vaadin-tab>Page 2</vaadin-tab>\n <vaadin-tab>Page 3</vaadin-tab>\n <vaadin-tab>Page 4</vaadin-tab>\n </vaadin-tabs>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n------------------|--------------------------------------\n`back-button` | Button for moving the scroll back\n`tabs` | The tabs container\n`forward-button` | Button for moving the scroll forward\n\nThe following state attributes are available for styling:\n\nAttribute | Description | Part name\n-----------|-------------|------------\n`orientation` | Tabs disposition, valid values are `horizontal` and `vertical`. | :host\n`overflow` | It's set to `start`, `end`, none or both. | :host\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
41
41
  "extension": true,
42
42
  "attributes": [
43
43
  {