@dexterai/connect 0.5.0 → 0.7.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.
package/dist/react.d.ts CHANGED
@@ -48,19 +48,21 @@ interface SignInWithDexterProps extends UseSignInWithDexterConfig {
48
48
  onError?: (error: ConnectError) => void;
49
49
  /** Button label when signed out. Default "Sign in with Dexter". */
50
50
  label?: string;
51
- /** className on the root (button when signed out, chip when connected) — for
52
- * full restyling. Brand it from the consumer; the inline defaults are a base. */
51
+ /** Visual variant: 'primary' = filled ember (default), 'secondary' = outline. */
52
+ variant?: 'primary' | 'secondary';
53
+ /** Extra className composed after the brand classes. Prefer overriding the
54
+ * `--dx-*` CSS variables for theming over restyling from scratch. */
53
55
  className?: string;
54
56
  /** Render the built-in connected chip (wallet + balance). Default true.
55
57
  * Set false to render nothing once connected (consumer renders its own UI). */
56
58
  showConnectedChip?: boolean;
57
59
  }
58
60
  /**
59
- * Turnkey "Sign in with Dexter" element. Signed out → an ember button; signed
60
- * in a compact chip with the Dexter Wallet address + USD available. Wraps
61
- * useSignInWithDexter; consumers who need the raw vault/passkey data should use
62
- * that hook directly. Inline styles are a sensible default — restyle via
63
- * className (Dexter Ember, no emojis, "unlock" banned per brand voice).
61
+ * Turnkey "Sign in with Dexter" element. Signed out → the branded ember button
62
+ * (hover / focus / active / loading states, themeable via --dx-* CSS vars);
63
+ * signed in a compact chip with the Dexter Wallet address + USD available.
64
+ * Wraps useSignInWithDexter; consumers who need the raw vault/passkey data
65
+ * should use that hook directly. Brand voice: no emojis, "unlock" banned.
64
66
  */
65
67
  declare function SignInWithDexter(props: SignInWithDexterProps): ReactElement | null;
66
68
 
package/dist/react.js CHANGED
@@ -116,22 +116,89 @@ function useSignInWithDexter(config = {}) {
116
116
  }
117
117
 
118
118
  // src/SignInWithDexter.tsx
