@zoreal/oauth2-react 0.2.19 → 0.2.21

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.d.cts CHANGED
@@ -254,6 +254,13 @@ declare function ZorealBusyRing({ busy, radius, theme, block, className, style,
254
254
  children: ReactNode;
255
255
  }): react.JSX.Element;
256
256
 
257
+ declare function ZorealMark({ size, brand, className, }: {
258
+ size?: number;
259
+ /** Paint the brand blue instead of inheriting currentColor. */
260
+ brand?: boolean;
261
+ className?: string;
262
+ }): react.JSX.Element;
263
+
257
264
  /**
258
265
  * The pairing modal, rendered by the SDK rather than by every integrator.
259
266
  *
@@ -279,10 +286,10 @@ declare function PairingModal({ state, qrUrl, onCancel, locale, theme, timeoutMs
279
286
 
280
287
  declare function useZorealLogin(options: {
281
288
  flow?: 'browser-direct';
282
- } & BrowserDirectFlowOptions): () => void;
289
+ } & BrowserDirectFlowOptions): (event?: unknown) => void;
283
290
  declare function useZorealLogin(options: {
284
291
  flow: 'auth-code';
285
- } & AuthCodeFlowOptions): () => void;
292
+ } & AuthCodeFlowOptions): (event?: unknown) => void;
286
293
 
287
294
  /**
288
295
  * Silent re-auth with prompt=none. NOT One Tap and never could be: there is no
@@ -323,4 +330,4 @@ declare function hasGrantedAnyScopeZoreal(response: Pick<ZorealCodeResponse, 'sc
323
330
  */
324
331
  declare function resolveIntent(intent: LoginIntent | undefined, scope: string | undefined, acrValues: string | readonly string[] | undefined): LoginIntent;
325
332
 
326
- export { type AcrValue, type AuthCodeFlowOptions, type BrowserDirectFlowOptions, DEFAULT_PAIRING_TIMEOUT_MS, type ErrorCode, type LoginIntent, type NonOAuthError, PairingModal, type PairingModalProps, type PairingState, type PairingUI, type SelectBy, type UseZorealAutoLoginOptions, ZorealBusyRing, type ZorealButtonConfiguration, type ZorealCodeResponse, type ZorealCredentialResponse, ZorealLogin, type ZorealLoginProps, type ZorealLoginRequestOptions, type ZorealOAuthContextProps, ZorealOAuthProvider, type ZorealOAuthProviderProps, type ZorealTheme, hasGrantedAllScopesZoreal, hasGrantedAnyScopeZoreal, resolveIntent, useZorealAutoLogin, useZorealLogin, useZorealOAuth, zorealLogout };
333
+ export { type AcrValue, type AuthCodeFlowOptions, type BrowserDirectFlowOptions, DEFAULT_PAIRING_TIMEOUT_MS, type ErrorCode, type LoginIntent, type NonOAuthError, PairingModal, type PairingModalProps, type PairingState, type PairingUI, type SelectBy, type UseZorealAutoLoginOptions, ZorealBusyRing, type ZorealButtonConfiguration, type ZorealCodeResponse, type ZorealCredentialResponse, ZorealLogin, type ZorealLoginProps, type ZorealLoginRequestOptions, ZorealMark, type ZorealOAuthContextProps, ZorealOAuthProvider, type ZorealOAuthProviderProps, type ZorealTheme, hasGrantedAllScopesZoreal, hasGrantedAnyScopeZoreal, resolveIntent, useZorealAutoLogin, useZorealLogin, useZorealOAuth, zorealLogout };
package/dist/index.d.ts CHANGED
@@ -254,6 +254,13 @@ declare function ZorealBusyRing({ busy, radius, theme, block, className, style,
254
254
  children: ReactNode;
255
255
  }): react.JSX.Element;
256
256
 
257
+ declare function ZorealMark({ size, brand, className, }: {
258
+ size?: number;
259
+ /** Paint the brand blue instead of inheriting currentColor. */
260
+ brand?: boolean;
261
+ className?: string;
262
+ }): react.JSX.Element;
263
+
257
264
  /**
258
265
  * The pairing modal, rendered by the SDK rather than by every integrator.
259
266
  *
@@ -279,10 +286,10 @@ declare function PairingModal({ state, qrUrl, onCancel, locale, theme, timeoutMs
279
286
 
280
287
  declare function useZorealLogin(options: {
281
288
  flow?: 'browser-direct';
282
- } & BrowserDirectFlowOptions): () => void;
289
+ } & BrowserDirectFlowOptions): (event?: unknown) => void;
283
290
  declare function useZorealLogin(options: {
284
291
  flow: 'auth-code';
285
- } & AuthCodeFlowOptions): () => void;
292
+ } & AuthCodeFlowOptions): (event?: unknown) => void;
286
293
 
287
294
  /**
288
295
  * Silent re-auth with prompt=none. NOT One Tap and never could be: there is no
@@ -323,4 +330,4 @@ declare function hasGrantedAnyScopeZoreal(response: Pick<ZorealCodeResponse, 'sc
323
330
  */
