@redvars/peacock 3.3.3 → 3.5.0
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/dist/IndividualComponent-DUINtMGK.js +67 -0
- package/dist/IndividualComponent-DUINtMGK.js.map +1 -0
- package/dist/assets/images/empty-state/no-document.svg +11 -12
- package/dist/assets/images/empty-state/page.svg +15 -9
- package/dist/assets/styles.css +1 -1
- package/dist/assets/styles.css.map +1 -1
- package/dist/banner.js +202 -0
- package/dist/banner.js.map +1 -0
- package/dist/bottom-sheet.js +238 -0
- package/dist/bottom-sheet.js.map +1 -0
- package/dist/{button-ClzS8JLq.js → button-DMN1dPAg.js} +358 -218
- package/dist/button-DMN1dPAg.js.map +1 -0
- package/dist/button-group-CX9CUUXk.js +435 -0
- package/dist/button-group-CX9CUUXk.js.map +1 -0
- package/dist/button-group.js +11 -6
- package/dist/button-group.js.map +1 -1
- package/dist/button.js +10 -5
- package/dist/button.js.map +1 -1
- package/dist/card-content.js +29 -0
- package/dist/card-content.js.map +1 -0
- package/dist/card.js +428 -44
- package/dist/card.js.map +1 -1
- package/dist/{chart-bar-DbnXQgvS.js → chart-bar-cn6rrna-.js} +2 -2
- package/dist/{chart-bar-DbnXQgvS.js.map → chart-bar-cn6rrna-.js.map} +1 -1
- package/dist/chart-bar.js +5 -4
- package/dist/chart-bar.js.map +1 -1
- package/dist/chart-doughnut.js +2 -1
- package/dist/chart-doughnut.js.map +1 -1
- package/dist/chart-pie.js +2 -1
- package/dist/chart-pie.js.map +1 -1
- package/dist/chart-stacked-bar.js +5 -4
- package/dist/chart-stacked-bar.js.map +1 -1
- package/dist/{class-map-59YGWLnx.js → class-map-YU7g0o3B.js} +4 -10
- package/dist/class-map-YU7g0o3B.js.map +1 -0
- package/dist/clock.js +2 -1
- package/dist/clock.js.map +1 -1
- package/dist/code-editor.js +8 -6
- package/dist/code-editor.js.map +1 -1
- package/dist/code-highlighter.js +6 -4
- package/dist/code-highlighter.js.map +1 -1
- package/dist/custom-elements-jsdocs.json +6270 -5026
- package/dist/custom-elements.json +5763 -2049
- package/dist/directive-ZPhl09Yt.js +9 -0
- package/dist/directive-ZPhl09Yt.js.map +1 -0
- package/dist/dispatch-event-utils-CuEqjlPT.js +127 -0
- package/dist/dispatch-event-utils-CuEqjlPT.js.map +1 -0
- package/dist/fab-C5Nzxk0E.js +497 -0
- package/dist/fab-C5Nzxk0E.js.map +1 -0
- package/dist/fab.js +11 -0
- package/dist/fab.js.map +1 -0
- package/dist/index.js +24 -12
- package/dist/index.js.map +1 -1
- package/dist/{observe-theme-change-pALI5fmV.js → is-dark-mode-DicqGkCJ.js} +8 -3
- package/dist/is-dark-mode-DicqGkCJ.js.map +1 -0
- package/dist/notification.js +417 -0
- package/dist/notification.js.map +1 -0
- package/dist/number-counter.js +4 -3
- package/dist/number-counter.js.map +1 -1
- package/dist/observe-slot-change-BGJfgg2E.js +31 -0
- package/dist/observe-slot-change-BGJfgg2E.js.map +1 -0
- package/dist/peacock-loader.js +59 -10
- package/dist/peacock-loader.js.map +1 -1
- package/dist/property-1psGvXOq.js +10 -0
- package/dist/property-1psGvXOq.js.map +1 -0
- package/dist/search.js +452 -0
- package/dist/search.js.map +1 -0
- package/dist/{radio-b70_Ie9n.js → select-4pl4XBj7.js} +2439 -521
- package/dist/select-4pl4XBj7.js.map +1 -0
- package/dist/side-sheet.js +186 -0
- package/dist/side-sheet.js.map +1 -0
- package/dist/spread-B5cgadZl.js +32 -0
- package/dist/spread-B5cgadZl.js.map +1 -0
- package/dist/src/__base_element/BaseHyperlink.d.ts +20 -0
- package/dist/src/__utils/cache-fetch.d.ts +1 -0
- package/dist/src/__utils/is-dark-mode.d.ts +1 -0
- package/dist/src/__utils/is-in-viewport.d.ts +1 -0
- package/dist/src/__utils/observe-slot-change.d.ts +1 -0
- package/dist/src/__utils/sanitize-svg.d.ts +1 -0
- package/dist/src/__utils/throttle.d.ts +4 -0
- package/dist/src/accordion/accordion-item.d.ts +33 -9
- package/dist/src/accordion/accordion.d.ts +21 -5
- package/dist/src/banner/banner.d.ts +47 -0
- package/dist/src/banner/index.d.ts +1 -0
- package/dist/src/bottom-sheet/bottom-sheet.d.ts +42 -0
- package/dist/src/bottom-sheet/index.d.ts +1 -0
- package/dist/src/button/BaseButton.d.ts +7 -13
- package/dist/src/button/button/button.d.ts +4 -0
- package/dist/src/button/button-group/button-group.d.ts +32 -3
- package/dist/src/button/icon-button/icon-button.d.ts +4 -0
- package/dist/src/card/card-content.d.ts +15 -0
- package/dist/src/card/card.d.ts +37 -3
- package/dist/src/card/index.d.ts +1 -0
- package/dist/src/container/container.d.ts +1 -1
- package/dist/src/empty-state/empty-state.d.ts +1 -1
- package/dist/src/fab/fab.d.ts +111 -0
- package/dist/src/fab/index.d.ts +1 -0
- package/dist/src/focus-ring/focus-ring.d.ts +4 -1
- package/dist/src/index.d.ts +11 -1
- package/dist/src/link/link.d.ts +3 -10
- package/dist/src/menu/menu/menu.d.ts +4 -2
- package/dist/src/menu/menu-item/menu-item.d.ts +0 -1
- package/dist/src/menu/sub-menu/sub-menu.d.ts +1 -0
- package/dist/src/notification/index.d.ts +1 -0
- package/dist/src/notification/notification.d.ts +69 -0
- package/dist/src/pagination/pagination.d.ts +8 -1
- package/dist/src/ripple/ripple.d.ts +19 -3
- package/dist/src/search/index.d.ts +1 -0
- package/dist/src/search/search.d.ts +76 -0
- package/dist/src/segmented-button/index.d.ts +2 -0
- package/dist/src/segmented-button/segmented-button-group.d.ts +46 -0
- package/dist/src/segmented-button/segmented-button.d.ts +65 -0
- package/dist/src/select/index.d.ts +3 -0
- package/dist/src/select/option.d.ts +55 -0
- package/dist/src/select/select.d.ts +114 -0
- package/dist/src/side-sheet/index.d.ts +1 -0
- package/dist/src/side-sheet/side-sheet.d.ts +41 -0
- package/dist/src/slider/slider.d.ts +4 -0
- package/dist/src/snackbar/snackbar.d.ts +14 -1
- package/dist/src/tabs/tab-group.d.ts +0 -1
- package/dist/src/tabs/tab.d.ts +8 -2
- package/dist/src/tabs/tabs.d.ts +13 -1
- package/dist/src/toolbar/index.d.ts +1 -0
- package/dist/src/toolbar/toolbar.d.ts +86 -0
- package/dist/state-DwbEjqVk.js +10 -0
- package/dist/state-DwbEjqVk.js.map +1 -0
- package/dist/{style-map-DcB52w-l.js → style-map-DVmWOuYy.js} +3 -3
- package/dist/{style-map-DcB52w-l.js.map → style-map-DVmWOuYy.js.map} +1 -1
- package/dist/test/search.test.d.ts +1 -0
- package/dist/test/toolbar.test.d.ts +1 -0
- package/dist/throttle-C7ZAPqtu.js +24 -0
- package/dist/throttle-C7ZAPqtu.js.map +1 -0
- package/dist/toolbar.js +306 -0
- package/dist/toolbar.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/{unsafe-html-C2r3PyzF.js → unsafe-html-BsGUjx94.js} +3 -3
- package/dist/{unsafe-html-C2r3PyzF.js.map → unsafe-html-BsGUjx94.js.map} +1 -1
- package/package.json +1 -1
- package/readme.md +2 -2
- package/scss/styles.scss +4 -0
- package/src/__base_element/BaseHyperlink.ts +42 -0
- package/src/__base_element/README.md +19 -0
- package/src/__utils/cache-fetch.ts +65 -0
- package/src/{utils → __utils}/dispatch-event-utils.ts +1 -0
- package/src/__utils/is-dark-mode.ts +3 -0
- package/src/__utils/is-in-viewport.ts +6 -0
- package/src/__utils/observe-slot-change.ts +38 -0
- package/src/__utils/sanitize-svg.ts +27 -0
- package/src/__utils/throttle.ts +27 -0
- package/src/accordion/accordion-item.scss +136 -65
- package/src/accordion/accordion-item.ts +117 -44
- package/src/accordion/accordion.scss +24 -5
- package/src/accordion/accordion.ts +29 -23
- package/src/accordion/demo/index.html +74 -35
- package/src/banner/banner.scss +87 -0
- package/src/banner/banner.ts +107 -0
- package/src/banner/index.ts +1 -0
- package/src/bottom-sheet/bottom-sheet.scss +88 -0
- package/src/bottom-sheet/bottom-sheet.ts +135 -0
- package/src/bottom-sheet/index.ts +1 -0
- package/src/button/BaseButton.ts +26 -30
- package/src/button/button/button-colors.scss +90 -19
- package/src/button/button/button-sizes.scss +39 -19
- package/src/button/button/button.scss +117 -116
- package/src/button/button/button.ts +29 -6
- package/src/button/button-group/button-group.scss +25 -22
- package/src/button/button-group/button-group.ts +122 -5
- package/src/button/icon-button/icon-button-sizes.scss +35 -15
- package/src/button/icon-button/icon-button.ts +25 -12
- package/src/card/card-colors.scss +10 -0
- package/src/card/card-content.ts +26 -0
- package/src/card/card.scss +221 -41
- package/src/card/card.ts +251 -8
- package/src/card/index.ts +1 -0
- package/src/chart-bar/chart-bar.ts +1 -1
- package/src/chart-bar/chart-stacked-bar.ts +3 -1
- package/src/chart-doughnut/chart-doughnut.ts +1 -1
- package/src/chart-pie/chart-pie.ts +1 -1
- package/src/checkbox/checkbox.ts +1 -1
- package/src/clock/clock.ts +1 -1
- package/src/code-editor/code-editor.ts +5 -5
- package/src/code-highlighter/code-highlighter.ts +2 -2
- package/src/container/container.ts +1 -1
- package/src/date-picker/date-picker.ts +5 -2
- package/src/divider/divider.ts +3 -1
- package/src/empty-state/empty-state.scss +9 -3
- package/src/empty-state/empty-state.ts +2 -2
- package/src/fab/fab-colors.scss +49 -0
- package/src/fab/fab-sizes.scss +47 -0
- package/src/fab/fab.scss +137 -0
- package/src/fab/fab.ts +285 -0
- package/src/fab/index.ts +1 -0
- package/src/field/field.ts +3 -1
- package/src/focus-ring/focus-ring.ts +37 -19
- package/src/icon/datasource.ts +1 -1
- package/src/icon/icon.ts +3 -1
- package/src/image/image.ts +3 -2
- package/src/index.ts +12 -1
- package/src/input/input.ts +5 -2
- package/src/link/link.ts +2 -15
- package/src/menu/menu/menu.scss +31 -3
- package/src/menu/menu/menu.ts +30 -6
- package/src/menu/menu-item/menu-item.scss +1 -0
- package/src/menu/menu-item/menu-item.ts +1 -9
- package/src/menu/sub-menu/sub-menu.ts +1 -0
- package/src/notification/index.ts +1 -0
- package/src/notification/notification.scss +201 -0
- package/src/notification/notification.ts +206 -0
- package/src/number-counter/number-counter.ts +3 -1
- package/src/number-field/number-field.ts +4 -2
- package/src/pagination/pagination.scss +33 -24
- package/src/pagination/pagination.ts +113 -60
- package/src/peacock-loader.ts +48 -0
- package/src/radio/radio.ts +3 -1
- package/src/ripple/ripple.ts +19 -3
- package/src/search/index.ts +1 -0
- package/src/search/search-colors.scss +14 -0
- package/src/search/search.scss +204 -0
- package/src/search/search.ts +240 -0
- package/src/segmented-button/index.ts +2 -0
- package/src/segmented-button/segmented-button-group.scss +21 -0
- package/src/segmented-button/segmented-button-group.ts +110 -0
- package/src/segmented-button/segmented-button.scss +115 -0
- package/src/segmented-button/segmented-button.ts +175 -0
- package/src/select/index.ts +3 -0
- package/src/select/option.ts +109 -0
- package/src/select/select.scss +125 -0
- package/src/select/select.ts +520 -0
- package/src/side-sheet/index.ts +1 -0
- package/src/side-sheet/side-sheet.scss +79 -0
- package/src/side-sheet/side-sheet.ts +100 -0
- package/src/slider/slider.scss +19 -1
- package/src/slider/slider.ts +30 -19
- package/src/snackbar/snackbar.scss +62 -31
- package/src/snackbar/snackbar.ts +92 -12
- package/src/switch/switch.ts +3 -1
- package/src/table/table.ts +3 -1
- package/src/tabs/demo/index.html +90 -0
- package/src/tabs/tab-group.ts +0 -3
- package/src/tabs/tab.scss +237 -25
- package/src/tabs/tab.ts +91 -14
- package/src/tabs/tabs.scss +37 -3
- package/src/tabs/tabs.ts +118 -2
- package/src/textarea/textarea.ts +4 -2
- package/src/time-picker/time-picker.ts +4 -2
- package/src/toolbar/index.ts +1 -0
- package/src/toolbar/toolbar-colors.scss +16 -0
- package/src/toolbar/toolbar.scss +165 -0
- package/src/toolbar/toolbar.ts +137 -0
- package/dist/IndividualComponent-Dt5xirYG.js +0 -73
- package/dist/IndividualComponent-Dt5xirYG.js.map +0 -1
- package/dist/button-ClzS8JLq.js.map +0 -1
- package/dist/button-group-BMS5WvaF.js +0 -292
- package/dist/button-group-BMS5WvaF.js.map +0 -1
- package/dist/chart-donut.js +0 -309
- package/dist/chart-donut.js.map +0 -1
- package/dist/class-map-59YGWLnx.js.map +0 -1
- package/dist/directive-Cuw6h7YA.js +0 -9
- package/dist/directive-Cuw6h7YA.js.map +0 -1
- package/dist/dispatch-event-utils-B4odODQf.js +0 -277
- package/dist/dispatch-event-utils-B4odODQf.js.map +0 -1
- package/dist/observe-theme-change-pALI5fmV.js.map +0 -1
- package/dist/radio-b70_Ie9n.js.map +0 -1
- package/dist/src/chart-donut/chart-donut.d.ts +0 -53
- package/dist/src/chart-donut/index.d.ts +0 -1
- package/dist/src/styleMixins.css.d.ts +0 -9
- package/dist/src/utils.d.ts +0 -9
- package/src/chart-donut/chart-donut.scss +0 -37
- package/src/chart-donut/chart-donut.ts +0 -287
- package/src/chart-donut/demo/index.html +0 -51
- package/src/chart-donut/index.ts +0 -1
- package/src/styleMixins.css.ts +0 -55
- package/src/utils.ts +0 -193
- /package/dist/src/{spread.d.ts → __directive/spread.d.ts} +0 -0
- /package/dist/src/{utils → __utils}/copy-to-clipboard.d.ts +0 -0
- /package/dist/src/{utils → __utils}/dispatch-event-utils.d.ts +0 -0
- /package/dist/src/{utils → __utils}/observe-theme-change.d.ts +0 -0
- /package/dist/test/{card.test.d.ts → banner.test.d.ts} +0 -0
- /package/src/{spread.ts → __directive/spread.ts} +0 -0
- /package/src/{utils → __utils}/copy-to-clipboard.ts +0 -0
- /package/src/{utils → __utils}/observe-theme-change.ts +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { html, LitElement } from 'lit';
|
|
2
|
-
import { property, query } from 'lit/decorators.js';
|
|
1
|
+
import { html, LitElement, nothing } from 'lit';
|
|
2
|
+
import { property, query, state } from 'lit/decorators.js';
|
|
3
3
|
import { classMap } from 'lit/directives/class-map.js';
|
|
4
4
|
import styles from './accordion-item.scss';
|
|
5
5
|
|
|
@@ -7,13 +7,27 @@ import styles from './accordion-item.scss';
|
|
|
7
7
|
* @label Accordion Item
|
|
8
8
|
* @tag wc-accordion-item
|
|
9
9
|
* @rawTag accordion-item
|
|
10
|
-
* @summary An
|
|
10
|
+
* @summary An expansion panel with a header that reveals or hides associated content. Follows Material Design 3 expansion panel guidelines.
|
|
11
11
|
* @parentRawTag accordion
|
|
12
|
-
*
|
|
12
|
+
*
|
|
13
|
+
* @slot - The body content revealed when the panel is expanded.
|
|
14
|
+
* @slot heading - The panel title. Renders as `body-large` text.
|
|
15
|
+
* @slot description - Optional subtitle rendered below the title. Renders as `body-small` text.
|
|
16
|
+
* @slot header-actions - Actions (e.g. icon buttons) placed at the trailing end of the header, before the toggle icon.
|
|
17
|
+
*
|
|
18
|
+
* @part header - The header `<button>` element.
|
|
19
|
+
* @part title - The title text container.
|
|
20
|
+
* @part description - The description text container.
|
|
21
|
+
* @part content - The expandable content region wrapper.
|
|
22
|
+
*
|
|
23
|
+
* @fires {CustomEvent<{ open: boolean }>} accordion-item:toggle - Fired when the panel is expanded or collapsed.
|
|
24
|
+
*
|
|
13
25
|
* @example
|
|
14
26
|
* ```html
|
|
15
27
|
* <wc-accordion-item>
|
|
16
|
-
*
|
|
28
|
+
* <span slot="heading">Personal information</span>
|
|
29
|
+
* <span slot="description">Fill in your details</span>
|
|
30
|
+
* <p>Content goes here.</p>
|
|
17
31
|
* </wc-accordion-item>
|
|
18
32
|
* ```
|
|
19
33
|
* @tags display
|
|
@@ -24,24 +38,38 @@ export class AccordionItem extends LitElement {
|
|
|
24
38
|
#id = crypto.randomUUID();
|
|
25
39
|
|
|
26
40
|
/**
|
|
27
|
-
*
|
|
28
|
-
*/
|
|
29
|
-
@property({ type: String, reflect: true })
|
|
30
|
-
heading: string = '';
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* If true, the user cannot interact with the button. Defaults to `false`.
|
|
41
|
+
* Whether the user cannot interact with the panel.
|
|
34
42
|
*/
|
|
35
43
|
@property({ type: Boolean, reflect: true })
|
|
36
44
|
disabled: boolean = false;
|
|
37
45
|
|
|
38
46
|
/**
|
|
39
|
-
*
|
|
47
|
+
* Whether the panel is expanded.
|
|
40
48
|
*/
|
|
41
49
|
@property({ type: Boolean, reflect: true })
|
|
42
50
|
open: boolean = false;
|
|
43
51
|
|
|
44
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Whether to hide the expand/collapse toggle indicator icon.
|
|
54
|
+
*/
|
|
55
|
+
@property({ type: Boolean, reflect: true, attribute: 'hide-toggle' })
|
|
56
|
+
hideToggle: boolean = false;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Position of the toggle icon relative to the panel title.
|
|
60
|
+
* `'after'` places it at the trailing end (default, matches M3).
|
|
61
|
+
* `'before'` places it at the leading start.
|
|
62
|
+
*/
|
|
63
|
+
@property({ type: String, reflect: true, attribute: 'toggle-position' })
|
|
64
|
+
togglePosition: 'before' | 'after' = 'after';
|
|
65
|
+
|
|
66
|
+
@state()
|
|
67
|
+
private _hasDescriptionSlot = false;
|
|
68
|
+
|
|
69
|
+
@state()
|
|
70
|
+
private _hasHeadingSlot = false;
|
|
71
|
+
|
|
72
|
+
@query('.header-button')
|
|
45
73
|
private readonly buttonElement!: HTMLElement | null;
|
|
46
74
|
|
|
47
75
|
override focus() {
|
|
@@ -52,48 +80,93 @@ export class AccordionItem extends LitElement {
|
|
|
52
80
|
this.buttonElement?.blur();
|
|
53
81
|
}
|
|
54
82
|
|
|
55
|
-
private
|
|
83
|
+
private _handleToggle() {
|
|
56
84
|
if (this.disabled) return;
|
|
57
85
|
this.open = !this.open;
|
|
58
86
|
this.dispatchEvent(
|
|
59
|
-
new CustomEvent('accordion-item
|
|
87
|
+
new CustomEvent('accordion-item:toggle', {
|
|
60
88
|
bubbles: true,
|
|
61
89
|
composed: true,
|
|
62
|
-
detail: { open: this.open
|
|
90
|
+
detail: { open: this.open },
|
|
63
91
|
}),
|
|
64
92
|
);
|
|
65
93
|
}
|
|
66
94
|
|
|
95
|
+
private static _onSlotChange(e: Event, setter: (v: boolean) => void) {
|
|
96
|
+
const slot = e.target as HTMLSlotElement;
|
|
97
|
+
const nodes = slot.assignedNodes({ flatten: true });
|
|
98
|
+
setter(
|
|
99
|
+
nodes.some(n =>
|
|
100
|
+
n.nodeType === Node.TEXT_NODE
|
|
101
|
+
? (n.textContent?.trim() ?? '') !== ''
|
|
102
|
+
: true,
|
|
103
|
+
),
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private _renderToggleIcon() {
|
|
108
|
+
if (this.hideToggle) return nothing;
|
|
109
|
+
return html`<wc-icon
|
|
110
|
+
class="toggle-icon"
|
|
111
|
+
name="keyboard_arrow_down"
|
|
112
|
+
aria-hidden="true"
|
|
113
|
+
></wc-icon>`;
|
|
114
|
+
}
|
|
115
|
+
|
|
67
116
|
render() {
|
|
68
|
-
return html
|
|
69
|
-
class=${classMap({
|
|
70
|
-
'accordion-item': true,
|
|
71
|
-
open: this.open,
|
|
72
|
-
disabled: this.disabled,
|
|
73
|
-
})}
|
|
74
|
-
>
|
|
75
|
-
<button
|
|
76
|
-
id=${`accordion-heading-${this.#id}`}
|
|
77
|
-
tabindex="0"
|
|
78
|
-
aria-controls=${`accordion-control-${this.#id}`}
|
|
79
|
-
class="accordion-heading"
|
|
80
|
-
aria-disabled=${this.disabled}
|
|
81
|
-
@click=${this.__handleToggle}
|
|
82
|
-
aria-expanded=${this.open}
|
|
83
|
-
>
|
|
84
|
-
<wc-icon class="accordion-icon" name="keyboard_arrow_down"></wc-icon>
|
|
85
|
-
<div part="title" class="accordion-title">
|
|
86
|
-
<slot name="heading">${this.heading}</slot>
|
|
87
|
-
</div>
|
|
88
|
-
</button>
|
|
117
|
+
return html`
|
|
89
118
|
<div
|
|
90
|
-
class
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
119
|
+
class=${classMap({
|
|
120
|
+
'expansion-panel': true,
|
|
121
|
+
open: this.open,
|
|
122
|
+
disabled: this.disabled,
|
|
123
|
+
})}
|
|
94
124
|
>
|
|
95
|
-
<
|
|
125
|
+
<button
|
|
126
|
+
id=${`panel-header-${this.#id}`}
|
|
127
|
+
part="header"
|
|
128
|
+
class="header-button"
|
|
129
|
+
tabindex=${this.disabled ? '-1' : '0'}
|
|
130
|
+
aria-controls=${`panel-content-${this.#id}`}
|
|
131
|
+
aria-disabled=${this.disabled}
|
|
132
|
+
aria-expanded=${this.open}
|
|
133
|
+
?disabled=${this.disabled}
|
|
134
|
+
@click=${this._handleToggle}
|
|
135
|
+
>
|
|
136
|
+
${this.togglePosition === 'before' ? this._renderToggleIcon() : nothing}
|
|
137
|
+
<span class="header-label">
|
|
138
|
+
<span part="title" class="panel-title">
|
|
139
|
+
<slot
|
|
140
|
+
name="heading"
|
|
141
|
+
@slotchange=${(e: Event) => AccordionItem._onSlotChange(e, v => { this._hasHeadingSlot = v; })}
|
|
142
|
+
></slot>
|
|
143
|
+
</span>
|
|
144
|
+
<span
|
|
145
|
+
part="description"
|
|
146
|
+
class="panel-description"
|
|
147
|
+
?hidden=${!this._hasDescriptionSlot}
|
|
148
|
+
>
|
|
149
|
+
<slot
|
|
150
|
+
name="description"
|
|
151
|
+
@slotchange=${(e: Event) => AccordionItem._onSlotChange(e, v => { this._hasDescriptionSlot = v; })}
|
|
152
|
+
></slot>
|
|
153
|
+
</span>
|
|
154
|
+
</span>
|
|
155
|
+
<slot name="header-actions" class="header-actions"></slot>
|
|
156
|
+
${this.togglePosition === 'after' ? this._renderToggleIcon() : nothing}
|
|
157
|
+
</button>
|
|
158
|
+
<div
|
|
159
|
+
id=${`panel-content-${this.#id}`}
|
|
160
|
+
part="content"
|
|
161
|
+
class="panel-content"
|
|
162
|
+
role="region"
|
|
163
|
+
aria-labelledby=${`panel-header-${this.#id}`}
|
|
164
|
+
>
|
|
165
|
+
<div class="content-inner">
|
|
166
|
+
<slot></slot>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
96
169
|
</div>
|
|
97
|
-
|
|
170
|
+
`;
|
|
98
171
|
}
|
|
99
172
|
}
|
|
@@ -2,15 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
@include mixin.base-styles;
|
|
4
4
|
|
|
5
|
+
// ─── Host ────────────────────────────────────────────────────────────────────
|
|
6
|
+
|
|
5
7
|
:host {
|
|
6
8
|
display: block;
|
|
7
9
|
}
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
// ─── Default display mode ────────────────────────────────────────────────────
|
|
12
|
+
// Each item is a fully-bordered rounded container (M3 expansion panel shape).
|
|
13
|
+
// Items are stacked with a gap; no shared dividers.
|
|
14
|
+
|
|
15
|
+
.accordion {
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
gap: var(--spacing-100); // 8dp gap between panels
|
|
11
19
|
}
|
|
12
20
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
21
|
+
// ─── Flat display mode ───────────────────────────────────────────────────────
|
|
22
|
+
// Removes the gap and the per-item border/background — for use inside cards.
|
|
23
|
+
|
|
24
|
+
:host([display-mode='flat']) {
|
|
25
|
+
.accordion {
|
|
26
|
+
gap: 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Push overrides into each item via inherited CSS custom properties.
|
|
30
|
+
// wc-accordion-item reads --_accordion-item-border / --_accordion-item-background.
|
|
31
|
+
slot::slotted(wc-accordion-item) {
|
|
32
|
+
--_accordion-item-border: none;
|
|
33
|
+
--_accordion-item-background: transparent;
|
|
34
|
+
}
|
|
16
35
|
}
|
|
@@ -7,14 +7,20 @@ import { AccordionItem } from './accordion-item.js';
|
|
|
7
7
|
* @label Accordion
|
|
8
8
|
* @tag wc-accordion
|
|
9
9
|
* @rawTag accordion
|
|
10
|
-
* @summary
|
|
10
|
+
* @summary A vertically stacked set of expansion panels. Follows Material Design 3 expansion panel guidelines.
|
|
11
11
|
*
|
|
12
12
|
* @example
|
|
13
13
|
* ```html
|
|
14
14
|
* <wc-accordion>
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* </
|
|
15
|
+
* <wc-accordion-item>
|
|
16
|
+
* <span slot="heading">Panel 1</span>
|
|
17
|
+
* <span slot="description">Summary text</span>
|
|
18
|
+
* Content
|
|
19
|
+
* </wc-accordion-item>
|
|
20
|
+
* <wc-accordion-item>
|
|
21
|
+
* <span slot="heading">Panel 2</span>
|
|
22
|
+
* Content
|
|
23
|
+
* </wc-accordion-item>
|
|
18
24
|
* </wc-accordion>
|
|
19
25
|
* ```
|
|
20
26
|
* @tags display
|
|
@@ -22,10 +28,22 @@ import { AccordionItem } from './accordion-item.js';
|
|
|
22
28
|
export class Accordion extends LitElement {
|
|
23
29
|
static styles = [styles];
|
|
24
30
|
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Whether multiple panels can be expanded simultaneously.
|
|
33
|
+
* When `false` (default), expanding one panel collapses all others.
|
|
34
|
+
*/
|
|
35
|
+
@property({ type: Boolean, reflect: true })
|
|
36
|
+
multi = false;
|
|
27
37
|
|
|
28
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Display mode for the accordion.
|
|
40
|
+
* `'default'` renders panels with a subtle background on expand and dividers between items.
|
|
41
|
+
* `'flat'` renders panels without borders or background changes — suitable for use inside cards.
|
|
42
|
+
*/
|
|
43
|
+
@property({ type: String, reflect: true, attribute: 'display-mode' })
|
|
44
|
+
displayMode: 'default' | 'flat' = 'default';
|
|
45
|
+
|
|
46
|
+
@queryAssignedElements({ selector: 'wc-accordion-item' })
|
|
29
47
|
items!: Array<AccordionItem>;
|
|
30
48
|
|
|
31
49
|
connectedCallback() {
|
|
@@ -39,7 +57,6 @@ export class Accordion extends LitElement {
|
|
|
39
57
|
disconnectedCallback() {
|
|
40
58
|
super.disconnectedCallback();
|
|
41
59
|
// @ts-ignore
|
|
42
|
-
// eslint-disable-next-line no-undef
|
|
43
60
|
this.removeEventListener('accordion-item:toggle', this._onItemToggle);
|
|
44
61
|
this.removeEventListener('keydown', this._onKeyDown);
|
|
45
62
|
}
|
|
@@ -47,11 +64,10 @@ export class Accordion extends LitElement {
|
|
|
47
64
|
private _onItemToggle(e: CustomEvent) {
|
|
48
65
|
const targetItem = e.target as AccordionItem;
|
|
49
66
|
|
|
50
|
-
//
|
|
51
|
-
// We check if the target item is a direct child of *this* accordion
|
|
67
|
+
// Ignore events from nested accordions — only handle direct children
|
|
52
68
|
if (targetItem.parentElement !== this) return;
|
|
53
69
|
|
|
54
|
-
if (!this.
|
|
70
|
+
if (!this.multi && targetItem.open) {
|
|
55
71
|
this.items.forEach(item => {
|
|
56
72
|
if (item !== targetItem && item.open) {
|
|
57
73
|
// eslint-disable-next-line no-param-reassign
|
|
@@ -62,17 +78,11 @@ export class Accordion extends LitElement {
|
|
|
62
78
|
}
|
|
63
79
|
|
|
64
80
|
private _onKeyDown(e: KeyboardEvent) {
|
|
65
|
-
// 1. Find which item currently has its HEADER focused.
|
|
66
|
-
// We check the shadowRoot of each item to see if the internal <button> is the active element.
|
|
67
81
|
const focusedItemIndex = this.items.findIndex(item => {
|
|
68
|
-
// Access the Shadow DOM of the item
|
|
69
82
|
const root = item.shadowRoot;
|
|
70
|
-
|
|
71
|
-
return root?.activeElement?.classList.contains('accordion-heading');
|
|
83
|
+
return root?.activeElement?.classList.contains('header-button');
|
|
72
84
|
});
|
|
73
85
|
|
|
74
|
-
// 2. If no header is focused (e.g., focus is on body content or outside), do nothing.
|
|
75
|
-
// This prevents stealing focus when the user is typing in a form inside the accordion.
|
|
76
86
|
if (focusedItemIndex === -1) return;
|
|
77
87
|
|
|
78
88
|
let nextIndex = -1;
|
|
@@ -81,12 +91,10 @@ export class Accordion extends LitElement {
|
|
|
81
91
|
switch (e.key) {
|
|
82
92
|
case 'ArrowDown':
|
|
83
93
|
e.preventDefault();
|
|
84
|
-
// Cycle next
|
|
85
94
|
nextIndex = (focusedItemIndex + 1) % this.items.length;
|
|
86
95
|
break;
|
|
87
96
|
case 'ArrowUp':
|
|
88
97
|
e.preventDefault();
|
|
89
|
-
// Cycle previous
|
|
90
98
|
nextIndex =
|
|
91
99
|
(focusedItemIndex - 1 + this.items.length) % this.items.length;
|
|
92
100
|
break;
|
|
@@ -100,12 +108,10 @@ export class Accordion extends LitElement {
|
|
|
100
108
|
break;
|
|
101
109
|
}
|
|
102
110
|
|
|
103
|
-
// 3. Apply Focus
|
|
104
111
|
if (nextIndex !== -1) {
|
|
105
112
|
const itemToFocus = this.items[nextIndex];
|
|
106
|
-
// Select the button inside the Shadow DOM of the target item
|
|
107
113
|
const button = itemToFocus.shadowRoot?.querySelector(
|
|
108
|
-
'.
|
|
114
|
+
'.header-button',
|
|
109
115
|
) as HTMLElement;
|
|
110
116
|
button?.focus();
|
|
111
117
|
}
|
|
@@ -9,50 +9,89 @@
|
|
|
9
9
|
<style>
|
|
10
10
|
body {
|
|
11
11
|
background: #fafafa;
|
|
12
|
+
padding: 2rem;
|
|
13
|
+
max-width: 640px;
|
|
14
|
+
margin: 0 auto;
|
|
12
15
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
h3 {
|
|
17
|
+
margin: 1.5rem 0 0.5rem;
|
|
18
|
+
font-family: sans-serif;
|
|
19
|
+
font-size: 0.875rem;
|
|
20
|
+
color: #666;
|
|
16
21
|
}
|
|
17
22
|
</style>
|
|
18
23
|
</head>
|
|
19
24
|
<body>
|
|
20
25
|
|
|
21
|
-
<
|
|
22
|
-
<
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
<h3>Default</h3>
|
|
27
|
+
<wc-accordion>
|
|
28
|
+
<wc-accordion-item>
|
|
29
|
+
<span slot="heading">Personal information</span>
|
|
30
|
+
<span slot="description">Fill in your personal details</span>
|
|
31
|
+
<p>Type in your name and address below.</p>
|
|
32
|
+
</wc-accordion-item>
|
|
33
|
+
<wc-accordion-item>
|
|
34
|
+
<span slot="heading">Shipping address</span>
|
|
35
|
+
<span slot="description">Where should we send your order?</span>
|
|
36
|
+
<p>Add your shipping address to continue.</p>
|
|
37
|
+
</wc-accordion-item>
|
|
38
|
+
<wc-accordion-item disabled>
|
|
39
|
+
<span slot="heading">Billing address</span>
|
|
40
|
+
<p>This section is unavailable.</p>
|
|
41
|
+
</wc-accordion-item>
|
|
42
|
+
</wc-accordion>
|
|
32
43
|
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
44
|
+
<h3>Multi (allow multiple panels open)</h3>
|
|
45
|
+
<wc-accordion multi>
|
|
46
|
+
<wc-accordion-item>
|
|
47
|
+
<span slot="heading">Panel A</span>
|
|
48
|
+
<p>Content for panel A.</p>
|
|
49
|
+
</wc-accordion-item>
|
|
50
|
+
<wc-accordion-item open>
|
|
51
|
+
<span slot="heading">Panel B</span>
|
|
52
|
+
<p>Content for panel B (initially open).</p>
|
|
53
|
+
</wc-accordion-item>
|
|
54
|
+
<wc-accordion-item>
|
|
55
|
+
<span slot="heading">Panel C</span>
|
|
56
|
+
<p>Content for panel C.</p>
|
|
57
|
+
</wc-accordion-item>
|
|
58
|
+
</wc-accordion>
|
|
43
59
|
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
</
|
|
60
|
+
<h3>Toggle position: before</h3>
|
|
61
|
+
<wc-accordion>
|
|
62
|
+
<wc-accordion-item toggle-position="before">
|
|
63
|
+
<span slot="heading">Panel 1</span>
|
|
64
|
+
<p>Icon appears at the leading start.</p>
|
|
65
|
+
</wc-accordion-item>
|
|
66
|
+
<wc-accordion-item toggle-position="before">
|
|
67
|
+
<span slot="heading">Panel 2</span>
|
|
68
|
+
<p>Icon appears at the leading start.</p>
|
|
69
|
+
</wc-accordion-item>
|
|
70
|
+
</wc-accordion>
|
|
55
71
|
|
|
72
|
+
<h3>Hide toggle</h3>
|
|
73
|
+
<wc-accordion>
|
|
74
|
+
<wc-accordion-item hide-toggle>
|
|
75
|
+
<span slot="heading">No toggle icon</span>
|
|
76
|
+
<p>The expand indicator is hidden.</p>
|
|
77
|
+
</wc-accordion-item>
|
|
78
|
+
<wc-accordion-item hide-toggle>
|
|
79
|
+
<span slot="heading">Another panel</span>
|
|
80
|
+
<p>Click the header to toggle.</p>
|
|
81
|
+
</wc-accordion-item>
|
|
82
|
+
</wc-accordion>
|
|
83
|
+
|
|
84
|
+
<h3>Flat display mode</h3>
|
|
85
|
+
<wc-accordion display-mode="flat">
|
|
86
|
+
<wc-accordion-item>
|
|
87
|
+
<span slot="heading">Flat Panel 1</span>
|
|
88
|
+
<p>No borders between panels. Suitable inside cards.</p>
|
|
89
|
+
</wc-accordion-item>
|
|
90
|
+
<wc-accordion-item>
|
|
91
|
+
<span slot="heading">Flat Panel 2</span>
|
|
92
|
+
<p>Content here.</p>
|
|
93
|
+
</wc-accordion-item>
|
|
94
|
+
</wc-accordion>
|
|
56
95
|
|
|
57
96
|
<script type='module' src='/dist/peacock-loader.js'></script>
|
|
58
97
|
</body>
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
@use '../../scss/mixin';
|
|
2
|
+
|
|
3
|
+
@include mixin.base-styles;
|
|
4
|
+
|
|
5
|
+
:host {
|
|
6
|
+
display: block;
|
|
7
|
+
|
|
8
|
+
--banner-container-color: var(--color-tertiary-container);
|
|
9
|
+
--banner-label-text-color: var(--color-on-tertiary-container);
|
|
10
|
+
--banner-description-text-color: var(--color-on-tertiary-container);
|
|
11
|
+
--banner-icon-color: var(--color-on-tertiary-container);
|
|
12
|
+
--banner-border-radius: var(--shape-corner-small);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.banner {
|
|
16
|
+
align-items: flex-start;
|
|
17
|
+
background: var(--banner-container-color);
|
|
18
|
+
border-radius: var(--banner-border-radius);
|
|
19
|
+
display: grid;
|
|
20
|
+
gap: var(--spacing-200);
|
|
21
|
+
grid-template-columns: auto 1fr;
|
|
22
|
+
padding: var(--spacing-200);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.banner-icon {
|
|
26
|
+
align-items: center;
|
|
27
|
+
color: var(--banner-icon-color);
|
|
28
|
+
display: inline-flex;
|
|
29
|
+
justify-content: center;
|
|
30
|
+
min-width: 1.5rem;
|
|
31
|
+
padding-top: 0.1rem;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.banner-content {
|
|
35
|
+
display: flex;
|
|
36
|
+
flex-direction: column;
|
|
37
|
+
gap: var(--spacing-050);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.banner-label {
|
|
41
|
+
@include mixin.get-typography(label-large);
|
|
42
|
+
color: var(--banner-label-text-color);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.banner-description {
|
|
46
|
+
@include mixin.get-typography(body-medium);
|
|
47
|
+
color: var(--banner-description-text-color);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.banner-content.inline {
|
|
51
|
+
flex-direction: row;
|
|
52
|
+
align-items: baseline;
|
|
53
|
+
flex-wrap: wrap;
|
|
54
|
+
gap: 0.25em;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.banner.info,
|
|
58
|
+
.banner-content.info {
|
|
59
|
+
--banner-container-color: var(--color-primary-container);
|
|
60
|
+
--banner-label-text-color: var(--color-on-primary-container);
|
|
61
|
+
--banner-description-text-color: var(--color-on-primary-container);
|
|
62
|
+
--banner-icon-color: var(--color-on-primary-container);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.banner.success,
|
|
66
|
+
.banner-content.success {
|
|
67
|
+
--banner-container-color: var(--color-success-container);
|
|
68
|
+
--banner-label-text-color: var(--color-on-success-container);
|
|
69
|
+
--banner-description-text-color: var(--color-on-success-container);
|
|
70
|
+
--banner-icon-color: var(--color-on-success-container);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.banner.warning,
|
|
74
|
+
.banner-content.warning {
|
|
75
|
+
--banner-container-color: var(--color-warning-container);
|
|
76
|
+
--banner-label-text-color: var(--color-on-warning-container);
|
|
77
|
+
--banner-description-text-color: var(--color-on-warning-container);
|
|
78
|
+
--banner-icon-color: var(--color-on-warning-container);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.banner.error,
|
|
82
|
+
.banner-content.error {
|
|
83
|
+
--banner-container-color: var(--color-error-container);
|
|
84
|
+
--banner-label-text-color: var(--color-on-error-container);
|
|
85
|
+
--banner-description-text-color: var(--color-on-error-container);
|
|
86
|
+
--banner-icon-color: var(--color-on-error-container);
|
|
87
|
+
}
|