@medialane/ui 0.171.0 → 0.172.0

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.
@@ -33,6 +33,8 @@ function ActionDialog({ open, onClose, width = 540, shadow = true, children }) {
33
33
  position: "fixed",
34
34
  inset: 0,
35
35
  zIndex: 1e3,
36
+ // Clickable even while another modal has disabled pointer events on the page.
37
+ pointerEvents: "auto",
36
38
  display: "flex",
37
39
  alignItems: "center",
38
40
  justifyContent: "center",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/action-dialog.tsx"],"sourcesContent":["\"use client\";\n\nexport interface ActionDialogProps {\n open: boolean;\n onClose: () => void;\n\n width?: number;\n shadow?: boolean;\n children: React.ReactNode;\n}\n\nexport function ActionDialog({ open, onClose, width = 540, shadow = true, children }: ActionDialogProps) {\n if (!open) return null;\n return (\n <div\n onClick={onClose}\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: 1000,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: 24,\n backdropFilter: 'blur(28px) saturate(150%)',\n WebkitBackdropFilter: 'blur(28px) saturate(150%)',\n background: 'rgba(6,7,15,0.55)',\n animation: 'mlFade .18s ease',\n }}\n >\n <div\n onClick={e => e.stopPropagation()}\n className=\"bg-card text-card-foreground border border-border overflow-y-auto\"\n style={{\n width,\n maxWidth: '100%',\n maxHeight: '92vh',\n borderRadius: 24,\n boxShadow: shadow ? '0 50px 120px rgba(0,0,0,0.6)' : 'none',\n animation: 'mlPop .22s cubic-bezier(.2,.8,.3,1)',\n }}\n >\n {children}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA8BM;AAnBC,SAAS,aAAa,EAAE,MAAM,SAAS,QAAQ,KAAK,SAAS,MAAM,SAAS,GAAsB;AACvG,MAAI,CAAC,KAAM,QAAO;AAClB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT,OAAO;AAAA,QACL,UAAU;AAAA,QACV,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,SAAS;AAAA,QACT,gBAAgB;AAAA,QAChB,sBAAsB;AAAA,QACtB,YAAY;AAAA,QACZ,WAAW;AAAA,MACb;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,SAAS,OAAK,EAAE,gBAAgB;AAAA,UAChC,WAAU;AAAA,UACV,OAAO;AAAA,YACL;AAAA,YACA,UAAU;AAAA,YACV,WAAW;AAAA,YACX,cAAc;AAAA,YACd,WAAW,SAAS,iCAAiC;AAAA,YACrD,WAAW;AAAA,UACb;AAAA,UAEC;AAAA;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/action-dialog.tsx"],"sourcesContent":["\"use client\";\n\nexport interface ActionDialogProps {\n open: boolean;\n onClose: () => void;\n\n width?: number;\n shadow?: boolean;\n children: React.ReactNode;\n}\n\nexport function ActionDialog({ open, onClose, width = 540, shadow = true, children }: ActionDialogProps) {\n if (!open) return null;\n return (\n <div\n onClick={onClose}\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: 1000,\n // Clickable even while another modal has disabled pointer events on the page.\n pointerEvents: 'auto',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: 24,\n backdropFilter: 'blur(28px) saturate(150%)',\n WebkitBackdropFilter: 'blur(28px) saturate(150%)',\n background: 'rgba(6,7,15,0.55)',\n animation: 'mlFade .18s ease',\n }}\n >\n <div\n onClick={e => e.stopPropagation()}\n className=\"bg-card text-card-foreground border border-border overflow-y-auto\"\n style={{\n width,\n maxWidth: '100%',\n maxHeight: '92vh',\n borderRadius: 24,\n boxShadow: shadow ? '0 50px 120px rgba(0,0,0,0.6)' : 'none',\n animation: 'mlPop .22s cubic-bezier(.2,.8,.3,1)',\n }}\n >\n {children}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgCM;AArBC,SAAS,aAAa,EAAE,MAAM,SAAS,QAAQ,KAAK,SAAS,MAAM,SAAS,GAAsB;AACvG,MAAI,CAAC,KAAM,QAAO;AAClB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT,OAAO;AAAA,QACL,UAAU;AAAA,QACV,OAAO;AAAA,QACP,QAAQ;AAAA;AAAA,QAER,eAAe;AAAA,QACf,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,SAAS;AAAA,QACT,gBAAgB;AAAA,QAChB,sBAAsB;AAAA,QACtB,YAAY;AAAA,QACZ,WAAW;AAAA,MACb;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,SAAS,OAAK,EAAE,gBAAgB;AAAA,UAChC,WAAU;AAAA,UACV,OAAO;AAAA,YACL;AAAA,YACA,UAAU;AAAA,YACV,WAAW;AAAA,YACX,cAAc;AAAA,YACd,WAAW,SAAS,iCAAiC;AAAA,YACrD,WAAW;AAAA,UACb;AAAA,UAEC;AAAA;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -10,6 +10,8 @@ function ActionDialog({ open, onClose, width = 540, shadow = true, children }) {
10
10
  position: "fixed",
11
11
  inset: 0,
12
12
  zIndex: 1e3,
13
+ // Clickable even while another modal has disabled pointer events on the page.
14
+ pointerEvents: "auto",
13
15
  display: "flex",
14
16
  alignItems: "center",
15
17
  justifyContent: "center",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/action-dialog.tsx"],"sourcesContent":["\"use client\";\n\nexport interface ActionDialogProps {\n open: boolean;\n onClose: () => void;\n\n width?: number;\n shadow?: boolean;\n children: React.ReactNode;\n}\n\nexport function ActionDialog({ open, onClose, width = 540, shadow = true, children }: ActionDialogProps) {\n if (!open) return null;\n return (\n <div\n onClick={onClose}\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: 1000,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: 24,\n backdropFilter: 'blur(28px) saturate(150%)',\n WebkitBackdropFilter: 'blur(28px) saturate(150%)',\n background: 'rgba(6,7,15,0.55)',\n animation: 'mlFade .18s ease',\n }}\n >\n <div\n onClick={e => e.stopPropagation()}\n className=\"bg-card text-card-foreground border border-border overflow-y-auto\"\n style={{\n width,\n maxWidth: '100%',\n maxHeight: '92vh',\n borderRadius: 24,\n boxShadow: shadow ? '0 50px 120px rgba(0,0,0,0.6)' : 'none',\n animation: 'mlPop .22s cubic-bezier(.2,.8,.3,1)',\n }}\n >\n {children}\n </div>\n </div>\n );\n}\n"],"mappings":";AA8BM;AAnBC,SAAS,aAAa,EAAE,MAAM,SAAS,QAAQ,KAAK,SAAS,MAAM,SAAS,GAAsB;AACvG,MAAI,CAAC,KAAM,QAAO;AAClB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT,OAAO;AAAA,QACL,UAAU;AAAA,QACV,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,SAAS;AAAA,QACT,gBAAgB;AAAA,QAChB,sBAAsB;AAAA,QACtB,YAAY;AAAA,QACZ,WAAW;AAAA,MACb;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,SAAS,OAAK,EAAE,gBAAgB;AAAA,UAChC,WAAU;AAAA,UACV,OAAO;AAAA,YACL;AAAA,YACA,UAAU;AAAA,YACV,WAAW;AAAA,YACX,cAAc;AAAA,YACd,WAAW,SAAS,iCAAiC;AAAA,YACrD,WAAW;AAAA,UACb;AAAA,UAEC;AAAA;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/action-dialog.tsx"],"sourcesContent":["\"use client\";\n\nexport interface ActionDialogProps {\n open: boolean;\n onClose: () => void;\n\n width?: number;\n shadow?: boolean;\n children: React.ReactNode;\n}\n\nexport function ActionDialog({ open, onClose, width = 540, shadow = true, children }: ActionDialogProps) {\n if (!open) return null;\n return (\n <div\n onClick={onClose}\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: 1000,\n // Clickable even while another modal has disabled pointer events on the page.\n pointerEvents: 'auto',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: 24,\n backdropFilter: 'blur(28px) saturate(150%)',\n WebkitBackdropFilter: 'blur(28px) saturate(150%)',\n background: 'rgba(6,7,15,0.55)',\n animation: 'mlFade .18s ease',\n }}\n >\n <div\n onClick={e => e.stopPropagation()}\n className=\"bg-card text-card-foreground border border-border overflow-y-auto\"\n style={{\n width,\n maxWidth: '100%',\n maxHeight: '92vh',\n borderRadius: 24,\n boxShadow: shadow ? '0 50px 120px rgba(0,0,0,0.6)' : 'none',\n animation: 'mlPop .22s cubic-bezier(.2,.8,.3,1)',\n }}\n >\n {children}\n </div>\n </div>\n );\n}\n"],"mappings":";AAgCM;AArBC,SAAS,aAAa,EAAE,MAAM,SAAS,QAAQ,KAAK,SAAS,MAAM,SAAS,GAAsB;AACvG,MAAI,CAAC,KAAM,QAAO;AAClB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT,OAAO;AAAA,QACL,UAAU;AAAA,QACV,OAAO;AAAA,QACP,QAAQ;AAAA;AAAA,QAER,eAAe;AAAA,QACf,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,SAAS;AAAA,QACT,gBAAgB;AAAA,QAChB,sBAAsB;AAAA,QACtB,YAAY;AAAA,QACZ,WAAW;AAAA,MACb;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,SAAS,OAAK,EAAE,gBAAgB;AAAA,UAChC,WAAU;AAAA,UACV,OAAO;AAAA,YACL;AAAA,YACA,UAAU;AAAA,YACV,WAAW;AAAA,YACX,cAAc;AAAA,YACd,WAAW,SAAS,iCAAiC;AAAA,YACrD,WAAW;AAAA,UACb;AAAA,UAEC;AAAA;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const buttonVariants: (props?: ({
