@cdfrd/publish-notification-plugin 0.1.1 → 0.1.2

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
@@ -44,12 +44,13 @@ var MAX_DISMISSED_VERSIONS = 3;
44
44
  var STANDALONE_APP_ID = "__standalone__";
45
45
  var DEFAULT_PRIMARY_COLOR = "#1677ff";
46
46
  var THEME_RETRY_MAX = 3;
47
- var THEME_WATCH_DEBOUNCE_MS = 150;
47
+ var THEME_WATCH_DEBOUNCE_MS = 32;
48
+ var THEME_BTN_BG_SETTLE_MS = 180;
48
49
  var PLACEMENT_STYLES = {
49
- topLeft: "top:16px;left:24px",
50
- topRight: "top:16px;right:24px",
51
- bottomLeft: "bottom:16px;left:24px",
52
- bottomRight: "bottom:16px;right:24px"
50
+ topLeft: "top:24px;left:24px",
51
+ topRight: "top:24px;right:24px",
52
+ bottomLeft: "bottom:24px;left:24px",
53
+ bottomRight: "bottom:24px;right:24px"
53
54
  };
54
55
  var DEFAULT_CHECK_INTERVAL = 10 * 60 * 1e3;
55
56
 
@@ -379,18 +380,18 @@ function ensureNotificationAnchor() {
379
380
  var PRESET_LOCALE = {
380
381
  zh_CN: {
381
382
  title: "\u53D1\u73B0\u65B0\u7248\u672C",
382
- description: "\u8BF7\u5237\u65B0\u540E\u7EE7\u7EED\u3002",
383
+ description: "\u7CFB\u7EDF\u5DF2\u53D1\u5E03\u65B0\u7248\u672C\uFF0C\u5237\u65B0\u9875\u9762\u540E\u751F\u6548\u3002",
383
384
  forcedTitle: "\u53D1\u73B0\u65B0\u7248\u672C",
384
- forcedDescription: "\u8BF7\u5237\u65B0\u540E\u7EE7\u7EED\u3002",
385
- buttonText: "\u5237\u65B0",
385
+ forcedDescription: "\u7CFB\u7EDF\u5DF2\u53D1\u5E03\u65B0\u7248\u672C\uFF0C\u5237\u65B0\u9875\u9762\u540E\u751F\u6548\u3002",
386
+ buttonText: "\u7ACB\u5373\u5237\u65B0",
386
387
  dismissButtonText: "\u7A0D\u540E"
387
388
  },
388
389
  en_US: {
389
- title: "Update available",
390
- description: "Please refresh to continue.",
391
- forcedTitle: "Update required",
392
- forcedDescription: "Please refresh to continue.",
393
- buttonText: "Refresh",
390
+ title: "New version available",
391
+ description: "Refresh the page for it to take effect.",
392
+ forcedTitle: "New version available",
393
+ forcedDescription: "Refresh the page for it to take effect.",
394
+ buttonText: "Refresh now",
394
395
  dismissButtonText: "Later"
395
396
  }
396
397
  };
@@ -413,9 +414,9 @@ var DEFAULT_NOTICE_CSS = `
413
414
  --update-bg: #ffffff;
414
415
  --update-text: rgba(0, 0, 0, 0.88);
415
416
  --update-text-secondary: rgba(0, 0, 0, 0.65);
416
- --update-border: #f0f0f0;
417
- --update-btn-border: #d9d9d9;
418
- --update-btn-hover-bg: rgba(0, 0, 0, 0.04);
417
+ --update-icon-color: rgba(0, 0, 0, 0.45);
418
+ --update-icon-hover: rgba(0, 0, 0, 0.88);
419
+ --update-btn-hover-bg: rgba(0, 0, 0, 0.06);
419
420
  --update-primary: #1677ff;
420
421
  --update-primary-hover: #4096ff;
421
422
  --update-mask: rgba(0, 0, 0, 0.45);
@@ -427,8 +428,8 @@ var DEFAULT_NOTICE_CSS = `
427
428
  --update-bg: #1f1f1f;
428
429
  --update-text: rgba(255, 255, 255, 0.85);
429
430
  --update-text-secondary: rgba(255, 255, 255, 0.65);
430
- --update-border: #303030;
431
- --update-btn-border: #424242;
431
+ --update-icon-color: rgba(255, 255, 255, 0.45);
432
+ --update-icon-hover: rgba(255, 255, 255, 0.85);
432
433
  --update-btn-hover-bg: rgba(255, 255, 255, 0.08);
433
434
  --update-primary: #1668dc;
434
435
  --update-primary-hover: #3c89e8;
@@ -449,7 +450,7 @@ var DEFAULT_NOTICE_CSS = `
449
450
  }
450
451
 
451
452
  .cdfrd-update-notice:not(.cdfrd-update-notice--forced) {
452
- width: 384px;
453
+ width: 340px;
453
454
  }
454
455
 
455
456
  .cdfrd-update-notice-panel {
@@ -461,91 +462,102 @@ var DEFAULT_NOTICE_CSS = `
461
462
  border-radius: 8px;
462
463
  background: var(--update-bg);
463
464
  color: var(--update-text);
464
- border: 1px solid var(--update-border);
465
465
  box-shadow: var(--update-shadow);
466
466
  }
