@vaadin/button 24.6.5 → 24.7.0-alpha10

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/button",
3
- "version": "24.6.5",
3
+ "version": "24.7.0-alpha10",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -36,17 +36,17 @@
36
36
  "dependencies": {
37
37
  "@open-wc/dedupe-mixin": "^1.3.0",
38
38
  "@polymer/polymer": "^3.0.0",
39
- "@vaadin/a11y-base": "~24.6.5",
40
- "@vaadin/component-base": "~24.6.5",
41
- "@vaadin/vaadin-lumo-styles": "~24.6.5",
42
- "@vaadin/vaadin-material-styles": "~24.6.5",
43
- "@vaadin/vaadin-themable-mixin": "~24.6.5",
39
+ "@vaadin/a11y-base": "24.7.0-alpha10",
40
+ "@vaadin/component-base": "24.7.0-alpha10",
41
+ "@vaadin/vaadin-lumo-styles": "24.7.0-alpha10",
42
+ "@vaadin/vaadin-material-styles": "24.7.0-alpha10",
43
+ "@vaadin/vaadin-themable-mixin": "24.7.0-alpha10",
44
44
  "lit": "^3.0.0"
45
45
  },
46
46
  "devDependencies": {
47
- "@vaadin/chai-plugins": "~24.6.5",
48
- "@vaadin/icon": "~24.6.5",
49
- "@vaadin/test-runner-commands": "~24.6.5",
47
+ "@vaadin/chai-plugins": "24.7.0-alpha10",
48
+ "@vaadin/icon": "24.7.0-alpha10",
49
+ "@vaadin/test-runner-commands": "24.7.0-alpha10",
50
50
  "@vaadin/testing-helpers": "^1.1.0",
51
51
  "sinon": "^18.0.0"
52
52
  },
@@ -54,5 +54,5 @@
54
54
  "web-types.json",
55
55
  "web-types.lit.json"
56
56
  ],
57
- "gitHead": "fc109a4234a1f60e89717ab1c0dc8fb4451aa418"
57
+ "gitHead": "c0f8933df2a6a40648d3fb9cfbae6bbf86a8aa90"
58
58
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2017 - 2024 Vaadin Ltd.
3
+ * Copyright (c) 2017 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import type { CSSResult, TemplateResult } from 'lit';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2017 - 2024 Vaadin Ltd.
3
+ * Copyright (c) 2017 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { css } from 'lit';
@@ -12,7 +12,6 @@ export const buttonStyles = css`
12
12
  outline: none;
13
13
  white-space: nowrap;
14
14
  -webkit-user-select: none;
15
- -moz-user-select: none;
16
15
  user-select: none;
17
16
  }
18
17
 
@@ -20,6 +19,11 @@ export const buttonStyles = css`
20
19
  display: none !important;
21
20
  }
22
21
 
22
+ :host([disabled]) {
23
+ pointer-events: var(--_vaadin-button-disabled-pointer-events, none);
24
+ cursor: not-allowed;
25
+ }
26
+
23
27
  /* Aligns the button with form fields when placed on the same line.
24
28
  Note, to make it work, the form fields should have the same "::before" pseudo-element. */
