Skip to content

Commit 56bdf47

Browse files
authored
feat: Aura button, button-like and input-field-like components (#10157)
1 parent 20743c1 commit 56bdf47

22 files changed

+682
-34
lines changed
Lines changed: 5 additions & 0 deletions
Loading

dev/assets/lucide-icons/folder.svg

Lines changed: 5 additions & 0 deletions
Loading

dev/aura.html

Lines changed: 292 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,25 @@
2121
import '@vaadin/app-layout';
2222
import '@vaadin/app-layout/src/vaadin-drawer-toggle.js';
2323
import '@vaadin/avatar';
24-
import '@vaadin/button';
2524
import '@vaadin/checkbox';
25+
import '@vaadin/checkbox-group';
26+
import '@vaadin/combo-box';
27+
import '@vaadin/date-time-picker';
2628
import '@vaadin/icon';
2729
import '@vaadin/master-detail-layout';
30+
import '@vaadin/menu-bar';
31+
import '@vaadin/message-list';
32+
import '@vaadin/message-input';
33+
import '@vaadin/multi-select-combo-box';
2834
import '@vaadin/popover';
35+
import '@vaadin/radio-group';
36+
import '@vaadin/select';
37+
import '@vaadin/scroller';
2938
import '@vaadin/side-nav';
39+
import '@vaadin/text-field';
3040
import '@vaadin/vertical-layout';
41+
import { html, render } from 'lit';
42+
import { Button } from '@vaadin/button';
3143

3244
function clearLocalStorage() {
3345
for (let i = localStorage.length - 1; i >= 0; i--) {
@@ -44,27 +56,146 @@
4456
});
4557

4658
document.querySelector('#useNavbar').addEventListener('change', (e) => {
59+
const drawerToggle = document.querySelector('vaadin-app-layout > header[slot] vaadin-drawer-toggle');
4760
if (e.target.checked) {
4861
document.querySelector('vaadin-app-layout > header[slot]').setAttribute('slot', 'navbar');
4962
document.querySelector('vaadin-app-layout > footer[slot]').setAttribute('slot', 'navbar');
63+
document.querySelector('vaadin-app-layout > header[slot]').prepend(drawerToggle);
5064
} else {
5165
document.querySelector('vaadin-app-layout > header[slot]').setAttribute('slot', 'drawer');
5266
document.querySelector('vaadin-app-layout > footer[slot]').setAttribute('slot', 'drawer');
67+
document.querySelector('vaadin-app-layout > header[slot]').append(drawerToggle);
5368
}
5469
});
70+
71+
function initComponentsView() {
72+
const view = document.querySelector('.components-view');
73+
74+
// Menu Bar
75+
view.querySelector('vaadin-menu-bar').items = [
76+
{
77+
text: 'Actions',
78+
children: [
79+
{ text: 'Edit' },
80+
{ text: 'Duplicate' },
81+
{ component: 'hr' },
82+
{ text: 'Archive' },
83+
{
84+
text: 'More',
85+
children: [
86+
{ text: 'Move to Project…' },
87+
{ text: 'Move to Folder…' },
88+
{ component: 'hr' },
89+
{ text: 'Advanced Options…' },
90+
],
91+
},
92+
{ component: 'hr' },
93+
{ text: 'Share' },
94+
{ text: 'Add to Favorites' },
95+
{ component: 'hr' },
96+
{ text: 'Delete', theme: 'danger' },
97+
],
98+
},
99+
];
100+
101+
// Select
102+
view.querySelector('vaadin-select').renderer = (root) => {
103+
render(
104+
html`
105+
<vaadin-select-list-box>
106+
<vaadin-select-item value="1">Option 1</vaadin-select-item>
107+
<vaadin-select-item value="2">Option 2</vaadin-select-item>
108+
<vaadin-select-item value="3">Option 3</vaadin-select-item>
109+
</vaadin-select-list-box>
110+
`,
111+
root,
112+
);
113+
};
114+
view.querySelector('vaadin-select').value = '1';
115+
116+
// Combo Box
117+
view.querySelectorAll('vaadin-combo-box, vaadin-multi-select-combo-box').forEach((comboBox) => {
118+
comboBox.dataProvider = async (params, callback) => {
119+
const index = params.page * params.pageSize;
120+
const response = await fetch(
121+
`https://demo.vaadin.com/demo-data/1.0/filtered-countries?index=${index}&count=${params.pageSize}&filter=${params.filter}`,
122+
);
123+
if (response.ok) {
124+
const { result, size } = await response.json();
125+
// Emulate network latency for demo purpose
126+
setTimeout(() => {
127+
callback(result, size);
128+
}, 1000);
129+
}
130+
};
131+
132+
if (!comboBox.placeholder) {
133+
if (comboBox.localName.startsWith('vaadin-multi-select')) {
134+
comboBox.selectedItems = ['Andorra', 'United Arab Emirates'];
135+
} else {
136+
comboBox.selectedItem = 'Andorra';
137+
}
138+
}
139+
});
140+
141+
// Message List
142+
view.querySelector('vaadin-message-list').items = [
143+
{
144+
userName: 'Matt Mambo',
145+
text: 'Nature does not hurry, yet everything gets accomplished.',
146+
time: '2 minutes ago',
147+
userColorIndex: 1,
148+
},
149+
{
150+
userName: 'Lindsey Listy',
151+
text: 'Using your talent, hobby or profession in a way that makes you contribute with something good to this world is truly the way to go.',
152+
time: 'just now',
153+
userColorIndex: 2,
154+
},
155+
];
156+
}
157+
158+
initComponentsView();
159+
160+
customElements.define(
161+
'mdl-back-button',
162+
class extends Button {
163+
constructor() {
164+
super();
165+
this.setAttribute('theme', 'tertiary');
166+
const icon = document.createElement('vaadin-icon');
167+
icon.setAttribute('src', './assets/lucide-icons/arrow-left.svg');
168+
this.append(icon);
169+
this.addEventListener('click', () => {
170+
const inner = this.closest('[slot="detail"]');
171+
const outer = inner.parentNode.closest('vaadin-master-detail-layout');
172+
outer?._setDetail(null);
173+
});
174+
}
175+
},
176+
);
55177
</script>
56178

57179
<style>
58180
html {
59181
--icon-rotate-ccw: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg>');
60182
}
183+
184+
/* TODO re-evaluate MDL API, how to achieve this */
185+
.dashboard-section::part(master) {
186+
flex-basis: 15%;
187+
}
188+
189+
.dashboard-section::part(detail) {
190+
flex-basis: 85%;
191+
}
61192
</style>
62193
</head>
63194
<body>
64195
<vaadin-app-layout>
65196
<header slot="drawer" class="aura-view-header">
66-
<vaadin-drawer-toggle theme="tertiary"></vaadin-drawer-toggle>
67197
<div class="aura-view-heading">Aura</div>
198+
<vaadin-drawer-toggle theme="tertiary permanent"></vaadin-drawer-toggle>
68199
</header>
69200

70201
<vaadin-scroller slot="drawer" theme="overflow-indicators">
@@ -164,15 +295,167 @@ <h1>Dashboard</h1>
164295

165296
<main class="aura-view" slot="detail">
166297
<header>
167-
<vaadin-drawer-toggle theme="tertiary"></vaadin-drawer-toggle>
298+
<mdl-back-button></mdl-back-button>
168299
<h1>Components</h1>
169300
</header>
170-
<vaadin-vertical-layout theme="padding">
171-
<div theme="surface" style="padding: 2em; --aura-surface-level: 1">Level 1</div>
172-
<div theme="surface" style="padding: 2em; --aura-surface-level: 2">Level 2</div>
173-
<div theme="surface" style="padding: 2em; --aura-surface-level: 3">Level 3</div>
174-
<div theme="surface" style="padding: 2em; --aura-surface-level: 4">Level 4</div>
175-
</vaadin-vertical-layout>
301+
<vaadin-scroller theme="overflow-indicator-top">
302+
<style>
303+
.components-view {
304+
container-type: inline-size;
305+
container-name: kitchen-sink;
306+
}
307+
308+
.components-view .grid {
309+
display: grid;
310+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
311+
grid-auto-flow: dense;
312+
--vaadin-field-default-width: 100%;
313+
align-items: stretch;
314+
gap: var(--vaadin-gap-s);
315+
padding: var(--vaadin-padding-l) var(--vaadin-padding-xs);
316+
padding-top: 0;
317+
}
318+
319+
.components-view .component {
320+
display: flex;
321+
height: 200px;
322+
align-items: center;
323+
justify-content: center;
324+
border-radius: var(--vaadin-radius-m);
325+
border: 1px solid var(--vaadin-border-color-subtle);
326+
gap: var(--vaadin-gap-s);
327+
padding: var(--vaadin-padding-l);
328+
box-sizing: border-box;
329+
position: relative;
330+
overflow: hidden;
331+
background: var(--aura-surface);
332+
--aura-surface-level: 3;
333+
background-clip: padding-box;
334+
}
335+
336+
.components-view .component.column {
337+
flex-direction: column;
338+
}
339+
340+
.components-view .component.tall {
341+
height: 100%;
342+
min-height: 400px;
343+
grid-row: auto / span 2;
344+
}
345+
346+
@container kitchen-sink (min-width: 400px) {
347+
.components-view .component.wide,
348+
.components-view .component.widest {
349+
grid-column: auto / span 2;
350+
}
351+
}
352+
353+
@container kitchen-sink (min-width: 600px) {
354+
.components-view .component.widest {
355+
grid-column: auto / span 3;
356+
}
357+
}
358+
359+
.components-view .component.no-padding {
360+
padding: 0;
361+
}
362+
363+
.components-view .sizes {
364+
display: flex;
365+
flex-direction: column;
366+
gap: 4px;
367+
}
368+
369+
.components-view .sizes > div {
370+
background: currentColor;
371+
height: 4px;
372+
width: var(--size);
373+
}
374+
</style>
375+
<div class="components-view">
376+
<div class="grid">
377+
<div class="component wide" theme="surface">
378+
<vaadin-button theme="primary">Primary</vaadin-button>
379+
<vaadin-button>Default</vaadin-button>
380+
<vaadin-button theme="tertiary">Tertiary</vaadin-button>
381+
</div>
382+
383+
<div class="component" theme="surface">
384+
<vaadin-radio-group label="Options">
385+
<vaadin-radio-button label="Option 1" value="1" checked></vaadin-radio-button>
386+
<vaadin-radio-button label="Option 2" value="2"></vaadin-radio-button>
387+
<vaadin-radio-button label="Option 3" value="3"></vaadin-radio-button>
388+
</vaadin-radio-group>
389+
</div>
390+
391+
<div class="component" theme="surface">
392+
<vaadin-menu-bar></vaadin-menu-bar>
393+
</div>
394+
395+
<div class="component wide" theme="surface">
396+
<vaadin-date-time-picker style="width: 20em" value="2025-09-09T12:00"></vaadin-date-time-picker>
397+
</div>
398+
399+
<div class="component" theme="surface">
400+
<div class="sizes">
401+
<h5>Sizes</h5>
402+
<div class="xs" style="--size: var(--vaadin-padding-xs)"></div>
403+
<div class="s" style="--size: var(--vaadin-padding-s)"></div>
404+
<div class="m" style="--size: var(--vaadin-padding-m)"></div>
405+
<div class="l" style="--size: var(--vaadin-padding-l)"></div>
406+
<div class="xl" style="--size: var(--vaadin-padding-xl)"></div>
407+
</div>
408+
</div>
409+
410+
<div class="component" theme="surface">
411+
<vaadin-checkbox-group label="Options">
412+
<vaadin-checkbox label="Option 1" value="1" checked></vaadin-checkbox>
413+
<vaadin-checkbox label="Option 2" value="2"></vaadin-checkbox>
414+
<vaadin-checkbox label="Option 3" value="3"></vaadin-checkbox>
415+
</vaadin-checkbox-group>
416+
</div>
417+
418+
<div class="component" theme="surface">
419+
<vaadin-combo-box item-label-path="name" item-value-path="id" label="Country"></vaadin-combo-box>
420+
</div>
421+
422+
<div class="component" theme="surface">
423+
<div class="type-scale">
424+
<h1>Heading</h1>
425+
<h2>Heading</h2>
426+
<h3>Heading</h3>
427+
<h4>Heading</h4>
428+
<h5>Heading</h5>
429+
<h6>Heading</h6>
430+
</div>
431+
</div>
432+
433+
<div class="component wide" theme="surface">
434+
<vaadin-select label="Options"></vaadin-select>
435+
</div>
436+
437+
<div class="component tall wide column" theme="surface">
438+
<vaadin-message-list></vaadin-message-list>
439+
<vaadin-message-input></vaadin-message-input>
440+
</div>
441+
442+
<div class="component" theme="surface">
443+
<vaadin-text-field clear-button-visible value="Projects">
444+
<vaadin-icon src="./assets/lucide-icons/folder.svg" slot="prefix"></vaadin-icon>
445+
</vaadin-text-field>
446+
</div>
447+
448+
<div class="component wide" theme="surface">
449+
<vaadin-multi-select-combo-box
450+
class="Countries"
451+
class="w-full"
452+
item-label-path="name"
453+
item-value-path="id"
454+
></vaadin-multi-select-combo-box>
455+
</div>
456+
</div>
457+
</div>
458+
</vaadin-scroller>
176459
</main>
177460
</vaadin-master-detail-layout>
178461
</vaadin-app-layout>

dev/aura/aura-number-control.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class AuraNumberControl extends AuraControl {
5757
this.#root = shadow;
5858
this.#input = shadow.getElementById('slider');
5959
this.#output = shadow.getElementById('val');
60-
this.#resetBtn = shadow.querySelector('vaadin-button.reset');
60+
this.#resetBtn = shadow.getElementById('reset');
6161
}
6262

6363
attributeChangedCallback(name, _old, val) {

dev/aura/aura-view.css

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,18 @@
2929
color: var(--vaadin-color);
3030
flex: 1;
3131

32+
&:first-child {
33+
padding-inline-start: var(--vaadin-padding-s);
34+
}
35+
3236
&:last-child {
3337
padding-inline-end: var(--vaadin-padding-s);
3438
}
3539
}
3640

37-
vaadin-app-layout[drawer-opened] :is(.aura-view > header, .aura-view-header) vaadin-drawer-toggle,
41+
:is(vaadin-app-layout[drawer-opened], vaadin-app-layout:has([slot='navbar'] vaadin-drawer-toggle))
42+
:is(.aura-view > header, .aura-view-header)
43+
vaadin-drawer-toggle:not([theme~='permanent']),
3844
vaadin-master-detail-layout:not([drawer], [stack]) [slot='detail'].aura-view > header mdl-back-button,
3945
vaadin-master-detail-layout:not([drawer], [stack]) [slot='detail'] .aura-view > header mdl-back-button {
4046
display: none;

0 commit comments

Comments
 (0)