119
- import { jsx, jsxs } from "react/jsx-runtime";
119
+ import { useEffect as useEffect2 } from "react";
120
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
121
+ var STYLE_ID = "dexter-connect-button-styles";
122
+ var BUTTON_CSS = `
123
+ @keyframes dx-spin { to { transform: rotate(360deg); } }
124
+ @keyframes dx-pulse { 0%,100% { opacity: 1; } 50% { opacity: .6; } }
125
+ .dx-btn{
126
+ --dx-ember:#f26c18; --dx-ember-2:#ba3a00; --dx-fg:#fff4ea; --dx-radius:0px;
127
+ position:relative; display:inline-flex; align-items:center; justify-content:center; gap:10px;
128
+ padding:11px 22px; border:1px solid color-mix(in srgb,var(--dx-ember) 55%,transparent);
129
+ border-radius:var(--dx-radius);
130
+ background:linear-gradient(135deg,var(--dx-ember),var(--dx-ember-2));
131
+ color:var(--dx-fg); font:inherit; font-weight:600; font-size:.78rem; letter-spacing:.12em;
132
+ text-transform:uppercase; cursor:pointer; -webkit-tap-highlight-color:transparent;
133
+ box-shadow:0 14px 26px color-mix(in srgb,var(--dx-ember) 24%,transparent);
134
+ transition:transform .16s ease, box-shadow .16s ease, filter .16s ease, background .16s ease;
135
+ }
136
+ .dx-btn:hover{ transform:translateY(-1px); filter:brightness(1.07); box-shadow:0 20px 34px color-mix(in srgb,var(--dx-ember) 32%,transparent); }
137
+ .dx-btn:active{ transform:translateY(0); filter:brightness(.97); box-shadow:0 8px 16px color-mix(in srgb,var(--dx-ember) 22%,transparent); }
138
+ .dx-btn:focus-visible{ outline:none; box-shadow:0 0 0 3px color-mix(in srgb,var(--dx-ember) 38%,transparent); }
139
+ .dx-btn:disabled{ cursor:default; filter:saturate(.85) brightness(.98); }
140
+ .dx-btn--secondary{ background:transparent; color:var(--dx-ember); box-shadow:none; border-color:color-mix(in srgb,var(--dx-ember) 45%,transparent); }
141
+ .dx-btn--secondary:hover{ background:color-mix(in srgb,var(--dx-ember) 9%,transparent); filter:none; box-shadow:none; }
142
+ .dx-btn__mark{ flex-shrink:0; }
143
+ .dx-btn__spin{ width:15px; height:15px; flex-shrink:0; border-radius:50%;
144
+ border:2px solid color-mix(in srgb,currentColor 30%,transparent); border-top-color:currentColor;
145
+ animation:dx-spin .7s linear infinite; }
146
+ .dx-btn__doing{ animation:dx-pulse 1.4s ease-in-out infinite; }
147
+ .dx-chip{ display:inline-flex; align-items:center; gap:8px; padding:6px 10px; font:inherit;
148
+ font-variant-numeric:tabular-nums; border-radius:var(--dx-radius,0);
149
+ border:1px solid color-mix(in srgb,var(--dx-ember,#f26c18) 35%,transparent); }
150
+ .dx-chip__dot{ width:7px; height:7px; border-radius:50%; background:var(--dx-ember,#f26c18); }
151
+ .dx-chip__bal{ font-weight:600; opacity:.85; }
152
+ .dx-chip__x{ margin-left:2px; border:none; background:transparent; color:inherit; cursor:pointer; font-size:16px; line-height:1; opacity:.6; }
153
+ .dx-chip__x:hover{ opacity:1; }
154
+ `;
155
+ function ensureStyles() {
156
+ if (typeof document === "undefined") return;
157
+ if (document.getElementById(STYLE_ID)) return;
158
+ const el = document.createElement("style");
159
+ el.id = STYLE_ID;
160
+ el.textContent = BUTTON_CSS;
161
+ document.head.appendChild(el);
162
+ }
163
+ ensureStyles();
164
+ function cx(...parts) {
165
+ return parts.filter(Boolean).join(" ");
166
+ }
120
167
  function shortAddress(addr) {
121
168
  return addr.length > 10 ? `${addr.slice(0, 4)}\u2026${addr.slice(-4)}` : addr;
122
169
  }
123
170
  function formatUsd(n) {
124
171
  return n.toLocaleString("en-US", { style: "currency", currency: "USD" });
125
172
  }
