Skip to content

Commit 65f2d34

Browse files
committed
Refactor components to functions
1 parent ceee0b2 commit 65f2d34

File tree

64 files changed

+3491
-3978
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+3491
-3978
lines changed

MIGRATION_REVIEW.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Migration Review: Functional Component Migration
2+
3+
## Status: Review Complete — 2 Fixes Required
4+
5+
Reviewed all 59 changed files from the functional component migration.
6+
7+
---
8+
9+
## 🔴 Issues Found — Must Fix
10+
11+
### Issue 1: Broken Tooltip in `TransactionValue.tsx`
12+
13+
**File:** `src/components/controlled/transactions-table/components/TransactionValue/TransactionValue.tsx`
14+
15+
**Problem:** Changed from `<mvx-tooltip>` (Stencil class with internal `@State() isVisible`) to `<Tooltip>` from `common/Tooltip/Tooltip`. The common `Tooltip` is a **controlled component** — it requires `isTooltipVisible` and `onVisibilityChange` props to function. Without them, `isTooltipVisible` defaults to `false` permanently and hovering does nothing. **Tooltip never shows.**
16+
17+
**Original:**
18+
```tsx
19+
<mvx-tooltip trigger={<Icon name="layers" class={styles.transactionValueIcon} />}>
20+
{value.titleText}
21+
</mvx-tooltip>
22+
```
23+
24+
**Current (broken):**
25+
```tsx
26+
<Tooltip trigger={<Icon name="layers" class={styles.transactionValueIcon} />}>{value.titleText}</Tooltip>
27+
```
28+
29+
**Fix:** `TransactionValue` is a functional component rendered by `transactions-table.tsx` (a class component). Add `@State() isValueTooltipVisible: boolean = false` to `TransactionTable`, pass `isTooltipVisible` + `onVisibilityChange` down through `TransactionValue` props.
30+
31+
**Alternatively:** Since `TransactionValue` renders inside a loop over many rows, each row needs its own tooltip state. A simpler approach: add `isTooltipVisible` and `onVisibilityChange` as optional props to `TransactionValue`, and manage state in the parent `transactions-table.tsx` using a map keyed by row index/hash.
32+
33+
---
34+
35+
### Issue 2: Broken Tooltip in `transaction-toast-content.tsx`
36+
37+
**File:** `src/components/functional/toasts-list/components/transaction-toast/components/transaction-toast-content/transaction-toast-content.tsx`
38+
39+
**Problem:** Same as above. Changed from `<mvx-tooltip>` to `<Tooltip>` from common without providing visibility state.
40+
41+
**Original:**
42+
```tsx
43+
<mvx-tooltip position="bottom" trigger={<mvx-circle-info-icon />}>
44+
{amount.label}
45+
</mvx-tooltip>
46+
```
47+
48+
**Current (broken):**
49+
```tsx
50+
<Tooltip position="bottom" trigger={<CircleInfoIcon />}>
51+
{amount.label}
52+
</Tooltip>
53+
```
54+
55+
**Fix:** `TransactionToastContent` already receives `toastId` and `onForceUpdate`. Add `isAmountTooltipVisible` + `onAmountTooltipVisibilityChange` props, pass them from `TransactionToast`, which gets them from `ToastList` (class component with `@State`).
56+
57+
**Simpler alternative:** Use the existing `MvxTooltip` wrapper from `src/components/visual/tooltip/tooltip.tsx` which has a module-level Map for state — but needs `tooltipKey={toastId + '-amount'}` to be stable AND needs `onTriggerRender={onForceUpdate}` to trigger re-renders.
58+
59+
---
60+
61+
## ✅ Everything Else — No Issues
62+
63+
| Area | Status | Notes |
64+
|------|--------|-------|
65+
| All 24 icon components | ✅ OK | Props, types, SVG preserved. Classes correctly propagated. |
66+
| `shard-icon` `shard` prop | ✅ OK | `number``number?` with same default `0` |
67+
| `getProviderButtonIcon.tsx` | ✅ OK | Direct icon function imports replace custom elements |
68+
| `TransactionAssetIcon.tsx` | ✅ OK | Icon functions replace custom elements |
69+
| `TransactionShards.tsx` | ✅ OK | `ArrowRightIcon` function replaces `mvx-arrow-right-icon` |
70+
| `ledger-confirm.tsx` | ✅ OK | `<Host>``<div>`, same render logic |
71+
| `ledger-intro.tsx` | ✅ OK | Delegates to `common/LedgerIntro/LedgerIntro` (same UI) |
72+
| `LedgerIntro` (common) | ✅ OK | `mvx-ledger-icon``LedgerIcon` function |
73+
| `ledger-connect.tsx` | ✅ OK | Imports updated correctly |
74+
| `ProviderIdleScreen.tsx` | ✅ OK | `onConnect` prop passed correctly |
75+
| `wallet-connect-scan.tsx` | ✅ OK | `@Event() downloadClick``onDownloadClick` prop |
76+
| `wallet-connect-download.tsx` | ✅ OK | Icons replaced correctly |
77+
| `wallet-connect.tsx` | ✅ OK | `onDownloadClick` event binding correct |
78+
| `transaction-toast-details.tsx` | ✅ OK | Expand/collapse via module-level Map + `onForceUpdate` is logically equivalent |
79+
| `transaction-toast.tsx` | ✅ OK | `@Event() deleteToast``onDeleteToast` prop |
80+
| `transaction-toast-content.tsx` | ✅ OK (except tooltip — see Issue 2) | |
81+
| `transaction-toast-details-body.tsx` | ✅ OK | CopyButton/ExplorerLink from common |
82+
| `simple-toast.tsx` | ✅ OK | |
83+
| `generic-toast.tsx` | ✅ OK | |
84+
| `custom-toast.tsx` | ✅ OK | `ref={initializeToast}` closure behavior equivalent |
85+
| `toast-list.tsx` | ✅ OK | Uses `{...toast}` spread + `onForceUpdate` |
86+
| `notifications-feed.tsx` | ✅ OK | `onForceUpdate` added |
87+
| `tooltip.tsx` (MvxTooltip) | ✅ OK (unused) | No callers in codebase |
88+
| `preloader.tsx` | ✅ OK | `<slot />``children` |
89+
| `Pagination.tsx` | ✅ OK | Already functional |
90+
| `PaginationEllipsis.tsx` | ✅ OK | Already functional |
91+
| `PaginationEllipsisForm.tsx` | ✅ OK | `MagnifyingGlassIcon` replaces custom element |
92+
| `address-table.tsx` Tooltips | ✅ OK | `@State isButtonTooltipVisible` + `@State shardTooltipVisibility` added |
93+
| `data-with-explorer-link.tsx` Tooltips | ✅ OK | `@State isCopyTooltipVisible` + `@State isExplorerTooltipVisible` |
94+
| `unlock-panel/getProviderButtonIcon` | ✅ OK | |
95+
96+
### Minor Note (no action needed):
97+
- `address-table.tsx`: `part="address"` removed from `<Trim>`. Since `address-table` uses `shadow: false`, CSS Shadow Parts have no effect anyway — no functional impact.
98+
- Module-level Maps in `transaction-toast-details.tsx` are never cleaned up — minor memory leak, but not a regression from original behavior.
99+
100+
---
101+
102+
## Fix Instructions for Next Agent
103+
104+
Fix the two tooltip issues described above. The simplest approach for both:
105+
106+
**For `transaction-toast-content.tsx`:**
107+
Add `isAmountTooltipVisible` and `onAmountTooltipVisibilityChange` props. Then trace up the call chain:
108+
- `TransactionToast` → add same props, pass through
109+
- `toast-list.tsx` (`ToastList` class) → add `@State() amountTooltipVisibility: Record<string, boolean> = {}`, pass per-toast visibility keyed by `toastId`
110+
- `notifications-feed.tsx` → same pattern
111+
112+
**For `TransactionValue.tsx`:**
113+
Add `isTooltipVisible` and `onTooltipVisibilityChange` props. Then:
114+
- `transactions-table.tsx` → add `@State() valueTooltipStates: Record<number, boolean> = {}`, pass per-row state
115+
116+
After fixing, run `npm test` to verify all 130 tests still pass, then `npm run build` to verify bundle size.

