@aircall/ds 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/dist/globals.css +1 -1
- package/dist/index.d.ts +28 -28
- package/dist/index.js +1 -1
- package/package.json +12 -2
- package/skills/aircall-ds/migrate-icons/SKILL.md +346 -0
- package/skills/aircall-ds/migrate-tractor/SKILL.md +314 -0
- package/skills/aircall-ds/migrate-tractor/accordion/SKILL.md +276 -0
- package/skills/aircall-ds/migrate-tractor/alert/SKILL.md +225 -0
- package/skills/aircall-ds/migrate-tractor/avatar/SKILL.md +272 -0
- package/skills/aircall-ds/migrate-tractor/badge/SKILL.md +274 -0
- package/skills/aircall-ds/migrate-tractor/button/SKILL.md +277 -0
- package/skills/aircall-ds/migrate-tractor/card/SKILL.md +278 -0
- package/skills/aircall-ds/migrate-tractor/combobox/SKILL.md +346 -0
- package/skills/aircall-ds/migrate-tractor/data-table/SKILL.md +333 -0
- package/skills/aircall-ds/migrate-tractor/dialog/SKILL.md +206 -0
- package/skills/aircall-ds/migrate-tractor/divider/SKILL.md +226 -0
- package/skills/aircall-ds/migrate-tractor/dropdown-menu/SKILL.md +266 -0
- package/skills/aircall-ds/migrate-tractor/dropzone/SKILL.md +338 -0
- package/skills/aircall-ds/migrate-tractor/form-and-field/SKILL.md +325 -0
- package/skills/aircall-ds/migrate-tractor/gauge/SKILL.md +248 -0
- package/skills/aircall-ds/migrate-tractor/input/SKILL.md +261 -0
- package/skills/aircall-ds/migrate-tractor/item/SKILL.md +298 -0
- package/skills/aircall-ds/migrate-tractor/link/SKILL.md +263 -0
- package/skills/aircall-ds/migrate-tractor/popover/SKILL.md +214 -0
- package/skills/aircall-ds/migrate-tractor/select/SKILL.md +245 -0
- package/skills/aircall-ds/migrate-tractor/sheet-vs-drawer/SKILL.md +272 -0
- package/skills/aircall-ds/migrate-tractor/skeleton/SKILL.md +190 -0
- package/skills/aircall-ds/migrate-tractor/styling/SKILL.md +421 -0
- package/skills/aircall-ds/migrate-tractor/tabs/SKILL.md +250 -0
- package/skills/aircall-ds/migrate-tractor/toast/SKILL.md +322 -0
- package/skills/aircall-ds/migrate-tractor/tooltip/SKILL.md +204 -0
- package/skills/aircall-ds/migrate-tractor/tree/SKILL.md +346 -0
- package/skills/aircall-ds/setup/SKILL.md +347 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: aircall-ds/migrate-tractor/alert
|
|
3
|
+
description: >
|
|
4
|
+
Migrate Tractor Banner (Banner, BannerHeading, BannerIcon, BannerParagraph) to
|
|
5
|
+
@aircall/ds Alert (rounded) vs Banner (inline). Load when a file imports Banner*
|
|
6
|
+
from @aircall/tractor.
|
|
7
|
+
type: sub-skill
|
|
8
|
+
library: aircall-ds
|
|
9
|
+
library_version: "0.13.0"
|
|
10
|
+
requires:
|
|
11
|
+
- aircall-ds/setup
|
|
12
|
+
- aircall-ds/migrate-tractor
|
|
13
|
+
sources:
|
|
14
|
+
- "aircall/hydra:docs/migration-guides/tractor-to-ds/recipes/alert-and-banner.md"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
This skill builds on aircall-ds/migrate-tractor. Apply all cross-cutting rules from that skill (prop renames, `render` prop, data attributes) before the alert-specific steps below.
|
|
18
|
+
|
|
19
|
+
## 1. Alert vs Banner — pick the right component
|
|
20
|
+
|
|
21
|
+
Tractor `Banner` maps to **two** DS components. Choose based on visual shape:
|
|
22
|
+
|
|
23
|
+
| If the Tractor `Banner` looks like… | Use DS component |
|
|
24
|
+
| --- | --- |
|
|
25
|
+
| Rounded card-style callout (`rounded-3xl`, full border) | `Alert` |
|
|
26
|
+
| Full-width inline strip with accent edge (square corners, border on one side) | `Banner` |
|
|
27
|
+
|
|
28
|
+
`Banner` re-exports the `Alert*` sub-parts under `Banner*` aliases — the children grammar is identical. Pick the container; the parts follow.
|
|
29
|
+
|
|
30
|
+
## 2. Sub-part mapping
|
|
31
|
+
|
|
32
|
+
| Tractor | DS (`Alert`) | DS (`Banner`) |
|
|
33
|
+
| --- | --- | --- |
|
|
34
|
+
| `BannerHeading` | `AlertTitle` | `BannerTitle` |
|
|
35
|
+
| `BannerIcon` | first `<svg>` child — **no wrapper** | same |
|
|
36
|
+
| `BannerSuffix` | `AlertAction` | `BannerAction` |
|
|
37
|
+
| `BannerParagraph` (body text) | `AlertDescription` | `BannerDescription` |
|
|
38
|
+
|
|
39
|
+
> **Icon is a direct child, not a part.** `Alert`/`Banner` detect a leading icon via `has-[>svg]` CSS. Render the icon as the **first child** — never wrap it. There is no `AlertIcon` or `BannerIcon` component in DS.
|
|
40
|
+
|
|
41
|
+
## 3. Verified DS exports (`packages/ds/src/index.ts`)
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
Alert, AlertAction, AlertDescription, AlertTitle,
|
|
45
|
+
Banner, BannerAction, BannerDescription, BannerTitle,
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
All eight names exist in the published public API. Do not use any other Alert/Banner parts.
|
|
49
|
+
|
|
50
|
+
## 4. Imports
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
import {
|
|
54
|
+
Alert, AlertTitle, AlertDescription, AlertAction,
|
|
55
|
+
Banner, BannerTitle, BannerDescription, BannerAction,
|
|
56
|
+
Button,
|
|
57
|
+
} from '@aircall/ds';
|
|
58
|
+
import { Info, AlertTriangle, X } from '@aircall/react-icons';
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## 5. Before / After
|
|
62
|
+
|
|
63
|
+
### Before (Tractor)
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import { Banner, BannerHeading, BannerIcon, BannerParagraph, BannerSuffix } from '@aircall/tractor';
|
|
67
|
+
|
|
68
|
+
// Rounded callout
|
|
69
|
+
<Banner variant="informative">
|
|
70
|
+
<BannerIcon><Info /></BannerIcon>
|
|
71
|
+
<BannerHeading>Heads up</BannerHeading>
|
|
72
|
+
<BannerParagraph>Your trial ends in 3 days.</BannerParagraph>
|
|
73
|
+
<BannerSuffix><button onClick={onDismiss}>✕</button></BannerSuffix>
|
|
74
|
+
</Banner>
|
|
75
|
+
|
|
76
|
+
// Full-width inline strip
|
|
77
|
+
<Banner variant="critical">
|
|
78
|
+
<BannerIcon><AlertTriangle /></BannerIcon>
|
|
79
|
+
<BannerHeading>Limited connectivity</BannerHeading>
|
|
80
|
+
<BannerParagraph>Some calls may not connect.</BannerParagraph>
|
|
81
|
+
<BannerSuffix><button onClick={onRetry}>Retry</button></BannerSuffix>
|
|
82
|
+
</Banner>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### After (DS)
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
import {
|
|
89
|
+
Alert, AlertTitle, AlertDescription, AlertAction,
|
|
90
|
+
Banner, BannerTitle, BannerDescription, BannerAction,
|
|
91
|
+
Button,
|
|
92
|
+
} from '@aircall/ds';
|
|
93
|
+
import { Info, AlertTriangle, X } from '@aircall/react-icons';
|
|
94
|
+
|
|
95
|
+
// Rounded callout → Alert
|
|
96
|
+
<Alert variant="info">
|
|
97
|
+
<Info /> {/* BannerIcon → first <svg> child, no wrapper */}
|
|
98
|
+
<AlertTitle>Heads up</AlertTitle>
|
|
99
|
+
<AlertDescription>Your trial ends in 3 days.</AlertDescription>
|
|
100
|
+
<AlertAction>
|
|
101
|
+
<Button variant="ghost" size="icon-sm" onClick={onDismiss}><X /></Button>
|
|
102
|
+
</AlertAction>
|
|
103
|
+
</Alert>
|
|
104
|
+
|
|
105
|
+
// Full-width inline strip → Banner
|
|
106
|
+
<Banner variant="error" borderDirection="top">
|
|
107
|
+
<AlertTriangle />
|
|
108
|
+
<BannerTitle>Limited connectivity</BannerTitle>
|
|
109
|
+
<BannerDescription>Some calls may not connect.</BannerDescription>
|
|
110
|
+
<BannerAction>
|
|
111
|
+
<Button variant="outline" size="sm" onClick={onRetry}>Retry</Button>
|
|
112
|
+
</BannerAction>
|
|
113
|
+
</Banner>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## 6. Variant mapping
|
|
117
|
+
|
|
118
|
+
| Tractor variant | DS variant |
|
|
119
|
+
| --- | --- |
|
|
120
|
+
| `informative` | `info` |
|
|
121
|
+
| `critical` | `error` |
|
|
122
|
+
| `warning` | `warning` |
|
|
123
|
+
| `positive` / `success` | `success` |
|
|
124
|
+
| (default / none) | `default` |
|
|
125
|
+
|
|
126
|
+
Both `Alert` and `Banner` share the same set: `default` / `info` / `success` / `warning` / `error`.
|
|
127
|
+
|
|
128
|
+
## 7. `Banner`-only prop: `borderDirection`
|
|
129
|
+
|
|
130
|
+
`Banner` accepts `borderDirection="top" | "bottom"` to place the accent border. `Alert` has no border-side prop — it is fully bordered and rounded.
|
|
131
|
+
|
|
132
|
+
## 8. Common Mistakes
|
|
133
|
+
|
|
134
|
+
### Mistake 1 — Wrapping the icon in a part component
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
// Wrong
|
|
138
|
+
<Alert variant="info">
|
|
139
|
+
<AlertIcon><Info /></AlertIcon> {/* AlertIcon does not exist in @aircall/ds */}
|
|
140
|
+
...
|
|
141
|
+
</Alert>
|
|
142
|
+
|
|
143
|
+
// Correct
|
|
144
|
+
<Alert variant="info">
|
|
145
|
+
<Info /> {/* bare <svg> first child activates the grid */}
|
|
146
|
+
...
|
|
147
|
+
</Alert>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`Alert`/`Banner` use `has-[>svg]` to detect the icon slot. Wrapping the SVG in any element breaks the CSS selector and the icon fails to render in the correct grid area.
|
|
151
|
+
Source: `packages/ds/src/components/alert.tsx`
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
### Mistake 2 — Using `destructive` instead of `error`
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
// Wrong
|
|
159
|
+
<Alert variant="destructive">...</Alert> {/* destructive is a Button variant, not Alert */}
|
|
160
|
+
|
|
161
|
+
// Correct
|
|
162
|
+
<Alert variant="error">...</Alert> {/* maps Tractor critical */}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`destructive` is a `Button` variant. `Alert`/`Banner` only accept `default | info | success | warning | error`. Passing an unknown variant silently falls through to `default` styling.
|
|
166
|
+
Source: `packages/ds/src/components/alert.tsx`
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
### Mistake 3 — Using `AlertAction`/`BannerAction` for the icon instead of the suffix
|
|
171
|
+
|
|
172
|
+
```tsx
|
|
173
|
+
// Wrong
|
|
174
|
+
<Alert variant="warning">
|
|
175
|
+
<AlertAction><AlertTriangle /></AlertAction> {/* icon in the trailing action slot */}
|
|
176
|
+
<AlertTitle>Watch out</AlertTitle>
|
|
177
|
+
</Alert>
|
|
178
|
+
|
|
179
|
+
// Correct
|
|
180
|
+
<Alert variant="warning">
|
|
181
|
+
<AlertTriangle /> {/* first <svg> child → leading icon slot */}
|
|
182
|
+
<AlertTitle>Watch out</AlertTitle>
|
|
183
|
+
</Alert>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
`AlertAction`/`BannerAction` is the **trailing** slot (self-positions right, vertically centered). It is for close buttons or CTAs, not the leading icon. Placing the icon there yields wrong layout.
|
|
187
|
+
Source: `packages/ds/src/components/alert.tsx`
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
### Mistake 4 — Setting icon color manually
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
// Wrong
|
|
195
|
+
<Alert variant="info">
|
|
196
|
+
<Info className="text-blue-500" /> {/* manual color overrides variant-driven color */}
|
|
197
|
+
...
|
|
198
|
+
</Alert>
|
|
199
|
+
|
|
200
|
+
// Correct
|
|
201
|
+
<Alert variant="info">
|
|
202
|
+
<Info /> {/* variant applies [&>svg]:text-info automatically */}
|
|
203
|
+
...
|
|
204
|
+
</Alert>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
`Alert`/`Banner` apply `[&>svg]:text-<variant>` on the root. Explicit color classes on the icon fight the cascade and cause inconsistency across themes.
|
|
208
|
+
Source: `packages/ds/src/components/alert.tsx`
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
### Mistake 5 — Using `borderDirection` on `Alert`
|
|
213
|
+
|
|
214
|
+
```tsx
|
|
215
|
+
// Wrong
|
|
216
|
+
<Alert variant="warning" borderDirection="top">...</Alert> {/* prop not supported on Alert */}
|
|
217
|
+
|
|
218
|
+
// Correct
|
|
219
|
+
<Banner variant="warning" borderDirection="top"> {/* Banner is the inline strip */}
|
|
220
|
+
...
|
|
221
|
+
</Banner>
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
`borderDirection` is a `Banner`-only prop (inline strip component). `Alert` is always fully bordered and rounded; it has no border-side prop. The prop is silently ignored on `Alert`.
|
|
225
|
+
Source: `packages/ds/src/components/banner.tsx`
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: aircall-ds/migrate-tractor/avatar
|
|
3
|
+
description: >
|
|
4
|
+
Migrate Tractor Avatar and QuickAvatar to the @aircall/ds Avatar compound
|
|
5
|
+
(Avatar, AvatarImage, AvatarFallback, AvatarBadge, AvatarGroup, AvatarGroupCount).
|
|
6
|
+
Load when a file imports Avatar or QuickAvatar from @aircall/tractor.
|
|
7
|
+
type: sub-skill
|
|
8
|
+
library: aircall-ds
|
|
9
|
+
library_version: "0.13.0"
|
|
10
|
+
requires:
|
|
11
|
+
- aircall-ds/setup
|
|
12
|
+
- aircall-ds/migrate-tractor
|
|
13
|
+
sources:
|
|
14
|
+
- "aircall/hydra:docs/migration-guides/tractor-to-ds/recipes/avatar.md"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
This skill builds on aircall-ds/migrate-tractor.
|
|
18
|
+
|
|
19
|
+
## 1. Component mapping
|
|
20
|
+
|
|
21
|
+
| Tractor part | DS replacement | Notes |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| `<Avatar src url name size>` | `<Avatar size><AvatarImage /><AvatarFallback /></Avatar>` | Compound — image and fallback are explicit children |
|
|
24
|
+
| `<QuickAvatar>` | `<Avatar>` | Identical DS compound; `QuickAvatar` had no extra API |
|
|
25
|
+
| `name="Jane Doe"` prop | `<AvatarFallback>JD</AvatarFallback>` | Derive initials yourself; DS has no auto-initials prop |
|
|
26
|
+
| Tractor `Badge` on avatar | `<AvatarBadge className="bg-…" />` | Child of `Avatar`; color set via `className` |
|
|
27
|
+
| Tractor `AvatarGroup` stack | `<AvatarGroup>` | Wraps `Avatar` children with overlap ring |
|
|
28
|
+
| Overflow chip `+N` | `<AvatarGroupCount>+3</AvatarGroupCount>` | Last child inside `AvatarGroup` |
|
|
29
|
+
|
|
30
|
+
## 2. Verified DS exports (`packages/ds/src/index.ts`)
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 3. Imports
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import {
|
|
40
|
+
Avatar,
|
|
41
|
+
AvatarBadge,
|
|
42
|
+
AvatarFallback,
|
|
43
|
+
AvatarGroup,
|
|
44
|
+
AvatarGroupCount,
|
|
45
|
+
AvatarImage,
|
|
46
|
+
} from '@aircall/ds';
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 4. Size mapping (Tractor → DS)
|
|
50
|
+
|
|
51
|
+
| Tractor `size` | DS `size` | Rendered px |
|
|
52
|
+
| --- | --- | --- |
|
|
53
|
+
| `small` | `sm` | 24 px |
|
|
54
|
+
| `regular` (default) | `default` | 32 px |
|
|
55
|
+
| `large` | `xl` | 48 px |
|
|
56
|
+
| `xLarge` | `xl` | 48 px |
|
|
57
|
+
| _(none / 20 px)_ | `xs` | 20 px |
|
|
58
|
+
| _(none / 40 px)_ | `lg` | 40 px |
|
|
59
|
+
|
|
60
|
+
There is no 64 px size in DS. Map Tractor `xLarge` (64 px) to `xl` (48 px) — the closest available size.
|
|
61
|
+
|
|
62
|
+
## 5. Before / After examples
|
|
63
|
+
|
|
64
|
+
### 5a. Basic avatar with image and initials fallback
|
|
65
|
+
|
|
66
|
+
**Before (Tractor):**
|
|
67
|
+
```tsx
|
|
68
|
+
import { Avatar } from '@aircall/tractor';
|
|
69
|
+
|
|
70
|
+
<Avatar
|
|
71
|
+
src="https://example.com/photo.jpg"
|
|
72
|
+
name="Jane Doe"
|
|
73
|
+
size="regular"
|
|
74
|
+
/>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**After (DS):**
|
|
78
|
+
```tsx
|
|
79
|
+
import { Avatar, AvatarFallback, AvatarImage } from '@aircall/ds';
|
|
80
|
+
|
|
81
|
+
<Avatar size="default">
|
|
82
|
+
<AvatarImage src="https://example.com/photo.jpg" alt="Jane Doe" />
|
|
83
|
+
<AvatarFallback>JD</AvatarFallback>
|
|
84
|
+
</Avatar>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 5b. QuickAvatar migration
|
|
88
|
+
|
|
89
|
+
**Before (Tractor):**
|
|
90
|
+
```tsx
|
|
91
|
+
import { QuickAvatar } from '@aircall/tractor';
|
|
92
|
+
|
|
93
|
+
<QuickAvatar src={photoUrl} size="large" />
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**After (DS):**
|
|
97
|
+
```tsx
|
|
98
|
+
import { Avatar, AvatarFallback, AvatarImage } from '@aircall/ds';
|
|
99
|
+
|
|
100
|
+
<Avatar size="xl">
|
|
101
|
+
<AvatarImage src={photoUrl} alt="" />
|
|
102
|
+
<AvatarFallback />
|
|
103
|
+
</Avatar>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 5c. Avatar with status badge
|
|
107
|
+
|
|
108
|
+
**Before (Tractor):**
|
|
109
|
+
```tsx
|
|
110
|
+
import { Avatar } from '@aircall/tractor';
|
|
111
|
+
|
|
112
|
+
<Avatar src={url} name="Jane Doe" size="regular" badge="online" />
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**After (DS):**
|
|
116
|
+
```tsx
|
|
117
|
+
import { Avatar, AvatarBadge, AvatarFallback, AvatarImage } from '@aircall/ds';
|
|
118
|
+
|
|
119
|
+
<Avatar size="default">
|
|
120
|
+
<AvatarImage src={url} alt="Jane Doe" />
|
|
121
|
+
<AvatarFallback>JD</AvatarFallback>
|
|
122
|
+
<AvatarBadge className="bg-success" />
|
|
123
|
+
</Avatar>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
`AvatarBadge` auto-positions at bottom-right and sizes itself from the parent `Avatar`'s `size` attribute. Pass a Tailwind background utility via `className` to set the status color.
|
|
127
|
+
|
|
128
|
+
### 5d. Overlapping avatar group with overflow count
|
|
129
|
+
|
|
130
|
+
**Before (Tractor):**
|
|
131
|
+
```tsx
|
|
132
|
+
import { Avatar, AvatarGroup } from '@aircall/tractor';
|
|
133
|
+
|
|
134
|
+
<AvatarGroup max={3} users={users} />
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**After (DS):**
|
|
138
|
+
```tsx
|
|
139
|
+
import {
|
|
140
|
+
Avatar,
|
|
141
|
+
AvatarFallback,
|
|
142
|
+
AvatarGroup,
|
|
143
|
+
AvatarGroupCount,
|
|
144
|
+
AvatarImage,
|
|
145
|
+
} from '@aircall/ds';
|
|
146
|
+
|
|
147
|
+
<AvatarGroup>
|
|
148
|
+
<Avatar>
|
|
149
|
+
<AvatarImage src={users[0].photo} alt={users[0].name} />
|
|
150
|
+
<AvatarFallback>AB</AvatarFallback>
|
|
151
|
+
</Avatar>
|
|
152
|
+
<Avatar>
|
|
153
|
+
<AvatarImage src={users[1].photo} alt={users[1].name} />
|
|
154
|
+
<AvatarFallback>CD</AvatarFallback>
|
|
155
|
+
</Avatar>
|
|
156
|
+
<AvatarGroupCount>+{users.length - 2}</AvatarGroupCount>
|
|
157
|
+
</AvatarGroup>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
DS has no built-in `max` or `users` props — slice the array yourself before rendering and compute the overflow count explicitly.
|
|
161
|
+
|
|
162
|
+
## 6. Common mistakes
|
|
163
|
+
|
|
164
|
+
### Mistake 1: Passing `name` as a prop instead of rendering `AvatarFallback`
|
|
165
|
+
|
|
166
|
+
**Wrong:**
|
|
167
|
+
```tsx
|
|
168
|
+
import { Avatar } from '@aircall/ds';
|
|
169
|
+
|
|
170
|
+
<Avatar name="Jane Doe" size="default" />
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Correct:**
|
|
174
|
+
```tsx
|
|
175
|
+
import { Avatar, AvatarFallback, AvatarImage } from '@aircall/ds';
|
|
176
|
+
|
|
177
|
+
<Avatar size="default">
|
|
178
|
+
<AvatarImage src={url} alt="Jane Doe" />
|
|
179
|
+
<AvatarFallback>JD</AvatarFallback>
|
|
180
|
+
</Avatar>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
DS `Avatar` has no `name` prop. The prop is silently ignored and no fallback text renders when the image fails to load — the avatar shows a blank circle instead of initials.
|
|
184
|
+
|
|
185
|
+
Source: packages/ds/src/components/avatar.tsx — `AvatarProps` extends `AvatarPrimitive.Root.Props` which has no `name` field.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
### Mistake 2: Omitting `AvatarFallback` when no image src is provided
|
|
190
|
+
|
|
191
|
+
**Wrong:**
|
|
192
|
+
```tsx
|
|
193
|
+
import { Avatar, AvatarImage } from '@aircall/ds';
|
|
194
|
+
|
|
195
|
+
<Avatar size="default">
|
|
196
|
+
<AvatarImage src={maybeUndefinedUrl} alt="User" />
|
|
197
|
+
</Avatar>
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Correct:**
|
|
201
|
+
```tsx
|
|
202
|
+
import { Avatar, AvatarFallback, AvatarImage } from '@aircall/ds';
|
|
203
|
+
|
|
204
|
+
<Avatar size="default">
|
|
205
|
+
<AvatarImage src={maybeUndefinedUrl} alt="User" />
|
|
206
|
+
<AvatarFallback>U</AvatarFallback>
|
|
207
|
+
</Avatar>
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
`AvatarImage` is a Base UI image that automatically swaps to `AvatarFallback` on load failure or when `src` is absent. Without `AvatarFallback`, a failed or missing image leaves an empty, unstyled circle with no content.
|
|
211
|
+
|
|
212
|
+
Source: packages/ds/src/components/avatar.tsx — `AvatarFallback` renders via `AvatarPrimitive.Fallback` which is only shown when the image is unavailable.
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
### Mistake 3: Placing `AvatarBadge` outside `Avatar`
|
|
217
|
+
|
|
218
|
+
**Wrong:**
|
|
219
|
+
```tsx
|
|
220
|
+
import { Avatar, AvatarBadge, AvatarFallback, AvatarImage } from '@aircall/ds';
|
|
221
|
+
|
|
222
|
+
<div style={{ position: 'relative' }}>
|
|
223
|
+
<Avatar size="default">
|
|
224
|
+
<AvatarImage src={url} alt="Jane Doe" />
|
|
225
|
+
<AvatarFallback>JD</AvatarFallback>
|
|
226
|
+
</Avatar>
|
|
227
|
+
<AvatarBadge className="bg-success" />
|
|
228
|
+
</div>
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Correct:**
|
|
232
|
+
```tsx
|
|
233
|
+
import { Avatar, AvatarBadge, AvatarFallback, AvatarImage } from '@aircall/ds';
|
|
234
|
+
|
|
235
|
+
<Avatar size="default">
|
|
236
|
+
<AvatarImage src={url} alt="Jane Doe" />
|
|
237
|
+
<AvatarFallback>JD</AvatarFallback>
|
|
238
|
+
<AvatarBadge className="bg-success" />
|
|
239
|
+
</Avatar>
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
`AvatarBadge` uses `absolute` positioning and reads the parent `group/avatar`'s `data-size` attribute to scale itself. Outside `Avatar`, it loses both the positioning context and the size-driven Tailwind group variants, so it renders at the wrong position and wrong size.
|
|
243
|
+
|
|
244
|
+
Source: packages/ds/src/components/avatar.tsx — `AvatarBadge` className includes `absolute right-0 bottom-0` and `group-data-[size=…]/avatar:size-…` variants.
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
### Mistake 4: Using Tractor `size="large"` or `size="xLarge"` expecting a 64 px avatar
|
|
249
|
+
|
|
250
|
+
**Wrong:**
|
|
251
|
+
```tsx
|
|
252
|
+
import { Avatar, AvatarFallback, AvatarImage } from '@aircall/ds';
|
|
253
|
+
|
|
254
|
+
<Avatar size="large">
|
|
255
|
+
<AvatarImage src={url} alt="User" />
|
|
256
|
+
<AvatarFallback>U</AvatarFallback>
|
|
257
|
+
</Avatar>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**Correct:**
|
|
261
|
+
```tsx
|
|
262
|
+
import { Avatar, AvatarFallback, AvatarImage } from '@aircall/ds';
|
|
263
|
+
|
|
264
|
+
<Avatar size="xl">
|
|
265
|
+
<AvatarImage src={url} alt="User" />
|
|
266
|
+
<AvatarFallback>U</AvatarFallback>
|
|
267
|
+
</Avatar>
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
DS has no `"large"` size token and no 64 px size. Passing `size="large"` falls back to the `default` (32 px) size because `data-size="large"` matches none of the Tailwind variants. The closest DS size to Tractor `xLarge` (64 px) is `xl` (48 px).
|
|
271
|
+
|
|
272
|
+
Source: packages/ds/src/components/avatar.tsx — `AvatarProps` size union is `'xs' | 'sm' | 'default' | 'lg' | 'xl'`.
|