@astryxdesign/cli 0.1.7-canary.cecb773 → 0.1.7-canary.d91c851
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/package.json +9 -9
- package/src/codemods/__tests__/registry.test.mjs +1 -0
- package/src/codemods/registry.mjs +1 -0
- package/src/codemods/transforms/v0.1.0/__tests__/drop-xds-prefix-imports.test.mjs +42 -7
- package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-module-specifiers.test.mjs +43 -0
- package/src/codemods/transforms/v0.1.0/drop-xds-prefix-imports.mjs +102 -3
- package/src/codemods/transforms/v0.1.0/migrate-xds-module-specifiers.mjs +72 -6
- package/src/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +161 -0
- package/src/codemods/transforms/v0.1.8/index.mjs +19 -0
- package/src/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +234 -0
- package/src/commands/agent-docs.mjs +72 -0
- package/src/commands/agent-docs.test.mjs +86 -0
- package/src/commands/upgrade.mjs +130 -27
- package/src/commands/upgrade.test.mjs +154 -0
- package/src/types/upgrade.d.ts +39 -2
- package/templates/blocks/components/Avatar/AvatarFallbackChain.tsx +4 -4
- package/templates/blocks/components/Avatar/AvatarGroup.tsx +2 -2
- package/templates/blocks/components/Avatar/AvatarInitialsFallback.tsx +1 -1
- package/templates/blocks/components/Avatar/AvatarShowcase.tsx +4 -4
- package/templates/blocks/components/Avatar/AvatarUserCard.tsx +1 -1
- package/templates/blocks/components/Avatar/AvatarWithImage.tsx +4 -4
- package/templates/blocks/components/Avatar/AvatarWithStatus.tsx +3 -3
- package/templates/blocks/components/AvatarGroup/AvatarGroupShowcase.tsx +2 -2
- package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowCustomText.tsx +1 -1
- package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowDefault.tsx +1 -1
- package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowShowcase.tsx +2 -2
- package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotShowcase.tsx +3 -3
- package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotVariants.tsx +3 -3
- package/templates/blocks/components/Carousel/CarouselSnap.tsx +1 -1
- package/templates/blocks/components/ChatMessage/ChatMessageAvatarName.tsx +2 -2
- package/templates/blocks/components/ChatMessage/ChatMessageMultiBubble.tsx +1 -1
- package/templates/blocks/components/ChatMessageBubble/ChatMessageBubbleGrouping.tsx +1 -1
- package/templates/blocks/components/ChatMessageBubble/ChatMessageBubbleMetadata.tsx +1 -1
- package/templates/blocks/components/ChatMessageList/ChatMessageListDensity.tsx +5 -9
- package/templates/blocks/components/ChatMessageList/ChatMessageListFullFeatured.tsx +1 -1
- package/templates/blocks/components/HoverCard/HoverCardShowcase.tsx +1 -1
- package/templates/blocks/components/Item/ItemWithMedia.tsx +2 -2
- package/templates/blocks/components/ListItem/ListItemWithMedia.tsx +2 -2
- package/templates/blocks/components/Pagination/PaginationDotsCarousel.tsx +2 -6
- package/templates/blocks/components/Stack/StackFillItem.tsx +2 -6
- package/templates/blocks/components/TypeaheadItem/TypeaheadItemShowcase.tsx +1 -1
- package/templates/pages/ai-chat/page.tsx +4 -4
- package/templates/pages/dashboard-portfolio/page.tsx +3 -11
- package/templates/pages/detail-page/page.tsx +5 -12
- package/templates/pages/documentation-design/page.tsx +1 -1
- package/templates/pages/messaging-shell/page.tsx +6 -8
- package/templates/pages/table-grouped/page.tsx +9 -14
- package/templates/pages/table-page/page.tsx +7 -9
- package/templates/pages/table-page-heatmap-status/page.tsx +5 -13
|
@@ -6,6 +6,7 @@ import * as path from 'node:path';
|
|
|
6
6
|
import * as os from 'node:os';
|
|
7
7
|
import {Command} from 'commander';
|
|
8
8
|
import {registerUpgrade} from './upgrade.mjs';
|
|
9
|
+
import {generateCompressedIndex} from './agent-docs.mjs';
|
|
9
10
|
|
|
10
11
|
let tmpDir;
|
|
11
12
|
let originalCwd;
|
|
@@ -158,3 +159,156 @@ describe('upgrade --list dedup', () => {
|
|
|
158
159
|
expect(names.length).toBe(unique.size);
|
|
159
160
|
});
|
|
160
161
|
});
|
|
162
|
+
|
|
163
|
+
// Issue #4168 — `upgrade` must refresh the managed agent-docs block after a
|
|
164
|
+
// version bump, on EVERY path (the block documents the installed library, not
|
|
165
|
+
// the codemod outcome), and must NOT write during a dry run.
|
|
166
|
+
describe('upgrade agent-docs refresh (#4168)', () => {
|
|
167
|
+
/** Write an agent-doc file with a managed block generated for `version`. */
|
|
168
|
+
function writeAgentBlock(rel, version) {
|
|
169
|
+
const filePath = path.join(tmpDir, rel);
|
|
170
|
+
fs.mkdirSync(path.dirname(filePath), {recursive: true});
|
|
171
|
+
fs.writeFileSync(filePath, `# Doc\n\n${generateCompressedIndex(version)}\n`);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
it('refreshes a stale block with --apply, even when there are no codemods (up-to-date path)', async () => {
|
|
175
|
+
writePkg();
|
|
176
|
+
writeInstalledCore('0.0.15');
|
|
177
|
+
writeAgentBlock('AGENTS.md', '0.0.1');
|
|
178
|
+
|
|
179
|
+
// --from == installed → up-to-date short-circuit: no codemods run, yet the
|
|
180
|
+
// stale block must still be brought current. This is the exact gap in #4168.
|
|
181
|
+
const result = await runJson(['--json', 'upgrade', '--from', '0.0.15', '--apply']);
|
|
182
|
+
|
|
183
|
+
expect(result.type).toBe('upgrade.status');
|
|
184
|
+
expect(result.data.status).toBe('up_to_date');
|
|
185
|
+
expect(result.data.agentDocs.status).toBe('stale');
|
|
186
|
+
expect(result.data.agentDocs.action).toBe('refreshed');
|
|
187
|
+
expect(result.data.agentDocs.refreshed).toBe(true);
|
|
188
|
+
expect(result.data.agentDocs.fromVersions).toEqual(['0.0.1']);
|
|
189
|
+
expect(result.data.agentDocs.files).toContain('AGENTS.md');
|
|
190
|
+
|
|
191
|
+
const content = fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8');
|
|
192
|
+
expect(content).toMatch(/Astryx v0\.0\.15 ·/);
|
|
193
|
+
expect(content).not.toMatch(/Astryx v0\.0\.1 ·/);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it('reports a stale block on a dry run WITHOUT writing', async () => {
|
|
197
|
+
writePkg();
|
|
198
|
+
writeInstalledCore('0.0.15');
|
|
199
|
+
writeAgentBlock('AGENTS.md', '0.0.1');
|
|
200
|
+
const before = fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8');
|
|
201
|
+
|
|
202
|
+
const result = await runJson(['--json', 'upgrade', '--from', '0.0.15']); // no --apply
|
|
203
|
+
|
|
204
|
+
expect(result.data.agentDocs.status).toBe('stale');
|
|
205
|
+
expect(result.data.agentDocs.action).toBe('would-refresh');
|
|
206
|
+
expect(result.data.agentDocs.refreshed).toBe(false);
|
|
207
|
+
// The file must be untouched by a dry run.
|
|
208
|
+
expect(fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8')).toBe(before);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('refreshes a stale block on the no-codemods path (--apply)', async () => {
|
|
212
|
+
writePkg();
|
|
213
|
+
writeInstalledCore('0.0.11'); // (0.0.10, 0.0.11] has no registered codemods
|
|
214
|
+
writeSourceFile();
|
|
215
|
+
writeAgentBlock('CLAUDE.md', '0.0.1');
|
|
216
|
+
|
|
217
|
+
const result = await runJson(['--json', 'upgrade', '--from', '0.0.10', '--apply', '--path', 'src']);
|
|
218
|
+
|
|
219
|
+
expect(result.type).toBe('upgrade.status');
|
|
220
|
+
expect(result.data.status).toBe('no_codemods');
|
|
221
|
+
expect(result.data.agentDocs.refreshed).toBe(true);
|
|
222
|
+
expect(fs.readFileSync(path.join(tmpDir, 'CLAUDE.md'), 'utf-8')).toMatch(/Astryx v0\.0\.11 ·/);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('nudges to run init when core is installed but no managed block exists', async () => {
|
|
226
|
+
writePkg();
|
|
227
|
+
writeInstalledCore('0.0.15');
|
|
228
|
+
// No agent-doc files at all.
|
|
229
|
+
|
|
230
|
+
const result = await runJson(['--json', 'upgrade', '--from', '0.0.15', '--apply']);
|
|
231
|
+
|
|
232
|
+
expect(result.data.agentDocs.status).toBe('missing');
|
|
233
|
+
expect(result.data.agentDocs.action).toBe('nudge-init');
|
|
234
|
+
expect(result.data.agentDocs.refreshed).toBe(false);
|
|
235
|
+
// Must NOT silently create docs during an upgrade.
|
|
236
|
+
expect(fs.existsSync(path.join(tmpDir, 'AGENTS.md'))).toBe(false);
|
|
237
|
+
expect(fs.existsSync(path.join(tmpDir, '.claude', 'CLAUDE.md'))).toBe(false);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
it('treats an agent file without our markers as "never initialized" (missing)', async () => {
|
|
241
|
+
writePkg();
|
|
242
|
+
writeInstalledCore('0.0.15');
|
|
243
|
+
fs.writeFileSync(path.join(tmpDir, 'AGENTS.md'), '# Agents\n\nHand-written, no astryx block.\n');
|
|
244
|
+
const before = fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8');
|
|
245
|
+
|
|
246
|
+
const result = await runJson(['--json', 'upgrade', '--from', '0.0.15', '--apply']);
|
|
247
|
+
|
|
248
|
+
expect(result.data.agentDocs.status).toBe('missing');
|
|
249
|
+
expect(result.data.agentDocs.action).toBe('nudge-init');
|
|
250
|
+
// An unmarked file is left exactly as-is.
|
|
251
|
+
expect(fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8')).toBe(before);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('does not silently no-op a stale block with malformed markers (START without END)', async () => {
|
|
255
|
+
writePkg();
|
|
256
|
+
writeInstalledCore('0.0.15');
|
|
257
|
+
// A corrupted block: START + version header but no matching END marker, so
|
|
258
|
+
// the writer can't safely splice it. This must not crash, corrupt the file,
|
|
259
|
+
// or falsely claim success — it should surface an error and nudge re-init.
|
|
260
|
+
const corrupted =
|
|
261
|
+
'# A\n\n<!-- ASTRYX:START -->\nAstryx v0.0.1 · 9 components\nguidance, but no end marker\n';
|
|
262
|
+
fs.writeFileSync(path.join(tmpDir, 'AGENTS.md'), corrupted);
|
|
263
|
+
|
|
264
|
+
const result = await runJson(['--json', 'upgrade', '--from', '0.0.15', '--apply']);
|
|
265
|
+
|
|
266
|
+
expect(result.data.agentDocs.status).toBe('stale');
|
|
267
|
+
expect(result.data.agentDocs.action).toBe('error');
|
|
268
|
+
expect(result.data.agentDocs.refreshed).toBe(false);
|
|
269
|
+
// File left byte-for-byte intact — never corrupted.
|
|
270
|
+
expect(fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8')).toBe(corrupted);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
it('stays silent when the block already matches the installed version', async () => {
|
|
274
|
+
writePkg();
|
|
275
|
+
writeInstalledCore('0.0.15');
|
|
276
|
+
writeAgentBlock('AGENTS.md', '0.0.15');
|
|
277
|
+
|
|
278
|
+
const result = await runJson(['--json', 'upgrade', '--from', '0.0.15', '--apply']);
|
|
279
|
+
|
|
280
|
+
expect(result.data.agentDocs.status).toBe('current');
|
|
281
|
+
expect(result.data.agentDocs.action).toBe('none');
|
|
282
|
+
expect(result.data.agentDocs.refreshed).toBe(false);
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
it('migrates a legacy XDS block to the current Astryx block (--apply)', async () => {
|
|
286
|
+
writePkg();
|
|
287
|
+
writeInstalledCore('0.0.15');
|
|
288
|
+
fs.writeFileSync(
|
|
289
|
+
path.join(tmpDir, 'CLAUDE.md'),
|
|
290
|
+
'# Claude\n\n<!-- XDS:START -->\nlegacy index\n<!-- XDS:END -->\n\nMore rules.\n',
|
|
291
|
+
);
|
|
292
|
+
|
|
293
|
+
const result = await runJson(['--json', 'upgrade', '--from', '0.0.15', '--apply']);
|
|
294
|
+
|
|
295
|
+
expect(result.data.agentDocs.status).toBe('stale');
|
|
296
|
+
expect(result.data.agentDocs.refreshed).toBe(true);
|
|
297
|
+
const content = fs.readFileSync(path.join(tmpDir, 'CLAUDE.md'), 'utf-8');
|
|
298
|
+
expect(content).toContain('<!-- ASTRYX:START -->');
|
|
299
|
+
expect(content).toMatch(/Astryx v0\.0\.15 ·/);
|
|
300
|
+
expect(content).not.toContain('legacy index');
|
|
301
|
+
expect(content).toContain('More rules.');
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it('surfaces agentDocs in the human output on the up-to-date path', async () => {
|
|
305
|
+
writePkg();
|
|
306
|
+
writeInstalledCore('0.0.15');
|
|
307
|
+
writeAgentBlock('AGENTS.md', '0.0.1');
|
|
308
|
+
|
|
309
|
+
const program = createProgram();
|
|
310
|
+
await program.parseAsync(['node', 'astryx', 'upgrade', '--from', '0.0.15', '--apply']);
|
|
311
|
+
const output = stdoutCalls.join('') + logCalls.join('\n');
|
|
312
|
+
expect(output).toMatch(/Agent docs refreshed/i);
|
|
313
|
+
});
|
|
314
|
+
});
|
package/src/types/upgrade.d.ts
CHANGED
|
@@ -23,6 +23,31 @@ export interface UpgradeListEntry {
|
|
|
23
23
|
version: string;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* State of the managed agent-docs block (`<!-- ASTRYX:START --> … END -->`)
|
|
28
|
+
* relative to the installed core version, plus what `upgrade` did about it.
|
|
29
|
+
* Present on every upgrade response (run, status, and the codemod/config error
|
|
30
|
+
* envelopes) because the block is refreshed independently of codemods.
|
|
31
|
+
*
|
|
32
|
+
* - `refreshed` — a stale block was rewritten (`--apply` only).
|
|
33
|
+
* - `would-refresh` — a stale block was detected in dry-run; nothing written.
|
|
34
|
+
* - `nudge-init` — no managed block exists; user should run `init`.
|
|
35
|
+
* - `error` — refresh was attempted but writing failed.
|
|
36
|
+
* - `none` — nothing to do (block already current).
|
|
37
|
+
*/
|
|
38
|
+
export interface AgentDocsSummary {
|
|
39
|
+
status: 'missing' | 'stale' | 'current';
|
|
40
|
+
/** Installed core version the block should reflect. */
|
|
41
|
+
installedVersion: string;
|
|
42
|
+
/** Distinct stale block versions found (the "from" side of the refresh). */
|
|
43
|
+
fromVersions: string[];
|
|
44
|
+
/** Files rewritten (apply) or that would be rewritten (dry-run). */
|
|
45
|
+
files: string[];
|
|
46
|
+
/** True only when a block was actually rewritten (apply mode). */
|
|
47
|
+
refreshed: boolean;
|
|
48
|
+
action: 'refreshed' | 'would-refresh' | 'nudge-init' | 'error' | 'none';
|
|
49
|
+
}
|
|
50
|
+
|
|
26
51
|
/** xds --json upgrade [--apply] */
|
|
27
52
|
export interface UpgradeRunResponse {
|
|
28
53
|
type: 'upgrade.run';
|
|
@@ -32,6 +57,7 @@ export interface UpgradeRunResponse {
|
|
|
32
57
|
codemods: number;
|
|
33
58
|
depsUpdated: string[];
|
|
34
59
|
agentDocsRefreshed: boolean;
|
|
60
|
+
agentDocs: AgentDocsSummary;
|
|
35
61
|
};
|
|
36
62
|
}
|
|
37
63
|
|
|
@@ -49,8 +75,18 @@ export interface UpgradeRunResponse {
|
|
|
49
75
|
export interface UpgradeStatusResponse {
|
|
50
76
|
type: 'upgrade.status';
|
|
51
77
|
data:
|
|
52
|
-
| {
|
|
53
|
-
|
|
78
|
+
| {
|
|
79
|
+
status: 'up_to_date';
|
|
80
|
+
from: string;
|
|
81
|
+
to: string;
|
|
82
|
+
agentDocs: AgentDocsSummary;
|
|
83
|
+
}
|
|
84
|
+
| {
|
|
85
|
+
status: 'no_codemods';
|
|
86
|
+
from: string;
|
|
87
|
+
to: string;
|
|
88
|
+
agentDocs: AgentDocsSummary;
|
|
89
|
+
}
|
|
54
90
|
| {
|
|
55
91
|
status: 'config_fixable';
|
|
56
92
|
from: string;
|
|
@@ -60,5 +96,6 @@ export interface UpgradeStatusResponse {
|
|
|
60
96
|
suggestedCommand: string;
|
|
61
97
|
message: string;
|
|
62
98
|
note: string;
|
|
99
|
+
agentDocs: AgentDocsSummary;
|
|
63
100
|
};
|
|
64
101
|
}
|
|
@@ -13,7 +13,7 @@ export default function AvatarFallbackChain() {
|
|
|
13
13
|
<Avatar
|
|
14
14
|
src="https://lookaside.facebook.com/assets/astryx/DATA-Daniela-Gimenez.png"
|
|
15
15
|
name="Daniela Gimenez"
|
|
16
|
-
size="
|
|
16
|
+
size="lg"
|
|
17
17
|
/>
|
|
18
18
|
<Text type="supporting">Valid src</Text>
|
|
19
19
|
</HStack>
|
|
@@ -22,7 +22,7 @@ export default function AvatarFallbackChain() {
|
|
|
22
22
|
src="https://lookaside.facebook.com/assets/astryx/does-not-exist-primary.jpg"
|
|
23
23
|
fallbackSrc="https://lookaside.facebook.com/assets/astryx/DATA-Ami-Pena.png"
|
|
24
24
|
name="Invalid User"
|
|
25
|
-
size="
|
|
25
|
+
size="lg"
|
|
26
26
|
/>
|
|
27
27
|
<Text type="supporting">Invalid src, valid fallbackSrc</Text>
|
|
28
28
|
</HStack>
|
|
@@ -31,14 +31,14 @@ export default function AvatarFallbackChain() {
|
|
|
31
31
|
src="https://lookaside.facebook.com/assets/astryx/does-not-exist-primary.jpg"
|
|
32
32
|
fallbackSrc="https://lookaside.facebook.com/assets/astryx/does-not-exist-fallback.jpg"
|
|
33
33
|
name="Test User"
|
|
34
|
-
size="
|
|
34
|
+
size="lg"
|
|
35
35
|
/>
|
|
36
36
|
<Text type="supporting">Both invalid, has name</Text>
|
|
37
37
|
</HStack>
|
|
38
38
|
<HStack gap={3} vAlign="center">
|
|
39
39
|
<Avatar
|
|
40
40
|
src="https://lookaside.facebook.com/assets/astryx/does-not-exist-primary.jpg"
|
|
41
|
-
size="
|
|
41
|
+
size="lg"
|
|
42
42
|
/>
|
|
43
43
|
<Text type="supporting">All invalid, no name</Text>
|
|
44
44
|
</HStack>
|
|
@@ -37,7 +37,7 @@ export default function AvatarGroupBlock() {
|
|
|
37
37
|
<Text type="supporting" color="secondary">
|
|
38
38
|
Team members
|
|
39
39
|
</Text>
|
|
40
|
-
<AvatarGroup size="
|
|
40
|
+
<AvatarGroup size="lg">
|
|
41
41
|
{USERS.map(user => (
|
|
42
42
|
<Avatar key={user.name} src={user.src} name={user.name} />
|
|
43
43
|
))}
|
|
@@ -48,7 +48,7 @@ export default function AvatarGroupBlock() {
|
|
|
48
48
|
<Text type="supporting" color="secondary">
|
|
49
49
|
Larger group
|
|
50
50
|
</Text>
|
|
51
|
-
<AvatarGroup size="
|
|
51
|
+
<AvatarGroup size="lg">
|
|
52
52
|
{USERS.slice(0, 3).map(user => (
|
|
53
53
|
<Avatar key={user.name} src={user.src} name={user.name} />
|
|
54
54
|
))}
|
|
@@ -18,7 +18,7 @@ export default function AvatarInitialsFallback() {
|
|
|
18
18
|
<Stack direction="horizontal" gap={6} vAlign="center">
|
|
19
19
|
{NAMES.map(({name, note}) => (
|
|
20
20
|
<Stack key={name} direction="vertical" gap={2} hAlign="center">
|
|
21
|
-
<Avatar name={name} size="
|
|
21
|
+
<Avatar name={name} size="lg" />
|
|
22
22
|
<Text type="supporting" color="secondary">
|
|
23
23
|
{note}
|
|
24
24
|
</Text>
|
|
@@ -11,23 +11,23 @@ export default function AvatarShowcase() {
|
|
|
11
11
|
<Avatar
|
|
12
12
|
src="https://lookaside.facebook.com/assets/astryx/DATA-Ana-Thomas.png"
|
|
13
13
|
name="Ana Thomas"
|
|
14
|
-
size="
|
|
14
|
+
size="xl"
|
|
15
15
|
status={<AvatarStatusDot variant="success" label="Online" />}
|
|
16
16
|
/>
|
|
17
17
|
<Avatar
|
|
18
18
|
src="https://lookaside.facebook.com/assets/astryx/DATA-Drew-Young.png"
|
|
19
19
|
name="Drew Young"
|
|
20
|
-
size="
|
|
20
|
+
size="xl"
|
|
21
21
|
/>
|
|
22
22
|
<Avatar
|
|
23
23
|
src="https://lookaside.facebook.com/assets/astryx/DATA-Jihoo-Song.png"
|
|
24
24
|
name="Jihoo Song"
|
|
25
|
-
size="
|
|
25
|
+
size="xl"
|
|
26
26
|
/>
|
|
27
27
|
<Avatar
|
|
28
28
|
src="https://lookaside.facebook.com/assets/astryx/DATA-Nam-Tran.png"
|
|
29
29
|
name="Nam Tran"
|
|
30
|
-
size="
|
|
30
|
+
size="xl"
|
|
31
31
|
status={<AvatarStatusDot variant="error" label="Online" />}
|
|
32
32
|
/>
|
|
33
33
|
</Stack>
|
|
@@ -11,22 +11,22 @@ export default function AvatarWithImage() {
|
|
|
11
11
|
<Avatar
|
|
12
12
|
src="https://lookaside.facebook.com/assets/astryx/DATA-Ami-Pena.png"
|
|
13
13
|
name="Ami Pena"
|
|
14
|
-
size="
|
|
14
|
+
size="xsm"
|
|
15
15
|
/>
|
|
16
16
|
<Avatar
|
|
17
17
|
src="https://lookaside.facebook.com/assets/astryx/DATA-Ana-Thomas.png"
|
|
18
18
|
name="Ana Thomas"
|
|
19
|
-
size="
|
|
19
|
+
size="md"
|
|
20
20
|
/>
|
|
21
21
|
<Avatar
|
|
22
22
|
src="https://lookaside.facebook.com/assets/astryx/DATA-Daniela-Gimenez.png"
|
|
23
23
|
name="Daniela Gimenez"
|
|
24
|
-
size="
|
|
24
|
+
size="lg"
|
|
25
25
|
/>
|
|
26
26
|
<Avatar
|
|
27
27
|
src="https://lookaside.facebook.com/assets/astryx/DATA-Gabriela-Fernandez.png"
|
|
28
28
|
name="Gabriela Fernandez"
|
|
29
|
-
size="
|
|
29
|
+
size="xl"
|
|
30
30
|
/>
|
|
31
31
|
</Stack>
|
|
32
32
|
);
|
|
@@ -11,19 +11,19 @@ export default function AvatarWithStatus() {
|
|
|
11
11
|
<Avatar
|
|
12
12
|
src="https://lookaside.facebook.com/assets/astryx/DATA-Itai-Jordaan.png"
|
|
13
13
|
name="Itai Jordaan"
|
|
14
|
-
size="
|
|
14
|
+
size="xl"
|
|
15
15
|
status={<AvatarStatusDot variant="success" label="Online" />}
|
|
16
16
|
/>
|
|
17
17
|
<Avatar
|
|
18
18
|
src="https://lookaside.facebook.com/assets/astryx/DATA-Margot-Schroder.png"
|
|
19
19
|
name="Margot Schroder"
|
|
20
|
-
size="
|
|
20
|
+
size="xl"
|
|
21
21
|
status={<AvatarStatusDot variant="neutral" label="Offline" />}
|
|
22
22
|
/>
|
|
23
23
|
<Avatar
|
|
24
24
|
src="https://lookaside.facebook.com/assets/astryx/DATA-Pablo-Morales.png"
|
|
25
25
|
name="Pablo Morales"
|
|
26
|
-
size="
|
|
26
|
+
size="xl"
|
|
27
27
|
status={<AvatarStatusDot variant="error" label="Busy" />}
|
|
28
28
|
/>
|
|
29
29
|
</Stack>
|
|
@@ -36,7 +36,7 @@ export default function AvatarGroupShowcase() {
|
|
|
36
36
|
<Text type="supporting" color="secondary">
|
|
37
37
|
Team members
|
|
38
38
|
</Text>
|
|
39
|
-
<AvatarGroup size="
|
|
39
|
+
<AvatarGroup size="lg">
|
|
40
40
|
{USERS.map(u => (
|
|
41
41
|
<Avatar key={u.key} name={u.name} />
|
|
42
42
|
))}
|
|
@@ -46,7 +46,7 @@ export default function AvatarGroupShowcase() {
|
|
|
46
46
|
<Text type="supporting" color="secondary">
|
|
47
47
|
With overflow
|
|
48
48
|
</Text>
|
|
49
|
-
<AvatarGroup size="
|
|
49
|
+
<AvatarGroup size="lg">
|
|
50
50
|
{USERS.slice(0, 3).map(u => (
|
|
51
51
|
<Avatar key={u.key} name={u.name} />
|
|
52
52
|
))}
|
|
@@ -24,7 +24,7 @@ export default function AvatarGroupOverflowCustomText() {
|
|
|
24
24
|
<Text type="supporting" color="secondary">
|
|
25
25
|
Team members
|
|
26
26
|
</Text>
|
|
27
|
-
<AvatarGroup size="
|
|
27
|
+
<AvatarGroup size="lg">
|
|
28
28
|
{TEAM.map(member => (
|
|
29
29
|
<Avatar key={member.name} name={member.name} />
|
|
30
30
|
))}
|
|
@@ -24,7 +24,7 @@ export default function AvatarGroupOverflowDefault() {
|
|
|
24
24
|
<Text type="supporting" color="secondary">
|
|
25
25
|
Reviewers
|
|
26
26
|
</Text>
|
|
27
|
-
<AvatarGroup size="
|
|
27
|
+
<AvatarGroup size="lg">
|
|
28
28
|
{REVIEWERS.map(reviewer => (
|
|
29
29
|
<Avatar key={reviewer.name} name={reviewer.name} />
|
|
30
30
|
))}
|
|
@@ -25,7 +25,7 @@ export default function AvatarGroupOverflowShowcase() {
|
|
|
25
25
|
<Text type="supporting" color="secondary">
|
|
26
26
|
Default overflow
|
|
27
27
|
</Text>
|
|
28
|
-
<AvatarGroup size="
|
|
28
|
+
<AvatarGroup size="lg">
|
|
29
29
|
{USERS.map(user => (
|
|
30
30
|
<Avatar key={user.name} name={user.name} />
|
|
31
31
|
))}
|
|
@@ -36,7 +36,7 @@ export default function AvatarGroupOverflowShowcase() {
|
|
|
36
36
|
<Text type="supporting" color="secondary">
|
|
37
37
|
Custom count text
|
|
38
38
|
</Text>
|
|
39
|
-
<AvatarGroup size="
|
|
39
|
+
<AvatarGroup size="lg">
|
|
40
40
|
{USERS.slice(0, 2).map(user => (
|
|
41
41
|
<Avatar key={user.name} name={user.name} />
|
|
42
42
|
))}
|
|
@@ -10,17 +10,17 @@ export default function AvatarStatusDotShowcase() {
|
|
|
10
10
|
<HStack gap={4} vAlign="center">
|
|
11
11
|
<Avatar
|
|
12
12
|
name="Online User"
|
|
13
|
-
size="
|
|
13
|
+
size="xl"
|
|
14
14
|
status={<AvatarStatusDot variant="success" label="Online" />}
|
|
15
15
|
/>
|
|
16
16
|
<Avatar
|
|
17
17
|
name="Away User"
|
|
18
|
-
size="
|
|
18
|
+
size="xl"
|
|
19
19
|
status={<AvatarStatusDot variant="neutral" label="Away" />}
|
|
20
20
|
/>
|
|
21
21
|
<Avatar
|
|
22
22
|
name="Busy User"
|
|
23
|
-
size="
|
|
23
|
+
size="xl"
|
|
24
24
|
status={<AvatarStatusDot variant="error" label="Busy" />}
|
|
25
25
|
/>
|
|
26
26
|
</HStack>
|
|
@@ -10,17 +10,17 @@ export default function AvatarStatusDotVariants() {
|
|
|
10
10
|
<HStack gap={4} vAlign="center">
|
|
11
11
|
<Avatar
|
|
12
12
|
name="Ana Silva"
|
|
13
|
-
size="
|
|
13
|
+
size="xl"
|
|
14
14
|
status={<AvatarStatusDot variant="success" label="Online" />}
|
|
15
15
|
/>
|
|
16
16
|
<Avatar
|
|
17
17
|
name="Ben Okafor"
|
|
18
|
-
size="
|
|
18
|
+
size="xl"
|
|
19
19
|
status={<AvatarStatusDot variant="neutral" label="Away" />}
|
|
20
20
|
/>
|
|
21
21
|
<Avatar
|
|
22
22
|
name="Cleo Marsh"
|
|
23
|
-
size="
|
|
23
|
+
size="xl"
|
|
24
24
|
status={<AvatarStatusDot variant="error" label="Do not disturb" />}
|
|
25
25
|
/>
|
|
26
26
|
</HStack>
|
|
@@ -27,7 +27,7 @@ export default function CarouselSnap() {
|
|
|
27
27
|
{TEAM.map(person => (
|
|
28
28
|
<Card key={person.name} width={180} minHeight={140}>
|
|
29
29
|
<Stack direction="vertical" gap={3} hAlign="center">
|
|
30
|
-
<Avatar name={person.name} size="
|
|
30
|
+
<Avatar name={person.name} size="lg" />
|
|
31
31
|
<Stack direction="vertical" gap={1} hAlign="center">
|
|
32
32
|
<Text type="body" weight="bold">
|
|
33
33
|
{person.name}
|
|
@@ -17,7 +17,7 @@ export default function ChatMessageAvatarName() {
|
|
|
17
17
|
<ChatMessageList style={{maxWidth: 500}}>
|
|
18
18
|
<ChatMessage
|
|
19
19
|
sender="assistant"
|
|
20
|
-
avatar={<Avatar name="Agent" size="
|
|
20
|
+
avatar={<Avatar name="Agent" size="md" />}>
|
|
21
21
|
<ChatMessageBubble
|
|
22
22
|
name={
|
|
23
23
|
<Text type="supporting" weight="semibold" color="secondary">
|
|
@@ -50,7 +50,7 @@ export default function ChatMessageAvatarName() {
|
|
|
50
50
|
</ChatMessage>
|
|
51
51
|
<ChatMessage
|
|
52
52
|
sender="assistant"
|
|
53
|
-
avatar={<Avatar name="Agent" size="
|
|
53
|
+
avatar={<Avatar name="Agent" size="md" />}>
|
|
54
54
|
<ChatMessageBubble
|
|
55
55
|
name={
|
|
56
56
|
<Text type="supporting" weight="semibold" color="secondary">
|
|
@@ -17,7 +17,7 @@ export default function ChatMessageBubbleGrouping() {
|
|
|
17
17
|
<ChatMessageList style={{maxWidth: 500}}>
|
|
18
18
|
<ChatMessage
|
|
19
19
|
sender="assistant"
|
|
20
|
-
avatar={<Avatar name="Agent" size="
|
|
20
|
+
avatar={<Avatar name="Agent" size="md" />}>
|
|
21
21
|
<ChatMessageBubble
|
|
22
22
|
group="first"
|
|
23
23
|
name={
|
|
@@ -20,7 +20,7 @@ export default function ChatMessageBubbleMetadata() {
|
|
|
20
20
|
<ChatMessageList style={{maxWidth: 500}}>
|
|
21
21
|
<ChatMessage
|
|
22
22
|
sender="assistant"
|
|
23
|
-
avatar={<Avatar name="Agent" size="
|
|
23
|
+
avatar={<Avatar name="Agent" size="md" />}>
|
|
24
24
|
<ChatMessageBubble
|
|
25
25
|
name={
|
|
26
26
|
<Text type="supporting" weight="semibold" color="secondary">
|
|
@@ -16,9 +16,9 @@ import {Fragment} from 'react';
|
|
|
16
16
|
const DENSITIES = ['compact', 'balanced', 'spacious'] as const;
|
|
17
17
|
|
|
18
18
|
const AVATAR_SIZE = {
|
|
19
|
-
compact: '
|
|
20
|
-
balanced: '
|
|
21
|
-
spacious: '
|
|
19
|
+
compact: 'sm' as const,
|
|
20
|
+
balanced: 'md' as const,
|
|
21
|
+
spacious: 'md' as const,
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
export default function ChatMessageListDensity() {
|
|
@@ -34,15 +34,11 @@ export default function ChatMessageListDensity() {
|
|
|
34
34
|
<VStack style={{flex: 1, minHeight: 0}}>
|
|
35
35
|
<ChatMessageList density={density}>
|
|
36
36
|
<ChatMessage sender="user">
|
|
37
|
-
<ChatMessageBubble>
|
|
38
|
-
How does density work?
|
|
39
|
-
</ChatMessageBubble>
|
|
37
|
+
<ChatMessageBubble>How does density work?</ChatMessageBubble>
|
|
40
38
|
</ChatMessage>
|
|
41
39
|
<ChatMessage
|
|
42
40
|
sender="assistant"
|
|
43
|
-
avatar={
|
|
44
|
-
<Avatar name="Agent" size={AVATAR_SIZE[density]} />
|
|
45
|
-
}>
|
|
41
|
+
avatar={<Avatar name="Agent" size={AVATAR_SIZE[density]} />}>
|
|
46
42
|
<ChatMessageBubble>
|
|
47
43
|
Density provides default spacing at every level — message
|
|
48
44
|
gap, bubble padding, and gap between child elements. Use gap
|
|
@@ -42,7 +42,7 @@ export default function ChatMessageListFullFeatured() {
|
|
|
42
42
|
|
|
43
43
|
<ChatMessage
|
|
44
44
|
sender="assistant"
|
|
45
|
-
avatar={<Avatar name="Agent" size="
|
|
45
|
+
avatar={<Avatar name="Agent" size="md" />}>
|
|
46
46
|
<ChatMessageBubble group="first">
|
|
47
47
|
<Markdown density="compact">
|
|
48
48
|
{`Sure! Here's the key pattern from **useReducer.ts**:`}
|
|
@@ -15,7 +15,7 @@ export default function HoverCardShowcase() {
|
|
|
15
15
|
content={
|
|
16
16
|
<Stack direction="vertical" gap={2} style={{width: 240}}>
|
|
17
17
|
<Stack direction="horizontal" gap={2} vAlign="center">
|
|
18
|
-
<Avatar name="Jane Doe" size="
|
|
18
|
+
<Avatar name="Jane Doe" size="lg" />
|
|
19
19
|
<Stack direction="vertical" gap={0}>
|
|
20
20
|
<Heading level={5}>Jane Doe</Heading>
|
|
21
21
|
<Text type="supporting" color="secondary">
|
|
@@ -13,14 +13,14 @@ export default function ItemWithMedia() {
|
|
|
13
13
|
return (
|
|
14
14
|
<Stack gap={0}>
|
|
15
15
|
<Item
|
|
16
|
-
startContent={<Avatar name="Ada Lovelace" size="
|
|
16
|
+
startContent={<Avatar name="Ada Lovelace" size="sm" />}
|
|
17
17
|
label="Ada Lovelace"
|
|
18
18
|
description="Design systems engineer"
|
|
19
19
|
endContent={<Badge label="Owner" variant="purple" />}
|
|
20
20
|
onClick={() => {}}
|
|
21
21
|
/>
|
|
22
22
|
<Item
|
|
23
|
-
startContent={<Avatar name="Grace Hopper" size="
|
|
23
|
+
startContent={<Avatar name="Grace Hopper" size="sm" />}
|
|
24
24
|
label="Grace Hopper"
|
|
25
25
|
description="Compiler platform"
|
|
26
26
|
endContent={<Text color="secondary">Online</Text>}
|
|
@@ -13,14 +13,14 @@ export default function ListItemWithMedia() {
|
|
|
13
13
|
<ListItem
|
|
14
14
|
label="Ada Lovelace"
|
|
15
15
|
description="Design systems engineer"
|
|
16
|
-
startContent={<Avatar name="Ada Lovelace" size="
|
|
16
|
+
startContent={<Avatar name="Ada Lovelace" size="sm" />}
|
|
17
17
|
endContent={<Badge label="Owner" variant="purple" />}
|
|
18
18
|
onClick={() => {}}
|
|
19
19
|
/>
|
|
20
20
|
<ListItem
|
|
21
21
|
label="Grace Hopper"
|
|
22
22
|
description="Platform infrastructure"
|
|
23
|
-
startContent={<Avatar name="Grace Hopper" size="
|
|
23
|
+
startContent={<Avatar name="Grace Hopper" size="sm" />}
|
|
24
24
|
endContent={<Badge label="On call" variant="blue" />}
|
|
25
25
|
onClick={() => {}}
|
|
26
26
|
/>
|