@brightspace-ui/core 2.75.5 → 2.76.1

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.
@@ -0,0 +1,173 @@
1
+ # Collapsible Panel
2
+
3
+ A collapsible panel is a container that can be expanded and collapsed to show/hide additional content and form options. Content within the panel is flexible and customizable -- form controls, buttons, text, and more can be put in the expanded version of this panel for users to interact with or view.
4
+
5
+ <!-- docs: demo -->
6
+ ```html
7
+ <script type="module">
8
+ import '@brightspace-ui/core/components/collapsible-panel/collapsible-panel.js';
9
+ </script>
10
+
11
+ <d2l-collapsible-panel panel-title="Availability Dates and Conditions">
12
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor.
13
+ </d2l-collapsible-panel>
14
+
15
+ <d2l-collapsible-panel type="subtle" panel-title="Availability Dates and Conditions">
16
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor.
17
+ </d2l-collapsible-panel>
18
+
19
+ <d2l-collapsible-panel type="inline" panel-title="Availability Dates and Conditions">
20
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor.
21
+ </d2l-collapsible-panel>
22
+ ```
23
+
24
+ ## Best Practices
25
+
26
+ <!-- docs: start best practices -->
27
+ <!-- docs: start dos -->
28
+ * Use for optional settings or additional information that you want to initially hide
29
+ * Use when the user would benefit from progressively disclosed information
30
+ <!-- docs: end dos -->
31
+
32
+ <!-- docs: start donts -->
33
+ * Don't nest collapsible panels within each other
34
+ * Don't change the header contents when the panel is expanded/collapsed
35
+ * Don't have interactions or elements in the closed state that are different or disappear in the open state (exception: the summary)
36
+ * For example, don't have a button that's only available in the collapsed state of the panel
37
+ * Avoid using a collapsible panel for required options in a form
38
+ * Avoid long lists of collapsible panels; consider using a nested [list](https://daylight.d2l.dev/components/list/) in this case (exceptions may apply)
39
+ <!-- docs: end donts -->
40
+ <!-- docs: end best practices -->
41
+
42
+
43
+ ## Collapsible Panel [d2l-collapsible-panel]
44
+
45
+ The `d2l-collapsible-panel` element is a container that provides specific layout slots such as `header`, `summary`, `actions`, and a default slot for the expanded content.
46
+
47
+ <!-- docs: demo live name:d2l-collapsible-panel -->
48
+ ```html
49
+ <script type="module">
50
+ import '@brightspace-ui/core/components/collapsible-panel/collapsible-panel.js';
51
+ </script>
52
+
53
+ <d2l-collapsible-panel panel-title="Availability Dates and Conditions">
54
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor.
55
+ </d2l-collapsible-panel>
56
+ ```
57
+
58
+ <!-- docs: start hidden content -->
59
+ ### Slots
60
+
61
+ | Slot | Type | Description |
62
+ |--|--|--|
63
+ | `header` | optional | Supporting header content |
64
+ | `actions` | optional | Buttons and dropdown openers to be placed in top right corner of header |
65
+ | `summary` | optional | Summary of the expanded content. Only accepts `d2l-collapsible-panel-summary-item` |
66
+ | `default` | required | Content that is rendered when the panel is expanded |
67
+
68
+
69
+ ### Properties
70
+
71
+ | Property | Type | Description |
72
+ |--|--|--|
73
+ | `expanded` | Boolean | Whether or not the panel is expanded |
74
+ | `expand-collapse-label` | String | Optional label describing the contents of the header (used by screen readers) |
75
+ | `heading-style` | Number | The heading style to use |
76
+ | `heading-level` | Number | Semantic heading level (h1-h4) |
77
+ | `no-sticky` | Boolean | Disables sticky positioning for the header |
78
+ | `padding` | String | Optionally set horizontal padding of inline panels |
79
+ | `panel-title` | String | The title of the panel |
80
+ | `type` | String | The type of collapsible panel |
81
+ <!-- docs: end hidden content -->
82
+
83
+ ### Panel Types
84
+
85
+ <!-- docs: demo -->
86
+ ```html
87
+ <script type="module">
88
+ import '@brightspace-ui/core/components/collapsible-panel/collapsible-panel.js';
89
+ </script>
90
+
91
+ <d2l-collapsible-panel panel-title="Default panel">
92
+ This is the default collapsible panel style
93
+ </d2l-collapsible-panel>
94
+
95
+ <d2l-collapsible-panel type="subtle" panel-title="Subtle panel">
96
+ This is the "subtle" collapsible panel style
97
+ </d2l-collapsible-panel>
98
+
99
+ <d2l-collapsible-panel type="inline" panel-title="Inline panel">
100
+ This is the "inline" collapsible panel style
101
+ </d2l-collapsible-panel>
102
+ ```
103
+
104
+ ## Summary Items [d2l-collapsible-panel-summary-item]
105
+ The summary area takes information from the expanded panel and summarizes it for the collapsed version. This can help the user understand what information is inside the panel without having to click on it.
106
+
107
+ <!-- docs: demo -->
108
+ ```html
109
+ <script type="module">
110
+ import '@brightspace-ui/core/components/collapsible-panel/collapsible-panel.js';
111
+ import '@brightspace-ui/core/components/collapsible-panel/collapsible-panel-summary-item.js';
112
+ </script>
113
+
114
+ <d2l-collapsible-panel panel-title="Availability Dates and Conditions">
115
+ <div slot="summary">
116
+ <d2l-collapsible-panel-summary-item text="Availability starts 8/16/2022 and ends 8/12/2022"></d2l-collapsible-panel-summary-item>
117
+ <d2l-collapsible-panel-summary-item text="1 release condition"></d2l-collapsible-panel-summary-item>
118
+ <d2l-collapsible-panel-summary-item text="Hidden by special access"></d2l-collapsible-panel-summary-item>
119
+ </div>
120
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor.
121
+ </d2l-collapsible-panel>
122
+ ```
123
+
124
+ ## Optional slots
125
+
126
+ Collapsible panels have two optional slots, `actions` and `header` that can be used to add more information to the header area.
127
+
128
+
129
+ <!-- docs: demo -->
130
+ ```html
131
+ <script type="module">
132
+ import '@brightspace-ui/core/components/button/button-icon.js';
133
+ import '@brightspace-ui/core/components/collapsible-panel/collapsible-panel.js';
134
+ import '@brightspace-ui/core/components/collapsible-panel/collapsible-panel-summary-item.js';
135
+ import '@brightspace-ui/core/components/dropdown/dropdown-more.js';
136
+ import '@brightspace-ui/core/components/dropdown/dropdown-menu.js';
137
+ import '@brightspace-ui/core/components/menu/menu.js';
138
+ import '@brightspace-ui/core/components/menu/menu-item.js';
139
+ import '@brightspace-ui/core/components/status-indicator/status-indicator.js';
140
+ </script>
141
+
142
+ <d2l-collapsible-panel panel-title="Session: January 1, 2021: 10:00 AM" expand-collapse-label="Session on January 1">
143
+ <d2l-button-icon slot="actions" icon="tier1:fullscreen"></d2l-button-icon>
144
+ <d2l-button-icon slot="actions" icon="tier1:download"></d2l-button-icon><d2l-dropdown-more>
145
+ <d2l-dropdown-menu>
146
+ <d2l-menu>
147
+ <d2l-menu-item text="Duplicate"></d2l-menu-item>
148
+ <d2l-menu-item text="Delete"></d2l-menu-item>
149
+ </d2l-menu>
150
+ </d2l-dropdown-menu>
151
+ </d2l-dropdown-more>
152
+ <div slot="header" style="align-items: center; display: flex; gap: 0.6rem;">
153
+ <d2l-status-indicator state="none" text="Due Today"></d2l-status-indicator>
154
+ <p class="d2l-body-small">Posts: 1 thread, 1 reply</p>
155
+ <d2l-link small href="https://www.d2l.com" target="blank">Link</d2l-link>
156
+ </div>
157
+ <div slot="summary">
158
+ <d2l-collapsible-panel-summary-item text="Always available"></d2l-collapsible-panel-summary-item>
159
+ </div>
160
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor. Praesent lobortis libero in libero sagittis consectetur. Maecenas ut velit efficitur, consectetur augue vitae, finibus turpis. In id tempor quam. Integer sed facilisis mi. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut a volutpat lacus. Suspendisse potenti. Quisque egestas erat urna, et accumsan est accumsan sit amet. Sed luctus vestibulum lacus. Mauris nisi orci, rhoncus sed est sit amet, pretium facilisis felis.
161
+ </d2l-collapsible-panel>
162
+ ```
163
+
164
+ ## Accessibility
165
+
166
+ ### Panel label
167
+ By default, the panel is described by screen readers with the `panel-title` attribute. There may be situations where the screen reader should read additional information. In this case, a special label can be specified using the `expand-collapse-label` property.
168
+
169
+ ### Keyboard behaviour
170
+
171
+ On focus, a focus ring (blue border) goes around the clickable area of the component. When collapsed, this area is the entire panel; when expanded, it's only the header.
172
+
173
+ Any focusable actions placed in the `actions` slot will receive focus after the panel recevies focus. The open/close icon beside the `actions` slot looks like a button, but is an indicator of component state. It will not receive focus like a typical button.
@@ -0,0 +1,45 @@
1
+ import '../colors/colors.js';
2
+ import { css, html, LitElement } from 'lit';
3
+ import { bodySmallStyles } from '../typography/styles.js';
4
+
5
+ /**
6
+ * A component for a "summary item" child component that describes the content in a collapsible panel.
7
+ */
8
+ class CollapsiblePanelSummaryItem extends LitElement {
9
+
10
+ static get properties() {
11
+ return {
12
+ /**
13
+ * REQUIRED: Text that is displayed
14
+ * @type {string}
15
+ */
16
+ text: { type: String },
17
+ };
18
+ }
19
+
20
+ static get styles() {
21
+ return [bodySmallStyles, css`
22
+ :host {
23
+ color: var(--d2l-color-galena);
24
+ display: block;
25
+ }
26
+ :host([hidden]) {
27
+ display: none;
28
+ }
29
+ .d2l-body-small {
30
+ line-height: 1.2rem;
31
+ }
32
+ `];
33
+ }
34
+
35
+ constructor() {
36
+ super();
37
+ this.text = '';
38
+ }
39
+
40
+ render() {
41
+ return html`<p class="d2l-body-small">${this.text}</p>`;
42
+ }
43
+ }
44
+
45
+ customElements.define('d2l-collapsible-panel-summary-item', CollapsiblePanelSummaryItem);
@@ -0,0 +1,436 @@
1
+ import '../colors/colors.js';
2
+ import '../icons/icon-custom.js';
3
+ import '../expand-collapse/expand-collapse-content.js';
4
+ import { css, html, LitElement } from 'lit';
5
+ import { heading1Styles, heading2Styles, heading3Styles, heading4Styles } from '../typography/styles.js';
6
+ import { classMap } from 'lit/directives/class-map.js';
7
+ import { offscreenStyles } from '../offscreen/offscreen.js';
8
+ import { RtlMixin } from '../../mixins/rtl-mixin.js';
9
+
10
+ const normalizeHeadingNumber = (number) => {
11
+ number = parseInt(number);
12
+ if (number < 1) { return 1; }
13
+ if (number > 4) { return 4; }
14
+ return number;
15
+ };
16
+
17
+ const defaultHeading = 3;
18
+
19
+ /**
20
+ * A container with a title that can be expanded/collapsed to show/hide content.
21
+ * @slot header - Slot for supporting header content
22
+ * @slot summary - Slot for the summary of the expanded content. Only accepts `d2l-collapsible-panel-summary-item`
23
+ * @slot default - Slot for the expanded content
24
+ * @slot actions - Slot for buttons and dropdown openers to be placed in top right corner of header
25
+ * @fires d2l-collapsible-panel-expand - Dispatched when the panel is expanded
26
+ * @fires d2l-collapsible-panel-collapse - Dispatched when the panel is collapsed
27
+ */
28
+ class CollapsiblePanel extends RtlMixin(LitElement) {
29
+
30
+ static get properties() {
31
+ return {
32
+ /**
33
+ * REQUIRED: The title of the panel
34
+ * @type {string}
35
+ */
36
+ panelTitle: { attribute: 'panel-title', type: String, reflect: true },
37
+ /**
38
+ * The semantic heading level (h1-h4)
39
+ * @type {'1'|'2'|'3'|'4'}
40
+ * @default "3"
41
+ */
42
+ headingLevel: { attribute: 'heading-level', type: String, reflect: true },
43
+ /**
44
+ * The heading style to use
45
+ * @type {'1'|'2'|'3'|'4'}
46
+ * @default "3"
47
+ */
48
+ headingStyle: { attribute: 'heading-style', type: String, reflect: true },
49
+ /**
50
+ * Whether or not the panel is expanded
51
+ * @type {boolean}
52
+ */
53
+ expanded: { type: Boolean, reflect: true },
54
+ /**
55
+ * REQUIRED: Label describing the contents of the header.
56
+ * Used for screen readers.
57
+ * @type {string}
58
+ */
59
+ expandCollapseLabel: { attribute: 'expand-collapse-label', type: String, reflect: true },
60
+ /**
61
+ * Type of collapsible panel
62
+ * @type {'default'|'subtle'|'inline'}
63
+ * @default "default"
64
+ */
65
+ type: { type: String, reflect: true },
66
+ /**
67
+ * Horizontal padding of the panel
68
+ * @type {'default'|'large'}
69
+ * @default "default"
70
+ */
71
+ padding: { type: String, reflect: true },
72
+ /**
73
+ * Disables sticky positioning for the header
74
+ * @type {boolean}
75
+ */
76
+ noSticky: { attribute: 'no-sticky', type: Boolean },
77
+ _focused: { state: true },
78
+ _hasSummary: { state: true },
79
+ _scrolled: { state: true },
80
+ };
81
+ }
82
+
83
+ static get styles() {
84
+ return [heading1Styles, heading2Styles, heading3Styles, heading4Styles, offscreenStyles, css`
85
+ :host {
86
+ --d2l-collapsible-panel-focus-outline: solid 2px var(--d2l-color-celestine);
87
+ --d2l-collapsible-panel-spacing-inline: 0.9rem;
88
+ --d2l-collapsible-panel-header-spacing: 0.6rem;
89
+ --d2l-collapsible-panel-transition-time: 0.2s;
90
+ --d2l-collapsible-panel-arrow-time: 0.5s;
91
+ display: block;
92
+ }
93
+ :host([hidden]) {
94
+ display: none;
95
+ }
96
+ :host([padding="large"][type="inline"]) {
97
+ --d2l-collapsible-panel-spacing-inline: 2rem;
98
+ }
99
+ .d2l-collapsible-panel {
100
+ border: 1px solid var(--d2l-color-mica);
101
+ border-radius: 0.4rem;
102
+ }
103
+ :host(:not([expanded])) .d2l-collapsible-panel {
104
+ cursor: pointer;
105
+ }
106
+ :host([type=subtle]) .d2l-collapsible-panel {
107
+ background-color: white;
108
+ border: none;
109
+ box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.03);
110
+ }
111
+ :host([type=inline]) .d2l-collapsible-panel {
112
+ border-left: none;
113
+ border-radius: 0;
114
+ border-right: none;
115
+ }
116
+ :host([heading-style="1"]) {
117
+ --d2l-collapsible-panel-header-spacing: 1.2rem;
118
+ }
119
+ :host([heading-style="4"]) {
120
+ --d2l-collapsible-panel-header-spacing: 0.3rem;
121
+ }
122
+ .d2l-collapsible-panel-header {
123
+ border-radius: 0.4rem;
124
+ cursor: pointer;
125
+ padding: var(--d2l-collapsible-panel-header-spacing) 0;
126
+ }
127
+ .d2l-collapsible-panel.scrolled .d2l-collapsible-panel-header {
128
+ background-color: white;
129
+ box-shadow: 0 8px 12px -9px rgba(0, 0, 0, 0.3);
130
+ position: sticky;
131
+ top: 0;
132
+ }
133
+ .d2l-collapsible-panel.focused.scrolled .d2l-collapsible-panel-header {
134
+ top: 2px;
135
+ }
136
+ .d2l-collapsible-panel-title {
137
+ flex: 1;
138
+ margin: 0.3rem;
139
+ margin-inline-start: var(--d2l-collapsible-panel-spacing-inline);
140
+ user-select: none;
141
+ }
142
+ .d2l-collapsible-panel.focused {
143
+ outline: var(--d2l-collapsible-panel-focus-outline);
144
+ }
145
+ :host([expanded]) .d2l-collapsible-panel.focused .d2l-collapsible-panel-header {
146
+ outline: var(--d2l-collapsible-panel-focus-outline);
147
+ }
148
+ :host([expanded]) .d2l-collapsible-panel {
149
+ outline: none;
150
+ }
151
+ .d2l-collapsible-panel-header-primary {
152
+ align-items: center;
153
+ display: flex;
154
+ justify-content: space-between;
155
+ }
156
+ .d2l-collapsible-panel-header-secondary {
157
+ display: flex;
158
+ margin-inline-start: var(--d2l-collapsible-panel-spacing-inline);
159
+ }
160
+ .d2l-collapsible-panel-header-secondary ::slotted(*) {
161
+ cursor: default;
162
+ }
163
+ .d2l-collapsible-panel-header-actions {
164
+ display: flex;
165
+ gap: 0.3rem;
166
+ }
167
+ .d2l-collapsible-panel-header-actions::after {
168
+ border-inline-end: 1px solid var(--d2l-color-mica);
169
+ content: '';
170
+ display: flex;
171
+ margin: 0.3rem;
172
+ }
173
+ .d2l-collapsible-panel-opener {
174
+ margin-inline-end: var(--d2l-collapsible-panel-spacing-inline);
175
+ }
176
+ .d2l-collapsible-panel-opener > d2l-icon-custom {
177
+ height: 0.9rem;
178
+ margin: 0.6rem;
179
+ margin-inline-end: 0;
180
+ position: relative;
181
+ width: 0.9rem;
182
+ }
183
+ .d2l-collapsible-panel-opener > d2l-icon-custom svg {
184
+ position: absolute;
185
+ transform-origin: 0.4rem;
186
+ }
187
+ :host([expanded]) .d2l-collapsible-panel-opener > d2l-icon-custom svg {
188
+ fill: var(--d2l-color-tungsten);
189
+ transform: rotate(90deg);
190
+ }
191
+ @media (prefers-reduced-motion: no-preference) {
192
+ .d2l-collapsible-panel-divider {
193
+ transition: opacity var(--d2l-collapsible-panel-transition-time) ease-in-out;
194
+ }
195
+ .d2l-collapsible-panel-opener > d2l-icon-custom svg {
196
+ animation: d2l-collapsible-panel-opener-close var(--d2l-collapsible-panel-arrow-time) ease-in-out;
197
+ }
198
+ :host([expanded]) .d2l-collapsible-panel-opener > d2l-icon-custom svg {
199
+ animation: d2l-collapsible-panel-opener-open var(--d2l-collapsible-panel-arrow-time) ease-in-out;
200
+ }
201
+ /* stylelint-disable order/properties-alphabetical-order */
202
+ @keyframes d2l-collapsible-panel-opener-open {
203
+ 0% { transform: rotate(0deg); }
204
+ 25% { transform: rotate(105deg); animation-timing-function: ease-in-out; }
205
+ 50% { transform: rotate(82deg); animation-timing-function: ease-in-out; }
206
+ 75% { transform: rotate(93deg); animation-timing-function: ease-in-out; }
207
+ 100% { transform: rotate(90deg); animation-timing-function: ease-in-out; }
208
+ }
209
+ @keyframes d2l-collapsible-panel-opener-close {
210
+ 0% { transform: rotate(90deg); }
211
+ 25% { transform: rotate(-15deg); animation-timing-function: ease-in-out; }
212
+ 50% { transform: rotate(8deg); animation-timing-function: ease-in-out; }
213
+ 75% { transform: rotate(-3deg); animation-timing-function: ease-in-out; }
214
+ 100% { transform: rotate(0deg); animation-timing-function: ease-in-out; }
215
+ }
216
+ /* stylelint-enable */
217
+ }
218
+ .d2l-collapsible-panel-divider {
219
+ border-bottom: 1px solid var(--d2l-color-mica);
220
+ margin-inline: var(--d2l-collapsible-panel-spacing-inline);
221
+ opacity: 1;
222
+ }
223
+ :host([type=inline]) .d2l-collapsible-panel-divider {
224
+ opacity: 0;
225
+ }
226
+ :host(:not([expanded])) .d2l-collapsible-panel:not(.has-summary) .d2l-collapsible-panel-divider {
227
+ opacity: 0;
228
+ }
229
+ .d2l-collapsible-panel-summary,
230
+ .d2l-collapsible-panel-content {
231
+ padding: 0.9rem var(--d2l-collapsible-panel-spacing-inline);
232
+ }
233
+ :host([type=inline]) .d2l-collapsible-panel-summary,
234
+ :host([type=inline]) .d2l-collapsible-panel-content {
235
+ padding-top: 0;
236
+ }
237
+ :host([type="inline"]) .d2l-collapsible-panel-summary {
238
+ margin-top: -0.3rem;
239
+ }
240
+ .d2l-collapsible-panel:not(.has-summary) .d2l-collapsible-panel-summary {
241
+ display: none;
242
+ }
243
+ `];
244
+ }
245
+
246
+ constructor() {
247
+ super();
248
+ this.expanded = false;
249
+ this.headingLevel = defaultHeading;
250
+ this.headingStyle = defaultHeading;
251
+ this.padding = 'default';
252
+ this.type = 'default';
253
+ this.noSticky = false;
254
+ this._focused = false;
255
+ this._hasSummary = false;
256
+ this._scrolled = false;
257
+ }
258
+
259
+ disconnectedCallback() {
260
+ super.disconnectedCallback();
261
+ if (this._intersectionObserver) this._intersectionObserver.disconnect();
262
+ }
263
+
264
+ render() {
265
+ const classes = {
266
+ 'd2l-collapsible-panel': true,
267
+ 'focused': this._focused,
268
+ 'has-summary': this._hasSummary,
269
+ 'scrolled': this._scrolled,
270
+ };
271
+ const expandCollapseLabel = this.expandCollapseLabel || this.panelTitle;
272
+
273
+ return html`
274
+ <button
275
+ aria-expanded="${this.expanded}"
276
+ class="d2l-offscreen"
277
+ type="button"
278
+ @click="${this._toggleExpand}"
279
+ @focus="${this._onFocus}"
280
+ @blur="${this._onBlur}"
281
+ >${expandCollapseLabel}</button>
282
+ <div class="${classMap(classes)}" @click="${this._handlePanelClick}">
283
+ <div class="d2l-collapsible-panel-top-sentinel"></div>
284
+ ${this._renderHeader()}
285
+ <d2l-expand-collapse-content
286
+ ?expanded="${this.expanded}"
287
+ @d2l-expand-collapse-content-collapse="${this._handleExpandCollapse}"
288
+ @d2l-expand-collapse-content-expand="${this._handleExpandCollapse}"
289
+ >
290
+ <div class="d2l-collapsible-panel-content">
291
+ <slot></slot>
292
+ </div>
293
+ </d2l-expand-collapse-content>
294
+ <d2l-expand-collapse-content ?expanded="${!this.expanded}">
295
+ <div class="d2l-collapsible-panel-summary">
296
+ <slot name="summary" @slotchange="${this._handleSummarySlotChange}"></slot>
297
+ </div>
298
+ </d2l-expand-collapse-content>
299
+ </div>
300
+ `;
301
+ }
302
+
303
+ updated(changedProperties) {
304
+ super.updated(changedProperties);
305
+
306
+ if (changedProperties.has('expanded')) {
307
+ if (!this.expanded) {
308
+ this._scrolled = false;
309
+ }
310
+ }
311
+
312
+ if (changedProperties.has('noSticky')) {
313
+ this._stickyObserverUpdate();
314
+ }
315
+ }
316
+
317
+ _handleActionsClick(e) {
318
+ const actions = this.shadowRoot.querySelector('.d2l-collapsible-panel-header-actions');
319
+ if (e.target !== actions) {
320
+ e.stopPropagation();
321
+ }
322
+ }
323
+
324
+ _handleExpandCollapse(e) {
325
+ const eventPromise = this.expanded ? e.detail.expandComplete : e.detail.collapseComplete;
326
+ const event = `d2l-collapsible-panel-${this.expanded ? 'expand' : 'collapse' }`;
327
+
328
+ this.dispatchEvent(new CustomEvent(
329
+ event, { bubbles: false, composed: false, detail: { complete: eventPromise } }
330
+ ));
331
+ }
332
+
333
+ _handleHeaderClick(e) {
334
+ if (this.expanded) {
335
+ this._toggleExpand();
336
+ e.stopPropagation();
337
+ }
338
+ }
339
+
340
+ _handleHeaderSecondaryClick(e) {
341
+ const header = this.shadowRoot.querySelector('.d2l-collapsible-panel-header-secondary');
342
+ if (e.target !== header) {
343
+ e.stopPropagation();
344
+ }
345
+ }
346
+
347
+ _handlePanelClick(e) {
348
+ if (!this.expanded) {
349
+ this._toggleExpand();
350
+ e.stopPropagation();
351
+ }
352
+ }
353
+
354
+ _handleSummarySlotChange(e) {
355
+ const content = e.target.assignedNodes({ flatten: true });
356
+ this._hasSummary = content?.length > 0;
357
+ }
358
+
359
+ _onBlur() {
360
+ this._focused = false;
361
+ }
362
+
363
+ _onFocus() {
364
+ this._focused = true;
365
+ }
366
+
367
+ _renderHeader() {
368
+ return html`
369
+ <div class="d2l-collapsible-panel-header" @click="${this._handleHeaderClick}">
370
+ <div class="d2l-collapsible-panel-header-primary">
371
+ ${this._renderPanelTitle()}
372
+ <div class="d2l-collapsible-panel-header-actions" @click="${this._handleActionsClick}">
373
+ <slot name="actions"></slot>
374
+ </div>
375
+ <div class="d2l-collapsible-panel-opener">
376
+ <d2l-icon-custom size="tier1">
377
+ <svg xmlns="http://www.w3.org/2000/svg" width="10" height="18" fill="none" viewBox="0 0 10 18">
378
+ <path stroke="var(--d2l-color-tungsten)" stroke-linejoin="round" stroke-width="2" d="m9 9-8 8V1l8 8Z"/>
379
+ </svg>
380
+ </d2l-icon-custom>
381
+ </div>
382
+ </div>
383
+ <div class="d2l-collapsible-panel-header-secondary" @click="${this._handleHeaderSecondaryClick}">
384
+ <slot name="header"></slot>
385
+ </div>
386
+ </div>
387
+ <div class="d2l-collapsible-panel-divider"></div>
388
+ `;
389
+ }
390
+
391
+ _renderPanelTitle() {
392
+ let headingStyle = (this.headingStyle === defaultHeading && this.headingLevel !== this.headingStyle) ? this.headingLevel : this.headingStyle;
393
+ headingStyle = normalizeHeadingNumber(headingStyle);
394
+
395
+ const titleClasses = {
396
+ 'd2l-collapsible-panel-title': true,
397
+ [`d2l-heading-${headingStyle}`]: true,
398
+ };
399
+
400
+ const headingLevel = normalizeHeadingNumber(this.headingLevel);
401
+ switch (headingLevel) {
402
+ case 1: return html`<h1 class="${classMap(titleClasses)}">${this.panelTitle}</h1>`;
403
+ case 2: return html`<h2 class="${classMap(titleClasses)}">${this.panelTitle}</h2>`;
404
+ case 3: return html`<h3 class="${classMap(titleClasses)}">${this.panelTitle}</h3>`;
405
+ case 4: return html`<h4 class="${classMap(titleClasses)}">${this.panelTitle}</h4>`;
406
+ }
407
+ }
408
+
409
+ _stickyObserverDisconnect() {
410
+ if (this._intersectionObserver) {
411
+ this._intersectionObserver.disconnect();
412
+ this._intersectionObserver = undefined;
413
+ this._scrolled = false;
414
+ }
415
+ }
416
+
417
+ _stickyObserverUpdate() {
418
+ this._stickyObserverDisconnect();
419
+
420
+ if (!this.noSticky && typeof(IntersectionObserver) === 'function') {
421
+ this._intersectionObserver = new IntersectionObserver(entries => {
422
+ if (!this.expanded) return;
423
+
424
+ const entry = entries[0];
425
+ this._scrolled = !entry.isIntersecting;
426
+ });
427
+ this._intersectionObserver.observe(this.shadowRoot.querySelector('.d2l-collapsible-panel-top-sentinel'));
428
+ }
429
+ }
430
+
431
+ _toggleExpand() {
432
+ this.expanded = !this.expanded;
433
+ }
434
+ }
435
+
436
+ customElements.define('d2l-collapsible-panel', CollapsiblePanel);
@@ -0,0 +1,191 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
5
+ <meta charset="UTF-8">
6
+ <link rel="stylesheet" href="../../demo/styles.css" type="text/css">
7
+ <script type="module">
8
+ import '../collapsible-panel.js';
9
+ import '../collapsible-panel-summary-item.js';
10
+ import '../../button/button-icon.js';
11
+ import '../../button/button-subtle.js';
12
+ import '../../dropdown/dropdown-more.js';
13
+ import '../../dropdown/dropdown-menu.js';
14
+ import '../../inputs/input-search.js';
15
+ import '../../filter/filter.js';
16
+ import '../../filter/filter-dimension-set.js';
17
+ import '../../link/link.js';
18
+ import '../../menu/menu.js';
19
+ import '../../menu/menu-item.js';
20
+ import '../../status-indicator/status-indicator.js';
21
+ import '../../demo/demo-page.js';
22
+ </script>
23
+ <style>
24
+ .background {
25
+ background-color: var(--d2l-color-gypsum);
26
+ margin: -18px;
27
+ padding: 18px;
28
+ }
29
+
30
+ .spacer d2l-collapsible-panel {
31
+ margin-bottom: 1rem;
32
+ }
33
+ </style>
34
+ </head>
35
+ <body unresolved>
36
+
37
+ <d2l-demo-page page-title="d2l-collapsible-panel">
38
+ <h2>Simple</h2>
39
+ <d2l-demo-snippet>
40
+ <div class="spacer">
41
+ <d2l-collapsible-panel panel-title="Availability Dates and Conditions">
42
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor.
43
+ </d2l-collapsible-panel>
44
+
45
+ <d2l-collapsible-panel panel-title="Availability Dates and Conditions">
46
+ <div slot="summary">
47
+ <d2l-collapsible-panel-summary-item text="Availability starts 8/16/2022 and ends 8/12/2022"></d2l-collapsible-panel-summary-item>
48
+ </div>
49
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor.
50
+ </d2l-collapsible-panel>
51
+ </div>
52
+ </d2l-demo-snippet>
53
+
54
+ <h2>Subtle</h2>
55
+ <d2l-demo-snippet>
56
+ <div class="background spacer">
57
+ <d2l-collapsible-panel panel-title="Availability Dates and Conditions" type="subtle">
58
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor. Praesent lobortis libero in libero sagittis consectetur. Maecenas ut velit efficitur, consectetur augue vitae, finibus turpis. In id tempor quam. Integer sed facilisis mi. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut a volutpat lacus. Suspendisse potenti. Quisque egestas erat urna, et accumsan est accumsan sit amet. Sed luctus vestibulum lacus. Mauris nisi orci, rhoncus sed est sit amet, pretium facilisis felis.
59
+ </d2l-collapsible-panel>
60
+ <d2l-collapsible-panel panel-title="Availability Dates and Conditions" type="subtle">
61
+ <div slot="summary">
62
+ <d2l-collapsible-panel-summary-item text="Availability starts 8/16/2022 and ends 8/12/2022"></d2l-collapsible-panel-summary-item>
63
+ </div>
64
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor. Praesent lobortis libero in libero sagittis consectetur. Maecenas ut velit efficitur, consectetur augue vitae, finibus turpis. In id tempor quam. Integer sed facilisis mi. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut a volutpat lacus. Suspendisse potenti. Quisque egestas erat urna, et accumsan est accumsan sit amet. Sed luctus vestibulum lacus. Mauris nisi orci, rhoncus sed est sit amet, pretium facilisis felis.
65
+ </d2l-collapsible-panel>
66
+ </div>
67
+ </d2l-demo-snippet>
68
+
69
+ <h2>Inline</h2>
70
+ <d2l-demo-snippet>
71
+ <d2l-collapsible-panel panel-title="Availability Dates and Conditions" type="inline">
72
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor. Praesent lobortis libero in libero sagittis consectetur. Maecenas ut velit efficitur, consectetur augue vitae, finibus turpis. In id tempor quam.
73
+ </d2l-collapsible-panel>
74
+ <d2l-collapsible-panel panel-title="Availability Dates and Conditions" type="inline">
75
+ <div slot="summary">
76
+ <d2l-collapsible-panel-summary-item text="Availability starts 8/16/2022 and ends 8/12/2022"></d2l-collapsible-panel-summary-item>
77
+ </div>
78
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor. Praesent lobortis libero in libero sagittis consectetur. Maecenas ut velit efficitur, consectetur augue vitae, finibus turpis. In id tempor quam.
79
+ </d2l-collapsible-panel>
80
+ </d2l-demo-snippet>
81
+
82
+ <h2>Inline with large padding</h2>
83
+ <d2l-demo-snippet>
84
+ <d2l-collapsible-panel panel-title="Availability Dates and Conditions" type="inline" padding="large">
85
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor. Praesent lobortis libero in libero sagittis consectetur. Maecenas ut velit efficitur, consectetur augue vitae, finibus turpis. In id tempor quam.
86
+ </d2l-collapsible-panel>
87
+ <d2l-collapsible-panel panel-title="Availability Dates and Conditions" type="inline" padding="large">
88
+ <div slot="summary">
89
+ <d2l-collapsible-panel-summary-item text="Availability starts 8/16/2022 and ends 8/12/2022"></d2l-collapsible-panel-summary-item>
90
+ </div>
91
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor. Praesent lobortis libero in libero sagittis consectetur. Maecenas ut velit efficitur, consectetur augue vitae, finibus turpis. In id tempor quam.
92
+ </d2l-collapsible-panel>
93
+ </d2l-demo-snippet>
94
+
95
+ <h2>Multi-line summary and interactive content</h2>
96
+ <d2l-demo-snippet>
97
+ <d2l-collapsible-panel panel-title="Availability Dates and Conditions">
98
+ <div slot="summary">
99
+ <d2l-collapsible-panel-summary-item text="Availability starts 8/16/2022 and ends 8/12/2022"></d2l-collapsible-panel-summary-item>
100
+ <d2l-collapsible-panel-summary-item text="1 release condition"></d2l-collapsible-panel-summary-item>
101
+ <d2l-collapsible-panel-summary-item text="Hidden by special access"></d2l-collapsible-panel-summary-item>
102
+ </div>
103
+ <div style="display: flex; gap: 0.3rem; margin-bottom: 1.2rem;">
104
+ <d2l-input-search label="search" placeholder="Search Students"></d2l-input-search>
105
+ <d2l-button-subtle text="Evaluate All"></d2l-button-subtle>
106
+ <d2l-filter>
107
+ <d2l-filter-dimension-set key="Filter" text="Filter">
108
+ </d2l-filter-dimension-set>
109
+ </d2l-filter>
110
+ </div>
111
+ <div>
112
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor.
113
+ </div>
114
+ </d2l-collapsible-panel>
115
+ </d2l-demo-snippet>
116
+
117
+
118
+ <h2>With custom action and header content</h2>
119
+ <d2l-demo-snippet>
120
+ <d2l-collapsible-panel panel-title="Session: January 1, 2021: 10:00 AM" expand-collapse-label="Session on January 1">
121
+ <d2l-button-icon slot="actions" icon="tier1:fullscreen"></d2l-button-icon><d2l-button-icon slot="actions" icon="tier1:download"></d2l-button-icon><d2l-dropdown-more>
122
+ <d2l-dropdown-menu>
123
+ <d2l-menu>
124
+ <d2l-menu-item text="Duplicate"></d2l-menu-item>
125
+ <d2l-menu-item text="Delete"></d2l-menu-item>
126
+ </d2l-menu>
127
+ </d2l-dropdown-menu>
128
+ </d2l-dropdown-more>
129
+ <div slot="header" style="align-items: center; display: flex; gap: 0.6rem;">
130
+ <d2l-status-indicator state="none" text="Due Today"></d2l-status-indicator>
131
+ <p class="d2l-body-small">Posts: 1 thread, 1 reply</p>
132
+ <d2l-link small href="https://www.d2l.com" target="blank">Link</d2l-link>
133
+ </div>
134
+ <div slot="summary">
135
+ <d2l-collapsible-panel-summary-item text="Always available"></d2l-collapsible-panel-summary-item>
136
+ </div>
137
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor. Praesent lobortis libero in libero sagittis consectetur. Maecenas ut velit efficitur, consectetur augue vitae, finibus turpis. In id tempor quam. Integer sed facilisis mi. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut a volutpat lacus. Suspendisse potenti. Quisque egestas erat urna, et accumsan est accumsan sit amet. Sed luctus vestibulum lacus. Mauris nisi orci, rhoncus sed est sit amet, pretium facilisis felis.
138
+ </d2l-collapsible-panel>
139
+ </d2l-demo-snippet>
140
+
141
+ <h2>Headings</h2>
142
+ <d2l-demo-snippet class="spacer">
143
+ <d2l-collapsible-panel heading-level="1" panel-title="Heading Level 1">
144
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor.
145
+ </d2l-collapsible-panel>
146
+
147
+ <d2l-collapsible-panel heading-level="2" panel-title="Heading Level 2">
148
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor.
149
+ </d2l-collapsible-panel>
150
+
151
+ <d2l-collapsible-panel heading-level="3" panel-title="Heading Level 3">
152
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor.
153
+ </d2l-collapsible-panel>
154
+
155
+ <d2l-collapsible-panel heading-level="4" panel-title="Heading Level 4">
156
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor.
157
+ </d2l-collapsible-panel>
158
+
159
+ <d2l-collapsible-panel heading-style="2" panel-title="Heading Style 2">
160
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor.
161
+ </d2l-collapsible-panel>
162
+
163
+ <d2l-collapsible-panel heading-style="4" heading-level="2" panel-title="Heading Style 4">
164
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas odio ligula, aliquam efficitur sollicitudin non, dignissim quis nisl. Nullam rutrum, lectus sed finibus consectetur, dolor leo blandit lorem, vitae consectetur arcu enim ornare tortor.
165
+ </d2l-collapsible-panel>
166
+ </d2l-demo-snippet>
167
+
168
+ <h2>Loooooong</h2>
169
+ <d2l-demo-snippet>
170
+ <d2l-collapsible-panel panel-title="Availability Dates and Conditions">
171
+ <div slot="summary">
172
+ <d2l-collapsible-panel-summary-item text="Availability starts 8/16/2022 and ends 8/12/2022"></d2l-collapsible-panel-summary-item>
173
+ <d2l-collapsible-panel-summary-item text="1 release condition"></d2l-collapsible-panel-summary-item>
174
+ <d2l-collapsible-panel-summary-item text="Hidden by special access"></d2l-collapsible-panel-summary-item>
175
+ </div>
176
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas a feugiat mi, in consectetur justo. Suspendisse finibus placerat purus, quis volutpat libero. Interdum et malesuada fames ac ante ipsum primis in faucibus. Donec tempor bibendum tempor. Suspendisse potenti. Quisque auctor purus id magna laoreet finibus. Maecenas eleifend est id velit vulputate finibus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vestibulum semper lorem nibh, gravida maximus libero hendrerit eu. Sed congue turpis ac iaculis laoreet. In commodo orci sit amet mollis facilisis. Pellentesque eu viverra metus. Nunc convallis laoreet augue, vitae sollicitudin nisl facilisis id. Aliquam sollicitudin fermentum dui, non convallis nulla facilisis quis.</p>
177
+
178
+ <p>Fusce lacus magna, efficitur in bibendum sit amet, egestas sit amet libero. Aenean nec felis ut justo maximus scelerisque in eget eros. Nam tincidunt nisi ipsum, vitae pretium augue vehicula a. Donec eget diam et ex posuere dictum eget id dui. Sed elementum felis in condimentum mattis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Maecenas volutpat dui semper mi semper, id varius purus sagittis. Praesent fringilla vel magna nec porttitor. Nulla nec gravida magna. Donec vitae dui consequat, ornare velit at, maximus turpis. Morbi porttitor massa eu tempus pretium. Nunc at justo eu erat dictum volutpat et ac lacus. Etiam congue ut massa vel tempor. Curabitur pellentesque nec massa a elementum. Nulla non dictum velit.</p>
179
+
180
+ <p>Duis risus mauris, egestas vel metus venenatis, vulputate placerat purus. Maecenas a congue risus. Cras auctor, massa id tincidunt tempor, nisi sem eleifend arcu, a gravida magna mauris ac ligula. Suspendisse quis purus commodo, faucibus orci ultricies, semper tortor. Proin at neque enim. Sed dapibus augue sit amet ligula tempor, interdum ornare nulla imperdiet. Nulla dolor ante, bibendum a velit a, molestie tincidunt nibh. Ut a viverra turpis. Vivamus vel dolor pulvinar, molestie libero ac, sollicitudin neque. Mauris dictum sem non dui pellentesque euismod. Integer mi velit, finibus ut libero eu, posuere commodo mi. Etiam sit amet leo metus. Ut ornare magna in tortor aliquet, quis condimentum ex lacinia. Sed ultricies sollicitudin est, et tempor ante rutrum vitae.</p>
181
+
182
+ <p>Quisque porttitor sollicitudin ligula, ut egestas tortor fringilla sed. Morbi porta libero velit, et venenatis massa facilisis nec. Nulla facilisi. In semper, ex ut egestas finibus, felis sem cursus orci, vel molestie sem leo vitae est. Cras vehicula massa et sapien pulvinar facilisis. Nam feugiat congue libero ut tristique. Ut id luctus arcu. Proin id augue eu est porttitor pretium. Ut bibendum semper rhoncus. Nullam a ligula faucibus, aliquet lectus sodales, dictum ipsum. Proin eget dapibus velit, sit amet egestas lorem. Vivamus suscipit sem turpis, nec sodales nibh ultrices vitae. Nulla augue sem, blandit sit amet fringilla at, tincidunt quis lacus.</p>
183
+
184
+ <p>Vestibulum enim leo, lobortis nec faucibus at, dictum rhoncus odio. Suspendisse dapibus, quam sed condimentum fermentum, est tellus malesuada justo, ut gravida libero dolor eu felis. Integer turpis dui, rhoncus sit amet dignissim eget, laoreet viverra magna. Nam varius arcu orci, sed consequat eros dictum nec. Nunc finibus quis diam id tincidunt. Quisque sed nunc ultrices, feugiat purus ac, iaculis leo. Morbi elementum, tellus sit amet eleifend tempor, magna massa eleifend turpis, id aliquam est ante vitae arcu. Vivamus non dapibus magna. Sed maximus fringilla sem, ac lacinia mi condimentum ac. Duis id eros nibh. Donec eget lectus et mi vulputate sollicitudin consequat quis lacus. Aliquam dui nibh, congue eu iaculis sed, fermentum a felis. Curabitur id magna sed urna lobortis hendrerit. Sed placerat nisl sit amet erat vulputate suscipit. Vestibulum sed efficitur odio. Sed dapibus nibh ac neque convallis tempus.</p>
185
+ </d2l-collapsible-panel>
186
+ </d2l-demo-snippet>
187
+
188
+ </d2l-demo-page>
189
+
190
+ </body>
191
+ </html>
@@ -164,8 +164,6 @@ class HtmlBlock extends RtlMixin(LitElement) {
164
164
  :host {
165
165
  display: block;
166
166
  overflow-wrap: break-word;
167
- overflow-x: auto;
168
- overflow-y: hidden;
169
167
  text-align: left;
170
168
  }
171
169
  :host([inline]),
@@ -187,7 +187,7 @@ export const ListItemMixin = superclass => class extends LocalizeCoreElement(Lis
187
187
  }
188
188
 
189
189
  [slot="content"] ::slotted([slot="illustration"]),
190
- [slot="content"] .d2l-list-item-illustration * {
190
+ [slot="content"] .d2l-list-item-illustration > * {
191
191
  border-radius: 6px;
192
192
  flex-grow: 0;
193
193
  flex-shrink: 0;
@@ -197,7 +197,7 @@ export const ListItemMixin = superclass => class extends LocalizeCoreElement(Lis
197
197
  overflow: hidden;
198
198
  }
199
199
  :host([dir="rtl"]) [slot="content"] ::slotted([slot="illustration"]),
200
- :host([dir="rtl"]) [slot="content"] .d2l-list-item-illustration * {
200
+ :host([dir="rtl"]) [slot="content"] .d2l-list-item-illustration > * {
201
201
  margin-left: 0.9rem;
202
202
  margin-right: 0;
203
203
  }
@@ -212,7 +212,7 @@ export const ListItemMixin = superclass => class extends LocalizeCoreElement(Lis
212
212
  }
213
213
 
214
214
  ::slotted([slot="actions"]),
215
- .d2l-list-item-actions * {
215
+ .d2l-list-item-actions > * {
216
216
  display: grid;
217
217
  gap: 0.3rem;
218
218
  grid-auto-columns: 1fr;
@@ -220,45 +220,45 @@ export const ListItemMixin = superclass => class extends LocalizeCoreElement(Lis
220
220
  }
221
221
 
222
222
  .d2l-list-item-content-extend-separators ::slotted([slot="actions"]),
223
- .d2l-list-item-content-extend-separators .d2l-list-item-actions * {
223
+ .d2l-list-item-content-extend-separators .d2l-list-item-actions > * {
224
224
  margin-right: 0.9rem;
225
225
  }
226
226
  :host([dir="rtl"]) .d2l-list-item-content-extend-separators ::slotted([slot="actions"]),
227
- :host([dir="rtl"]) .d2l-list-item-content-extend-separators .d2l-list-item-actions * {
227
+ :host([dir="rtl"]) .d2l-list-item-content-extend-separators .d2l-list-item-actions > * {
228
228
  margin-left: 0.9rem;
229
229
  margin-right: 0;
230
230
  }
231
231
 
232
232
  [data-breakpoint="1"] ::slotted([slot="illustration"]),
233
- [data-breakpoint="1"] .d2l-list-item-illustration * {
233
+ [data-breakpoint="1"] .d2l-list-item-illustration > * {
234
234
  margin-right: 1rem;
235
235
  max-height: 3.55rem;
236
236
  max-width: 6rem;
237
237
  }
238
238
  :host([dir="rtl"]) [data-breakpoint="1"] ::slotted([slot="illustration"]),
239
- :host([dir="rtl"]) [data-breakpoint="1"] .d2l-list-item-illustration * {
239
+ :host([dir="rtl"]) [data-breakpoint="1"] .d2l-list-item-illustration > * {
240
240
  margin-left: 1rem;
241
241
  margin-right: 0;
242
242
  }
243
243
  [data-breakpoint="2"] ::slotted([slot="illustration"]),
244
- [data-breakpoint="2"] .d2l-list-item-illustration * {
244
+ [data-breakpoint="2"] .d2l-list-item-illustration > * {
245
245
  margin-right: 1rem;
246
246
  max-height: 5.1rem;
247
247
  max-width: 9rem;
248
248
  }
249
249
  :host([dir="rtl"]) [data-breakpoint="2"] ::slotted([slot="illustration"]),
250
- :host([dir="rtl"]) [data-breakpoint="2"] .d2l-list-item-illustration * {
250
+ :host([dir="rtl"]) [data-breakpoint="2"] .d2l-list-item-illustration > * {
251
251
  margin-left: 1rem;
252
252
  margin-right: 0;
253
253
  }
254
254
  [data-breakpoint="3"] ::slotted([slot="illustration"]),
255
- [data-breakpoint="3"] .d2l-list-item-illustration * {
255
+ [data-breakpoint="3"] .d2l-list-item-illustration > * {
256
256
  margin-right: 1rem;
257
257
  max-height: 6rem;
258
258
  max-width: 10.8rem;
259
259
  }
260
260
  :host([dir="rtl"]) [data-breakpoint="3"] ::slotted([slot="illustration"]),
261
- :host([dir="rtl"]) [data-breakpoint="3"] .d2l-list-item-illustration * {
261
+ :host([dir="rtl"]) [data-breakpoint="3"] .d2l-list-item-illustration > * {
262
262
  margin-left: 1rem;
263
263
  margin-right: 0;
264
264
  }
@@ -1044,6 +1044,165 @@
1044
1044
  }
1045
1045
  ]
1046
1046
  },
1047
+ {
1048
+ "name": "d2l-collapsible-panel-summary-item",
1049
+ "path": "./components/collapsible-panel/collapsible-panel-summary-item.js",
1050
+ "description": "A component for a \"summary item\" child component that describes the content in a collapsible panel.",
1051
+ "attributes": [
1052
+ {
1053
+ "name": "text",
1054
+ "description": "REQUIRED: Text that is displayed",
1055
+ "type": "string",
1056
+ "default": "\"\""
1057
+ }
1058
+ ],
1059
+ "properties": [
1060
+ {
1061
+ "name": "text",
1062
+ "attribute": "text",
1063
+ "description": "REQUIRED: Text that is displayed",
1064
+ "type": "string",
1065
+ "default": "\"\""
1066
+ }
1067
+ ]
1068
+ },
1069
+ {
1070
+ "name": "d2l-collapsible-panel",
1071
+ "path": "./components/collapsible-panel/collapsible-panel.js",
1072
+ "description": "A container with a title that can be expanded/collapsed to show/hide content.",
1073
+ "attributes": [
1074
+ {
1075
+ "name": "panel-title",
1076
+ "description": "REQUIRED: The title of the panel",
1077
+ "type": "string"
1078
+ },
1079
+ {
1080
+ "name": "expand-collapse-label",
1081
+ "description": "REQUIRED: Label describing the contents of the header.\nUsed for screen readers.",
1082
+ "type": "string"
1083
+ },
1084
+ {
1085
+ "name": "expanded",
1086
+ "description": "Whether or not the panel is expanded",
1087
+ "type": "boolean",
1088
+ "default": "false"
1089
+ },
1090
+ {
1091
+ "name": "heading-level",
1092
+ "description": "The semantic heading level (h1-h4)",
1093
+ "type": "'1'|'2'|'3'|'4'",
1094
+ "default": "\"\\\"3\\\"\""
1095
+ },
1096
+ {
1097
+ "name": "heading-style",
1098
+ "description": "The heading style to use",
1099
+ "type": "'1'|'2'|'3'|'4'",
1100
+ "default": "\"\\\"3\\\"\""
1101
+ },
1102
+ {
1103
+ "name": "padding",
1104
+ "description": "Horizontal padding of the panel",
1105
+ "type": "'default'|'large'",
1106
+ "default": "\"\\\"default\\\"\""
1107
+ },
1108
+ {
1109
+ "name": "type",
1110
+ "description": "Type of collapsible panel",
1111
+ "type": "'default'|'subtle'|'inline'",
1112
+ "default": "\"\\\"default\\\"\""
1113
+ },
1114
+ {
1115
+ "name": "no-sticky",
1116
+ "description": "Disables sticky positioning for the header",
1117
+ "type": "boolean",
1118
+ "default": "false"
1119
+ }
1120
+ ],
1121
+ "properties": [
1122
+ {
1123
+ "name": "panelTitle",
1124
+ "attribute": "panel-title",
1125
+ "description": "REQUIRED: The title of the panel",
1126
+ "type": "string"
1127
+ },
1128
+ {
1129
+ "name": "expandCollapseLabel",
1130
+ "attribute": "expand-collapse-label",
1131
+ "description": "REQUIRED: Label describing the contents of the header.\nUsed for screen readers.",
1132
+ "type": "string"
1133
+ },
1134
+ {
1135
+ "name": "expanded",
1136
+ "attribute": "expanded",
1137
+ "description": "Whether or not the panel is expanded",
1138
+ "type": "boolean",
1139
+ "default": "false"
1140
+ },
1141
+ {
1142
+ "name": "headingLevel",
1143
+ "attribute": "heading-level",
1144
+ "description": "The semantic heading level (h1-h4)",
1145
+ "type": "'1'|'2'|'3'|'4'",
1146
+ "default": "\"\\\"3\\\"\""
1147
+ },
1148
+ {
1149
+ "name": "headingStyle",
1150
+ "attribute": "heading-style",
1151
+ "description": "The heading style to use",
1152
+ "type": "'1'|'2'|'3'|'4'",
1153
+ "default": "\"\\\"3\\\"\""
1154
+ },
1155
+ {
1156
+ "name": "padding",
1157
+ "attribute": "padding",
1158
+ "description": "Horizontal padding of the panel",
1159
+ "type": "'default'|'large'",
1160
+ "default": "\"\\\"default\\\"\""
1161
+ },
1162
+ {
1163
+ "name": "type",
1164
+ "attribute": "type",
1165
+ "description": "Type of collapsible panel",
1166
+ "type": "'default'|'subtle'|'inline'",
1167
+ "default": "\"\\\"default\\\"\""
1168
+ },
1169
+ {
1170
+ "name": "noSticky",
1171
+ "attribute": "no-sticky",
1172
+ "description": "Disables sticky positioning for the header",
1173
+ "type": "boolean",
1174
+ "default": "false"
1175
+ }
1176
+ ],
1177
+ "events": [
1178
+ {
1179
+ "name": "d2l-collapsible-panel-expand",
1180
+ "description": "Dispatched when the panel is expanded"
1181
+ },
1182
+ {
1183
+ "name": "d2l-collapsible-panel-collapse",
1184
+ "description": "Dispatched when the panel is collapsed"
1185
+ }
1186
+ ],
1187
+ "slots": [
1188
+ {
1189
+ "name": "header",
1190
+ "description": "Slot for supporting header content"
1191
+ },
1192
+ {
1193
+ "name": "summary",
1194
+ "description": "Slot for the summary of the expanded content. Only accepts `d2l-collapsible-panel-summary-item`"
1195
+ },
1196
+ {
1197
+ "name": "default",
1198
+ "description": "Slot for the expanded content"
1199
+ },
1200
+ {
1201
+ "name": "actions",
1202
+ "description": "Slot for buttons and dropdown openers to be placed in top right corner of header"
1203
+ }
1204
+ ]
1205
+ },
1047
1206
  {
1048
1207
  "name": "d2l-color-swatch",
1049
1208
  "path": "./components/colors/demo/color-swatch.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspace-ui/core",
3
- "version": "2.75.5",
3
+ "version": "2.76.1",
4
4
  "description": "A collection of accessible, free, open-source web components for building Brightspace applications",
5
5
  "type": "module",
6
6
  "repository": "https://github.com/BrightspaceUI/core.git",