@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.
Files changed (34) hide show
  1. package/README.md +31 -0
  2. package/dist/globals.css +1 -1
  3. package/dist/index.d.ts +28 -28
  4. package/dist/index.js +1 -1
  5. package/package.json +12 -2
  6. package/skills/aircall-ds/migrate-icons/SKILL.md +346 -0
  7. package/skills/aircall-ds/migrate-tractor/SKILL.md +314 -0
  8. package/skills/aircall-ds/migrate-tractor/accordion/SKILL.md +276 -0
  9. package/skills/aircall-ds/migrate-tractor/alert/SKILL.md +225 -0
  10. package/skills/aircall-ds/migrate-tractor/avatar/SKILL.md +272 -0
  11. package/skills/aircall-ds/migrate-tractor/badge/SKILL.md +274 -0
  12. package/skills/aircall-ds/migrate-tractor/button/SKILL.md +277 -0
  13. package/skills/aircall-ds/migrate-tractor/card/SKILL.md +278 -0
  14. package/skills/aircall-ds/migrate-tractor/combobox/SKILL.md +346 -0
  15. package/skills/aircall-ds/migrate-tractor/data-table/SKILL.md +333 -0
  16. package/skills/aircall-ds/migrate-tractor/dialog/SKILL.md +206 -0
  17. package/skills/aircall-ds/migrate-tractor/divider/SKILL.md +226 -0
  18. package/skills/aircall-ds/migrate-tractor/dropdown-menu/SKILL.md +266 -0
  19. package/skills/aircall-ds/migrate-tractor/dropzone/SKILL.md +338 -0
  20. package/skills/aircall-ds/migrate-tractor/form-and-field/SKILL.md +325 -0
  21. package/skills/aircall-ds/migrate-tractor/gauge/SKILL.md +248 -0
  22. package/skills/aircall-ds/migrate-tractor/input/SKILL.md +261 -0
  23. package/skills/aircall-ds/migrate-tractor/item/SKILL.md +298 -0
  24. package/skills/aircall-ds/migrate-tractor/link/SKILL.md +263 -0
  25. package/skills/aircall-ds/migrate-tractor/popover/SKILL.md +214 -0
  26. package/skills/aircall-ds/migrate-tractor/select/SKILL.md +245 -0
  27. package/skills/aircall-ds/migrate-tractor/sheet-vs-drawer/SKILL.md +272 -0
  28. package/skills/aircall-ds/migrate-tractor/skeleton/SKILL.md +190 -0
  29. package/skills/aircall-ds/migrate-tractor/styling/SKILL.md +421 -0
  30. package/skills/aircall-ds/migrate-tractor/tabs/SKILL.md +250 -0
  31. package/skills/aircall-ds/migrate-tractor/toast/SKILL.md +322 -0
  32. package/skills/aircall-ds/migrate-tractor/tooltip/SKILL.md +204 -0
  33. package/skills/aircall-ds/migrate-tractor/tree/SKILL.md +346 -0
  34. 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'`.