@vaadin/context-menu 24.0.0-alpha9 → 24.0.0-beta2

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.
@@ -3,37 +3,9 @@
3
3
  * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
+ import './vaadin-context-menu-item.js';
7
+ import './vaadin-context-menu-list-box.js';
6
8
  import { isTouch } from '@vaadin/component-base/src/browser-utils.js';
7
- import { Item } from '@vaadin/item/src/vaadin-item.js';
8
- import { ListBox } from '@vaadin/list-box/src/vaadin-list-box.js';
9
-
10
- /**
11
- * An element used internally by `<vaadin-context-menu>`. Not intended to be used separately.
12
- *
13
- * @extends Item
14
- * @protected
15
- */
16
- class ContextMenuItemElement extends Item {
17
- static get is() {
18
- return 'vaadin-context-menu-item';
19
- }
20
- }
21
-
22
- customElements.define(ContextMenuItemElement.is, ContextMenuItemElement);
23
-
24
- /**
25
- * An element used internally by `<vaadin-context-menu>`. Not intended to be used separately.
26
- *
27
- * @extends ListBox
28
- * @protected
29
- */
30
- class ContextMenuListBox extends ListBox {
31
- static get is() {
32
- return 'vaadin-context-menu-list-box';
33
- }
34
- }
35
-
36
- customElements.define(ContextMenuListBox.is, ContextMenuListBox);
37
9
 
38
10
  /**
39
11
  * @polymerMixin
@@ -65,20 +37,20 @@ export const ItemsMixin = (superClass) =>
65
37
  *
66
38
  * ```javascript
67
39
  * contextMenu.items = [
68
- * {text: 'Menu Item 1', theme: 'primary', children:
40
+ * { text: 'Menu Item 1', theme: 'primary', children:
69
41
  * [
70
- * {text: 'Menu Item 1-1', checked: true},
71
- * {text: 'Menu Item 1-2'}
42
+ * { text: 'Menu Item 1-1', checked: true },
43
+ * { text: 'Menu Item 1-2' }
72
44
  * ]
73
45
  * },
74
- * {component: 'hr'},
75
- * {text: 'Menu Item 2', children:
46
+ * { component: 'hr' },
47
+ * { text: 'Menu Item 2', children:
76
48
  * [
77
- * {text: 'Menu Item 2-1'},
78
- * {text: 'Menu Item 2-2', disabled: true}
49
+ * { text: 'Menu Item 2-1' },
50
+ * { text: 'Menu Item 2-2', disabled: true }
79
51
  * ]
80
52
  * },
81
- * {text: 'Menu Item 3', disabled: true}
53
+ * { text: 'Menu Item 3', disabled: true }
82
54
  * ];
83
55
  * ```
84
56
  *
@@ -98,6 +70,15 @@ export const ItemsMixin = (superClass) =>
98
70
  };
99
71
  }
100
72
 
73
+ /**
74
+ * Tag name prefix used by overlay, list-box and items.
75
+ * @protected
76
+ * @return {string}
77
+ */
78
+ get _tagNamePrefix() {
79
+ return 'vaadin-context-menu';
80
+ }
81
+
101
82
  /** @protected */
