@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 +2 -0
- package/package.json +8 -8
- package/src/keyboard-controller.js +0 -8
- package/src/vaadin-dashboard-helpers.js +4 -0
- package/src/vaadin-dashboard-item-mixin.js +28 -3
- package/src/vaadin-dashboard-layout-mixin.js +12 -6
- package/src/vaadin-dashboard-layout.d.ts +2 -1
- package/src/vaadin-dashboard-layout.js +2 -1
- package/src/vaadin-dashboard-section.js +4 -2
- package/src/vaadin-dashboard-styles.js +45 -32
- package/src/vaadin-dashboard-widget.js +8 -6
- package/src/vaadin-dashboard.d.ts +2 -1
- package/src/vaadin-dashboard.js +21 -3
- package/src/widget-resize-controller.js +2 -2
- package/theme/lumo/vaadin-dashboard-layout-styles.js +2 -1
- package/theme/lumo/vaadin-dashboard-section-styles.js +65 -1
- package/theme/lumo/vaadin-dashboard-widget-styles.js +199 -124
- package/web-types.json +3 -3
- package/web-types.lit.json +3 -3
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-
|
|
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-
|
|
41
|
-
"@vaadin/component-base": "24.6.0-
|
|
42
|
-
"@vaadin/vaadin-lumo-styles": "24.6.0-
|
|
43
|
-
"@vaadin/vaadin-material-styles": "24.6.0-
|
|
44
|
-
"@vaadin/vaadin-themable-mixin": "24.6.0-
|
|
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-
|
|
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": "
|
|
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) {
|
|
@@ -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
|
|
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
|
|
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
|
-
|
|
40
|
-
|
|
40
|
+
|
|
41
|
+
/* Padding around dashboard edges */
|
|
42
|
+
--_vaadin-dashboard-default-padding: 1rem;
|
|
43
|
+
--_vaadin-dashboard-padding: max(
|
|
41
44
|
0px,
|
|
42
|
-
var(--vaadin-dashboard-
|
|
45
|
+
var(--vaadin-dashboard-padding, var(--_vaadin-dashboard-default-padding))
|
|
43
46
|
);
|
|
44
|
-
padding: var(--_vaadin-dashboard-
|
|
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-
|
|
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-
|
|
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-
|
|
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.
|
|
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]))
|
|
34
|
-
:host(:not([editable]))
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
|
|
80
|
+
[part~='move-backward-button'] {
|
|
86
81
|
inset-inline-start: 0;
|
|
87
82
|
transform: translateY(-50%);
|
|
88
83
|
}
|
|
89
84
|
|
|
90
|
-
|
|
85
|
+
[part~='move-forward-button'] {
|
|
91
86
|
inset-inline-end: 0;
|
|
92
87
|
transform: translateY(-50%);
|
|
93
88
|
}
|
|
94
89
|
|
|
95
|
-
|
|
90
|
+
[part~='move-apply-button'] {
|
|
96
91
|
left: 50%;
|
|
97
92
|
transform: translate(-50%, -50%);
|
|
98
93
|
}
|
|
99
94
|
|
|
100
|
-
:host([first-child])
|
|
101
|
-
:host([last-child])
|
|
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
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
-
|
|
115
|
-
inset-inline-end:
|
|
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
|
-
|
|
121
|
-
inset-inline-start:
|
|
126
|
+
[part~='resize-grow-width-button'] {
|
|
127
|
+
inset-inline-start: 100%;
|
|
122
128
|
top: 50%;
|
|
123
|
-
transform: translateY(-50%);
|
|
124
129
|
}
|
|
125
130
|
|
|
126
|
-
|
|
127
|
-
|
|
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
|
-
|
|
133
|
-
top:
|
|
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
|
-
|
|
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]))
|
|
121
|
+
:host(:not([editable])) [part~='resize-button'] {
|
|
122
122
|
display: none;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
[part~='content'] {
|
|
126
126
|
flex: 1;
|
|
127
127
|
overflow: hidden;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
|
|
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
|
-
|
|
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.
|
|
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-
|
|
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
|
*
|
package/src/vaadin-dashboard.js
CHANGED
|
@@ -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-
|
|
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('
|
|
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('
|
|
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-
|
|
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
|
-
--
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
--
|
|
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([
|
|
41
|
-
|
|
44
|
+
:host([selected]) {
|
|
45
|
+
opacity: 1;
|
|
46
|
+
z-index: 1;
|
|
42
47
|
}
|
|
43
48
|
|
|
44
|
-
:host([
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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-
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
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
|
-
|
|
78
|
-
|
|
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
|
|
82
|
-
|
|
98
|
+
/* Drag handle */
|
|
99
|
+
[part~='move-button'] {
|
|
83
100
|
cursor: move;
|
|
84
|
-
--icon: var(--lumo-icons-
|
|
101
|
+
--icon: var(--lumo-icons-drag-handle);
|
|
85
102
|
}
|
|
86
103
|
|
|
87
|
-
/* Remove button
|
|
88
|
-
|
|
104
|
+
/* Remove button */
|
|
105
|
+
[part~='remove-button'] {
|
|
89
106
|
cursor: pointer;
|
|
90
107
|
--icon: var(--lumo-icons-cross);
|
|
91
108
|
}
|
|
92
109
|
|
|
93
|
-
/*
|
|
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
|
|
115
|
+
/* Move mode */
|
|
115
116
|
|
|
116
|
-
|
|
117
|
-
|
|
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']))
|
|
133
|
-
:host([dir='rtl'])
|
|
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
|
-
|
|
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
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
-
|
|
153
|
-
|
|
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
|
-
|
|
158
|
+
--_shadow: var(--vaadin-dashboard-widget-selected-shadow);
|
|
159
|
+
background: var(--lumo-primary-color-10pct);
|
|
158
160
|
}
|
|
159
161
|
|
|
160
|
-
:host([
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
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
|
-
|
|
172
|
-
|
|
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(--
|
|
175
|
-
inset-inline-end: var(--
|
|
176
|
-
cursor:
|
|
177
|
-
--icon: var(--lumo-icons-
|
|
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'])
|
|
212
|
+
:host([dir='rtl']) [part~='resize-button'] {
|
|
181
213
|
cursor: sw-resize;
|
|
182
214
|
}
|
|
183
215
|
|
|
184
|
-
|
|
185
|
-
transform:
|
|
216
|
+
:host([dir='rtl']) [part~='resize-button'] .icon::before {
|
|
217
|
+
transform: scaleX(-1);
|
|
186
218
|
}
|
|
187
219
|
|
|
188
|
-
|
|
189
|
-
transform: rotate(45deg);
|
|
190
|
-
}
|
|
220
|
+
/* Accessible resize mode controls */
|
|
191
221
|
|
|
192
|
-
|
|
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
|
-
|
|
199
|
-
|
|
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
|
-
|
|
206
|
-
|
|
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
|
-
|
|
241
|
+
padding-right: 0;
|
|
242
|
+
padding-left: 0;
|
|
209
243
|
}
|
|
210
244
|
|
|
211
|
-
|
|
212
|
-
|
|
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(
|
|
219
|
-
:host([dir='rtl'])
|
|
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
|
-
|
|
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
|
-
|
|
263
|
+
border-bottom-left-radius: 0;
|
|
229
264
|
}
|
|
230
265
|
|
|
231
|
-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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",
|
package/web-types.lit.json
CHANGED
|
@@ -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-
|
|
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-
|
|
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-
|
|
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
|
{
|