@camstack/ui-library 1.2.339 → 1.2.341
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/CHANGELOG.md +12 -0
- package/dist/index.cjs +58 -19
- package/dist/index.js +58 -19
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.2.341] - 2026-10-28
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Account sign-in fields follow the vendor-login path of the hub login proxy
|
|
15
|
+
|
|
16
|
+
## [1.2.340] - 2026-10-27
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- The account sign-in form waits for the hub to finish the sign-in on its own and keeps the paste box as a fallback.
|
|
21
|
+
|
|
10
22
|
## [1.2.339] - 2026-10-27
|
|
11
23
|
|
|
12
24
|
### Added
|
package/dist/index.cjs
CHANGED
|
@@ -14514,6 +14514,7 @@ Button.displayName = "Button";
|
|
|
14514
14514
|
//#endregion
|
|
14515
14515
|
//#region src/composites/account-sign-in-field.tsx
|
|
14516
14516
|
var INPUT_CLASS$1 = "w-full rounded-md border border-border bg-background px-2.5 py-1.5 text-xs text-foreground focus:border-primary focus:ring-1 focus:ring-primary/30 outline-none disabled:opacity-50 disabled:cursor-not-allowed";
|
|
14517
|
+
var CLAIM_POLL_MS = 2e3;
|
|
14517
14518
|
var BARE_CODE = /^[A-Za-z0-9._~-]{8,}$/;
|
|
14518
14519
|
function isRecord$4(value) {
|
|
14519
14520
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -14557,6 +14558,10 @@ function choicesOf(value) {
|
|
|
14557
14558
|
function selectedChoice(value) {
|
|
14558
14559
|
return typeof value === "string" ? value : "";
|
|
14559
14560
|
}
|
|
14561
|
+
/** A hub-relative path (the proxied login) opens on the hub's own origin. */
|
|
14562
|
+
function openableUrl(url) {
|
|
14563
|
+
return url.startsWith("/") && !url.startsWith("//") ? new URL(url, window.location.origin).toString() : url;
|
|
14564
|
+
}
|
|
14560
14565
|
function shouldComplete(text) {
|
|
14561
14566
|
const trimmed = text.trim();
|
|
14562
14567
|
if (trimmed.length === 0) return false;
|
|
@@ -14595,6 +14600,33 @@ function AccountSignInField({ field, values, disabled, onAction, onChangeMany })
|
|
|
14595
14600
|
setAttemptId(null);
|
|
14596
14601
|
setAuthorizeUrl(null);
|
|
14597
14602
|
};
|
|
14603
|
+
const claimAction = field.claimAction;
|
|
14604
|
+
(0, react$1.useEffect)(() => {
|
|
14605
|
+
if (claimAction === void 0 || attemptId === null || phase !== "pasting" || !onAction) return;
|
|
14606
|
+
let stopped = false;
|
|
14607
|
+
const timer = setInterval(() => {
|
|
14608
|
+
if (inFlight.current) return;
|
|
14609
|
+
onAction(claimAction, field.key, { attemptId }).then((result) => {
|
|
14610
|
+
if (stopped || !isRecord$4(result) || result["pending"] === true) return;
|
|
14611
|
+
stopped = true;
|
|
14612
|
+
applyResult(result);
|
|
14613
|
+
}).catch((err) => {
|
|
14614
|
+
if (stopped) return;
|
|
14615
|
+
stopped = true;
|
|
14616
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
14617
|
+
});
|
|
14618
|
+
}, CLAIM_POLL_MS);
|
|
14619
|
+
return () => {
|
|
14620
|
+
stopped = true;
|
|
14621
|
+
clearInterval(timer);
|
|
14622
|
+
};
|
|
14623
|
+
}, [
|
|
14624
|
+
claimAction,
|
|
14625
|
+
attemptId,
|
|
14626
|
+
phase,
|
|
14627
|
+
onAction,
|
|
14628
|
+
field.key
|
|
14629
|
+
]);
|
|
14598
14630
|
const begin = async () => {
|
|
14599
14631
|
if (!onAction || working) return;
|
|
14600
14632
|
setWorking(true);
|
|
@@ -14612,7 +14644,7 @@ function AccountSignInField({ field, values, disabled, onAction, onChangeMany })
|
|
|
14612
14644
|
setAttemptId(result["attemptId"]);
|
|
14613
14645
|
setAuthorizeUrl(result["authorizeUrl"]);
|
|
14614
14646
|
setPhase("pasting");
|
|
14615
|
-
window.open(result["authorizeUrl"], "_blank", "noopener,noreferrer");
|
|
14647
|
+
window.open(openableUrl(result["authorizeUrl"]), "_blank", "noopener,noreferrer");
|
|
14616
14648
|
} catch (err) {
|
|
14617
14649
|
setError(err instanceof Error ? err.message : String(err));
|
|
14618
14650
|
} finally {
|
|
@@ -14725,24 +14757,31 @@ function AccountSignInField({ field, values, disabled, onAction, onChangeMany })
|
|
|
14725
14757
|
}),
|
|
14726
14758
|
showPaste && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
14727
14759
|
className: "flex flex-col gap-1.5",
|
|
14728
|
-
children: [
|
|
14729
|
-
|
|
14730
|
-
|
|
14731
|
-
|
|
14732
|
-
|
|
14733
|
-
|
|
14734
|
-
|
|
14735
|
-
|
|
14736
|
-
|
|
14737
|
-
|
|
14738
|
-
|
|
14739
|
-
|
|
14740
|
-
|
|
14741
|
-
|
|
14742
|
-
|
|
14743
|
-
|
|
14744
|
-
|
|
14745
|
-
|
|
14760
|
+
children: [
|
|
14761
|
+
authorizeUrl !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
14762
|
+
className: "text-[11px] text-primary break-all",
|
|
14763
|
+
href: authorizeUrl,
|
|
14764
|
+
target: "_blank",
|
|
14765
|
+
rel: "noopener noreferrer",
|
|
14766
|
+
children: t("uiLibrary.accountSignIn.open", "Open the sign-in page")
|
|
14767
|
+
}),
|
|
14768
|
+
claimAction !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
14769
|
+
className: "text-[11px] text-muted-foreground",
|
|
14770
|
+
children: t("uiLibrary.accountSignIn.pasteFallback", "If the page does not finish, paste the address it stops on here.")
|
|
14771
|
+
}),
|
|
14772
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
14773
|
+
className: `${INPUT_CLASS$1} min-h-[60px] resize-y`,
|
|
14774
|
+
"aria-label": t("uiLibrary.accountSignIn.paste", "Redirect address or code"),
|
|
14775
|
+
placeholder: field.pastePlaceholder,
|
|
14776
|
+
value: paste,
|
|
14777
|
+
disabled: disabled || working,
|
|
14778
|
+
onChange: (event) => {
|
|
14779
|
+
const next = event.target.value;
|
|
14780
|
+
setPaste(next);
|
|
14781
|
+
if (shouldComplete(next)) complete(next);
|
|
14782
|
+
}
|
|
14783
|
+
})
|
|
14784
|
+
]
|
|
14746
14785
|
}),
|
|
14747
14786
|
error !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
14748
14787
|
className: "text-[11px] text-danger",
|
package/dist/index.js
CHANGED
|
@@ -14490,6 +14490,7 @@ Button.displayName = "Button";
|
|
|
14490
14490
|
//#endregion
|
|
14491
14491
|
//#region src/composites/account-sign-in-field.tsx
|
|
14492
14492
|
var INPUT_CLASS$1 = "w-full rounded-md border border-border bg-background px-2.5 py-1.5 text-xs text-foreground focus:border-primary focus:ring-1 focus:ring-primary/30 outline-none disabled:opacity-50 disabled:cursor-not-allowed";
|
|
14493
|
+
var CLAIM_POLL_MS = 2e3;
|
|
14493
14494
|
var BARE_CODE = /^[A-Za-z0-9._~-]{8,}$/;
|
|
14494
14495
|
function isRecord$4(value) {
|
|
14495
14496
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -14533,6 +14534,10 @@ function choicesOf(value) {
|
|
|
14533
14534
|
function selectedChoice(value) {
|
|
14534
14535
|
return typeof value === "string" ? value : "";
|
|
14535
14536
|
}
|
|
14537
|
+
/** A hub-relative path (the proxied login) opens on the hub's own origin. */
|
|
14538
|
+
function openableUrl(url) {
|
|
14539
|
+
return url.startsWith("/") && !url.startsWith("//") ? new URL(url, window.location.origin).toString() : url;
|
|
14540
|
+
}
|
|
14536
14541
|
function shouldComplete(text) {
|
|
14537
14542
|
const trimmed = text.trim();
|
|
14538
14543
|
if (trimmed.length === 0) return false;
|
|
@@ -14571,6 +14576,33 @@ function AccountSignInField({ field, values, disabled, onAction, onChangeMany })
|
|
|
14571
14576
|
setAttemptId(null);
|
|
14572
14577
|
setAuthorizeUrl(null);
|
|
14573
14578
|
};
|
|
14579
|
+
const claimAction = field.claimAction;
|
|
14580
|
+
useEffect(() => {
|
|
14581
|
+
if (claimAction === void 0 || attemptId === null || phase !== "pasting" || !onAction) return;
|
|
14582
|
+
let stopped = false;
|
|
14583
|
+
const timer = setInterval(() => {
|
|
14584
|
+
if (inFlight.current) return;
|
|
14585
|
+
onAction(claimAction, field.key, { attemptId }).then((result) => {
|
|
14586
|
+
if (stopped || !isRecord$4(result) || result["pending"] === true) return;
|
|
14587
|
+
stopped = true;
|
|
14588
|
+
applyResult(result);
|
|
14589
|
+
}).catch((err) => {
|
|
14590
|
+
if (stopped) return;
|
|
14591
|
+
stopped = true;
|
|
14592
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
14593
|
+
});
|
|
14594
|
+
}, CLAIM_POLL_MS);
|
|
14595
|
+
return () => {
|
|
14596
|
+
stopped = true;
|
|
14597
|
+
clearInterval(timer);
|
|
14598
|
+
};
|
|
14599
|
+
}, [
|
|
14600
|
+
claimAction,
|
|
14601
|
+
attemptId,
|
|
14602
|
+
phase,
|
|
14603
|
+
onAction,
|
|
14604
|
+
field.key
|
|
14605
|
+
]);
|
|
14574
14606
|
const begin = async () => {
|
|
14575
14607
|
if (!onAction || working) return;
|
|
14576
14608
|
setWorking(true);
|
|
@@ -14588,7 +14620,7 @@ function AccountSignInField({ field, values, disabled, onAction, onChangeMany })
|
|
|
14588
14620
|
setAttemptId(result["attemptId"]);
|
|
14589
14621
|
setAuthorizeUrl(result["authorizeUrl"]);
|
|
14590
14622
|
setPhase("pasting");
|
|
14591
|
-
window.open(result["authorizeUrl"], "_blank", "noopener,noreferrer");
|
|
14623
|
+
window.open(openableUrl(result["authorizeUrl"]), "_blank", "noopener,noreferrer");
|
|
14592
14624
|
} catch (err) {
|
|
14593
14625
|
setError(err instanceof Error ? err.message : String(err));
|
|
14594
14626
|
} finally {
|
|
@@ -14701,24 +14733,31 @@ function AccountSignInField({ field, values, disabled, onAction, onChangeMany })
|
|
|
14701
14733
|
}),
|
|
14702
14734
|
showPaste && /* @__PURE__ */ jsxs("div", {
|
|
14703
14735
|
className: "flex flex-col gap-1.5",
|
|
14704
|
-
children: [
|
|
14705
|
-
|
|
14706
|
-
|
|
14707
|
-
|
|
14708
|
-
|
|
14709
|
-
|
|
14710
|
-
|
|
14711
|
-
|
|
14712
|
-
|
|
14713
|
-
|
|
14714
|
-
|
|
14715
|
-
|
|
14716
|
-
|
|
14717
|
-
|
|
14718
|
-
|
|
14719
|
-
|
|
14720
|
-
|
|
14721
|
-
|
|
14736
|
+
children: [
|
|
14737
|
+
authorizeUrl !== null && /* @__PURE__ */ jsx("a", {
|
|
14738
|
+
className: "text-[11px] text-primary break-all",
|
|
14739
|
+
href: authorizeUrl,
|
|
14740
|
+
target: "_blank",
|
|
14741
|
+
rel: "noopener noreferrer",
|
|
14742
|
+
children: t("uiLibrary.accountSignIn.open", "Open the sign-in page")
|
|
14743
|
+
}),
|
|
14744
|
+
claimAction !== void 0 && /* @__PURE__ */ jsx("p", {
|
|
14745
|
+
className: "text-[11px] text-muted-foreground",
|
|
14746
|
+
children: t("uiLibrary.accountSignIn.pasteFallback", "If the page does not finish, paste the address it stops on here.")
|
|
14747
|
+
}),
|
|
14748
|
+
/* @__PURE__ */ jsx("textarea", {
|
|
14749
|
+
className: `${INPUT_CLASS$1} min-h-[60px] resize-y`,
|
|
14750
|
+
"aria-label": t("uiLibrary.accountSignIn.paste", "Redirect address or code"),
|
|
14751
|
+
placeholder: field.pastePlaceholder,
|
|
14752
|
+
value: paste,
|
|
14753
|
+
disabled: disabled || working,
|
|
14754
|
+
onChange: (event) => {
|
|
14755
|
+
const next = event.target.value;
|
|
14756
|
+
setPaste(next);
|
|
14757
|
+
if (shouldComplete(next)) complete(next);
|
|
14758
|
+
}
|
|
14759
|
+
})
|
|
14760
|
+
]
|
|
14722
14761
|
}),
|
|
14723
14762
|
error !== null && /* @__PURE__ */ jsx("p", {
|
|
14724
14763
|
className: "text-[11px] text-danger",
|