324
331
  declare function resolveIntent(intent: LoginIntent | undefined, scope: string | undefined, acrValues: string | readonly string[] | undefined): LoginIntent;
325
332
 
326
- export { type AcrValue, type AuthCodeFlowOptions, type BrowserDirectFlowOptions, DEFAULT_PAIRING_TIMEOUT_MS, type ErrorCode, type LoginIntent, type NonOAuthError, PairingModal, type PairingModalProps, type PairingState, type PairingUI, type SelectBy, type UseZorealAutoLoginOptions, ZorealBusyRing, type ZorealButtonConfiguration, type ZorealCodeResponse, type ZorealCredentialResponse, ZorealLogin, type ZorealLoginProps, type ZorealLoginRequestOptions, type ZorealOAuthContextProps, ZorealOAuthProvider, type ZorealOAuthProviderProps, type ZorealTheme, hasGrantedAllScopesZoreal, hasGrantedAnyScopeZoreal, resolveIntent, useZorealAutoLogin, useZorealLogin, useZorealOAuth, zorealLogout };
333
+ export { type AcrValue, type AuthCodeFlowOptions, type BrowserDirectFlowOptions, DEFAULT_PAIRING_TIMEOUT_MS, type ErrorCode, type LoginIntent, type NonOAuthError, PairingModal, type PairingModalProps, type PairingState, type PairingUI, type SelectBy, type UseZorealAutoLoginOptions, ZorealBusyRing, type ZorealButtonConfiguration, type ZorealCodeResponse, type ZorealCredentialResponse, ZorealLogin, type ZorealLoginProps, type ZorealLoginRequestOptions, ZorealMark, type ZorealOAuthContextProps, ZorealOAuthProvider, type ZorealOAuthProviderProps, type ZorealTheme, hasGrantedAllScopesZoreal, hasGrantedAnyScopeZoreal, resolveIntent, useZorealAutoLogin, useZorealLogin, useZorealOAuth, zorealLogout };
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { createContext, useContext, useMemo, useState as useState2 } from "react
5
5
 
6
6
  // src/wire.ts
7
7
  var WIRE_VERSION = 1;
8
- var SDK_VERSION = "0.2.19";
8
+ var SDK_VERSION = "0.2.21";
9
9
  var DEFAULT_ISSUER = "https://id.zoreal.com";
10
10
  var POLL_INTERVAL_MS = 2e3;
11
11
  var POLL_INTERVAL_ENROLLING_MS = 5e3;
