# Legacy Component → ListItem Migration Guide

## Import Management

1. Remove imports: `{ ActionOption, NavigationOption, NavigationOptionList, Summary, SwitchOption, CheckboxOption, RadioOption }` from `'@transferwise/components'`
2. Add import: `{ ListItem }` from `'@transferwise/components'`
3. For `ul`/`ol` wrappers or `NavigationOptionList`: Add `{ List }` from `'@transferwise/components'`
4. For Summary with info: Add `{ Modal }` and/or `{ Popover }` from `'@transferwise/components'`
5. For Summary with info: Add `{ QuestionMarkCircle }` from `'@transferwise/icons'`
6. For Summary with info modal: Add `{ useState }` from `'react'`

## Universal Rules

1. `title` → `title` (direct)
2. `content` or `description` → `subtitle`
3. `disabled` stays on `ListItem` (not controls)
4. `id` stays on `ListItem` (not controls)
5. Remove deprecated props: `as`, `complex`, `showMediaAtAllSizes`, `showMediaCircle`, `isContainerAligned` from deprecated components
6. Preserve string quotes exactly as they are (don't convert ``to`'`or`"`)
7. `ListItem` renders as a `li` element by default, it doesn't need wrapping
8. Convert `<ul>` or `<ol>` wrappers containing legacy components to `<List>` (import from `'@transferwise/components'`)

---

## List Wrapper Conversion

- Convert `<ul>` or `<ol>` wrappers to `<List>`
- `<List>` defaults to `ul`, but can be `ol` or `div` via the `as` property
- Use `<List as="ol">` when converting `<ol>` tags to preserve semantic HTML

```tsx
<ul><ActionOption /></ul> → <List><ListItem /></List>
<ol><ActionOption /></ol> → <List as="ol"><ListItem /></List>
```

---

## ActionOption → ListItem.Button

- `action` → Button children
- `onClick` → Button `onClick`
- Priority mapping:
  - default or `"primary"` → `"primary"`
  - `"secondary"` → `"secondary-neutral"`
  - `"secondary-send"` → `"secondary"`
  - `"tertiary"` → `"tertiary"`

```tsx
<ActionOption title="Title" content="Text" action="Click" priority="secondary" onClick={fn} />
→
<ListItem title="Title" subtitle="Text" control={<ListItem.Button priority="secondary-neutral" onClick={fn}>Click</ListItem.Button>} />
```

---

## CheckboxOption → ListItem.Checkbox

- `id` stays on ListItem
- `name` is removed (not transferred)
- `onChange`: `(checked: boolean) => void` → `(event: ChangeEvent<HTMLInputElement>) => void`
  - Update handler: `(checked) => setX(checked)` → `(event) => setX(event.target.checked)`

```tsx
<CheckboxOption id="x" name="y" title="Title" content="Text" checked={v} onChange={(c) => set(c)} />
→
<ListItem id="x" title="Title" subtitle="Text" control={<ListItem.Checkbox checked={v} onChange={(e) => set(e.target.checked)} />} />
```

---

## RadioOption → ListItem.Radio

- `id` stays on ListItem
- `name`, `value`, `checked`, `onChange` move to Radio

```tsx
<RadioOption id="x" name="y" value="v" title="Title" content="Text" checked={v==='v'} onChange={set} />
→
<ListItem id="x" title="Title" subtitle="Text" control={<ListItem.Radio name="y" value="v" checked={v==='v'} onChange={set} />} />
```

---

## SwitchOption → ListItem.Switch

- `id` stays on ListItem
- `aria-label` is moved to `ListItem.Switch`
- `onChange` → `onClick` with manual toggle: `onChange={set}` → `onClick={() => set(!v)}`

```tsx
<SwitchOption id="x" title="Title" content="Text" checked={v} aria-label="Toggle" onChange={set} />
→
<ListItem id="x" title="Title" subtitle="Text" control={<ListItem.Switch checked={v} aria-label="Toggle" onClick={() => set(!v)} />} />
```

---

## NavigationOption → ListItem.Navigation

- `onClick` or `href` move to Navigation

```tsx
<NavigationOption title="Title" content="Text" onClick={fn} />
→
<ListItem title="Title" subtitle="Text" control={<ListItem.Navigation onClick={fn} />} />
```

---

## NavigationOptionList → List

- Convert `NavigationOptionList` wrapper to `<List></List>`
- Convert each child `NavigationOption` to `ListItem` with `ListItem.Navigation`

```tsx
<NavigationOptionList>
  <NavigationOption title="T1" content="C1" onClick={fn1} />
  <NavigationOption title="T2" content="C2" href="/link" />
</NavigationOptionList>
→
<List>
  <ListItem title="T1" subtitle="C1" control={<ListItem.Navigation onClick={fn1} />} />
  <ListItem title="T2" subtitle="C2" control={<ListItem.Navigation href="/link" />} />
</List>
```

---

## Option → ListItem

- Wrap `media` in `ListItem.AvatarView`

```tsx
<Option media={<Icon />} title="Title" />
→
<ListItem title="Title" media={<ListItem.AvatarView><Icon /></ListItem.AvatarView>} />
```

---

## Summary → ListItem

### Basic

- `icon` → wrap in `ListItem.AvatarView` with `size={32}` as `media`
- Remove `size` prop from child icon

### Status mapping

- `Status.DONE` → `badge={{ status: 'positive' }}` on AvatarView
- `Status.PENDING` → `badge={{ status: 'pending' }}` on AvatarView
- `Status.NOT_DONE` → no badge

### Action

- `action.text` → `action.label` in `ListItem.AdditionalInfo`
- Pass entire action object including `href`, `onClick`, `target`
- Remove `aria-label` from action (not supported)

### Info with Modal (add state management)

- Add: `const [open, setOpen] = useState(false)`
- Create `ListItem.IconButton` with `partiallyInteractive` and `onClick`
- Render `Modal` separately with state
- Transfer `aria-label` to IconButton

### Info with Popover

- `Popover` wraps `ListItem.IconButton` with `partiallyInteractive`
- Transfer `aria-label` to IconButton

```tsx
// Basic
<Summary title="T" description="D" icon={<Icon size={24} />} />
→
<ListItem title="T" subtitle="D" media={<ListItem.AvatarView size={32}><Icon /></ListItem.AvatarView>} />

// Status
<Summary title="T" description="D" icon={<Icon />} status={Status.DONE} />
→
<ListItem title="T" subtitle="D" media={<ListItem.AvatarView size={32} badge={{status:'positive'}}><Icon /></ListItem.AvatarView>} />

// Action
<Summary title="T" description="D" icon={<Icon />} action={{text:'Go', href:'/go', target:'_blank'}} />
→
<ListItem title="T" subtitle="D" media={<ListItem.AvatarView size={32}><Icon /></ListItem.AvatarView>} additionalInfo={<ListItem.AdditionalInfo action={{label:'Go', href:'/go', target:'_blank'}} />} />

// Modal (requires state: const [open, setOpen] = useState(false))
<Summary title="T" description="D" icon={<Icon />} info={{title:'Help', content:'Text', presentation:'MODAL', 'aria-label':'Info'}} />
→
<>
  <ListItem title="T" subtitle="D" media={<ListItem.AvatarView size={32}><Icon /></ListItem.AvatarView>} control={
    <ListItem.IconButton partiallyInteractive aria-label="Info" onClick={()=>setOpen(!open)}>
      <QuestionMarkCircle />
    </ListItem.IconButton>
  } />
  <Modal open={open} title="Help" body="Text" onClose={()=>setOpen(false)} />
</>

// Popover
<Summary title="T" description="D" icon={<Icon />} info={{title:'Help', content:'Text', presentation:'POPOVER', 'aria-label':'Info'}} />
→
<ListItem title="T" subtitle="D" media={<ListItem.AvatarView size={32}><Icon /></ListItem.AvatarView>} control={
  <Popover title="Help" content="Text" onClose={()=>setOpen(false)}>
    <ListItem.IconButton partiallyInteractive aria-label="Info">
      <QuestionMarkCircle />
    </ListItem.IconButton>
  </Popover>
} />
```
