@carbon/ibm-products-web-components 0.11.0-rc.0 → 0.11.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.
Files changed (73) hide show
  1. package/es/components/about-modal/about-modal.d.ts +87 -61
  2. package/es/components/side-panel/side-panel.d.ts +87 -61
  3. package/es/components/tearsheet/tearsheet.d.ts +87 -61
  4. package/es/components/user-avatar/user-avatar.d.ts +87 -61
  5. package/es/package.json.js +1 -1
  6. package/es-custom/components/about-modal/about-modal.d.ts +418 -0
  7. package/es-custom/components/about-modal/about-modal.js +143 -0
  8. package/es-custom/components/about-modal/about-modal.js.map +1 -0
  9. package/es-custom/components/about-modal/about-modal.scss.js +13 -0
  10. package/es-custom/components/about-modal/about-modal.scss.js.map +1 -0
  11. package/es-custom/components/about-modal/about-modal.test.d.ts +7 -0
  12. package/es-custom/components/about-modal/about-modal.test.js +87 -0
  13. package/es-custom/components/about-modal/about-modal.test.js.map +1 -0
  14. package/es-custom/components/about-modal/defs.d.ts +8 -0
  15. package/es-custom/components/about-modal/defs.js +8 -0
  16. package/es-custom/components/about-modal/defs.js.map +1 -0
  17. package/es-custom/components/about-modal/index.d.ts +9 -0
  18. package/es-custom/components/about-modal/index.js +9 -0
  19. package/es-custom/components/about-modal/index.js.map +1 -0
  20. package/es-custom/components/side-panel/defs.d.ts +39 -0
  21. package/es-custom/components/side-panel/defs.js +51 -0
  22. package/es-custom/components/side-panel/defs.js.map +1 -0
  23. package/es-custom/components/side-panel/index.d.ts +9 -0
  24. package/es-custom/components/side-panel/index.js +9 -0
  25. package/es-custom/components/side-panel/index.js.map +1 -0
  26. package/es-custom/components/side-panel/side-panel.d.ts +546 -0
  27. package/es-custom/components/side-panel/side-panel.js +828 -0
  28. package/es-custom/components/side-panel/side-panel.js.map +1 -0
  29. package/es-custom/components/side-panel/side-panel.scss.js +13 -0
  30. package/es-custom/components/side-panel/side-panel.scss.js.map +1 -0
  31. package/es-custom/components/side-panel/side-panel.test.d.ts +7 -0
  32. package/es-custom/components/side-panel/side-panel.test.js +56 -0
  33. package/es-custom/components/side-panel/side-panel.test.js.map +1 -0
  34. package/es-custom/components/tearsheet/defs.d.ts +26 -0
  35. package/es-custom/components/tearsheet/defs.js +39 -0
  36. package/es-custom/components/tearsheet/defs.js.map +1 -0
  37. package/es-custom/components/tearsheet/index.d.ts +9 -0
  38. package/es-custom/components/tearsheet/index.js +9 -0
  39. package/es-custom/components/tearsheet/index.js.map +1 -0
  40. package/es-custom/components/tearsheet/tearsheet.d.ts +516 -0
  41. package/es-custom/components/tearsheet/tearsheet.js +676 -0
  42. package/es-custom/components/tearsheet/tearsheet.js.map +1 -0
  43. package/es-custom/components/tearsheet/tearsheet.scss.js +13 -0
  44. package/es-custom/components/tearsheet/tearsheet.scss.js.map +1 -0
  45. package/es-custom/components/tearsheet/tearsheet.test.d.ts +7 -0
  46. package/es-custom/components/tearsheet/tearsheet.test.js +121 -0
  47. package/es-custom/components/tearsheet/tearsheet.test.js.map +1 -0
  48. package/es-custom/components/user-avatar/index.d.ts +9 -0
  49. package/es-custom/components/user-avatar/index.js +9 -0
  50. package/es-custom/components/user-avatar/index.js.map +1 -0
  51. package/es-custom/components/user-avatar/user-avatar.d.ts +405 -0
  52. package/es-custom/components/user-avatar/user-avatar.js +151 -0
  53. package/es-custom/components/user-avatar/user-avatar.js.map +1 -0
  54. package/es-custom/components/user-avatar/user-avatar.scss.js +13 -0
  55. package/es-custom/components/user-avatar/user-avatar.scss.js.map +1 -0
  56. package/es-custom/globals/internal/handle.d.ts +18 -0
  57. package/es-custom/globals/internal/handle.js +8 -0
  58. package/es-custom/globals/internal/handle.js.map +1 -0
  59. package/es-custom/globals/internal/storybook-cdn.js +78 -0
  60. package/es-custom/globals/internal/storybook-cdn.js.map +1 -0
  61. package/es-custom/globals/settings.d.ts +15 -0
  62. package/es-custom/globals/settings.js +28 -0
  63. package/es-custom/globals/settings.js.map +1 -0
  64. package/es-custom/index.d.ts +12 -0
  65. package/es-custom/index.js +12 -0
  66. package/es-custom/index.js.map +1 -0
  67. package/es-custom/package.json.js +13 -0
  68. package/es-custom/package.json.js.map +1 -0
  69. package/lib/components/about-modal/about-modal.d.ts +87 -61
  70. package/lib/components/side-panel/side-panel.d.ts +87 -61
  71. package/lib/components/tearsheet/tearsheet.d.ts +87 -61
  72. package/lib/components/user-avatar/user-avatar.d.ts +87 -61
  73. package/package.json +6 -4