6
- variant?: "ghost" | "link" | "default" | "destructive" | "outline" | "secondary" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
6
+ variant?: "link" | "default" | "destructive" | "outline" | "ghost" | "secondary" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
7
7
  size?: "icon" | "default" | "sm" | "lg" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const buttonVariants: (props?: ({
6
- variant?: "ghost" | "link" | "default" | "destructive" | "outline" | "secondary" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
6
+ variant?: "link" | "default" | "destructive" | "outline" | "ghost" | "secondary" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
7
7
  size?: "icon" | "default" | "sm" | "lg" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
@@ -27,12 +27,15 @@ var import_jsx_runtime = require("react/jsx-runtime");
27
27
  var import_react = require("react");
28
28
  var import_sdk = require("@medialane/sdk");
29
29
  var import_action_dialog = require("../action-dialog.js");
30
- function feeLabelFor(estimate) {
31
- if (estimate === "loading" || estimate == null) return null;
32
- const [whole, fraction = ""] = (0, import_sdk.formatAmount)(estimate.feeRaw.toString(), 18).split(".");
30
+ function amountLabel(raw, unit) {
31
+ const [whole, fraction = ""] = (0, import_sdk.formatAmount)(raw.toString(), 18).split(".");
33
32
  const trimmed = fraction.slice(0, 6).replace(/0+$/, "");
34
33
  const amount = trimmed ? `${whole}.${trimmed}` : whole;
35
- return `${amount} ${estimate.unit === "FRI" ? "STRK" : "ETH"}`;
34
+ return `${amount} ${unit === "FRI" ? "STRK" : "ETH"}`;
35
+ }
36
+ function feeLabelFor(estimate) {
37
+ if (estimate === "loading" || estimate == null) return null;
38
+ return amountLabel(estimate.feeRaw, estimate.unit);
36
39
  }
37
40
  function SelfFundConsentDialog({ consent }) {
38
41
  const [pending, setPending] = (0, import_react.useState)(null);
@@ -52,13 +55,21 @@ function SelfFundConsentDialog({ consent }) {
52
55
  setPending(null);
53
56
  };
54
57
  const label = feeLabelFor(pending?.feeEstimate ?? null);
58
+ const estimate = pending?.feeEstimate && pending.feeEstimate !== "loading" ? pending.feeEstimate : null;
59
+ const balanceLabel = estimate?.balanceRaw != null ? amountLabel(estimate.balanceRaw, estimate.unit) : null;
60
+ const notEnough = estimate?.balanceRaw != null && estimate.balanceRaw < estimate.feeRaw;
55
61
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_action_dialog.ActionDialog, { open: pending !== null, onClose: () => respond(false), width: 420, shadow: false, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "p-6 space-y-4", children: [
56
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-lg font-semibold", children: "Pay this transaction" }),
57
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-muted-foreground", children: "This transaction will cover onchain fees with funds from your account." }),
62
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-lg font-semibold", children: "Network fee needed" }),
63
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-muted-foreground", children: "Medialane usually covers network fees for you, but can't right now. You can pay this one from your wallet, or try again later." }),
58
64
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "rounded-lg bg-muted px-4 py-3 flex items-center justify-between", children: [
59
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm text-muted-foreground", children: "Estimated cost" }),
60
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm font-semibold", children: label ?? "Estimating\u2026" })
65
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm text-muted-foreground", children: "Network fee" }),
66
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm font-semibold", children: label ? `\u2248 ${label}` : "Estimating\u2026" })
67
+ ] }),
68
+ balanceLabel && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between px-4", children: [
69
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm text-muted-foreground", children: "Your balance" }),
70
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm font-semibold", children: balanceLabel })
61
71
  ] }),
72
+ notEnough && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-destructive", children: "You don't have enough to pay this fee. Try again later, when Medialane can cover it." }),
62
73
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex justify-end gap-2", children: [
63
74
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
64
75
  "button",
@@ -66,7 +77,7 @@ function SelfFundConsentDialog({ consent }) {
66
77
  type: "button",
67
78
  onClick: () => respond(false),
68
79
  className: "px-4 py-2 rounded-lg text-sm font-medium text-muted-foreground hover:bg-muted transition-colors",
69
- children: "Cancel"
80
+ children: "Try again later"
70
81
  }
71
82
  ),
72
83
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -74,8 +85,9 @@ function SelfFundConsentDialog({ consent }) {
74
85
  {
75
86
  type: "button",
76
87
  onClick: () => respond(true),
77
- className: "px-4 py-2 rounded-lg text-sm font-medium bg-primary text-primary-foreground hover:opacity-90 transition-opacity",
78
- children: "Pay with my wallet"
88
+ disabled: notEnough,
89
+ className: "px-4 py-2 rounded-lg text-sm font-medium bg-primary text-primary-foreground hover:opacity-90 transition-opacity disabled:opacity-50 disabled:cursor-not-allowed",
90
+ children: label ? `Pay ${label}` : "Pay from my wallet"
79
91
  }
80
92
  )
81
93
  ] })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/wallet/self-fund-consent-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { formatAmount } from \"@medialane/sdk\";\nimport type { SelfFundConsent, SelfFundFeeEstimate } from \"@medialane/sdk/starknet\";\nimport { ActionDialog } from \"../action-dialog.js\";\n\ninterface PendingRequest {\n resolve: (consented: boolean) => void;\n feeEstimate: SelfFundFeeEstimate | null | \"loading\";\n}\n\nexport function feeLabelFor(estimate: SelfFundFeeEstimate | null | \"loading\"): string | null {\n if (estimate === \"loading\" || estimate == null) return null;\n const [whole, fraction = \"\"] = formatAmount(estimate.feeRaw.toString(), 18).split(\".\");\n const trimmed = fraction.slice(0, 6).replace(/0+$/, \"\");\n const amount = trimmed ? `${whole}.${trimmed}` : whole;\n return `${amount} ${estimate.unit === \"FRI\" ? \"STRK\" : \"ETH\"}`;\n}\n\nexport function SelfFundConsentDialog({ consent }: { consent: SelfFundConsent }) {\n const [pending, setPending] = useState<PendingRequest | null>(null);\n\n useEffect(() => {\n consent.registerHandler((feeEstimatePromise) => {\n return new Promise<boolean>((resolve) => {\n setPending({ resolve, feeEstimate: \"loading\" });\n void feeEstimatePromise.then((feeEstimate) => {\n setPending((current) => (current ? { ...current, feeEstimate } : current));\n });\n });\n });\n return () => consent.registerHandler(null);\n }, [consent]);\n\n const respond = (consented: boolean) => {\n pending?.resolve(consented);\n setPending(null);\n };\n\n const label = feeLabelFor(pending?.feeEstimate ?? null);\n\n return (\n <ActionDialog open={pending !== null} onClose={() => respond(false)} width={420} shadow={false}>\n <div className=\"p-6 space-y-4\">\n <h2 className=\"text-lg font-semibold\">Pay this transaction</h2>\n <p className=\"text-sm text-muted-foreground\">\n This transaction will cover onchain fees with funds from your account.\n </p>\n <div className=\"rounded-lg bg-muted px-4 py-3 flex items-center justify-between\">\n <span className=\"text-sm text-muted-foreground\">Estimated cost</span>\n <span className=\"text-sm font-semibold\">{label ?? \"Estimating…\"}</span>\n </div>\n <div className=\"flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => respond(false)}\n className=\"px-4 py-2 rounded-lg text-sm font-medium text-muted-foreground hover:bg-muted transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={() => respond(true)}\n className=\"px-4 py-2 rounded-lg text-sm font-medium bg-primary text-primary-foreground hover:opacity-90 transition-opacity\"\n >\n Pay with my wallet\n </button>\n </div>\n </div>\n </ActionDialog>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6CQ;AA3CR,mBAAoC;AACpC,iBAA6B;AAE7B,2BAA6B;AAOtB,SAAS,YAAY,UAAiE;AAC3F,MAAI,aAAa,aAAa,YAAY,KAAM,QAAO;AACvD,QAAM,CAAC,OAAO,WAAW,EAAE,QAAI,yBAAa,SAAS,OAAO,SAAS,GAAG,EAAE,EAAE,MAAM,GAAG;AACrF,QAAM,UAAU,SAAS,MAAM,GAAG,CAAC,EAAE,QAAQ,OAAO,EAAE;AACtD,QAAM,SAAS,UAAU,GAAG,KAAK,IAAI,OAAO,KAAK;AACjD,SAAO,GAAG,MAAM,IAAI,SAAS,SAAS,QAAQ,SAAS,KAAK;AAC9D;AAEO,SAAS,sBAAsB,EAAE,QAAQ,GAAiC;AAC/E,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAgC,IAAI;AAElE,8BAAU,MAAM;AACd,YAAQ,gBAAgB,CAAC,uBAAuB;AAC9C,aAAO,IAAI,QAAiB,CAAC,YAAY;AACvC,mBAAW,EAAE,SAAS,aAAa,UAAU,CAAC;AAC9C,aAAK,mBAAmB,KAAK,CAAC,gBAAgB;AAC5C,qBAAW,CAAC,YAAa,UAAU,EAAE,GAAG,SAAS,YAAY,IAAI,OAAQ;AAAA,QAC3E,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AACD,WAAO,MAAM,QAAQ,gBAAgB,IAAI;AAAA,EAC3C,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,UAAU,CAAC,cAAuB;AACtC,aAAS,QAAQ,SAAS;AAC1B,eAAW,IAAI;AAAA,EACjB;AAEA,QAAM,QAAQ,YAAY,SAAS,eAAe,IAAI;AAEtD,SACE,4CAAC,qCAAa,MAAM,YAAY,MAAM,SAAS,MAAM,QAAQ,KAAK,GAAG,OAAO,KAAK,QAAQ,OACvF,uDAAC,SAAI,WAAU,iBACb;AAAA,gDAAC,QAAG,WAAU,yBAAwB,kCAAoB;AAAA,IAC1D,4CAAC,OAAE,WAAU,iCAAgC,oFAE7C;AAAA,IACA,6CAAC,SAAI,WAAU,mEACb;AAAA,kDAAC,UAAK,WAAU,iCAAgC,4BAAc;AAAA,MAC9D,4CAAC,UAAK,WAAU,yBAAyB,mBAAS,oBAAc;AAAA,OAClE;AAAA,IACA,6CAAC,SAAI,WAAU,0BACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,MAAM,QAAQ,KAAK;AAAA,UAC5B,WAAU;AAAA,UACX;AAAA;AAAA,MAED;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,MAAM,QAAQ,IAAI;AAAA,UAC3B,WAAU;AAAA,UACX;AAAA;AAAA,MAED;AAAA,OACF;AAAA,KACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/wallet/self-fund-consent-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { formatAmount } from \"@medialane/sdk\";\nimport type { SelfFundConsent, SelfFundFeeEstimate } from \"@medialane/sdk/starknet\";\nimport { ActionDialog } from \"../action-dialog.js\";\n\ninterface PendingRequest {\n resolve: (consented: boolean) => void;\n feeEstimate: SelfFundFeeEstimate | null | \"loading\";\n}\n\nfunction amountLabel(raw: bigint, unit: string): string {\n const [whole, fraction = \"\"] = formatAmount(raw.toString(), 18).split(\".\");\n const trimmed = fraction.slice(0, 6).replace(/0+$/, \"\");\n const amount = trimmed ? `${whole}.${trimmed}` : whole;\n return `${amount} ${unit === \"FRI\" ? \"STRK\" : \"ETH\"}`;\n}\n\nexport function feeLabelFor(estimate: SelfFundFeeEstimate | null | \"loading\"): string | null {\n if (estimate === \"loading\" || estimate == null) return null;\n return amountLabel(estimate.feeRaw, estimate.unit);\n}\n\nexport function SelfFundConsentDialog({ consent }: { consent: SelfFundConsent }) {\n const [pending, setPending] = useState<PendingRequest | null>(null);\n\n useEffect(() => {\n consent.registerHandler((feeEstimatePromise) => {\n return new Promise<boolean>((resolve) => {\n setPending({ resolve, feeEstimate: \"loading\" });\n void feeEstimatePromise.then((feeEstimate) => {\n setPending((current) => (current ? { ...current, feeEstimate } : current));\n });\n });\n });\n return () => consent.registerHandler(null);\n }, [consent]);\n\n const respond = (consented: boolean) => {\n pending?.resolve(consented);\n setPending(null);\n };\n\n const label = feeLabelFor(pending?.feeEstimate ?? null);\n const estimate = pending?.feeEstimate && pending.feeEstimate !== \"loading\" ? pending.feeEstimate : null;\n const balanceLabel = estimate?.balanceRaw != null ? amountLabel(estimate.balanceRaw, estimate.unit) : null;\n const notEnough = estimate?.balanceRaw != null && estimate.balanceRaw < estimate.feeRaw;\n\n return (\n <ActionDialog open={pending !== null} onClose={() => respond(false)} width={420} shadow={false}>\n <div className=\"p-6 space-y-4\">\n <h2 className=\"text-lg font-semibold\">Network fee needed</h2>\n <p className=\"text-sm text-muted-foreground\">\n Medialane usually covers network fees for you, but can&apos;t right now. You can pay this one from your\n wallet, or try again later.\n </p>\n <div className=\"rounded-lg bg-muted px-4 py-3 flex items-center justify-between\">\n <span className=\"text-sm text-muted-foreground\">Network fee</span>\n <span className=\"text-sm font-semibold\">{label ? `≈ ${label}` : \"Estimating…\"}</span>\n </div>\n {balanceLabel && (\n <div className=\"flex items-center justify-between px-4\">\n <span className=\"text-sm text-muted-foreground\">Your balance</span>\n <span className=\"text-sm font-semibold\">{balanceLabel}</span>\n </div>\n )}\n {notEnough && (\n <p className=\"text-sm text-destructive\">\n You don&apos;t have enough to pay this fee. Try again later, when Medialane can cover it.\n </p>\n )}\n <div className=\"flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => respond(false)}\n className=\"px-4 py-2 rounded-lg text-sm font-medium text-muted-foreground hover:bg-muted transition-colors\"\n >\n Try again later\n </button>\n <button\n type=\"button\"\n onClick={() => respond(true)}\n disabled={notEnough}\n className=\"px-4 py-2 rounded-lg text-sm font-medium bg-primary text-primary-foreground hover:opacity-90 transition-opacity disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {label ? `Pay ${label}` : \"Pay from my wallet\"}\n </button>\n </div>\n </div>\n </ActionDialog>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoDQ;AAlDR,mBAAoC;AACpC,iBAA6B;AAE7B,2BAA6B;AAO7B,SAAS,YAAY,KAAa,MAAsB;AACtD,QAAM,CAAC,OAAO,WAAW,EAAE,QAAI,yBAAa,IAAI,SAAS,GAAG,EAAE,EAAE,MAAM,GAAG;AACzE,QAAM,UAAU,SAAS,MAAM,GAAG,CAAC,EAAE,QAAQ,OAAO,EAAE;AACtD,QAAM,SAAS,UAAU,GAAG,KAAK,IAAI,OAAO,KAAK;AACjD,SAAO,GAAG,MAAM,IAAI,SAAS,QAAQ,SAAS,KAAK;AACrD;AAEO,SAAS,YAAY,UAAiE;AAC3F,MAAI,aAAa,aAAa,YAAY,KAAM,QAAO;AACvD,SAAO,YAAY,SAAS,QAAQ,SAAS,IAAI;AACnD;AAEO,SAAS,sBAAsB,EAAE,QAAQ,GAAiC;AAC/E,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAgC,IAAI;AAElE,8BAAU,MAAM;AACd,YAAQ,gBAAgB,CAAC,uBAAuB;AAC9C,aAAO,IAAI,QAAiB,CAAC,YAAY;AACvC,mBAAW,EAAE,SAAS,aAAa,UAAU,CAAC;AAC9C,aAAK,mBAAmB,KAAK,CAAC,gBAAgB;AAC5C,qBAAW,CAAC,YAAa,UAAU,EAAE,GAAG,SAAS,YAAY,IAAI,OAAQ;AAAA,QAC3E,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AACD,WAAO,MAAM,QAAQ,gBAAgB,IAAI;AAAA,EAC3C,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,UAAU,CAAC,cAAuB;AACtC,aAAS,QAAQ,SAAS;AAC1B,eAAW,IAAI;AAAA,EACjB;AAEA,QAAM,QAAQ,YAAY,SAAS,eAAe,IAAI;AACtD,QAAM,WAAW,SAAS,eAAe,QAAQ,gBAAgB,YAAY,QAAQ,cAAc;AACnG,QAAM,eAAe,UAAU,cAAc,OAAO,YAAY,SAAS,YAAY,SAAS,IAAI,IAAI;AACtG,QAAM,YAAY,UAAU,cAAc,QAAQ,SAAS,aAAa,SAAS;AAEjF,SACE,4CAAC,qCAAa,MAAM,YAAY,MAAM,SAAS,MAAM,QAAQ,KAAK,GAAG,OAAO,KAAK,QAAQ,OACvF,uDAAC,SAAI,WAAU,iBACb;AAAA,gDAAC,QAAG,WAAU,yBAAwB,gCAAkB;AAAA,IACxD,4CAAC,OAAE,WAAU,iCAAgC,4IAG7C;AAAA,IACA,6CAAC,SAAI,WAAU,mEACb;AAAA,kDAAC,UAAK,WAAU,iCAAgC,yBAAW;AAAA,MAC3D,4CAAC,UAAK,WAAU,yBAAyB,kBAAQ,UAAK,KAAK,KAAK,oBAAc;AAAA,OAChF;AAAA,IACC,gBACC,6CAAC,SAAI,WAAU,0CACb;AAAA,kDAAC,UAAK,WAAU,iCAAgC,0BAAY;AAAA,MAC5D,4CAAC,UAAK,WAAU,yBAAyB,wBAAa;AAAA,OACxD;AAAA,IAED,aACC,4CAAC,OAAE,WAAU,4BAA2B,kGAExC;AAAA,IAEF,6CAAC,SAAI,WAAU,0BACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,MAAM,QAAQ,KAAK;AAAA,UAC5B,WAAU;AAAA,UACX;AAAA;AAAA,MAED;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,MAAM,QAAQ,IAAI;AAAA,UAC3B,UAAU;AAAA,UACV,WAAU;AAAA,UAET,kBAAQ,OAAO,KAAK,KAAK;AAAA;AAAA,MAC5B;AAAA,OACF;AAAA,KACF,GACF;AAEJ;","names":[]}