173
+ function DexterMark() {
174
+ return /* @__PURE__ */ jsxs(
175
+ "svg",
176
+ {
177
+ className: "dx-btn__mark",
178
+ width: "18",
179
+ height: "18",
180
+ viewBox: "0 0 300 300",
181
+ fill: "currentColor",
182
+ "aria-hidden": "true",
183
+ children: [
184
+ /* @__PURE__ */ jsx("path", { d: "M143.18,22.65c35.41,7.66,68.19,23.6,94.89,48.28,5.22,4.86,11.17,10.45,15.18,16.1,1.38,1.93,1.94,3.6.99,5.23-1.08,1.92-4.22,3.41-6.56,4.17-28.39,9.43-61.55,8.26-88.62-4.69-13.81-7.66-17.02-5.76-31.67-3.48-21.89,2.38-46.67.37-65.06-12.31-6.07-4.99-9.33-12.71-8.8-20.52-.16-9.4,4.25-18.12,11.47-24.06,21.29-17.85,52.64-14.45,78-8.77l.18.04h0Z" }),
185
+ /* @__PURE__ */ jsx("path", { d: "M46.08,129.98c1.06-1.03,3.52-1.07,5.29-1.04,48.98-.05,98.1-.06,146.83-.1,17.53.14,35.01-.31,52.49.18,2.13.18,3.89.74,4.73,2.05,1.46,2.38.35,6.09-1.98,7.6-3.66,2.05-8.62,1.33-12.86,1.74-2.85.12-5.45.13-7.02,2.02-.91,1.07-1.28,2.56-1.56,3.95-.57,3.23-1.16,6.52-1.89,9.62-2.81,12.43-8.68,24.65-19.76,31.56-9.49,5.59-20.42,6.86-31.2,5.75-11.88-1.69-22.15-8.81-29.11-18.28-3.51-4.81-4.92-10.5-5.8-16.29-.47-2.56-.51-5.87-1.35-8-1.16-3.38-6.14-2.59-9.25-1.92-4.21.95-4.39,5.7-5.14,9.19-2.25,11.18-6.84,20.68-16.15,27.65-1.31,1.05-2.91,2.03-2.12,3.66,2.5,3.21,6.65,4.49,10.44,5.97,3.26,1.17,6.86,2.41,7.18,6.06.05,8.18-11.97,3.46-16.32,1.85-3.95-1.55-7.4-4.27-10.42-7.26-3.92-4.28-9.66-4.5-15.16-4.45-3.45-.07-6.99-.19-10.45-.82-21.29-4-31.08-21.3-30.9-42.01-.08-4.63.03-9.32.09-13.91.04-1.69.07-3.46,1.28-4.67l.1-.09h0Z" }),
186
+ /* @__PURE__ */ jsx("path", { d: "M173.06,203.11c9.24-.06,21.6,4.49,22.85,14.84.3,2.12-.67,4.34-2.92,4.73-1.38.29-2.88-.05-4.09-.75-1.64-.9-2.97-2.86-4.19-3.05-1.33-.2-1.99.81-2.93,1.94-10.27,13.34-28.04,20.92-44.83,20.42-15.41-.33-31.89-5.95-43.53-17.34-3.15-3.39-1.55-9.88,3.61-9.19,1.83.32,3.29,1.45,4.76,2.65,10.49,10.12,24.85,14.04,39.12,13.03,10.55-1.23,20.38-5.47,28.74-11.92,1.11-1.06,4.45-3.63,3.5-5.12-.76-.85-4.31-.47-5.92-2.01-2.25-1.92-1.39-6.22,1.16-7.36,1.36-.65,2.96-.81,4.47-.86h.2,0Z" })
187
+ ]
188
+ }
189
+ );
190
+ }
126
191
  function SignInWithDexter(props) {
127
192
  const {
128
193
  onSuccess,
129
194
  onError,
130
195
  label = "Sign in with Dexter",
196
+ variant = "primary",
131
197
  className,
132
198
  showConnectedChip = true,
133
199
  ...config
134
200
  } = props;
201
+ useEffect2(ensureStyles, []);
135
202
  const c = useSignInWithDexter(config);
136
203
  const handleClick = async () => {
137
204
  try {
@@ -142,81 +209,44 @@ function SignInWithDexter(props) {
142
209
  };
143
210
  if (c.isVaultConnected) {
144
211
  if (!showConnectedChip) return null;
145
- return /* @__PURE__ */ jsxs("span", { className, style: CHIP, children: [
146
- /* @__PURE__ */ jsx("span", { style: DOT, "aria-hidden": true }),
212
+ return /* @__PURE__ */ jsxs("span", { className: cx("dx-chip", className), children: [
213
+ /* @__PURE__ */ jsx("span", { className: "dx-chip__dot", "aria-hidden": true }),
147
214
  /* @__PURE__ */ jsx("span", { children: c.vaultAddress ? shortAddress(c.vaultAddress) : "Connected" }),
148
- c.usdcBalance !== null && /* @__PURE__ */ jsxs("span", { style: BALANCE, children: [
215
+ c.usdcBalance !== null && /* @__PURE__ */ jsxs("span", { className: "dx-chip__bal", children: [
149
216
  formatUsd(c.usdcBalance),
150
217
  " available"
151
218
  ] }),
152
- /* @__PURE__ */ jsx("button", { type: "button", onClick: c.disconnect, style: DISCONNECT, "aria-label": "Disconnect", children: "\xD7" })
219
+ /* @__PURE__ */ jsx("button", { type: "button", className: "dx-chip__x", onClick: c.disconnect, "aria-label": "Disconnect", children: "\xD7" })
153
220
  ] });
154
221
  }
222
+ const pending = c.status === "pending";
155
223
  return /* @__PURE__ */ jsx(
156
224
  "button",
157
225
  {
158
226
  type: "button",
159
- className,
227
+ className: cx("dx-btn", variant === "secondary" && "dx-btn--secondary", className),
160
228
  onClick: handleClick,
161
- disabled: c.status === "pending",
162
- style: BUTTON,
163
- children: c.status === "pending" ? "Signing in\u2026" : label
229
+ disabled: pending,
230
+ "aria-busy": pending,
231
+ children: pending ? /* @__PURE__ */ jsxs(Fragment, { children: [
232
+ /* @__PURE__ */ jsx("span", { className: "dx-btn__spin", "aria-hidden": true }),
233
+ /* @__PURE__ */ jsx("span", { className: "dx-btn__doing", children: "Connecting\u2026" })
234
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
235
+ /* @__PURE__ */ jsx(DexterMark, {}),
236
+ label
237
+ ] })
164
238
  }
165
239
  );
166
240
  }
167
- var EMBER = "#ef6820";
168
- var BUTTON = {
169
- display: "inline-flex",
170
- alignItems: "center",
171
- gap: 8,
172
- padding: "10px 16px",
173
- border: "none",
174
- borderRadius: 6,
175
- background: EMBER,
176
- color: "#fff",
177
- font: "inherit",
178
- fontWeight: 600,
179
- cursor: "pointer"
180
- };
181
- var CHIP = {
182
- display: "inline-flex",
183
- alignItems: "center",
184
- gap: 8,
185
- padding: "6px 10px",
186
- borderRadius: 6,
187
- border: "1px solid rgba(239,104,32,0.35)",
188
- font: "inherit",
189
- fontVariantNumeric: "tabular-nums"
190
- };
191
- var DOT = {
192
- width: 7,
193
- height: 7,
194
- borderRadius: "50%",
195
- background: EMBER
196
- };
197
- var BALANCE = {
198
- fontWeight: 600,
199
- opacity: 0.85
200
- };
201
- var DISCONNECT = {
202
- marginLeft: 2,
203
- border: "none",
204
- background: "transparent",
205
- color: "inherit",
206
- cursor: "pointer",
207
- fontSize: 16,
208
- lineHeight: 1,
209
- opacity: 0.6
210
- };
211
241
 
212
242
  // src/useDexterWallet.ts
213
- import { useCallback as useCallback2, useEffect as useEffect2, useState as useState2 } from "react";
243
+ import { useCallback as useCallback2, useEffect as useEffect3, useState as useState2 } from "react";
214
244
  var NO_SUPPORT = { rename: false, prune: false, syncAccepted: false };
215
245
  function useDexterWallet() {
216
246
  const [activeHandle, setHandle] = useState2(() => getActiveHandle());
217
247
  const [wallets, setWallets] = useState2(() => listWallets());
218
248
  const [support, setSupport] = useState2(NO_SUPPORT);
219
- useEffect2(() => {
249
+ useEffect3(() => {
220
250
  const sync = () => {
221
251
  setHandle(getActiveHandle());
222
252
  setWallets(listWallets());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dexterai/connect",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Sign in with Dexter — passkey connector. Composes @dexterai/vault.",
5
5
  "type": "module",
6
6
  "exports": {