@@ -1360,6 +1360,16 @@ var CSS = `
1360
1360
  transition: opacity 200ms ease-out;
1361
1361
  }
1362
1362
  .${PREFIX}-ring[data-busy="true"] > .${PREFIX}-ring-svg { opacity: 1; }
1363
+ /* The same light as an overlay in the document body, placed over a site's
1364
+ own control by the package itself (busy.ts): nothing of the site's
1365
+ markup or CSS is touched, and neither an ancestor's overflow nor a
1366
+ selector on the control's parent is affected. */
1367
+ .${PREFIX}-ring-overlay {
1368
+ position: fixed;
1369
+ display: block;
1370
+ z-index: 2147483000;
1371
+ pointer-events: none;
1372
+ }
1363
1373
  .${PREFIX}-ring-svg rect {
1364
1374
  --zrl-l: var(--zrl-ring-len, 600px);
1365
1375
  x: 2px;
@@ -1600,6 +1610,96 @@ import { useMemo as useMemo2, useState as useState4 } from "react";
1600
1610
  // src/useZorealLogin.ts
1601
1611
  import { useCallback, useEffect as useEffect2, useRef as useRef2, useState as useState3 } from "react";
1602
1612
 
1613
+ // src/busy.ts
1614
+ var SVG_NS = "http://www.w3.org/2000/svg";
1615
+ var TAIL = 0.3;
1616
+ var STACK = Array.from({ length: 12 }, (_, i) => 12 - i);
1617
+ var HALO = [3, 2, 1];
1618
+ function radiusOf(control) {
1619
+ const value = parseFloat(getComputedStyle(control).borderTopLeftRadius);
1620
+ return Number.isFinite(value) ? value : 8;
1621
+ }
1622
+ function holdBusy(control) {
1623
+ if (typeof document === "undefined") return () => {
1624
+ };
1625
+ ensureStyles();
1626
+ const hadDisabled = control.hasAttribute("disabled");
1627
+ const hadBusy = control.getAttribute("aria-busy");
1628
+ if (control instanceof HTMLButtonElement || control instanceof HTMLInputElement) {
1629
+ control.disabled = true;
1630
+ } else {
1631
+ control.setAttribute("aria-disabled", "true");
1632
+ }
1633
+ control.setAttribute("aria-busy", "true");
1634
+ const overlay = document.createElement("div");
1635
+ overlay.className = `${cx("root")} ${cx("ring")} ${cx("ring-overlay")}`;
1636
+ overlay.dataset.theme = "auto";
1637
+ overlay.dataset.busy = "true";
1638
+ overlay.setAttribute("aria-hidden", "true");
1639
+ const svg = document.createElementNS(SVG_NS, "svg");
1640
+ svg.setAttribute("class", cx("ring-svg"));
1641
+ const rx = radiusOf(control) + 2;
1642
+ const layer = (name, len, alpha) => {
1643
+ const rect = document.createElementNS(SVG_NS, "rect");
1644
+ rect.setAttribute("class", cx(name));
1645
+ rect.setAttribute("rx", String(rx));
1646
+ rect.setAttribute("ry", String(rx));
1647
+ rect.style.strokeDasharray = `calc(var(--zrl-l) * ${len}) calc(var(--zrl-l) * ${1 - len})`;
1648
+ rect.style.setProperty("--zrl-s", `calc(var(--zrl-l) * ${-(TAIL - len)})`);
1649
+ rect.style.opacity = alpha;
1650
+ svg.appendChild(rect);
1651
+ return rect;
1652
+ };
1653
+ let measured = null;
1654
+ for (const n of HALO) {
1655
+ const rect = layer("ring-halo", TAIL * n / HALO.length, `calc(var(--zrl-glow-opacity) * 0.6 / ${n})`);
1656
+ measured ?? (measured = rect);
1657
+ }
1658
+ for (const n of STACK) layer(n <= 2 ? "ring-head" : "ring-tail", TAIL * n / STACK.length, String(1 / n));
1659
+ overlay.appendChild(svg);
1660
+ document.body.appendChild(overlay);
1661
+ let frame = 0;
1662
+ const place = () => {
1663
+ frame = 0;
1664
+ const box = control.getBoundingClientRect();
1665
+ overlay.style.left = `${box.left}px`;
1666
+ overlay.style.top = `${box.top}px`;
1667
+ overlay.style.width = `${box.width}px`;
1668
+ overlay.style.height = `${box.height}px`;
1669
+ const length = typeof measured?.getTotalLength === "function" ? measured.getTotalLength() : 0;
1670
+ if (length > 0) overlay.style.setProperty("--zrl-ring-len", `${length}px`);
1671
+ };
1672
+ const schedule = () => {
1673
+ if (!frame) frame = requestAnimationFrame(place);
1674
+ };
1675
+ place();
1676
+ const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(schedule);
1677
+ observer?.observe(control);
1678
+ window.addEventListener("scroll", schedule, true);
1679
+ window.addEventListener("resize", schedule);
1680
+ let released = false;
1681
+ return () => {
1682
+ if (released) return;
1683
+ released = true;
1684
+ if (frame) cancelAnimationFrame(frame);
1685
+ observer?.disconnect();
1686
+ window.removeEventListener("scroll", schedule, true);
1687
+ window.removeEventListener("resize", schedule);
1688
+ overlay.remove();
1689
+ if (control instanceof HTMLButtonElement || control instanceof HTMLInputElement) {
1690
+ control.disabled = hadDisabled;
1691
+ } else {
1692
+ control.removeAttribute("aria-disabled");
1693
+ }
1694
+ if (hadBusy === null) control.removeAttribute("aria-busy");
1695
+ else control.setAttribute("aria-busy", hadBusy);
1696
+ };
1697
+ }
1698
+ function controlFrom(event) {
1699
+ const target = event?.currentTarget;
1700
+ return typeof HTMLElement !== "undefined" && target instanceof HTMLElement ? target : null;
1701
+ }
1702
+
1603
1703
  // src/return.ts
1604
1704
  var PREFIX2 = "zoreal:oauth2:return:";
1605
1705
  var DONE = "zoreal:oauth2:done:";
@@ -2064,6 +2164,7 @@ function useZorealFlow(options) {
2064
2164
  () => () => {
2065
2165
  abortRef.current?.abort();
2066
2166
  publishRef.current?.(null);
2167
+ releaseRef.current();
2067
2168
  },
2068
2169
  []
2069
2170
  );
@@ -2122,10 +2223,21 @@ function useZorealFlow(options) {
2122
2223
  }
2123
2224
  })();
2124
2225
  }, [clientId, issuer]);
2125
- const login = useCallback(() => {
2226
+ const releaseRef = useRef2(() => {
2227
+ });
2228
+ const login = useCallback((event) => {
2126
2229
  const opts = optionsRef.current;
2230
+ const control = controlFrom(event);
2127
2231
  const run = async () => {
2128
2232
  abortRef.current?.abort();
2233
+ releaseRef.current();
2234
+ releaseRef.current = control ? holdBusy(control) : () => {
2235
+ };
2236
+ const release = () => {
2237
+ releaseRef.current();
2238
+ releaseRef.current = () => {
2239
+ };
2240
+ };
2129
2241
  const controller = new AbortController();
2130
2242
  abortRef.current = controller;
2131
2243
  const flow = opts.flow;
@@ -2274,6 +2386,7 @@ function useZorealFlow(options) {
2274
2386
  setPairing(null);
2275
2387
  publishRef.current?.(null);
2276
2388
  if (returnId) markReturnDone(returnId);
2389
+ release();
2277
2390
  if (flow === "auth-code") {
2278
2391
  opts.onCode?.({
2279
2392
  code,
@@ -2298,6 +2411,7 @@ function useZorealFlow(options) {
2298
2411
  };
2299
2412
  opts.onCredential?.(response);
2300
2413
  } catch (e) {
2414
+ release();
2301
2415
  setPairing(null);
2302
2416
  publishRef.current?.(null);
2303
2417
  if (e instanceof DOMException && e.name === "AbortError") {
@@ -2346,9 +2460,9 @@ function useZorealLogin(options) {
2346
2460
  // src/ring.tsx
2347
2461
  import { useEffect as useEffect3, useLayoutEffect, useRef as useRef3 } from "react";
2348
2462
  import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
2349
- var TAIL = 0.3;
2350
- var STACK = Array.from({ length: 12 }, (_, i) => 12 - i);
2351
- var HALO = [3, 2, 1];
2463
+ var TAIL2 = 0.3;
2464
+ var STACK2 = Array.from({ length: 12 }, (_, i) => 12 - i);
2465
+ var HALO2 = [3, 2, 1];
2352
2466
  function ZorealBusyRing({
2353
2467
  busy,
2354
2468
  radius = 8,
@@ -2387,7 +2501,7 @@ function ZorealBusyRing({
2387
2501
  ry: rx,
2388
2502
  style: {
2389
2503
  strokeDasharray: `calc(var(--zrl-l) * ${len}) calc(var(--zrl-l) * ${1 - len})`,
2390
- "--zrl-s": `calc(var(--zrl-l) * ${-(TAIL - len)})`,
2504
+ "--zrl-s": `calc(var(--zrl-l) * ${-(TAIL2 - len)})`,
2391
2505
  opacity: alpha
2392
2506
  }
2393
2507
  },
@@ -2404,10 +2518,10 @@ function ZorealBusyRing({
2404
2518
  children: [
2405
2519
  children,
2406
2520
  /* @__PURE__ */ jsxs5("svg", { className: cx("ring-svg"), "aria-hidden": "true", children: [
2407
- HALO.map(
2408
- (n, i) => layer(`h${n}`, "ring-halo", TAIL * n / HALO.length, `calc(var(--zrl-glow-opacity) * 0.6 / ${n})`, i === 0 ? measureRef : void 0)
2521
+ HALO2.map(
2522
+ (n, i) => layer(`h${n}`, "ring-halo", TAIL2 * n / HALO2.length, `calc(var(--zrl-glow-opacity) * 0.6 / ${n})`, i === 0 ? measureRef : void 0)
2409
2523
  ),
2410
- STACK.map((n) => layer(`t${n}`, n <= 2 ? "ring-head" : "ring-tail", TAIL * n / STACK.length, String(1 / n)))
2524
+ STACK2.map((n) => layer(`t${n}`, n <= 2 ? "ring-head" : "ring-tail", TAIL2 * n / STACK2.length, String(1 / n)))
2411
2525
  ] })
2412
2526
  ]
2413
2527
  }
@@ -2553,6 +2667,7 @@ export {
2553
2667
  PairingModal,
2554
2668
  ZorealBusyRing,
2555
2669
  ZorealLogin,
2670
+ ZorealMark,
2556
2671
  ZorealOAuthProvider,
2557
2672
  hasGrantedAllScopesZoreal,
2558
2673
  hasGrantedAnyScopeZoreal,