@@ -3,12 +3,15 @@ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useEffect, useState } from "react";
4
4
  import { formatAmount } from "@medialane/sdk";
5
5
  import { ActionDialog } from "../action-dialog.js";
6
- function feeLabelFor(estimate) {
7
- if (estimate === "loading" || estimate == null) return null;
8
- const [whole, fraction = ""] = formatAmount(estimate.feeRaw.toString(), 18).split(".");
6
+ function amountLabel(raw, unit) {
7
+ const [whole, fraction = ""] = formatAmount(raw.toString(), 18).split(".");
9
8
  const trimmed = fraction.slice(0, 6).replace(/0+$/, "");
10
9
  const amount = trimmed ? `${whole}.${trimmed}` : whole;
11
- return `${amount} ${estimate.unit === "FRI" ? "STRK" : "ETH"}`;
10
+ return `${amount} ${unit === "FRI" ? "STRK" : "ETH"}`;
11
+ }
12
+ function feeLabelFor(estimate) {
13
+ if (estimate === "loading" || estimate == null) return null;
14
+ return amountLabel(estimate.feeRaw, estimate.unit);
12
15
  }
13
16
  function SelfFundConsentDialog({ consent }) {
14
17
  const [pending, setPending] = useState(null);
@@ -28,13 +31,21 @@ function SelfFundConsentDialog({ consent }) {
28
31
  setPending(null);
29
32
  };
30
33
  const label = feeLabelFor(pending?.feeEstimate ?? null);
34
+ const estimate = pending?.feeEstimate && pending.feeEstimate !== "loading" ? pending.feeEstimate : null;
35
+ const balanceLabel = estimate?.balanceRaw != null ? amountLabel(estimate.balanceRaw, estimate.unit) : null;
36
+ const notEnough = estimate?.balanceRaw != null && estimate.balanceRaw < estimate.feeRaw;
31
37
  return /* @__PURE__ */ jsx(ActionDialog, { open: pending !== null, onClose: () => respond(false), width: 420, shadow: false, children: /* @__PURE__ */ jsxs("div", { className: "p-6 space-y-4", children: [
32
- /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: "Pay this transaction" }),
33
- /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "This transaction will cover onchain fees with funds from your account." }),
38
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: "Network fee needed" }),
39
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Medialane usually covers network fees for you, but can't right now. You can pay this one from your wallet, or try again later." }),
34
40
  /* @__PURE__ */ jsxs("div", { className: "rounded-lg bg-muted px-4 py-3 flex items-center justify-between", children: [
35
- /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "Estimated cost" }),
36
- /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: label ?? "Estimating\u2026" })
41
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "Network fee" }),
42
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: label ? `\u2248 ${label}` : "Estimating\u2026" })
43
+ ] }),
44
+ balanceLabel && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4", children: [
45
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "Your balance" }),
46
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: balanceLabel })
37
47
  ] }),
