myio-js-library 0.1.261 → 0.1.263

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -26378,9 +26378,43 @@ var WelcomeModalView = class {
26378
26378
  userEmailEl.textContent = this.params.userInfo.email;
26379
26379
  return;
26380
26380
  }
26381
+ const getToken = () => {
26382
+ const tokenKeys = ["jwt_token", "access_token", "authToken", "tb_token"];
26383
+ for (const key of tokenKeys) {
26384
+ const token = localStorage.getItem(key);
26385
+ if (token) return token;
26386
+ }
26387
+ for (const key of tokenKeys) {
26388
+ const token = sessionStorage.getItem(key);
26389
+ if (token) return token;
26390
+ }
26391
+ const win = window;
26392
+ if (win.AuthService?.jwtToken) return win.AuthService.jwtToken;
26393
+ const cookies = document.cookie.split(";");
26394
+ for (const cookie of cookies) {
26395
+ const [name, value] = cookie.trim().split("=");
26396
+ if (tokenKeys.includes(name)) return value;
26397
+ }
26398
+ return null;
26399
+ };
26381
26400
  try {
26382
- const token = localStorage.getItem("jwt_token");
26401
+ const token = getToken();
26383
26402
  if (!token) {
26403
+ const ctx = this.params.ctx;
26404
+ if (ctx?.currentUser) {
26405
+ const user = ctx.currentUser;
26406
+ const fullName = [user.firstName, user.lastName].filter(Boolean).join(" ") || user.name || "Usu\xE1rio";
26407
+ userNameEl.textContent = fullName;
26408
+ userEmailEl.textContent = user.email || "";
26409
+ return;
26410
+ }
26411
+ const tbUser = window.tb_user;
26412
+ if (tbUser) {
26413
+ const fullName = [tbUser.firstName, tbUser.lastName].filter(Boolean).join(" ") || tbUser.name || "Usu\xE1rio";
26414
+ userNameEl.textContent = fullName;
26415
+ userEmailEl.textContent = tbUser.email || "";
26416
+ return;
26417
+ }
26384
26418
  userNameEl.textContent = "Usu\xE1rio";
26385
26419
  userEmailEl.textContent = "";
26386
26420
  return;
@@ -26414,6 +26448,124 @@ var WelcomeModalView = class {
26414
26448
  if (userNameEl) userNameEl.textContent = info.fullName;
26415
26449
  if (userEmailEl) userEmailEl.textContent = info.email;
26416
26450
  }
26451
+ /**
26452
+ * Update shopping cards after data loads (RFC-0111: loading state support)
26453
+ */
26454
+ updateShoppingCards(cards) {
26455
+ this.params.shoppingCards = cards;
26456
+ let shortcutsSection = this.container.querySelector(".myio-welcome-shortcuts");
26457
+ const modalContainer = this.container.querySelector(".myio-welcome-modal-container");
26458
+ if (cards.length === 0) {
26459
+ if (shortcutsSection) {
26460
+ shortcutsSection.remove();
26461
+ }
26462
+ return;
26463
+ }
26464
+ const shortcutsTitle = this.params.shortcutsTitle ?? this.config.defaultShortcutsTitle ?? "Acesso R\xE1pido aos Shoppings";
26465
+ const themeConfig = this.getThemeConfig();
26466
+ const shortcutsTitleColor = themeConfig.shortcutsTitleColor ?? themeConfig.mutedTextColor;
26467
+ if (!shortcutsSection && modalContainer) {
26468
+ shortcutsSection = document.createElement("div");
26469
+ shortcutsSection.className = "myio-welcome-shortcuts";
26470
+ modalContainer.appendChild(shortcutsSection);
26471
+ }
26472
+ if (shortcutsSection) {
26473
+ shortcutsSection.innerHTML = `
26474
+ <h2 class="myio-welcome-shortcuts-title"${shortcutsTitleColor ? ` style="color: ${shortcutsTitleColor}"` : ""}>${shortcutsTitle}</h2>
26475
+ <div class="myio-welcome-cards-grid" id="welcomeCardsGrid">
26476
+ ${cards.map((card, index) => this.buildCardHTML(card, index)).join("")}
26477
+ </div>
26478
+ `;
26479
+ this.bindCardEvents();
26480
+ this.setupLazyLoading();
26481
+ }
26482
+ if (this.config.enableDebugMode) {
26483
+ console.log("[WelcomeModal] Shopping cards updated:", cards.length);
26484
+ }
26485
+ }
26486
+ /**
26487
+ * Bind events for shopping cards (used after dynamic update)
26488
+ */
26489
+ bindCardEvents() {
26490
+ const cards = this.container.querySelectorAll(".myio-welcome-card");
26491
+ cards.forEach((card, index) => {
26492
+ const shoppingCard = this.params.shoppingCards?.[index];
26493
+ if (!shoppingCard) return;
26494
+ card.addEventListener("click", (e) => {
26495
+ const target = e.target;
26496
+ if (target.closest(".myio-welcome-card-device-count")) {
26497
+ return;
26498
+ }
26499
+ this.emit("card-click", shoppingCard);
26500
+ });
26501
+ card.addEventListener("keydown", (e) => {
26502
+ const keyEvent = e;
26503
+ if (keyEvent.key === "Enter" || keyEvent.key === " ") {
26504
+ e.preventDefault();
26505
+ this.emit("card-click", shoppingCard);
26506
+ }
26507
+ });
26508
+ });
26509
+ this.bindTooltipEvents();
26510
+ }
26511
+ /**
26512
+ * Set CTA button label
26513
+ */
26514
+ setCtaLabel(label) {
26515
+ const ctaBtn = this.container.querySelector("#welcomeCtaBtn");
26516
+ if (ctaBtn) {
26517
+ const svgIcon = ctaBtn.querySelector("svg");
26518
+ ctaBtn.textContent = "";
26519
+ ctaBtn.appendChild(document.createTextNode(label + " "));
26520
+ if (svgIcon) {
26521
+ ctaBtn.appendChild(svgIcon);
26522
+ } else {
26523
+ const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
26524
+ svg.setAttribute("viewBox", "0 0 24 24");
26525
+ svg.setAttribute("fill", "none");
26526
+ svg.setAttribute("stroke", "currentColor");
26527
+ svg.setAttribute("stroke-width", "2");
26528
+ svg.setAttribute("stroke-linecap", "round");
26529
+ svg.setAttribute("stroke-linejoin", "round");
26530
+ svg.innerHTML = '<line x1="5" y1="12" x2="19" y2="12" /><polyline points="12 5 19 12 12 19" />';
26531
+ ctaBtn.appendChild(svg);
26532
+ }
26533
+ }
26534
+ }
26535
+ /**
26536
+ * Set CTA button disabled state
26537
+ */
26538
+ setCtaDisabled(disabled) {
26539
+ const ctaBtn = this.container.querySelector("#welcomeCtaBtn");
26540
+ if (ctaBtn) {
26541
+ ctaBtn.disabled = disabled;
26542
+ ctaBtn.style.opacity = disabled ? "0.5" : "1";
26543
+ ctaBtn.style.cursor = disabled ? "not-allowed" : "pointer";
26544
+ }
26545
+ }
26546
+ /**
26547
+ * Show the modal (after it was hidden)
26548
+ */
26549
+ show() {
26550
+ this.container.style.display = "flex";
26551
+ this.container.style.opacity = "0";
26552
+ requestAnimationFrame(() => {
26553
+ this.container.style.opacity = "1";
26554
+ this.container.style.transition = "opacity 0.3s ease";
26555
+ });
26556
+ document.body.style.overflow = "hidden";
26557
+ }
26558
+ /**
26559
+ * Hide the modal (without destroying it)
26560
+ */
26561
+ hide() {
26562
+ this.container.style.opacity = "0";
26563
+ this.container.style.transition = "opacity 0.3s ease";
26564
+ setTimeout(() => {
26565
+ this.container.style.display = "none";
26566
+ document.body.style.overflow = "";
26567
+ }, 300);
26568
+ }
26417
26569
  /**
26418
26570
  * Cleanup resources
26419
26571
  */
@@ -26534,8 +26686,15 @@ function openWelcomeModal(params) {
26534
26686
  element.style.opacity = "1";
26535
26687
  element.style.transition = "opacity 0.3s ease";
26536
26688
  });
26689
+ function open() {
26690
+ if (!element.parentNode) {
26691
+ document.body.appendChild(element);
26692
+ }
26693
+ view.show();
26694
+ }
26537
26695
  return {
26538
26696
  close,
26697
+ open,
26539
26698
  element,
26540
26699
  on: (event, handler) => {
26541
26700
  if (event === "close") {
@@ -26545,7 +26704,15 @@ function openWelcomeModal(params) {
26545
26704
  /** Set the theme mode from outside (e.g., from MAIN component) */
26546
26705
  setThemeMode: (mode) => view.setThemeMode(mode),
26547
26706
  /** Get the current theme mode */
26548
- getThemeMode: () => view.getThemeMode()
26707
+ getThemeMode: () => view.getThemeMode(),
26708
+ /** Update shopping cards after data loads (RFC-0111: loading state) */
26709
+ updateShoppingCards: (cards) => view.updateShoppingCards(cards),
26710
+ /** Update user info display */
26711
+ updateUserInfo: (info) => view.updateUserInfo(info),
26712
+ /** Set CTA button label */
26713
+ setCtaLabel: (label) => view.setCtaLabel(label),
26714
+ /** Set CTA button disabled state */
26715
+ setCtaDisabled: (disabled) => view.setCtaDisabled(disabled)
26549
26716
  };
26550
26717
  }
26551
26718
 
package/dist/index.d.cts CHANGED
@@ -2788,6 +2788,8 @@ interface WelcomeModalParams {
2788
2788
  interface WelcomeModalInstance {
2789
2789
  /** Close the modal programmatically */
2790
2790
  close: () => void;
2791
+ /** Open/show the modal again after it was closed */
2792
+ open: () => void;
2791
2793
  /** The modal's root DOM element */
2792
2794
  element: HTMLElement;
2793
2795
  /** Register event handlers */
@@ -2796,6 +2798,14 @@ interface WelcomeModalInstance {
2796
2798
  setThemeMode: (mode: WelcomeThemeMode) => void;
2797
2799
  /** Get the current theme mode */
2798
2800
  getThemeMode: () => WelcomeThemeMode;
2801
+ /** Update shopping cards after data loads (RFC-0111: loading state) */
2802
+ updateShoppingCards: (cards: ShoppingCard[]) => void;
2803
+ /** Update user info display */
2804
+ updateUserInfo: (info: UserInfo$1) => void;
2805
+ /** Set CTA button label */
2806
+ setCtaLabel: (label: string) => void;
2807
+ /** Set CTA button disabled state */
2808
+ setCtaDisabled: (disabled: boolean) => void;
2799
2809
  }
2800
2810
  /**
2801
2811
  * Default palette values
package/dist/index.js CHANGED
@@ -26161,9 +26161,43 @@ var WelcomeModalView = class {
26161
26161
  userEmailEl.textContent = this.params.userInfo.email;
26162
26162
  return;
26163
26163
  }
26164
+ const getToken = () => {
26165
+ const tokenKeys = ["jwt_token", "access_token", "authToken", "tb_token"];
26166
+ for (const key of tokenKeys) {
26167
+ const token = localStorage.getItem(key);
26168
+ if (token) return token;
26169
+ }
26170
+ for (const key of tokenKeys) {
26171
+ const token = sessionStorage.getItem(key);
26172
+ if (token) return token;
26173
+ }
26174
+ const win = window;
26175
+ if (win.AuthService?.jwtToken) return win.AuthService.jwtToken;
26176
+ const cookies = document.cookie.split(";");
26177
+ for (const cookie of cookies) {
26178
+ const [name, value] = cookie.trim().split("=");
26179
+ if (tokenKeys.includes(name)) return value;
26180
+ }
26181
+ return null;
26182
+ };
26164
26183
  try {
26165
- const token = localStorage.getItem("jwt_token");
26184
+ const token = getToken();
26166
26185
  if (!token) {
26186
+ const ctx = this.params.ctx;
26187
+ if (ctx?.currentUser) {
26188
+ const user = ctx.currentUser;
26189
+ const fullName = [user.firstName, user.lastName].filter(Boolean).join(" ") || user.name || "Usu\xE1rio";
26190
+ userNameEl.textContent = fullName;
26191
+ userEmailEl.textContent = user.email || "";
26192
+ return;
26193
+ }
26194
+ const tbUser = window.tb_user;
26195
+ if (tbUser) {
26196
+ const fullName = [tbUser.firstName, tbUser.lastName].filter(Boolean).join(" ") || tbUser.name || "Usu\xE1rio";
26197
+ userNameEl.textContent = fullName;
26198
+ userEmailEl.textContent = tbUser.email || "";
26199
+ return;
26200
+ }
26167
26201
  userNameEl.textContent = "Usu\xE1rio";
26168
26202
  userEmailEl.textContent = "";
26169
26203
  return;
@@ -26197,6 +26231,124 @@ var WelcomeModalView = class {
26197
26231
  if (userNameEl) userNameEl.textContent = info.fullName;
26198
26232
  if (userEmailEl) userEmailEl.textContent = info.email;
26199
26233
  }
26234
+ /**
26235
+ * Update shopping cards after data loads (RFC-0111: loading state support)
26236
+ */
26237
+ updateShoppingCards(cards) {
26238
+ this.params.shoppingCards = cards;
26239
+ let shortcutsSection = this.container.querySelector(".myio-welcome-shortcuts");
26240
+ const modalContainer = this.container.querySelector(".myio-welcome-modal-container");
26241
+ if (cards.length === 0) {
26242
+ if (shortcutsSection) {
26243
+ shortcutsSection.remove();
26244
+ }
26245
+ return;
26246
+ }
26247
+ const shortcutsTitle = this.params.shortcutsTitle ?? this.config.defaultShortcutsTitle ?? "Acesso R\xE1pido aos Shoppings";
26248
+ const themeConfig = this.getThemeConfig();
26249
+ const shortcutsTitleColor = themeConfig.shortcutsTitleColor ?? themeConfig.mutedTextColor;
26250
+ if (!shortcutsSection && modalContainer) {
26251
+ shortcutsSection = document.createElement("div");
26252
+ shortcutsSection.className = "myio-welcome-shortcuts";
26253
+ modalContainer.appendChild(shortcutsSection);
26254
+ }
26255
+ if (shortcutsSection) {
26256
+ shortcutsSection.innerHTML = `
26257
+ <h2 class="myio-welcome-shortcuts-title"${shortcutsTitleColor ? ` style="color: ${shortcutsTitleColor}"` : ""}>${shortcutsTitle}</h2>
26258
+ <div class="myio-welcome-cards-grid" id="welcomeCardsGrid">
26259
+ ${cards.map((card, index) => this.buildCardHTML(card, index)).join("")}
26260
+ </div>
26261
+ `;
26262
+ this.bindCardEvents();
26263
+ this.setupLazyLoading();
26264
+ }
26265
+ if (this.config.enableDebugMode) {
26266
+ console.log("[WelcomeModal] Shopping cards updated:", cards.length);
26267
+ }
26268
+ }
26269
+ /**
26270
+ * Bind events for shopping cards (used after dynamic update)
26271
+ */
26272
+ bindCardEvents() {
26273
+ const cards = this.container.querySelectorAll(".myio-welcome-card");
26274
+ cards.forEach((card, index) => {
26275
+ const shoppingCard = this.params.shoppingCards?.[index];
26276
+ if (!shoppingCard) return;
26277
+ card.addEventListener("click", (e) => {
26278
+ const target = e.target;
26279
+ if (target.closest(".myio-welcome-card-device-count")) {
26280
+ return;
26281
+ }
26282
+ this.emit("card-click", shoppingCard);
26283
+ });
26284
+ card.addEventListener("keydown", (e) => {
26285
+ const keyEvent = e;
26286
+ if (keyEvent.key === "Enter" || keyEvent.key === " ") {
26287
+ e.preventDefault();
26288
+ this.emit("card-click", shoppingCard);
26289
+ }
26290
+ });
26291
+ });
26292
+ this.bindTooltipEvents();
26293
+ }
26294
+ /**
26295
+ * Set CTA button label
26296
+ */
26297
+ setCtaLabel(label) {
26298
+ const ctaBtn = this.container.querySelector("#welcomeCtaBtn");
26299
+ if (ctaBtn) {
26300
+ const svgIcon = ctaBtn.querySelector("svg");
26301
+ ctaBtn.textContent = "";
26302
+ ctaBtn.appendChild(document.createTextNode(label + " "));
26303
+ if (svgIcon) {
26304
+ ctaBtn.appendChild(svgIcon);
26305
+ } else {
26306
+ const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
26307
+ svg.setAttribute("viewBox", "0 0 24 24");
26308
+ svg.setAttribute("fill", "none");
26309
+ svg.setAttribute("stroke", "currentColor");
26310
+ svg.setAttribute("stroke-width", "2");
26311
+ svg.setAttribute("stroke-linecap", "round");
26312
+ svg.setAttribute("stroke-linejoin", "round");
26313
+ svg.innerHTML = '<line x1="5" y1="12" x2="19" y2="12" /><polyline points="12 5 19 12 12 19" />';
26314
+ ctaBtn.appendChild(svg);
26315
+ }
26316
+ }
26317
+ }
26318
+ /**
26319
+ * Set CTA button disabled state
26320
+ */
26321
+ setCtaDisabled(disabled) {
26322
+ const ctaBtn = this.container.querySelector("#welcomeCtaBtn");
26323
+ if (ctaBtn) {
26324
+ ctaBtn.disabled = disabled;
26325
+ ctaBtn.style.opacity = disabled ? "0.5" : "1";
26326
+ ctaBtn.style.cursor = disabled ? "not-allowed" : "pointer";
26327
+ }
26328
+ }
26329
+ /**
26330
+ * Show the modal (after it was hidden)
26331
+ */
26332
+ show() {
26333
+ this.container.style.display = "flex";
26334
+ this.container.style.opacity = "0";
26335
+ requestAnimationFrame(() => {
26336
+ this.container.style.opacity = "1";
26337
+ this.container.style.transition = "opacity 0.3s ease";
26338
+ });
26339
+ document.body.style.overflow = "hidden";
26340
+ }
26341
+ /**
26342
+ * Hide the modal (without destroying it)
26343
+ */
26344
+ hide() {
26345
+ this.container.style.opacity = "0";
26346
+ this.container.style.transition = "opacity 0.3s ease";
26347
+ setTimeout(() => {
26348
+ this.container.style.display = "none";
26349
+ document.body.style.overflow = "";
26350
+ }, 300);
26351
+ }
26200
26352
  /**
26201
26353
  * Cleanup resources
26202
26354
  */
@@ -26317,8 +26469,15 @@ function openWelcomeModal(params) {
26317
26469
  element.style.opacity = "1";
26318
26470
  element.style.transition = "opacity 0.3s ease";
26319
26471
  });
26472
+ function open() {
26473
+ if (!element.parentNode) {
26474
+ document.body.appendChild(element);
26475
+ }
26476
+ view.show();
26477
+ }
26320
26478
  return {
26321
26479
  close,
26480
+ open,
26322
26481
  element,
26323
26482
  on: (event, handler) => {
26324
26483
  if (event === "close") {
@@ -26328,7 +26487,15 @@ function openWelcomeModal(params) {
26328
26487
  /** Set the theme mode from outside (e.g., from MAIN component) */
26329
26488
  setThemeMode: (mode) => view.setThemeMode(mode),
26330
26489
  /** Get the current theme mode */
26331
- getThemeMode: () => view.getThemeMode()
26490
+ getThemeMode: () => view.getThemeMode(),
26491
+ /** Update shopping cards after data loads (RFC-0111: loading state) */
26492
+ updateShoppingCards: (cards) => view.updateShoppingCards(cards),
26493
+ /** Update user info display */
26494
+ updateUserInfo: (info) => view.updateUserInfo(info),
26495
+ /** Set CTA button label */
26496
+ setCtaLabel: (label) => view.setCtaLabel(label),
26497
+ /** Set CTA button disabled state */
26498
+ setCtaDisabled: (disabled) => view.setCtaDisabled(disabled)
26332
26499
  };
26333
26500
  }
26334
26501
 
@@ -25974,9 +25974,43 @@
25974
25974
  userEmailEl.textContent = this.params.userInfo.email;
25975
25975
  return;
25976
25976
  }
25977
+ const getToken = () => {
25978
+ const tokenKeys = ["jwt_token", "access_token", "authToken", "tb_token"];
25979
+ for (const key of tokenKeys) {
25980
+ const token = localStorage.getItem(key);
25981
+ if (token) return token;
25982
+ }
25983
+ for (const key of tokenKeys) {
25984
+ const token = sessionStorage.getItem(key);
25985
+ if (token) return token;
25986
+ }
25987
+ const win = window;
25988
+ if (win.AuthService?.jwtToken) return win.AuthService.jwtToken;
25989
+ const cookies = document.cookie.split(";");
25990
+ for (const cookie of cookies) {
25991
+ const [name, value] = cookie.trim().split("=");
25992
+ if (tokenKeys.includes(name)) return value;
25993
+ }
25994
+ return null;
25995
+ };
25977
25996
  try {
25978
- const token = localStorage.getItem("jwt_token");
25997
+ const token = getToken();
25979
25998
  if (!token) {
25999
+ const ctx = this.params.ctx;
26000
+ if (ctx?.currentUser) {
26001
+ const user = ctx.currentUser;
26002
+ const fullName = [user.firstName, user.lastName].filter(Boolean).join(" ") || user.name || "Usu\xE1rio";
26003
+ userNameEl.textContent = fullName;
26004
+ userEmailEl.textContent = user.email || "";
26005
+ return;
26006
+ }
26007
+ const tbUser = window.tb_user;
26008
+ if (tbUser) {
26009
+ const fullName = [tbUser.firstName, tbUser.lastName].filter(Boolean).join(" ") || tbUser.name || "Usu\xE1rio";
26010
+ userNameEl.textContent = fullName;
26011
+ userEmailEl.textContent = tbUser.email || "";
26012
+ return;
26013
+ }
25980
26014
  userNameEl.textContent = "Usu\xE1rio";
25981
26015
  userEmailEl.textContent = "";
25982
26016
  return;
@@ -26010,6 +26044,124 @@
26010
26044
  if (userNameEl) userNameEl.textContent = info.fullName;
26011
26045
  if (userEmailEl) userEmailEl.textContent = info.email;
26012
26046
  }
26047
+ /**
26048
+ * Update shopping cards after data loads (RFC-0111: loading state support)
26049
+ */
26050
+ updateShoppingCards(cards) {
26051
+ this.params.shoppingCards = cards;
26052
+ let shortcutsSection = this.container.querySelector(".myio-welcome-shortcuts");
26053
+ const modalContainer = this.container.querySelector(".myio-welcome-modal-container");
26054
+ if (cards.length === 0) {
26055
+ if (shortcutsSection) {
26056
+ shortcutsSection.remove();
26057
+ }
26058
+ return;
26059
+ }
26060
+ const shortcutsTitle = this.params.shortcutsTitle ?? this.config.defaultShortcutsTitle ?? "Acesso R\xE1pido aos Shoppings";
26061
+ const themeConfig = this.getThemeConfig();
26062
+ const shortcutsTitleColor = themeConfig.shortcutsTitleColor ?? themeConfig.mutedTextColor;
26063
+ if (!shortcutsSection && modalContainer) {
26064
+ shortcutsSection = document.createElement("div");
26065
+ shortcutsSection.className = "myio-welcome-shortcuts";
26066
+ modalContainer.appendChild(shortcutsSection);
26067
+ }
26068
+ if (shortcutsSection) {
26069
+ shortcutsSection.innerHTML = `
26070
+ <h2 class="myio-welcome-shortcuts-title"${shortcutsTitleColor ? ` style="color: ${shortcutsTitleColor}"` : ""}>${shortcutsTitle}</h2>
26071
+ <div class="myio-welcome-cards-grid" id="welcomeCardsGrid">
26072
+ ${cards.map((card, index) => this.buildCardHTML(card, index)).join("")}
26073
+ </div>
26074
+ `;
26075
+ this.bindCardEvents();
26076
+ this.setupLazyLoading();
26077
+ }
26078
+ if (this.config.enableDebugMode) {
26079
+ console.log("[WelcomeModal] Shopping cards updated:", cards.length);
26080
+ }
26081
+ }
26082
+ /**
26083
+ * Bind events for shopping cards (used after dynamic update)
26084
+ */
26085
+ bindCardEvents() {
26086
+ const cards = this.container.querySelectorAll(".myio-welcome-card");
26087
+ cards.forEach((card, index) => {
26088
+ const shoppingCard = this.params.shoppingCards?.[index];
26089
+ if (!shoppingCard) return;
26090
+ card.addEventListener("click", (e) => {
26091
+ const target = e.target;
26092
+ if (target.closest(".myio-welcome-card-device-count")) {
26093
+ return;
26094
+ }
26095
+ this.emit("card-click", shoppingCard);
26096
+ });
26097
+ card.addEventListener("keydown", (e) => {
26098
+ const keyEvent = e;
26099
+ if (keyEvent.key === "Enter" || keyEvent.key === " ") {
26100
+ e.preventDefault();
26101
+ this.emit("card-click", shoppingCard);
26102
+ }
26103
+ });
26104
+ });
26105
+ this.bindTooltipEvents();
26106
+ }
26107
+ /**
26108
+ * Set CTA button label
26109
+ */
26110
+ setCtaLabel(label) {
26111
+ const ctaBtn = this.container.querySelector("#welcomeCtaBtn");
26112
+ if (ctaBtn) {
26113
+ const svgIcon = ctaBtn.querySelector("svg");
26114
+ ctaBtn.textContent = "";
26115
+ ctaBtn.appendChild(document.createTextNode(label + " "));
26116
+ if (svgIcon) {
26117
+ ctaBtn.appendChild(svgIcon);
26118
+ } else {
26119
+ const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
26120
+ svg.setAttribute("viewBox", "0 0 24 24");
26121
+ svg.setAttribute("fill", "none");
26122
+ svg.setAttribute("stroke", "currentColor");
26123
+ svg.setAttribute("stroke-width", "2");
26124
+ svg.setAttribute("stroke-linecap", "round");
26125
+ svg.setAttribute("stroke-linejoin", "round");
26126
+ svg.innerHTML = '<line x1="5" y1="12" x2="19" y2="12" /><polyline points="12 5 19 12 12 19" />';
26127
+ ctaBtn.appendChild(svg);
26128
+ }
26129
+ }
26130
+ }
26131
+ /**
26132
+ * Set CTA button disabled state
26133
+ */
26134
+ setCtaDisabled(disabled) {
26135
+ const ctaBtn = this.container.querySelector("#welcomeCtaBtn");
26136
+ if (ctaBtn) {
26137
+ ctaBtn.disabled = disabled;
26138
+ ctaBtn.style.opacity = disabled ? "0.5" : "1";
26139
+ ctaBtn.style.cursor = disabled ? "not-allowed" : "pointer";
26140
+ }
26141
+ }
26142
+ /**
26143
+ * Show the modal (after it was hidden)
26144
+ */
26145
+ show() {
26146
+ this.container.style.display = "flex";
26147
+ this.container.style.opacity = "0";
26148
+ requestAnimationFrame(() => {
26149
+ this.container.style.opacity = "1";
26150
+ this.container.style.transition = "opacity 0.3s ease";
26151
+ });
26152
+ document.body.style.overflow = "hidden";
26153
+ }
26154
+ /**
26155
+ * Hide the modal (without destroying it)
26156
+ */
26157
+ hide() {
26158
+ this.container.style.opacity = "0";
26159
+ this.container.style.transition = "opacity 0.3s ease";
26160
+ setTimeout(() => {
26161
+ this.container.style.display = "none";
26162
+ document.body.style.overflow = "";
26163
+ }, 300);
26164
+ }
26013
26165
  /**
26014
26166
  * Cleanup resources
26015
26167
  */
@@ -26130,8 +26282,15 @@
26130
26282
  element.style.opacity = "1";
26131
26283
  element.style.transition = "opacity 0.3s ease";
26132
26284
  });
26285
+ function open() {
26286
+ if (!element.parentNode) {
26287
+ document.body.appendChild(element);
26288
+ }
26289
+ view.show();
26290
+ }
26133
26291
  return {
26134
26292
  close,
26293
+ open,
26135
26294
  element,
26136
26295
  on: (event, handler) => {
26137
26296
  if (event === "close") {
@@ -26141,7 +26300,15 @@
26141
26300
  /** Set the theme mode from outside (e.g., from MAIN component) */
26142
26301
  setThemeMode: (mode) => view.setThemeMode(mode),
26143
26302
  /** Get the current theme mode */
26144
- getThemeMode: () => view.getThemeMode()
26303
+ getThemeMode: () => view.getThemeMode(),
26304
+ /** Update shopping cards after data loads (RFC-0111: loading state) */
26305
+ updateShoppingCards: (cards) => view.updateShoppingCards(cards),
26306
+ /** Update user info display */
26307
+ updateUserInfo: (info) => view.updateUserInfo(info),
26308
+ /** Set CTA button label */
26309
+ setCtaLabel: (label) => view.setCtaLabel(label),
26310
+ /** Set CTA button disabled state */
26311
+ setCtaDisabled: (disabled) => view.setCtaDisabled(disabled)
26145
26312
  };
26146
26313
  }
26147
26314