@vaadin/dashboard 24.6.0-alpha9 → 24.6.0-rc1

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/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  A responsive, grid-based dashboard layout component
4
4
 
5
+ > ⚠️ This component is experimental and the API may change. In order to use it, enable the feature flag by setting `window.Vaadin.featureFlags.dashboardComponent = true`.
6
+
5
7
  > ℹ️  A commercial Vaadin [subscription](https://vaadin.com/pricing) is required to use Dashboard in your project.
6
8
 
7
9
  [Documentation + Live Demo ↗](https://vaadin.com/docs/latest/components/dashboard)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/dashboard",
3
- "version": "24.6.0-alpha9",
3
+ "version": "24.6.0-rc1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -37,15 +37,15 @@
37
37
  ],
38
38
  "dependencies": {
39
39
  "@open-wc/dedupe-mixin": "^1.3.0",
40
- "@vaadin/button": "24.6.0-alpha9",
41
- "@vaadin/component-base": "24.6.0-alpha9",
42
- "@vaadin/vaadin-lumo-styles": "24.6.0-alpha9",
43
- "@vaadin/vaadin-material-styles": "24.6.0-alpha9",
44
- "@vaadin/vaadin-themable-mixin": "24.6.0-alpha9",
40
+ "@vaadin/button": "24.6.0-rc1",
41
+ "@vaadin/component-base": "24.6.0-rc1",
42
+ "@vaadin/vaadin-lumo-styles": "24.6.0-rc1",
43
+ "@vaadin/vaadin-material-styles": "24.6.0-rc1",
44
+ "@vaadin/vaadin-themable-mixin": "24.6.0-rc1",
45
45
  "lit": "^3.0.0"
46
46
  },
47
47
  "devDependencies": {
48
- "@vaadin/chai-plugins": "24.6.0-alpha9",
48
+ "@vaadin/chai-plugins": "24.6.0-rc1",
49
49
  "@vaadin/testing-helpers": "^1.0.0"
50
50
  },
51
51
  "cvdlName": "vaadin-dashboard",
@@ -53,5 +53,5 @@
53
53
  "web-types.json",
54
54
  "web-types.lit.json"
55
55
  ],
56
- "gitHead": "e303d77ba20c3089c9998be9a318733d9ec5b53c"
56
+ "gitHead": "d62ba309e3286777ad3ea7e015d50a2c4976bb42"
57
57
  }
@@ -18,7 +18,6 @@ export class KeyboardController {
18
18
  this.host = host;
19
19
 
20
20
  host.addEventListener('focusout', (e) => this.__focusout(e));
21
- host.addEventListener('focusin', (e) => this.__focusin(e));
22
21
  host.addEventListener('keydown', (e) => this.__keydown(e));
23
22
  }
24
23
 
@@ -36,13 +35,6 @@ export class KeyboardController {
36
35
  }
37
36
  }
38
37
 
39
- /** @private */
40
- __focusin(e) {
41
- if (e.target === this.host) {
42
- this.host.__focused = true;
43
- }
44
- }
45
-
46
38
  /** @private */
47
39
  __keydown(e) {
48
40
  if (e.metaKey || e.ctrlKey || !this.host.__selected) {
@@ -87,6 +87,10 @@ export function fireResize(element, colspanDelta, rowspanDelta) {
87
87
  },
88
88
  }),
89
89
  );
90
+
91
+ if ('requestUpdate' in element) {
92
+ element.requestUpdate();
93
+ }
90
94
  }
91
95
 
92
96
  /**
@@ -132,8 +132,19 @@ export const DashboardItemMixin = (superClass) =>
132
132
  aria-label=${this.__i18n[i18nSelectTitleForEditingProperty]}
133
133
  aria-describedby="title"
134
134
  aria-pressed="${!!this.__selected}"
135
+ @focus="${() => {
136
+ this.__focused = true;
137
+ }}"
138
+ @blur="${() => {
139
+ this.__focused = false;
140
+ }}"
135
141
  @click="${() => {
136
- this.__selected = true;
142
+ const wasSelected = this.__selected;
143
+ this.__selected = !wasSelected;
144
+ this.__focused = wasSelected;
145
+ if (this.__selected) {
146
+ this.$['drag-handle'].focus();
147
+ }
137
148
  }}"
138
149
  ></button>
139
150
  </label>`;
@@ -198,7 +209,17 @@ export const DashboardItemMixin = (superClass) =>
198
209
 
199
210
  /** @private */
