You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GoodDollar/GoodWalletV2
Context: We already have mapped, based on GoodWalletV2, the high-level design system and css into our local preset (local path: packages/ui/src/presets.ts) it also includes already claim-flow localized design definitions from GoodWalletV2. (local path: packages/claim-widget/src/ClaimWidget) and component like Drawer (local path: pacakges/ui/src/components/Drawer.tsx)
Use these as starting reference before starting to analyse and map GoodWalletV2's remaining components.
Goal: Map existing UI components from GoodWalletV2 to GoodWidget primitives using Tamagui.
Steps:
Explore GoodWalletV2 repository and identify reusable UI components
For each component:
name
purpose
usage patterns
design system: verify both what it uses from high-level design system (GoodWalletV2 path: src/ui/styles.css) and what is in GoodWalletV2 defined in a given .module.css (usually sibling file in same directory of a component).
Map each to:
Tamagui primitive (if exists)
or GoodWidget composition
Use Drawer.tsx as reference for correct pattern
Output:
structured mapping
recommended first-wave primitives
create new GitHub issue for GoodWidget
=== End of original prompt, below is the Agents contribution
Overview
This issue tracks iterative application of GoodWalletV2 design elements onto GoodWidget's existing demo primitives in packages/ui/src/components-test/ and packages/ui/src/components/.
We are not migrating all primitives at once. Instead, we start from GoodWalletV2 in-use components and add UI primitives on a per-need basis, iteratively.
Relationship to issue #3:
Issue #3 covers the first-wave migration of components-test primitives from Stack-based scaffolds to correct Tamagui-native equivalents. That migration is a pre-condition for several items below. Where a component needs issue #3 migration before GoodWalletV2 design can be cleanly applied, this is called out explicitly.
About components-test:
Files in packages/ui/src/components-test/ are scaffolded demos. They are not yet correctly mapped to the GoodWidget preset or using proper Tamagui primitives in all cases. Changes here require:
Then applying GoodWalletV2 design values through the preset
Design System Reference
GoodWalletV2's styles.css defines two brand themes (theme-blue, theme-green) switching --token-primary between blue (#1a85ff) and green (#13c636). All semantic layers are already captured in the GoodWidget preset:
GoodWalletV2 source:src/ui/icon/Icon.tsx Local file:none — needs to be created in packages/ui/src/components/ Tamagui base: no direct Tamagui Icon primitive; wrap SVG/icon-library elements using styled(Stack) or a named createComponent
What's needed:
Decide on icon library (react-icons as in V2, Lucide, or custom SVG set)
Create a named Icon component via createComponent with name: 'Icon'
Props: name, size (2xs→2xl), color (primary/text/muted/error/success/inherit), spin, round
Map sizes to existing tokens.size.icon* tokens (icon2xs=12 … icon2xl=64)
Blocks: Button icon/list variants, Dialog close button, Toast status icons
2. Button — ⚠️ extend components-test/Button.tsx
GoodWalletV2 source:src/ui/button/Button.tsx + Button.module.css Local file:packages/ui/src/components-test/Button.tsx Current base:ButtonFrame = createComponent(Stack, { name: 'Button', ... }) — uses Stack, not Tamagui Button
Pre-condition (issue #3): Migrate ButtonFrame from Stack to Tamagui Button as its behavioral base before extending variants.
What's needed after migration:
Radius: V2 solid buttons use pill radius (9999px). Current default is $2 (8px). Update default to $full or $6 for brand alignment.
text-soft (#ccc) — between $color (white) and $placeholderColor (grey500); consider adding colorSoft semantic key to light/dark themes in presets.ts
text-tertiary (#4d4d4d) — exists as $grey600 token but not as a theme semantic key; consider adding colorDim
5. Dialog — ❌ new component (no existing demo)
GoodWalletV2 source:src/ui/dialog/Dialog.tsx + dialogStore.ts Local file:none — needs to be created in packages/ui/src/components/ Tamagui base: Tamagui Dialog primitive
Original prompt:
Use GitHub MCP to inspect the repository:
GoodDollar/GoodWalletV2
Context: We already have mapped, based on GoodWalletV2, the high-level design system and css into our local preset (local path: packages/ui/src/presets.ts) it also includes already claim-flow localized design definitions from GoodWalletV2. (local path: packages/claim-widget/src/ClaimWidget) and component like Drawer (local path: pacakges/ui/src/components/Drawer.tsx)
Use these as starting reference before starting to analyse and map GoodWalletV2's remaining components.
Goal: Map existing UI components from GoodWalletV2 to GoodWidget primitives using Tamagui.
Steps:
Explore GoodWalletV2 repository and identify reusable UI components
For each component:
name
purpose
usage patterns
design system: verify both what it uses from high-level design system (GoodWalletV2 path: src/ui/styles.css) and what is in GoodWalletV2 defined in a given .module.css (usually sibling file in same directory of a component).
Map each to:
Tamagui primitive (if exists)
or GoodWidget composition
Use Drawer.tsx as reference for correct pattern
Output:
structured mapping
recommended first-wave primitives
create new GitHub issue for GoodWidget
=== End of original prompt, below is the Agents contribution
Overview
This issue tracks iterative application of GoodWalletV2 design elements onto GoodWidget's existing demo primitives in
packages/ui/src/components-test/andpackages/ui/src/components/.We are not migrating all primitives at once. Instead, we start from GoodWalletV2 in-use components and add UI primitives on a per-need basis, iteratively.
Design System Reference
GoodWalletV2's
styles.cssdefines two brand themes (theme-blue,theme-green) switching--token-primarybetween blue (#1a85ff) and green (#13c636). All semantic layers are already captured in the GoodWidget preset:--token-bgtokens.color.background/theme.background--token-bg-raisedtokens.color.surface/theme.backgroundHover--token-bg-inputtokens.color.backgroundInput/theme.backgroundPress--token-bg-overlaytokens.color.backgroundOverlay/theme.backgroundOverlay--token-primarytokens.color.primary/light_Button.background--token-texttokens.color.text/theme.color--token-text-mutedtokens.color.textSecondary/theme.placeholderColor--token-bordertokens.color.border/theme.borderColor--z-drawer(200)tokens.zIndex.4Components
1.
Icon— ❌ new component (no existing demo)GoodWalletV2 source:
src/ui/icon/Icon.tsxLocal file: none — needs to be created in
packages/ui/src/components/Tamagui base: no direct Tamagui
Iconprimitive; wrap SVG/icon-library elements usingstyled(Stack)or a namedcreateComponentWhat's needed:
Iconcomponent viacreateComponentwithname: 'Icon'name,size(2xs→2xl),color(primary/text/muted/error/success/inherit),spin,roundtokens.size.icon*tokens (icon2xs=12…icon2xl=64)Blocks: Button icon/list variants, Dialog close button, Toast status icons
2.⚠️ extend
Button—components-test/Button.tsxGoodWalletV2 source:
src/ui/button/Button.tsx+Button.module.cssLocal file:
packages/ui/src/components-test/Button.tsxCurrent base:
ButtonFrame = createComponent(Stack, { name: 'Button', ... })— usesStack, not TamaguiButtonPre-condition (issue #3): Migrate
ButtonFramefromStackto TamaguiButtonas its behavioral base before extending variants.What's needed after migration:
9999px). Current default is$2(8px). Update default to$fullor$6for brand alignment.pillheight: 35,borderRadius: $full, uppercase 11px, muted bg + colored texticontextghost)list--blacktext on--mainbg for green theme. Currentlight_Buttonhardcodes white. Note this theme-level distinction.Spinner. Document this difference.3.⚠️ extend
Separator—components-test/Separator.tsGoodWalletV2 source:
src/ui/divider/Divider.tsx+Divider.module.cssLocal file:
packages/ui/src/components-test/Separator.tsCurrent base:
createComponent(YStack, { name: 'Separator', height: 1, ... })— usesYStackPre-condition (issue #3): Evaluate replacing
YStackbase with Tamagui's ownSeparatorprimitive for semantic correctness.What's needed after base decision:
sizevariant:sm= 1px,md= 2px,lg= 4px (currently only 1px)colorvariant:default($borderColor),muted($borderColor+ opacity),primary($primary)4.⚠️ extend
Text—components-test/Text.tsGoodWalletV2 source:
src/ui/typography/Typography.tsxLocal file:
packages/ui/src/components-test/Text.tsCurrent base:
createComponent(TamaguiText, { name: 'GWText', ... })— already wraps TamaguiTextcorrectly; no issue #3 pre-conditionWhat's needed:
truncateprop — single-line ellipsis (numberOfLines={1},overflow: hidden,textOverflow: ellipsis)noWrapprop —whiteSpace: 'nowrap'text-soft(#ccc) — between$color(white) and$placeholderColor(grey500); consider addingcolorSoftsemantic key tolight/darkthemes inpresets.tstext-tertiary(#4d4d4d) — exists as$grey600token but not as a theme semantic key; consider addingcolorDim5.
Dialog— ❌ new component (no existing demo)GoodWalletV2 source:
src/ui/dialog/Dialog.tsx+dialogStore.tsLocal file: none — needs to be created in
packages/ui/src/components/Tamagui base: Tamagui
DialogprimitiveWhat's needed:
Dialogas the behavioral baseDialogOverlay(name: 'DialogOverlay'),DialogFrame(name: 'Dialog', extendsCard)light_Dialog/dark_Dialogcomponent theme entries inpresets.ts$backgroundOverlayoverlay,$backgroundHovercontainer bg,borderRadius="$4"(16px),width={345},padding="$8"(32px)createDialog,updateStatus,useDialog6.⚠️ extend
Toast—components-test/Toast.tsxGoodWalletV2 source:
src/ui/notifications/Notifications.tsx+notificationStore.tsLocal file:
packages/ui/src/components-test/Toast.tsxCurrent base:
ToastFrame = createComponent(Stack, { name: 'Toast', ... })— usesStack, not TamaguiToastPre-condition (issue #3 second wave): Migrate
ToastFramefromStackto TamaguiToastas its behavioral base before extending.What's needed after migration:
ToastContainer— fixed-position wrapper at widget boundary bottom (max-width 768px, z-1000)toastStore— queue withcreateToast,updateToast,removeToast,useToaststatusvariant onToastFrame:pending(spinner icon),success(check icon),error(exclamation icon) — depends onIconcomponent (Add iframe/webview bridge package and runnable Expo demo #1 above)background: $primary, 0→100% in 3s) for auto-close toastsPublic API:
Toast,ToastContainer,createToast,updateToast,removeToast,useToastImplementation Order (recommended)
Icon— unblocked; needed by Button list/icon variants, Dialog close button, Toast status iconsButtonadditional variants — after issue [BOUNTY] Migrate First-Wave UI Primitives To Tamagui-Native Wrappers #3 Button migration + IconSeparatorenhancements — after issue [BOUNTY] Migrate First-Wave UI Primitives To Tamagui-Native Wrappers #3 Separator base decision; quick and self-containedTextenhancements —truncate,noWrap, optionalcolorSoft/colorDimtheme keys; no issue [BOUNTY] Migrate First-Wave UI Primitives To Tamagui-Native Wrappers #3 pre-conditionDialog— new named primitive + store + theme entries; after Icon. should be based on tamagui's Dialog.Toast/ notification system — after issue [BOUNTY] Migrate First-Wave UI Primitives To Tamagui-Native Wrappers #3 Toast migration + IconAll finalized components should be moved over to, or newly created in
componentsfolderRelated files
packages/ui/src/presets.tspackages/ui/src/components/Card.ts,packages/ui/src/components/Drawer.tsxpackages/ui/src/components-test/packages/claim-widget/src/ClaimWidget.tsxpackages/ui/src/createComponent.tssrc/ui/in GoodDollar/GoodWalletV2