Skip to content

feat(frontend): replace the hand-rolled widgets with Ark UI and lucide-react - #147

Merged
gabitoesmiapodo merged 5 commits into
mainfrom
feat/138-ark-ui
Sep 4, 2026
Merged

feat(frontend): replace the hand-rolled widgets with Ark UI and lucide-react#147
gabitoesmiapodo merged 5 commits into
mainfrom
feat/138-ark-ui

Conversation

@gabitoesmiapodo

@gabitoesmiapodo gabitoesmiapodo commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

Closes #138

The demo app hand-rolled its dropdowns, tooltip, dialog, toasts, segmented controls and progress bar, so anyone studying it to learn Canton had to reverse-engineer our inventions. Every interactive control now comes from Ark UI, which wraps the same Zag machines the kit already resolves, so no second copy lands in the lock file.

Changes

  • Menus, dialog, tooltip, select, toasts, wizard steps, number input and toggle groups come from Ark UI
  • Generic icons come from lucide-react; only the brand and house marks stay hand-rolled
  • The dashboard filters and the create form's curve switch share one component
  • The create wizard shows a three-step header instead of a count in its title
  • Each control reports its own state through the library's roles, so a screen reader gets the vested share, the checked pill and the current step
  • Three modules are gone: the dismiss hook, the top-layer store, and the toast store with its timer map

Deviations

  • Milestone percentages are checked for NaN, which the old regex strip made impossible and the number input allows mid-edit
  • The four social marks are renamed *Mark, so what stays hand-rolled is visible and XIcon no longer collides with lucide's own
  • components/Spinner keeps the spin animation that left with SpinnerIcon
  • utils/popover.ts holds the panel surface the three dropdowns share
  • CopyButton runs a caller's click handler instead of dropping it, so the copy control can be a menu item
  • The toast region is portalled to the page body, because an open dialog hides everything else from a screen reader

Acceptance criteria

  • AccountMenu and RoleSelect use Ark Menu, and hooks/useDismissable.ts is deleted
  • Toasts use Ark Toast, and the store and timer map in utils/toast.ts are deleted
  • Modal uses Ark Dialog, and utils/topLayer.ts is deleted
  • InfoTip uses Ark Tooltip and opens on touch
  • Dashboard's filter pills and the create-grant curve toggle share one Ark component
  • The create-grant wizard uses Ark Steps instead of a step counter
  • ScheduleBar uses Ark Progress and reports its value to a screen reader
  • The milestone percent field uses Ark NumberInput instead of stripping characters by regex
  • Select uses Ark Select
  • Generic icons come from lucide-react, and only the brand and house marks stay hand-rolled

Test plan

Automated tests

  1. Run pnpm install
  2. Run pnpm -C dapp/frontend test
  3. Expect 158 passing tests
  4. Run pnpm lint, pnpm typecheck, pnpm build, pnpm knip, pnpm docs:check and pnpm run check:anatomy
  5. Expect every one to pass

Manual verification

  1. Bring the local stack up as the root README describes, then run pnpm run app:dev
  2. Connect a wallet and open the account menu; expect the arrow keys to move between the copy row and disconnect
  3. Press Create, fill in the first step, then continue; expect a step header to go back but refuse to jump forward from an incomplete step
  4. On the schedule step choose Milestone and type a letter into a percent field; expect it to be refused
  5. Close the wallet and submit; expect the failure toast to sit above the dialog, stay until dismissed, and its copy button to leave the dialog open
  6. Hover an amount's coin mark for the tooltip, then tap the same mark on a phone

Breaking changes

None.

Checklist

  • Self-reviewed my own diff
  • Tests added or updated
  • Docs updated (if applicable)
  • No unrelated changes bundled in

Screenshots

image image image image image image image image image

`validVestingSchedule` checks each milestone fraction against the one before it,
and a NaN loses every comparison. So a NaN fraction was read as valid, and it
then became `prevFraction`, which let every milestone after it pass too. A
schedule that still ended at 100% was accepted with a meaningless fraction
inside it.

The same loop already guarded milestone dates this way. The fractions now get
the same check.
…e-react

Every interactive control in the dApp now comes from Ark UI, which wraps the
same Zag state machines `canton-dappbooster` already resolves, so the lock file
holds one copy of each. A reader studying the app can look any control up in
public docs instead of reverse-engineering ours.

- menus, the dialog, the tooltip, the select, toasts, the wizard's steps, the
  number input and the toggle groups are all Ark's
- `hooks/useDismissable.ts`, `utils/topLayer.ts`, and the toast store with its
  timer map are deleted
- the dashboard filters and the create form's curve switch share the new
  `components/Pills`
- generic icons come from `lucide-react`; `src/icons/` keeps only the brand and
  house marks, each renamed `*Mark`
- `utils/popover.ts` holds the panel surface the three dropdowns share, and
  `components/Spinner` owns the spin animation

Two behaviours worth naming. The toast region is portalled to `<body>`, which is
what keeps it announced and clickable over an open dialog. The create form
mounts a step's panel when the step is reached rather than when the dialog
opens, because Ark hides a panel it is not on rather than unmounting it.
@gabitoesmiapodo gabitoesmiapodo self-assigned this Sep 3, 2026
@vercel

vercel Bot commented Sep 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
docs.canton-dappbooster Ready Ready Preview Sep 4, 2026 2:20pm UTC
1 Skipped Deployment
Project Deployment Actions Updated
demo.canton-dappbooster Skipped Skipped Sep 4, 2026 2:20pm UTC

Request Review

…l position

Follow-up to the Ark UI move, all in the vesting dApp.

- The create dialog closed the moment it opened. Ark dismisses a layer when
  focus lands outside it, and mounting is what opens ours, so no
  Dialog.Trigger is registered for Ark to skip. The focus trap handing focus
  back to the button that opened the dialog then read as an interaction
  outside. Modal refuses that dismissal now; a press outside and Escape still
  close it.
- Locking or disconnecting the wallet drops `?create=1`, so the dialog closes
  and does not reopen on the next connect. The connect prompt inside the
  dialog goes with it, along with the line about the receiver accepting.
- The eye button had no hover state: `enabled:` only ever matches form
  controls, and that button renders a link. Every variant uses
  `not-disabled:` now. Icon buttons are 32px and sit closer together.
- Opening a grant starts at the top of the page, through ScrollRestoration
  keyed on the pathname so the role and create params do not reset it.
- Tooltips grew a tip and a 4px radius. Card titles are only as wide as their
  text and cut with an ellipsis. The wizard's steps are three bars that fill
  as you advance.
- Only error toasts stay on screen, and copying a party id raises none.
@gabitoesmiapodo

Copy link
Copy Markdown
Collaborator Author

@fernandomg

I checked out things manually and everything seems to be working as it did before.

This is mostly mechanical replacements of hand-rolled components by Ark UI's. I'd say just check manually (the preview should work just fine AFAIK), skim or skip code, a deeper review is not worth our time.

@gabitoesmiapodo
gabitoesmiapodo marked this pull request as ready for review September 4, 2026 13:59
Base automatically changed from feat/134-faucet to main September 4, 2026 14:19
@gabitoesmiapodo
gabitoesmiapodo merged commit 69b1e6b into main Sep 4, 2026
9 checks passed
@gabitoesmiapodo
gabitoesmiapodo deleted the feat/138-ark-ui branch September 4, 2026 15:09
@github-project-automation github-project-automation Bot moved this from In review to Done in Canton - dAppBooster (#390) Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Replace the demo app's hand-rolled widgets with Ark UI and lucide-react

2 participants