@aircall/ds 0.10.0 → 0.13.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.
@@ -0,0 +1,57 @@
1
+ # @aircall/ds — Guide for AI Agents (Consumers)
2
+
3
+ You are generating code that **uses** `@aircall/ds` (Aircall's design system) in a
4
+ consuming app. This file lists the rules that the TypeScript types can't express.
5
+ Trust the shipped `.d.ts` for exact prop names and values — they are accurate and
6
+ variants are typed as literal unions. Do **not** invent props.
7
+
8
+ ## Stack
9
+
10
+ - Built on **Base UI** (`@base-ui/react`), **not** Radix. Tailwind CSS v4 + CVA.
11
+ - React 18 or 19(React 19 is recommended).
12
+
13
+ ## Import rules
14
+
15
+ - Import components from the package root: `import { Button, Dialog } from '@aircall/ds'`.
16
+ There are no deep component import paths in normal use.
17
+ - Import icons from `@aircall/react-icons` — **never** `lucide-react` directly.
18
+ Icons are passed as `children` (e.g. `<Button><Phone />Call</Button>`).
19
+
20
+ ## Required: import the stylesheet once
21
+
22
+ The app must import the stylesheet a single time at its entry point:
23
+
24
+ ```tsx
25
+ import '@aircall/ds/globals.css';
26
+ ```
27
+
28
+ In a published-package (non-monorepo) consumer this is a **precompiled** Tailwind v4
29
+ bundle. Do **not** also add `@import 'tailwindcss';` — it duplicates the reset. You do
30
+ not need to configure Tailwind to consume DS.
31
+
32
+ ## Base UI conventions (the common mistakes)
33
+
34
+ - To render a component as a different element, use the **`render`** prop, **not**
35
+ `asChild`: `<Button render={<a href="/x" />}>Go</Button>`.
36
+ - Base UI uses its own prop/event conventions — rely on the component's TypeScript
37
+ types rather than assuming Radix-style APIs.
38
+
39
+ ## Dark mode
40
+
41
+ Controlled by the `data-theme` attribute on a root element:
42
+
43
+ ```tsx
44
+ <html data-theme="dark">
45
+ ```
46
+
47
+ ## Peer dependencies
48
+
49
+ Required: `react`, `react-dom`, `@aircall/react-icons`, `@aircall/numbers`.
50
+ Install only if you use the component: `react-day-picker` + `date-fns` (Calendar),
51
+ `@tanstack/react-table` (DataTable).
52
+
53
+ ## When unsure about an API
54
+
55
+ 1. Read the component's type in `node_modules/@aircall/ds/dist/components/<name>.d.ts`.
56
+ 2. Browse live docs and examples at https://ds.aircall.io.
57
+ 3. Do not guess prop names — if it isn't in the types, it doesn't exist.
package/README.md CHANGED
@@ -1,16 +1,25 @@
1
1
  # @aircall/ds - Aircall Design System
2
2
 
3
- Modern React component library built with TailwindCSS 4, Radix UI primitives, and TypeScript.
3
+ Modern React component library built with TailwindCSS 4, Base UI primitives, and TypeScript.
4
4
 
5
5
  ## Tech Stack
6
6
 
7
7
  - **React 19** - Latest React with compiler optimizations
8
8
  - **TailwindCSS 4** - Utility-first CSS with OKLch color space
9
- - **Radix UI** - Unstyled, accessible component primitives
9
+ - **Base UI** - Unstyled, accessible component primitives (`@base-ui/react`)
10
10
  - **TypeScript 5.7** - Type-safe development
11
11
  - **Class Variance Authority (CVA)** - Variant-based component styling
12
12
  - **Storybook 10** - Interactive component documentation
13
13
 
14
+ ## For AI agents / coding assistants
15
+
16
+ If you are an AI assistant generating code that uses `@aircall/ds`, read
17
+ [`AGENTS.consumer.md`](./AGENTS.consumer.md) (shipped in this package) for the rules the
18
+ TypeScript types can't express — Base UI conventions (use `render`, not `asChild`), the
19
+ required `@aircall/ds/globals.css` import, icon imports from `@aircall/react-icons`, and
20
+ dark-mode setup. The shipped `.d.ts` files are the source of truth for prop names and
21
+ values (variants are typed as literal unions) — do not invent props.
22
+
14
23
  ## Installation
15
24
 
16
25
  ### For Monorepo Apps (Hydra Workspace)
@@ -37,7 +46,7 @@ pnpm add @aircall/ds
37
46
  **Required peer dependencies:**
38
47
 
39
48
  ```bash
40
- pnpm add react react-dom @aircall/icons @aircall/numbers
49
+ pnpm add react react-dom @aircall/react-icons @aircall/numbers
41
50
  ```
42
51
 
43
52
  **Optional peer dependencies (install only if you use these components):**
@@ -55,6 +64,8 @@ pnpm add react-day-picker date-fns
55
64
  pnpm add @tanstack/react-table
56
65
  ```
57
66
 
67
+ > The package is published with its module graph preserved (`tsdown` `unbundle`) and is marked `sideEffects: ["**/*.css"]`, so these peers are only pulled into a consumer's bundle when `Calendar` / `DataTable` are actually imported. Importing other components (e.g. `Button`) tree-shakes them away — no install required.
68
+
58
69
  ## Usage
59
70
 
60
71
  ### Import Components
@@ -75,15 +86,15 @@ function App() {
75
86
 
76
87
  ### Import CSS Styles
77
88
 
78
- **The CSS import differs depending on your environment:**
89
+ **There is one stylesheet, `@aircall/ds/globals.css`, but it resolves to a different artifact depending on how you consume the package.** (There is no separate `styles.css` export.)
79
90
 
80
- #### Monorepo Apps
91
+ #### Monorepo Apps (`workspace:*`)
81
92
 
82
- In monorepo apps, import the source CSS for optimal build integration:
93
+ The package's `exports` point at **source**, so `@aircall/ds/globals.css` is the un-compiled Tailwind source (`@import "tailwindcss"`, `@theme`, …). Your app's Tailwind v4 build compiles it, and `@source` scans your own files for class names:
83
94
 
84
95
  ```css
85
- /* In your app's entry point or globals.css */
86
- import '@aircall/ds/globals.css';
96
+ /* your app's entry CSS */
97
+ @import '@aircall/ds/globals.css';
87
98
 
88
99
  /* Scan your own source files for Tailwind classes */
89
100
  @source "your_own_source_file";
@@ -95,32 +106,24 @@ Benefits:
95
106
  - Shared Tailwind context for better optimization
96
107
  - Access to theme variables and utilities
97
108
 
98
- #### External Apps
99
-
100
- In external apps, use the pre-compiled CSS bundle:
101
-
102
- ```css
103
- @import 'tailwindcss';
104
- @import '@aircall/ds/globals.css';
105
-
106
- /* Scan your own source files for Tailwind classes */
107
- @source "your_own_source_file";
108
- ```
109
+ #### External Apps (published npm package)
109
110
 
110
- Or in TypeScript/JavaScript entry point:
111
+ The published tarball rewrites `exports` to **`dist`**, so `@aircall/ds/globals.css` is a **precompiled** Tailwind v4 bundle — reset, tokens, and every component utility already generated. Import it directly; no Tailwind build and no `@source` are needed to consume DS, and you must **not** prepend `@import 'tailwindcss'` (it would duplicate the reset):
111
112
 
112
113
  ```tsx
113
114
  // main.tsx
114
- import '@aircall/ds/styles.css';
115
+ import '@aircall/ds/globals.css';
115
116
  ```
116
117
 
117
118
  Benefits:
118
119
 
119
- - No need to configure Tailwind to scan node_modules
120
+ - No need to configure Tailwind to scan `node_modules`
120
121
  - Smaller bundle size (pre-compiled and minified)
121
122
  - Faster build times
122
123
  - Simpler setup
123
124
 
125
+ If your app authors its **own** Tailwind classes, set Tailwind up for *your* sources separately — the precompiled DS bundle still doesn't require it.
126
+
124
127
  ### Dark Mode
125
128
 
126
129
  Dark mode is controlled via the `data-theme` attribute:
@@ -139,45 +142,50 @@ The design system uses CSS variables that automatically adjust based on this att
139
142
 
140
143
  ### Button
141
144
 
142
- Versatile button component with multiple variants, colors, sizes, and shapes.
145
+ Versatile button component with multiple variants and sizes, built on the Base UI
146
+ button primitive (so it also accepts Base UI `Button` props such as `disabled`).
143
147
 
144
148
  **Props:**
145
149
 
146
- - `variant`: 'default' | 'outline' | 'ghost' | 'link'
147
- - `color`: 'primary' | 'secondary' | 'brand-primary' | 'brand-secondary' | 'brand-destructive' | 'info' | 'success' | 'warning' | 'destructive'
148
- - `size`: 'xs' | 'sm' | 'default' | 'lg'
149
- - `shape`: 'default' | 'square' | 'circle'
150
- - `readOnly`: boolean
151
- - `block`: boolean (full width)
150
+ - `variant`: 'default' | 'secondary' | 'outline' | 'ghost' | 'destructive' | 'link' (default: `'default'`)
151
+ - `size`: 'default' | 'sm' | 'lg' | 'icon' | 'icon-sm' | 'icon-lg' (default: `'default'`)
152
+ - `block`: boolean full width (default: `false`)
152
153
  - `render`: ReactElement — render Button as a different element (e.g. `<a>`). Replaces the former `asChild` / Slot pattern.
153
154
 
155
+ > Icons are passed as children. Import them from `@aircall/react-icons` (never `lucide-react` directly).
156
+
154
157
  **Examples:**
155
158
 
156
159
  ```tsx
157
- // Primary button
158
- <Button variant="default" color="primary">Primary</Button>
160
+ import { Button } from '@aircall/ds';
161
+ import { Phone, Mail } from '@aircall/react-icons';
162
+
163
+ // Primary button (default variant)
164
+ <Button>Primary</Button>
159
165
 
160
- // Outline button
161
- <Button variant="outline" color="secondary">Outline</Button>
166
+ // Secondary / outline / ghost
167
+ <Button variant="secondary">Secondary</Button>
168
+ <Button variant="outline">Outline</Button>
169
+ <Button variant="ghost">Ghost</Button>
162
170
 
163
- // Icon button
164
- <Button shape="circle" size="sm">
165
- <Phone className="size-4" />
171
+ // Icon-only button — use an `icon*` size
172
+ <Button variant="outline" size="icon-sm">
173
+ <Phone />
166
174
  </Button>
167
175
 
168
- // Button with icon
176
+ // Button with a leading icon
169
177
  <Button>
170
- <Mail className="size-4" />
178
+ <Mail />
171
179
  Send Email
172
180
  </Button>
173
181
 
174
- // Full width button
182
+ // Full-width button
175
183
  <Button block>Full Width</Button>
176
184
 
177
185
  // Destructive button
178
- <Button color="destructive">Delete</Button>
186
+ <Button variant="destructive">Delete</Button>
179
187
 
180
- // Link rendered as a button — use the `render` prop
188
+ // Render as a link — use the `render` prop (not `asChild`)
181
189
  <Button render={<a href="/profile" />}>Go to Profile</Button>
182
190
  ```
183
191
 
@@ -220,30 +228,30 @@ Static site output: `storybook-static/`. See [Recipes (shadcn Registry)](#recipe
220
228
  This package uses shadcn/ui patterns for component development:
221
229
 
222
230
  ```bash
223
- # Add a new component from shadcn
224
- pnpm add <component-name>
231
+ # Add a new component from shadcn (wraps `pnpx shadcn@latest add`)
232
+ pnpm shadcn:add <component-name>
225
233
  ```
226
234
 
227
235
  ### File Structure
228
236
 
229
237
  ```
230
238
  src/
231
- ├── components/ # React components (published to npm)
232
- └── button/
233
- ├── __stories__/
234
- └── Button.stories.tsx
235
- │ └── button.tsx
239
+ ├── components/ # React components, one flat file per component (published to npm)
240
+ ├── button.tsx
241
+ ├── dialog.tsx
242
+ │ └──
243
+ ├── stories/ # Storybook stories (PascalCase, e.g. Button.stories.tsx)
236
244
  ├── styles/ # Global styles
237
245
  │ ├── globals.css # TailwindCSS + theme variables
238
246
  │ └── brand.css # Aircall brand colors
239
247
  ├── lib/ # Utilities
240
248
  │ └── utils.ts # cn() helper for class merging
241
249
  ├── hooks/ # Custom React hooks
242
- └── fonts/ # Fellix Aircall font files
243
- ├── recipes/ # shadcn registry recipes (copy-paste patterns)
250
+ ├── recipes/ # shadcn registry recipes (copy-paste patterns, NOT published to npm)
244
251
  │ ├── combobox-searchable-select.tsx
245
252
  │ ├── combobox-dropdown-search.tsx
246
253
  │ └── combobox-multi-select.tsx
254
+ └── fonts/ # Fellix Aircall font files
247
255
  ```
248
256
 
249
257
  ### Styling System
@@ -374,7 +382,7 @@ pnpm sb:build:deploy # Full deployment build: runs registry:build, builds St
374
382
  pnpm pack # Create tarball for local testing
375
383
 
376
384
  # Component Management
377
- pnpm add <component> # Add new shadcn component
385
+ pnpm shadcn:add <component> # Add new shadcn component
378
386
 
379
387
  # Maintenance
380
388
  pnpm clean # Remove build artifacts