@vaadin/details 23.3.3 → 24.0.0-alpha10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +8 -7
- package/src/content-controller.d.ts +11 -0
- package/src/content-controller.js +28 -0
- package/src/summary-controller.d.ts +21 -0
- package/src/summary-controller.js +68 -0
- package/src/vaadin-details-mixin.d.ts +23 -0
- package/src/vaadin-details-mixin.js +79 -0
- package/src/vaadin-details-summary.js +62 -0
- package/src/vaadin-details.d.ts +14 -7
- package/src/vaadin-details.js +77 -77
- package/theme/lumo/vaadin-details-styles.js +2 -110
- package/theme/lumo/vaadin-details-summary-styles.js +123 -0
- package/theme/lumo/vaadin-details.js +1 -0
- package/theme/material/vaadin-details-styles.js +2 -96
- package/theme/material/vaadin-details-summary-styles.js +104 -0
- package/theme/material/vaadin-details.js +1 -0
- package/web-types.json +96 -8
- package/web-types.lit.json +32 -4
package/README.md
CHANGED
|
@@ -9,8 +9,8 @@ A web component that provides an expandable panel for showing and hiding content
|
|
|
9
9
|
|
|
10
10
|
```html
|
|
11
11
|
<vaadin-details opened>
|
|
12
|
-
<
|
|
13
|
-
Toggle using mouse, Enter and Space keys
|
|
12
|
+
<vaadin-details-summary slot="summary">Expandable Details</vaadin-details-summary>
|
|
13
|
+
<div>Toggle using mouse, Enter and Space keys.</div>
|
|
14
14
|
</vaadin-details>
|
|
15
15
|
```
|
|
16
16
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/details",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "24.0.0-alpha10",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -35,12 +35,13 @@
|
|
|
35
35
|
"polymer"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
+
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
38
39
|
"@polymer/polymer": "^3.0.0",
|
|
39
|
-
"@vaadin/
|
|
40
|
-
"@vaadin/
|
|
41
|
-
"@vaadin/vaadin-lumo-styles": "
|
|
42
|
-
"@vaadin/vaadin-material-styles": "
|
|
43
|
-
"@vaadin/vaadin-themable-mixin": "
|
|
40
|
+
"@vaadin/button": "24.0.0-alpha10",
|
|
41
|
+
"@vaadin/component-base": "24.0.0-alpha10",
|
|
42
|
+
"@vaadin/vaadin-lumo-styles": "24.0.0-alpha10",
|
|
43
|
+
"@vaadin/vaadin-material-styles": "24.0.0-alpha10",
|
|
44
|
+
"@vaadin/vaadin-themable-mixin": "24.0.0-alpha10"
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|
|
46
47
|
"@esm-bundle/chai": "^4.3.4",
|
|
@@ -51,5 +52,5 @@
|
|
|
51
52
|
"web-types.json",
|
|
52
53
|
"web-types.lit.json"
|
|
53
54
|
],
|
|
54
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "2e04534d8b47bcd216f89b5f849bafef1a73b174"
|
|
55
56
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2019 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { SlotChildObserveController } from '@vaadin/component-base/src/slot-child-observe-controller.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A controller to manage the default content slot.
|
|
10
|
+
*/
|
|
11
|
+
export class ContentController extends SlotChildObserveController {}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2019 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { SlotChildObserveController } from '@vaadin/component-base/src/slot-child-observe-controller.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A controller to manage the default content slot.
|
|
10
|
+
*/
|
|
11
|
+
export class ContentController extends SlotChildObserveController {
|
|
12
|
+
/**
|
|
13
|
+
* Override method from `SlotController` to change
|
|
14
|
+
* the ID prefix for the default slot content.
|
|
15
|
+
*
|
|
16
|
+
* @param {HTMLElement} host
|
|
17
|
+
* @return {string}
|
|
18
|
+
* @protected
|
|
19
|
+
* @override
|
|
20
|
+
*/
|
|
21
|
+
static generateId(host) {
|
|
22
|
+
return super.generateId(host, 'content');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
constructor(host) {
|
|
26
|
+
super(host, '', null, { multiple: true });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2019 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { SlotChildObserveController } from '@vaadin/component-base/src/slot-child-observe-controller.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A controller to manage the summary element.
|
|
10
|
+
*/
|
|
11
|
+
export class SummaryController extends SlotChildObserveController {
|
|
12
|
+
/**
|
|
13
|
+
* String used for the summary.
|
|
14
|
+
*/
|
|
15
|
+
protected summary: string | null | undefined;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Set summary based on corresponding host property.
|
|
19
|
+
*/
|
|
20
|
+
setSummary(label: string | null | undefined): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2019 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { SlotChildObserveController } from '@vaadin/component-base/src/slot-child-observe-controller.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A controller to manage the summary element.
|
|
10
|
+
*/
|
|
11
|
+
export class SummaryController extends SlotChildObserveController {
|
|
12
|
+
constructor(host, tagName) {
|
|
13
|
+
super(host, 'summary', tagName);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Set summary based on corresponding host property.
|
|
18
|
+
*
|
|
19
|
+
* @param {string} summary
|
|
20
|
+
*/
|
|
21
|
+
setSummary(summary) {
|
|
22
|
+
this.summary = summary;
|
|
23
|
+
|
|
24
|
+
// Restore the default summary, if needed.
|
|
25
|
+
const summaryNode = this.getSlotChild();
|
|
26
|
+
if (!summaryNode) {
|
|
27
|
+
this.restoreDefaultNode();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// When default summary is used, update it.
|
|
31
|
+
if (this.node === this.defaultNode) {
|
|
32
|
+
this.updateDefaultNode(this.node);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Override method inherited from `SlotChildObserveController`
|
|
38
|
+
* to restore and observe the default summary element.
|
|
39
|
+
*
|
|
40
|
+
* @protected
|
|
41
|
+
* @override
|
|
42
|
+
*/
|
|
43
|
+
restoreDefaultNode() {
|
|
44
|
+
const { summary } = this;
|
|
45
|
+
|
|
46
|
+
// Restore the default summary.
|
|
47
|
+
if (summary && summary.trim() !== '') {
|
|
48
|
+
this.attachDefaultNode();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Override method inherited from `SlotChildObserveController`
|
|
54
|
+
* to update the default summary element text content.
|
|
55
|
+
*
|
|
56
|
+
* @param {Node | undefined} node
|
|
57
|
+
* @protected
|
|
58
|
+
* @override
|
|
59
|
+
*/
|
|
60
|
+
updateDefaultNode(node) {
|
|
61
|
+
if (node) {
|
|
62
|
+
node.textContent = this.summary;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Notify the host after update.
|
|
66
|
+
super.updateDefaultNode(node);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2017 - 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
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A mixin providing common details functionality.
|
|
10
|
+
*/
|
|
11
|
+
export declare function DetailsMixin<T extends Constructor<HTMLElement>>(base: T): Constructor<DetailsMixinClass> & T;
|
|
12
|
+
|
|
13
|
+
export declare class DetailsMixinClass {
|
|
14
|
+
/**
|
|
15
|
+
* If true, the collapsible content is visible.
|
|
16
|
+
*/
|
|
17
|
+
opened: boolean;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* List of elements passed to the details default slot.
|
|
21
|
+
*/
|
|
22
|
+
protected _contentElements: HTMLElement[];
|
|
23
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2019 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { ContentController } from './content-controller.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A mixin providing common details functionality.
|
|
10
|
+
*
|
|
11
|
+
* @polymerMixin
|
|
12
|
+
*/
|
|
13
|
+
export const DetailsMixin = (superClass) =>
|
|
14
|
+
class DetailsMixinClass extends superClass {
|
|
15
|
+
static get properties() {
|
|
16
|
+
return {
|
|
17
|
+
/**
|
|
18
|
+
* If true, the collapsible content is visible.
|
|
19
|
+
* @type {boolean}
|
|
20
|
+
*/
|
|
21
|
+
opened: {
|
|
22
|
+
type: Boolean,
|
|
23
|
+
value: false,
|
|
24
|
+
reflectToAttribute: true,
|
|
25
|
+
notify: true,
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* List of elements passed to the details default slot.
|
|
30
|
+
*
|
|
31
|
+
* @protected
|
|
32
|
+
*/
|
|
33
|
+
_contentElements: {
|
|
34
|
+
type: Array,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static get observers() {
|
|
40
|
+
return ['_openedOrContentChanged(opened, _contentElements)'];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
constructor() {
|
|
44
|
+
super();
|
|
45
|
+
|
|
46
|
+
this._contentController = new ContentController(this);
|
|
47
|
+
|
|
48
|
+
this._contentController.addEventListener('slot-content-changed', (event) => {
|
|
49
|
+
const content = event.target.nodes || [];
|
|
50
|
+
|
|
51
|
+
// Exclude nodes that are no longer connected
|
|
52
|
+
this._contentElements = content.filter((node) => node.parentNode === this);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** @protected */
|
|
57
|
+
ready() {
|
|
58
|
+
super.ready();
|
|
59
|
+
|
|
60
|
+
this.addController(this._contentController);
|
|
61
|
+
|
|
62
|
+
// Only handle click and not keydown, because `vaadin-details-summary` uses `ButtonMixin`
|
|
63
|
+
// that already covers this logic, and `vaadin-accordion-heading` uses native `<button>`.
|
|
64
|
+
this.addEventListener('click', (event) => {
|
|
65
|
+
if (event.target === this.focusElement) {
|
|
66
|
+
this.opened = !this.opened;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** @private */
|
|
72
|
+
_openedOrContentChanged(opened, elements) {
|
|
73
|
+
if (elements) {
|
|
74
|
+
elements.forEach((el) => {
|
|
75
|
+
el.setAttribute('aria-hidden', opened ? 'false' : 'true');
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2017 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
7
|
+
import { ButtonMixin } from '@vaadin/button/src/vaadin-button-mixin.js';
|
|
8
|
+
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
|
|
9
|
+
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The details summary element.
|
|
13
|
+
*
|
|
14
|
+
* @extends HTMLElement
|
|
15
|
+
* @mixes ButtonMixin
|
|
16
|
+
* @mixes DirMixin
|
|
17
|
+
* @mixes ThemableMixin
|
|
18
|
+
*/
|
|
19
|
+
class DetailsSummary extends ButtonMixin(DirMixin(ThemableMixin(PolymerElement))) {
|
|
20
|
+
static get is() {
|
|
21
|
+
return 'vaadin-details-summary';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static get template() {
|
|
25
|
+
return html`
|
|
26
|
+
<style>
|
|
27
|
+
:host {
|
|
28
|
+
display: block;
|
|
29
|
+
outline: none;
|
|
30
|
+
white-space: nowrap;
|
|
31
|
+
-webkit-user-select: none;
|
|
32
|
+
-moz-user-select: none;
|
|
33
|
+
user-select: none;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
:host([hidden]) {
|
|
37
|
+
display: none !important;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
:host([disabled]) {
|
|
41
|
+
pointer-events: none;
|
|
42
|
+
}
|
|
43
|
+
</style>
|
|
44
|
+
<span part="toggle" aria-hidden="true"></span>
|
|
45
|
+
<div part="content"><slot></slot></div>
|
|
46
|
+
`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static get properties() {
|
|
50
|
+
return {
|
|
51
|
+
/**
|
|
52
|
+
* When true, the element is opened.
|
|
53
|
+
*/
|
|
54
|
+
opened: {
|
|
55
|
+
type: Boolean,
|
|
56
|
+
reflectToAttribute: true,
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
customElements.define(DetailsSummary.is, DetailsSummary);
|
package/src/vaadin-details.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2019 -
|
|
3
|
+
* Copyright (c) 2019 - 2023 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
|
|
7
|
+
import { DelegateFocusMixin } from '@vaadin/component-base/src/delegate-focus-mixin.js';
|
|
8
|
+
import { DelegateStateMixin } from '@vaadin/component-base/src/delegate-state-mixin.js';
|
|
7
9
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
8
|
-
import { ShadowFocusMixin } from '@vaadin/field-base/src/shadow-focus-mixin.js';
|
|
9
10
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
11
|
+
import { DetailsMixin } from './vaadin-details-mixin.js';
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
* Fired when the `opened` property changes.
|
|
@@ -25,8 +27,10 @@ export type DetailsEventMap = DetailsCustomEventMap & HTMLElementEventMap;
|
|
|
25
27
|
*
|
|
26
28
|
* ```
|
|
27
29
|
* <vaadin-details>
|
|
28
|
-
* <
|
|
29
|
-
*
|
|
30
|
+
* <vaadin-details-summary slot="summary">Expandable Details</vaadin-details-summary>
|
|
31
|
+
* <div>
|
|
32
|
+
* Toggle using mouse, Enter and Space keys.
|
|
33
|
+
* </div>
|
|
30
34
|
* </vaadin-details>
|
|
31
35
|
* ```
|
|
32
36
|
*
|
|
@@ -54,11 +58,14 @@ export type DetailsEventMap = DetailsCustomEventMap & HTMLElementEventMap;
|
|
|
54
58
|
*
|
|
55
59
|
* @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
|
|
56
60
|
*/
|
|
57
|
-
declare class Details extends
|
|
61
|
+
declare class Details extends DetailsMixin(
|
|
62
|
+
DelegateStateMixin(DelegateFocusMixin(ElementMixin(ThemableMixin(ControllerMixin(HTMLElement))))),
|
|
63
|
+
) {
|
|
58
64
|
/**
|
|
59
|
-
*
|
|
65
|
+
* A text that is displayed in the summary, if no
|
|
66
|
+
* element is assigned to the `summary` slot.
|
|
60
67
|
*/
|
|
61
|
-
|
|
68
|
+
summary: string | null | undefined;
|
|
62
69
|
|
|
63
70
|
addEventListener<K extends keyof DetailsEventMap>(
|
|
64
71
|
type: K,
|
package/src/vaadin-details.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2019 -
|
|
3
|
+
* Copyright (c) 2019 - 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-details-summary.js';
|
|
6
7
|
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
7
8
|
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
|
|
9
|
+
import { DelegateFocusMixin } from '@vaadin/component-base/src/delegate-focus-mixin.js';
|
|
10
|
+
import { DelegateStateMixin } from '@vaadin/component-base/src/delegate-state-mixin.js';
|
|
8
11
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
9
12
|
import { TooltipController } from '@vaadin/component-base/src/tooltip-controller.js';
|
|
10
|
-
import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
|
|
11
|
-
import { ShadowFocusMixin } from '@vaadin/field-base/src/shadow-focus-mixin.js';
|
|
12
13
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
14
|
+
import { SummaryController } from './summary-controller.js';
|
|
15
|
+
import { DetailsMixin } from './vaadin-details-mixin.js';
|
|
13
16
|
|
|
14
17
|
/**
|
|
15
18
|
* `<vaadin-details>` is a Web Component which the creates an
|
|
@@ -17,8 +20,10 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
|
|
|
17
20
|
*
|
|
18
21
|
* ```
|
|
19
22
|
* <vaadin-details>
|
|
20
|
-
* <
|
|
21
|
-
*
|
|
23
|
+
* <vaadin-details-summary slot="summary">Expandable Details</vaadin-details-summary>
|
|
24
|
+
* <div>
|
|
25
|
+
* Toggle using mouse, Enter and Space keys.
|
|
26
|
+
* </div>
|
|
22
27
|
* </vaadin-details>
|
|
23
28
|
* ```
|
|
24
29
|
*
|
|
@@ -48,11 +53,15 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
|
|
|
48
53
|
*
|
|
49
54
|
* @extends HTMLElement
|
|
50
55
|
* @mixes ControllerMixin
|
|
51
|
-
* @mixes
|
|
56
|
+
* @mixes DetailsMixin
|
|
57
|
+
* @mixes DelegateFocusMixin
|
|
58
|
+
* @mixes DelegateStateMixin
|
|
52
59
|
* @mixes ElementMixin
|
|
53
60
|
* @mixes ThemableMixin
|
|
54
61
|
*/
|
|
55
|
-
class Details extends
|
|
62
|
+
class Details extends DetailsMixin(
|
|
63
|
+
DelegateStateMixin(DelegateFocusMixin(ElementMixin(ThemableMixin(ControllerMixin(PolymerElement))))),
|
|
64
|
+
) {
|
|
56
65
|
static get template() {
|
|
57
66
|
return html`
|
|
58
67
|
<style>
|
|
@@ -66,36 +75,20 @@ class Details extends ShadowFocusMixin(ElementMixin(ThemableMixin(ControllerMixi
|
|
|
66
75
|
|
|
67
76
|
[part='content'] {
|
|
68
77
|
display: none;
|
|
69
|
-
overflow: hidden;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
[part='summary'][disabled] {
|
|
73
|
-
pointer-events: none;
|
|
74
78
|
}
|
|
75
79
|
|
|
76
80
|
:host([opened]) [part='content'] {
|
|
77
81
|
display: block;
|
|
78
|
-
overflow: visible;
|
|
79
82
|
}
|
|
80
83
|
</style>
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
on-click="_onToggleClick"
|
|
86
|
-
on-keydown="_onToggleKeyDown"
|
|
87
|
-
disabled$="[[disabled]]"
|
|
88
|
-
aria-expanded$="[[_getAriaExpanded(opened)]]"
|
|
89
|
-
aria-controls$="[[_contentId]]"
|
|
90
|
-
>
|
|
91
|
-
<span part="toggle" aria-hidden="true"></span>
|
|
92
|
-
<span part="summary-content"><slot name="summary"></slot></span>
|
|
93
|
-
</div>
|
|
94
|
-
<slot name="tooltip"></slot>
|
|
95
|
-
</div>
|
|
96
|
-
<section id$="[[_contentId]]" part="content" aria-hidden$="[[_getAriaHidden(opened)]]">
|
|
84
|
+
|
|
85
|
+
<slot name="summary"></slot>
|
|
86
|
+
|
|
87
|
+
<div part="content">
|
|
97
88
|
<slot></slot>
|
|
98
|
-
</
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<slot name="tooltip"></slot>
|
|
99
92
|
`;
|
|
100
93
|
}
|
|
101
94
|
|
|
@@ -106,79 +99,86 @@ class Details extends ShadowFocusMixin(ElementMixin(ThemableMixin(ControllerMixi
|
|
|
106
99
|
static get properties() {
|
|
107
100
|
return {
|
|
108
101
|
/**
|
|
109
|
-
*
|
|
110
|
-
*
|
|
102
|
+
* A text that is displayed in the summary, if no
|
|
103
|
+
* element is assigned to the `summary` slot.
|
|
111
104
|
*/
|
|
112
|
-
|
|
113
|
-
type:
|
|
114
|
-
|
|
115
|
-
reflectToAttribute: true,
|
|
116
|
-
notify: true,
|
|
117
|
-
observer: '_openedChanged',
|
|
105
|
+
summary: {
|
|
106
|
+
type: String,
|
|
107
|
+
observer: '_summaryChanged',
|
|
118
108
|
},
|
|
119
109
|
};
|
|
120
110
|
}
|
|
121
111
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
* @protected
|
|
125
|
-
*/
|
|
126
|
-
get _collapsible() {
|
|
127
|
-
return this.shadowRoot.querySelector('[part="content"]');
|
|
112
|
+
static get observers() {
|
|
113
|
+
return ['__updateAriaControls(focusElement, _contentElements)', '__updateAriaExpanded(focusElement, opened)'];
|
|
128
114
|
}
|
|
129
115
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
* @return {!HTMLElement}
|
|
133
|
-
* @protected
|
|
134
|
-
*/
|
|
135
|
-
get focusElement() {
|
|
136
|
-
return this.shadowRoot.querySelector('[part="summary"]');
|
|
116
|
+
static get delegateAttrs() {
|
|
117
|
+
return ['theme'];
|
|
137
118
|
}
|
|
138
119
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
120
|
+
static get delegateProps() {
|
|
121
|
+
return ['disabled', 'opened'];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
constructor() {
|
|
125
|
+
super();
|
|
126
|
+
|
|
127
|
+
this._summaryController = new SummaryController(this, 'vaadin-details-summary');
|
|
128
|
+
this._summaryController.addEventListener('slot-content-changed', (event) => {
|
|
129
|
+
const { node } = event.target;
|
|
130
|
+
|
|
131
|
+
this._setFocusElement(node);
|
|
132
|
+
this.stateTarget = node;
|
|
133
|
+
|
|
134
|
+
this._tooltipController.setTarget(node);
|
|
148
135
|
});
|
|
149
136
|
|
|
150
137
|
this._tooltipController = new TooltipController(this);
|
|
151
|
-
this.addController(this._tooltipController);
|
|
152
|
-
|
|
153
|
-
this._tooltipController.setTarget(this.focusElement);
|
|
154
138
|
this._tooltipController.setPosition('bottom-start');
|
|
155
139
|
}
|
|
156
140
|
|
|
157
|
-
/** @
|
|
158
|
-
|
|
159
|
-
|
|
141
|
+
/** @protected */
|
|
142
|
+
ready() {
|
|
143
|
+
super.ready();
|
|
144
|
+
|
|
145
|
+
this.addController(this._summaryController);
|
|
146
|
+
this.addController(this._tooltipController);
|
|
160
147
|
}
|
|
161
148
|
|
|
162
|
-
/**
|
|
163
|
-
|
|
164
|
-
|
|
149
|
+
/**
|
|
150
|
+
* Override method inherited from `DisabledMixin`
|
|
151
|
+
* to not set `aria-disabled` on the host element.
|
|
152
|
+
*
|
|
153
|
+
* @protected
|
|
154
|
+
* @override
|
|
155
|
+
*/
|
|
156
|
+
_setAriaDisabled() {
|
|
157
|
+
// The `aria-disabled` is set on the details summary.
|
|
165
158
|
}
|
|
166
159
|
|
|
167
160
|
/** @private */
|
|
168
|
-
|
|
169
|
-
this.
|
|
161
|
+
_summaryChanged(summary) {
|
|
162
|
+
this._summaryController.setSummary(summary);
|
|
170
163
|
}
|
|
171
164
|
|
|
172
165
|
/** @private */
|
|
173
|
-
|
|
174
|
-
|
|
166
|
+
__updateAriaControls(summary, contentElements) {
|
|
167
|
+
if (summary && contentElements) {
|
|
168
|
+
const node = contentElements[0];
|
|
169
|
+
|
|
170
|
+
if (node && node.id) {
|
|
171
|
+
summary.setAttribute('aria-controls', node.id);
|
|
172
|
+
} else {
|
|
173
|
+
summary.removeAttribute('aria-controls');
|
|
174
|
+
}
|
|
175
|
+
}
|
|
175
176
|
}
|
|
176
177
|
|
|
177
178
|
/** @private */
|
|
178
|
-
|
|
179
|
-
if (
|
|
180
|
-
|
|
181
|
-
this.opened = !this.opened;
|
|
179
|
+
__updateAriaExpanded(focusElement, opened) {
|
|
180
|
+
if (focusElement) {
|
|
181
|
+
focusElement.setAttribute('aria-expanded', opened ? 'true' : 'false');
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import '@vaadin/vaadin-lumo-styles/color.js';
|
|
2
|
-
import '@vaadin/vaadin-lumo-styles/font-icons.js';
|
|
3
|
-
import '@vaadin/vaadin-lumo-styles/sizing.js';
|
|
4
2
|
import '@vaadin/vaadin-lumo-styles/spacing.js';
|
|
5
3
|
import '@vaadin/vaadin-lumo-styles/style.js';
|
|
6
4
|
import '@vaadin/vaadin-lumo-styles/typography.js';
|
|
@@ -12,64 +10,10 @@ const details = css`
|
|
|
12
10
|
outline: none;
|
|
13
11
|
}
|
|
14
12
|
|
|
15
|
-
[
|
|
16
|
-
display: flex;
|
|
17
|
-
align-items: center;
|
|
18
|
-
width: 100%;
|
|
19
|
-
outline: none;
|
|
20
|
-
padding: var(--lumo-space-s) 0;
|
|
21
|
-
box-sizing: border-box;
|
|
22
|
-
font-family: var(--lumo-font-family);
|
|
23
|
-
font-size: var(--lumo-font-size-m);
|
|
24
|
-
font-weight: 500;
|
|
25
|
-
line-height: var(--lumo-line-height-xs);
|
|
26
|
-
color: var(--lumo-secondary-text-color);
|
|
27
|
-
background-color: inherit;
|
|
28
|
-
border-radius: var(--lumo-border-radius-m);
|
|
29
|
-
cursor: var(--lumo-clickable-cursor);
|
|
30
|
-
-webkit-tap-highlight-color: transparent;
|
|
31
|
-
-webkit-font-smoothing: antialiased;
|
|
32
|
-
-moz-osx-font-smoothing: grayscale;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
:host([focus-ring]) [part='summary'] {
|
|
13
|
+
:host([focus-ring]) ::slotted([slot='summary']) {
|
|
36
14
|
box-shadow: 0 0 0 2px var(--lumo-primary-color-50pct);
|
|
37
15
|
}
|
|
38
16
|
|
|
39
|
-
[part='toggle'] {
|
|
40
|
-
display: block;
|
|
41
|
-
width: 1em;
|
|
42
|
-
height: 1em;
|
|
43
|
-
margin-left: calc(var(--lumo-space-xs) * -1);
|
|
44
|
-
margin-right: var(--lumo-space-xs);
|
|
45
|
-
font-size: var(--lumo-icon-size-s);
|
|
46
|
-
line-height: 1;
|
|
47
|
-
color: var(--lumo-contrast-60pct);
|
|
48
|
-
font-family: 'lumo-icons';
|
|
49
|
-
cursor: var(--lumo-clickable-cursor);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
:host([disabled]) [part='summary'],
|
|
53
|
-
:host([disabled]) [part='toggle'] {
|
|
54
|
-
color: var(--lumo-disabled-text-color);
|
|
55
|
-
cursor: default;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
@media (hover: hover) {
|
|
59
|
-
:host(:not([disabled])) [part='summary']:hover,
|
|
60
|
-
:host(:not([disabled])) [part='summary']:hover [part='toggle'] {
|
|
61
|
-
color: var(--lumo-contrast-80pct);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
[part='toggle']::before {
|
|
66
|
-
content: var(--lumo-icons-angle-right);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
:host([opened]) [part='toggle'] {
|
|
70
|
-
transform: rotate(90deg);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
17
|
[part='content'] {
|
|
74
18
|
padding: var(--lumo-space-xs) 0 var(--lumo-space-s);
|
|
75
19
|
font-size: var(--lumo-font-size-m);
|
|
@@ -81,66 +25,14 @@ const details = css`
|
|
|
81
25
|
border-radius: var(--lumo-border-radius-m);
|
|
82
26
|
}
|
|
83
27
|
|
|
84
|
-
:host([theme~='filled']) [part='summary'] {
|
|
85
|
-
padding: var(--lumo-space-s) calc(var(--lumo-space-s) + var(--lumo-space-xs) / 2);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
28
|
:host([theme~='filled']) [part='content'] {
|
|
89
29
|
padding-left: var(--lumo-space-m);
|
|
90
30
|
padding-right: var(--lumo-space-m);
|
|
91
31
|
}
|
|
92
32
|
|
|
93
|
-
:host([theme~='small']) [part
|
|
94
|
-
padding-top: var(--lumo-space-xs);
|
|
95
|
-
padding-bottom: var(--lumo-space-xs);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
:host([theme~='small']) [part='toggle'] {
|
|
99
|
-
margin-right: calc(var(--lumo-space-xs) / 2);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
:host([theme~='small']) [part\$='content'] {
|
|
33
|
+
:host([theme~='small']) [part$='content'] {
|
|
103
34
|
font-size: var(--lumo-font-size-s);
|
|
104
35
|
}
|
|
105
|
-
|
|
106
|
-
:host([theme~='reverse']) [part='summary'] {
|
|
107
|
-
justify-content: space-between;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
:host([theme~='reverse']) [part='toggle'] {
|
|
111
|
-
order: 1;
|
|
112
|
-
margin-right: 0;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
:host([theme~='reverse'][theme~='filled']) [part='summary'] {
|
|
116
|
-
padding-left: var(--lumo-space-m);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/* RTL specific styles */
|
|
120
|
-
:host([dir='rtl']) [part='toggle'] {
|
|
121
|
-
margin-left: var(--lumo-space-xs);
|
|
122
|
-
margin-right: calc(var(--lumo-space-xs) * -1);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
:host([dir='rtl']) [part='toggle']::before {
|
|
126
|
-
content: var(--lumo-icons-angle-left);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
:host([opened][dir='rtl']) [part='toggle'] {
|
|
130
|
-
transform: rotate(-90deg);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
:host([theme~='small'][dir='rtl']) [part='toggle'] {
|
|
134
|
-
margin-left: calc(var(--lumo-space-xs) / 2);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
:host([theme~='reverse'][dir='rtl']) [part='toggle'] {
|
|
138
|
-
margin-left: 0;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
:host([theme~='reverse'][theme~='filled'][dir='rtl']) [part='summary'] {
|
|
142
|
-
padding-right: var(--lumo-space-m);
|
|
143
|
-
}
|
|
144
36
|
`;
|
|
145
37
|
|
|
146
38
|
registerStyles('vaadin-details', details, { moduleId: 'lumo-details' });
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import '@vaadin/vaadin-lumo-styles/color.js';
|
|
2
|
+
import '@vaadin/vaadin-lumo-styles/font-icons.js';
|
|
3
|
+
import '@vaadin/vaadin-lumo-styles/sizing.js';
|
|
4
|
+
import '@vaadin/vaadin-lumo-styles/spacing.js';
|
|
5
|
+
import '@vaadin/vaadin-lumo-styles/style.js';
|
|
6
|
+
import '@vaadin/vaadin-lumo-styles/typography.js';
|
|
7
|
+
import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
8
|
+
|
|
9
|
+
const detailsSummary = css`
|
|
10
|
+
:host {
|
|
11
|
+
display: flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
width: 100%;
|
|
14
|
+
outline: none;
|
|
15
|
+
padding: var(--lumo-space-s) 0;
|
|
16
|
+
box-sizing: border-box;
|
|
17
|
+
font-family: var(--lumo-font-family);
|
|
18
|
+
font-size: var(--lumo-font-size-m);
|
|
19
|
+
font-weight: 500;
|
|
20
|
+
line-height: var(--lumo-line-height-xs);
|
|
21
|
+
color: var(--lumo-secondary-text-color);
|
|
22
|
+
background-color: inherit;
|
|
23
|
+
border-radius: var(--lumo-border-radius-m);
|
|
24
|
+
cursor: var(--lumo-clickable-cursor);
|
|
25
|
+
-webkit-tap-highlight-color: transparent;
|
|
26
|
+
-webkit-font-smoothing: antialiased;
|
|
27
|
+
-moz-osx-font-smoothing: grayscale;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
:host([disabled]),
|
|
31
|
+
:host([disabled]) [part='toggle'] {
|
|
32
|
+
color: var(--lumo-disabled-text-color);
|
|
33
|
+
cursor: default;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@media (hover: hover) {
|
|
37
|
+
:host(:hover:not([disabled])),
|
|
38
|
+
:host(:hover:not([disabled])) [part='toggle'] {
|
|
39
|
+
color: var(--lumo-contrast-80pct);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
[part='toggle'] {
|
|
44
|
+
display: block;
|
|
45
|
+
width: 1em;
|
|
46
|
+
height: 1em;
|
|
47
|
+
margin-left: calc(var(--lumo-space-xs) * -1);
|
|
48
|
+
margin-right: var(--lumo-space-xs);
|
|
49
|
+
font-size: var(--lumo-icon-size-s);
|
|
50
|
+
line-height: 1;
|
|
51
|
+
color: var(--lumo-contrast-60pct);
|
|
52
|
+
font-family: 'lumo-icons';
|
|
53
|
+
cursor: var(--lumo-clickable-cursor);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
[part='toggle']::before {
|
|
57
|
+
content: var(--lumo-icons-angle-right);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
:host([opened]) [part='toggle'] {
|
|
61
|
+
transform: rotate(90deg);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* RTL styles */
|
|
65
|
+
:host([dir='rtl']) [part='toggle'] {
|
|
66
|
+
margin-left: var(--lumo-space-xs);
|
|
67
|
+
margin-right: calc(var(--lumo-space-xs) * -1);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
:host([dir='rtl']) [part='toggle']::before {
|
|
71
|
+
content: var(--lumo-icons-angle-left);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
:host([opened][dir='rtl']) [part='toggle'] {
|
|
75
|
+
transform: rotate(-90deg);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Small */
|
|
79
|
+
:host([theme~='small']) {
|
|
80
|
+
padding-top: var(--lumo-space-xs);
|
|
81
|
+
padding-bottom: var(--lumo-space-xs);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
:host([theme~='small']) [part='toggle'] {
|
|
85
|
+
margin-right: calc(var(--lumo-space-xs) / 2);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
:host([theme~='small'][dir='rtl']) [part='toggle'] {
|
|
89
|
+
margin-left: calc(var(--lumo-space-xs) / 2);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* Filled */
|
|
93
|
+
:host([theme~='filled']) {
|
|
94
|
+
padding: var(--lumo-space-s) calc(var(--lumo-space-s) + var(--lumo-space-xs) / 2);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* Reverse */
|
|
98
|
+
:host([theme~='reverse']) {
|
|
99
|
+
justify-content: space-between;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
:host([theme~='reverse']) [part='toggle'] {
|
|
103
|
+
order: 1;
|
|
104
|
+
margin-right: 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
:host([theme~='reverse'][dir='rtl']) [part='toggle'] {
|
|
108
|
+
margin-left: 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* Filled reverse */
|
|
112
|
+
:host([theme~='reverse'][theme~='filled']) {
|
|
113
|
+
padding-left: var(--lumo-space-m);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
:host([theme~='reverse'][theme~='filled'][dir='rtl']) {
|
|
117
|
+
padding-right: var(--lumo-space-m);
|
|
118
|
+
}
|
|
119
|
+
`;
|
|
120
|
+
|
|
121
|
+
registerStyles('vaadin-details-summary', detailsSummary, { moduleId: 'lumo-details-summary' });
|
|
122
|
+
|
|
123
|
+
export { detailsSummary };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import '@vaadin/vaadin-material-styles/color.js';
|
|
2
|
-
import '@vaadin/vaadin-material-styles/font-icons.js';
|
|
3
2
|
import '@vaadin/vaadin-material-styles/shadow.js';
|
|
4
3
|
import '@vaadin/vaadin-material-styles/typography.js';
|
|
5
4
|
import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
@@ -11,106 +10,13 @@ const details = css`
|
|
|
11
10
|
outline: none;
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
[
|
|
15
|
-
|
|
16
|
-
align-items: center;
|
|
17
|
-
justify-content: space-between;
|
|
18
|
-
width: 100%;
|
|
19
|
-
position: relative;
|
|
20
|
-
outline: none;
|
|
21
|
-
min-height: 48px;
|
|
22
|
-
padding: 0 24px;
|
|
23
|
-
box-sizing: border-box;
|
|
24
|
-
font-weight: 500;
|
|
25
|
-
font-size: var(--material-small-font-size);
|
|
26
|
-
background-color: var(--material-background-color);
|
|
27
|
-
color: var(--material-body-text-color);
|
|
28
|
-
cursor: default;
|
|
29
|
-
-webkit-tap-highlight-color: transparent;
|
|
30
|
-
-webkit-font-smoothing: antialiased;
|
|
31
|
-
-moz-osx-font-smoothing: grayscale;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
:host([disabled]) [part='summary'] {
|
|
35
|
-
color: var(--material-disabled-text-color);
|
|
36
|
-
background: var(--material-disabled-color);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
:host([focus-ring]) [part='summary'] {
|
|
40
|
-
background: var(--material-secondary-background-color);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
[part='summary-content'] {
|
|
44
|
-
margin: 12px 0;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
[part='toggle'] {
|
|
48
|
-
position: relative;
|
|
49
|
-
order: 1;
|
|
50
|
-
margin-right: -8px;
|
|
51
|
-
width: 24px;
|
|
52
|
-
height: 24px;
|
|
53
|
-
padding: 4px;
|
|
54
|
-
color: var(--material-secondary-text-color);
|
|
55
|
-
line-height: 24px;
|
|
56
|
-
text-align: center;
|
|
57
|
-
transform: rotate(90deg);
|
|
58
|
-
transition: transform 0.1s cubic-bezier(0.4, 0, 0.2, 0.1);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
[part='toggle']::before {
|
|
62
|
-
font-family: 'material-icons';
|
|
63
|
-
font-size: 24px;
|
|
64
|
-
width: 24px;
|
|
65
|
-
display: inline-block;
|
|
66
|
-
content: var(--material-icons-chevron-right);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
[part='toggle']::after {
|
|
70
|
-
display: inline-block;
|
|
71
|
-
content: '';
|
|
72
|
-
position: absolute;
|
|
73
|
-
top: 0;
|
|
74
|
-
left: 0;
|
|
75
|
-
width: 100%;
|
|
76
|
-
height: 100%;
|
|
77
|
-
border-radius: 50%;
|
|
78
|
-
background-color: var(--material-disabled-text-color);
|
|
79
|
-
transform: scale(0);
|
|
80
|
-
opacity: 0;
|
|
81
|
-
transition: transform 0s 0.8s, opacity 0.8s;
|
|
82
|
-
will-change: transform, opacity;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
:host([disabled]) [part='toggle'] {
|
|
86
|
-
color: var(--material-disabled-color);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
:host(:not([disabled])) [part='summary']:active [part='toggle']::after {
|
|
90
|
-
transition-duration: 0.08s, 0.01s;
|
|
91
|
-
transition-delay: 0s, 0s;
|
|
92
|
-
transform: scale(1.25);
|
|
93
|
-
opacity: 0.15;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
:host([opened]) [part='toggle'] {
|
|
97
|
-
transform: rotate(270deg);
|
|
13
|
+
:host([focus-ring]) ::slotted([slot='summary']) {
|
|
14
|
+
background-color: var(--material-secondary-background-color);
|
|
98
15
|
}
|
|
99
16
|
|
|
100
17
|
[part='content'] {
|
|
101
18
|
padding: 8px 24px 24px;
|
|
102
19
|
}
|
|
103
|
-
|
|
104
|
-
/* RTL specific styles */
|
|
105
|
-
:host([dir='rtl']) [part='toggle'] {
|
|
106
|
-
margin-left: -8px;
|
|
107
|
-
margin-right: 0;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
:host([dir='rtl']) [part='toggle']::after {
|
|
111
|
-
left: auto;
|
|
112
|
-
right: 0;
|
|
113
|
-
}
|
|
114
20
|
`;
|
|
115
21
|
|
|
116
22
|
registerStyles('vaadin-details', details, { moduleId: 'material-details' });
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import '@vaadin/vaadin-material-styles/color.js';
|
|
2
|
+
import '@vaadin/vaadin-material-styles/font-icons.js';
|
|
3
|
+
import '@vaadin/vaadin-material-styles/typography.js';
|
|
4
|
+
import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
5
|
+
|
|
6
|
+
const detailsSummary = css`
|
|
7
|
+
:host {
|
|
8
|
+
display: flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
justify-content: space-between;
|
|
11
|
+
width: 100%;
|
|
12
|
+
position: relative;
|
|
13
|
+
outline: none;
|
|
14
|
+
min-height: 48px;
|
|
15
|
+
padding: 0 24px;
|
|
16
|
+
box-sizing: border-box;
|
|
17
|
+
font-weight: 500;
|
|
18
|
+
font-size: var(--material-small-font-size);
|
|
19
|
+
background-color: var(--material-background-color);
|
|
20
|
+
color: var(--material-body-text-color);
|
|
21
|
+
cursor: default;
|
|
22
|
+
-webkit-tap-highlight-color: transparent;
|
|
23
|
+
-webkit-font-smoothing: antialiased;
|
|
24
|
+
-moz-osx-font-smoothing: grayscale;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
:host([disabled]) {
|
|
28
|
+
color: var(--material-disabled-text-color);
|
|
29
|
+
background-color: var(--material-disabled-color);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
[part='content'] {
|
|
33
|
+
margin: 0;
|
|
34
|
+
position: relative;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
[part='toggle'] {
|
|
38
|
+
position: relative;
|
|
39
|
+
order: 1;
|
|
40
|
+
margin-inline-start: auto;
|
|
41
|
+
right: -8px;
|
|
42
|
+
width: 24px;
|
|
43
|
+
height: 24px;
|
|
44
|
+
padding: 4px;
|
|
45
|
+
color: var(--material-secondary-text-color);
|
|
46
|
+
line-height: 24px;
|
|
47
|
+
text-align: center;
|
|
48
|
+
transform: rotate(90deg);
|
|
49
|
+
transition: transform 0.1s cubic-bezier(0.4, 0, 0.2, 0.1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
[part='toggle']::before {
|
|
53
|
+
font-family: 'material-icons';
|
|
54
|
+
font-size: 24px;
|
|
55
|
+
width: 24px;
|
|
56
|
+
display: inline-block;
|
|
57
|
+
content: var(--material-icons-chevron-right);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
[part='toggle']::after {
|
|
61
|
+
display: inline-block;
|
|
62
|
+
content: '';
|
|
63
|
+
position: absolute;
|
|
64
|
+
top: 0;
|
|
65
|
+
left: 0;
|
|
66
|
+
width: 100%;
|
|
67
|
+
height: 100%;
|
|
68
|
+
border-radius: 50%;
|
|
69
|
+
background-color: var(--material-disabled-text-color);
|
|
70
|
+
transform: scale(0);
|
|
71
|
+
opacity: 0;
|
|
72
|
+
transition: transform 0s 0.8s, opacity 0.8s;
|
|
73
|
+
will-change: transform, opacity;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
:host([disabled]) [part='toggle'] {
|
|
77
|
+
color: var(--material-disabled-color);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
:host([active]:not([disabled])) [part='toggle']::after {
|
|
81
|
+
transition-duration: 0.08s, 0.01s;
|
|
82
|
+
transition-delay: 0s, 0s;
|
|
83
|
+
transform: scale(1.25);
|
|
84
|
+
opacity: 0.15;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
:host([opened]) [part='toggle'] {
|
|
88
|
+
transform: rotate(270deg);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* RTL specific styles */
|
|
92
|
+
:host([dir='rtl']) [part='toggle'] {
|
|
93
|
+
right: 8px;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
:host([dir='rtl']) [part='toggle']::after {
|
|
97
|
+
left: auto;
|
|
98
|
+
right: 0;
|
|
99
|
+
}
|
|
100
|
+
`;
|
|
101
|
+
|
|
102
|
+
registerStyles('vaadin-details-summary', detailsSummary, { moduleId: 'material-details-summary' });
|
|
103
|
+
|
|
104
|
+
export { detailsSummary };
|
package/web-types.json
CHANGED
|
@@ -1,15 +1,90 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/web-types",
|
|
3
3
|
"name": "@vaadin/details",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "24.0.0-alpha10",
|
|
5
5
|
"description-markup": "markdown",
|
|
6
6
|
"contributions": {
|
|
7
7
|
"html": {
|
|
8
8
|
"elements": [
|
|
9
|
+
{
|
|
10
|
+
"name": "vaadin-details-summary",
|
|
11
|
+
"description": "The details summary element.",
|
|
12
|
+
"attributes": [
|
|
13
|
+
{
|
|
14
|
+
"name": "disabled",
|
|
15
|
+
"description": "If true, the user cannot interact with this element.",
|
|
16
|
+
"value": {
|
|
17
|
+
"type": [
|
|
18
|
+
"boolean",
|
|
19
|
+
"null",
|
|
20
|
+
"undefined"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "opened",
|
|
26
|
+
"description": "When true, the element is opened.",
|
|
27
|
+
"value": {
|
|
28
|
+
"type": [
|
|
29
|
+
"boolean",
|
|
30
|
+
"null",
|
|
31
|
+
"undefined"
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "theme",
|
|
37
|
+
"description": "The theme variants to apply to the component.",
|
|
38
|
+
"value": {
|
|
39
|
+
"type": [
|
|
40
|
+
"string",
|
|
41
|
+
"null",
|
|
42
|
+
"undefined"
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
],
|
|
47
|
+
"js": {
|
|
48
|
+
"properties": [
|
|
49
|
+
{
|
|
50
|
+
"name": "disabled",
|
|
51
|
+
"description": "If true, the user cannot interact with this element.",
|
|
52
|
+
"value": {
|
|
53
|
+
"type": [
|
|
54
|
+
"boolean",
|
|
55
|
+
"null",
|
|
56
|
+
"undefined"
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"name": "opened",
|
|
62
|
+
"description": "When true, the element is opened.",
|
|
63
|
+
"value": {
|
|
64
|
+
"type": [
|
|
65
|
+
"boolean",
|
|
66
|
+
"null",
|
|
67
|
+
"undefined"
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
],
|
|
72
|
+
"events": []
|
|
73
|
+
}
|
|
74
|
+
},
|
|
9
75
|
{
|
|
10
76
|
"name": "vaadin-details",
|
|
11
|
-
"description": "`<vaadin-details>` is a Web Component which the creates an\nexpandable panel similar to `<details>` HTML element.\n\n```\n<vaadin-details>\n <
|
|
77
|
+
"description": "`<vaadin-details>` is a Web Component which the creates an\nexpandable panel similar to `<details>` HTML element.\n\n```\n<vaadin-details>\n <vaadin-details-summary slot=\"summary\">Expandable Details</vaadin-details-summary>\n <div>\n Toggle using mouse, Enter and Space keys.\n </div>\n</vaadin-details>\n```\n\n### Styling\n\nThe following shadow DOM parts are exposed for styling:\n\nPart name | Description\n-----------------|----------------\n`summary` | The element used to open and close collapsible content.\n`toggle` | The element used as indicator, can represent an icon.\n`summary-content`| The wrapper for the slotted summary content.\n`content` | The wrapper for the collapsible details content.\n\nThe following attributes are exposed for styling:\n\nAttribute | Description\n-------------| -----------\n`opened` | Set when the collapsible content is expanded and visible.\n`disabled` | Set when the element is disabled.\n`focus-ring` | Set when the element is focused using the keyboard.\n`focused` | Set when the element is focused.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
|
|
12
78
|
"attributes": [
|
|
79
|
+
{
|
|
80
|
+
"name": "opened",
|
|
81
|
+
"description": "If true, the collapsible content is visible.",
|
|
82
|
+
"value": {
|
|
83
|
+
"type": [
|
|
84
|
+
"boolean"
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
},
|
|
13
88
|
{
|
|
14
89
|
"name": "disabled",
|
|
15
90
|
"description": "If true, the user cannot interact with this element.",
|
|
@@ -33,11 +108,13 @@
|
|
|
33
108
|
}
|
|
34
109
|
},
|
|
35
110
|
{
|
|
36
|
-
"name": "
|
|
37
|
-
"description": "
|
|
111
|
+
"name": "summary",
|
|
112
|
+
"description": "A text that is displayed in the summary, if no\nelement is assigned to the `summary` slot.",
|
|
38
113
|
"value": {
|
|
39
114
|
"type": [
|
|
40
|
-
"
|
|
115
|
+
"string",
|
|
116
|
+
"null",
|
|
117
|
+
"undefined"
|
|
41
118
|
]
|
|
42
119
|
}
|
|
43
120
|
},
|
|
@@ -55,6 +132,15 @@
|
|
|
55
132
|
],
|
|
56
133
|
"js": {
|
|
57
134
|
"properties": [
|
|
135
|
+
{
|
|
136
|
+
"name": "opened",
|
|
137
|
+
"description": "If true, the collapsible content is visible.",
|
|
138
|
+
"value": {
|
|
139
|
+
"type": [
|
|
140
|
+
"boolean"
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
},
|
|
58
144
|
{
|
|
59
145
|
"name": "disabled",
|
|
60
146
|
"description": "If true, the user cannot interact with this element.",
|
|
@@ -78,11 +164,13 @@
|
|
|
78
164
|
}
|
|
79
165
|
},
|
|
80
166
|
{
|
|
81
|
-
"name": "
|
|
82
|
-
"description": "
|
|
167
|
+
"name": "summary",
|
|
168
|
+
"description": "A text that is displayed in the summary, if no\nelement is assigned to the `summary` slot.",
|
|
83
169
|
"value": {
|
|
84
170
|
"type": [
|
|
85
|
-
"
|
|
171
|
+
"string",
|
|
172
|
+
"null",
|
|
173
|
+
"undefined"
|
|
86
174
|
]
|
|
87
175
|
}
|
|
88
176
|
}
|
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/details",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "24.0.0-alpha10",
|
|
5
5
|
"description-markup": "markdown",
|
|
6
6
|
"framework": "lit",
|
|
7
7
|
"framework-config": {
|
|
@@ -14,11 +14,39 @@
|
|
|
14
14
|
"contributions": {
|
|
15
15
|
"html": {
|
|
16
16
|
"elements": [
|
|
17
|
+
{
|
|
18
|
+
"name": "vaadin-details-summary",
|
|
19
|
+
"description": "The details summary element.",
|
|
20
|
+
"extension": true,
|
|
21
|
+
"attributes": [
|
|
22
|
+
{
|
|
23
|
+
"name": "?disabled",
|
|
24
|
+
"description": "If true, the user cannot interact with this element.",
|
|
25
|
+
"value": {
|
|
26
|
+
"kind": "expression"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "?opened",
|
|
31
|
+
"description": "When true, the element is opened.",
|
|
32
|
+
"value": {
|
|
33
|
+
"kind": "expression"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
},
|
|
17
38
|
{
|
|
18
39
|
"name": "vaadin-details",
|
|
19
|
-
"description": "`<vaadin-details>` is a Web Component which the creates an\nexpandable panel similar to `<details>` HTML element.\n\n```\n<vaadin-details>\n <
|
|
40
|
+
"description": "`<vaadin-details>` is a Web Component which the creates an\nexpandable panel similar to `<details>` HTML element.\n\n```\n<vaadin-details>\n <vaadin-details-summary slot=\"summary\">Expandable Details</vaadin-details-summary>\n <div>\n Toggle using mouse, Enter and Space keys.\n </div>\n</vaadin-details>\n```\n\n### Styling\n\nThe following shadow DOM parts are exposed for styling:\n\nPart name | Description\n-----------------|----------------\n`summary` | The element used to open and close collapsible content.\n`toggle` | The element used as indicator, can represent an icon.\n`summary-content`| The wrapper for the slotted summary content.\n`content` | The wrapper for the collapsible details content.\n\nThe following attributes are exposed for styling:\n\nAttribute | Description\n-------------| -----------\n`opened` | Set when the collapsible content is expanded and visible.\n`disabled` | Set when the element is disabled.\n`focus-ring` | Set when the element is focused using the keyboard.\n`focused` | Set when the element is focused.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
|
|
20
41
|
"extension": true,
|
|
21
42
|
"attributes": [
|
|
43
|
+
{
|
|
44
|
+
"name": "?opened",
|
|
45
|
+
"description": "If true, the collapsible content is visible.",
|
|
46
|
+
"value": {
|
|
47
|
+
"kind": "expression"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
22
50
|
{
|
|
23
51
|
"name": "?disabled",
|
|
24
52
|
"description": "If true, the user cannot interact with this element.",
|
|
@@ -34,8 +62,8 @@
|
|
|
34
62
|
}
|
|
35
63
|
},
|
|
36
64
|
{
|
|
37
|
-
"name": "
|
|
38
|
-
"description": "
|
|
65
|
+
"name": ".summary",
|
|
66
|
+
"description": "A text that is displayed in the summary, if no\nelement is assigned to the `summary` slot.",
|
|
39
67
|
"value": {
|
|
40
68
|
"kind": "expression"
|
|
41
69
|
}
|