@@ -0,0 +1,828 @@
1
+ /**
2
+ * Copyright IBM Corp. 2024
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import { __decorate } from 'tslib';
9
+ import { LitElement, html } from 'lit';
10
+ import { query, queryAssignedElements, state, property } from 'lit/decorators.js';
11
+ import { prefix, carbonPrefix } from '../../globals/settings.js';
12
+ import HostListener from '@carbon/web-components/es/globals/decorators/host-listener.js';
13
+ import HostListenerMixin from '@carbon/web-components/es/globals/mixins/host-listener.js';
14
+ import { SIDE_PANEL_PLACEMENT, SIDE_PANEL_SIZE } from './defs.js';
15
+ import styles from './side-panel.scss.js';
16
+ import { selectorTabbable } from '@carbon/web-components/es/globals/settings.js';
17
+ import { carbonElement } from '@carbon/web-components/es/globals/decorators/carbon-element.js';
18
+ import ArrowLeft16 from '@carbon/web-components/es/icons/arrow--left/16';
19
+ import Close20 from '@carbon/web-components/es/icons/close/20';
20
+ import { moderate02 } from '@carbon/motion';
21
+ import '@carbon/web-components/es-custom/components/button/index.js';
22
+ import '@carbon/web-components/es-custom/components/button/button-set-base.js';
23
+ import '@carbon/web-components/es-custom/components/icon-button/index.js';
24
+ import '@carbon/web-components/es-custom/components/layer/index.js';
25
+
26
+ /**
27
+ * @license
28
+ *
29
+ * Copyright IBM Corp. 2023, 2024
30
+ *
31
+ * This source code is licensed under the Apache-2.0 license found in the
32
+ * LICENSE file in the root directory of this source tree.
33
+ */
34
+ const blockClass = `${prefix}--side-panel`;
35
+ const blockClassActionSet = `${prefix}--action-set`;
36
+ /**
37
+ * Observes resize of the given element with the given resize observer.
38
+ *
39
+ * @param observer The resize observer.
40
+ * @param elem The element to observe the resize.
41
+ */
42
+ const observeResize = (observer, elem) => {
43
+ if (!elem) {
44
+ return null;
45
+ }
46
+ observer.observe(elem);
47
+ return {
48
+ release() {
49
+ observer.unobserve(elem);
50
+ return null;
51
+ },
52
+ };
53
+ };
54
+ /**
55
+ * Tries to focus on the given elements and bails out if one of them is successful.
56
+ *
57
+ * @param elements The elements.
58
+ * @param reverse `true` to go through the list in reverse order.
59
+ * @returns `true` if one of the attempts is successful, `false` otherwise.
60
+ */
61
+ function tryFocusElements(elements, reverse) {
62
+ {
63
+ for (let i = elements.length - 1; i >= 0; --i) {
64
+ const elem = elements[i];
65
+ elem.focus();
66
+ if (elem.ownerDocument.activeElement === elem) {
67
+ return true;
68
+ }
69
+ }
70
+ }
71
+ return false;
72
+ }
73
+ /**
74
+ * SidePanel.
75
+ *
76
+ * @element c4p-side-panel
77
+ * @csspart dialog The dialog.
78
+ * @fires c4p-side-panel-beingclosed
79
+ * The custom event fired before this side-panel is being closed upon a user gesture.
80
+ * Cancellation of this event stops the user-initiated action of closing this side-panel.
81
+ * @fires c4p-side-panel-closed - The custom event fired after this side-panel is closed upon a user gesture.
82
+ * @fires c4p-side-panel-navigate-back - custom event fired when clicking navigate back (available when step > 0)
83
+ */
84
+ let CDSSidePanel = class CDSSidePanel extends HostListenerMixin(LitElement) {
85
+ constructor() {
86
+ super(...arguments);
87
+ /**
88
+ * The handle for observing resize of the parent element of this element.
89
+ */
90
+ this._hObserveResize = null;
91
+ /**
92
+ * The element that had focus before this side-panel gets open.
93
+ */
94
+ this._launcher = null;
95
+ this._doAnimateTitle = true;
96
+ this._isOpen = false;
97
+ this._containerScrollTop = -16;
98
+ this._hasSubtitle = false;
99
+ this._hasSlug = false;
100
+ this._hasActionToolbar = false;
101
+ this._actionsCount = 0;
102
+ this._slugCloseSize = 'sm';
103
+ /**
104
+ * Handles `blur` event on this element.
105
+ *
106
+ * @param event The event.
107
+ * @param event.target The event target.
108
+ * @param event.relatedTarget The event relatedTarget.
109
+ */
110
+ this._handleBlur = async ({ target, relatedTarget }) => {
111
+ var _a;
112
+ const { open, _startSentinelNode: startSentinelNode, _endSentinelNode: endSentinelNode, } = this;
113
+ const oldContains = target !== this && this.contains(target);
114
+ const currentContains = relatedTarget !== this &&
115
+ (this.contains(relatedTarget) ||
116
+ (((_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.contains(relatedTarget)) &&
117
+ relatedTarget !== startSentinelNode &&
118
+ relatedTarget !== endSentinelNode));
119
+ // Performs focus wrapping if _all_ of the following is met:
120
+ // * This side-panel is open
121
+ // * The viewport still has focus
122
+ // * SidePanel body used to have focus but no longer has focus
123
+ const { selectorTabbable: selectorTabbableForSidePanel } = this
124
+ .constructor;
125
+ if (open && relatedTarget && oldContains && !currentContains) {
126
+ const comparisonResult = target.compareDocumentPosition(relatedTarget);
127
+ if (relatedTarget === startSentinelNode || comparisonResult) {
128
+ await this.constructor._delay();
129
+ if (!tryFocusElements(this.querySelectorAll(selectorTabbableForSidePanel)) &&
130
+ relatedTarget !== this) {
131
+ this.focus();
132
+ }
133
+ }
134
+ else if (relatedTarget === endSentinelNode || comparisonResult) {
135
+ await this.constructor._delay();
136
+ if (!tryFocusElements(this.querySelectorAll(selectorTabbableForSidePanel))) {
137
+ this.focus();
138
+ }
139
+ }
140
+ }
141
+ };
142
+ this._handleKeydown = ({ key, target }) => {
143
+ if (key === 'Esc' || key === 'Escape') {
144
+ this._handleUserInitiatedClose(target);
145
+ }
146
+ };
147
+ this._reducedMotion = typeof window !== 'undefined' && (window === null || window === void 0 ? void 0 : window.matchMedia)
148
+ ? window.matchMedia('(prefers-reduced-motion: reduce)')
149
+ : { matches: true };
150
+ this._adjustPageContent = () => {
151
+ var _a, _b;
152
+ // sets/resets styles based on slideIn property and selectorPageContent;
153
+ if (this.selectorPageContent) {
154
+ const pageContentEl = document.querySelector(this.selectorPageContent);
155
+ if (pageContentEl) {
156
+ const newValues = {
157
+ marginInlineStart: '',
158
+ marginInlineEnd: '',
159
+ inlineSize: '',
160
+ transition: this._reducedMotion.matches
161
+ ? 'none'
162
+ : `all ${moderate02}`,
163
+ transitionProperty: 'margin-inline-start, margin-inline-end',
164
+ };
165
+ if (this.open) {
166
+ newValues.inlineSize = 'auto';
167
+ if (this.placement === 'left') {
168
+ newValues.marginInlineStart = `${(_a = this === null || this === void 0 ? void 0 : this._sidePanel) === null || _a === void 0 ? void 0 : _a.offsetWidth}px`;
169
+ }
170
+ else {
171
+ newValues.marginInlineEnd = `${(_b = this === null || this === void 0 ? void 0 : this._sidePanel) === null || _b === void 0 ? void 0 : _b.offsetWidth}px`;
172
+ }
173
+ }
174
+ if (this.slideIn) {
175
+ Object.keys(newValues).forEach((key) => {
176
+ pageContentEl.style[key] = newValues[key];
177
+ });
178
+ }
179
+ }
180
+ }
181
+ };
182
+ this._checkSetOpen = () => {
183
+ var _a;
184
+ const { _sidePanel: sidePanel } = this;
185
+ if (sidePanel && this._isOpen) {
186
+ if ((_a = this._reducedMotion) === null || _a === void 0 ? void 0 : _a.matches) {
187
+ this._isOpen = false;
188
+ }
189
+ else {
190
+ // wait until the side panel has transitioned off the screen to remove
191
+ sidePanel.addEventListener('transitionend', () => {
192
+ this._isOpen = false;
193
+ });
194
+ }
195
+ }
196
+ else {
197
+ // allow the html to render before animating in the side panel
198
+ this._isOpen = this.open;
199
+ }
200
+ };
201
+ this._checkUpdateIconButtonSizes = () => {
202
+ var _a, _b;
203
+ const slug = this.querySelector(`${prefix}-slug`);
204
+ const otherButtons = (_a = this === null || this === void 0 ? void 0 : this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll('#nav-back-button, #close-button');
205
+ let iconButtonSize = 'sm';
206
+ if (slug || (otherButtons === null || otherButtons === void 0 ? void 0 : otherButtons.length)) {
207
+ const actions = (_b = this === null || this === void 0 ? void 0 : this.querySelectorAll) === null || _b === void 0 ? void 0 : _b.call(this, `${prefix}-button[slot='actions']`);
208
+ if ((actions === null || actions === void 0 ? void 0 : actions.length) && /l/.test(this.size)) {
209
+ iconButtonSize = 'md';
210
+ }
211
+ }
212
+ if (slug) {
213
+ slug === null || slug === void 0 ? void 0 : slug.setAttribute('size', iconButtonSize);
214
+ }
215
+ if (otherButtons) {
216
+ [...otherButtons].forEach((btn) => {
217
+ btn.setAttribute('size', iconButtonSize);
218
+ });
219
+ }
220
+ };
221
+ this._checkUpdateActionSizes = () => {
222
+ if (this._actions) {
223
+ for (let i = 0; i < this._actions.length; i++) {
224
+ this._actions[i].setAttribute('size', this.condensedActions ? 'lg' : 'xl');
225
+ }
226
+ }
227
+ };
228
+ this._maxActions = 3;
229
+ this._checkSetDoAnimateTitle = () => {
230
+ var _a, _b, _c;
231
+ let canDoAnimateTitle = false;
232
+ if (this._sidePanel &&
233
+ this.open &&
234
+ this.animateTitle &&
235
+ ((_a = this === null || this === void 0 ? void 0 : this.title) === null || _a === void 0 ? void 0 : _a.length) &&
236
+ !this._reducedMotion.matches) {
237
+ const scrollAnimationDistance = this._getScrollAnimationDistance();
238
+ // used to calculate the header moves
239
+ (_c = (_b = this === null || this === void 0 ? void 0 : this._sidePanel) === null || _b === void 0 ? void 0 : _b.style) === null || _c === void 0 ? void 0 : _c.setProperty(`--${blockClass}--scroll-animation-distance`, `${scrollAnimationDistance}`);
240
+ let scrollEl = this._animateScrollWrapper;
241
+ if (!scrollEl && this.animateTitle && !this._doAnimateTitle) {
242
+ scrollEl = this._innerContent;
243
+ }
244
+ if (scrollEl) {
245
+ const innerComputed = window === null || window === void 0 ? void 0 : window.getComputedStyle(this._innerContent);
246
+ const innerPaddingHeight = innerComputed
247
+ ? parseFloat(innerComputed === null || innerComputed === void 0 ? void 0 : innerComputed.paddingTop) +
248
+ parseFloat(innerComputed === null || innerComputed === void 0 ? void 0 : innerComputed.paddingBottom)
249
+ : 0;
250
+ canDoAnimateTitle =
251
+ (!!this.labelText || !!this._hasActionToolbar || this._hasSubtitle) &&
252
+ scrollEl.scrollHeight - scrollEl.clientHeight >=
253
+ scrollAnimationDistance + innerPaddingHeight;
254
+ }
255
+ }
256
+ this._doAnimateTitle = canDoAnimateTitle;
257
+ };
258
+ /**
259
+ * The `ResizeObserver` instance for observing element resizes for re-positioning floating menu position.
260
+ */
261
+ // TODO: Wait for `.d.ts` update to support `ResizeObserver`
262
+ // @ts-ignore
263
+ this._resizeObserver = new ResizeObserver(() => {
264
+ if (this._sidePanel) {
265
+ this._checkSetDoAnimateTitle();
266
+ }
267
+ });
268
+ this._getScrollAnimationDistance = () => {
269
+ var _a, _b, _c, _d;
270
+ const labelHeight = (_b = (_a = this === null || this === void 0 ? void 0 : this._label) === null || _a === void 0 ? void 0 : _a.offsetHeight) !== null && _b !== void 0 ? _b : 0;
271
+ const subtitleHeight = (_d = (_c = this === null || this === void 0 ? void 0 : this._subtitle) === null || _c === void 0 ? void 0 : _c.offsetHeight) !== null && _d !== void 0 ? _d : 0;
272
+ const titleVerticalBorder = this._hasActionToolbar
273
+ ? this._title.offsetHeight - this._title.clientHeight
274
+ : 0;
275
+ return labelHeight + subtitleHeight + titleVerticalBorder;
276
+ };
277
+ this._scrollObserver = () => {
278
+ var _a, _b, _c, _d;
279
+ const scrollTop = (_b = (_a = this._animateScrollWrapper) === null || _a === void 0 ? void 0 : _a.scrollTop) !== null && _b !== void 0 ? _b : 0;
280
+ const scrollAnimationDistance = this._getScrollAnimationDistance();
281
+ (_d = (_c = this === null || this === void 0 ? void 0 : this._sidePanel) === null || _c === void 0 ? void 0 : _c.style) === null || _d === void 0 ? void 0 : _d.setProperty(`--${blockClass}--scroll-animation-progress`, `${Math.min(scrollTop, scrollAnimationDistance) / scrollAnimationDistance}`);
282
+ };
283
+ this._handleCurrentStepUpdate = () => {
284
+ var _a;
285
+ const scrollable = (_a = this._animateScrollWrapper) !== null && _a !== void 0 ? _a : this._innerContent;
286
+ if (scrollable) {
287
+ scrollable.scrollTop = 0;
288
+ }
289
+ };
290
+ /**
291
+ * Determines if the title will animate on scroll
292
+ */
293
+ this.animateTitle = true;
294
+ /**
295
+ * Sets the close button icon description
296
+ */
297
+ this.closeIconDescription = 'Close';
298
+ /**
299
+ * Determines whether the side panel should render the condensed version (affects action buttons primarily)
300
+ */
301
+ this.condensedActions = false;
302
+ /**
303
+ * Determines whether the side panel should render with an overlay
304
+ */
305
+ this.includeOverlay = false;
306
+ /**
307
+ * Sets the icon description for the navigation back icon button
308
+ */
309
+ this.navigationBackIconDescription = 'Back';
310
+ /**
311
+ * `true` if the side-panel should be open.
312
+ */
313
+ this.open = false;
314
+ /**
315
+ * SidePanel placement.
316
+ */
317
+ this.placement = SIDE_PANEL_PLACEMENT.RIGHT;
318
+ /**
319
+ * Prevent closing on click outside of side-panel
320
+ */
321
+ this.preventCloseOnClickOutside = false;
322
+ /**
323
+ * Selector for page content, used to push content to side except
324
+ */
325
+ this.selectorPageContent = '';
326
+ /**
327
+ * SidePanel size.
328
+ */
329
+ this.size = SIDE_PANEL_SIZE.MEDIUM;
330
+ /**
331
+ * Determines if this panel slides in
332
+ */
333
+ this.slideIn = false;
334
+ }
335
+ /**
336
+ * Handles `click` event on the side-panel container.
337
+ *
338
+ * @param event The event.
339
+ */
340
+ _handleClickOnOverlay(event) {
341
+ if (!this.preventCloseOnClickOutside) {
342
+ this._handleUserInitiatedClose(event.target);
343
+ }
344
+ }
345
+ /**
346
+ * Handles `click` event on the side-panel container.
347
+ *
348
+ * @param event The event.
349
+ */
350
+ _handleCloseClick(event) {
351
+ this._handleUserInitiatedClose(event.target);
352
+ }
353
+ /**
354
+ * Handles user-initiated close request of this side-panel.
355
+ *
356
+ * @param triggeredBy The element that triggered this close request.
357
+ */
358
+ _handleUserInitiatedClose(triggeredBy) {
359
+ if (this.open) {
360
+ const init = {
361
+ bubbles: true,
362
+ cancelable: true,
363
+ composed: true,
364
+ detail: {
365
+ triggeredBy,
366
+ },
367
+ };
368
+ if (this.dispatchEvent(new CustomEvent(this.constructor.eventBeforeClose, init))) {
369
+ this.open = false;
370
+ this.dispatchEvent(new CustomEvent(this.constructor.eventClose, init));
371
+ }
372
+ }
373
+ }
374
+ _handleNavigateBack(triggeredBy) {
375
+ this.dispatchEvent(new CustomEvent(this.constructor.eventNavigateBack, {
376
+ composed: true,
377
+ detail: {
378
+ triggeredBy,
379
+ },
380
+ }));
381
+ }
382
+ _handleSlugChange(e) {
383
+ this._checkUpdateIconButtonSizes();
384
+ const childItems = e.target.assignedElements();
385
+ this._hasSlug = childItems.length > 0;
386
+ }
387
+ _handleSubtitleChange(e) {
388
+ const target = e.target;
389
+ const subtitle = target === null || target === void 0 ? void 0 : target.assignedElements();
390
+ this._hasSubtitle = subtitle.length > 0;
391
+ }
392
+ _handleActionToolbarChange(e) {
393
+ const target = e.target;
394
+ const toolbarActions = target === null || target === void 0 ? void 0 : target.assignedElements();
395
+ this._hasActionToolbar = toolbarActions && toolbarActions.length > 0;
396
+ if (this._hasActionToolbar) {
397
+ for (const toolbarAction of toolbarActions) {
398
+ // toolbar actions size should always be sm
399
+ toolbarAction.setAttribute('size', 'sm');
400
+ }
401
+ }
402
+ }
403
+ _handleActionsChange(e) {
404
+ var _a;
405
+ const target = e.target;
406
+ const actions = target === null || target === void 0 ? void 0 : target.assignedElements();
407
+ // update slug size
408
+ this._checkUpdateIconButtonSizes();
409
+ const actionsCount = (_a = actions === null || actions === void 0 ? void 0 : actions.length) !== null && _a !== void 0 ? _a : 0;
410
+ if (actionsCount > this._maxActions) {
411
+ this._actionsCount = this._maxActions;
412
+ if (process.env.NODE_ENV === 'development') {
413
+ console.error(`Too many side-panel actions, max ${this._maxActions}.`);
414
+ }
415
+ }
416
+ else {
417
+ this._actionsCount = actionsCount;
418
+ }
419
+ for (let i = 0; i < (actions === null || actions === void 0 ? void 0 : actions.length); i++) {
420
+ if (i + 1 > this._maxActions) {
421
+ // hide excessive side panel actions
422
+ actions[i].setAttribute('hidden', 'true');
423
+ actions[i].setAttribute(`data-actions-limit-${this._maxActions}-exceeded`, `${actions.length}`);
424
+ }
425
+ else {
426
+ actions[i].classList.add(`${blockClassActionSet}__action-button`);
427
+ }
428
+ }
429
+ this._checkUpdateActionSizes();
430
+ }
431
+ async connectObservers() {
432
+ await this.updateComplete;
433
+ this._hObserveResize = observeResize(this._resizeObserver, this._sidePanel);
434
+ }
435
+ disconnectObservers() {
436
+ if (this._hObserveResize) {
437
+ this._hObserveResize = this._hObserveResize.release();
438
+ }
439
+ }
440
+ connectedCallback() {
441
+ super.connectedCallback();
442
+ this.disconnectObservers();
443
+ this.connectObservers();
444
+ }
445
+ disconnectedCallback() {
446
+ super.disconnectedCallback();
447
+ this.disconnectObservers();
448
+ }
449
+ render() {
450
+ const { closeIconDescription, condensedActions, currentStep, includeOverlay, labelText, navigationBackIconDescription, open, placement, size, slideIn, title, } = this;
451
+ if (!open && !this._isOpen) {
452
+ return html ``;
453
+ }
454
+ const actionsMultiple = ['', 'single', 'double', 'triple'][this._actionsCount];
455
+ const titleTemplate = html `<div
456
+ class=${`${blockClass}__title`}
457
+ ?no-label=${!!labelText}
458
+ >
459
+ <h2 class=${title ? `${blockClass}__title-text` : ''} title=${title}>
460
+ ${title}
461
+ </h2>
462
+
463
+ ${this._doAnimateTitle
464
+ ? html `<h2
465
+ class=${`${blockClass}__collapsed-title-text`}
466
+ title=${title}
467
+ aria-hidden="true"
468
+ >
469
+ ${title}
470
+ </h2>`
471
+ : ''}
472
+ </div>`;
473
+ const headerHasTitleClass = this.title
474
+ ? ` ${blockClass}__header--has-title `
475
+ : '';
476
+ const headerTemplate = html `
477
+ <div
478
+ class=${`${blockClass}__header${headerHasTitleClass}`}
479
+ ?detail-step=${currentStep > 0}
480
+ ?no-title-animation=${!this._doAnimateTitle}
481
+ ?reduced-motion=${this._reducedMotion.matches}
482
+ >
483
+ <!-- render back button -->
484
+ ${currentStep > 0
485
+ ? html `<cds-custom-icon-button
486
+ align="bottom-left"
487
+ aria-label=${navigationBackIconDescription}
488
+ kind="ghost"
489
+ size="sm"
490
+ class=${`${prefix}--btn ${blockClass}__navigation-back-button`}
491
+ @click=${this._handleNavigateBack}
492
+ >
493
+ ${ArrowLeft16({ slot: 'icon' })}
494
+ <span slot="tooltip-content">
495
+ ${navigationBackIconDescription}
496
+ </span>
497
+ </cds-custom-icon-button>`
498
+ : ''}
499
+
500
+ <!-- render title label -->
501
+ ${(title === null || title === void 0 ? void 0 : title.length) && (labelText === null || labelText === void 0 ? void 0 : labelText.length)
502
+ ? html ` <p class=${`${blockClass}__label-text`}>${labelText}</p>`
503
+ : ''}
504
+
505
+ <!-- title -->
506
+ ${title ? titleTemplate : ''}
507
+
508
+ <!-- render slug and close button area -->
509
+ <div class=${`${blockClass}__slug-and-close`}>
510
+ <slot name="slug" @slotchange=${this._handleSlugChange}></slot>
511
+ <!-- {normalizedSlug} -->
512
+ <cds-custom-icon-button
513
+ align="bottom-right"
514
+ aria-label=${closeIconDescription}
515
+ kind="ghost"
516
+ size="sm"
517
+ class=${`${blockClass}__close-button`}
518
+ @click=${this._handleCloseClick}
519
+ >
520
+ ${Close20({ slot: 'icon' })}
521
+ <span slot="tooltip-content"> ${closeIconDescription} </span>
522
+ </cds-custom-icon-button>
523
+ </div>
524
+
525
+ <!-- render sub title -->
526
+ <p
527
+ class=${this._hasSubtitle ? `${blockClass}__subtitle-text` : ''}
528
+ ?hidden=${!this._hasSubtitle}
529
+ ?no-title-animation=${!this._doAnimateTitle}
530
+ ?no-action-toolbar=${!this._hasActionToolbar}
531
+ ?no-title=${!title}
532
+ >
533
+ <slot
534
+ name="subtitle"
535
+ @slotchange=${this._handleSubtitleChange}
536
+ ></slot>
537
+ </p>
538
+
539
+ <div
540
+ class=${this._hasActionToolbar ? `${blockClass}__action-toolbar` : ''}
541
+ ?hidden=${!this._hasActionToolbar}
542
+ ?no-title-animation=${!this._doAnimateTitle}
543
+ >
544
+ <slot
545
+ name="action-toolbar"
546
+ @slotchange=${this._handleActionToolbarChange}
547
+ ></slot>
548
+ </div>
549
+ </div>
550
+ `;
551
+ const mainTemplate = html `<div
552
+ class=${`${blockClass}__inner-content`}
553
+ ?scrolls=${!this._doAnimateTitle}
554
+ >
555
+ <cds-custom-layer level="1">
556
+ <slot></slot>
557
+ </cds-custom-layer>
558
+ </div> `;
559
+ const sidePanelAnimateTitleClass = this._doAnimateTitle
560
+ ? ` ${blockClass}--animated-title`
561
+ : '';
562
+ return html `
563
+ <div
564
+ class=${`${blockClass}${sidePanelAnimateTitleClass}`}
565
+ part="dialog"
566
+ role="complementary"
567
+ placement="${placement}"
568
+ ?has-slug=${this._hasSlug}
569
+ ?open=${this._isOpen}
570
+ ?opening=${open && !this._isOpen}
571
+ ?closing=${!open && this._isOpen}
572
+ ?condensed-actions=${condensedActions}
573
+ ?overlay=${includeOverlay || slideIn}
574
+ ?slide-in=${slideIn}
575
+ size=${size}
576
+ >
577
+ <a
578
+ id="start-sentinel"
579
+ class="sentinel"
580
+ hidden
581
+ href="javascript:void 0"
582
+ role="navigation"
583
+ ></a>
584
+
585
+ ${this._doAnimateTitle
586
+ ? html `<div class=${`${blockClass}__animated-scroll-wrapper`} scrolls>
587
+ ${headerTemplate} ${mainTemplate}
588
+ </div>`
589
+ : html ` ${headerTemplate} ${mainTemplate}`}
590
+
591
+ <cds-custom-button-set-base
592
+ class=${`${blockClass}__actions-container`}
593
+ ?hidden=${this._actionsCount === 0}
594
+ ?condensed=${condensedActions}
595
+ actions-multiple=${actionsMultiple}
596
+ size=${size}
597
+ >
598
+ <slot name="actions" @slotchange=${this._handleActionsChange}></slot>
599
+ </cds-custom-button-set-base>
600
+
601
+ <a
602
+ id="end-sentinel"
603
+ class="sentinel"
604
+ hidden
605
+ href="javascript:void 0"
606
+ role="navigation"
607
+ ></a>
608
+ </div>
609
+
610
+ ${includeOverlay
611
+ ? html `<div
612
+ ?slide-in=${slideIn}
613
+ class=${`${blockClass}__overlay`}
614
+ ?open=${this.open}
615
+ ?opening=${open && !this._isOpen}
616
+ ?closing=${!open && this._isOpen}
617
+ tabindex="-1"
618
+ @click=${this._handleClickOnOverlay}
619
+ ></div>`
620
+ : ''}
621
+ `;
622
+ }
623
+ async updated(changedProperties) {
624
+ var _a, _b, _c, _d;
625
+ if (changedProperties.has('condensedActions')) {
626
+ this._checkUpdateActionSizes();
627
+ }
628
+ if (changedProperties.has('currentStep')) {
629
+ this._handleCurrentStepUpdate();
630
+ }
631
+ if (changedProperties.has('_doAnimateTitle')) {
632
+ (_a = this === null || this === void 0 ? void 0 : this._animateScrollWrapper) === null || _a === void 0 ? void 0 : _a.removeEventListener('scroll', this._scrollObserver);
633
+ if (this._doAnimateTitle) {
634
+ (_b = this === null || this === void 0 ? void 0 : this._animateScrollWrapper) === null || _b === void 0 ? void 0 : _b.addEventListener('scroll', this._scrollObserver);
635
+ }
636
+ else {
637
+ (_d = (_c = this === null || this === void 0 ? void 0 : this._sidePanel) === null || _c === void 0 ? void 0 : _c.style) === null || _d === void 0 ? void 0 : _d.setProperty(`--${blockClass}--scroll-animation-progress`, '0');
638
+ }
639
+ }
640
+ if (changedProperties.has('_isOpen') ||
641
+ changedProperties.has('animateTitle')) {
642
+ /* @state property changed */
643
+ this._checkSetDoAnimateTitle();
644
+ }
645
+ if (changedProperties.has('slideIn') ||
646
+ changedProperties.has('open') ||
647
+ changedProperties.has('includeOverlay')) {
648
+ this._adjustPageContent();
649
+ }
650
+ if (changedProperties.has('open')) {
651
+ this._checkSetOpen();
652
+ this.disconnectObservers();
653
+ if (this.open) {
654
+ this.connectObservers();
655
+ this._launcher = this.ownerDocument.activeElement;
656
+ const focusNode = this.selectorInitialFocus &&
657
+ this.querySelector(this.selectorInitialFocus);
658
+ await this.constructor._delay();
659
+ if (focusNode) {
660
+ // For cases where a `carbon-web-components` component (e.g. `<cds-custom-button>`) being `primaryFocusNode`,
661
+ // where its first update/render cycle that makes it focusable happens after `<c4p-side-panel>`'s first update/render cycle
662
+ focusNode.focus();
663
+ }
664
+ else if (!tryFocusElements(this.querySelectorAll(this.constructor.selectorTabbable))) {
665
+ this.focus();
666
+ }
667
+ }
668
+ else if (this._launcher &&
669
+ typeof this._launcher.focus === 'function') {
670
+ this._launcher.focus();
671
+ this._launcher = null;
672
+ }
673
+ }
674
+ }
675
+ /**
676
+ * @param ms The number of milliseconds.
677
+ * @returns A promise that is resolves after the given milliseconds.
678
+ */
679
+ static _delay(ms = 0) {
680
+ return new Promise((resolve) => {
681
+ setTimeout(resolve, ms);
682
+ });
683
+ }
684
+ /**
685
+ * A selector selecting tabbable nodes.
686
+ */
687
+ static get selectorTabbable() {
688
+ return selectorTabbable;
689
+ }
690
+ /**
691
+ * The name of the custom event fired before this side-panel is being closed upon a user gesture.
692
+ * Cancellation of this event stops the user-initiated action of closing this side-panel.
693
+ */
694
+ static get eventBeforeClose() {
695
+ return `${prefix}-side-panel-beingclosed`;
696
+ }
697
+ /**
698
+ * The name of the custom event fired after this side-panel is closed upon a user gesture.
699
+ */
700
+ static get eventClose() {
701
+ return `${prefix}-side-panel-closed`;
702
+ }
703
+ /**
704
+ * The name of the custom event fired on clicking the navigate back button
705
+ */
706
+ static get eventNavigateBack() {
707
+ return `${prefix}-side-panel-navigate-back`;
708
+ }
709
+ };
710
+ CDSSidePanel.styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader
711
+ __decorate([
712
+ query('#start-sentinel')
713
+ ], CDSSidePanel.prototype, "_startSentinelNode", void 0);
714
+ __decorate([
715
+ query('#end-sentinel')
716
+ ], CDSSidePanel.prototype, "_endSentinelNode", void 0);
717
+ __decorate([
718
+ query(`.${blockClass}`)
719
+ ], CDSSidePanel.prototype, "_sidePanel", void 0);
720
+ __decorate([
721
+ query(`.${blockClass}__animated-scroll-wrapper`)
722
+ ], CDSSidePanel.prototype, "_animateScrollWrapper", void 0);
723
+ __decorate([
724
+ query(`.${blockClass}__label-text`)
725
+ ], CDSSidePanel.prototype, "_label", void 0);
726
+ __decorate([
727
+ query(`.${blockClass}__title-text`)
728
+ ], CDSSidePanel.prototype, "_title", void 0);
729
+ __decorate([
730
+ query(`.${blockClass}__subtitle-text`)
731
+ ], CDSSidePanel.prototype, "_subtitle", void 0);
732
+ __decorate([
733
+ query(`.${blockClass}__inner-content`)
734
+ ], CDSSidePanel.prototype, "_innerContent", void 0);
735
+ __decorate([
736
+ queryAssignedElements({
737
+ slot: 'actions',
738
+ selector: `${carbonPrefix}-button`,
739
+ })
740
+ ], CDSSidePanel.prototype, "_actions", void 0);
741
+ __decorate([
742
+ state()
743
+ ], CDSSidePanel.prototype, "_doAnimateTitle", void 0);
744
+ __decorate([
745
+ state()
746
+ ], CDSSidePanel.prototype, "_isOpen", void 0);
747
+ __decorate([
748
+ state()
749
+ ], CDSSidePanel.prototype, "_containerScrollTop", void 0);
750
+ __decorate([
751
+ state()
752
+ ], CDSSidePanel.prototype, "_hasSubtitle", void 0);
753
+ __decorate([
754
+ state()
755
+ ], CDSSidePanel.prototype, "_hasSlug", void 0);
756
+ __decorate([
757
+ state()
758
+ ], CDSSidePanel.prototype, "_hasActionToolbar", void 0);
759
+ __decorate([
760
+ state()
761
+ ], CDSSidePanel.prototype, "_actionsCount", void 0);
762
+ __decorate([
763
+ state()
764
+ ], CDSSidePanel.prototype, "_slugCloseSize", void 0);
765
+ __decorate([
766
+ HostListener('shadowRoot:focusout')
767
+ // @ts-ignore: The decorator refers to this method but TS thinks this method is not referred to
768
+ ], CDSSidePanel.prototype, "_handleBlur", void 0);
769
+ __decorate([
770
+ HostListener('document:keydown')
771
+ // @ts-ignore: The decorator refers to this method but TS thinks this method is not referred to
772
+ ], CDSSidePanel.prototype, "_handleKeydown", void 0);
773
+ __decorate([
774
+ property({ reflect: true, attribute: 'animate-title', type: Boolean })
775
+ ], CDSSidePanel.prototype, "animateTitle", void 0);
776
+ __decorate([
777
+ property({ reflect: true, attribute: 'close-icon-description' })
778
+ ], CDSSidePanel.prototype, "closeIconDescription", void 0);
779
+ __decorate([
780
+ property({ type: Boolean, reflect: true, attribute: 'condensed-actions' })
781
+ ], CDSSidePanel.prototype, "condensedActions", void 0);
782
+ __decorate([
783
+ property({ reflect: true, attribute: 'current-step', type: Number })
784
+ ], CDSSidePanel.prototype, "currentStep", void 0);
785
+ __decorate([
786
+ property({ attribute: 'include-overlay', type: Boolean, reflect: true })
787
+ ], CDSSidePanel.prototype, "includeOverlay", void 0);
788
+ __decorate([
789
+ property({ reflect: true, attribute: 'label-text' })
790
+ ], CDSSidePanel.prototype, "labelText", void 0);
791
+ __decorate([
792
+ property({ reflect: true, attribute: 'navigation-back-icon-description' })
793
+ ], CDSSidePanel.prototype, "navigationBackIconDescription", void 0);
794
+ __decorate([
795
+ property({ type: Boolean, reflect: true })
796
+ ], CDSSidePanel.prototype, "open", void 0);
797
+ __decorate([
798
+ property({ reflect: true, type: String })
799
+ ], CDSSidePanel.prototype, "placement", void 0);
800
+ __decorate([
801
+ property({ type: Boolean, attribute: 'prevent-close-on-click-outside' })
802
+ ], CDSSidePanel.prototype, "preventCloseOnClickOutside", void 0);
803
+ __decorate([
804
+ property({
805
+ reflect: true,
806
+ attribute: 'selector-initial-focus',
807
+ type: String,
808
+ })
809
+ ], CDSSidePanel.prototype, "selectorInitialFocus", void 0);
810
+ __decorate([
811
+ property({ reflect: true, attribute: 'selector-page-content' })
812
+ ], CDSSidePanel.prototype, "selectorPageContent", void 0);
813
+ __decorate([
814
+ property({ reflect: true, type: String })
815
+ ], CDSSidePanel.prototype, "size", void 0);
816
+ __decorate([
817
+ property({ attribute: 'slide-in', type: Boolean, reflect: true })
818
+ ], CDSSidePanel.prototype, "slideIn", void 0);
819
+ __decorate([
820
+ property({ reflect: false, type: String })
821
+ ], CDSSidePanel.prototype, "title", void 0);
822
+ CDSSidePanel = __decorate([
823
+ carbonElement(`${prefix}-side-panel`)
824
+ ], CDSSidePanel);
825
+ var CDSSidePanel$1 = CDSSidePanel;
826
+
827
+ export { SIDE_PANEL_PLACEMENT, SIDE_PANEL_SIZE, CDSSidePanel$1 as default };
828
+ //# sourceMappingURL=side-panel.js.map