@entropy-softworks/ui 2026.8.41 → 2026.9.1

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 CHANGED
@@ -7,151 +7,161 @@ are CalVer — `YYYY.M.D` of the publish date, with leading zeros dropped (npm's
7
7
  them), matching the `entropy-auth` crate. The `0.1.0` entry below predates the switch and was never
8
8
  published to npm.
9
9
 
10
+ ## 2026.8.42
11
+
12
+ ### Fixed
13
+
14
+ - Custom uploaded icons never rendered on a phone. `useUploadBlobUrl` built its URI with
15
+ `URL.createObjectURL`, which is a browser API — React Native's `URL` does not implement it in any
16
+ way that can be relied on, so the call either threw or produced something no image loader would
17
+ open, and every upload fell through to the fallback glyph on every native consumer. Web still gets
18
+ a blob URL (no copy, and revocable); native now reads the bytes and builds
19
+ `data:<type>;base64,...`, which every RN image loader accepts. Base64 inflates by a third and the
20
+ string lives as long as the row is mounted, which is affordable for icons — vault caps an upload
21
+ at 256KB — and is why the two platforms differ rather than both taking the data URI.
22
+ - The base64 encoder is hand-rolled rather than `btoa`. React Native ships no `btoa`, so whether one
23
+ exists depends on which polyfill the consuming app installed, which is not something a library can
24
+ assume.
25
+
26
+ ### Added
27
+
28
+ - `useUploadBlobUrl` takes an options object — `{ uploadsPath, resolve }` — in place of the bare
29
+ path, which still works. `resolve` produces the URI for an upload id without going through
30
+ `apiFetch` at all, for a consumer whose uploads are not behind a server: vault's device-only
31
+ vaults keep theirs in on-device SQLite. Returning `null` reports `errored`, so an id that does not
32
+ resolve draws the same fallback a failed fetch does. The resolver is held in a ref and only
33
+ `uploadId` / `uploadsPath` re-run the effect, so an arrow defined inline at the call site cannot
34
+ turn every render into a refetch.
35
+ - `ItemIcon` takes `resolveUpload`, passed straight through. Without it such a consumer had to
36
+ pre-resolve the reference into a `data:` URI and hand it over as `iconUrl` — which works only
37
+ because anything that is not `custom:` is treated as a plain URL, and hides the intent completely.
38
+
10
39
  ## 2026.8.41
11
40
 
12
41
  ### Fixed
13
42
 