48
+ notEnough && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: "You don't have enough to pay this fee. Try again later, when Medialane can cover it." }),
38
49
  /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
39
50
  /* @__PURE__ */ jsx(
40
51
  "button",
@@ -42,7 +53,7 @@ function SelfFundConsentDialog({ consent }) {
42
53
  type: "button",
43
54
  onClick: () => respond(false),
44
55
  className: "px-4 py-2 rounded-lg text-sm font-medium text-muted-foreground hover:bg-muted transition-colors",
45
- children: "Cancel"
56
+ children: "Try again later"
46
57
  }
47
58
  ),
48
59
  /* @__PURE__ */ jsx(
@@ -50,8 +61,9 @@ function SelfFundConsentDialog({ consent }) {
50
61
  {
51
62
  type: "button",
52
63
  onClick: () => respond(true),
53
- className: "px-4 py-2 rounded-lg text-sm font-medium bg-primary text-primary-foreground hover:opacity-90 transition-opacity",
54
- children: "Pay with my wallet"
64
+ disabled: notEnough,
65
+ className: "px-4 py-2 rounded-lg text-sm font-medium bg-primary text-primary-foreground hover:opacity-90 transition-opacity disabled:opacity-50 disabled:cursor-not-allowed",
66
+ children: label ? `Pay ${label}` : "Pay from my wallet"
55
67
  }
56
68
  )
57
69
  ] })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/wallet/self-fund-consent-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { formatAmount } from \"@medialane/sdk\";\nimport type { SelfFundConsent, SelfFundFeeEstimate } from \"@medialane/sdk/starknet\";\nimport { ActionDialog } from \"../action-dialog.js\";\n\ninterface PendingRequest {\n resolve: (consented: boolean) => void;\n feeEstimate: SelfFundFeeEstimate | null | \"loading\";\n}\n\nexport function feeLabelFor(estimate: SelfFundFeeEstimate | null | \"loading\"): string | null {\n if (estimate === \"loading\" || estimate == null) return null;\n const [whole, fraction = \"\"] = formatAmount(estimate.feeRaw.toString(), 18).split(\".\");\n const trimmed = fraction.slice(0, 6).replace(/0+$/, \"\");\n const amount = trimmed ? `${whole}.${trimmed}` : whole;\n return `${amount} ${estimate.unit === \"FRI\" ? \"STRK\" : \"ETH\"}`;\n}\n\nexport function SelfFundConsentDialog({ consent }: { consent: SelfFundConsent }) {\n const [pending, setPending] = useState<PendingRequest | null>(null);\n\n useEffect(() => {\n consent.registerHandler((feeEstimatePromise) => {\n return new Promise<boolean>((resolve) => {\n setPending({ resolve, feeEstimate: \"loading\" });\n void feeEstimatePromise.then((feeEstimate) => {\n setPending((current) => (current ? { ...current, feeEstimate } : current));\n });\n });\n });\n return () => consent.registerHandler(null);\n }, [consent]);\n\n const respond = (consented: boolean) => {\n pending?.resolve(consented);\n setPending(null);\n };\n\n const label = feeLabelFor(pending?.feeEstimate ?? null);\n\n return (\n <ActionDialog open={pending !== null} onClose={() => respond(false)} width={420} shadow={false}>\n <div className=\"p-6 space-y-4\">\n <h2 className=\"text-lg font-semibold\">Pay this transaction</h2>\n <p className=\"text-sm text-muted-foreground\">\n This transaction will cover onchain fees with funds from your account.\n </p>\n <div className=\"rounded-lg bg-muted px-4 py-3 flex items-center justify-between\">\n <span className=\"text-sm text-muted-foreground\">Estimated cost</span>\n <span className=\"text-sm font-semibold\">{label ?? \"Estimating…\"}</span>\n </div>\n <div className=\"flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => respond(false)}\n className=\"px-4 py-2 rounded-lg text-sm font-medium text-muted-foreground hover:bg-muted transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={() => respond(true)}\n className=\"px-4 py-2 rounded-lg text-sm font-medium bg-primary text-primary-foreground hover:opacity-90 transition-opacity\"\n >\n Pay with my wallet\n </button>\n </div>\n </div>\n </ActionDialog>\n );\n}\n"],"mappings":";AA6CQ,cAIA,YAJA;AA3CR,SAAS,WAAW,gBAAgB;AACpC,SAAS,oBAAoB;AAE7B,SAAS,oBAAoB;AAOtB,SAAS,YAAY,UAAiE;AAC3F,MAAI,aAAa,aAAa,YAAY,KAAM,QAAO;AACvD,QAAM,CAAC,OAAO,WAAW,EAAE,IAAI,aAAa,SAAS,OAAO,SAAS,GAAG,EAAE,EAAE,MAAM,GAAG;AACrF,QAAM,UAAU,SAAS,MAAM,GAAG,CAAC,EAAE,QAAQ,OAAO,EAAE;AACtD,QAAM,SAAS,UAAU,GAAG,KAAK,IAAI,OAAO,KAAK;AACjD,SAAO,GAAG,MAAM,IAAI,SAAS,SAAS,QAAQ,SAAS,KAAK;AAC9D;AAEO,SAAS,sBAAsB,EAAE,QAAQ,GAAiC;AAC/E,QAAM,CAAC,SAAS,UAAU,IAAI,SAAgC,IAAI;AAElE,YAAU,MAAM;AACd,YAAQ,gBAAgB,CAAC,uBAAuB;AAC9C,aAAO,IAAI,QAAiB,CAAC,YAAY;AACvC,mBAAW,EAAE,SAAS,aAAa,UAAU,CAAC;AAC9C,aAAK,mBAAmB,KAAK,CAAC,gBAAgB;AAC5C,qBAAW,CAAC,YAAa,UAAU,EAAE,GAAG,SAAS,YAAY,IAAI,OAAQ;AAAA,QAC3E,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AACD,WAAO,MAAM,QAAQ,gBAAgB,IAAI;AAAA,EAC3C,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,UAAU,CAAC,cAAuB;AACtC,aAAS,QAAQ,SAAS;AAC1B,eAAW,IAAI;AAAA,EACjB;AAEA,QAAM,QAAQ,YAAY,SAAS,eAAe,IAAI;AAEtD,SACE,oBAAC,gBAAa,MAAM,YAAY,MAAM,SAAS,MAAM,QAAQ,KAAK,GAAG,OAAO,KAAK,QAAQ,OACvF,+BAAC,SAAI,WAAU,iBACb;AAAA,wBAAC,QAAG,WAAU,yBAAwB,kCAAoB;AAAA,IAC1D,oBAAC,OAAE,WAAU,iCAAgC,oFAE7C;AAAA,IACA,qBAAC,SAAI,WAAU,mEACb;AAAA,0BAAC,UAAK,WAAU,iCAAgC,4BAAc;AAAA,MAC9D,oBAAC,UAAK,WAAU,yBAAyB,mBAAS,oBAAc;AAAA,OAClE;AAAA,IACA,qBAAC,SAAI,WAAU,0BACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,MAAM,QAAQ,KAAK;AAAA,UAC5B,WAAU;AAAA,UACX;AAAA;AAAA,MAED;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,MAAM,QAAQ,IAAI;AAAA,UAC3B,WAAU;AAAA,UACX;AAAA;AAAA,MAED;AAAA,OACF;AAAA,KACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/wallet/self-fund-consent-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { formatAmount } from \"@medialane/sdk\";\nimport type { SelfFundConsent, SelfFundFeeEstimate } from \"@medialane/sdk/starknet\";\nimport { ActionDialog } from \"../action-dialog.js\";\n\ninterface PendingRequest {\n resolve: (consented: boolean) => void;\n feeEstimate: SelfFundFeeEstimate | null | \"loading\";\n}\n\nfunction amountLabel(raw: bigint, unit: string): string {\n const [whole, fraction = \"\"] = formatAmount(raw.toString(), 18).split(\".\");\n const trimmed = fraction.slice(0, 6).replace(/0+$/, \"\");\n const amount = trimmed ? `${whole}.${trimmed}` : whole;\n return `${amount} ${unit === \"FRI\" ? \"STRK\" : \"ETH\"}`;\n}\n\nexport function feeLabelFor(estimate: SelfFundFeeEstimate | null | \"loading\"): string | null {\n if (estimate === \"loading\" || estimate == null) return null;\n return amountLabel(estimate.feeRaw, estimate.unit);\n}\n\nexport function SelfFundConsentDialog({ consent }: { consent: SelfFundConsent }) {\n const [pending, setPending] = useState<PendingRequest | null>(null);\n\n useEffect(() => {\n consent.registerHandler((feeEstimatePromise) => {\n return new Promise<boolean>((resolve) => {\n setPending({ resolve, feeEstimate: \"loading\" });\n void feeEstimatePromise.then((feeEstimate) => {\n setPending((current) => (current ? { ...current, feeEstimate } : current));\n });\n });\n });\n return () => consent.registerHandler(null);\n }, [consent]);\n\n const respond = (consented: boolean) => {\n pending?.resolve(consented);\n setPending(null);\n };\n\n const label = feeLabelFor(pending?.feeEstimate ?? null);\n const estimate = pending?.feeEstimate && pending.feeEstimate !== \"loading\" ? pending.feeEstimate : null;\n const balanceLabel = estimate?.balanceRaw != null ? amountLabel(estimate.balanceRaw, estimate.unit) : null;\n const notEnough = estimate?.balanceRaw != null && estimate.balanceRaw < estimate.feeRaw;\n\n return (\n <ActionDialog open={pending !== null} onClose={() => respond(false)} width={420} shadow={false}>\n <div className=\"p-6 space-y-4\">\n <h2 className=\"text-lg font-semibold\">Network fee needed</h2>\n <p className=\"text-sm text-muted-foreground\">\n Medialane usually covers network fees for you, but can&apos;t right now. You can pay this one from your\n wallet, or try again later.\n </p>\n <div className=\"rounded-lg bg-muted px-4 py-3 flex items-center justify-between\">\n <span className=\"text-sm text-muted-foreground\">Network fee</span>\n <span className=\"text-sm font-semibold\">{label ? `≈ ${label}` : \"Estimating…\"}</span>\n </div>\n {balanceLabel && (\n <div className=\"flex items-center justify-between px-4\">\n <span className=\"text-sm text-muted-foreground\">Your balance</span>\n <span className=\"text-sm font-semibold\">{balanceLabel}</span>\n </div>\n )}\n {notEnough && (\n <p className=\"text-sm text-destructive\">\n You don&apos;t have enough to pay this fee. Try again later, when Medialane can cover it.\n </p>\n )}\n <div className=\"flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => respond(false)}\n className=\"px-4 py-2 rounded-lg text-sm font-medium text-muted-foreground hover:bg-muted transition-colors\"\n >\n Try again later\n </button>\n <button\n type=\"button\"\n onClick={() => respond(true)}\n disabled={notEnough}\n className=\"px-4 py-2 rounded-lg text-sm font-medium bg-primary text-primary-foreground hover:opacity-90 transition-opacity disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {label ? `Pay ${label}` : \"Pay from my wallet\"}\n </button>\n </div>\n </div>\n </ActionDialog>\n );\n}\n"],"mappings":";AAoDQ,cAKA,YALA;AAlDR,SAAS,WAAW,gBAAgB;AACpC,SAAS,oBAAoB;AAE7B,SAAS,oBAAoB;AAO7B,SAAS,YAAY,KAAa,MAAsB;AACtD,QAAM,CAAC,OAAO,WAAW,EAAE,IAAI,aAAa,IAAI,SAAS,GAAG,EAAE,EAAE,MAAM,GAAG;AACzE,QAAM,UAAU,SAAS,MAAM,GAAG,CAAC,EAAE,QAAQ,OAAO,EAAE;AACtD,QAAM,SAAS,UAAU,GAAG,KAAK,IAAI,OAAO,KAAK;AACjD,SAAO,GAAG,MAAM,IAAI,SAAS,QAAQ,SAAS,KAAK;AACrD;AAEO,SAAS,YAAY,UAAiE;AAC3F,MAAI,aAAa,aAAa,YAAY,KAAM,QAAO;AACvD,SAAO,YAAY,SAAS,QAAQ,SAAS,IAAI;AACnD;AAEO,SAAS,sBAAsB,EAAE,QAAQ,GAAiC;AAC/E,QAAM,CAAC,SAAS,UAAU,IAAI,SAAgC,IAAI;AAElE,YAAU,MAAM;AACd,YAAQ,gBAAgB,CAAC,uBAAuB;AAC9C,aAAO,IAAI,QAAiB,CAAC,YAAY;AACvC,mBAAW,EAAE,SAAS,aAAa,UAAU,CAAC;AAC9C,aAAK,mBAAmB,KAAK,CAAC,gBAAgB;AAC5C,qBAAW,CAAC,YAAa,UAAU,EAAE,GAAG,SAAS,YAAY,IAAI,OAAQ;AAAA,QAC3E,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AACD,WAAO,MAAM,QAAQ,gBAAgB,IAAI;AAAA,EAC3C,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,UAAU,CAAC,cAAuB;AACtC,aAAS,QAAQ,SAAS;AAC1B,eAAW,IAAI;AAAA,EACjB;AAEA,QAAM,QAAQ,YAAY,SAAS,eAAe,IAAI;AACtD,QAAM,WAAW,SAAS,eAAe,QAAQ,gBAAgB,YAAY,QAAQ,cAAc;AACnG,QAAM,eAAe,UAAU,cAAc,OAAO,YAAY,SAAS,YAAY,SAAS,IAAI,IAAI;AACtG,QAAM,YAAY,UAAU,cAAc,QAAQ,SAAS,aAAa,SAAS;AAEjF,SACE,oBAAC,gBAAa,MAAM,YAAY,MAAM,SAAS,MAAM,QAAQ,KAAK,GAAG,OAAO,KAAK,QAAQ,OACvF,+BAAC,SAAI,WAAU,iBACb;AAAA,wBAAC,QAAG,WAAU,yBAAwB,gCAAkB;AAAA,IACxD,oBAAC,OAAE,WAAU,iCAAgC,4IAG7C;AAAA,IACA,qBAAC,SAAI,WAAU,mEACb;AAAA,0BAAC,UAAK,WAAU,iCAAgC,yBAAW;AAAA,MAC3D,oBAAC,UAAK,WAAU,yBAAyB,kBAAQ,UAAK,KAAK,KAAK,oBAAc;AAAA,OAChF;AAAA,IACC,gBACC,qBAAC,SAAI,WAAU,0CACb;AAAA,0BAAC,UAAK,WAAU,iCAAgC,0BAAY;AAAA,MAC5D,oBAAC,UAAK,WAAU,yBAAyB,wBAAa;AAAA,OACxD;AAAA,IAED,aACC,oBAAC,OAAE,WAAU,4BAA2B,kGAExC;AAAA,IAEF,qBAAC,SAAI,WAAU,0BACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,MAAM,QAAQ,KAAK;AAAA,UAC5B,WAAU;AAAA,UACX;AAAA;AAAA,MAED;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,MAAM,QAAQ,IAAI;AAAA,UAC3B,UAAU;AAAA,UACV,WAAU;AAAA,UAET,kBAAQ,OAAO,KAAK,KAAK;AAAA;AAAA,MAC5B;AAAA,OACF;AAAA,KACF,GACF;AAEJ;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medialane/ui",
3
- "version": "0.171.0",
3
+ "version": "0.172.0",
4
4
  "description": "Shared UI components for Medialane apps",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -51,7 +51,7 @@
51
51
  "preview": "vite --config preview/vite.config.ts"
52
52
  },
53
53
  "peerDependencies": {
54
- "@medialane/sdk": ">=0.142.0",
54
+ "@medialane/sdk": ">=0.144.0",
55
55
  "@radix-ui/react-checkbox": ">=1.1.0",
56
56
  "@radix-ui/react-collapsible": ">=1.1.0",
57
57
  "@radix-ui/react-dialog": ">=1.1.0",
@@ -79,7 +79,7 @@
79
79
  "zod": "^3.25.0"
80
80
  },
81
81
  "devDependencies": {
82
- "@medialane/sdk": "0.142.0",
82
+ "@medialane/sdk": "0.144.0",
83
83
  "@radix-ui/react-checkbox": "^1.3.8",
84
84
  "@radix-ui/react-collapsible": "^1.1.17",
85
85
  "@radix-ui/react-dialog": "^1.1.20",