200
211
  __renderResizeControls() {
201
- const hasMinRowHeight = getComputedStyle(this).getPropertyValue('--_vaadin-dashboard-row-min-height') !== 'auto';
212
+ const style = getComputedStyle(this);
213
+ const hasMinRowHeight = style.getPropertyValue('--_vaadin-dashboard-row-min-height') !== 'auto';
214
+
215
+ const effectiveColCount = style.getPropertyValue('--_vaadin-dashboard-col-count');
216
+ const maxColCount = style.getPropertyValue('--_vaadin-dashboard-col-max-count');
217
+ const colCount = Math.min(effectiveColCount, maxColCount);
218
+ const colspan = style.getPropertyValue('--vaadin-dashboard-item-colspan') || 1;
219
+ const rowspan = style.getPropertyValue('--vaadin-dashboard-item-rowspan') || 1;
220
+ const canShrinkWidth = colspan > 1;
221
+ const canShrinkHeight = rowspan > 1;
222
+ const canGrowWidth = colspan < colCount;
202
223
 
203
224
  return html`<div
204
225
  id="resize-controls"
@@ -221,6 +242,7 @@ export const DashboardItemMixin = (superClass) =>
221
242
  aria-label="${this.__i18n.resizeShrinkWidth}"
222
243
  title="${this.__i18n.resizeShrinkWidth}"
223
244
  @click="${() => fireResize(this, -1, 0)}"
245
+ .hidden="${!canShrinkWidth}"
224
246
  id="resize-shrink-width"
225
247
  part="resize-shrink-width-button"
226
248
  >
@@ -231,6 +253,7 @@ export const DashboardItemMixin = (superClass) =>
231
253
  aria-label="${this.__i18n.resizeGrowWidth}"
232
254
  title="${this.__i18n.resizeGrowWidth}"
233
255
  @click="${() => fireResize(this, 1, 0)}"
256
+ .hidden="${!canGrowWidth}"
234
257
  id="resize-grow-width"
235
258
  part="resize-grow-width-button"
236
259
  >
@@ -243,7 +266,7 @@ export const DashboardItemMixin = (superClass) =>
243
266
  @click="${() => fireResize(this, 0, -1)}"
244
267
  id="resize-shrink-height"
245
268
  part="resize-shrink-height-button"
246
- .hidden="${!hasMinRowHeight}"
269
+ .hidden="${!hasMinRowHeight || !canShrinkHeight}"
247
270
  >
248
271
  <div class="icon"></div>
249
272
  </vaadin-dashboard-button>
@@ -316,6 +339,8 @@ export const DashboardItemMixin = (superClass) =>
316
339
  __focusApply() {
317
340
  if (this.__moveMode) {
318
341
  this.$['move-apply'].focus();
342
+ } else if (this.__resizeMode) {
343
+ this.$['resize-apply'].focus();
319
344
  }
320
345
  }
321
346
 
@@ -24,6 +24,7 @@ export const DashboardLayoutMixin = (superClass) =>
24
24
  :host {
25
25
  display: block;
26
26
  overflow: hidden;
27
+ width: 100%;
27
28
  }
28
29
 
29
30
  :host([hidden]) {
@@ -36,12 +37,19 @@ export const DashboardLayoutMixin = (superClass) =>
36
37
 
37
38
  #grid {
38
39
  box-sizing: border-box;
39
- --_vaadin-dashboard-default-spacing: 1rem;
40
- --_vaadin-dashboard-spacing: max(
40
+
41
+ /* Padding around dashboard edges */
42
+ --_vaadin-dashboard-default-padding: 1rem;
43
+ --_vaadin-dashboard-padding: max(
41
44
  0px,
42
- var(--vaadin-dashboard-spacing, var(--_vaadin-dashboard-default-spacing))
45
+ var(--vaadin-dashboard-padding, var(--_vaadin-dashboard-default-padding))
43
46
  );
44
- padding: var(--_vaadin-dashboard-spacing);
47
+ padding: var(--_vaadin-dashboard-padding);
48
+
49
+ /* Gap between widgets */
50
+ --_vaadin-dashboard-default-gap: 1rem;
51
+ --_vaadin-dashboard-gap: max(0px, var(--vaadin-dashboard-gap, var(--_vaadin-dashboard-default-gap)));
52
+ gap: var(--_vaadin-dashboard-gap);
45
53
 
46
54
  /* Default min and max column widths */
47
55
  --_vaadin-dashboard-default-col-min-width: 25rem;
@@ -86,8 +94,6 @@ export const DashboardLayoutMixin = (superClass) =>
86
94
  );
87
95
 
88
96
  grid-auto-rows: var(--_vaadin-dashboard-row-height);
89
-
90
- gap: var(--_vaadin-dashboard-spacing);
91
97
  }
92
98
 
93
99
  ::slotted(*) {
@@ -35,7 +35,8 @@ import { DashboardLayoutMixin } from './vaadin-dashboard-layout-mixin.js';
35
35
  * `--vaadin-dashboard-col-max-width` | maximum column width of the layout
36
36
  * `--vaadin-dashboard-row-min-height` | minimum row height of the layout
37
37
  * `--vaadin-dashboard-col-max-count` | maximum column count of the layout
38
- * `--vaadin-dashboard-spacing` | spacing between child elements and space around its outer edges. Must be in length units (0 is not allowed, 0px is)
38
+ * `--vaadin-dashboard-gap` | gap between child elements. Must be in length units (0 is not allowed, 0px is)
39
+ * `--vaadin-dashboard-padding` | space around the dashboard's outer edges. Must be in length units (0 is not allowed, 0px is)
39
40
  *
40
41
  * The following state attributes are available for styling:
41
42
  *
@@ -38,7 +38,8 @@ import { DashboardLayoutMixin } from './vaadin-dashboard-layout-mixin.js';
38
38
  * `--vaadin-dashboard-col-max-width` | maximum column width of the layout
39
39
  * `--vaadin-dashboard-row-min-height` | minimum row height of the layout
40
40
  * `--vaadin-dashboard-col-max-count` | maximum column count of the layout
41
- * `--vaadin-dashboard-spacing` | spacing between child elements and space around its outer edges. Must be in length units (0 is not allowed, 0px is)
41
+ * `--vaadin-dashboard-gap` | gap between child elements. Must be in length units (0 is not allowed, 0px is)
42
+ * `--vaadin-dashboard-padding` | space around the dashboard's outer edges. Must be in length units (0 is not allowed, 0px is)
42
43
  *
43
44
  * The following state attributes are available for styling:
44
45
  *
@@ -87,7 +87,7 @@ class DashboardSection extends DashboardItemMixin(ElementMixin(ThemableMixin(Pol
87
87
  grid-template-columns: subgrid;
88
88
  --_vaadin-dashboard-section-column: 1 / calc(var(--_vaadin-dashboard-effective-col-count) + 1);
89
89
  grid-column: var(--_vaadin-dashboard-section-column) !important;
90
- gap: var(--_vaadin-dashboard-spacing, 1rem);
90
+ gap: var(--_vaadin-dashboard-gap, 1rem);
91
91
  /* Dashboard section header height */
92
92
  --_vaadin-dashboard-section-header-height: minmax(0, auto);
93
93
  grid-template-rows: var(--_vaadin-dashboard-section-header-height) repeat(
@@ -179,9 +179,11 @@ class DashboardSection extends DashboardItemMixin(ElementMixin(ThemableMixin(Pol
179
179
  /** @protected */
180
180
  render() {
181
181
  return html`
182
- ${this.__renderFocusButton('selectSection')} ${this.__renderMoveControls()}
182
+ ${this.__renderMoveControls()}
183
183
 
184
184
  <div id="focustrap">
185
+ ${this.__renderFocusButton('selectSection')}
186
+
185
187
  <header part="header">
186
188
  ${this.__renderDragHandle()}
187
189
  <h2 id="title" part="title">${this.sectionTitle}</h2>
@@ -19,19 +19,14 @@ export const hasWidgetWrappers = css`
19
19
  export const dashboardWidgetAndSectionStyles = css`
20
20
  :host {
21
21
  box-sizing: border-box;
22
- /* Calculates the offset by which mode buttons that by default overflow the widget edges
23
- should be shifted inwards based on a custom --vaadin-dashboard-spacing value */
24
- --_mode-button-spacing-offset: calc(
25
- max(0px, var(--_vaadin-dashboard-default-spacing) - var(--_vaadin-dashboard-spacing))
26
- );
27
22
  }
28
23
 
29
24
  :host([dragging]) * {
30
25
  visibility: hidden;
31
26
  }
32
27
 
33
- :host(:not([editable])) #drag-handle,
34
- :host(:not([editable])) #remove-button,
28
+ :host(:not([editable])) [part~='move-button'],
29
+ :host(:not([editable])) [part~='remove-button'],
35
30
  :host(:not([editable])) #focus-button,
36
31
  :host(:not([editable])) #focus-button-wrapper,
37
32
  :host(:not([editable])) .mode-controls {
@@ -75,67 +70,85 @@ export const dashboardWidgetAndSectionStyles = css`
75
70
  }
76
71
 
77
72
  /* Move-mode buttons */
78
- #move-backward,
79
- #move-forward,
80
- #move-apply {
73
+ [part~='move-backward-button'],
74
+ [part~='move-forward-button'],
75
+ [part~='move-apply-button'] {
81
76
  position: absolute;
82
77
  top: 50%;
83
78
  }
84
79
 
85
- #move-backward {
80
+ [part~='move-backward-button'] {
86
81
  inset-inline-start: 0;
87
82
  transform: translateY(-50%);
88
83
  }
89
84
 
90
- #move-forward {
85
+ [part~='move-forward-button'] {
91
86
  inset-inline-end: 0;
92
87
  transform: translateY(-50%);
93
88
  }
94
89
 
95
- #move-apply {
90
+ [part~='move-apply-button'] {
96
91
  left: 50%;
97
92
  transform: translate(-50%, -50%);
98
93
  }
99
94
 
100
- :host([first-child]) #move-backward,
101
- :host([last-child]) #move-forward {
95
+ :host([first-child]) [part~='move-backward-button'],
96
+ :host([last-child]) [part~='move-forward-button'] {
102
97
  display: none;
103
98
  }
104
99
 
105
100
  /* Resize-mode buttons */
106
- #resize-shrink-width,
107
- #resize-shrink-height,
108
- #resize-grow-width,
109
- #resize-grow-height,
110
- #resize-apply {
101
+ [part~='resize-shrink-width-button'],
102
+ [part~='resize-shrink-height-button'],
103
+ [part~='resize-grow-width-button'],
104
+ [part~='resize-grow-height-button'],
105
+ [part~='resize-apply-button'] {
111
106
  position: absolute;
112
107
  }
113
108
 
114
- #resize-shrink-width {
115
- inset-inline-end: calc(0px + var(--_mode-button-spacing-offset));
109
+ [part~='resize-shrink-width-button'] {
110
+ inset-inline-end: 0;
116
111
  top: 50%;
112
+ }
113
+
114
+ :host(:not([dir='rtl'])) [part~='resize-shrink-width-button'] {
115
+ transform: translateY(-50%) translateX(-100%);
116
+ }
117
+
118
+ :host([dir='rtl']) [part~='resize-shrink-width-button'] {
119
+ transform: translateY(-50%) translateX(100%);
120
+ }
121
+
122
+ .mode-controls:has([part~='resize-grow-width-button'][hidden]) [part~='resize-shrink-width-button'] {
117
123
  transform: translateY(-50%);
118
124
  }
119
125
 
120
- #resize-grow-width {
121
- inset-inline-start: calc(100% - var(--_mode-button-spacing-offset));
126
+ [part~='resize-grow-width-button'] {
127
+ inset-inline-start: 100%;
122
128
  top: 50%;
123
- transform: translateY(-50%);
124
129
  }
125
130
 
126
- #resize-shrink-height {
127
- bottom: calc(0px + var(--_mode-button-spacing-offset));
131
+ :host(:not([dir='rtl'])) [part~='resize-grow-width-button'] {
132
+ transform: translateY(-50%) translateX(-100%);
133
+ }
134
+
135
+ :host([dir='rtl']) [part~='resize-grow-width-button'] {
136
+ transform: translateY(-50%) translateX(100%);
137
+ }
138
+
139
+ [part~='resize-shrink-height-button'] {
140
+ bottom: 0;
128
141
  left: 50%;
129
- transform: translateX(-50%);
142
+ transform: translateX(-50%) translateY(-100%);
130
143
  }
131
144
 
132
- #resize-grow-height {
133
- top: calc(100% - var(--_mode-button-spacing-offset));
145
+ [part~='resize-grow-height-button'] {
146
+ top: 100%;
134
147
  left: 50%;
135
- transform: translateX(-50%);
148
+ transform: translateX(-50%) translateY(-100%);
136
149
  }
137
150
 
138
- #resize-apply {
151
+ [part~='resize-apply-button'] {
139
152
  left: 50%;
140
153
  top: 50%;
141
154
 
@@ -118,16 +118,16 @@ class DashboardWidget extends DashboardItemMixin(ElementMixin(ThemableMixin(Poly
118
118
  display: none !important;
119
119
  }
120
120
 
121
- :host(:not([editable])) #resize-handle {
121
+ :host(:not([editable])) [part~='resize-button'] {
122
122
  display: none;
123
123
  }
124
124
 
125
- #content {
125
+ [part~='content'] {
126
126
  flex: 1;
127
127
  overflow: hidden;
128
128
  }
129
129
 
130
- #resize-handle {
130
+ [part~='resize-button'] {
131
131
  position: absolute;
132
132
  bottom: 0;
133
133
  inset-inline-end: 0;
@@ -139,11 +139,11 @@ class DashboardWidget extends DashboardItemMixin(ElementMixin(ThemableMixin(Poly
139
139
  content: '';
140
140
  z-index: 2;
141
141
  position: absolute;
142
- inset-inline-start: 0;
143
- top: 0;
142
+ top: -1px;
144
143
  width: var(--_vaadin-dashboard-widget-resizer-width, 0);
145
144
  height: var(--_vaadin-dashboard-widget-resizer-height, 0);
146
145
  background: rgba(0, 0, 0, 0.1);
146
+ border-radius: inherit;
147
147
  }
148
148
  `,
149
149
  super.styles,
@@ -209,9 +209,11 @@ class DashboardWidget extends DashboardItemMixin(ElementMixin(ThemableMixin(Poly
209
209
  /** @protected */
210
210
  render() {
211
211
  return html`
212
- ${this.__renderFocusButton('selectWidget')} ${this.__renderMoveControls()} ${this.__renderResizeControls()}
212
+ ${this.__renderMoveControls()} ${this.__renderResizeControls()}
213
213
 
214
214
  <div id="focustrap">
215
+ ${this.__renderFocusButton('selectWidget')}
216
+
215
217
  <header part="header">
216
218
  ${this.__renderDragHandle()}
217
219
  ${this.__nestedHeadingLevel
@@ -196,7 +196,8 @@ export interface DashboardI18n {
196
196
  * `--vaadin-dashboard-col-max-width` | maximum column width of the dashboard
197
197
  * `--vaadin-dashboard-row-min-height` | minimum row height of the dashboard
198
198
  * `--vaadin-dashboard-col-max-count` | maximum column count of the dashboard
199
- * `--vaadin-dashboard-spacing` | spacing between child elements and space around its outer edges. Must be in length units (0 is not allowed, 0px is)
199
+ * `--vaadin-dashboard-gap` | gap between child elements. Must be in length units (0 is not allowed, 0px is)
200
+ * `--vaadin-dashboard-padding` | space around the dashboard's outer edges. Must be in length units (0 is not allowed, 0px is)
200
201
  *
201
202
  * The following state attributes are available for styling:
202
203
  *
@@ -76,7 +76,8 @@ import { WidgetResizeController } from './widget-resize-controller.js';
76
76
  * `--vaadin-dashboard-col-max-width` | maximum column width of the dashboard
77
77
  * `--vaadin-dashboard-row-min-height` | minimum row height of the dashboard
78
78
  * `--vaadin-dashboard-col-max-count` | maximum column count of the dashboard
79
- * `--vaadin-dashboard-spacing` | spacing between child elements and space around its outer edges. Must be in length units (0 is not allowed, 0px is)
79
+ * `--vaadin-dashboard-gap` | gap between child elements. Must be in length units (0 is not allowed, 0px is)
80
+ * `--vaadin-dashboard-padding` | space around the dashboard's outer edges. Must be in length units (0 is not allowed, 0px is)
80
81
  *
81
82
  * The following state attributes are available for styling:
82
83
  *
@@ -258,7 +259,7 @@ class Dashboard extends DashboardLayoutMixin(ElementMixin(ThemableMixin(PolylitM
258
259
  let wrappers = [...hostElement.children].filter((el) => el.localName === WRAPPER_LOCAL_NAME);
259
260
  let previousWrapper = null;
260
261
 
261
- const focusedWrapper = wrappers.find((wrapper) => wrapper.querySelector('[focused]'));
262
+ const focusedWrapper = wrappers.find((wrapper) => wrapper.querySelector(':focus'));
262
263
  const focusedWrapperWillBeRemoved = focusedWrapper && !this.__isActiveWrapper(focusedWrapper);
263
264
  const wrapperClosestToRemovedFocused =
264
265
  focusedWrapperWillBeRemoved && this.__getClosestActiveWrapper(focusedWrapper);
@@ -319,7 +320,7 @@ class Dashboard extends DashboardLayoutMixin(ElementMixin(ThemableMixin(PolylitM
319
320
  this.__focusWrapperContent(wrapperClosestToRemovedFocused || this.querySelector(WRAPPER_LOCAL_NAME));
320
321
  }
321
322
 
322
- const focusedItem = this.querySelector('[focused]');
323
+ const focusedItem = this.querySelector(':focus');
323
324
  if (focusedItem && this.__outsideViewport(focusedItem)) {
324
325
  // If the focused wrapper is not in the viewport, scroll it into view
325
326
  focusedItem.scrollIntoView();
@@ -461,6 +462,23 @@ class Dashboard extends DashboardLayoutMixin(ElementMixin(ThemableMixin(PolylitM
461
462
  this.__dispatchCustomEvent('dashboard-item-resize-mode-changed', getElementItem(e.target), e.detail.value);
462
463
  }
463
464
 
465
+ /**
466
+ * @private
467
+ */
468
+ __updateColumnCount() {
469
+ const previousColumnCount = this.$.grid.style.getPropertyValue('--_vaadin-dashboard-col-count');
470
+ super.__updateColumnCount();
471
+
472
+ // Request update for all the widgets if the column count has changed on resize
473
+ if (previousColumnCount !== this.$.grid.style.getPropertyValue('--_vaadin-dashboard-col-count')) {
474
+ this.querySelectorAll(WRAPPER_LOCAL_NAME).forEach((wrapper) => {
475
+ if (wrapper.firstElementChild && 'requestUpdate' in wrapper.firstElementChild) {
476
+ wrapper.firstElementChild.requestUpdate();
477
+ }
478
+ });
479
+ }
480
+ }
481
+
464
482
  /**
465
483
  * Fired when an item selected state changed
466
484
  *
@@ -89,10 +89,10 @@ export class WidgetResizeController {
89
89
 
90
90
  const currentElementHeight = itemWrapper.firstElementChild.offsetHeight;
91
91
  const rowMinHeight = Math.min(...gridStyle.gridTemplateRows.split(' ').map((height) => parseFloat(height)));
92
- if (this.__resizeHeight > currentElementHeight + gapSize + rowMinHeight / 2) {
92
+ if (e.detail.ddy > 0 && this.__resizeHeight > currentElementHeight + gapSize + rowMinHeight / 2) {
93
93
  // Resized vertically above the half of the next row, increase rowspan
94
94
  this.__updateResizedItem(0, 1);
95
- } else if (this.__resizeHeight < currentElementHeight - rowMinHeight / 2) {
95
+ } else if (e.detail.ddy < 0 && this.__resizeHeight < currentElementHeight - rowMinHeight / 2) {
96
96
  // Resized vertically below the half of the current row, decrease rowspan
97
97
  this.__updateResizedItem(0, -1);
98
98
  }
@@ -2,7 +2,8 @@ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themab
2
2
 
3
3
  export const dashboardLayoutStyles = css`
4
4
  #grid {
5
- --_vaadin-dashboard-default-spacing: var(--lumo-space-l);
5
+ --_vaadin-dashboard-default-gap: var(--lumo-space-m);
6
+ --_vaadin-dashboard-default-padding: var(--lumo-space-m);
6
7
  }
7
8
  `;
8
9
 
@@ -7,14 +7,78 @@ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themab
7
7
  import { dashboardWidgetAndSection } from './vaadin-dashboard-widget-styles.js';
8
8
 
9
9
  const section = css`
10
+ /* stylelint-disable rule-empty-line-before */
11
+
10
12
  :host {
11
- --_focus-ring-spacing-max-offset: calc(var(--_vaadin-dashboard-spacing) / 2);
13
+ --_section-outline-offset: calc(min(var(--_vaadin-dashboard-gap), var(--_vaadin-dashboard-padding)) / 3);
14
+ --_focus-ring-offset: calc((var(--_section-outline-offset) - var(--_focus-ring-width)));
15
+ border-radius: var(--lumo-border-radius-l);
16
+ }
17
+
18
+ header {
19
+ margin-bottom: calc(-1 * var(--_section-outline-offset));
20
+ line-height: var(--lumo-line-height-s);
21
+ padding-inline: var(--lumo-space-s);
22
+ min-height: var(--lumo-size-l);
23
+ }
24
+
25
+ [part='title'] {
26
+ font-size: var(--lumo-font-size-xl);
27
+ font-weight: 600;
28
+ }
29
+
30
+ /* Section states */
31
+
32
+ :host([editable]) {
33
+ outline: 1px solid var(--lumo-contrast-10pct);
34
+ outline-offset: calc(var(--_section-outline-offset) - 1px);
35
+ background: var(--lumo-contrast-5pct);
36
+ box-shadow: 0 0 0 var(--_section-outline-offset) var(--lumo-contrast-5pct);
37
+ }
38
+ :host([editable]) header {
39
+ padding-inline: var(--lumo-space-xs);
40
+ }
41
+
42
+ :host([focused])::after {
43
+ content: '';
44
+ display: block;
45
+ position: absolute;
46
+ inset: 0;
47
+ border-radius: var(--lumo-border-radius-l);
48
+ z-index: 9;
49
+ outline: var(--_focus-ring-width) solid var(--_focus-ring-color);
50
+ outline-offset: var(--_focus-ring-offset);
51
+ }
52
+
53
+ :host([selected]) {
54
+ background: var(--lumo-primary-color-10pct);
55
+ box-shadow: 0 0 0 var(--_section-outline-offset) var(--lumo-primary-color-10pct);
56
+ }
57
+ :host([selected]:not([focused])) {
58
+ outline-color: var(--lumo-primary-color-50pct);
12
59
  }
13
60
 
14
61
  :host([move-mode]) ::slotted(*) {
15
62
  --_vaadin-dashboard-widget-opacity: 0.3;
16
63
  --_vaadin-dashboard-widget-filter: blur(10px);
17
64
  }
65
+
66
+ :host([dragging]) {
67
+ background: var(--vaadin-dashboard-drop-target-background-color);
68
+ outline: var(--vaadin-dashboard-drop-target-border);
69
+ box-shadow: 0 0 0 var(--_section-outline-offset) var(--vaadin-dashboard-drop-target-background-color);
70
+ }
71
+
72
+ /* Accessible move mode controls */
73
+
74
+ [part~='move-backward-button'] {
75
+ inset-inline-start: calc(-1 * var(--_section-outline-offset));
76
+ }
77
+
78
+ [part~='move-forward-button'] {
79
+ inset-inline-end: calc(-1 * var(--_section-outline-offset));
80
+ transform: translateY(-50%);
81
+ }
18
82
  `;
19
83
 
20
84
  registerStyles('vaadin-dashboard-section', [dashboardWidgetAndSection, section], {
@@ -4,234 +4,309 @@ import '@vaadin/vaadin-lumo-styles/spacing.js';
4
4
  import '@vaadin/vaadin-lumo-styles/style.js';
5
5
  import '@vaadin/vaadin-lumo-styles/typography.js';
6
6
  import '@vaadin/vaadin-lumo-styles/font-icons.js';
7
+ import { addGlobalThemeStyles } from '@vaadin/vaadin-themable-mixin/register-styles';
7
8
  import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
8
9
 
10
+ /* Global styles */
11
+ const dashboardWidgetProps = css`
12
+ html {
13
+ --vaadin-dashboard-widget-background: var(--lumo-base-color);
14
+ --vaadin-dashboard-widget-border-radius: var(--lumo-border-radius-l);
15
+ --vaadin-dashboard-widget-border-width: 1px;
16
+ --vaadin-dashboard-widget-border-color: var(--lumo-contrast-20pct);
17
+ --vaadin-dashboard-widget-shadow: 0 0 0 0 transparent;
18
+ --vaadin-dashboard-widget-editable-shadow: var(--lumo-box-shadow-s);
19
+ --vaadin-dashboard-widget-selected-shadow: 0 2px 4px -1px var(--lumo-primary-color-10pct),
20
+ 0 3px 12px -1px var(--lumo-primary-color-50pct);
21
+ --vaadin-dashboard-drop-target-background-color: var(--lumo-primary-color-10pct);
22
+ --vaadin-dashboard-drop-target-border: 1px dashed var(--lumo-primary-color-50pct);
23
+ }
24
+ `;
25
+ addGlobalThemeStyles('dashboard-widget-props', dashboardWidgetProps);
26
+
27
+ /* Styles shared between widgets and sections */
9
28
  const dashboardWidgetAndSection = css`
29
+ /* stylelint-disable rule-empty-line-before */
30
+ /* stylelint-disable length-zero-no-unit */
31
+
10
32
  :host {
11
- border-radius: var(--lumo-border-radius-l);
12
33
  color: var(--lumo-body-text-color);
13
34
  font-family: var(--lumo-font-family);
14
35
  font-size: var(--lumo-font-size-m);
15
36
  line-height: var(--lumo-line-height-m);
16
37
  --_focus-ring-color: var(--vaadin-focus-ring-color, var(--lumo-primary-color-50pct));
17
38
  --_focus-ring-width: var(--vaadin-focus-ring-width, 2px);
18
- /* default max value for the focus ring spacing offset. calc doesn't support unitless 0. */
19
- /* stylelint-disable length-zero-no-unit */
20
- --_focus-ring-spacing-max-offset: 0px;
21
- /* Calculates the offset by which the focus ring should be shifted inwards based on a custom --vaadin-dashboard-spacing value.
22
- Effectively keeps the focus ring visible if --vaadin-dashboard-spacing is set to 0px */
23
- --_focus-ring-spacing-offset: min(
24
- max(calc(var(--_focus-ring-width) * -1), var(--_vaadin-dashboard-spacing) - var(--_focus-ring-width)),
25
- var(--_focus-ring-spacing-max-offset, 0px)
26
- );
27
- outline: none;
28
- }
29
-
30
- :host::before {
31
- content: '';
32
- display: block;
33
- position: absolute;
34
- inset: 0;
35
- border-radius: var(--lumo-border-radius-l);
36
- pointer-events: none;
37
- margin: calc(var(--_focus-ring-spacing-offset) * -1);
39
+ --_icon-color: var(--lumo-contrast-60pct);
40
+ opacity: var(--_vaadin-dashboard-widget-opacity);
41
+ filter: var(--_vaadin-dashboard-widget-filter);
38
42
  }
39
43
 
40
- :host([focused])::before {
41
- outline: var(--_focus-ring-width) solid var(--_focus-ring-color);
44
+ :host([selected]) {
45
+ opacity: 1;
46
+ z-index: 1;
42
47
  }
43
48
 
44
- :host([selected])::before {
45
- box-shadow:
46
- 0 2px 4px -1px var(--lumo-primary-color-10pct),
47
- 0 3px 12px -1px var(--lumo-primary-color-50pct);
49
+ :host([focused]) {
50
+ z-index: 1;
51
+ }
52
+
53
+ header {
54
+ display: flex;
55
+ align-items: center;
56
+ box-sizing: border-box;
57
+ justify-content: space-between;
58
+ gap: var(--lumo-space-xs);
59
+ }
60
+
61
+ [part='title'] {
62
+ flex: 1;
63
+ color: var(--lumo-header-text-color);
64
+ margin: 0;
65
+ white-space: nowrap;
66
+ text-overflow: ellipsis;
67
+ overflow: hidden;
48
68
  }
49
69
 
50
- /* Buttons styling */
51
70
  vaadin-dashboard-button {
52
71
  font-family: 'lumo-icons';
53
- font-size: var(--lumo-icon-size-s);
72
+ font-size: var(--lumo-icon-size-m);
73
+ margin: 0;
54
74
  }
55
75
 
56
- .icon::before {
76
+ vaadin-dashboard-button .icon::before {
57
77
  display: block;
58
78
  content: var(--icon);
59
79
  }
60
80
 
61
- :host(:not([selected])) *:not(.mode-controls) vaadin-dashboard-button,
62
- :host([move-mode]) *:not(.mode-controls) vaadin-dashboard-button,
63
- :host([resize-mode]) *:not(.mode-controls) vaadin-dashboard-button {
64
- color: var(--lumo-disabled-text-color);
81
+ /* Common styles for non-mode edit buttons */
82
+ [part='move-button'],
83
+ [part='resize-button'],
84
+ [part='remove-button'] {
85
+ color: var(--_icon-color);
86
+ padding-inline: 0;
65
87
  }
66
-
67
- /* Header styling */
68
- header {
69
- display: flex;
70
- align-items: center;
71
- padding: var(--lumo-space-s) var(--lumo-space-m);
72
- gap: var(--lumo-space-s);
73
- min-height: var(--lumo-size-m);
74
- justify-content: space-between;
88
+ :where([part='move-button'], [part='resize-button'], [part='remove-button']):hover {
89
+ --_icon-color: var(--lumo-primary-text-color);
75
90
  }
76
-
77
- :host([editable]) header {
78
- padding-inline: var(--lumo-space-s);
91
+ :host([selected]) {
92
+ --_icon-color: var(--lumo-primary-text-color);
93
+ }
94
+ :host(:is([move-mode], [resize-mode])) {
95
+ --_icon-color: var(--lumo-disabled-text-color);
79
96
  }
80
97
 
81
- /* Drag handle styling */
82
- #drag-handle {
98
+ /* Drag handle */
99
+ [part~='move-button'] {
83
100
  cursor: move;
84
- --icon: var(--lumo-icons-menu);
101
+ --icon: var(--lumo-icons-drag-handle);
85
102
  }
86
103
 
87
- /* Remove button styling */
88
- #remove-button {
104
+ /* Remove button */
105
+ [part~='remove-button'] {
89
106
  cursor: pointer;
90
107
  --icon: var(--lumo-icons-cross);
91
108
  }
92
109
 
93
- /* Title styling */
94
- h2,
95
- h3 {
96
- flex: 1;
97
- font-size: var(--lumo-font-size-m);
98
- font-weight: 500;
99
- color: var(--lumo-header-text-color);
100
- margin: 0;
101
- }
102
-
103
- /* Content styling */
104
- #content {
105
- min-height: var(--lumo-size-m);
106
- padding: var(--lumo-space-s);
107
- }
108
-
109
- /* Mode controls styling */
110
+ /* Mode controls */
110
111
  .mode-controls vaadin-dashboard-button[focused] {
111
112
  z-index: 3;
112
113
  }
113
114
 
114
- /* Move mode styling */
115
+ /* Move mode */
115
116
 
116
- #move-backward {
117
- inset-inline-start: calc(0px - var(--_focus-ring-spacing-offset));
118
- }
119
-
120
- #move-forward {
121
- inset-inline-end: calc(0px - var(--_focus-ring-spacing-offset));
122
- transform: translateY(-50%);
123
- }
124
-
125
- :host(:not([dir='rtl'])) #move-backward,
126
- :host([dir='rtl']) #move-forward {
117
+ :host(:not([dir='rtl'])) [part~='move-backward-button'],
118
+ :host([dir='rtl']) [part~='move-forward-button'] {
127
119
  border-top-left-radius: 0;
128
120
  border-bottom-left-radius: 0;
129
121
  --icon: var(--lumo-icons-angle-left);
130
122
  }
131
123
 
132
- :host(:not([dir='rtl'])) #move-forward,
133
- :host([dir='rtl']) #move-backward {
124
+ :host(:not([dir='rtl'])) [part~='move-forward-button'],
125
+ :host([dir='rtl']) [part~='move-backward-button'] {
134
126
  border-top-right-radius: 0;
135
127
  border-bottom-right-radius: 0;
136
128
  --icon: var(--lumo-icons-angle-right);
137
129
  }
138
130
 
139
- #move-apply {
131
+ [part~='move-apply-button'] {
140
132
  --icon: var(--lumo-icons-checkmark);
141
133
  font-size: var(--lumo-icon-size-m);
142
134
  }
143
135
  `;
144
136
 
137
+ /* Widget styles */
145
138
  const dashboardWidget = css`
146
139
  :host {
147
- opacity: var(--_vaadin-dashboard-widget-opacity);
148
- filter: var(--_vaadin-dashboard-widget-filter);
149
- background-color: var(--lumo-base-color);
140
+ background: var(--vaadin-dashboard-widget-background);
141
+ border-radius: var(--vaadin-dashboard-widget-border-radius);
142
+ --_border-shadow: 0 0 0 var(--vaadin-dashboard-widget-border-width) var(--vaadin-dashboard-widget-border-color);
143
+ --_shadow: var(--vaadin-dashboard-widget-shadow);
144
+ box-shadow: var(--_shadow), var(--_border-shadow);
150
145
  }
151
146
 
152
- :host(:not([selected])) {
153
- box-shadow: var(--lumo-box-shadow-s);
147
+ /* Widget states */
148
+
149
+ :host([editable]) {
150
+ --_shadow: var(--vaadin-dashboard-widget-editable-shadow);
151
+ }
152
+
153
+ :host([focused]) {
154
+ --_border-shadow: inset 0 0 0 var(--_focus-ring-width) var(--_focus-ring-color);
154
155
  }
155
156
 
156
157
  :host([selected]) {
157
- opacity: 1;
158
+ --_shadow: var(--vaadin-dashboard-widget-selected-shadow);
159
+ background: var(--lumo-primary-color-10pct);
158
160
  }
159
161
 
160
- :host([resize-mode]) #content,
161
- :host([move-mode]) #content {
162
- opacity: 0.3;
163
- filter: blur(10px);
162
+ :host([dragging]) {
163
+ box-shadow: none;
164
+ background: var(--vaadin-dashboard-drop-target-background-color);
165
+ border: var(--vaadin-dashboard-drop-target-border);
164
166
  }
165
167
 
166
- /* Header styling */
168
+ :host([resizing])::after {
169
+ background: var(--vaadin-dashboard-drop-target-background-color);
170
+ border: var(--vaadin-dashboard-drop-target-border);
171
+ }
172
+
173
+ /* Widget parts */
174
+
167
175
  header {
176
+ min-height: var(--lumo-size-l);
177
+ padding: 0 var(--lumo-space-m);
168
178
  border-bottom: 1px solid var(--lumo-contrast-10pct);
169
179
  }
170
180
 
171
- /* Resize handle styling */
172
- #resize-handle {
181
+ :host([editable]) header {
182
+ padding-inline: var(--lumo-space-xs);
183
+ }
184
+
185
+ [part='title'] {
186
+ font-size: var(--lumo-font-size-l);
187
+ font-weight: 600;
188
+ }
189
+
190
+ #content {
191
+ min-height: var(--lumo-size-m);
192
+ padding: var(--lumo-space-s);
193
+ }
194
+
195
+ :host([resize-mode]) #content,
196
+ :host([move-mode]) #content {
197
+ opacity: 0.75;
198
+ filter: blur(10px);
199
+ }
200
+
201
+ /* Resize handle */
202
+
203
+ [part~='resize-button'] {
204
+ --_resize-button-offset: min(var(--_vaadin-dashboard-gap), var(--_vaadin-dashboard-padding), var(--lumo-space-xs));
173
205
  position: absolute;
174
- bottom: var(--lumo-space-s);
175
- inset-inline-end: var(--lumo-space-s);
176
- cursor: se-resize;
177
- --icon: var(--lumo-icons-chevron-down);
206
+ bottom: calc(-1 * var(--_resize-button-offset));
207
+ inset-inline-end: calc(-1 * var(--_resize-button-offset));
208
+ cursor: nwse-resize;
209
+ --icon: var(--lumo-icons-resize-handle);
178
210
  }
179
211
 
180
- :host([dir='rtl']) #resize-handle {
212
+ :host([dir='rtl']) [part~='resize-button'] {
181
213
  cursor: sw-resize;
182
214
  }
183
215
 
184
- #resize-handle .icon::before {
185
- transform: rotate(-45deg);
216
+ :host([dir='rtl']) [part~='resize-button'] .icon::before {
217
+ transform: scaleX(-1);
186
218
  }
187
219
 
188
- :host([dir='rtl']) #resize-handle .icon::before {
189
- transform: rotate(45deg);
190
- }
220
+ /* Accessible resize mode controls */
191
221
 
192
- /* Resize mode styling */
193
- #resize-apply {
222
+ [part~='resize-apply-button'] {
194
223
  --icon: var(--lumo-icons-checkmark);
195
224
  font-size: var(--lumo-icon-size-m);
196
225
  }
197
226
 
198
- #resize-grow-width,
199
- #resize-shrink-width {
227
+ [part~='resize-grow-width-button'],
228
+ [part~='resize-shrink-width-button'] {
200
229
  padding-right: 0;
201
230
  padding-left: 0;
202
231
  min-width: var(--lumo-size-s);
203
232
  }
204
233
 
205
- #resize-grow-height,
206
- #resize-shrink-height {
234
+ [part~='resize-shrink-width-button'] + [part~='resize-grow-width-button'] {
235
+ margin-left: 1px;
236
+ }
237
+
238
+ [part~='resize-grow-height-button'],
239
+ [part~='resize-shrink-height-button'] {
207
240
  height: var(--lumo-size-s);
208
- margin: 0;
241
+ padding-right: 0;
242
+ padding-left: 0;
209
243
  }
210
244
 
211
- :host(:not([dir='rtl'])) #resize-shrink-width,
212
- :host([dir='rtl']) #resize-grow-width {
245
+ [part~='resize-shrink-height-button'] + [part~='resize-grow-height-button'] {
246
+ margin-top: 1px;
247
+ }
248
+
249
+ :host(:not([dir='rtl'])) [part~='resize-grow-width-button'],
250
+ :host(:not([dir='rtl'])) [part~='resize-shrink-width-button'] {
213
251
  border-top-right-radius: 0;
214
252
  border-bottom-right-radius: 0;
215
- --icon: var(--lumo-icons-angle-left);
216
253
  }
217
254
 
218
- :host(:not([dir='rtl'])) #resize-grow-width,
219
- :host([dir='rtl']) #resize-shrink-width {
255
+ :host([dir='rtl']) [part~='resize-grow-width-button'],
256
+ :host([dir='rtl']) [part~='resize-shrink-width-button'] {
220
257
  border-top-left-radius: 0;
221
258
  border-bottom-left-radius: 0;
222
- --icon: var(--lumo-icons-angle-right);
223
259
  }
224
260
 
225
- #resize-grow-height {
226
- border-top-right-radius: 0;
261
+ :host(:not([dir='rtl'])) [part~='resize-shrink-width-button']:not([hidden]) + [part~='resize-grow-width-button'] {
227
262
  border-top-left-radius: 0;
228
- --icon: var(--lumo-icons-angle-down);
263
+ border-bottom-left-radius: 0;
229
264
  }
230
265
 
231
- #resize-shrink-height {
266
+ :host([dir='rtl']) [part~='resize-shrink-width-button']:not([hidden]) + [part~='resize-grow-width-button'] {
267
+ border-top-right-radius: 0;
232
268
  border-bottom-right-radius: 0;
269
+ }
270
+
271
+ [part~='resize-grow-height-button'],
272
+ [part~='resize-grow-width-button'] {
273
+ --icon: var(--lumo-icons-plus);
274
+ }
275
+
276
+ [part~='resize-shrink-height-button'],
277
+ [part~='resize-shrink-width-button'] {
278
+ --icon: var(--lumo-icons-minus);
279
+ }
280
+
281
+ [part~='resize-grow-height-button'],
282
+ [part~='resize-shrink-height-button'] {
233
283
  border-bottom-left-radius: 0;
234
- --icon: var(--lumo-icons-angle-up);
284
+ border-bottom-right-radius: 0;
285
+ }
286
+
287
+ [part~='resize-shrink-height-button']:not([hidden]) + [part~='resize-grow-height-button'] {
288
+ border-top-left-radius: 0;
289
+ border-top-right-radius: 0;
290
+ }
291
+
292
+ /* Windows High Contrast Mode */
293
+ @media (forced-colors: active) {
294
+ :host {
295
+ border: 1px solid;
296
+ }
297
+ :host([focused]) {
298
+ outline: 2px solid;
299
+ outline-offset: 1px;
300
+ }
301
+ :host([selected]) {
302
+ outline-width: 1px;
303
+ outline-offset: 0px;
304
+ outline-color: Highlight;
305
+ }
306
+ :host([selected][focused]) {
307
+ outline-width: 3px;
308
+ outline-offset: 0px;
309
+ }
235
310
  }
236
311
  `;
237
312
 
package/web-types.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/dashboard",
4
- "version": "24.6.0-alpha9",
4
+ "version": "24.6.0-rc1",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
8
8
  "elements": [
9
9
  {
10
10
  "name": "vaadin-dashboard-layout",
11
- "description": "A responsive, grid-based dashboard layout component\n\n```html\n<vaadin-dashboard-layout>\n <vaadin-dashboard-widget widget-title=\"Widget 1\"></vaadin-dashboard-widget>\n <vaadin-dashboard-widget widget-title=\"Widget 2\"></vaadin-dashboard-widget>\n <vaadin-dashboard-section section-title=\"Section\">\n <vaadin-dashboard-widget widget-title=\"Widget in Section\"></vaadin-dashboard-widget>\n </vaadin-dashboard-section>\n</vaadin-dashboard-layout>\n```\n\n### Styling\n\nThe following custom properties are available:\n\nCustom Property | Description\n------------------------------------|-------------\n`--vaadin-dashboard-col-min-width` | minimum column width of the layout\n`--vaadin-dashboard-col-max-width` | maximum column width of the layout\n`--vaadin-dashboard-row-min-height` | minimum row height of the layout\n`--vaadin-dashboard-col-max-count` | maximum column count of the layout\n`--vaadin-dashboard-spacing` | spacing between child elements and space around its outer edges. Must be in length units (0 is not allowed, 0px is)\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------|-------------\n`dense-layout` | Set when the dashboard is in dense mode.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
11
+ "description": "A responsive, grid-based dashboard layout component\n\n```html\n<vaadin-dashboard-layout>\n <vaadin-dashboard-widget widget-title=\"Widget 1\"></vaadin-dashboard-widget>\n <vaadin-dashboard-widget widget-title=\"Widget 2\"></vaadin-dashboard-widget>\n <vaadin-dashboard-section section-title=\"Section\">\n <vaadin-dashboard-widget widget-title=\"Widget in Section\"></vaadin-dashboard-widget>\n </vaadin-dashboard-section>\n</vaadin-dashboard-layout>\n```\n\n### Styling\n\nThe following custom properties are available:\n\nCustom Property | Description\n------------------------------------|-------------\n`--vaadin-dashboard-col-min-width` | minimum column width of the layout\n`--vaadin-dashboard-col-max-width` | maximum column width of the layout\n`--vaadin-dashboard-row-min-height` | minimum row height of the layout\n`--vaadin-dashboard-col-max-count` | maximum column count of the layout\n`--vaadin-dashboard-gap` | gap between child elements. Must be in length units (0 is not allowed, 0px is)\n`--vaadin-dashboard-padding` | space around the dashboard's outer edges. Must be in length units (0 is not allowed, 0px is)\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------|-------------\n`dense-layout` | Set when the dashboard is in dense mode.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
12
12
  "attributes": [
13
13
  {
14
14
  "name": "dense-layout",
@@ -136,7 +136,7 @@
136
136
  },
137
137
  {
138
138
  "name": "vaadin-dashboard",
139
- "description": "A responsive, grid-based dashboard layout component\n\n### Quick Start\n\nAssign an array to the [`items`](https://cdn.vaadin.com/vaadin-web-components/24.6.0-alpha9/#/elements/vaadin-dashboard#property-items) property.\nSet a renderer function to the [`renderer`](https://cdn.vaadin.com/vaadin-web-components/24.6.0-alpha9/#/elements/vaadin-dashboard#property-renderer) property.\n\nThe widgets and the sections will be generated and configured based on the renderer and the items provided.\n\n```html\n<vaadin-dashboard></vaadin-dashboard>\n```\n```js\nconst dashboard = document.querySelector('vaadin-dashboard');\n\ndashboard.items = [\n { title: 'Widget 1 title', content: 'Text 1', rowspan: 2 },\n { title: 'Widget 2 title', content: 'Text 2', colspan: 2 },\n {\n title: 'Section title',\n items: [{ title: 'Widget in section title', content: 'Text 3' }]\n },\n // ... more items\n];\n\ndashboard.renderer = (root, _dashboard, { item }) => {\n const widget = root.firstElementChild || document.createElement('vaadin-dashboard-widget');\n if (!root.contains(widget)) {\n root.appendChild(widget);\n }\n widget.widgetTitle = item.title;\n widget.textContent = item.content;\n};\n```\n\n### Styling\n\nThe following custom properties are available:\n\nCustom Property | Description\n------------------------------------|-------------\n`--vaadin-dashboard-col-min-width` | minimum column width of the dashboard\n`--vaadin-dashboard-col-max-width` | maximum column width of the dashboard\n`--vaadin-dashboard-row-min-height` | minimum row height of the dashboard\n`--vaadin-dashboard-col-max-count` | maximum column count of the dashboard\n`--vaadin-dashboard-spacing` | spacing between child elements and space around its outer edges. Must be in length units (0 is not allowed, 0px is)\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------|-------------\n`editable` | Set when the dashboard is editable.\n`dense-layout` | Set when the dashboard is in dense mode.\n`item-selected`| Set when an item is selected.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
139
+ "description": "A responsive, grid-based dashboard layout component\n\n### Quick Start\n\nAssign an array to the [`items`](https://cdn.vaadin.com/vaadin-web-components/24.6.0-rc1/#/elements/vaadin-dashboard#property-items) property.\nSet a renderer function to the [`renderer`](https://cdn.vaadin.com/vaadin-web-components/24.6.0-rc1/#/elements/vaadin-dashboard#property-renderer) property.\n\nThe widgets and the sections will be generated and configured based on the renderer and the items provided.\n\n```html\n<vaadin-dashboard></vaadin-dashboard>\n```\n```js\nconst dashboard = document.querySelector('vaadin-dashboard');\n\ndashboard.items = [\n { title: 'Widget 1 title', content: 'Text 1', rowspan: 2 },\n { title: 'Widget 2 title', content: 'Text 2', colspan: 2 },\n {\n title: 'Section title',\n items: [{ title: 'Widget in section title', content: 'Text 3' }]\n },\n // ... more items\n];\n\ndashboard.renderer = (root, _dashboard, { item }) => {\n const widget = root.firstElementChild || document.createElement('vaadin-dashboard-widget');\n if (!root.contains(widget)) {\n root.appendChild(widget);\n }\n widget.widgetTitle = item.title;\n widget.textContent = item.content;\n};\n```\n\n### Styling\n\nThe following custom properties are available:\n\nCustom Property | Description\n------------------------------------|-------------\n`--vaadin-dashboard-col-min-width` | minimum column width of the dashboard\n`--vaadin-dashboard-col-max-width` | maximum column width of the dashboard\n`--vaadin-dashboard-row-min-height` | minimum row height of the dashboard\n`--vaadin-dashboard-col-max-count` | maximum column count of the dashboard\n`--vaadin-dashboard-gap` | gap between child elements. Must be in length units (0 is not allowed, 0px is)\n`--vaadin-dashboard-padding` | space around the dashboard's outer edges. Must be in length units (0 is not allowed, 0px is)\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------|-------------\n`editable` | Set when the dashboard is editable.\n`dense-layout` | Set when the dashboard is in dense mode.\n`item-selected`| Set when an item is selected.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
140
140
  "attributes": [
141
141
  {
142
142
  "name": "dense-layout",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/dashboard",
4
- "version": "24.6.0-alpha9",
4
+ "version": "24.6.0-rc1",
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-dashboard-layout",
19
- "description": "A responsive, grid-based dashboard layout component\n\n```html\n<vaadin-dashboard-layout>\n <vaadin-dashboard-widget widget-title=\"Widget 1\"></vaadin-dashboard-widget>\n <vaadin-dashboard-widget widget-title=\"Widget 2\"></vaadin-dashboard-widget>\n <vaadin-dashboard-section section-title=\"Section\">\n <vaadin-dashboard-widget widget-title=\"Widget in Section\"></vaadin-dashboard-widget>\n </vaadin-dashboard-section>\n</vaadin-dashboard-layout>\n```\n\n### Styling\n\nThe following custom properties are available:\n\nCustom Property | Description\n------------------------------------|-------------\n`--vaadin-dashboard-col-min-width` | minimum column width of the layout\n`--vaadin-dashboard-col-max-width` | maximum column width of the layout\n`--vaadin-dashboard-row-min-height` | minimum row height of the layout\n`--vaadin-dashboard-col-max-count` | maximum column count of the layout\n`--vaadin-dashboard-spacing` | spacing between child elements and space around its outer edges. Must be in length units (0 is not allowed, 0px is)\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------|-------------\n`dense-layout` | Set when the dashboard is in dense mode.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
19
+ "description": "A responsive, grid-based dashboard layout component\n\n```html\n<vaadin-dashboard-layout>\n <vaadin-dashboard-widget widget-title=\"Widget 1\"></vaadin-dashboard-widget>\n <vaadin-dashboard-widget widget-title=\"Widget 2\"></vaadin-dashboard-widget>\n <vaadin-dashboard-section section-title=\"Section\">\n <vaadin-dashboard-widget widget-title=\"Widget in Section\"></vaadin-dashboard-widget>\n </vaadin-dashboard-section>\n</vaadin-dashboard-layout>\n```\n\n### Styling\n\nThe following custom properties are available:\n\nCustom Property | Description\n------------------------------------|-------------\n`--vaadin-dashboard-col-min-width` | minimum column width of the layout\n`--vaadin-dashboard-col-max-width` | maximum column width of the layout\n`--vaadin-dashboard-row-min-height` | minimum row height of the layout\n`--vaadin-dashboard-col-max-count` | maximum column count of the layout\n`--vaadin-dashboard-gap` | gap between child elements. Must be in length units (0 is not allowed, 0px is)\n`--vaadin-dashboard-padding` | space around the dashboard's outer edges. Must be in length units (0 is not allowed, 0px is)\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------|-------------\n`dense-layout` | Set when the dashboard is in dense mode.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
20
20
  "extension": true,
21
21
  "attributes": [
22
22
  {
@@ -58,7 +58,7 @@
58
58
  },
59
59
  {
60
60
  "name": "vaadin-dashboard",
61
- "description": "A responsive, grid-based dashboard layout component\n\n### Quick Start\n\nAssign an array to the [`items`](https://cdn.vaadin.com/vaadin-web-components/24.6.0-alpha9/#/elements/vaadin-dashboard#property-items) property.\nSet a renderer function to the [`renderer`](https://cdn.vaadin.com/vaadin-web-components/24.6.0-alpha9/#/elements/vaadin-dashboard#property-renderer) property.\n\nThe widgets and the sections will be generated and configured based on the renderer and the items provided.\n\n```html\n<vaadin-dashboard></vaadin-dashboard>\n```\n```js\nconst dashboard = document.querySelector('vaadin-dashboard');\n\ndashboard.items = [\n { title: 'Widget 1 title', content: 'Text 1', rowspan: 2 },\n { title: 'Widget 2 title', content: 'Text 2', colspan: 2 },\n {\n title: 'Section title',\n items: [{ title: 'Widget in section title', content: 'Text 3' }]\n },\n // ... more items\n];\n\ndashboard.renderer = (root, _dashboard, { item }) => {\n const widget = root.firstElementChild || document.createElement('vaadin-dashboard-widget');\n if (!root.contains(widget)) {\n root.appendChild(widget);\n }\n widget.widgetTitle = item.title;\n widget.textContent = item.content;\n};\n```\n\n### Styling\n\nThe following custom properties are available:\n\nCustom Property | Description\n------------------------------------|-------------\n`--vaadin-dashboard-col-min-width` | minimum column width of the dashboard\n`--vaadin-dashboard-col-max-width` | maximum column width of the dashboard\n`--vaadin-dashboard-row-min-height` | minimum row height of the dashboard\n`--vaadin-dashboard-col-max-count` | maximum column count of the dashboard\n`--vaadin-dashboard-spacing` | spacing between child elements and space around its outer edges. Must be in length units (0 is not allowed, 0px is)\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------|-------------\n`editable` | Set when the dashboard is editable.\n`dense-layout` | Set when the dashboard is in dense mode.\n`item-selected`| Set when an item is selected.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
61
+ "description": "A responsive, grid-based dashboard layout component\n\n### Quick Start\n\nAssign an array to the [`items`](https://cdn.vaadin.com/vaadin-web-components/24.6.0-rc1/#/elements/vaadin-dashboard#property-items) property.\nSet a renderer function to the [`renderer`](https://cdn.vaadin.com/vaadin-web-components/24.6.0-rc1/#/elements/vaadin-dashboard#property-renderer) property.\n\nThe widgets and the sections will be generated and configured based on the renderer and the items provided.\n\n```html\n<vaadin-dashboard></vaadin-dashboard>\n```\n```js\nconst dashboard = document.querySelector('vaadin-dashboard');\n\ndashboard.items = [\n { title: 'Widget 1 title', content: 'Text 1', rowspan: 2 },\n { title: 'Widget 2 title', content: 'Text 2', colspan: 2 },\n {\n title: 'Section title',\n items: [{ title: 'Widget in section title', content: 'Text 3' }]\n },\n // ... more items\n];\n\ndashboard.renderer = (root, _dashboard, { item }) => {\n const widget = root.firstElementChild || document.createElement('vaadin-dashboard-widget');\n if (!root.contains(widget)) {\n root.appendChild(widget);\n }\n widget.widgetTitle = item.title;\n widget.textContent = item.content;\n};\n```\n\n### Styling\n\nThe following custom properties are available:\n\nCustom Property | Description\n------------------------------------|-------------\n`--vaadin-dashboard-col-min-width` | minimum column width of the dashboard\n`--vaadin-dashboard-col-max-width` | maximum column width of the dashboard\n`--vaadin-dashboard-row-min-height` | minimum row height of the dashboard\n`--vaadin-dashboard-col-max-count` | maximum column count of the dashboard\n`--vaadin-dashboard-gap` | gap between child elements. Must be in length units (0 is not allowed, 0px is)\n`--vaadin-dashboard-padding` | space around the dashboard's outer edges. Must be in length units (0 is not allowed, 0px is)\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------|-------------\n`editable` | Set when the dashboard is editable.\n`dense-layout` | Set when the dashboard is in dense mode.\n`item-selected`| Set when an item is selected.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
62
62
  "extension": true,
63
63
  "attributes": [
64
64
  {