docs/migration-plan.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# Migration Plan: Internal Web Components → Functional Components
2+
3+
## Context
4+
5+
Iulia has been refactoring internal Stencil web components into plain functional components to reduce the `dist/web-components` bundle size. This was confirmed by comparing builds: commit `96ccca55` (2.2MB) → `0db2a31a` (2.1MB).
6+
7+
Only components consumed externally by `mx-sdk-dapp`, `mx-wallet-dapp`, or `mx-template-dapp` should remain as exported web components. Everything else must become internal functions.
8+
9+
**Already done by Iulia (no action needed):**
10+
- `SignTransactionsHeader`, `SignTransactionsAdvanced`, `SignTransactionsFooter`, `SignTransactionsOverview`
11+
- `UnlockPanelFooter`, `UnlockPanelGroup`, `UnlockProviderButton`
12+
- `SidePanel`, `SidePanelHeader`, `SidePanelSwiper`
13+
- `TransactionListItem`
14+
15+
---
16+
17+
## Migration Pattern
18+
19+
**Before (Stencil @Component):**
20+
```tsx
21+
@Component({ tag: 'mvx-tooltip', styleUrl: 'tooltip.scss', shadow: true })
22+
export class Tooltip {
23+
@Prop() position: 'top' | 'bottom' = 'top';
24+
render() { return <TooltipComponent position={this.position} />; }
25+
}
26+
```
27+
28+
**After (functional):**
29+
```tsx
30+
import { h } from '@stencil/core';
31+
interface TooltipPropsType { position?: 'top' | 'bottom'; }
32+
export function Tooltip({ position = 'top' }: TooltipPropsType) {
33+
return <TooltipComponent position={position} />;
34+
}
35+
```
36+
37+
**Steps for each migration:**
38+
1. Remove `@Component` decorator and `tag`/`styleUrl`/`shadow` config
39+
2. Remove Stencil decorators: `@Prop`, `@State`, `@Event`, `@Method`, `@Element`
40+
3. Convert class + `render()` to a plain exported function with props interface
41+
4. Keep `.scss` file — must contain the Tailwind comment (see `src/components/visual/tooltip/tooltip.scss`)
42+
5. Update all parent component usages: replace `<mvx-xxx />` custom element tags with direct function imports `<Xxx />`
43+
6. Run build, verify `components.d.ts` auto-updates and size reduces
44+
45+
---
46+
47+
## Group 1: Icon Components (24 components) — highest ROI
48+
49+
All located in `src/assets/icons/`. Simple SVG wrappers, no state or events.
50+
51+
| Component tag | File |
52+
|---------------|------|
53+
| `mvx-arc-extension-provider-icon` | `src/assets/icons/arc-extension-provider-icon/` |
54+
| `mvx-arrow-right-icon` | `src/assets/icons/arrow-right-icon/` |
55+
| `mvx-brave-extension-provider-icon` | `src/assets/icons/brave-extension-provider-icon/` |
56+
| `mvx-circle-info-icon` | `src/assets/icons/circle-info-icon/` |
57+
| `mvx-default-transaction-icon-large` | `src/assets/icons/default-transaction-icon-large/` |
58+
| `mvx-default-transaction-icon-small` | `src/assets/icons/default-transaction-icon-small/` |
59+
| `mvx-edge-extension-provider-icon` | `src/assets/icons/edge-extension-provider-icon/` |
60+
| `mvx-extension-provider-icon` | `src/assets/icons/extension-provider-icon/` |
61+
| `mvx-firefox-extension-provider-icon` | `src/assets/icons/firefox-extension-provider-icon/` |
62+
| `mvx-ledger-icon` | `src/assets/icons/ledger-icon/` |
63+
| `mvx-ledger-provider-icon` | `src/assets/icons/ledger-provider-icon/` |
64+
| `mvx-magnifying-glass-icon` | `src/assets/icons/magnifying-glass-icon/` |
65+
| `mvx-metamask-provider-icon` | `src/assets/icons/metamask-provider-icon/` |
66+
| `mvx-multiversx-logo-icon` | `src/assets/icons/multiversx-logo-icon/` |
67+
| `mvx-multiversx-symbol-icon` | `src/assets/icons/multiversx-symbol-icon/` |
68+
| `mvx-passkey-provider-icon` | `src/assets/icons/passkey-provider-icon/` |
69+
| `mvx-shard-icon` | `src/assets/icons/shard-icon/` |
70+
| `mvx-spinner-icon` | `src/assets/icons/spinner-icon/` |
71+
| `mvx-wallet-connect-app-gallery-icon` | `src/assets/icons/wallet-connect-app-gallery-icon/` |
72+
| `mvx-wallet-connect-app-store-icon` | `src/assets/icons/wallet-connect-app-store-icon/` |
73+
| `mvx-wallet-connect-google-play-icon` | `src/assets/icons/wallet-connect-google-play-icon/` |
74+
| `mvx-wallet-provider-icon` | `src/assets/icons/wallet-provider-icon/` |
75+
| `mvx-xportal-download-qr-icon` | `src/assets/icons/xportal-download-qr-icon/` |
76+
| `mvx-xportal-qr-code-preloader` | `src/assets/icons/xportal-qr-code-preloader/` |
77+
78+
**Steps per icon:**
79+
1. Open `<icon-name>.tsx`, remove `@Component`, convert class → function
80+
2. Keep `.scss` file with Tailwind comment
81+
3. Grep all parent usages of `<mvx-<icon-name>` → update to direct import
82+
83+
---
84+
85+
## Group 2: Toast Sub-components (8 components)
86+
87+
All internal to `mvx-toast-list` (which is kept). None consumed externally.
88+
89+
**Work inside-out (deepest nested first):**
90+
91+
| # | Component tag | File |
92+
|---|---------------|------|
93+
| 1 | `mvx-transaction-toast-details-body` | `src/components/functional/toasts-list/components/transaction-toast/components/transaction-toast-details/components/transaction-toast-details-body.tsx` |
94+
| 2 | `mvx-transaction-toast-progress` | `.../transaction-toast/components/transaction-toast-progress/transaction-toast-progress.tsx` |
95+
| 3 | `mvx-transaction-toast-content` | `.../transaction-toast/components/transaction-toast-content/transaction-toast-content.tsx` |
96+
| 4 | `mvx-transaction-toast-details` | `.../transaction-toast/components/transaction-toast-details/transaction-toast-details.tsx` |
97+
| 5 | `mvx-transaction-toast` | `.../toasts-list/components/transaction-toast/transaction-toast.tsx` |
98+
| 6 | `mvx-simple-toast` | `.../custom-toast/components/simple-toast/simple-toast.tsx` |
99+
| 7 | `mvx-generic-toast` | `.../custom-toast/generic-toast.tsx` |
100+
| 8 | `mvx-custom-toast` | `.../custom-toast/components/custom-create-toast/custom-toast.tsx` |
101+
102+
**Steps:**
103+
1. Convert `mvx-transaction-toast-details-body` → update usage in `transaction-toast-details.tsx`
104+
2. Convert `mvx-transaction-toast-progress` → update usage in `transaction-toast-content.tsx`
105+
3. Convert `mvx-transaction-toast-content` → update usage in `transaction-toast.tsx`
106+
4. Convert `mvx-transaction-toast-details` → update usage in `transaction-toast.tsx`
107+
5. Convert `mvx-transaction-toast` → update usage in `toast-list.tsx`
108+
6. Convert `mvx-simple-toast` → update usage in `generic-toast.tsx`
109+
7. Convert `mvx-generic-toast` → update usage in `custom-toast.tsx`
110+
8. Convert `mvx-custom-toast` → update usage in `toast-list.tsx`
111+
112+
---
113+
114+
## Group 3: Wallet Connect Sub-components (2 components)
115+
116+
Internal to `mvx-wallet-connect` (which is kept).
117+
118+
| Component tag | File |
119+
|---------------|------|
120+
| `mvx-wallet-connect-download` | `src/components/functional/wallet-connect/components/wallet-connect-download/wallet-connect-download.tsx` |
121+
| `mvx-wallet-connect-scan` | `src/components/functional/wallet-connect/components/wallet-connect-scan/wallet-connect-scan.tsx` |
122+
123+
**Steps:**
124+
1. Convert `mvx-wallet-connect-download` → update usage in `wallet-connect.tsx`
125+
2. Convert `mvx-wallet-connect-scan` → update usage in `wallet-connect.tsx`
126+
127+
---
128+
129+
## Group 4: Ledger Sub-components (2 components)
130+
131+
Internal to `mvx-ledger-connect` (which is kept).
132+
133+
| Component tag | File |
134+
|---------------|------|
135+
| `mvx-ledger-confirm` | `src/components/functional/ledger-connect/components/ledger-confirm/ledger-confirm.tsx` |
136+
| `mvx-ledger-intro` | `src/components/functional/ledger-connect/components/ledger-intro/ledger-intro.tsx` |
137+
138+
**Steps:**
139+
1. Convert `mvx-ledger-confirm` → update usage in `ledger-connect.tsx`
140+
2. Convert `mvx-ledger-intro` → update usage in `ledger-connect.tsx`
141+
142+
---
143+
144+
## Group 5: Visual Utilities (5 components)
145+
146+
| # | Component tag | File |
147+
|---|---------------|------|
148+
| 1 | `mvx-pagination-ellipsis-form` | `src/components/visual/address-table/components/pagination/` |
149+
| 2 | `mvx-pagination-ellipsis` | `src/components/visual/address-table/components/pagination/` |
150+
| 3 | `mvx-pagination` | `src/components/visual/address-table/components/pagination/pagination.tsx` |
151+
| 4 | `mvx-tooltip` | `src/components/visual/tooltip/tooltip.tsx` |
152+
| 5 | `mvx-preloader` | `src/components/visual/preloader/preloader.tsx` |
153+
154+
**Steps (inside-out):**
155+
1. Convert `mvx-pagination-ellipsis-form` → update usage in pagination
156+
2. Convert `mvx-pagination-ellipsis` → update usage in pagination
157+
3. Convert `mvx-pagination` → update usage in `address-table.tsx`
158+
4. Convert `mvx-tooltip` → grep all usages across the codebase, update each
159+
5. Convert `mvx-preloader` → grep all usages across the codebase, update each
160+
161+
---
162+
163+
## Files Affected Per Migration
164+
165+
For each component:
166+
- `<component>.tsx` — main change (remove `@Component`, convert to function)
167+
- `<component>.scss` — keep as-is with Tailwind comment
168+
- Parent `.tsx` files — replace custom element tags with direct function imports
169+
- `src/components.d.ts` — auto-regenerated on build (no manual edit needed)
170+
171+
---
172+
173+
## Verification
174+
175+
After each group:
176+
```bash
177+
npm run build
178+
du -sh dist/web-components/
179+
```
180+
181+
Baseline (at `0db2a31a`): `dist/web-components` = **2.1MB**
182+
183+
Expected: progressive reduction with each group. Largest drop expected from Group 1 (icons).

0 commit comments

Comments
 (0)