@usethrottle/auth 0.3.1 → 0.5.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/{chunk-NCSTIPJF.js → chunk-HQP5QTHQ.js} +3 -1
- package/dist/{chunk-NCSTIPJF.js.map → chunk-HQP5QTHQ.js.map} +1 -1
- package/dist/{chunk-ST77QX7X.js → chunk-K7RCWADI.js} +18 -1
- package/dist/chunk-K7RCWADI.js.map +1 -0
- package/dist/{chunk-2DREGJUF.js → chunk-TKSBAC7W.js} +2 -2
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/react/components/index.cjs +904 -628
- package/dist/react/components/index.cjs.map +1 -1
- package/dist/react/components/index.d.cts +62 -6
- package/dist/react/components/index.d.ts +62 -6
- package/dist/react/components/index.js +860 -603
- package/dist/react/components/index.js.map +1 -1
- package/dist/react/forms/index.cjs +17 -0
- package/dist/react/forms/index.cjs.map +1 -1
- package/dist/react/forms/index.js +2 -2
- package/dist/react/index.cjs +2 -0
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +40 -0
- package/dist/react/index.d.ts +40 -0
- package/dist/react/index.js +2 -2
- package/dist/styles.css +47 -3
- package/package.json +1 -1
- package/dist/chunk-ST77QX7X.js.map +0 -1
- /package/dist/{chunk-2DREGJUF.js.map → chunk-TKSBAC7W.js.map} +0 -0
package/dist/styles.css
CHANGED
|
@@ -200,11 +200,13 @@
|
|
|
200
200
|
align-items: center;
|
|
201
201
|
justify-content: center;
|
|
202
202
|
cursor: pointer;
|
|
203
|
+
/* A label that wraps turns a control into a two-line block of text. */
|
|
204
|
+
white-space: nowrap;
|
|
203
205
|
transition: opacity var(--throttle-transition), background-color var(--throttle-transition), border-color var(--throttle-transition), filter var(--throttle-transition), box-shadow var(--throttle-transition);
|
|
204
206
|
}
|
|
205
207
|
.throttle-button:disabled { opacity: .55; cursor: not-allowed; }
|
|
206
208
|
.throttle-button:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--throttle-color-background), 0 0 0 4px var(--throttle-color-primary); }
|
|
207
|
-
.throttle-button--primary { background: var(--throttle-color-primary); color: var(--throttle-color-primary-foreground); width: 100
|
|
209
|
+
.throttle-button--primary { background: var(--throttle-color-primary); color: var(--throttle-color-primary-foreground); width: var(--throttle-button-width, 100%); }
|
|
208
210
|
.throttle-button--primary:hover:not(:disabled) { filter: brightness(0.92); }
|
|
209
211
|
.throttle-button--secondary { background: var(--throttle-color-surface); color: var(--throttle-color-foreground); border-color: var(--throttle-color-border-control); }
|
|
210
212
|
.throttle-button--secondary:hover:not(:disabled) { background: var(--throttle-color-muted); }
|
|
@@ -371,6 +373,10 @@
|
|
|
371
373
|
.throttle-addresses { grid-template-columns: 1fr; }
|
|
372
374
|
.throttle-fieldrow { grid-template-columns: 1fr; }
|
|
373
375
|
.throttle-tabs__rail { width: 100%; }
|
|
376
|
+
/* One column, and the rail stops sticking — on a phone a sticky summary
|
|
377
|
+
covers the very line items it is summarising. */
|
|
378
|
+
.throttle-detail { grid-template-columns: 1fr; }
|
|
379
|
+
.throttle-detail__rail { position: static; }
|
|
374
380
|
}
|
|
375
381
|
|
|
376
382
|
.throttle-table { width: 100%; border-collapse: collapse; text-align: left; }
|
|
@@ -448,12 +454,50 @@
|
|
|
448
454
|
padding: var(--throttle-space-3) 0;
|
|
449
455
|
}
|
|
450
456
|
.throttle-rowitem:first-child { border-top: none; padding-top: 0; }
|
|
451
|
-
.throttle-actions {
|
|
457
|
+
.throttle-actions {
|
|
458
|
+
display: flex; gap: var(--throttle-space-2); flex-wrap: wrap; align-items: center;
|
|
459
|
+
/* Primary buttons are full-width so a form's submit fills its card. In a row
|
|
460
|
+
of sibling actions that same rule made every button claim 100% and then
|
|
461
|
+
shrink to share the line, squeezing Resume to 59px so its label wrapped to
|
|
462
|
+
two lines inside a 48px box. A custom property INHERITS to the buttons, so
|
|
463
|
+
the row opts them back to content width without a descendant selector —
|
|
464
|
+
those outrank the merchant overrides in appearance.elements. */
|
|
465
|
+
--throttle-button-width: auto;
|
|
466
|
+
}
|
|
452
467
|
.throttle-table__money { display: block; text-align: right; font-variant-numeric: tabular-nums; }
|
|
453
|
-
.throttle-lineitem { display: flex; align-items:
|
|
468
|
+
.throttle-lineitem { display: flex; align-items: flex-start; gap: var(--throttle-space-3); padding: var(--throttle-space-2) 0; }
|
|
469
|
+
/* The UA's 1em paragraph margins pushed a two-line item to 96px, so five
|
|
470
|
+
items filled a screen with mostly whitespace. These carry the spacing
|
|
471
|
+
instead. Separate classes, not a ".throttle-lineitem p" descendant
|
|
472
|
+
selector -- those outrank the merchant's appearance.elements overrides. */
|
|
473
|
+
.throttle-lineitem__desc { margin: var(--throttle-space-1) 0 0; color: var(--throttle-color-muted-foreground); }
|
|
474
|
+
.throttle-lineitem__meta { margin: var(--throttle-space-1) 0 0; color: var(--throttle-color-muted-foreground); font-size: var(--throttle-font-size-sm); }
|
|
454
475
|
.throttle-lineitem__image { width: 48px; height: 48px; object-fit: cover; border-radius: var(--throttle-radius-sm); flex: none; }
|
|
455
476
|
.throttle-totals { display: flex; flex-direction: column; gap: var(--throttle-space-1); }
|
|
456
477
|
|
|
478
|
+
/* Order and invoice detail: the record on the left, what it costs and what
|
|
479
|
+
you can do about it on the right. The rail sticks so the total and the
|
|
480
|
+
actions stay reachable on an order with thirty lines, which is exactly when
|
|
481
|
+
a buyer most wants them. Collapses below, where a sticky rail would eat a
|
|
482
|
+
phone screen. */
|
|
483
|
+
.throttle-detail { display: grid; grid-template-columns: minmax(0, 1fr) 17rem; gap: var(--throttle-space-6); align-items: start; }
|
|
484
|
+
.throttle-detail__main { display: flex; flex-direction: column; gap: var(--throttle-space-5); min-width: 0; }
|
|
485
|
+
.throttle-detail__rail {
|
|
486
|
+
display: flex; flex-direction: column; gap: var(--throttle-space-4);
|
|
487
|
+
position: sticky; top: var(--throttle-space-4);
|
|
488
|
+
padding: var(--throttle-space-4);
|
|
489
|
+
border: var(--throttle-border-width) solid var(--throttle-color-border);
|
|
490
|
+
border-radius: var(--throttle-radius-md);
|
|
491
|
+
background: var(--throttle-color-surface);
|
|
492
|
+
}
|
|
493
|
+
/* The one number the buyer came for. */
|
|
494
|
+
.throttle-detail__headline { font-size: var(--throttle-font-size-xl); font-weight: 600; line-height: 1.2; }
|
|
495
|
+
.throttle-detail__section { display: flex; flex-direction: column; gap: var(--throttle-space-2); }
|
|
496
|
+
.throttle-detail__label { font-size: var(--throttle-font-size-sm); font-weight: 500; color: var(--throttle-color-muted-foreground); letter-spacing: .04em; text-transform: uppercase; }
|
|
497
|
+
/* A rail action column: full width, stacked, so the primary reads as primary. */
|
|
498
|
+
.throttle-detail__actions { display: flex; flex-direction: column; gap: var(--throttle-space-2); --throttle-button-width: 100%; }
|
|
499
|
+
.throttle-detail__link { display: inline-flex; align-items: center; gap: var(--throttle-space-1); }
|
|
500
|
+
|
|
457
501
|
@media (prefers-reduced-motion: reduce) {
|
|
458
502
|
.throttle-button, .throttle-field__input, .throttle-dropdown__item, .throttle-dropdown__trigger, .throttle-tabs__tab, .throttle-table__row, .throttle-modal__close {
|
|
459
503
|
transition: none;
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react/forms/messages.ts"],"sourcesContent":["import { ThrottleAuthError } from '../../errors';\n\nfunction waitCopy(seconds?: number): string {\n if (!seconds || !Number.isFinite(seconds)) return 'Please wait a moment and try again.';\n if (seconds < 60) return `Please wait ${Math.ceil(seconds)} seconds and try again.`;\n const minutes = Math.ceil(seconds / 60);\n return `Please wait ${minutes} ${minutes === 1 ? 'minute' : 'minutes'} and try again.`;\n}\n\n\n/**\n * `addressLine1` -> `Address line 1`. The API names fields for programs; this\n * is the same name written for the person reading the form.\n */\nfunction fieldLabel(path: string): string {\n const words = path\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n .replace(/([a-zA-Z])([0-9])/g, '$1 $2')\n .toLowerCase()\n .trim();\n return words.charAt(0).toUpperCase() + words.slice(1);\n}\n\ninterface ValidationDetail { path?: string; message?: string }\n\n/**\n * Buyer-facing copy for every code the storefront API returns. Two codes are\n * deliberately NOT passed through from the server: `invalid_credentials` (the\n * server is vague on purpose — enumerating accounts through our own UI would\n * undo that) and anything unrecognised.\n */\nexport function messageForError(err: unknown): string {\n const e = err as Partial<ThrottleAuthError> & { code?: string };\n switch (e?.code) {\n case 'invalid_credentials':\n return 'That email or password is not correct.';\n case 'weak_password':\n // The server's message IS the policy reason (\"Use at least 12 characters\").\n return e.message || 'Please choose a stronger password.';\n case 'too_many_attempts':\n return `Too many attempts. ${waitCopy(e.retryAfter)}`;\n case 'verification_required':\n return 'Please verify your email address to continue.';\n case 'step_up_required':\n return 'Please re-enter your password to continue.';\n case 'session_revoked':\n return 'Your session has ended. Please sign in again.';\n case 'token_expired':\n case 'token_invalid':\n case 'token_already_used':\n return 'That link is no longer valid. Please request a new link.';\n case 'auth_unavailable':\n return 'Accounts are briefly unavailable. Please try again shortly.';\n case 'origin_not_allowed':\n case 'auth_not_enabled':\n case 'invalid_api_key':\n case 'environment_mismatch':\n // Merchant misconfiguration, not something the buyer can fix.\n return 'Accounts are not available right now. Please contact support.';\n case 'cart_already_claimed':\n return 'That cart belongs to a different account.';\n case 'not_found':\n return 'We could not find that.';\n case 'payment_method_in_use':\n // The server's message IS the fix (\"set another card as default\n // first\") — same rationale as weak_password below.\n return e.message || 'That payment method is in use and cannot be removed.';\n case 'validation_error': {\n // The server already said which field is wrong and why. Dropping that on\n // the floor left buyers staring at \"Something went wrong\" in front of a\n // one-word fix (a country name typed where ISO-3166 alpha-2 belongs).\n // The raw `message` is an ajv path (\"body/countryCode must ...\"), so it\n // is the details we want, not the summary.\n const first = (e.details as ValidationDetail[] | undefined)?.[0];\n if (first?.path && first?.message) {\n return `${fieldLabel(first.path)} ${first.message.replace(/\\bNOT\\b/g, 'not')}.`;\n }\n return 'Please check the highlighted fields and try again.';\n }\n default:\n return 'Something went wrong. Please try again.';\n }\n}\n"],"mappings":";;;AAEA,SAAS,SAAS,SAA0B;AAC1C,MAAI,CAAC,WAAW,CAAC,OAAO,SAAS,OAAO,EAAG,QAAO;AAClD,MAAI,UAAU,GAAI,QAAO,eAAe,KAAK,KAAK,OAAO,CAAC;AAC1D,QAAM,UAAU,KAAK,KAAK,UAAU,EAAE;AACtC,SAAO,eAAe,OAAO,IAAI,YAAY,IAAI,WAAW,SAAS;AACvE;AAOA,SAAS,WAAW,MAAsB;AACxC,QAAM,QAAQ,KACX,QAAQ,mBAAmB,OAAO,EAClC,QAAQ,sBAAsB,OAAO,EACrC,YAAY,EACZ,KAAK;AACR,SAAO,MAAM,OAAO,CAAC,EAAE,YAAY,IAAI,MAAM,MAAM,CAAC;AACtD;AAUO,SAAS,gBAAgB,KAAsB;AACpD,QAAM,IAAI;AACV,UAAQ,GAAG,MAAM;AAAA,IACf,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAEH,aAAO,EAAE,WAAW;AAAA,IACtB,KAAK;AACH,aAAO,sBAAsB,SAAS,EAAE,UAAU,CAAC;AAAA,IACrD,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAEH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAGH,aAAO,EAAE,WAAW;AAAA,IACtB,KAAK,oBAAoB;AAMvB,YAAM,QAAS,EAAE,UAA6C,CAAC;AAC/D,UAAI,OAAO,QAAQ,OAAO,SAAS;AACjC,eAAO,GAAG,WAAW,MAAM,IAAI,CAAC,IAAI,MAAM,QAAQ,QAAQ,YAAY,KAAK,CAAC;AAAA,MAC9E;AACA,aAAO;AAAA,IACT;AAAA,IACA;AACE,aAAO;AAAA,EACX;AACF;","names":[]}
|
|
File without changes
|