25
29
  .vaadin-button-container::before {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2017 - 2024 Vaadin Ltd.
3
+ * Copyright (c) 2017 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import type { Constructor } from '@open-wc/dedupe-mixin';
@@ -1,12 +1,14 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2017 - 2024 Vaadin Ltd.
3
+ * Copyright (c) 2017 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { ActiveMixin } from '@vaadin/a11y-base/src/active-mixin.js';
7
7
  import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
8
8
  import { TabindexMixin } from '@vaadin/a11y-base/src/tabindex-mixin.js';
9
9
 
10
+ const INTERACTION_EVENTS = ['mousedown', 'mouseup', 'click', 'dblclick', 'keypress', 'keydown', 'keyup'];
11
+
10
12
  /**
11
13
  * A mixin providing common button functionality.
12
14
  *
@@ -17,20 +19,17 @@ import { TabindexMixin } from '@vaadin/a11y-base/src/tabindex-mixin.js';
17
19
  */
18
20
  export const ButtonMixin = (superClass) =>
19
21
  class ButtonMixinClass extends ActiveMixin(TabindexMixin(FocusMixin(superClass))) {
20
- static get properties() {
21
- return {
22
- /**
23
- * Indicates whether the element can be focused and where it participates in sequential keyboard navigation.
24
- *
25
- * @override
26
- * @protected
27
- */
28
- tabindex: {
29
- type: Number,
30
- value: 0,
31
- reflectToAttribute: true,
32
- },
33
- };
22
+ constructor() {
23
+ super();
24
+
25
+ this.__onInteractionEvent = this.__onInteractionEvent.bind(this);
26
+
27
+ INTERACTION_EVENTS.forEach((eventType) => {
28
+ this.addEventListener(eventType, this.__onInteractionEvent, true);
29
+ });
30
+
31
+ // Set tabindex to 0 by default
32
+ this.tabindex = 0;
34
33
  }
35
34
 
36
35
  /**
@@ -54,6 +53,10 @@ export const ButtonMixin = (superClass) =>
54
53
  if (!this.hasAttribute('role')) {
55
54
  this.setAttribute('role', 'button');
56
55
  }
56
+
57
+ if (this.__shouldAllowFocusWhenDisabled()) {
58
+ this.style.setProperty('--_vaadin-button-disabled-pointer-events', 'auto');
59
+ }
57
60
  }
58
61
 
59
62
  /**
@@ -86,4 +89,21 @@ export const ButtonMixin = (superClass) =>
86
89
  this.click();
87
90
  }
88
91
  }
92
+
93
+ /** @private */
94
+ __onInteractionEvent(event) {
95
+ if (this.__shouldSuppressInteractionEvent(event)) {
96
+ event.stopImmediatePropagation();
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Returns whether to suppress interaction events like `click`, `keydown`, etc.
102
+ * By default suppresses all interaction events when the button is disabled.
103
+ *
104
+ * @private
105
+ */
106
+ __shouldSuppressInteractionEvent(_event) {
107
+ return this.disabled;
108
+ }
89
109
  };
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2017 - 2024 Vaadin Ltd.
3
+ * Copyright (c) 2017 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
@@ -36,7 +36,26 @@ import { ButtonMixin } from './vaadin-button-mixin.js';
36
36
  *
37
37
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
38
38
  */
39
- declare class Button extends ButtonMixin(ElementMixin(ThemableMixin(ControllerMixin(HTMLElement)))) {}
39
+ declare class Button extends ButtonMixin(ElementMixin(ThemableMixin(ControllerMixin(HTMLElement)))) {
40
+ /**
41
+ * When disabled, the button is rendered as "dimmed" and prevents all
42
+ * user interactions (mouse and keyboard).
43
+ *
44
+ * Since disabled buttons are not focusable and cannot react to hover
45
+ * events by default, it can cause accessibility issues by making them
46
+ * entirely invisible to assistive technologies, and prevents the use
47
+ * of Tooltips to explain why the action is not available. This can be
48
+ * addressed by enabling the feature flag `accessibleDisabledButtons`,
49
+ * which makes disabled buttons focusable and hoverable, while still
50
+ * preventing them from being triggered:
51
+ *
52
+ * ```
53
+ * // Set before any button is attached to the DOM.
54
+ * window.Vaadin.featureFlags.accessibleDisabledButtons = true
55
+ * ```
56
+ */
57
+ disabled: boolean;
58
+ }
40
59
 
41
60
  declare global {
42
61
  interface HTMLElementTagNameMap {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2017 - 2024 Vaadin Ltd.
3
+ * Copyright (c) 2017 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
@@ -50,6 +50,32 @@ registerStyles('vaadin-button', buttonStyles, { moduleId: 'vaadin-button-styles'
50
50
  * @mixes ThemableMixin
51
51
  */
52
52
  class Button extends ButtonMixin(ElementMixin(ThemableMixin(ControllerMixin(PolymerElement)))) {
53
+ static get properties() {
54
+ return {
55
+ /**
56
+ * When disabled, the button is rendered as "dimmed" and prevents all
57
+ * user interactions (mouse and keyboard).
58
+ *
59
+ * Since disabled buttons are not focusable and cannot react to hover
60
+ * events by default, it can cause accessibility issues by making them
61
+ * entirely invisible to assistive technologies, and prevents the use
62
+ * of Tooltips to explain why the action is not available. This can be
63
+ * addressed by enabling the feature flag `accessibleDisabledButtons`,
64
+ * which makes disabled buttons focusable and hoverable, while still
65
+ * preventing them from being triggered:
66
+ *
67
+ * ```
68
+ * // Set before any button is attached to the DOM.
69
+ * window.Vaadin.featureFlags.accessibleDisabledButtons = true
70
+ * ```
71
+ */
72
+ disabled: {
73
+ type: Boolean,
74
+ value: false,
75
+ },
76
+ };
77
+ }
78
+
53
79
  static get is() {
54
80
  return 'vaadin-button';
55
81
  }
@@ -65,6 +91,11 @@ class Button extends ButtonMixin(ElementMixin(ThemableMixin(ControllerMixin(Poly
65
91
  this._tooltipController = new TooltipController(this);
66
92
  this.addController(this._tooltipController);
67
93
  }
94
+
95
+ /** @override */
96
+ __shouldAllowFocusWhenDisabled() {
97
+ return window.Vaadin.featureFlags.accessibleDisabledButtons;
98
+ }
68
99
  }
69
100
 
70
101
  defineCustomElement(Button);
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2017 - 2024 Vaadin Ltd.
3
+ * Copyright (c) 2017 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  export * from './vaadin-button.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2017 - 2024 Vaadin Ltd.
3
+ * Copyright (c) 2017 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { html, LitElement } from 'lit';
@@ -42,6 +42,11 @@ class Button extends ButtonMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElem
42
42
  this._tooltipController = new TooltipController(this);
43
43
  this.addController(this._tooltipController);
44
44
  }
45
+
46
+ /** @override */
47
+ __shouldAllowFocusWhenDisabled() {
48
+ return window.Vaadin.featureFlags.accessibleDisabledButtons;
49
+ }
45
50
  }
46
51
 
47
52
  defineCustomElement(Button);
@@ -75,7 +75,7 @@ const button = css`
75
75
  /* Hover */
76
76
 
77
77
  @media (any-hover: hover) {
78
- :host(:hover)::before {
78
+ :host(:not([disabled]):hover)::before {
79
79
  opacity: 0.02;
80
80
  }
81
81
  }
@@ -159,7 +159,7 @@ const button = css`
159
159
  }
160
160
 
161
161
  @media (any-hover: hover) {
162
- :host([theme~='primary']:hover)::before {
162
+ :host([theme~='primary']:not([disabled]):hover)::before {
163
163
  opacity: 0.05;
164
164
  }
165
165
  }
@@ -213,7 +213,6 @@ const button = css`
213
213
  /* Disabled state. Keep selectors after other color variants. */
214
214
 
215
215
  :host([disabled]) {
216
- pointer-events: none;
217
216
  color: var(--lumo-disabled-text-color);
218
217
  }
219
218
 
@@ -60,7 +60,7 @@ const button = css`
60
60
  vertical-align: middle;
61
61
  }
62
62
 
63
- :host(:hover)::before,
63
+ :host(:hover:not([disabled]))::before,
64
64
  :host([focus-ring])::before {
65
65
  opacity: 0.08;
66
66
  transition-duration: 0.2s;
@@ -77,13 +77,12 @@ const button = css`
77
77
  transition: 0s;
78
78
  }
79
79
 
80
- :host(:hover:not([active]))::after {
80
+ :host(:hover:not([active]):not([disabled]))::after {
81
81
  transform: translate(-50%, -50%) scale(1);
82
82
  opacity: 0;
83
83
  }
84
84
 
85
85
  :host([disabled]) {
86
- pointer-events: none;
87
86
  color: var(--material-disabled-text-color);
88
87
  }
89
88
 
@@ -107,7 +106,7 @@ const button = css`
107
106
  background-color: var(--material-secondary-background-color);
108
107
  }
109
108
 
110
- :host([theme~='contained']:hover) {
109
+ :host([theme~='contained']:not([disabled]):hover) {
111
110
  box-shadow: var(--material-shadow-elevation-4dp);
112
111
  }
113
112
 
@@ -150,7 +149,7 @@ const button = css`
150
149
  transform: translate(50%, -50%) scale(0.0000001);
151
150
  }
152
151
 
153
- :host(:hover:not([active])[dir='rtl'])::after {
152
+ :host(:hover:not([active]):not([disabled])[dir='rtl'])::after {
154
153
  transform: translate(50%, -50%) scale(1);
155
154
  }
156
155
 
package/web-types.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/button",
4
- "version": "24.6.5",
4
+ "version": "24.7.0-alpha10",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
@@ -12,7 +12,7 @@
12
12
  "attributes": [
13
13
  {
14
14
  "name": "disabled",
15
- "description": "If true, the user cannot interact with this element.",
15
+ "description": "When disabled, the button is rendered as \"dimmed\" and prevents all\nuser interactions (mouse and keyboard).\n\nSince disabled buttons are not focusable and cannot react to hover\nevents by default, it can cause accessibility issues by making them\nentirely invisible to assistive technologies, and prevents the use\nof Tooltips to explain why the action is not available. This can be\naddressed by enabling the feature flag `accessibleDisabledButtons`,\nwhich makes disabled buttons focusable and hoverable, while still\npreventing them from being triggered:\n\n```\n// Set before any button is attached to the DOM.\nwindow.Vaadin.featureFlags.accessibleDisabledButtons = true\n```",
16
16
  "value": {
17
17
  "type": [
18
18
  "boolean",
@@ -37,7 +37,7 @@
37
37
  "properties": [
38
38
  {
39
39
  "name": "disabled",
40
- "description": "If true, the user cannot interact with this element.",
40
+ "description": "When disabled, the button is rendered as \"dimmed\" and prevents all\nuser interactions (mouse and keyboard).\n\nSince disabled buttons are not focusable and cannot react to hover\nevents by default, it can cause accessibility issues by making them\nentirely invisible to assistive technologies, and prevents the use\nof Tooltips to explain why the action is not available. This can be\naddressed by enabling the feature flag `accessibleDisabledButtons`,\nwhich makes disabled buttons focusable and hoverable, while still\npreventing them from being triggered:\n\n```\n// Set before any button is attached to the DOM.\nwindow.Vaadin.featureFlags.accessibleDisabledButtons = true\n```",
41
41
  "value": {
42
42
  "type": [
43
43
  "boolean",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/button",
4
- "version": "24.6.5",
4
+ "version": "24.7.0-alpha10",
5
5
  "description-markup": "markdown",
6
6
  "framework": "lit",
7
7
  "framework-config": {
@@ -21,7 +21,7 @@
21
21
  "attributes": [
22
22
  {
23
23
  "name": "?disabled",
24
- "description": "If true, the user cannot interact with this element.",
24
+ "description": "When disabled, the button is rendered as \"dimmed\" and prevents all\nuser interactions (mouse and keyboard).\n\nSince disabled buttons are not focusable and cannot react to hover\nevents by default, it can cause accessibility issues by making them\nentirely invisible to assistive technologies, and prevents the use\nof Tooltips to explain why the action is not available. This can be\naddressed by enabling the feature flag `accessibleDisabledButtons`,\nwhich makes disabled buttons focusable and hoverable, while still\npreventing them from being triggered:\n\n```\n// Set before any button is attached to the DOM.\nwindow.Vaadin.featureFlags.accessibleDisabledButtons = true\n```",
25
25
  "value": {
26
26
  "kind": "expression"
27
27
  }