14
- - `AuthScreen`'s form-height lock skipped its measuring pass for any consumer
15
- that resolves `signUpEnabled` asynchronously. `probed` was initialised from
16
- `signUpEnabled`, which is right when the consumer knows its registration
17
- policy at mount but one that has to ASK for it (Access's portal fetches the
18
- tenant's policy and starts at the conservative "closed") mounted with sign-up
19
- off, skipped the pre-measure, and turned sign-up on a moment later with
20
- nothing measured. The first real toggle was then the one that grew the card:
21
- it resized once, then held still forever, which is exactly the symptom the
22
- lock exists to remove. The probe now re-arms on the false -> true edge.
43
+ - `AuthScreen`'s form-height lock skipped its measuring pass for any consumer that resolves
44
+ `signUpEnabled` asynchronously. `probed` was initialised from `signUpEnabled`, which is right when
45
+ the consumer knows its registration policy at mount but one that has to ASK for it (Access's
46
+ portal fetches the tenant's policy and starts at the conservative "closed") mounted with sign-up
47
+ off, skipped the pre-measure, and turned sign-up on a moment later with nothing measured. The
48
+ first real toggle was then the one that grew the card: it resized once, then held still forever,
49
+ which is exactly the symptom the lock exists to remove. The probe now re-arms on the false -> true
50
+ edge.
23
51
 
24
52
  ## 2026.8.40
25
53
 
26
54
  ### Added
27
55
 
28
- - `AuthScreen` takes `lockFormHeight` (default `true`). The card reserves the
29
- height of the taller of Sign In / Sign Up so the two toggle without the
30
- layout moving; the cost is slack, left as empty space above the shorter
31
- mode's submit button. Where Sign Up carries several more fields that gap is
32
- the more visible flaw of the two most people only ever sign in, and they
33
- all see it — so a consumer can now let the card resize instead. The body is
34
- already wrapped in a layout animation, so the change eases rather than jumps.
56
+ - `AuthScreen` takes `lockFormHeight` (default `true`). The card reserves the height of the taller
57
+ of Sign In / Sign Up so the two toggle without the layout moving; the cost is slack, left as empty
58
+ space above the shorter mode's submit button. Where Sign Up carries several more fields that gap
59
+ is the more visible flaw of the two most people only ever sign in, and they all see it — so a
60
+ consumer can now let the card resize instead. The body is already wrapped in a layout animation,
61
+ so the change eases rather than jumps.
35
62
 
36
63
  ## 2026.8.39
37
64
 
38
65
  ### Added
39
66
 
40
- - `SocialConnections` takes `showEntropy` (default `true`), which drops the
41
- first-party "Continue with Entropy" button from the row. Unlike the other
42
- three, that one is not a staged-rollout placeholder waiting for its
43
- connector: on Entropy Access's own sign-in surfaces it offers to sign in to
44
- the identity provider with the identity provider, which is a button that can
45
- never mean anything. A flag rather than inferring intent from a missing
46
- `onEntropy`, because rendering an unhandled provider is deliberate here
47
- simple-finance renders the whole row with no handlers at all, and inference
48
- would silently take that button away from it.
67
+ - `SocialConnections` takes `showEntropy` (default `true`), which drops the first-party "Continue
68
+ with Entropy" button from the row. Unlike the other three, that one is not a staged-rollout
69
+ placeholder waiting for its connector: on Entropy Access's own sign-in surfaces it offers to sign
70
+ in to the identity provider with the identity provider, which is a button that can never mean
71
+ anything. A flag rather than inferring intent from a missing `onEntropy`, because rendering an
72
+ unhandled provider is deliberate here simple-finance renders the whole row with no handlers at
73
+ all, and inference would silently take that button away from it.
49
74
 
50
75
  ## 2026.8.35
51
76
 
52
77
  ### Fixed
53
78
 
54
- - `AuthService.getCurrentUser()` destroyed the session it was asked about. It
55
- returned `loadPersistedUser()` and nothing else, and on web that reads a
56
- module-level variable which is null in every freshly loaded document — so it
57
- answered "nobody" on each page load and refresh while the session cookie was
58
- perfectly valid. `useAuth.checkAuth` treats that as a session it cannot
59
- resolve and calls `logout()`, which POSTs `/auth/logout` and ends the session
60
- server-side: the user was signed out by the act of loading the page.
61
-
62
- Observed on Access, whose portal and admin console are separate SPAs on one
63
- origin so every navigation between them is a fresh document and therefore a
64
- guaranteed logout, presenting as an infinite sign-in loop. Its audit log
65
- recorded the logouts nobody had asked for.
66
-
67
- Native was affected too, if less visibly: `isAuthenticated()` there is
68
- satisfied by a token in SecureStore, so a token that outlived its cached user
69
- record produced the same spurious logout.
70
-
71
- `getCurrentUser()` now falls back to `GET /auth/me` when nothing is persisted.
72
- It deliberately does not route through `isAuthenticated()`, whose web branch
73
- falls back to calling `getCurrentUser()` going the other way would recurse
74
- until the stack gave out, on exactly the signed-out path this makes cheap.
75
- The request is shared with `refreshUserData()` through a private `fetchMe`,
76
- parameterised on whether a 401 should log out: a refresh of a session
77
- believed live that 401s means the session died, while a lookup that 401s is
78
- just an anonymous visitor and must not tear anything down.
79
+ - `AuthService.getCurrentUser()` destroyed the session it was asked about. It returned
80
+ `loadPersistedUser()` and nothing else, and on web that reads a module-level variable which is
81
+ null in every freshly loaded document — so it answered "nobody" on each page load and refresh
82
+ while the session cookie was perfectly valid. `useAuth.checkAuth` treats that as a session it
83
+ cannot resolve and calls `logout()`, which POSTs `/auth/logout` and ends the session server-side:
84
+ the user was signed out by the act of loading the page.
85
+
86
+ Observed on Access, whose portal and admin console are separate SPAs on one origin — so every
87
+ navigation between them is a fresh document and therefore a guaranteed logout, presenting as an
88
+ infinite sign-in loop. Its audit log recorded the logouts nobody had asked for.
89
+
90
+ Native was affected too, if less visibly: `isAuthenticated()` there is satisfied by a token in
91
+ SecureStore, so a token that outlived its cached user record produced the same spurious logout.
92
+
93
+ `getCurrentUser()` now falls back to `GET /auth/me` when nothing is persisted. It deliberately
94
+ does not route through `isAuthenticated()`, whose web branch falls back to calling
95
+ `getCurrentUser()` — going the other way would recurse until the stack gave out, on exactly the
96
+ signed-out path this makes cheap. The request is shared with `refreshUserData()` through a private
97
+ `fetchMe`, parameterised on whether a 401 should log out: a refresh of a session believed live
98
+ that 401s means the session died, while a lookup that 401s is just an anonymous visitor and must
99
+ not tear anything down.
79
100
 
80
101
  ## 2026.8.17
81
102
 
82
103
  ### Fixed
83
104
 
84
- - The systemic bare-CSS-var-no-`dark:`-fallback pattern flagged as a known
85
- follow-up in 2026.8.15 — completed across the rest of the package: `Card`,
86
- `ContextMenu`, `DataTable`, `DropdownMenu`, `Popover`, `SettingsRow`,
87
- `PinPad`, `PasswordGenerator`, `EntropyByline`, `ErrorBoundary` (severe:
88
- its retry button's label was invisible white-on-white in dark mode),
89
- `Pagination`, `LockOverlay`, `ProtectedRoute`, and every screen under
90
- `src/screens/auth/*` (root backgrounds, plus scattered destructive-text and
91
- `ServerConfigScreen`'s from-scratch raw-`Text` markup).
92
- - `CardFooter`'s base `items-center` was never overridden by the `flex-col`
93
- className every consuming screen passes it (`AuthScreen`, `LoginScreen`,
94
- `RegisterScreen`, and ~10 others) `flex-row`→`flex-col` and `border-t`→
95
- `border-t-0` correctly override via tailwind-merge's same-property
96
- matching, but `items-center` has no `items-*` counterpart in that
97
- className to conflict with, so it silently survived. Left the submit
98
- button's wrapping view with ambiguous (content-fit) width instead of
99
- stretching to match its own `w-full` Pressable child — surfaced as the
100
- "Sign In" button rendering with a runaway width specifically once its
101
- content swapped from label text to the loading spinner (the one thing
102
- that actually changes Yoga's layout resolution for that ambiguous case).
103
- Added `items-stretch` alongside `flex-col` at every call site.
105
+ - The systemic bare-CSS-var-no-`dark:`-fallback pattern flagged as a known follow-up in 2026.8.15 —
106
+ completed across the rest of the package: `Card`, `ContextMenu`, `DataTable`, `DropdownMenu`,
107
+ `Popover`, `SettingsRow`, `PinPad`, `PasswordGenerator`, `EntropyByline`, `ErrorBoundary` (severe:
108
+ its retry button's label was invisible white-on-white in dark mode), `Pagination`, `LockOverlay`,
109
+ `ProtectedRoute`, and every screen under `src/screens/auth/*` (root backgrounds, plus scattered
110
+ destructive-text and `ServerConfigScreen`'s from-scratch raw-`Text` markup).
111
+ - `CardFooter`'s base `items-center` was never overridden by the `flex-col` className every
112
+ consuming screen passes it (`AuthScreen`, `LoginScreen`, `RegisterScreen`, and ~10 others)
113
+ `flex-row`→`flex-col` and `border-t`→ `border-t-0` correctly override via tailwind-merge's
114
+ same-property matching, but `items-center` has no `items-*` counterpart in that className to
115
+ conflict with, so it silently survived. Left the submit button's wrapping view with ambiguous
116
+ (content-fit) width instead of stretching to match its own `w-full` Pressable child surfaced as
117
+ the "Sign In" button rendering with a runaway width specifically once its content swapped from
118
+ label text to the loading spinner (the one thing that actually changes Yoga's layout resolution
119
+ for that ambiguous case). Added `items-stretch` alongside `flex-col` at every call site.
104
120
 
105
121
  ## 2026.8.15
106
122
 
107
123
  ### Fixed
108
124
 
109
- - Several components colored themselves with a bare CSS-variable utility
110
- (`bg-primary`, `bg-background`, `border-border`, `bg-destructive`, …) and no
111
- `dark:` fallback on native Android that value stays stuck on its light
112
- setting regardless of actual system theme; only components carrying an
113
- explicit `dark:`-prefixed class (the existing pattern in `Heading`/`Text`/
114
- `MutedText`) reacted correctly. Added matching `dark:` variants one per
115
- CSS variable's own `.dark` value in `styles/globals.css` to `Button`,
116
- `Input`, `Dialog`'s destructive variant, `legal-dialog`'s body text, and
117
- `AuthScreen`'s root background. Surfaced as vault's "Get Started" screen
118
- going render-broken in dark mode: invisible button, invisible heading/legal
119
- text, and a background that stayed white.
120
- - `AuthScreen`'s tagline and "← Back" link used the plain `Text` component
121
- with a `text-muted-foreground` override that fought `Text`'s own base
122
- `dark:text-white` the override lost to the base class's `dark:` variant,
123
- so both rendered bright white instead of muted in dark mode. Switched both
124
- to `MutedText`, which carries the correct `dark:text-neutral-400`.
125
- - Known follow-up, not fixed here: the same bare-CSS-var-no-dark:-fallback
126
- pattern is present in roughly 15 more files in this package
127
- (`password-generator.tsx`, `pin-pad.tsx`, `tag-chip.tsx`, several other
128
- still-active auth screens, …) — scoped out of this release to unblock the
129
- reported bug; needs its own pass.
125
+ - Several components colored themselves with a bare CSS-variable utility (`bg-primary`,
126
+ `bg-background`, `border-border`, `bg-destructive`, …) and no `dark:` fallback — on native Android
127
+ that value stays stuck on its light setting regardless of actual system theme; only components
128
+ carrying an explicit `dark:`-prefixed class (the existing pattern in `Heading`/`Text`/
129
+ `MutedText`) reacted correctly. Added matching `dark:` variants one per CSS variable's own
130
+ `.dark` value in `styles/globals.css` to `Button`, `Input`, `Dialog`'s destructive variant,
131
+ `legal-dialog`'s body text, and `AuthScreen`'s root background. Surfaced as vault's "Get Started"
132
+ screen going render-broken in dark mode: invisible button, invisible heading/legal text, and a
133
+ background that stayed white.
134
+ - `AuthScreen`'s tagline and "← Back" link used the plain `Text` component with a
135
+ `text-muted-foreground` override that fought `Text`'s own base `dark:text-white` — the override
136
+ lost to the base class's `dark:` variant, so both rendered bright white instead of muted in dark
137
+ mode. Switched both to `MutedText`, which carries the correct `dark:text-neutral-400`.
138
+ - Known follow-up, not fixed here: the same bare-CSS-var-no-dark:-fallback pattern is present in
139
+ roughly 15 more files in this package (`password-generator.tsx`, `pin-pad.tsx`, `tag-chip.tsx`,
140
+ several other still-active auth screens, …) — scoped out of this release to unblock the reported
141
+ bug; needs its own pass.
130
142
 
131
143
  ## 2026.8.2
132
144
 
133
145
  ### Fixed
134
146
 
135
- - `registerTelemetry` and the rest of the telemetry registry were exported from
136
- the root barrel twice — once through `export * from "./services"` and once by
137
- name. Metro's CommonJS interop resolved the duplicate ambiguously and
138
- consumers got `undefined` at runtime despite the types checking. The root
139
- barrel now re-exports them only through `./services`.
147
+ - `registerTelemetry` and the rest of the telemetry registry were exported from the root barrel
148
+ twice — once through `export * from "./services"` and once by name. Metro's CommonJS interop
149
+ resolved the duplicate ambiguously and consumers got `undefined` at runtime despite the types
150
+ checking. The root barrel now re-exports them only through `./services`.
140
151
 
141
152
  ## 2026.8.1
142
153
 
143
154
  ### Added
144
155
 
145
- - Telemetry registry (`registerTelemetry`, `trackClick`, `withClickTracking`). The
146
- package reports interactions to a sink the host app supplies; it knows nothing
147
- about batching, authentication or transport. No sink registered means every
148
- entry point is a no-op, so consumers that do not opt in are unaffected.
149
- - `telemetryId` prop on `Button` and `IconButton`. Reports a stable,
150
- author-assigned id when the control is activated. Wired through `onPress`, so
151
- a disabled or loading button records nothing.
152
- - All 69 interactive controls across the 18 auth screens carry a `telemetryId`,
153
- making sign-in, sign-up, MFA and consent measurable by consuming apps without
154
- each of them re-tagging the packaged screens.
156
+ - Telemetry registry (`registerTelemetry`, `trackClick`, `withClickTracking`). The package reports
157
+ interactions to a sink the host app supplies; it knows nothing about batching, authentication or
158
+ transport. No sink registered means every entry point is a no-op, so consumers that do not opt in
159
+ are unaffected.
160
+ - `telemetryId` prop on `Button` and `IconButton`. Reports a stable, author-assigned id when the
161
+ control is activated. Wired through `onPress`, so a disabled or loading button records nothing.
162
+ - All 69 interactive controls across the 18 auth screens carry a `telemetryId`, making sign-in,
163
+ sign-up, MFA and consent measurable by consuming apps without each of them re-tagging the packaged
164
+ screens.
155
165
 
156
166
  ## [Unreleased]
157
167
 
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import { type UploadResolver } from "../hooks/useUploadBlobUrl";
2
3
  export interface ItemIconProps {
3
4
  /**
4
5
  * Stored icon reference. Either a literal URL, a `custom:<uploadId>`
@@ -22,6 +23,21 @@ export interface ItemIconProps {
22
23
  faviconPath?: string;
23
24
  /** Upload-fetch path prefix. Defaults to `/uploads`. */
24
25
  uploadsPath?: string;
26
+ /**
27
+ * Resolve a `custom:<uploadId>` reference yourself instead of letting this
28
+ * component fetch it.
29
+ *
30
+ * For a consumer whose uploads are not behind `apiFetch` at all — vault's
31
+ * device-only vaults keep them in on-device SQLite, with no server to ask.
32
+ * Without this, such a consumer has to either fork the component or
33
+ * pre-resolve the reference into a `data:` URI and pass it as `iconUrl`,
34
+ * which works by accident (anything that is not `custom:` is treated as a
35
+ * plain URL) and hides the intent.
36
+ *
37
+ * Return `null` for an id that does not resolve; the fallback glyph is drawn,
38
+ * exactly as for a fetch that fails.
39
+ */
40
+ resolveUpload?: UploadResolver;
25
41
  }
26
42
  /**
27
43
  * Per-item icon: shows the custom upload, falls back to the favicon
@@ -1 +1 @@
1
- {"version":3,"file":"item-icon.d.ts","sourceRoot":"","sources":["../../src/components/item-icon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAOnD,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAQD;;;;GAIG;AACH,eAAO,MAAM,QAAQ,2CAmEnB,CAAC"}
1
+ {"version":3,"file":"item-icon.d.ts","sourceRoot":"","sources":["../../src/components/item-icon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAKnD,OAAO,EAAE,KAAK,cAAc,EAAoB,MAAM,2BAA2B,CAAC;AAElF,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;;;;OAaG;IACH,aAAa,CAAC,EAAE,cAAc,CAAC;CAChC;AAQD;;;;GAIG;AACH,eAAO,MAAM,QAAQ,2CAoEnB,CAAC"}
@@ -13,12 +13,12 @@ const WEB_LAZY_PROPS = Platform.OS === "web" ? { loading: "lazy", decoding: "asy
13
13
  * proxy, then to a generic globe glyph on a tile-toned square. Shared
14
14
  * between RN clients (mobile) and RN-Web (extension popup).
15
15
  */
16
- export const ItemIcon = React.memo(function ItemIcon({ iconUrl, siteUrl, size = 40, imageSize, borderRadius, background, fallbackColor, faviconPath = "/favicon", uploadsPath = "/uploads", }) {
16
+ export const ItemIcon = React.memo(function ItemIcon({ iconUrl, siteUrl, size = 40, imageSize, borderRadius, background, fallbackColor, faviconPath = "/favicon", uploadsPath = "/uploads", resolveUpload, }) {
17
17
  const { colorScheme } = useColorScheme();
18
18
  const isDark = colorScheme === "dark";
19
19
  const resolved = resolveIcon({ iconUrl, siteUrl, faviconPath });
20
20
  const uploadId = resolved.kind === "upload" ? resolved.uploadId : null;
21
- const upload = useUploadBlobUrl(uploadId, uploadsPath);
21
+ const upload = useUploadBlobUrl(uploadId, { uploadsPath, resolve: resolveUpload });
22
22
  const directUri = resolved.kind === "url" ? resolved.uri : null;
23
23
  const [urlErrored, setUrlErrored] = useState(false);
24
24
  useEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"item-icon.jsx","sourceRoot":"","sources":["../../src/components/item-icon.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"item-icon.jsx","sourceRoot":"","sources":["../../src/components/item-icon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAuB,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AA0ClF,uEAAuE;AACvE,sEAAsE;AACtE,6CAA6C;AAC7C,MAAM,cAAc,GAClB,QAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAA6B,CAAC,CAAC,CAAC,EAAE,CAAC;AAElG;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,QAAQ,CAAC,EACnD,OAAO,EACP,OAAO,EACP,IAAI,GAAG,EAAE,EACT,SAAS,EACT,YAAY,EACZ,UAAU,EACV,aAAa,EACb,WAAW,GAAG,UAAU,EACxB,WAAW,GAAG,UAAU,EACxB,aAAa,GACC;IACd,MAAM,EAAE,WAAW,EAAE,GAAG,cAAc,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,WAAW,KAAK,MAAM,CAAC;IAEtC,MAAM,QAAQ,GAAG,WAAW,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;IACvE,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;IAEnF,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAChE,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpD,SAAS,CAAC,GAAG,EAAE;QACb,aAAa,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IACpD,MAAM,aAAa,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;IAC7D,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,UAAU,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;IACjF,MAAM,UAAU,GAAG,YAAY,IAAI,IAAI,GAAG,IAAI,CAAC;IAC/C,MAAM,SAAS,GAAG,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,aAAa,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;IAE3F,MAAM,YAAY,GAAG,CAAC,SAAS,IAAI,aAAa,CAAC;IAEjD,OAAO,CACL,CAAC,IAAI,CACH,KAAK,CAAC,CAAC;YACL,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,IAAI;YACZ,YAAY,EAAE,UAAU;YACxB,eAAe,EAAE,MAAM;YACvB,UAAU,EAAE,QAAQ;YACpB,cAAc,EAAE,QAAQ;YACxB,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAEF;MAAA,CAAC,YAAY,CAAC,CAAC,CAAC,CACd,CAAC,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,EAAG,CACzF,CAAC,CAAC,CAAC,CACF,CAAC,KAAK,CACJ,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,IAAI,EAAE,EAAE,CAAC,CACjC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAC/C,UAAU,CAAC,SAAS,CACpB,OAAO,CAAC,CAAC,OAAO,CAAC,CACjB,gCAAgC,CAChC,IAAI,cAAc,CAAC,EACnB,CACH,CACH;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -4,6 +4,21 @@ import React from "react";
4
4
  * the active palette via NativeWind classes). Self-manages the entered
5
5
  * digits and fires `onComplete` when `length` is reached; pass a changing
6
6
  * `resetKey` to clear it (e.g. after a wrong PIN).
7
+ *
8
+ * # Sizing
9
+ *
10
+ * The pad measures itself against the viewport instead of sitting at a fixed
11
+ * 288px. On a modern phone a fixed pad reads as a small control marooned in the
12
+ * middle of a large screen — and this is the primary way into the app for a
13
+ * device-only vault, so it should feel like the screen's purpose rather than a
14
+ * widget on it. Keys grow with the available width and stop at `MAX_KEY` so a
15
+ * tablet does not get comedy-sized buttons.
16
+ *
17
+ * # Why the keys have a fill
18
+ *
19
+ * They previously had no background at all until the moment of the press, which
20
+ * left three columns of bare digits that did not read as pressable. A resting
21
+ * fill plus a border is what makes a target look like a target.
7
22
  */
8
23
  export interface PinPadProps {
9
24
  length?: number;
@@ -14,7 +29,13 @@ export interface PinPadProps {
14
29
  /** Bump to clear the entered digits. */
15
30
  resetKey?: string | number;
16
31
  error?: boolean;
32
+ /**
33
+ * Haptic feedback on each key. On by default, and a no-op on web and on any
34
+ * device without a haptic engine. Pass `false` where a press already triggers
35
+ * feedback of its own.
36
+ */
37
+ haptics?: boolean;
17
38
  }
18
- export declare function PinPad({ length, onComplete, onChange, onBiometric, resetKey, error, }: PinPadProps): React.JSX.Element;
39
+ export declare function PinPad({ length, onComplete, onChange, onBiometric, resetKey, error, haptics, }: PinPadProps): React.JSX.Element;
19
40
  export default PinPad;
20
41
  //# sourceMappingURL=pin-pad.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pin-pad.d.ts","sourceRoot":"","sources":["../../src/components/pin-pad.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAID,wBAAgB,MAAM,CAAC,EACrB,MAAU,EACV,UAAU,EACV,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,KAAK,GACN,EAAE,WAAW,qBAqGb;AAyBD,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"pin-pad.d.ts","sourceRoot":"","sources":["../../src/components/pin-pad.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAOxE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAWD,wBAAgB,MAAM,CAAC,EACrB,MAAU,EACV,UAAU,EACV,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,KAAK,EACL,OAAc,GACf,EAAE,WAAW,qBAoJb;AAmDD,eAAe,MAAM,CAAC"}
@@ -1,11 +1,28 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from "react";
2
- import { Platform, Pressable, Text, View } from "react-native";
2
+ import { Platform, Pressable, Text, useWindowDimensions, View } from "react-native";
3
+ import Animated, { useAnimatedStyle, useSharedValue, withTiming } from "react-native-reanimated";
4
+ import * as Haptics from "expo-haptics";
3
5
  import { useColorScheme } from "nativewind";
4
6
  import { Delete, Fingerprint } from "lucide-react-native";
5
7
  const KEYS = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];
6
- export function PinPad({ length = 6, onComplete, onChange, onBiometric, resetKey, error, }) {
8
+ /** Key diameter bounds, and the gap between them. */
9
+ const MIN_KEY = 76;
10
+ const MAX_KEY = 104;
11
+ const GAP = 16;
12
+ /** Room left for the screen's own horizontal padding. */
13
+ const SIDE_PADDING = 48;
14
+ export function PinPad({ length = 6, onComplete, onChange, onBiometric, resetKey, error, haptics = true, }) {
7
15
  const { colorScheme } = useColorScheme();
8
- const iconColor = colorScheme === "dark" ? "#FFFFFF" : "#000000";
16
+ const isDark = colorScheme === "dark";
17
+ const iconColor = isDark ? "#FFFFFF" : "#000000";
18
+ const { width } = useWindowDimensions();
19
+ // Three keys and two gaps have to fit inside the viewport less the screen's
20
+ // padding. Clamped at both ends: MIN_KEY keeps the pad usable on a small
21
+ // phone even if that means it is the widest thing on screen, MAX_KEY stops a
22
+ // tablet from rendering three dinner plates.
23
+ const keySize = Math.max(MIN_KEY, Math.min(MAX_KEY, Math.floor((width - SIDE_PADDING - 2 * GAP) / 3)));
24
+ const padWidth = keySize * 3 + GAP * 2;
25
+ const dotSize = Math.round(keySize * 0.17);
9
26
  const [pin, setPin] = useState("");
10
27
  // Source of truth for the latest digits — lets callbacks fire OUTSIDE the
11
28
  // setPin updater (calling a parent setState inside an updater triggers
@@ -21,11 +38,28 @@ export function PinPad({ length = 6, onComplete, onChange, onBiometric, resetKey
21
38
  setPin("");
22
39
  }
23
40
  }
41
+ /**
42
+ * A tap you can feel.
43
+ *
44
+ * Deliberately fire-and-forget: the feedback is worth nothing if the digit
45
+ * waits for it, and a device with no haptic engine rejects the promise rather
46
+ * than throwing, which must not surface as an unhandled rejection over a
47
+ * keypress.
48
+ */
49
+ const tap = useCallback(() => {
50
+ if (!haptics || Platform.OS === "web") {
51
+ return;
52
+ }
53
+ void Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light).catch(() => {
54
+ // No haptic engine, or the OS declined. Nothing to say about it.
55
+ });
56
+ }, [haptics]);
24
57
  const press = useCallback((d) => {
25
58
  const cur = pinRef.current;
26
59
  if (cur.length >= length) {
27
60
  return;
28
61
  }
62
+ tap();
29
63
  const next = cur + d;
30
64
  pinRef.current = next;
31
65
  setPin(next);
@@ -33,13 +67,17 @@ export function PinPad({ length = 6, onComplete, onChange, onBiometric, resetKey
33
67
  if (next.length === length) {
34
68
  onComplete(next);
35
69
  }
36
- }, [length, onChange, onComplete]);
70
+ }, [length, onChange, onComplete, tap]);
37
71
  const back = useCallback(() => {
72
+ if (pinRef.current.length === 0) {
73
+ return;
74
+ }
75
+ tap();
38
76
  const next = pinRef.current.slice(0, -1);
39
77
  pinRef.current = next;
40
78
  setPin(next);
41
79
  onChange?.(next);
42
- }, [onChange]);
80
+ }, [onChange, tap]);
43
81
  // Physical keyboard / numpad support (web): digits type, Backspace/Delete
44
82
  // removes, Enter submits a full PIN.
45
83
  useEffect(() => {
@@ -65,29 +103,44 @@ export function PinPad({ length = 6, onComplete, onChange, onBiometric, resetKey
65
103
  window.addEventListener("keydown", onKey);
66
104
  return () => window.removeEventListener("keydown", onKey);
67
105
  }, [press, back, onComplete, length]);
68
- return (<View className="items-center gap-7">
106
+ return (<View className="items-center gap-8">
69
107
  {/* dots */}
70
- <View className="flex-row gap-3">
71
- {Array.from({ length }).map((_, i) => (<View key={i} className={i < pin.length
108
+ <View className="flex-row" style={{ gap: Math.round(dotSize * 0.9) }}>
109
+ {Array.from({ length }).map((_, i) => (<View key={i} style={{ width: dotSize, height: dotSize, borderRadius: dotSize / 2 }} className={i < pin.length
72
110
  ? error
73
- ? "h-3.5 w-3.5 rounded-full bg-destructive dark:bg-red-900"
74
- : "h-3.5 w-3.5 rounded-full bg-primary dark:bg-white"
75
- : "h-3.5 w-3.5 rounded-full border-2 border-border dark:border-neutral-800"}/>))}
111
+ ? "bg-destructive dark:bg-red-900"
112
+ : "bg-primary dark:bg-white"
113
+ : "border-2 border-border dark:border-neutral-700"}/>))}
76
114
  </View>
77
115
 
78
116
  {/* keypad */}
79
- <View className="w-72 flex-row flex-wrap justify-center gap-3">
80
- {KEYS.map((k) => (<Key key={k} label={k} onPress={() => press(k)}/>))}
81
- {onBiometric ? (<Key onPress={onBiometric} icon={<Fingerprint size={26} color={iconColor}/>}/>) : (<View className="h-20 w-20"/>)}
82
- <Key label="0" onPress={() => press("0")}/>
83
- <Key onPress={back} icon={<Delete size={24} color={iconColor}/>}/>
117
+ <View className="flex-row flex-wrap justify-center" style={{ width: padWidth, gap: GAP }}>
118
+ {KEYS.map((k) => (<Key key={k} label={k} size={keySize} onPress={() => press(k)}/>))}
119
+ {onBiometric ? (<Key size={keySize} onPress={onBiometric} icon={<Fingerprint size={Math.round(keySize * 0.34)} color={iconColor}/>} accessibilityLabel="Unlock with biometrics"/>) : (<View style={{ width: keySize, height: keySize }}/>)}
120
+ <Key label="0" size={keySize} onPress={() => press("0")}/>
121
+ <Key size={keySize} onPress={back} icon={<Delete size={Math.round(keySize * 0.3)} color={iconColor}/>} accessibilityLabel="Delete"/>
84
122
  </View>
85
123
  </View>);
86
124
  }
87
- function Key({ label, icon, onPress, }) {
88
- return (<Pressable onPress={onPress} className="h-20 w-20 items-center justify-center rounded-full active:bg-secondary dark:active:bg-neutral-800" accessibilityRole="button" accessibilityLabel={label ?? "key"}>
89
- {icon ?? (<Text className="font-sans-medium text-2xl text-foreground dark:text-white">{label}</Text>)}
90
- </Pressable>);
125
+ function Key({ label, icon, size, onPress, accessibilityLabel, }) {
126
+ // Same two-part response as Button: a dip in scale and a lift in fill. The
127
+ // fill change alone was too easy to miss on a dark screen, and on a keypad
128
+ // "did that register?" is the entire question the user is asking.
129
+ const pressed = useSharedValue(0);
130
+ const pressStyle = useAnimatedStyle(() => ({
131
+ transform: [{ scale: 1 - pressed.value * 0.08 }],
132
+ }));
133
+ return (<Animated.View style={pressStyle}>
134
+ <Pressable onPress={onPress} onPressIn={() => {
135
+ pressed.value = withTiming(1, { duration: 60 });
136
+ }} onPressOut={() => {
137
+ pressed.value = withTiming(0, { duration: 160 });
138
+ }} style={{ width: size, height: size, borderRadius: size / 2 }} className="items-center justify-center border border-border bg-secondary active:bg-border dark:border-neutral-700 dark:bg-neutral-900 dark:active:bg-neutral-700" accessibilityRole="button" accessibilityLabel={accessibilityLabel ?? label ?? "key"}>
139
+ {icon ?? (<Text className="font-sans-medium text-foreground dark:text-white" style={{ fontSize: Math.round(size * 0.38) }}>
140
+ {label}
141
+ </Text>)}
142
+ </Pressable>
143
+ </Animated.View>);
91
144
  }
92
145
  export default PinPad;
93
146
  //# sourceMappingURL=pin-pad.jsx.map
@@ -1 +1 @@
1
- {"version":3,"file":"pin-pad.jsx","sourceRoot":"","sources":["../../src/components/pin-pad.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pin-pad.jsx","sourceRoot":"","sources":["../../src/components/pin-pad.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpF,OAAO,QAAQ,EAAE,EAAE,gBAAgB,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACjG,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAwC1D,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAC;AAEpE,qDAAqD;AACrD,MAAM,OAAO,GAAG,EAAE,CAAC;AACnB,MAAM,OAAO,GAAG,GAAG,CAAC;AACpB,MAAM,GAAG,GAAG,EAAE,CAAC;AACf,yDAAyD;AACzD,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,MAAM,UAAU,MAAM,CAAC,EACrB,MAAM,GAAG,CAAC,EACV,UAAU,EACV,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,KAAK,EACL,OAAO,GAAG,IAAI,GACF;IACZ,MAAM,EAAE,WAAW,EAAE,GAAG,cAAc,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,WAAW,KAAK,MAAM,CAAC;IACtC,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IACjD,MAAM,EAAE,KAAK,EAAE,GAAG,mBAAmB,EAAE,CAAC;IAExC,4EAA4E;IAC5E,yEAAyE;IACzE,6EAA6E;IAC7E,6CAA6C;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CACtB,OAAO,EACP,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,YAAY,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CACpE,CAAC;IACF,MAAM,QAAQ,GAAG,OAAO,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAE3C,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnC,0EAA0E;IAC1E,uEAAuE;IACvE,wEAAwE;IACxE,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,CAAC,OAAO,GAAG,GAAG,CAAC;IAErB,+BAA+B;IAC/B,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,UAAU,CAAC,QAAQ,CAAC,CAAC;QACrB,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,CAAC,OAAO,GAAG,EAAE,CAAC;YACpB,MAAM,CAAC,EAAE,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE;QAC3B,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;YACtC,OAAO;QACT,CAAC;QACD,KAAK,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACrE,iEAAiE;QACnE,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,MAAM,KAAK,GAAG,WAAW,CACvB,CAAC,CAAS,EAAE,EAAE;QACZ,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC;QAC3B,IAAI,GAAG,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;YACzB,OAAO;QACT,CAAC;QACD,GAAG,EAAE,CAAC;QACN,MAAM,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;QACrB,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,MAAM,CAAC,IAAI,CAAC,CAAC;QACb,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC;QACjB,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC3B,UAAU,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,EACD,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,CACpC,CAAC;IAEF,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE;QAC5B,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO;QACT,CAAC;QACD,GAAG,EAAE,CAAC;QACN,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,MAAM,CAAC,IAAI,CAAC,CAAC;QACb,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;IAEpB,0EAA0E;IAC1E,qCAAqC;IACrC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;YAC3D,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,CAAC,CAAgB,EAAE,EAAE;YACjC,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC;gBACjC,CAAC,CAAC,cAAc,EAAE,CAAC;gBACnB,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACf,CAAC;iBAAM,IAAI,CAAC,CAAC,GAAG,KAAK,WAAW,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;gBACvD,CAAC,CAAC,cAAc,EAAE,CAAC;gBACnB,IAAI,EAAE,CAAC;YACT,CAAC;iBAAM,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;gBAC7B,CAAC,CAAC,cAAc,EAAE,CAAC;gBACnB,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;oBACrC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAC7B,CAAC;YACH,CAAC;QACH,CAAC,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAC1C,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC5D,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;IAEtC,OAAO,CACL,CAAC,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAClC;MAAA,CAAC,UAAU,CACX;MAAA,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC,EAAE,CAAC,CACnE;QAAA,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CACpC,CAAC,IAAI,CACH,GAAG,CAAC,CAAC,CAAC,CAAC,CACP,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,GAAG,CAAC,EAAE,CAAC,CACtE,SAAS,CAAC,CACR,CAAC,GAAG,GAAG,CAAC,MAAM;gBACZ,CAAC,CAAC,KAAK;oBACL,CAAC,CAAC,gCAAgC;oBAClC,CAAC,CAAC,0BAA0B;gBAC9B,CAAC,CAAC,gDACN,CAAC,EACD,CACH,CAAC,CACJ;MAAA,EAAE,IAAI,CAEN;;MAAA,CAAC,YAAY,CACb;MAAA,CAAC,IAAI,CAAC,SAAS,CAAC,mCAAmC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CACvF;QAAA,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAG,CAClE,CAAC,CACF;QAAA,CAAC,WAAW,CAAC,CAAC,CAAC,CACb,CAAC,GAAG,CACF,IAAI,CAAC,CAAC,OAAO,CAAC,CACd,OAAO,CAAC,CAAC,WAAW,CAAC,CACrB,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,EAAG,CAAC,CAC1E,kBAAkB,CAAC,wBAAwB,EAC3C,CACH,CAAC,CAAC,CAAC,CACF,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAG,CACrD,CACD;QAAA,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EACxD;QAAA,CAAC,GAAG,CACF,IAAI,CAAC,CAAC,OAAO,CAAC,CACd,OAAO,CAAC,CAAC,IAAI,CAAC,CACd,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,EAAG,CAAC,CACpE,kBAAkB,CAAC,QAAQ,EAE/B;MAAA,EAAE,IAAI,CACR;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC;AAED,SAAS,GAAG,CAAC,EACX,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,kBAAkB,GAOnB;IACC,2EAA2E;IAC3E,2EAA2E;IAC3E,kEAAkE;IAClE,MAAM,OAAO,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC;QACzC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,EAAE,CAAC;KACjD,CAAC,CAAC,CAAC;IAEJ,OAAO,CACL,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAC/B;MAAA,CAAC,SAAS,CACR,OAAO,CAAC,CAAC,OAAO,CAAC,CACjB,SAAS,CAAC,CAAC,GAAG,EAAE;YACd,OAAO,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QAClD,CAAC,CAAC,CACF,UAAU,CAAC,CAAC,GAAG,EAAE;YACf,OAAO,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;QACnD,CAAC,CAAC,CACF,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC,CAC7D,SAAS,CAAC,uJAAuJ,CACjK,iBAAiB,CAAC,QAAQ,CAC1B,kBAAkB,CAAC,CAAC,kBAAkB,IAAI,KAAK,IAAI,KAAK,CAAC,CAEzD;QAAA,CAAC,IAAI,IAAI,CACP,CAAC,IAAI,CACH,SAAS,CAAC,kDAAkD,CAC5D,KAAK,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,CAE7C;YAAA,CAAC,KAAK,CACR;UAAA,EAAE,IAAI,CAAC,CACR,CACH;MAAA,EAAE,SAAS,CACb;IAAA,EAAE,QAAQ,CAAC,IAAI,CAAC,CACjB,CAAC;AACJ,CAAC;AAED,eAAe,MAAM,CAAC"}
@@ -2,6 +2,6 @@ export { AuthProvider, useAuth, useRole, useRequireAuth, useSession, type AuthPr
2
2
  export { useShakeAnimation } from "./useShakeAnimation";
3
3
  export { useDebouncedValue } from "./useDebouncedValue";
4
4
  export { useAutoLock, type UseAutoLockOptions } from "./useAutoLock";
5
- export { useUploadBlobUrl, type UploadBlobUrlResult } from "./useUploadBlobUrl";
5
+ export { type UploadBlobUrlOptions, type UploadBlobUrlResult, type UploadResolver, useUploadBlobUrl, } from "./useUploadBlobUrl";
6
6
  export { usePasswordGenerator, getPasswordStrength, type UsePasswordGeneratorResult, type PasswordStrength, type BreachState, } from "./usePasswordGenerator";
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,OAAO,EACP,OAAO,EACP,cAAc,EACd,UAAU,EACV,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,GAC7B,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAErE,OAAO,EAAE,gBAAgB,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEhF,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,KAAK,0BAA0B,EAC/B,KAAK,gBAAgB,EACrB,KAAK,WAAW,GACjB,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,OAAO,EACP,OAAO,EACP,cAAc,EACd,UAAU,EACV,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,GAC7B,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAErE,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,KAAK,0BAA0B,EAC/B,KAAK,gBAAgB,EACrB,KAAK,WAAW,GACjB,MAAM,wBAAwB,CAAC"}
@@ -2,6 +2,6 @@ export { AuthProvider, useAuth, useRole, useRequireAuth, useSession, } from "./u
2
2
  export { useShakeAnimation } from "./useShakeAnimation";
3
3
  export { useDebouncedValue } from "./useDebouncedValue";
4
4
  export { useAutoLock } from "./useAutoLock";
5
- export { useUploadBlobUrl } from "./useUploadBlobUrl";
5
+ export { useUploadBlobUrl, } from "./useUploadBlobUrl";
6
6
  export { usePasswordGenerator, getPasswordStrength, } from "./usePasswordGenerator";
7
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,OAAO,EACP,OAAO,EACP,cAAc,EACd,UAAU,GAKX,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,WAAW,EAA2B,MAAM,eAAe,CAAC;AAErE,OAAO,EAAE,gBAAgB,EAA4B,MAAM,oBAAoB,CAAC;AAEhF,OAAO,EACL,oBAAoB,EACpB,mBAAmB,GAIpB,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,OAAO,EACP,OAAO,EACP,cAAc,EACd,UAAU,GAKX,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,WAAW,EAA2B,MAAM,eAAe,CAAC;AAErE,OAAO,EAIL,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,oBAAoB,EACpB,mBAAmB,GAIpB,MAAM,wBAAwB,CAAC"}