467
467
 
468
- .cdfrd-update-notice-header {
469
- display: flex;
470
- align-items: flex-start;
471
- gap: 8px;
472
- margin-bottom: 4px;
473
- }
474
-
475
468
  .cdfrd-update-notice-title {
476
- flex: 1;
477
- min-width: 0;
469
+ margin: 0;
470
+ padding-right: 28px;
478
471
  font-size: 16px;
479
472
  font-weight: 600;
480
473
  line-height: 1.5;
481
474
  color: var(--update-text);
482
475
  }
483
476
 
477
+ .cdfrd-update-notice-desc {
478
+ margin: 4px 0 0;
479
+ padding-right: 28px;
480
+ font-size: 14px;
481
+ line-height: 1.5714;
482
+ color: var(--update-text-secondary);
483
+ }
484
+
485
+ /* Close \u2014 slightly larger than default antd notice close */
484
486
  .cdfrd-update-notice-close {
485
- flex-shrink: 0;
487
+ position: absolute;
488
+ top: 14px;
489
+ right: 16px;
490
+ z-index: 1;
486
491
  cursor: pointer;
487
- width: 22px;
488
- height: 22px;
492
+ width: 28px;
493
+ height: 28px;
489
494
  padding: 0;
490
495
  border: none;
491
496
  border-radius: 4px;
492
497
  background: transparent;
493
- color: var(--update-text-secondary);
494
- font-size: 16px;
495
- line-height: 22px;
498
+ color: var(--update-icon-color);
499
+ font-size: 20px;
500
+ line-height: 28px;
501
+ text-align: center;
496
502
  }
497
503
 
498
504
  .cdfrd-update-notice-close:hover {
499
- color: var(--update-text);
505
+ color: var(--update-icon-hover);
500
506
  background: var(--update-btn-hover-bg);
501
507
  }
502
508
 
503
- .cdfrd-update-notice-desc {
504
- font-size: 14px;
505
- line-height: 1.5714;
506
- color: var(--update-text-secondary);
507
- margin: 0 0 12px;
508
- }
509
-
509
+ /* Actions \u2014 float right, margin-top (antd Semantic DOM: actions) */
510
510
  .cdfrd-update-notice-actions {
511
511
  display: flex;
512
512
  align-items: center;
513
513
  justify-content: flex-end;
514
+ flex-wrap: wrap;
514
515
  gap: 8px;
516
+ margin-top: 12px;
515
517
  }
516
518
 
517
519
  .cdfrd-update-notice-btn {
518
520
  cursor: pointer;
519
521
  font-size: 14px;
520
522
  line-height: 1.5714;
521
- height: 32px;
522
- padding: 4px 15px;
523
- border: 1px solid var(--update-btn-border);
524
- border-radius: 6px;
525
- background: var(--update-bg);
526
- color: var(--update-text);
523
+ height: 24px;
524
+ padding: 0 7px;
525
+ border: none;
526
+ border-radius: 4px;
527
+ background: transparent;
527
528
  box-sizing: border-box;
529
+ white-space: nowrap;
528
530
  transition: all 0.2s;
529
531
  }
530
532
 