102
83
  ready() {
103
84
  super.ready();
@@ -105,7 +86,7 @@ export const ItemsMixin = (superClass) =>
105
86
  // Overlay's outside click listener doesn't work with modeless
106
87
  // overlays (submenus) so we need additional logic for it
107
88
  this.__itemsOutsideClickListener = (e) => {
108
- if (!e.composedPath().some((el) => el.localName === 'vaadin-context-menu-overlay')) {
89
+ if (!e.composedPath().some((el) => el.localName === `${this._tagNamePrefix}-overlay`)) {
109
90
  this.dispatchEvent(new CustomEvent('items-outside-click'));
110
91
  }
111
92
  };
@@ -177,55 +158,216 @@ export const ItemsMixin = (superClass) =>
177
158
  }
178
159
 
179
160
  /**
180
- * @param {!HTMLElement} root
181
- * @param {!ContextMenu} menu
182
- * @param {!ContextMenuRendererContext} context
183
- * @protected
161
+ * @param {!ContextMenuItem} item
162
+ * @return {HTMLElement}
163
+ * @private
184
164
  */
185
- __itemsRenderer(root, menu, context) {
186
- this.__initMenu(root, menu);
165
+ __createComponent(item) {
166
+ let component;
187
167
 
188
- const subMenu = root.querySelector(this.constructor.is);
189
- subMenu.closeOn = menu.closeOn;
168
+ if (item.component instanceof HTMLElement) {
169
+ component = item.component;
170
+ } else {
171
+ component = document.createElement(item.component || `${this._tagNamePrefix}-item`);
172
+ }
190
173
 
191
- const listBox = root.querySelector('vaadin-context-menu-list-box');
174
+ // Support menu-bar / context-menu item
175
+ if (component._hasVaadinItemMixin) {
176
+ component.setAttribute('role', 'menuitem');
177
+ }
192
178
 
193
- listBox.innerHTML = '';
179
+ if (component.localName === 'hr') {
180
+ component.setAttribute('role', 'separator');
181
+ } else {
182
+ // Accept not `menuitem` elements e.g. `<button>`
183
+ component.setAttribute('aria-haspopup', 'false');
184
+ }
194
185
 
195
- const items = Array.from(context.detail.children || menu.items);
186
+ this._setMenuItemTheme(component, item, this._theme);
196
187
 
197
- items.forEach((item) => {
198
- let component;
199
- if (item.component instanceof HTMLElement) {
200
- component = item.component;
201
- } else {
202
- component = document.createElement(item.component || 'vaadin-context-menu-item');
188
+ component._item = item;
189
+
190
+ if (item.text) {
191
+ component.textContent = item.text;
192
+ }
193
+
194
+ this.__toggleMenuComponentAttribute(component, 'menu-item-checked', item.checked);
195
+ this.__toggleMenuComponentAttribute(component, 'disabled', item.disabled);
196
+
197
+ if (item.children && item.children.length) {
198
+ this.__updateExpanded(component, false);
199
+ component.setAttribute('aria-haspopup', 'true');
200
+ }
201
+
202
+ return component;
203
+ }
204
+
205
+ /** @private */
206
+ __initListBox() {
207
+ const listBox = document.createElement(`${this._tagNamePrefix}-list-box`);
208
+
209
+ if (this._theme) {
210
+ listBox.setAttribute('theme', this._theme);
211
+ }
212
+
213
+ listBox.addEventListener('selected-changed', (event) => {
214
+ const { value } = event.detail;
215
+ if (typeof value === 'number') {
216
+ const item = listBox.items[value]._item;
217
+ if (!item.children) {
218
+ this.dispatchEvent(new CustomEvent('item-selected', { detail: { value: item } }));
219
+ }
220
+ listBox.selected = null;
203
221
  }
222
+ });
223
+
224
+ return listBox;
225
+ }
204
226
 
205
- if (component instanceof Item) {
206
- component.setAttribute('role', 'menuitem');
207
- } else if (component.localName === 'hr') {
208
- component.setAttribute('role', 'separator');
227
+ /** @private */
228
+ __initOverlay() {
229
+ const overlay = this.$.overlay;
230
+
231
+ overlay.$.backdrop.addEventListener('click', () => {
232
+ this.close();
233
+ });
234
+
235
+ // Open a submenu on click event when a touch device is used.
236
+ // On desktop, a submenu opens on hover.
237
+ overlay.addEventListener(isTouch ? 'click' : 'mouseover', (event) => {
238
+ this.__showSubMenu(event);
239
+ });
240
+
241
+ overlay.addEventListener('keydown', (event) => {
242
+ const { key } = event;
243
+ const isRTL = this.__isRTL;
244
+
245
+ const isArrowRight = key === 'ArrowRight';
246
+ const isArrowLeft = key === 'ArrowLeft';
247
+
248
+ if ((!isRTL && isArrowRight) || (isRTL && isArrowLeft) || key === 'Enter' || key === ' ') {
249
+ // Open a sub-menu
250
+ this.__showSubMenu(event);
251
+ } else if ((!isRTL && isArrowLeft) || (isRTL && isArrowRight)) {
252
+ // Close the menu
253
+ this.close();
254
+ this.listenOn.focus();
255
+ } else if (key === 'Escape' || key === 'Tab') {
256
+ // Close all menus
257
+ this.dispatchEvent(new CustomEvent('close-all-menus'));
209
258
  }
259
+ });
260
+ }
261
+
262
+ /** @private */
263
+ __initSubMenu() {
264
+ const subMenu = document.createElement(this.constructor.is);
210
265
 
211
- this._setMenuItemTheme(component, item, this._theme);
266
+ subMenu._modeless = true;
267
+ subMenu.openOn = 'opensubmenu';
212
268
 
213
- component._item = item;
269
+ // Sub-menu doesn't have a target to wrap,
270
+ // so there is no need to keep it visible.
271
+ subMenu.setAttribute('hidden', '');
214
272
 
215
- if (item.text) {
216
- component.textContent = item.text;
273
+ // Close sub-menu when the parent menu closes.
274
+ this.addEventListener('opened-changed', (event) => {
275
+ if (!event.detail.value) {
276
+ this._subMenu.close();
217
277
  }
278
+ });
218
279
 
219
- this.__toggleMenuComponentAttribute(component, 'menu-item-checked', item.checked);
220
- this.__toggleMenuComponentAttribute(component, 'disabled', item.disabled);
280
+ // Forward event to the parent menu element.
281
+ subMenu.addEventListener('close-all-menus', () => {
282
+ this.dispatchEvent(new CustomEvent('close-all-menus'));
283
+ });
221
284
 
222
- component.setAttribute('aria-haspopup', 'false');
223
- if (item.children && item.children.length) {
224
- component.setAttribute('aria-haspopup', 'true');
225
- component.setAttribute('aria-expanded', 'false');
226
- component.removeAttribute('expanded');
285
+ // Forward event to the parent menu element.
286
+ subMenu.addEventListener('item-selected', (event) => {
287
+ const { detail } = event;
288
+ this.dispatchEvent(new CustomEvent('item-selected', { detail }));
289
+ });
290
+
291
+ // Listen to the forwarded event from sub-menu.
292
+ this.addEventListener('close-all-menus', () => {
293
+ this.close();
294
+ });
295
+
296
+ // Listen to the forwarded event from sub-menu.
297
+ this.addEventListener('item-selected', () => {
298
+ this.close();
299
+ });
300
+
301
+ // Mark parent item as collapsed when closing.
302
+ subMenu.addEventListener('opened-changed', (event) => {
303
+ if (!event.detail.value) {
304
+ const expandedItem = this._listBox.querySelector('[expanded]');
305
+ if (expandedItem) {
306
+ this.__updateExpanded(expandedItem, false);
307
+ }
308
+ }
309
+ });
310
+
311
+ return subMenu;
312
+ }
313
+
314
+ /** @private */
315
+ __showSubMenu(event, item = event.composedPath().find((node) => node.localName === `${this._tagNamePrefix}-item`)) {
316
+ // Delay enabling the mouseover listener to avoid it from triggering on parent menu open
317
+ if (!this.__openListenerActive) {
318
+ return;
319
+ }
320
+
321
+ // Don't open sub-menus while the menu is still opening
322
+ if (this.$.overlay.hasAttribute('opening')) {
323
+ requestAnimationFrame(() => {
324
+ this.__showSubMenu(event, item);
325
+ });
326
+
327
+ return;
328
+ }
329
+
330
+ const subMenu = this._subMenu;
331
+
332
+ if (item) {
333
+ const { children } = item._item;
334
+
335
+ if (subMenu.items !== children) {
336
+ subMenu.close();
337
+ }
338
+ if (!this.opened) {
339
+ return;
227
340
  }
228
341
 
342
+ if (children && children.length) {
343
+ this.__updateExpanded(item, true);
344
+
345
+ // Forward parent overlay class
346
+ const { overlayClass } = this;
347
+ this.__openSubMenu(subMenu, item, overlayClass);
348
+ } else {
349
+ subMenu.listenOn.focus();
350
+ }
351
+ }
352
+ }
353
+
354
+ /**
355
+ * @param {!HTMLElement} root
356
+ * @param {!ContextMenu} menu
357
+ * @param {!ContextMenuRendererContext} context
358
+ * @protected
359
+ */
360
+ __itemsRenderer(root, menu, { detail }) {
361
+ this.__initMenu(root, menu);
362
+
363
+ const subMenu = root.querySelector(this.constructor.is);
364
+ subMenu.closeOn = menu.closeOn;
365
+
366
+ const listBox = root.querySelector(`${this._tagNamePrefix}-list-box`);
367
+ listBox.innerHTML = '';
368
+
369
+ [...(detail.children || menu.items)].forEach((item) => {
370
+ const component = this.__createComponent(item);
229
371
  listBox.appendChild(component);
230
372
  });
231
373
  }
@@ -241,11 +383,7 @@ export const ItemsMixin = (superClass) =>
241
383
  theme = Array.isArray(item.theme) ? item.theme.join(' ') : item.theme;
242
384
  }
243
385
 
244
- if (theme) {
245
- component.setAttribute('theme', theme);
246
- } else {
247
- component.removeAttribute('theme');
248
- }
386
+ this.__updateTheme(component, theme);
249
387
  }
250
388
 
251
389
  /** @private */
@@ -261,122 +399,39 @@ export const ItemsMixin = (superClass) =>
261
399
 
262
400
  /** @private */
263
401
  __initMenu(root, menu) {
402
+ // NOTE: in this method, `menu` and `this` reference the same element,
403
+ // so we can use either of those. Original implementation used `menu`.
264
404
  if (!root.firstElementChild) {
265
- const listBox = document.createElement('vaadin-context-menu-list-box');
266
- root.appendChild(listBox);
405
+ this.__initOverlay();
267
406
 
268
- if (this._theme) {
269
- listBox.setAttribute('theme', this._theme);
270
- }
271
- requestAnimationFrame(() => listBox.setAttribute('role', 'menu'));
407
+ const listBox = this.__initListBox();
408
+ this._listBox = listBox;
409
+ root.appendChild(listBox);
272
410
 
273
- const subMenu = document.createElement(this.constructor.is);
274
- subMenu.setAttribute('hidden', '');
411
+ const subMenu = this.__initSubMenu();
412
+ this._subMenu = subMenu;
275
413
  root.appendChild(subMenu);
276
- subMenu.$.overlay.modeless = true;
277
- subMenu.openOn = 'opensubmenu';
278
-
279
- menu.addEventListener('opened-changed', (e) => !e.detail.value && subMenu.close());
280
- subMenu.addEventListener('opened-changed', (e) => {
281
- if (!e.detail.value) {
282
- const expandedItem = listBox.querySelector('[expanded]');
283
- if (expandedItem) {
284
- expandedItem.setAttribute('aria-expanded', 'false');
285
- expandedItem.removeAttribute('expanded');
286
- }
287
- }
288
- });
289
-
290
- listBox.addEventListener('selected-changed', (e) => {
291
- if (typeof e.detail.value === 'number') {
292
- const item = e.target.items[e.detail.value]._item;
293
- if (!item.children) {
294
- const detail = { value: item };
295
- menu.dispatchEvent(new CustomEvent('item-selected', { detail }));
296
- }
297
- listBox.selected = null;
298
- }
299
- });
300
-
301
- subMenu.addEventListener('item-selected', (e) => {
302
- menu.dispatchEvent(new CustomEvent('item-selected', { detail: e.detail }));
303
- });
304
-
305
- subMenu.addEventListener('close-all-menus', () => {
306
- menu.dispatchEvent(new CustomEvent('close-all-menus'));
307
- });
308
- menu.addEventListener('close-all-menus', menu.close);
309
- menu.addEventListener('item-selected', menu.close);
310
- menu.$.overlay.$.backdrop.addEventListener('click', () => menu.close());
311
-
312
- menu.$.overlay.addEventListener('keydown', (e) => {
313
- const isRTL = this.__isRTL;
314
- if ((!isRTL && e.keyCode === 37) || (isRTL && e.keyCode === 39)) {
315
- menu.close();
316
- menu.listenOn.focus();
317
- } else if (e.key === 'Escape' || e.key === 'Tab') {
318
- menu.dispatchEvent(new CustomEvent('close-all-menus'));
319
- }
320
- });
321
414
 
322
415
  requestAnimationFrame(() => {
323
416
  this.__openListenerActive = true;
324
417
  });
325
- const openSubMenu = (
326
- e,
327
- itemElement = e.composedPath().find((e) => e.localName === 'vaadin-context-menu-item'),
328
- ) => {
329
- // Delay enabling the mouseover listener to avoid it from triggering on parent menu open
330
- if (!this.__openListenerActive) {
331
- return;
332
- }
333
-
334
- // Don't open sub-menus while the menu is still opening
335
- if (menu.$.overlay.hasAttribute('opening')) {
336
- requestAnimationFrame(() => openSubMenu(e, itemElement));
337
- return;
338
- }
339
-
340
- if (itemElement) {
341
- if (subMenu.items !== itemElement._item.children) {
342
- subMenu.close();
343
- }
344
- if (!menu.opened) {
345
- return;
346
- }
347
- if (itemElement._item.children && itemElement._item.children.length) {
348
- itemElement.setAttribute('aria-expanded', 'true');
349
- itemElement.setAttribute('expanded', '');
350
-
351
- // Forward parent overlay class
352
- const { overlayClass } = menu;
353
- this.__openSubMenu(subMenu, itemElement, overlayClass);
354
- } else {
355
- subMenu.listenOn.focus();
356
- }
357
- }
358
- };
359
-
360
- // Open a submenu on click event when a touch device is used.
361
- // On desktop, a submenu opens on hover.
362
- menu.$.overlay.addEventListener(isTouch ? 'click' : 'mouseover', openSubMenu);
418
+ } else {
419
+ this.__updateTheme(this._listBox, this._theme);
420
+ }
421
+ }
363
422
 
364
- menu.$.overlay.addEventListener('keydown', (e) => {
365
- const isRTL = this.__isRTL;
366
- const shouldOpenSubMenu =
367
- (!isRTL && e.keyCode === 39) || (isRTL && e.keyCode === 37) || e.keyCode === 13 || e.keyCode === 32;
423
+ /** @private */
424
+ __updateExpanded(component, expanded) {
425
+ component.setAttribute('aria-expanded', expanded.toString());
426
+ component.toggleAttribute('expanded', expanded);
427
+ }
368
428
 
369
- if (shouldOpenSubMenu) {
370
- openSubMenu(e);
371
- }
372
- });
429
+ /** @private */
430
+ __updateTheme(component, theme) {
431
+ if (theme) {
432
+ component.setAttribute('theme', theme);
373
433
  } else {
374
- const listBox = root.querySelector('vaadin-context-menu-list-box');
375
- if (this._theme) {
376
- listBox.setAttribute('theme', this._theme);
377
- } else {
378
- listBox.removeAttribute('theme');
379
- }
434
+ component.removeAttribute('theme');
380
435
  }
381
436
  }
382
437
  };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import type { Constructor } from '@open-wc/dedupe-mixin';
7
+ import type { PositionMixinClass } from '@vaadin/overlay/src/vaadin-overlay-position-mixin.js';
8
+
9
+ export declare function MenuOverlayMixin<T extends Constructor<HTMLElement>>(
10
+ base: T,
11
+ ): Constructor<MenuOverlayMixinClass> & Constructor<PositionMixinClass> & T;
12
+
13
+ export declare class MenuOverlayMixinClass {
14
+ protected readonly parentOverlay: HTMLElement | undefined;
15
+
16
+ /**
17
+ * Returns the adjusted boundaries of the overlay.
18
+ */
19
+ getBoundaries(): { xMax: number; xMin: number; yMax: number };
20
+
21
+ /**
22
+ * Returns the first element in the overlay content.
23
+ */
24
+ getFirstChild(): HTMLElement;
25
+ }
@@ -0,0 +1,119 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { PositionMixin } from '@vaadin/overlay/src/vaadin-overlay-position-mixin.js';
7
+
8
+ /**
9
+ * @polymerMixin
10
+ */
11
+ export const MenuOverlayMixin = (superClass) =>
12
+ class MenuOverlayMixin extends PositionMixin(superClass) {
13
+ static get properties() {
14
+ return {
15
+ /**
16
+ * @protected
17
+ */
18
+ parentOverlay: {
19
+ type: Object,
20
+ readOnly: true,
21
+ },
22
+ };
23
+ }
24
+
25
+ static get observers() {
26
+ return ['_themeChanged(_theme)'];
27
+ }
28
+
29
+ /** @protected */
30
+ ready() {
31
+ super.ready();
32
+
33
+ this.addEventListener('keydown', (e) => {
34
+ if (!e.defaultPrevented && e.composedPath()[0] === this.$.overlay && [38, 40].indexOf(e.keyCode) > -1) {
35
+ const child = this.getFirstChild();
36
+ if (child && Array.isArray(child.items) && child.items.length) {
37
+ e.preventDefault();
38
+ if (e.keyCode === 38) {
39
+ child.items[child.items.length - 1].focus();
40
+ } else {
41
+ child.focus();
42
+ }
43
+ }
44
+ }
45
+ });
46
+ }
47
+
48
+ /**
49
+ * Returns the first element in the overlay content.
50
+ *
51
+ * @returns {HTMLElement}
52
+ */
53
+ getFirstChild() {
54
+ return this.querySelector(':not(style):not(slot)');
55
+ }
56
+
57
+ /** @private */
58
+ _themeChanged() {
59
+ this.close();
60
+ }
61
+
62
+ /**
63
+ * Returns the adjusted boundaries of the overlay.
64
+ *
65
+ * @returns {object}
66
+ */
67
+ getBoundaries() {
68
+ // Measure actual overlay and content sizes
69
+ const overlayRect = this.getBoundingClientRect();
70
+ const contentRect = this.$.overlay.getBoundingClientRect();
71
+
72
+ // Maximum x and y values are imposed by content size and overlay limits.
73
+ let yMax = overlayRect.bottom - contentRect.height;
74
+
75
+ // Adjust constraints to ensure bottom-aligned applies to sub-menu.
76
+ const parent = this.parentOverlay;
77
+ if (parent && parent.hasAttribute('bottom-aligned')) {
78
+ const parentStyle = getComputedStyle(parent);
79
+ yMax = yMax - parseFloat(parentStyle.bottom) - parseFloat(parentStyle.height);
80
+ }
81
+
82
+ return {
83
+ xMax: overlayRect.right - contentRect.width,
84
+ xMin: overlayRect.left + contentRect.width,
85
+ yMax,
86
+ };
87
+ }
88
+
89
+ /**
90
+ * @protected
91
+ * @override
92
+ */
93
+ _updatePosition() {
94
+ super._updatePosition();
95
+
96
+ if (this.positionTarget && this.parentOverlay) {
97
+ // This overlay is positioned by a parent menu item,
98
+ // adjust the position by the overlay content paddings
99
+ const content = this.$.content;
100
+ const style = getComputedStyle(content);
101
+
102
+ // Horizontal adjustment
103
+ const isLeftAligned = !!this.style.left;
104
+ if (isLeftAligned) {
105
+ this.style.left = `${parseFloat(this.style.left) + parseFloat(style.paddingLeft)}px`;
106
+ } else {
107
+ this.style.right = `${parseFloat(this.style.right) + parseFloat(style.paddingRight)}px`;
108
+ }
109
+
110
+ // Vertical adjustment
111
+ const isBottomAligned = !!this.style.bottom;
112
+ if (isBottomAligned) {
113
+ this.style.bottom = `${parseFloat(this.style.bottom) - parseFloat(style.paddingBottom)}px`;
114
+ } else {
115
+ this.style.top = `${parseFloat(this.style.top) - parseFloat(style.paddingTop)}px`;
116
+ }
117
+ }
118
+ }
119
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import type { CSSResult } from 'lit';
7
+
8
+ export const styles: CSSResult;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { css } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
7
+
8
+ export const styles = css`
9
+ :host {
10
+ align-items: flex-start;
11
+ justify-content: flex-start;
12
+ }
13
+
14
+ :host([right-aligned]),
15
+ :host([end-aligned]) {
16
+ align-items: flex-end;
17
+ }
18
+
19
+ :host([bottom-aligned]) {
20
+ justify-content: flex-end;
21
+ }
22
+
23
+ [part='overlay'] {
24
+ background-color: #fff;
25
+ }
26
+ `;