@gerege-systems/eid-mongolia-sdk 0.14.0 → 0.14.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/button.d.ts CHANGED
@@ -17,13 +17,18 @@ interface EidLoginButtonOptions {
17
17
  lang?: Lang;
18
18
  /** auto (анхдагч: утас → Web2App, бусад → QR цонх) | qr | app. */
19
19
  mode?: "auto" | "qr" | "app";
20
+ /** auto (анхдагч: html[data-theme] / html.dark / prefers-color-scheme-ийг дагана) | light | dark. */
21
+ theme?: "auto" | "light" | "dark";
20
22
  /** Амжилтын дараа (backend redirect өгөөгүй бол) шилжих URL. */
21
23
  successUrl?: string;
22
24
  onSuccess?: (s: EidLoginStatus) => void;
23
25
  onError?: (error: string) => void;
24
26
  }
27
+ type Scheme = "light" | "dark";
28
+ /** `theme` атрибутын утгыг (light | dark | auto) бодит схем болгоно. auto: html[data-theme] → html.dark/.light → OS. */
29
+ declare function resolveEidTheme(theme: string | null, doc?: Document): Scheme;
25
30
  declare const Base: typeof HTMLElement;
26
- /** `<eid-login-button>` — атрибут: start-url, status-url, lang (mn|en), mode (auto|qr|app), success-url. */
31
+ /** `<eid-login-button>` — атрибут: start-url, status-url, lang (mn|en), mode (auto|qr|app), theme (auto|light|dark), success-url. */
27
32
  declare class EidLoginButton extends Base {
28
33
  static readonly observedAttributes: string[];
29
34
  /** Тест/дотоод: гар утас эсэхийг дарж бичих. */
@@ -41,11 +46,20 @@ declare class EidLoginButton extends Base {
41
46
  private fails;
42
47
  private gen;
43
48
  private lastFocus;
49
+ private darkStyle;
50
+ private themeObs;
51
+ private mq;
52
+ private readonly onScheme;
44
53
  private get t();
45
54
  private attr;
46
55
  connectedCallback(): void;
47
- attributeChangedCallback(): void;
56
+ attributeChangedCallback(name: string): void;
48
57
  disconnectedCallback(): void;
58
+ /** Одоогийн бодит схем (`theme` + auto үед хуудас/OS). */
59
+ get scheme(): Scheme;
60
+ private applyTheme;
61
+ /** auto үед хуудасны html[data-theme]/class ба OS-ийн схемийн өөрчлөлтийг дагана. */
62
+ private watchTheme;
49
63
  /** Товчны үйлдэл (программаар ч дуудаж болно). */
50
64
  start(): void;
51
65
  private open;
@@ -76,4 +90,4 @@ declare function defineEidLoginButton(tag?: string): void;
76
90
  /** Элементэд товч нэмнэ (framework-гүй хуудас, React/Vue-ийн ref). Үүссэн элементийг буцаана. */
77
91
  declare function mountEidLoginButton(target: Element, opts: EidLoginButtonOptions): EidLoginButton;
78
92
 
79
- export { EidLoginButton, type EidLoginButtonOptions, type EidLoginStatus, defineEidLoginButton, mountEidLoginButton };
93
+ export { EidLoginButton, type EidLoginButtonOptions, type EidLoginStatus, defineEidLoginButton, mountEidLoginButton, resolveEidTheme };
package/dist/button.js CHANGED
@@ -436,7 +436,7 @@ var T = {
436
436
  minute: "1 minute left"
437
437
  }
438
438
  };
439
- var CSS = `
439
+ var CSS_BASE = `
440
440
  :host { display: inline-block;
441
441
  --eid-bg: hsl(0 0% 100%); --eid-bg-subtle: hsl(210 40% 98%); --eid-bg-muted: hsl(210 40% 96%);
442
442
  --eid-fg: hsl(222 47% 11%); --eid-fg-muted: hsl(215 19% 35%); --eid-fg-subtle: hsl(215 16% 45%);
@@ -444,22 +444,26 @@ var CSS = `
444
444
  --eid-accent: oklch(0.534 0.2 259); --eid-accent-fg: #fff; --eid-accent-subtle: oklch(0.97 0.03 259);
445
445
  --eid-accent-subtle-fg: oklch(0.474 0.19 259); --eid-ring: oklch(0.604 0.2 259);
446
446
  --eid-warning-bg: hsl(48 100% 96%); --eid-warning-border: hsl(45 95% 78%); --eid-warning-fg: hsl(23 75% 33%);
447
- --eid-danger-fg: hsl(0 74% 42%); --eid-radius: 6px; --eid-radius-lg: 8px; font-family: inherit; }
448
- @media (prefers-color-scheme: dark) { :host {
447
+ --eid-danger-fg: hsl(0 74% 42%); --eid-radius: 6px; --eid-radius-lg: 8px; font-family: inherit; color-scheme: light; }
448
+ button, input { font-family: inherit; }
449
+ `;
450
+ var DARK_CSS = `:host { color-scheme: dark;
449
451
  --eid-bg: hsl(229 50% 6%); --eid-bg-subtle: hsl(222 47% 9%); --eid-bg-muted: hsl(217 33% 13%);
450
452
  --eid-fg: hsl(210 40% 98%); --eid-fg-muted: hsl(213 27% 84%); --eid-fg-subtle: hsl(215 20% 65%);
451
453
  --eid-border: hsl(217 33% 17%); --eid-border-strong: hsl(215 25% 27%);
452
454
  --eid-accent: oklch(0.64 0.15 259); --eid-accent-fg: hsl(229 50% 6%); --eid-accent-subtle: oklch(0.24 0.06 259);
453
455
  --eid-accent-subtle-fg: oklch(0.82 0.1 259); --eid-ring: oklch(0.68 0.15 259);
454
456
  --eid-warning-bg: hsl(20 60% 10%); --eid-warning-border: hsl(22 70% 26%); --eid-warning-fg: hsl(40 92% 65%);
455
- --eid-danger-fg: hsl(0 91% 71%); } }
457
+ --eid-danger-fg: hsl(0 91% 71%); }
458
+ `;
459
+ var CSS_REST = `
456
460
  *, *::before, *::after { box-sizing: border-box; }
457
461
  [hidden] { display: none !important; }
458
462
  h2, p, ol { margin: 0; }
459
463
  :focus-visible { outline: 2px solid var(--eid-ring); outline-offset: 2px; }
460
464
  .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
461
465
  .btn { display: inline-flex; width: 100%; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 0 20px;
462
- border-radius: var(--eid-radius); font: 500 1rem/1.25 inherit; text-decoration: none; border: 1px solid transparent; cursor: pointer;
466
+ border-radius: var(--eid-radius); font-family: inherit; font-weight: 500; font-size: 1rem; line-height: 1.25; text-decoration: none; border: 1px solid transparent; cursor: pointer;
463
467
  transition: background-color 160ms cubic-bezier(0,0,0.2,1); }
464
468
  .btn:disabled { opacity: 0.6; cursor: progress; }
465
469
  .btn-primary { background: var(--eid-accent); color: var(--eid-accent-fg); }
@@ -496,7 +500,7 @@ h2, p, ol { margin: 0; }
496
500
  .field { display: grid; gap: 8px; }
497
501
  .field label { font-weight: 500; }
498
502
  .field input { width: 100%; height: 44px; padding: 0 12px; border: 1px solid var(--eid-border-strong); border-radius: var(--eid-radius);
499
- background: var(--eid-bg); color: var(--eid-fg); font: 1rem/1.5rem inherit; letter-spacing: 0.02em; text-transform: uppercase; }
503
+ background: var(--eid-bg); color: var(--eid-fg); font-family: inherit; font-size: 1rem; line-height: 1.5rem; letter-spacing: 0.02em; text-transform: uppercase; }
500
504
  .field input::placeholder { color: var(--eid-fg-subtle); text-transform: none; }
501
505
  .field input[aria-invalid="true"] { border-color: var(--eid-danger-fg); }
502
506
  .hint { font-size: 0.8125rem; color: var(--eid-fg-subtle); }
@@ -516,6 +520,17 @@ h2, p, ol { margin: 0; }
516
520
  @media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; }
517
521
  .spinner { animation: none; border-right-color: currentColor; opacity: 0.6; } }
518
522
  `;
523
+ var CSS = CSS_BASE + CSS_REST;
524
+ function resolveEidTheme(theme, doc = document) {
525
+ if (theme === "light" || theme === "dark") return theme;
526
+ const html = doc.documentElement;
527
+ const dt = html?.getAttribute("data-theme");
528
+ if (dt === "dark" || dt === "light") return dt;
529
+ if (html?.classList.contains("dark")) return "dark";
530
+ if (html?.classList.contains("light")) return "light";
531
+ const mq = doc.defaultView?.matchMedia?.("(prefers-color-scheme: dark)");
532
+ return mq?.matches ? "dark" : "light";
533
+ }
519
534
  var ID_RE = /^([А-ЯЁӨҮ]{2}[0-9]{8}|[0-9]{8,14})$/;
520
535
  var FOCUSABLE = 'button:not([disabled]), input:not([disabled]), a[href], [tabindex]:not([tabindex="-1"])';
521
536
  function el(tag, attrs = {}, text) {
@@ -527,7 +542,7 @@ function el(tag, attrs = {}, text) {
527
542
  var Base = typeof HTMLElement === "undefined" ? class {
528
543
  } : HTMLElement;
529
544
  var EidLoginButton = class extends Base {
530
- static observedAttributes = ["lang"];
545
+ static observedAttributes = ["lang", "theme"];
531
546
  /** Тест/дотоод: гар утас эсэхийг дарж бичих. */
532
547
  isMobile = () => isMobileUserAgent();
533
548
  /** Тест/дотоод: шилжилт (location.assign). */
@@ -544,6 +559,10 @@ var EidLoginButton = class extends Base {
544
559
  gen = 0;
545
560
  // цонх нээх бүрд нэмэгдэнэ — хуучин fetch-ийн хариуг үл тооно
546
561
  lastFocus = null;
562
+ darkStyle;
563
+ themeObs = null;
564
+ mq = null;
565
+ onScheme = () => this.applyTheme();
547
566
  get t() {
548
567
  return T[this.getAttribute("lang") === "en" ? "en" : "mn"];
549
568
  }
@@ -551,21 +570,52 @@ var EidLoginButton = class extends Base {
551
570
  return this.getAttribute(name) ?? def;
552
571
  }
553
572
  connectedCallback() {
554
- if (this.root) return;
555
- this.root = this.attachShadow({ mode: "open" });
556
- const style = el("style");
557
- style.textContent = CSS;
558
- this.trigger = el("button", { type: "button", class: "btn btn-outline trigger", part: "button", "aria-haspopup": "dialog" });
559
- this.trigger.append(el("img", { src: EID_LOGO_DATA_URI, alt: "", width: "20", height: "20" }), el("span", {}, this.t.button));
560
- this.trigger.addEventListener("click", () => this.start());
561
- this.root.append(style, this.trigger);
562
- }
563
- attributeChangedCallback() {
573
+ if (!this.root) {
574
+ this.root = this.attachShadow({ mode: "open" });
575
+ const style = el("style");
576
+ style.textContent = CSS;
577
+ this.darkStyle = el("style", { "data-eid-theme": "dark" });
578
+ this.trigger = el("button", { type: "button", class: "btn btn-outline trigger", part: "button", "aria-haspopup": "dialog" });
579
+ this.trigger.append(el("img", { src: EID_LOGO_DATA_URI, alt: "", width: "20", height: "20" }), el("span", {}, this.t.button));
580
+ this.trigger.addEventListener("click", () => this.start());
581
+ this.root.append(style, this.darkStyle, this.trigger);
582
+ }
583
+ this.watchTheme();
584
+ this.applyTheme();
585
+ }
586
+ attributeChangedCallback(name) {
587
+ if (name === "theme") {
588
+ if (this.root) this.applyTheme();
589
+ return;
590
+ }
564
591
  const label = this.trigger?.querySelector("span");
565
592
  if (label) label.textContent = this.t.button;
566
593
  }
567
594
  disconnectedCallback() {
568
595
  this.close();
596
+ this.themeObs?.disconnect();
597
+ this.themeObs = null;
598
+ this.mq?.removeEventListener?.("change", this.onScheme);
599
+ this.mq = null;
600
+ }
601
+ /** Одоогийн бодит схем (`theme` + auto үед хуудас/OS). */
602
+ get scheme() {
603
+ return resolveEidTheme(this.getAttribute("theme"));
604
+ }
605
+ applyTheme() {
606
+ const css = this.scheme === "dark" ? DARK_CSS : "";
607
+ if (this.darkStyle.textContent !== css) this.darkStyle.textContent = css;
608
+ }
609
+ /** auto үед хуудасны html[data-theme]/class ба OS-ийн схемийн өөрчлөлтийг дагана. */
610
+ watchTheme() {
611
+ if (!this.themeObs && typeof MutationObserver !== "undefined" && document.documentElement) {
612
+ this.themeObs = new MutationObserver(this.onScheme);
613
+ this.themeObs.observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme", "class"] });
614
+ }
615
+ if (!this.mq && typeof matchMedia === "function") {
616
+ this.mq = matchMedia("(prefers-color-scheme: dark)");
617
+ this.mq.addEventListener?.("change", this.onScheme);
618
+ }
569
619
  }
570
620
  /** Товчны үйлдэл (программаар ч дуудаж болно). */
571
621
  start() {
@@ -909,6 +959,7 @@ function mountEidLoginButton(target, opts) {
909
959
  b.setAttribute("status-url", opts.statusUrl);
910
960
  b.setAttribute("lang", opts.lang ?? "mn");
911
961
  if (opts.mode) b.setAttribute("mode", opts.mode);
962
+ if (opts.theme) b.setAttribute("theme", opts.theme);
912
963
  if (opts.successUrl) b.setAttribute("success-url", opts.successUrl);
913
964
  if (opts.onSuccess) b.addEventListener("eid-login-success", (e) => opts.onSuccess(e.detail));
914
965
  if (opts.onError) b.addEventListener("eid-login-error", (e) => opts.onError(e.detail.error));
@@ -919,5 +970,6 @@ defineEidLoginButton();
919
970
  export {
920
971
  EidLoginButton,
921
972
  defineEidLoginButton,
922
- mountEidLoginButton
973
+ mountEidLoginButton,
974
+ resolveEidTheme
923
975
  };
@@ -60,6 +60,12 @@ var ApiError = class extends EidError {
60
60
  return (this.status === 429 || this.status === 503) && (this.retryAfterMs ?? 0) > 0;
61
61
  }
62
62
  };
63
+ var NoSigningCertificateError = class extends ApiError {
64
+ };
65
+ var CertChoiceInvalidError = class extends ApiError {
66
+ };
67
+ var RequestInvalidError = class extends ApiError {
68
+ };
63
69
  var RETRYABLE_ERROR_CODES = [
64
70
  "PDF_PREPARE_BUSY",
65
71
  "DOCUMENT_PENDING",
@@ -170,6 +176,9 @@ export {
170
176
  AuthenticationError,
171
177
  ForbiddenError,
172
178
  ApiError,
179
+ NoSigningCertificateError,
180
+ CertChoiceInvalidError,
181
+ RequestInvalidError,
173
182
  RETRYABLE_ERROR_CODES,
174
183
  parseRetryAfter,
175
184
  ON_BEHALF_ERROR_CODES,