531
- .cdfrd-update-notice-btn:hover {
533
+ /* Text / link button \u2014 weakened secondary action (antd Button type="link" size="small") */
534
+ .cdfrd-update-notice-btn-link {
535
+ height: auto;
536
+ padding: 0 4px;
532
537
  color: var(--update-primary);
533
- border-color: var(--update-primary);
538
+ background: transparent;
539
+ }
540
+
541
+ .cdfrd-update-notice-btn-link:hover {
542
+ color: var(--update-primary-hover);
543
+ background: transparent;
534
544
  }
535
545
 
536
546
  .cdfrd-update-notice-btn-primary {
547
+ height: 24px;
548
+ padding: 0 7px;
537
549
  background: var(--update-primary);
538
- border-color: var(--update-primary);
539
550
  color: #fff;
551
+ font-size: 14px;
552
+ border-radius: 4px;
540
553
  }
541
554
 
542
555
  .cdfrd-update-notice-btn-primary:hover {
543
556
  background: var(--update-primary-hover);
544
- border-color: var(--update-primary-hover);
545
557
  color: #fff;
546
558
  }
547
559
 
548
- /* Forced centered modal \u2014 Ant Design Modal */
560
+ /* Forced update \u2014 centered card, still notification-like */
549
561
  .cdfrd-update-notice--forced {
550
562
  inset: 0;
551
563
  max-width: none;
@@ -560,23 +572,27 @@ var DEFAULT_NOTICE_CSS = `
560
572
  }
561
573
 
562
574
  .cdfrd-update-notice--forced .cdfrd-update-notice-panel {
563
- width: min(416px, 100%);
575
+ width: max-content;
576
+ max-width: min(360px, calc(100vw - 48px));
564
577
  padding: 20px 24px;
565
- border: none;
566
- text-align: left;
567
- }
568
-
569
- .cdfrd-update-notice--forced .cdfrd-update-notice-title {
570
- margin-bottom: 8px;
571
578
  }
572
579
 
580
+ .cdfrd-update-notice--forced .cdfrd-update-notice-title,
573
581
  .cdfrd-update-notice--forced .cdfrd-update-notice-desc {
574
- margin-bottom: 0;
582
+ padding-right: 0;
575
583
  }
576
584
 
577
585
  .cdfrd-update-notice--forced .cdfrd-update-notice-actions {
578
- margin-top: 12px;
579
- justify-content: flex-end;
586
+ margin-top: 16px;
587
+ justify-content: center;
588
+ }
589
+
590
+ .cdfrd-update-notice--forced .cdfrd-update-notice-btn-primary {
591
+ width: auto;
592
+ height: 24px;
593
+ padding: 0 7px;
594
+ border-radius: 4px;
595
+ font-size: 14px;
580
596
  }
581
597
  `.trim();
582
598
 
@@ -597,6 +613,26 @@ var ANT_PRIMARY_VARS = [
597
613
  "--ant-primary-color",
598
614
  "--colorPrimary"
599
615
  ];
616
+ var ANT_BG_VARS = [
617
+ "--ant-color-bg-elevated",
618
+ "--ant-color-bg-container",
619
+ "--ant-color-bg-base",
620
+ "--ant-bg-color"
621
+ ];
622
+ var SURFACE_SELECTORS = [
623
+ ".ant-modal-content",
624
+ ".ant-notification-notice",
625
+ ".ant-popover-inner",
626
+ ".ant-card",
627
+ ".ant-input",
628
+ ".ant-btn-default"
629
+ ];
630
+ var SURFACE_PROBE_CLASSES = [
631
+ "ant-modal-content",
632
+ "ant-btn ant-btn-default",
633
+ "ant-input"
634
+ ];
635
+ var DARK_LUMINANCE_THRESHOLD = 0.45;
600
636
  function isInvalidColor(color) {
601
637
  if (!color) return true;
602
638
  const c = color.trim().toLowerCase();
@@ -729,6 +765,138 @@ function resolvePrimaryColorLazy(config, theme, onDone, maxAttempts = THEME_RETR
729
765
  };
730
766
  run();
731
767
  }
768
+ function parseRgbChannels(color) {
769
+ const trimmed = color.trim();
770
+ const rgb = trimmed.match(
771
+ /^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)(?:\s*,\s*[\d.]+)?\s*\)$/i
772
+ );
773
+ if (rgb) return [Number(rgb[1]), Number(rgb[2]), Number(rgb[3])];
774
+ const hex = trimmed.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);
775
+ if (!hex) return null;
776
+ const h = hex[1];
777
+ if (h.length === 3) {
778
+ return [
779
+ parseInt(h[0] + h[0], 16),
780
+ parseInt(h[1] + h[1], 16),
781
+ parseInt(h[2] + h[2], 16)
782
+ ];
783
+ }
784
+ return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)];
785
+ }
786
+ function relativeLuminance(r, g, b) {
787
+ const toLinear = (c) => {
788
+ const s = c / 255;
789
+ return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
790
+ };
791
+ return 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);
792
+ }
793
+ function themeFromBackgroundColor(color) {
794
+ if (isInvalidColor(color)) return null;
795
+ const channels = parseRgbChannels(color);
796
+ if (!channels) return null;
797
+ return relativeLuminance(...channels) < DARK_LUMINANCE_THRESHOLD ? "dark" : "light";
798
+ }
799
+ function tryResolveDomThemeHint() {
800
+ if (typeof document === "undefined") return null;
801
+ const roots = [document.documentElement, document.body].filter(Boolean);
802
+ for (const el2 of roots) {
803
+ const dataTheme = el2.dataset.theme || el2.getAttribute("data-theme") || el2.dataset.demoTheme || el2.getAttribute("data-demo-theme");
804
+ if (dataTheme === "dark" || dataTheme === "light") return dataTheme;
805
+ }
806
+ for (const el2 of roots) {
807
+ if (el2.classList.contains("dark") || el2.classList.contains("ant-theme-dark")) return "dark";
808
+ if (el2.classList.contains("light") || el2.classList.contains("ant-theme-light")) return "light";
809
+ }
810
+ return null;
811
+ }
812
+ function readBgVarFromElement(el2) {
813
+ try {
814
+ const style = getComputedStyle(el2);
815
+ for (const name of ANT_BG_VARS) {
816
+ const value = style.getPropertyValue(name)?.trim();
817
+ if (!isInvalidColor(value)) return value;
818
+ }
819
+ } catch {
820
+ return null;
821
+ }
822
+ return null;
823
+ }
824
+ function readCssVariableBg() {
825
+ if (typeof document === "undefined") return null;
826
+ for (const root of [document.documentElement, document.body]) {
827
+ if (!root) continue;
828
+ const value = readBgVarFromElement(root);
829
+ if (value) return value;
830
+ }
831
+ const seeds = document.querySelectorAll(
832
+ '.ant-btn-primary, .ant-btn, .ant-modal-content, .ant-input, [class*="css-var"]'
833
+ );
834
+ for (const seed of seeds) {
835
+ let el2 = seed;
836
+ while (el2) {
837
+ const value = readBgVarFromElement(el2);
838
+ if (value) return value;
839
+ el2 = el2.parentElement;
840
+ }
841
+ }
842
+ return null;
843
+ }
844
+ function readExistingSurfaceBg() {
845
+ if (typeof document === "undefined") return null;
846
+ for (const selector of SURFACE_SELECTORS) {
847
+ const node = document.querySelector(selector);
848
+ if (!node) continue;
849
+ try {
850
+ const color = getComputedStyle(node).backgroundColor;
851
+ if (!isInvalidColor(color)) return color;
852
+ } catch {
853
+ }
854
+ }
855
+ return null;
856
+ }
857
+ function probeSurfaceBg() {
858
+ if (typeof document === "undefined" || !document.body) return null;
859
+ beginSuppressThemeWatch();
860
+ try {
861
+ const seed = document.querySelector(
862
+ ".ant-btn-primary, .ant-btn, .ant-input, .ant-modal-content"
863
+ );
864
+ const hashClasses = seed ? Array.from(seed.classList).filter((c) => c.startsWith("css-") || c.includes("css-var")) : [];
865
+ const mountAt = seed?.closest('[class*="css-var"]') || seed?.parentElement || document.body;
866
+ for (const className of SURFACE_PROBE_CLASSES) {
867
+ const tag = className.includes("ant-btn") ? "button" : className.includes("ant-input") ? "input" : "div";
868
+ const node = document.createElement(tag);
869
+ node.className = [className, ...hashClasses].filter(Boolean).join(" ");
870
+ node.setAttribute("aria-hidden", "true");
871
+ node.style.cssText = "position:absolute;left:0;top:0;opacity:0;pointer-events:none;width:0;height:0;overflow:hidden;";
872
+ mountAt.appendChild(node);
873
+ const color = getComputedStyle(node).backgroundColor;
874
+ node.remove();
875
+ if (!isInvalidColor(color)) return color;
876
+ }
877
+ return null;
878
+ } catch {
879
+ return null;
880
+ } finally {
881
+ endSuppressThemeWatch();
882
+ }
883
+ }
884
+ function tryResolveAntdSurfaceBg(options) {
885
+ try {
886
+ const allowProbe = options?.allowProbe !== false;
887
+ const fromVar = readCssVariableBg();
888
+ if (fromVar) return fromVar;
889
+ const fromSurface = readExistingSurfaceBg();
890
+ if (fromSurface) return fromSurface;
891
+ if (allowProbe) return probeSurfaceBg();
892
+ return null;
893
+ } catch {
894
+ return null;
895
+ }
896
+ }
897
+ function tryResolveAntdThemeMode(options) {
898
+ return tryResolveDomThemeHint() ?? themeFromBackgroundColor(tryResolveAntdSurfaceBg(options));
899
+ }
732
900
  function isUpdateNoticeMutationTarget(node) {
733
901
  if (!node || node.nodeType !== Node.ELEMENT_NODE) return false;
734
902
  const el2 = node;
@@ -748,7 +916,7 @@ function mutationsOnlyAffectNotice(mutations) {
748
916
  return false;
749
917
  });
