@sebgroup/green-core 3.18.1 → 3.20.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.
@@ -1,5 +1,7 @@
1
1
  import { PropertyValues } from 'lit';
2
2
  import { GdsElement } from '../../gds-element';
3
+ type AlertRole = 'alert' | 'status';
4
+ declare const GdsAlert_base: (new (...args: any[]) => import("../../utils/mixins/declarative-layout-mixins").MarginProps) & typeof GdsElement;
3
5
  /**
4
6
  * @element gds-alert
5
7
  * @status beta
@@ -10,10 +12,12 @@ import { GdsElement } from '../../gds-element';
10
12
  * @slot - Alert message content
11
13
  * @event gds-close - Fired when alert is dismissed
12
14
  * @event gds-action - Fired when action button is clicked
15
+ * @event gds-ui-state - Fired when the alert is closed internally
13
16
  */
14
- export declare class GdsAlert extends GdsElement {
17
+ export declare class GdsAlert extends GdsAlert_base {
15
18
  #private;
16
19
  static styles: (import("lit").CSSResult | import("lit").CSSResult[])[];
20
+ static styleExpressionBaseSelector: string;
17
21
  /**
18
22
  * The variant of the alert, which determines its appearance and icon.
19
23
  */
@@ -24,14 +28,29 @@ export declare class GdsAlert extends GdsElement {
24
28
  */
25
29
  label: string;
26
30
  /**
27
- * The role of the alert, which can be 'alert' or 'status'.
31
+ * The role of the alert live region, which can be 'alert' or 'status'.
28
32
  * 'alert' is used for critical messages that require immediate attention,
29
- * while 'status' is for informational messages. These corresponds to the
33
+ * while 'status' is for informational messages. These correspond to the
30
34
  * ARIA roles, which you can read more about on MDN:
31
35
  * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/alert_role
32
36
  * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/status_role
33
37
  */
34
- role: 'alert' | 'status';
38
+ alertRole?: AlertRole;
39
+ /**
40
+ * The role of the alert live region.
41
+ *
42
+ * @deprecated Use `alertRole` / `alert-role` instead. The native `role`
43
+ * attribute is reserved for the host element and will be removed from the
44
+ * host to avoid nested live regions.
45
+ */
46
+ role: AlertRole;
47
+ /**
48
+ * Whether the alert is closed.
49
+ *
50
+ * For dynamic announcements, mount the alert before the message should be
51
+ * announced, keep it closed, and then set `closed` to `false`.
52
+ */
53
+ closed: boolean;
35
54
  /**
36
55
  * The dismissibility of the alert, which determines whether it can be closed by the user.
37
56
  */
@@ -48,8 +67,8 @@ export declare class GdsAlert extends GdsElement {
48
67
  buttonLabel: string;
49
68
  private _progress;
50
69
  private _isClosing;
51
- private _cardHidden;
52
70
  constructor();
71
+ connectedCallback(): void;
53
72
  protected updated(changed: PropertyValues): void;
54
73
  render(): any;
55
74
  }
@@ -58,3 +77,4 @@ declare global {
58
77
  'gds-alert': GdsAlert;
59
78
  }
60
79
  }
80
+ export {};
@@ -5,7 +5,7 @@ import {
5
5
  __privateMethod,
6
6
  __privateSet
7
7
  } from "../../chunks/chunk.CAV4X6PU.js";
8
- var _timeoutId, _progressIntervalId, _alertRef, _observer, _isVisible, _remaining, _lastTick, _timerController, _setupObserver, setupObserver_fn, _disconnectObserver, disconnectObserver_fn, _startTicking, startTicking_fn, _resumeTimer, resumeTimer_fn, _pauseTimer, pauseTimer_fn, _clearTimers, clearTimers_fn, _dismiss, dismiss_fn, _handleButtonClick, handleButtonClick_fn, _handleKeyDown, handleKeyDown_fn, _config, config_get, _renderIcon, renderIcon_fn, _renderMessage, renderMessage_fn, _renderActionButton, renderActionButton_fn, _renderCloseButton, renderCloseButton_fn, _renderProgressBar, renderProgressBar_fn;
8
+ var _timeoutId, _progressIntervalId, _alertRef, _observer, _remaining, _lastTick, _timerController, _setupObserver, setupObserver_fn, _disconnectObserver, disconnectObserver_fn, _startTicking, startTicking_fn, _resumeTimer, resumeTimer_fn, _pauseTimer, pauseTimer_fn, _clearTimers, clearTimers_fn, _dismiss, dismiss_fn, _dispatchUiStateEvent, dispatchUiStateEvent_fn, _consumeDeprecatedRoleAttribute, consumeDeprecatedRoleAttribute_fn, _handleButtonClick, handleButtonClick_fn, _handleKeyDown, handleKeyDown_fn, _config, config_get, _effectiveRole, effectiveRole_get, _renderIcon, renderIcon_fn, _renderMessage, renderMessage_fn, _renderActionButton, renderActionButton_fn, _renderCloseButton, renderCloseButton_fn, _renderProgressBar, renderProgressBar_fn;
9
9
  import { localized, msg } from "@lit/localize";
10
10
  import { nothing } from "lit";
11
11
  import { property, state } from "lit/decorators.js";
@@ -16,6 +16,7 @@ import { GdsElement } from "../../gds-element.js";
16
16
  import { gdsCustomElement, getScopedTagName, html } from "../../scoping.js";
17
17
  import { tokens } from "../../tokens.style.js";
18
18
  import { ariaForwarding } from "../../utils/decorators/aria-forwarding.js";
19
+ import { withMarginProps } from "../../utils/mixins/declarative-layout-mixins.js";
19
20
  import { GdsButton } from "../button/button.component.js";
20
21
  import { GdsCard } from "../card/card.component.js";
21
22
  import { IconCircleCheck } from "../icon/icons/circle-check.component.js";
@@ -62,7 +63,7 @@ const VARIANT_CONFIG = {
62
63
  };
63
64
  const FADE_DURATION = 300;
64
65
  const PROGRESS_INTERVAL = 100;
65
- let GdsAlert = class extends GdsElement {
66
+ let GdsAlert = class extends withMarginProps(GdsElement) {
66
67
  constructor() {
67
68
  super();
68
69
  __privateAdd(this, _setupObserver);
@@ -73,11 +74,15 @@ let GdsAlert = class extends GdsElement {
73
74
  __privateAdd(this, _pauseTimer);
74
75
  __privateAdd(this, _clearTimers);
75
76
  __privateAdd(this, _dismiss);
77
+ __privateAdd(this, _dispatchUiStateEvent);
78
+ // Remove when deprecated role attribute is removed
79
+ __privateAdd(this, _consumeDeprecatedRoleAttribute);
76
80
  // Event handlers
77
81
  __privateAdd(this, _handleButtonClick);
78
82
  __privateAdd(this, _handleKeyDown);
79
83
  // Helpers
80
84
  __privateAdd(this, _config);
85
+ __privateAdd(this, _effectiveRole);
81
86
  // Render methods
82
87
  __privateAdd(this, _renderIcon);
83
88
  __privateAdd(this, _renderMessage);
@@ -87,22 +92,21 @@ let GdsAlert = class extends GdsElement {
87
92
  this.variant = "information";
88
93
  this.label = "";
89
94
  this.role = "alert";
95
+ this.closed = false;
90
96
  this.dismissible = false;
91
97
  this.timeout = 0;
92
98
  this.buttonLabel = "";
93
99
  this._progress = 100;
94
100
  this._isClosing = false;
95
- this._cardHidden = false;
96
101
  __privateAdd(this, _timeoutId, void 0);
97
102
  __privateAdd(this, _progressIntervalId, void 0);
98
103
  __privateAdd(this, _alertRef, createRef());
99
104
  __privateAdd(this, _observer, void 0);
100
- __privateAdd(this, _isVisible, false);
101
105
  __privateAdd(this, _remaining, 0);
102
106
  __privateAdd(this, _lastTick, 0);
103
107
  __privateAdd(this, _timerController, {
104
108
  hostConnected: () => {
105
- if (this.timeout > 0) {
109
+ if (!this.closed && this.timeout > 0) {
106
110
  __privateMethod(this, _setupObserver, setupObserver_fn).call(this);
107
111
  }
108
112
  },
@@ -113,19 +117,28 @@ let GdsAlert = class extends GdsElement {
113
117
  });
114
118
  this.addController(__privateGet(this, _timerController));
115
119
  }
120
+ connectedCallback() {
121
+ super.connectedCallback();
122
+ __privateMethod(this, _consumeDeprecatedRoleAttribute, consumeDeprecatedRoleAttribute_fn).call(this);
123
+ }
116
124
  updated(changed) {
117
- if (changed.has("timeout")) {
125
+ if (this.hasAttribute("role")) {
126
+ __privateMethod(this, _consumeDeprecatedRoleAttribute, consumeDeprecatedRoleAttribute_fn).call(this);
127
+ }
128
+ if (changed.has("closed") && this.closed) {
129
+ __privateMethod(this, _disconnectObserver, disconnectObserver_fn).call(this);
130
+ __privateMethod(this, _clearTimers, clearTimers_fn).call(this);
131
+ }
132
+ if (changed.has("timeout") || changed.has("closed") && !this.closed) {
118
133
  __privateMethod(this, _disconnectObserver, disconnectObserver_fn).call(this);
119
134
  __privateMethod(this, _clearTimers, clearTimers_fn).call(this);
120
135
  __privateSet(this, _remaining, Math.max(0, this.timeout));
121
136
  this._progress = 100;
122
- if (this.timeout > 0)
137
+ if (!this.closed && this.timeout > 0)
123
138
  __privateMethod(this, _setupObserver, setupObserver_fn).call(this);
124
139
  }
125
140
  }
126
141
  render() {
127
- if (this._cardHidden)
128
- return nothing;
129
142
  const classes = {
130
143
  dismissing: this._isClosing,
131
144
  dismissible: this.dismissible,
@@ -133,24 +146,30 @@ let GdsAlert = class extends GdsElement {
133
146
  timeout: this.timeout > 0
134
147
  };
135
148
  return html`
136
- <gds-card
137
- ${ref(__privateGet(this, _alertRef))}
138
- role=${this.role}
139
- aria-label=${this.label}
140
- border=${`5xs solid ${__privateGet(this, _config, config_get).border}`}
141
- background=${__privateGet(this, _config, config_get).background}
142
- color=${__privateGet(this, _config, config_get).color}
143
- class=${classMap(classes)}
144
- @keydown=${__privateMethod(this, _handleKeyDown, handleKeyDown_fn)}
145
- id="alert-message"
146
- padding="m"
149
+ <div
150
+ id="alert-region"
151
+ role=${__privateGet(this, _effectiveRole, effectiveRole_get)}
152
+ aria-label=${!this.closed || this._isClosing ? this.label || nothing : nothing}
147
153
  >
148
- <div class="wrapper">
149
- ${__privateMethod(this, _renderIcon, renderIcon_fn).call(this)} ${__privateMethod(this, _renderMessage, renderMessage_fn).call(this)}
150
- </div>
151
- ${!this.timeout && this.buttonLabel ? __privateMethod(this, _renderActionButton, renderActionButton_fn).call(this, this.buttonLabel) : nothing}
152
- ${__privateMethod(this, _renderCloseButton, renderCloseButton_fn).call(this)} ${__privateMethod(this, _renderProgressBar, renderProgressBar_fn).call(this)}
153
- </gds-card>
154
+ ${!this.closed || this._isClosing ? html`
155
+ <gds-card
156
+ ${ref(__privateGet(this, _alertRef))}
157
+ border=${`5xs solid ${__privateGet(this, _config, config_get).border}`}
158
+ background=${__privateGet(this, _config, config_get).background}
159
+ color=${__privateGet(this, _config, config_get).color}
160
+ class=${classMap(classes)}
161
+ @keydown=${__privateMethod(this, _handleKeyDown, handleKeyDown_fn)}
162
+ id="alert-message"
163
+ padding="m"
164
+ >
165
+ <div class="wrapper">
166
+ ${__privateMethod(this, _renderIcon, renderIcon_fn).call(this)} ${__privateMethod(this, _renderMessage, renderMessage_fn).call(this)}
167
+ </div>
168
+ ${!this.timeout && this.buttonLabel ? __privateMethod(this, _renderActionButton, renderActionButton_fn).call(this, this.buttonLabel) : nothing}
169
+ ${__privateMethod(this, _renderCloseButton, renderCloseButton_fn).call(this)} ${__privateMethod(this, _renderProgressBar, renderProgressBar_fn).call(this)}
170
+ </gds-card>
171
+ ` : nothing}
172
+ </div>
154
173
  `;
155
174
  }
156
175
  };
@@ -158,7 +177,6 @@ _timeoutId = new WeakMap();
158
177
  _progressIntervalId = new WeakMap();
159
178
  _alertRef = new WeakMap();
160
179
  _observer = new WeakMap();
161
- _isVisible = new WeakMap();
162
180
  _remaining = new WeakMap();
163
181
  _lastTick = new WeakMap();
164
182
  _timerController = new WeakMap();
@@ -173,11 +191,9 @@ setupObserver_fn = function() {
173
191
  const entry = entries[0];
174
192
  const ratio = entry?.intersectionRatio ?? 0;
175
193
  const nowVisible = ratio >= 0.1;
176
- if (nowVisible && !__privateGet(this, _isVisible)) {
177
- __privateSet(this, _isVisible, true);
194
+ if (nowVisible) {
178
195
  __privateMethod(this, _resumeTimer, resumeTimer_fn).call(this);
179
- } else if (!nowVisible && __privateGet(this, _isVisible)) {
180
- __privateSet(this, _isVisible, false);
196
+ } else {
181
197
  __privateMethod(this, _pauseTimer, pauseTimer_fn).call(this);
182
198
  }
183
199
  },
@@ -194,7 +210,6 @@ disconnectObserver_fn = function() {
194
210
  __privateGet(this, _observer).disconnect();
195
211
  __privateSet(this, _observer, void 0);
196
212
  }
197
- __privateSet(this, _isVisible, false);
198
213
  };
199
214
  _startTicking = new WeakSet();
200
215
  startTicking_fn = function() {
@@ -228,7 +243,11 @@ clearTimers_fn = function() {
228
243
  };
229
244
  _dismiss = new WeakSet();
230
245
  dismiss_fn = async function(source) {
246
+ if (this.closed || this._isClosing)
247
+ return;
231
248
  this._isClosing = true;
249
+ this.closed = true;
250
+ __privateMethod(this, _dispatchUiStateEvent, dispatchUiStateEvent_fn).call(this, source);
232
251
  __privateMethod(this, _disconnectObserver, disconnectObserver_fn).call(this);
233
252
  __privateMethod(this, _clearTimers, clearTimers_fn).call(this);
234
253
  await this.updateComplete;
@@ -238,7 +257,23 @@ dismiss_fn = async function(source) {
238
257
  composed: true
239
258
  });
240
259
  await new Promise((r) => setTimeout(r, FADE_DURATION));
241
- this._cardHidden = true;
260
+ this._isClosing = false;
261
+ };
262
+ _dispatchUiStateEvent = new WeakSet();
263
+ dispatchUiStateEvent_fn = function(reason) {
264
+ this.dispatchCustomEvent("gds-ui-state", {
265
+ detail: { closed: this.closed, open: !this.closed, reason },
266
+ bubbles: false,
267
+ composed: false
268
+ });
269
+ };
270
+ _consumeDeprecatedRoleAttribute = new WeakSet();
271
+ consumeDeprecatedRoleAttribute_fn = function() {
272
+ const role = this.getAttribute("role");
273
+ if (role === "alert" || role === "status") {
274
+ this.removeAttribute("role");
275
+ this.role = role;
276
+ }
242
277
  };
243
278
  _handleButtonClick = new WeakSet();
244
279
  handleButtonClick_fn = function(e) {
@@ -259,6 +294,10 @@ _config = new WeakSet();
259
294
  config_get = function() {
260
295
  return VARIANT_CONFIG[this.variant];
261
296
  };
297
+ _effectiveRole = new WeakSet();
298
+ effectiveRole_get = function() {
299
+ return this.alertRole ?? this.role ?? "alert";
300
+ };
262
301
  _renderIcon = new WeakSet();
263
302
  renderIcon_fn = function() {
264
303
  const icon = `gds-icon-${__privateGet(this, _config, config_get).icon}`;
@@ -320,6 +359,7 @@ renderProgressBar_fn = function() {
320
359
  ` : nothing;
321
360
  };
322
361
  GdsAlert.styles = [tokens, AlertStyles];
362
+ GdsAlert.styleExpressionBaseSelector = "#alert-message";
323
363
  __decorateClass([
324
364
  property({ type: String, reflect: true })
325
365
  ], GdsAlert.prototype, "variant", 2);
@@ -327,8 +367,14 @@ __decorateClass([
327
367
  property({ type: String })
328
368
  ], GdsAlert.prototype, "label", 2);
329
369
  __decorateClass([
330
- property({ type: String, reflect: true })
370
+ property({ attribute: "alert-role" })
371
+ ], GdsAlert.prototype, "alertRole", 2);
372
+ __decorateClass([
373
+ property({ type: String })
331
374
  ], GdsAlert.prototype, "role", 2);
375
+ __decorateClass([
376
+ property({ type: Boolean, reflect: true })
377
+ ], GdsAlert.prototype, "closed", 2);
332
378
  __decorateClass([
333
379
  property({ type: Boolean })
334
380
  ], GdsAlert.prototype, "dismissible", 2);
@@ -344,9 +390,6 @@ __decorateClass([
344
390
  __decorateClass([
345
391
  state()
346
392
  ], GdsAlert.prototype, "_isClosing", 2);
347
- __decorateClass([
348
- state()
349
- ], GdsAlert.prototype, "_cardHidden", 2);
350
393
  GdsAlert = __decorateClass([
351
394
  gdsCustomElement("gds-alert", {
352
395
  dependsOn: [
@@ -359,8 +402,8 @@ GdsAlert = __decorateClass([
359
402
  ]
360
403
  }),
361
404
  ariaForwarding({
362
- labelledBy: '[role="alert"]',
363
- describedBy: '[role="alert"]'
405
+ labelledBy: "#alert-region",
406
+ describedBy: "#alert-region"
364
407
  }),
365
408
  localized()
366
409
  ], GdsAlert);
@@ -348,6 +348,7 @@ GdsDialog = __decorateClass([
348
348
  dependsOn: [GdsButton, GdsCard, GdsDiv, GdsFlex, IconCrossLarge]
349
349
  }),
350
350
  ariaForwarding({
351
+ label: "dialog",
351
352
  labelledBy: "dialog",
352
353
  describedBy: "dialog"
353
354
  }),
@@ -1,13 +1,6 @@
1
1
  /**
2
2
  * Based on https://github.com/shoelace-style/shoelace/blob/next/src/internal/scroll.ts
3
+ *
4
+ * Re-exported from shared utils so both dialog and spinner can use the same scroll lock.
3
5
  */
4
- export declare function registerGlobalScrollLockStyles(): void;
5
- /**
6
- * Prevents body scrolling. Keeps track of which elements requested a lock so multiple levels of locking are possible
7
- * without premature unlocking.
8
- */
9
- export declare function lockBodyScrolling(lockingEl: HTMLElement): void;
10
- /**
11
- * Unlocks body scrolling. Scrolling will only be unlocked once all elements that requested a lock call this method.
12
- */
13
- export declare function unlockBodyScrolling(lockingEl: HTMLElement): void;
6
+ export { lockBodyScrolling, registerGlobalScrollLockStyles, unlockBodyScrolling, } from '../../utils/scroll-lock';
@@ -1,62 +1,9 @@
1
1
  import "../../chunks/chunk.CAV4X6PU.js";
2
- import { css } from "lit";
3
- import { GlobalStylesRegistry } from "../../utils/global-styles.js";
4
- const locks = /* @__PURE__ */ new Set();
5
- function registerGlobalScrollLockStyles() {
6
- GlobalStylesRegistry.instance.injectGlobalStyles(
7
- "dialog-scroll-lock",
8
- css`
9
- .gds-scroll-lock body {
10
- padding-right: var(--gds-scroll-lock-size) !important;
11
- overflow: hidden !important;
12
- }
13
- `
14
- );
15
- }
16
- function lockBodyScrolling(lockingEl) {
17
- locks.add(lockingEl);
18
- if (!document.documentElement.classList.contains("gds-scroll-lock")) {
19
- const scrollbarWidth = getScrollbarWidth() + getExistingBodyPadding();
20
- let scrollbarGutterProperty = getComputedStyle(
21
- document.documentElement
22
- ).scrollbarGutter;
23
- if (!scrollbarGutterProperty || scrollbarGutterProperty === "auto") {
24
- scrollbarGutterProperty = "stable";
25
- }
26
- if (scrollbarWidth < 2) {
27
- scrollbarGutterProperty = "";
28
- }
29
- document.documentElement.style.setProperty(
30
- "--gds-scroll-lock-gutter",
31
- scrollbarGutterProperty
32
- );
33
- document.documentElement.classList.add("gds-scroll-lock");
34
- document.documentElement.style.setProperty(
35
- "--gds-scroll-lock-size",
36
- `${scrollbarWidth}px`
37
- );
38
- }
39
- }
40
- function unlockBodyScrolling(lockingEl) {
41
- locks.delete(lockingEl);
42
- if (locks.size === 0) {
43
- document.documentElement.classList.remove("gds-scroll-lock");
44
- document.documentElement.style.removeProperty("--gds-scroll-lock-size");
45
- }
46
- }
47
- function getScrollbarWidth() {
48
- const documentWidth = document.documentElement.clientWidth;
49
- return Math.abs(window.innerWidth - documentWidth);
50
- }
51
- function getExistingBodyPadding() {
52
- const padding = Number(
53
- getComputedStyle(document.body).paddingRight.replace(/px/, "")
54
- );
55
- if (isNaN(padding) || !padding) {
56
- return 0;
57
- }
58
- return padding;
59
- }
2
+ import {
3
+ lockBodyScrolling,
4
+ registerGlobalScrollLockStyles,
5
+ unlockBodyScrolling
6
+ } from "../../utils/scroll-lock.js";
60
7
  export {
61
8
  lockBodyScrolling,
62
9
  registerGlobalScrollLockStyles,
@@ -2,7 +2,7 @@ import "../../chunks/chunk.CAV4X6PU.js";
2
2
  const ICON_REPLACEMENTS = {
3
3
  // seb: 'gds-icon-brand-seb',
4
4
  };
5
- const DEPRECATED_NAMES = [];
5
+ const DEPRECATED_NAMES = ["filter"];
6
6
  const deprecatedIcons = Object.fromEntries([
7
7
  ...Object.entries(ICON_REPLACEMENTS).map(([name, replacement]) => [
8
8
  `gds-icon-${name}`,
@@ -1,6 +1,7 @@
1
1
  import { GdsIcon } from '../icon';
2
2
  /**
3
3
  * @element gds-icon-filter
4
+ * @deprecated This icon is deprecated
4
5
  */
5
6
  export declare class IconFilter extends GdsIcon {
6
7
  /** @private */
@@ -45,10 +45,8 @@ export declare class GdsSpinner extends GdsSpinner_base {
45
45
  * Sets up accessibility attributes and initializes the spinner
46
46
  */
47
47
  connectedCallback(): void;
48
- /**
49
- * Cleans up document styles if fullscreen mode was used
50
- */
51
48
  disconnectedCallback(): void;
49
+ private _handleFullscreenChange;
52
50
  /**
53
51
  * Updates the aria-label attribute based on the label property
54
52
  */
@@ -57,11 +55,6 @@ export declare class GdsSpinner extends GdsSpinner_base {
57
55
  * Renders the spinner component
58
56
  */
59
57
  protected render(): any;
60
- /**
61
- * Toggles document root styles when in fullscreen mode
62
- * Prevents scrolling of the document when fullscreen overlay is active
63
- */
64
- private _toggleRootStyles;
65
58
  }
66
59
  declare global {
67
60
  interface HTMLElementTagNameMap {
@@ -2,11 +2,11 @@ import {
2
2
  __decorateClass,
3
3
  __privateAdd,
4
4
  __privateGet,
5
- __privateMethod
5
+ __privateMethod,
6
+ __privateSet
6
7
  } from "../../chunks/chunk.CAV4X6PU.js";
7
- var _fullscreenStyles, _getWrapperClasses, getWrapperClasses_fn;
8
+ var _getWrapperClasses, getWrapperClasses_fn, _didLockScroll, _lockScroll, lockScroll_fn, _unlockScroll, unlockScroll_fn;
8
9
  import { localized, msg } from "@lit/localize";
9
- import { css } from "lit";
10
10
  import { property, state } from "lit/decorators.js";
11
11
  import { classMap } from "lit/directives/class-map.js";
12
12
  import { when } from "lit/directives/when.js";
@@ -14,13 +14,18 @@ import { GdsElement } from "../../gds-element.js";
14
14
  import { gdsCustomElement, html } from "../../scoping.js";
15
15
  import { tokens } from "../../tokens.style.js";
16
16
  import { watch } from "../../utils/decorators/watch.js";
17
- import { GlobalStylesRegistry } from "../../utils/global-styles.js";
18
17
  import {
19
18
  withLayoutChildProps,
20
19
  withMarginProps,
21
20
  withPositioningProps
22
21
  } from "../../utils/mixins/declarative-layout-mixins.js";
22
+ import {
23
+ lockBodyScrolling,
24
+ registerGlobalScrollLockStyles,
25
+ unlockBodyScrolling
26
+ } from "../../utils/scroll-lock.js";
23
27
  import styles from "./spinner.styles.js";
28
+ registerGlobalScrollLockStyles();
24
29
  let GdsSpinner = class extends withMarginProps(
25
30
  withPositioningProps(withLayoutChildProps(GdsElement))
26
31
  ) {
@@ -30,15 +35,8 @@ let GdsSpinner = class extends withMarginProps(
30
35
  * Generates CSS classes for the wrapper element based on component state
31
36
  */
32
37
  __privateAdd(this, _getWrapperClasses);
33
- /**
34
- * Global styles for fullscreen mode
35
- */
36
- __privateAdd(this, _fullscreenStyles, css`
37
- html {
38
- overflow: hidden !important;
39
- overscroll-behavior: none !important;
40
- }
41
- `);
38
+ __privateAdd(this, _lockScroll);
39
+ __privateAdd(this, _unlockScroll);
42
40
  this.label = msg("Loading...");
43
41
  this.labelPosition = "bottom";
44
42
  this.showLabel = false;
@@ -46,6 +44,7 @@ let GdsSpinner = class extends withMarginProps(
46
44
  this.fullscreen = false;
47
45
  this.size = "md";
48
46
  this._isAnimating = false;
47
+ __privateAdd(this, _didLockScroll, false);
49
48
  }
50
49
  /**
51
50
  * Sets up accessibility attributes and initializes the spinner
@@ -55,18 +54,20 @@ let GdsSpinner = class extends withMarginProps(
55
54
  this.setAttribute("role", "status");
56
55
  this.setAttribute("aria-live", "polite");
57
56
  this._isAnimating = true;
57
+ if (this.fullscreen)
58
+ __privateMethod(this, _lockScroll, lockScroll_fn).call(this);
58
59
  this.dispatchCustomEvent("gds-spinner-connected");
59
60
  }
60
- /**
61
- * Cleans up document styles if fullscreen mode was used
62
- */
63
61
  disconnectedCallback() {
64
62
  super.disconnectedCallback();
65
- if (this.fullscreen) {
66
- this.fullscreen = false;
67
- this._toggleRootStyles();
68
- }
69
63
  this._isAnimating = false;
64
+ __privateMethod(this, _unlockScroll, unlockScroll_fn).call(this);
65
+ }
66
+ _handleFullscreenChange() {
67
+ if (this.fullscreen)
68
+ __privateMethod(this, _lockScroll, lockScroll_fn).call(this);
69
+ else
70
+ __privateMethod(this, _unlockScroll, unlockScroll_fn).call(this);
70
71
  }
71
72
  _updateAriaLabel() {
72
73
  this.setAttribute("aria-label", this.label);
@@ -85,17 +86,7 @@ let GdsSpinner = class extends withMarginProps(
85
86
  </div>
86
87
  `;
87
88
  }
88
- _toggleRootStyles() {
89
- const registry = GlobalStylesRegistry.instance;
90
- const key = `gds-spinner-fullscreen-${this.id || "default"}`;
91
- if (this.fullscreen) {
92
- registry.injectGlobalStyles(key, __privateGet(this, _fullscreenStyles));
93
- } else {
94
- registry.clearGlobalStyles(key);
95
- }
96
- }
97
89
  };
98
- _fullscreenStyles = new WeakMap();
99
90
  _getWrapperClasses = new WeakSet();
100
91
  getWrapperClasses_fn = function() {
101
92
  return {
@@ -107,6 +98,21 @@ getWrapperClasses_fn = function() {
107
98
  [`spinner-label-${this.labelPosition}`]: this.labelPosition
108
99
  };
109
100
  };
101
+ _didLockScroll = new WeakMap();
102
+ _lockScroll = new WeakSet();
103
+ lockScroll_fn = function() {
104
+ if (__privateGet(this, _didLockScroll))
105
+ return;
106
+ lockBodyScrolling(this);
107
+ __privateSet(this, _didLockScroll, true);
108
+ };
109
+ _unlockScroll = new WeakSet();
110
+ unlockScroll_fn = function() {
111
+ if (!__privateGet(this, _didLockScroll))
112
+ return;
113
+ unlockBodyScrolling(this);
114
+ __privateSet(this, _didLockScroll, false);
115
+ };
110
116
  /** All styles are defined in the external styles file */
111
117
  GdsSpinner.styles = [tokens, styles];
112
118
  __decorateClass([
@@ -130,12 +136,12 @@ __decorateClass([
130
136
  __decorateClass([
131
137
  state()
132
138
  ], GdsSpinner.prototype, "_isAnimating", 2);
139
+ __decorateClass([
140
+ watch("fullscreen")
141
+ ], GdsSpinner.prototype, "_handleFullscreenChange", 1);
133
142
  __decorateClass([
134
143
  watch("label")
135
144
  ], GdsSpinner.prototype, "_updateAriaLabel", 1);
136
- __decorateClass([
137
- watch("fullscreen")
138
- ], GdsSpinner.prototype, "_toggleRootStyles", 1);
139
145
  GdsSpinner = __decorateClass([
140
146
  gdsCustomElement("gds-spinner"),
141
147
  localized()