feat: add protections vault (hub, create flow, detail, withdraw) - #53
Open
nicoletting wants to merge 53 commits into
Open
feat: add protections vault (hub, create flow, detail, withdraw)#53nicoletting wants to merge 53 commits into
nicoletting wants to merge 53 commits into
Conversation
Optional indicator prop (icon | dot, default icon) so vault statuses can render a dot instead of a lucide icon. Backward-compatible — existing StatusPill usages are unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Textarea: add rightIcon, editable, minHeight and scrollEnabled for a read-only display + copy mode (used by the vault address). DetailKVRow: add onPressInfo for an info tooltip button on the label. Both backward-compatible. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Numeric keypad for amount entry, rebuilt in StyleSheet + theme.ts from the kastle-mobile reference (components/ui/keypad.tsx). Pure and controlled (value/onChange); del long-press clears; fraction-digit cap. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Vault view (VaultCard, CountdownRing, VaultAddressCard, VaultListScreen, VaultDetailScreen), hub (ProtectionTypeCard, ProtectionsHubScreen) and create step 1 (CreateVaultAmountStep). Body-only, pure, props-driven. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Step 2 window (5 fixed presets, radio select, reuses Alert), step 3 external recovery address (reuses Textarea + Alert), step 4 confirm (VaultAddressCard + DetailKVRow summary + EstFeeSheet + InfoSheet + SwipeToConfirm). Body-only, pure, props-driven. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Withdraw confirmation bottom sheet (ActionSheet + VaultAddressCard + SwipeToConfirm), reused for Withdraw now and for starting a withdrawal. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Keypad: a fixed-height message row (an info link such as How a Vault works?, replaced by a red error) so toggling it never shifts the keys. Textarea: reserveErrorSpace keeps the error line's height even when empty (no layout jump). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
VaultAddressCard gains a labeled surface-card variant (header label + copy + chain badge) for the confirm screen; the bare Textarea reuse stays for the vault detail. Amount step moves the info/error into the keypad; confirm uses the labeled address card + bg50 summary; recovery reserves error space. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Figma's withdraw confirm (node 12802:619523) is a full screen — illustration + the external recovery address card + an Arrives in / Amount / Est. Fee summary + swipe — not a bottom sheet. Replaces WithdrawSheet, which was wrong. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replaces invented copy with the strings pulled from the Figma nodes: hub cards, window presets + alert, recovery hints + alerts, confirm and detail rows, tooltips, and How a Vault works. Note 'Refundable deposit' is really 'Recovery marker'. Layout: soon cards are not dimmed and keep the active colours, no chevron, correct Soon badge colours, address info icon beside the label, keypad info/error moved above the keypad and turned blue, fiat always shown, window rows no longer resize on select (padding compensates the border) and use a check rather than a filled dot, vault cards are a fixed height, the list scans with skeletons / hides the balance behind **** / orders newest first, and the detail hides the backup card while withdrawing. Alert title is now optional since Figma's alerts are description-only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
VaultIntroScreen (node 12711:223618) and ProtectionsBanner (node 13385:318218) — the entry points into the vault flow. Copy from Figma; the banner's exact styling still needs a parity pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
VaultBalanceRows (Figma node 13381:90879) — coins / lock rows whose borders collapse, Locked taps through to the vaults list. Also fills in the real How a Vault works? sheet copy (node 12824:656344) on the amount step. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Toast (shared): loading/success/error pill per Figma — spinner,
check-circle-2 (success), x-circle (danger), optional text action.
VaultBalanceRows: add `state` — default / scanning ("Scanning for
vaults...", textSecondary, no balance) / loading (skeleton values).
VaultDetailScreen — corrections after re-reading Figma
12802:617586 + the clawback withdraw variants 13393:44068:
- countdown label "Funds leave when this ends" -> "Funds leave in"
- Details title 14 textPrimary -> 16 SemiBold textSecondary
- Vault Status renders a StatusPill (dot), not plain text
- Vault amount gains its fiat sub-line ($200.232 USD)
- action button: locked = outline/muted "Withdraw",
withdrawing = orange (warning.w500) "Withdraw now", 18 Medium
- danger note ("Wasn't you? ...") sits in the action bar above the button
- backup "Done" 14 semibold -> 12 Medium
- stories: clawback countdown variants DD:HH:MM / HH:MM:SS / 90 days
DetailKVRow: three backward-compatible optional props — labelColor,
valueNode (for the pill), subValue (fiat line). Existing activity rows
render byte-identical.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
All 8 tooltip sheets on the Vault page pulled from Figma; three were
missing from the build:
- Vault amount ("The KAS going into your vault...")
- Funds leave in — the countdown label carries a 12px ⓘ (Figma
Frame 1410127708, gap 4), wired to CountdownRing.onPressInfo
- Arrives in — WithdrawConfirmScreen's first row
InfoSheet: optional `actions` row (Figma shows/hides the buttons on the
same Actionsheet, so this is a variant, not a new component). Buttons
40 high, r9999, 16 Medium, gap 12 — outline (#7b9aaa) / warning
(#fb954b), matching the detail screen's action colours.
VaultDetailScreen: "Withdraw now" raises the clawback confirm sheet
("Withdraw now?" / Back / Withdraw now).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Clawback confirm states are Toasts over the screen behind them (Figma 12802:633805), not new screens: - loading "Sending to your recovery address…" (vault detail) - fail "Couldn't withdraw" + Close (vault detail) - success "Withdrawal complete" + View TX (vaults list) Story decorator padded to Figma's toast wrapper offset (120 from top). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New shared BottomActionBar (Figma "Button Container" 12698:208160) — pad [12,20,16,20], gap 12, buttons 48 high, message slot above them. Every screen's CTA now comes from one place instead of per-screen hand-rolled spacing. Variants: primary / outline / warning. Assets: vault.png + vault-intro.png exported from Figma; kaspa-logo.png + us-flag.png copied from kastle-mobile. CreateVaultAmountStep - error + "How a Vault works?" move INTO the action bar above Continue (Figma 12831:678052) — they were floating above the keypad - info/error rows gain the ⓘ icon, coloured to match their text - amount gains the Kaspa logo + "KAS" 20 SemiBold; fiat row gains the USD flag chip + KAS/USD swap button (Figma 12757:300288) Keypad — measured against Figma 12831:678052 - key height 48 -> 40, row gap 16 -> 4, del icon 20 -> 18 - Max button 32 -> 36 high, label semibold -> 14 Medium - grid inset [0,12,0,10] so keys land on their 118-wide columns VaultDetailScreen - real vault artwork; hero art only while locked (withdrawing shows the ring alone, per Figma) - Details title gains its paddingVertical 12 - backup title: drop the alert-triangle (hidden in Figma) and give the header its 32 height - Recovery address is plain white, not a blue link - action bar -> BottomActionBar DetailKVRow: the whole row is the tooltip tap target, and the ⓘ takes its colour from the adjacent label. VaultIntroScreen: real artwork + BottomActionBar. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
CreateVaultWindowStep: the checkbox was a p500 circle; Figma (12757:304730) is a 16px rounded square (r6) with a 2px b400 outline, filled with the brighter p600 (colors.link) + a white 12px check when selected. That p500 fill is why the enabled state read as dim. ProtectionsHubScreen: the active ProtectionTypeCard gets its chevron-right back (20px, secondary.s500). The title icon stays off — only the trailing chevron is in Figma. CreateVaultConfirmStep - the recovery card's ⓘ never opened anything: VaultAddressCard was rendered without onPressInfo. Wired via a new recoveryTooltip prop. - Est. Fee opened its sheet through onPressValue, which is what turned the value blue and added a link icon; it now opens from the ⓘ like every other explainer. VaultAddressCard: the whole label row is the tap target, and the ⓘ only renders when it does something. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
CreateVaultAmountStep: the info link can't share the action bar with the CTA, so "How a Vault works?" moves back above the keypad (ⓘ + link blue, pad [16,0,16,0]). The action bar's message slot now carries the validation error only — that part was right. BottomActionBar: a one-line message centres under the button; once it wraps it left-aligns with the icon pinned to the first line, measured off the rendered text height rather than a character count. CreateVaultConfirmStep: summary labels were falling back to the row's muted default — they take typography.t800 per Nicole. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
VaultDetailScreen: Done now dismisses the backup card (the state the flow was missing) and gets a real 32-high tap target instead of bare 12px text. New backupDone prop + LockedBackedUp story. CreateVaultWindowStep: checkbox is round per Nicole — the Figma node draws a 6px-radius square, noted in the style. ProtectionsBanner: takes an illustration that bleeds off the right edge, with the copy inset clear of it. Awaiting Nicole's exported artwork. VaultCard: stories pass the vault artwork — the slot existed but nothing ever filled it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Alert: the description carried opacity 0.6, which washed the info banner's p800 text out — Figma (12757:330135) renders it at full strength. The severity token was right all along; the opacity was the bug. Affects the two create-vault steps and ImportPassphraseScreen. DetailKVRow: `emphasis` renders a total row — bold label + value on a bg100 fill that bleeds to the card's edges (Figma 12757:476249, where the total's Table input is filled and borderless while every other row is transparent with a divider). CreateVaultConfirmStep: "Total from wallet" uses it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The labeled VaultAddressCard filled with white 5%, which composites to a shade off the bg50 summary card directly below it on the confirm step. Figma has the two surfaces genuinely different; Nicole's call is bg50 for both. Noted in the style so the divergence from the node is deliberate. Affects the confirm step and the withdraw confirm screen (the vault detail backup card uses the bare variant and is untouched). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
kastle-ui had no signing illustration — the explore sign sheets use dApp icons, not artwork — so sign.png comes from kastle-mobile. WithdrawConfirmScreen and CreateVaultConfirmStep both default to it (the create step had no artwork at all). VaultCard defaults to the vault artwork rather than the lucide glyph, so the list grid gets it without every caller remembering to pass it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Verified against Figma 13385:286750 by screenshotting both sides rather than reading the node dump alone. - the stack is one r16 card; the shared border reads as a divider - value + chevron sit flush right (the value was floating mid-row because the label column was a fixed 114 and the value hugged it) - scanning: lucide LoaderCircle, not the 8-spoke Loader - scanning label is textDimmed (#4B7D92), not textSecondary — caught while checking the loader, not reported - loading: the chevron dims to 40% Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The vault address rendered in t900 white; Figma binds it to
Typography/typography600 (#9EB7C4). Resolved from the node's variable
binding, not by hex-matching — t800/t900/white are indistinguishable by
value.
Scoped to editable={false}, which only VaultAddressCard's bare variant
uses, so typed input keeps t900.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Both caught by the parity pass, neither reported by Nicole. - Figma's Table input is 50 high with a hairline underneath (Border/border200, bottom edge only). DetailKVRow gains `divider`; the vault table draws it on every row but the last. - The Vault amount row shows a 20px Kaspa logo and hides the ⓘ (logo frame > Token > Kaspa). Nicole confirmed: keep the logo, drop the tooltip. DetailKVRow gains `labelIcon`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Figma's Amount Info stacks [amount+KAS] / [fiat+USD chip] / [swap], with the 32px swap button on its own row pinned right (counterAxisAlignItems MAX). It was inline in the fiat row. Also checked and NOT changed: the amount step has no title/subtitle in the body. "How much to protect?" and its subtitle resolve to Content > Header > Top nav — header content, which lives in kastle-mobile (去頭去尾). They look missing in a side-by-side; the node chain says they aren't ours. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Same hairline the vault detail table was missing (Figma's confirm Table input carries a bottom stroke; the filled total row doesn't). Labels move to typography.t900 — the node binds raw typography800, but Nicole's semantic set (Figma "Fixed Colors": Text/Title Color -> t900, Secondary -> t600, Tertiary -> t400) has no t800, so the binding bypasses the system. Same #FFFFFF either way; her call is t900. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Figma's preset row is text + checkbox only: the row's logo frame slot is hidden. The clock-in-a-circle was invented, same as the alert-triangle on the backup title. "Recommended" sits on the right beside the checkbox, not next to the label. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Figma's Balance Container is edge-to-edge with a Border/border50 bottom stroke separating it from the grid (pad [8,20,8,20]). Kept as-is, deliberately: the card timer reads "20h:02m:02s" where the Figma node shows "20:02:02" — Nicole asked for the units explicitly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Figma 12711:223618 stacks: ⓘ "How a Vault works?" link / "Set up now" (primary) / "Close" (outline). The second button read "How a Vault works?" and there was no Close — the info link belongs in the action bar's message slot, which is what that slot is for. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Exported from Figma (Vault/ Notification Container's Rectangle fill) rather than waiting on a hand-off — same route as vault.png. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Figma binds every badge label to the 800 tone of its ramp (Success/success800 #5EEAD4 over Success/success background) — the 500/600 tones I had are the brand/indicator colours. Nicole's call: follow Figma. Affects the shared pill, so ActivityScreen + ActivityDetailSheet change too — the Figma Badge component uses the same 800 tone for its own SUCCESS/PENDING/FAILED variants, so they should match. The dot/icon keeps the brand tone: its fill sits in a nested instance the export doesn't resolve, so it isn't verified either way — not guessed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Nicole's call: the vault/quote table isn't the activity row. DetailKVRow is a two-tone label/value line for the activity sheet — closer to the swap quote — and bending it into the vault's table had taken six added props (labelColor, valueNode, subValue, emphasis, labelIcon, divider) before it stopped being the same component. - DetailKVRow reverted to main verbatim: Paul's Activity sheet renders exactly as before, and the PR no longer carries six props his feature never uses. - New protections/DetailTable owns what the vault table actually is (Figma "Table Component"): bordered r16 bg50 card, 50-high rows, Border/border200 hairlines, white labels, pill + token-logo slots, fiat sub-lines, filled bold total, whole-row ⓘ targets. - VaultDetailScreen, CreateVaultConfirmStep, WithdrawConfirmScreen all moved over; screenshots identical before/after. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Figma's protection hub has two states and only "user never create a vault" was built. The other (13385:419530) drops the CTA and puts a status pill before the chevron — the card stops selling the feature and starts reporting on it. ProtectionTypeCard gains `pill` (a variant, not a second card). Stories: Locked / 1 vault withdrawing / 2 vaults withdrawing. Caption stays the same as the active state, per Nicole. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Her exports replace mine: the intro vault keeps its glow, which my export lost — the glow ellipses use a blend mode that only resolves over the dark page, so a standalone node export baked them into an opaque blob. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- CountdownRing + VaultCard timers use tabular figures. Proportional digits are each a different width, so a live countdown reflowed on every tick; this locks them to one width without freezing the layout. - Window step rows are 68 high per Figma (they were ~46). The fixed height also absorbs the 1→2px border on select, so the +1 padding compensation is only needed horizontally now. - Amount step: the USD chip had a surface fill I invented — Figma's Button has no fill. - Intro screen: "How a Vault works?" now opens the explainer; the link was wired to a callback with no sheet behind it. - Vault list: six vaults (Populated + BalanceHidden), so the grid and scrolling are actually exercised. - Story rename: LockedBackedUp -> LockedAddressSaved (states should read as states, not as steps the user took). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The old one was the last "needs a Figma parity pass" draft and was wrong in every dimension: ~3x too tall, no artwork, no shield, no dismiss, and a filled CTA button where Figma has a text link. Now matches "Vault/ Notification Container": 353x113, bg50, r16, pad [16,16,8,16], gap 12; artwork 364 wide at x=-6 so it bleeds both edges; shield 18; title 14 Bold; body 12 Regular typography600; "Set up now" as a 14 Medium primary text link; 20px round dismiss on background500. Two design-system gaps flagged inline, not guessed away: - the border is a 3-stop linear gradient (#4adcef/#00d7ff/#0095f1) — no theme.ts token matches any stop, and expo-linear-gradient isn't a dependency (Paul's call). Solid brand tone stands in. - the title binds no variable: raw #f4f3f2, no theme.ts counterpart. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The ring was primary.p50 dark blue. Figma (13409:25553) stacks two amber arcs at innerRadius 0.87: a base in Warning/Warning soft background (#b45a1a @ 24% — exactly theme's warning.softBackground) and a `start` arc in Warning/warning500 on top, which is the progress sweep. I recorded "solid ring, primary.p50" back when Nicole confirmed "實心環 :無問題" — she was confirming it isn't a gradient, not confirming the colour. I took one answer as two. - base ring now amber; the whole caption is the ⓘ tap target, not the 12px icon - CountdownRing stories wire a real InfoSheet, so the ⓘ opens the explainer in isolation instead of calling into nothing - story names read as states: NearEnd -> UnderOneDay, LiveTicking -> Ticking⚠️ The progress sweep is NOT drawn — an arc needs react-native-svg, which isn't a dependency (Paul's call). The ring shows the track only. Flagged to Nicole. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Both still hand-rolled their own Continue button and action bar — the exact per-screen spacing drift BottomActionBar was created to end. Found by auditing every protections file's shared-component imports rather than waiting for the spacing to look wrong again. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Nicole changed the node so the copy no longer overlaps the vault art. v2 wraps [shield + text] in one flex group, then a 46px gap, then the close — that reserved right zone is what the graphic shows through. The text column is ~34px narrower than before, so it wraps before the vault instead of running over it. Responsive: - artwork is right-anchored (contentPosition right, bleeds -6) so the vault hugs the right edge at any width, not pinned to a 353 box - content flexes; the 46 gap + 20 close reserve stays fixed on the right Verified the copy clears the vault at 360 / 393 / 430 wide. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
VaultCard - removed the `complete` status — Figma's vault list only has Locked / Withdrawing (it was invented, like the earlier clock icon) - removed the Grid story — VaultListScreen/Populated already shows the real grid; Grid was a layout demo masquerading as a card state - amount splits into number + unit: the number truncates with an ellipsis (flexShrink + minWidth:0) while the unit (flexShrink:0) stays whole on the same line, so a huge amount can't wrap "KAS" onto a second line and every card keeps its 222 height. New WithdrawingLongAmount story exercises it.⚠️ truncate-number / pin-unit is my proposal for the overflow case — Figma doesn't specify it; confirm. VaultAddressCard (bare): read-only value is 14px per Figma, via a new backward-compatible `textStyle` override on the shared Textarea (Paul's 16px default is untouched). VaultBalanceRows: amount↔chevron gap 6 -> 8 (Figma). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The root View had no style, so it hugged content in some layouts — the bare VaultAddressCard came out ~half width next to the labeled variant. alignSelf: stretch on the root makes it fill, matching the labeled card and the backup card in VaultDetailScreen. Shared component, but this is the correct default for a textarea; existing users only get wider. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
CreateVaultAmountStep (Figma 12757:300288 / 12831:678052) - token section ↔ usd section gap 8 -> 12 - amount ↔ Kaspa logo gap 8 -> 10 (logo ↔ "KAS" stays 8) - usd value ↔ usd chip gap 8 -> 0 - action bar clears the keypad with 46 top padding; the error slot reserves its height so Continue never jumps CreateVaultConfirmStep (Figma 12757:476249) - image ↔ address card 16, address card ↔ quote 8 (was uniform 16) - Vault amount gains its "$200.232 USD" sub-line (ConfirmRow was dropping subValue before it reached DetailTable) - footer message slot added (both here and BottomActionBar) —⚠️ the copy (node 12757:461001) still needs the Figma bridge to read; slot is wired, text pending DetailTable: label ↔ tooltip icon gap 4 -> 8 InfoSheet: title ↔ divider was double-spaced (titleSection gap 16 + divider marginTop 16 = 32); dropped the marginTop, now 16 VaultCard: long-amount demo uses 1,000,000,000.9999999 KAS and a real vault name (users can't rename); also seeded into the vault list Naming: ProtectionsBanner story -> Home/; hub stories -> NoVaultYet / AllLocked / OneWithdrawing / TwoWithdrawing Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… gaps Read against Figma (bridge back up): - Alert info: bg was #1a282e; Nicole changed it to the blue soft tint Info/Warning soft background (#0973a8 @ 24%, fill + stroke both). Fill and stroke share info.softBackground now.⚠️ shared Alert — every info alert gets the new tint. - CreateVaultWindowStep checkbox: back to a 6px-radius square (Figma 12757:304731) — Nicole had earlier said circle, then corrected it. - VaultDetailScreen "Done": 12 Medium -> 14 Medium (Figma 13367:16830). - CreateVaultConfirmStep footer copy filled from Figma 12757:461001: "You can't change this later. To use different settings, close the vault and make a new one." - CreateVaultRecoveryStep: the two alerts sit 8 apart (was 16); they already reuse the shared Alert master. Added a Filled story (13493:967389) — an address entered; the 2px #4b7d92 active border is the Textarea's focus state. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Resolves the reuse violation: ProtectionsBanner had rebuilt what
explore/Banner already does. Both are the same Figma component set
("Notification Container").
New shared NotificationBanner (icon + title + description + LinkButton
CTA), with the two real differences as props, per Nicole:
- `art`: "cover" (faded full-bleed image, copy full width — explore) vs
"bleedRight" (graphic hugs the right, copy reserves its 46px zone —
the Protections banner's different caption width)
- `onPressDismiss`: the × is a toggle — pass a handler to show it, omit
to hide, since not every banner is dismissible
ProtectionsBanner is now a thin preset of it (bleedRight + vault art +
shield + solid brand border placeholder). Renders identically.
⚠️ explore/Banner (Paul's) is untouched — it can migrate to
NotificationBanner in a follow-up PR for his review; the shared API
already covers its shape (cover art, lucide/emoji icon, remote image).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Read against Figma (bridge up). VaultDetailScreen - Vault address + Recovery address rows get copy + external-link icons (Figma 12802:620022) — DetailTable gains onPressCopy/onPressExternal - withdraw danger line "Wasn't you? ..." is centred with no icon (Figma "Error message" hides its icon); colour was already Text/Invalid Color. BottomActionMessage gains hideIcon + alwaysCenter - backup note padding 4 -> 8 (Figma 13367:16830) - WithdrawingOneDayLeft now ticks the ring live in HH:MM:SS VaultIntroScreen - image was letterboxed: a 256x186 box on a 1.195:1 asset showed it ~222 wide. Box is now 256x214 (asset aspect), matching Figma's 248x213 - "How a Vault works?" gets 16 vertical padding (Figma "Info message") WithdrawConfirmScreen (Figma 12802:619523) - Amount gains "≈ $24,000 USD", Est. Fee gains "≈ $0 USD" - Est. Fee gains its ⓘ tooltip.⚠️ no vault-specific Est. Fee tooltip in Figma — reused the existing InfoSheet "Est. Fee" copy; confirm it fits - address card ↔ quote gap 16 -> 8 (image ↔ address stays 16) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Removed the Toast component + stories. Per Paul, the clawback result
toasts are wired app-side when the data flow lands; they don't belong
in Storybook.
- Copy corrected against Figma:
- intro title had a stray leading space -> "Your KAS just got a Vault"
- recovery error "Invalid Kaspa address" -> "That's not a valid Kaspa
address."
- amount error "Amount exceeds your balance" -> "Oh, you don't have
enough funds"
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
On iPhone SE (375) the Recovery address value wrapped to a second line
beside its copy/external icons ("kaspa:pfdf…" / "v45s") because the
longer "Recovery address" label left less room and the value allowed 2
lines. Address values are already middle-ellipsised, so DetailTable now
pins them to one line (numberOfLines 1) and lets them shrink
(flexShrink + minWidth:0) when a row has the copy/external actions.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The last row sat flush against the bottom when scrolled. Added 24 bottom padding to the grid so the final card has breathing room. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Est. Fee sheet (Figma 13350:255308 / 13393:63687): - EstFeeSheet gains free-form `label`, per-row `description`, and a `subtitle` prop (backward-compatible with the "<network> network fees" transfer usage). Vault breakdown now shows Network / Kastle / Creation fees with the creation note, "…for this transaction" subtitle. - WithdrawConfirmScreen Est. Fee ⓘ opens the breakdown sheet (Network + Kastle) instead of a wrong text tooltip. How a Vault works? sheet: - InfoSheet gains `descriptionRich` (white-semibold step headings + inline Normal:/Theft:). Shared HOW_VAULT_WORKS constant threaded through the amount step + intro screen. Vault detail (Galaxy S5 / iPhone SE): - Bare VaultAddressCard fills width + hugs height, address wraps (no scroll, no overflow). - Address values 12px; danger note amber not red; VaultCard timer keeps its icon and shrinks the number to stay on one line. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
onPressRecoveryInfo was a raw callback prop with no content wired to it
and never passed by the story, so VaultAddressCard's ⓘ disabled itself
(disabled={!onPressInfo}). Replaced with recoveryTooltip, mirroring
CreateVaultConfirmStep's pattern — same Figma instance (13391:560165)
both screens reuse.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Vault address / Recovery address rows carry a tooltip AND copy/external actions at once. The whole row was one TouchableOpacity firing onPressInfo, so tapping the copy or external icon fired the tooltip too (or fought it) instead of its own action. Now: label+ⓘ is its own zone (tooltip), the address text + copy icon share one zone (copy), the external-link icon is a third, separate zone (explorer). Verified by instrumenting the story's onPressCopy/ onPressExternal and clicking each zone's exact coordinates — each fires only its own callback, and only the label zone opens the tooltip sheet. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…stories
adjustsFontSizeToFit is a no-op in RN-web, so the countdown silently fell
back to numberOfLines ellipsis ("89d:23h:5…") instead of shrinking.
Same length-tier approach as CreateVaultAmountStep's AMOUNT_TIERS: both
real countdown formats ("20h:02m:02s", "89d:23h:59m") now render in full
down to a 360px-wide card.
Also adds DetailTable.stories.tsx — it had zero story coverage despite
being reused by 3 screens and just getting its tap-zone split; Default
covers every row shape, AddressRow isolates the ⓘ/copy/external split.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
🎨 Storybook Preview Ready!Your Storybook preview has been deployed and is available at: 🔗 Preview URL: https://forbole.github.io/kastle-ui/preview/pr-53/ 📝 What's included:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Protections Vault UI, body-only (no header/nav/routing — those stay in kastle-mobile): hub, the 4-step create flow, vault detail, withdraw confirm, and clawback. Built component-first against Figma (
BdTDUVIHEeOjdlHSPij0xi, page "└─ Vault").Screens
ProtectionsHubScreen— entry banner + live vault statusVaultListScreen— 2-column vault grid, balance summary, scanning/empty statesVaultIntroScreen,CreateVaultAmountStep,CreateVaultWindowStep,CreateVaultRecoveryStep,CreateVaultConfirmStep— create flowVaultDetailScreen— locked/withdrawing detail, backup card, clawbackWithdrawConfirmScreen— withdraw confirmNew shared components
BottomActionBar— owns action-bar spacing/message slot; every screen's CTA row now goes through it instead of hand-rolled barsDetailTable— the vault/quote summary table (reused by 3 screens)NotificationBanner— generalized fromProtectionsBanner(now a thin preset)Keypad,VaultCard,VaultAddressCard,VaultBalanceRows,CountdownRing,ProtectionTypeCardAlert,InfoSheet(rich-text runs),EstFeeSheet(free-form labels + description rows for the vault fee breakdown),StatusPill,TextareaWhy
New Protections Vault feature — locks KAS behind a time-delay with an external recovery address. UI built directly in kastle-ui; data/signing wired in by dev after merge.
Screenshots / recordings
PR title triggers the Storybook preview build — reviewers get a live link. Every screen/component was screenshot-verified against its Figma node during the build (see commit history); happy to drop specific before/after shots here if useful.
Design tokens used
All styling via
src/config/theme.ts—colors,background,border,typography,spacing,borderRadius,borderWidth,textStyles,fontFamilies/fontSize/fontWeight,warning/info/successsemantic colors. No hardcoded hex/spacing in new work.Known follow-ups (not blocking)
StatusPilland theEstFeeSheet/InfoSheetsheet chrome have a few pre-existing literal numbers (9999,8,4,12,16,32) that exactly match existing spacing/radius tokens but weren't swapped in — flagged, zero visual risk, happy to clean up in a follow-up.Testing
npm run preview)npm run storybook:native)