750
918
  }
751
- function watchThemeChanges(config, getTheme, onChange) {
919
+ function watchThemeChanges(config, getTheme, onChange, onThemeMode) {
752
920
  if (typeof document === "undefined") {
753
921
  return () => void 0;
754
922
  }
@@ -760,39 +928,70 @@ function watchThemeChanges(config, getTheme, onChange) {
760
928
  return () => void 0;
761
929
  }
762
930
  let last = "";
931
+ let lastThemeMode = null;
763
932
  let btnBgCandidate = "";
764
933
  let debounceTimer;
765
934
  let settleTimer;
935
+ let rafPending = false;
766
936
  const clearTimers = () => {
767
937
  if (debounceTimer !== void 0) clearTimeout(debounceTimer);
768
938
  if (settleTimer !== void 0) clearTimeout(settleTimer);
769
939
  debounceTimer = void 0;
770
940
  settleTimer = void 0;
941
+ rafPending = false;
771
942
  };
772
- const evaluate = () => {
773
- const found = tryResolveAntdPrimaryDetailed({ allowProbe: false });
774
- if (!found) return;
943
+ const applyThemeModeIfChanged = (mode) => {
944
+ if (!mode || mode === lastThemeMode) return;
945
+ lastThemeMode = mode;
946
+ if (mode !== getTheme()) {
947
+ onThemeMode?.(mode);
948
+ }
949
+ };
950
+ const applyPrimaryIfChanged = (found, opts) => {
775
951
  const { color, source } = found;
776
952
  if (color === last) {
777
953
  btnBgCandidate = "";
778
- return;
954
+ return false;
779
955
  }
780
- if (source === "btnBg" && color !== btnBgCandidate) {
781
- btnBgCandidate = color;
782
- if (settleTimer !== void 0) clearTimeout(settleTimer);
783
- settleTimer = setTimeout(() => {
784
- settleTimer = void 0;
785
- evaluate();
786
- }, THEME_WATCH_DEBOUNCE_MS);
787
- return;
956
+ if (source === "btnBg" && !opts?.allowUnsettledBtnBg) {
957
+ if (color !== btnBgCandidate) {
958
+ btnBgCandidate = color;
959
+ if (settleTimer !== void 0) clearTimeout(settleTimer);
960
+ settleTimer = setTimeout(() => {
961
+ settleTimer = void 0;
962
+ evaluate({ settlePass: true });
963
+ }, THEME_BTN_BG_SETTLE_MS);
964
+ return false;
965
+ }
788
966
  }
789
967
  last = color;
790
968
  btnBgCandidate = "";
791
969
  onChange(color);
970
+ return true;
971
+ };
972
+ const evaluate = (opts) => {
973
+ let mode = tryResolveAntdThemeMode({ allowProbe: false });
974
+ if (!mode) mode = tryResolveAntdThemeMode({ allowProbe: true });
975
+ applyThemeModeIfChanged(mode);
976
+ const found = tryResolveAntdPrimaryDetailed({ allowProbe: false });
977
+ if (!found) return;
978
+ applyPrimaryIfChanged(found, { allowUnsettledBtnBg: opts?.settlePass === true });
792
979
  };
793
980
  const schedule = (mutations) => {
794
981
  if (suppressThemeWatch > 0) return;
795
982
  if (mutations && mutationsOnlyAffectNotice(mutations)) return;
983
+ if (!rafPending) {
984
+ rafPending = true;
985
+ scheduleFrame(() => {
986
+ rafPending = false;
987
+ if (suppressThemeWatch > 0) return;
988
+ applyThemeModeIfChanged(tryResolveAntdThemeMode({ allowProbe: false }));
989
+ const found = tryResolveAntdPrimaryDetailed({ allowProbe: false });
990
+ if (found?.source === "cssVar") {
991
+ applyPrimaryIfChanged(found);
992
+ }
993
+ });
994
+ }
796
995
  if (debounceTimer !== void 0) clearTimeout(debounceTimer);
797
996
  debounceTimer = setTimeout(() => {
798
997
  debounceTimer = void 0;
@@ -801,7 +1000,13 @@ function watchThemeChanges(config, getTheme, onChange) {
801
1000
  }, THEME_WATCH_DEBOUNCE_MS);
802
1001
  };
803
1002
  const observer = new MutationObserver((mutations) => schedule(mutations));
804
- const attrFilter = ["class", "style", "data-theme", "data-update-notice-theme"];
1003
+ const attrFilter = [
1004
+ "class",
1005
+ "style",
1006
+ "data-theme",
1007
+ "data-demo-theme",
1008
+ "data-update-notice-theme"
1009
+ ];
805
1010
  observer.observe(document.documentElement, {
806
1011
  attributes: true,
807
1012
  attributeFilter: attrFilter
@@ -858,6 +1063,18 @@ function applyPrimaryColor(primary) {
858
1063
  endSuppressThemeWatch();
859
1064
  }
860
1065
  }
1066
+ function applySurfaceBackground(bg) {
1067
+ beginSuppressThemeWatch();
1068
+ try {
1069
+ document.querySelectorAll(".cdfrd-update-notice").forEach((node) => {
1070
+ const el2 = node;
1071
+ if (bg) el2.style.setProperty("--update-bg", bg);
1072
+ else el2.style.removeProperty("--update-bg");
1073
+ });
1074
+ } finally {
1075
+ endSuppressThemeWatch();
1076
+ }
1077
+ }
861
1078
  function closeDefaultNotice() {
862
1079
  document.querySelector(".cdfrd-update-notice")?.remove();
863
1080
  visible = false;
@@ -909,18 +1126,12 @@ function showDefaultNotice(options) {
909
1126
  actions.appendChild(refreshBtn);
910
1127
  panel.appendChild(actions);
911
1128
  } else {
912
- const header = el("div", "cdfrd-update-notice-header");
913
- header.appendChild(el("div", "cdfrd-update-notice-title", copy.title));
914
- const closeBtn = el("button", `cdfrd-update-notice-close ${NOTIFICATION_CLOSE_BTN_CLASS}`, "\xD7");
915
- closeBtn.setAttribute("type", "button");
916
- closeBtn.setAttribute("aria-label", "close");
917
- header.appendChild(closeBtn);
918
- panel.appendChild(header);
1129
+ panel.appendChild(el("div", "cdfrd-update-notice-title", copy.title));
919
1130
  panel.appendChild(el("div", "cdfrd-update-notice-desc", copy.description));
920
1131
  const actions = el("div", "cdfrd-update-notice-actions");
921
1132
  const dismissBtn = el(
922
1133
  "button",
923
- `cdfrd-update-notice-btn ${NOTIFICATION_DISMISS_BTN_CLASS}`,
1134
+ `cdfrd-update-notice-btn cdfrd-update-notice-btn-link ${NOTIFICATION_DISMISS_BTN_CLASS}`,
924
1135
  copy.dismissButtonText
925
1136
  );
926
1137
  dismissBtn.setAttribute("type", "button");
@@ -933,6 +1144,10 @@ function showDefaultNotice(options) {
933
1144
  refreshBtn.setAttribute("type", "button");
934
1145
  actions.appendChild(refreshBtn);
935
1146
  panel.appendChild(actions);
1147
+ const closeBtn = el("button", `cdfrd-update-notice-close ${NOTIFICATION_CLOSE_BTN_CLASS}`, "\xD7");
1148
+ closeBtn.setAttribute("type", "button");
1149
+ closeBtn.setAttribute("aria-label", "close");
1150
+ panel.appendChild(closeBtn);
936
1151
  }
937
1152
  wrap.appendChild(panel);
938
1153
  let anchor = document.body.querySelector(`:scope > .cdfrd-update-notice-anchor`);
@@ -1045,6 +1260,24 @@ var UpdateNoticeManager = class _UpdateNoticeManager {
1045
1260
  }
1046
1261
  this.refreshPrimaryColor(gen);
1047
1262
  }
1263
+ /** Sync light/dark panel tokens + surface bg from Antd when detectable. */
1264
+ syncAntdThemeMode(allowProbe = true) {
1265
+ const adapter = this.getActiveThemeAdapter();
1266
+ if ((adapter?.type ?? "antd") !== "antd") {
1267
+ applySurfaceBackground(null);
1268
+ return;
1269
+ }
1270
+ const bg = tryResolveAntdSurfaceBg({ allowProbe });
1271
+ const bgMode = themeFromBackgroundColor(bg);
1272
+ const domMode = tryResolveDomThemeHint();
1273
+ const mode = domMode ?? bgMode;
1274
+ if (mode && mode !== this.theme) {
1275
+ this.theme = mode;
1276
+ applyTheme(mode);
1277
+ }
1278
+ const surfaceOk = Boolean(bg && bgMode && mode && bgMode === mode);
1279
+ applySurfaceBackground(surfaceOk ? bg : null);
1280
+ }
1048
1281
  notifyUpdate(_runtime, _version) {
1049
1282
  void _runtime;
1050
1283
  void _version;
@@ -1053,6 +1286,7 @@ var UpdateNoticeManager = class _UpdateNoticeManager {
1053
1286
  ensureNotificationAnchor();
1054
1287
  const adapter = runtime.options.themeAdapter ?? this.themeAdapter;
1055
1288
  const gen = this.primaryResolveGen;
1289
+ this.syncAntdThemeMode(true);
1056
1290
  resolvePrimaryColorLazy(adapter, this.theme, (color) => {
1057
1291
  if (gen !== this.primaryResolveGen) return;
1058
1292
  this.primaryColor = color;
@@ -1078,6 +1312,7 @@ var UpdateNoticeManager = class _UpdateNoticeManager {
1078
1312
  runtime.dismissVersion(version);
1079
1313
  }
1080
1314
  });
1315
+ this.syncAntdThemeMode(true);
1081
1316
  });
1082
1317
  return true;
1083
1318
  }
@@ -1092,11 +1327,22 @@ var UpdateNoticeManager = class _UpdateNoticeManager {
1092
1327
  startThemeWatch() {
1093
1328
  this.stopWatchTheme?.();
1094
1329
  const adapter = this.getActiveThemeAdapter();
1095
- this.stopWatchTheme = watchThemeChanges(adapter, () => this.theme, (color) => {
1096
- this.primaryResolveGen += 1;
1097
- this.primaryColor = color;
1098
- applyPrimaryColor(color);
1099
- });
1330
+ this.stopWatchTheme = watchThemeChanges(
1331
+ adapter,
1332
+ () => this.theme,
1333
+ (color) => {
1334
+ this.primaryResolveGen += 1;
1335
+ this.primaryColor = color;
1336
+ applyPrimaryColor(color);
1337
+ this.syncAntdThemeMode(true);
1338
+ },
1339
+ (theme) => {
1340
+ if (theme === this.theme) return;
1341
+ this.theme = theme;
1342
+ applyTheme(theme);
1343
+ this.syncAntdThemeMode(true);
1344
+ }
1345
+ );
1100
1346
  }
1101
1347
  destroy() {
1102
1348
  this.stopWatchTheme?.();