@aircall/ds 0.13.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 +94 -33
- package/dist/index.js +292 -42
- package/package.json +16 -3
- 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,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'`.
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: aircall-ds/migrate-tractor/badge
|
|
3
|
+
description: >
|
|
4
|
+
Migrate Tractor Tag and CounterBadge to @aircall/ds Badge, CounterBadge, BadgeGroup,
|
|
5
|
+
and BadgeGroupCount. Load when a file imports Tag or CounterBadge from @aircall/tractor.
|
|
6
|
+
Maps Tractor variant (grey/primary/blue/red/yellow/green/purple/pink/dark* prefixes)
|
|
7
|
+
to the DS color + tone two-axis model, and Tractor status Badge (dot) to AvatarBadge.
|
|
8
|
+
type: sub-skill
|
|
9
|
+
library: aircall-ds
|
|
10
|
+
library_version: "0.13.0"
|
|
11
|
+
requires:
|
|
12
|
+
- aircall-ds/setup
|
|
13
|
+
- aircall-ds/migrate-tractor
|
|
14
|
+
sources:
|
|
15
|
+
- "aircall/hydra:docs/migration-guides/tractor-to-ds/recipes/badge.md"
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
This skill builds on aircall-ds/migrate-tractor.
|
|
19
|
+
|
|
20
|
+
## 1. Component mapping
|
|
21
|
+
|
|
22
|
+
Tractor's badge surface had three distinct concepts that map to different DS components:
|
|
23
|
+
|
|
24
|
+
| Tractor component | DS replacement | Notes |
|
|
25
|
+
| --- | --- | --- |
|
|
26
|
+
| `<Tag>` | `<Badge>` | Color model changes from single `variant` to `color` + `tone` |
|
|
27
|
+
| `<CounterBadge>` | `<CounterBadge>` | No `max` prop — cap the value yourself before passing as children |
|
|
28
|
+
| `<Badge>` (status dot) | `<AvatarBadge>` | Tractor's dot-indicator badge is unrelated to DS `Badge`; see the avatar skill |
|
|
29
|
+
| _(grouping)_ | `<BadgeGroup>` + `<BadgeGroupCount>` | Wraps multiple badges; `BadgeGroupCount` renders the overflow "+N" chip |
|
|
30
|
+
|
|
31
|
+
## 2. Verified DS exports (`packages/ds/src/index.ts`)
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
Badge, BadgeGroup, BadgeGroupCount
|
|
35
|
+
CounterBadge, counterBadgeVariants
|
|
36
|
+
AvatarBadge
|
|
37
|
+
Chip, ChipRemove
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 3. Imports
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { Badge, BadgeGroup, BadgeGroupCount, CounterBadge } from '@aircall/ds';
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Icons inside badges import from `@aircall/react-icons` — never from `lucide-react` directly.
|
|
47
|
+
|
|
48
|
+
## 4. `Tag` variant → `Badge` color + tone
|
|
49
|
+
|
|
50
|
+
DS Badge uses two orthogonal props instead of Tractor's single `variant`:
|
|
51
|
+
|
|
52
|
+
- `color`: `charcoal` (default) · `red` · `green` · `blue` · `purple` · `yellow` · `pink`
|
|
53
|
+
- `tone`: `dark` · `medium-dark` · `medium-light` · `light` (default)
|
|
54
|
+
|
|
55
|
+
| Tractor `variant` | DS `color` | DS `tone` |
|
|
56
|
+
| --- | --- | --- |
|
|
57
|
+
| `grey` / `white` | `charcoal` | `light` |
|
|
58
|
+
| `secondary` | `charcoal` | `medium-light` |
|
|
59
|
+
| `lightSecondary` | `charcoal` | `light` |
|
|
60
|
+
| `darkSecondary` | `charcoal` | `medium-dark` |
|
|
61
|
+
| `primary` | `green` | `medium-light` |
|
|
62
|
+
| `lightPrimary` | `green` | `light` |
|
|
63
|
+
| `darkPrimary` | `green` | `dark` |
|
|
64
|
+
| `blue` | `blue` | `medium-light` |
|
|
65
|
+
| `darkBlue` | `blue` | `dark` |
|
|
66
|
+
| `red` | `red` | `medium-light` |
|
|
67
|
+
| `darkRed` | `red` | `dark` |
|
|
68
|
+
| `yellow` | `yellow` | `medium-light` |
|
|
69
|
+
| `darkYellow` | `yellow` | `dark` |
|
|
70
|
+
| `green` | `green` | `medium-light` |
|
|
71
|
+
| `darkGreen` | `green` | `dark` |
|
|
72
|
+
| `purple` | `purple` | `medium-light` |
|
|
73
|
+
| `darkPurple` | `purple` | `dark` |
|
|
74
|
+
| `pink` | `pink` | `medium-light` |
|
|
75
|
+
|
|
76
|
+
> The base color variant maps to `medium-light`; `dark*` variants map to `dark` or `medium-dark`. `light*` variants map to `light`. Pick the tone that best matches the surface.
|
|
77
|
+
|
|
78
|
+
### Hard-coded hex colors (`bg` prop)
|
|
79
|
+
|
|
80
|
+
When Tractor used a hard-coded hex (e.g. `bg="#0761B5"`), pass it via `legacyColor` — DS resolves it to the nearest `color` + `tone` at render time from an internal map. Unknown hexes fall back to `charcoal` / `dark`.
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
<Badge legacyColor="#0761B5">Sales</Badge>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 5. Size mapping
|
|
87
|
+
|
|
88
|
+
| Tractor `size` | DS `size` |
|
|
89
|
+
| --- | --- |
|
|
90
|
+
| `xSmall` | `default` (20px) |
|
|
91
|
+
| `small` | `default` (20px) |
|
|
92
|
+
| `regular` (default) | `default` (20px) |
|
|
93
|
+
| `large` | `lg` (24px) |
|
|
94
|
+
|
|
95
|
+
DS has no `mode` prop (`outline` / `fill`). Use a lighter `tone` (e.g. `light`) to approximate the old outline look.
|
|
96
|
+
|
|
97
|
+
## 6. CounterBadge
|
|
98
|
+
|
|
99
|
+
DS `CounterBadge` has no `max` prop. Cap the displayed value yourself before passing as children:
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
<CounterBadge>{count > 99 ? '99+' : count}</CounterBadge>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Available `variant` values: `default` (destructive background) · `secondary` · `ghost`.
|
|
106
|
+
|
|
107
|
+
## 7. Grouping badges
|
|
108
|
+
|
|
109
|
+
Use `BadgeGroup` to wrap a set of badges with consistent spacing, and `BadgeGroupCount` for the trailing overflow chip:
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
<BadgeGroup>
|
|
113
|
+
<Badge color="blue" tone="medium-light">Support</Badge>
|
|
114
|
+
<Badge color="green" tone="medium-light">Active</Badge>
|
|
115
|
+
<BadgeGroupCount>{overflow}</BadgeGroupCount>
|
|
116
|
+
</BadgeGroup>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## 8. Before / After examples
|
|
120
|
+
|
|
121
|
+
### 8a. Simple Tag → Badge (variant rename)
|
|
122
|
+
|
|
123
|
+
**Before (Tractor):**
|
|
124
|
+
```tsx
|
|
125
|
+
import { Tag } from '@aircall/tractor';
|
|
126
|
+
|
|
127
|
+
<Tag variant="primary">Active</Tag>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**After (DS):**
|
|
131
|
+
```tsx
|
|
132
|
+
import { Badge } from '@aircall/ds';
|
|
133
|
+
|
|
134
|
+
<Badge color="green" tone="medium-light">Active</Badge>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
> Tractor `primary` = green brand color → DS `color="green"` `tone="medium-light"`.
|
|
138
|
+
|
|
139
|
+
### 8b. Dark variant
|
|
140
|
+
|
|
141
|
+
**Before (Tractor):**
|
|
142
|
+
```tsx
|
|
143
|
+
import { Tag } from '@aircall/tractor';
|
|
144
|
+
|
|
145
|
+
<Tag variant="darkBlue">Escalated</Tag>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**After (DS):**
|
|
149
|
+
```tsx
|
|
150
|
+
import { Badge } from '@aircall/ds';
|
|
151
|
+
|
|
152
|
+
<Badge color="blue" tone="dark">Escalated</Badge>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### 8c. Hard-coded hex color
|
|
156
|
+
|
|
157
|
+
**Before (Tractor):**
|
|
158
|
+
```tsx
|
|
159
|
+
import { Tag } from '@aircall/tractor';
|
|
160
|
+
|
|
161
|
+
<Tag bg="#0761B5">Sales</Tag>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**After (DS):**
|
|
165
|
+
```tsx
|
|
166
|
+
import { Badge } from '@aircall/ds';
|
|
167
|
+
|
|
168
|
+
<Badge legacyColor="#0761B5">Sales</Badge>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### 8d. CounterBadge with max cap
|
|
172
|
+
|
|
173
|
+
**Before (Tractor):**
|
|
174
|
+
```tsx
|
|
175
|
+
import { CounterBadge } from '@aircall/tractor';
|
|
176
|
+
|
|
177
|
+
<CounterBadge count={count} max={99} />
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**After (DS):**
|
|
181
|
+
```tsx
|
|
182
|
+
import { CounterBadge } from '@aircall/ds';
|
|
183
|
+
|
|
184
|
+
<CounterBadge>{count > 99 ? '99+' : count}</CounterBadge>
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### 8e. Icon inside a Badge
|
|
188
|
+
|
|
189
|
+
**Before (Tractor):**
|
|
190
|
+
```tsx
|
|
191
|
+
import { Tag } from '@aircall/tractor';
|
|
192
|
+
import { CheckCircle } from '@aircall/react-icons';
|
|
193
|
+
|
|
194
|
+
<Tag variant="green"><CheckCircle size={12} /> Verified</Tag>
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**After (DS):**
|
|
198
|
+
```tsx
|
|
199
|
+
import { Badge } from '@aircall/ds';
|
|
200
|
+
import { CheckCircle } from '@aircall/react-icons';
|
|
201
|
+
|
|
202
|
+
<Badge color="green" tone="medium-light"><CheckCircle /> Verified</Badge>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
> DS auto-sizes SVG children via `[&>svg]:size-3!` (default) or `[&>svg]:size-4!` (lg). Do not pass a `size` prop to the icon.
|
|
206
|
+
|
|
207
|
+
## 9. Common mistakes
|
|
208
|
+
|
|
209
|
+
### Mistake 1: Using `variant` instead of `color` + `tone`
|
|
210
|
+
|
|
211
|
+
```tsx
|
|
212
|
+
// Wrong — DS Badge has no `variant` prop; it is silently ignored
|
|
213
|
+
<Badge variant="primary">Active</Badge>
|
|
214
|
+
|
|
215
|
+
// Correct — map to the two-axis color + tone model
|
|
216
|
+
<Badge color="green" tone="medium-light">Active</Badge>
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**Mechanism:** DS Badge replaced Tractor's single `variant` string with two orthogonal props `color` and `tone`. Passing `variant` goes to the underlying `span` as an unknown HTML attribute and has no visual effect — the badge renders with the default charcoal/light appearance instead of the intended color.
|
|
220
|
+
|
|
221
|
+
Source: `packages/ds/src/components/badge.tsx` — `badgeVariants` has `color` and `tone` keys, no `variant` key.
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
### Mistake 2: Mapping Tractor status `Badge` (dot) to DS `Badge`
|
|
226
|
+
|
|
227
|
+
```tsx
|
|
228
|
+
// Wrong — DS Badge is a label chip, not a status dot
|
|
229
|
+
<Badge status="online" />
|
|
230
|
+
|
|
231
|
+
// Correct — Tractor's status dot maps to AvatarBadge
|
|
232
|
+
import { Avatar, AvatarBadge, AvatarImage } from '@aircall/ds';
|
|
233
|
+
|
|
234
|
+
<Avatar>
|
|
235
|
+
<AvatarImage src={src} alt={name} />
|
|
236
|
+
<AvatarBadge />
|
|
237
|
+
</Avatar>
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**Mechanism:** Tractor had two components both named `Badge`: a label chip (`Tag`) and a small status dot (`Badge`). DS names them differently — `Badge` is the label chip and `AvatarBadge` is the status indicator that composes inside `Avatar`. Migrating the dot to DS `Badge` renders a text chip with no content instead of a dot.
|
|
241
|
+
|
|
242
|
+
Source: `packages/ds/src/components/badge.tsx` — `Badge` is a label chip; `packages/ds/src/components/avatar.tsx` exports `AvatarBadge` for the status dot.
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
### Mistake 3: Relying on DS `CounterBadge` to cap overflow automatically
|
|
247
|
+
|
|
248
|
+
```tsx
|
|
249
|
+
// Wrong — DS CounterBadge has no `max` prop; it renders the raw number
|
|
250
|
+
<CounterBadge max={99} count={count} />
|
|
251
|
+
|
|
252
|
+
// Correct — cap the value yourself before passing as children
|
|
253
|
+
<CounterBadge>{count > 99 ? '99+' : count}</CounterBadge>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Mechanism:** Tractor's `CounterBadge` accepted a `max` prop and formatted "99+" internally. DS `CounterBadge` is a presentational span that renders whatever children it receives — the cap logic is the caller's responsibility. Passing `max` and `count` as props results in an empty badge with two unknown HTML attributes instead of the formatted string.
|
|
257
|
+
|
|
258
|
+
Source: `packages/ds/src/components/counter-badge.tsx` — `CounterBadge.Props` extends `useRender.ComponentProps<'span'>` with only a `variant` prop; no `max` or `count` keys.
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
### Mistake 4: Using `outline` / `fill` mode to style a badge
|
|
263
|
+
|
|
264
|
+
```tsx
|
|
265
|
+
// Wrong — DS Badge has no `mode` prop
|
|
266
|
+
<Badge color="blue" mode="outline">Beta</Badge>
|
|
267
|
+
|
|
268
|
+
// Correct — reach for a lighter tone to approximate the outline look
|
|
269
|
+
<Badge color="blue" tone="light">Beta</Badge>
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Mechanism:** Tractor's `Tag` supported a `mode` prop (`outline` / `fill`) that toggled between a bordered and a filled appearance. DS Badge has no `mode` prop — the visual weight is controlled entirely by `tone`. A lighter tone (`light` or `medium-light`) produces a softer background that approximates the old outline look.
|
|
273
|
+
|
|
274
|
+
Source: `packages/ds/src/components/badge.tsx` — `badgeVariants` has `size`, `color`, and `tone` variants; no `mode` variant.
|