@agentero/design-system 0.2.0 → 0.3.1
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.
|
@@ -576,7 +576,7 @@
|
|
|
576
576
|
<header>
|
|
577
577
|
<div class="wrap">
|
|
578
578
|
<h1>Manifest Debugger</h1>
|
|
579
|
-
<div class="summary"><a class="filter-pill all" data-k="all" href="#filter-all">All</a><span class="filter-pill ok" aria-disabled="true">
|
|
579
|
+
<div class="summary"><a class="filter-pill all" data-k="all" href="#filter-all">All</a><span class="filter-pill ok" aria-disabled="true">4 components ok</span><span class="filter-pill ok" aria-disabled="true">44 stories ok</span></div>
|
|
580
580
|
</div>
|
|
581
581
|
</header>
|
|
582
582
|
<main>
|
|
@@ -1268,6 +1268,301 @@ variant?: ButtonVariantType</code></pre>
|
|
|
1268
1268
|
|
|
1269
1269
|
</div>
|
|
1270
1270
|
</article>
|
|
1271
|
+
<article
|
|
1272
|
+
class="card
|
|
1273
|
+
no-error
|
|
1274
|
+
no-info
|
|
1275
|
+
no-story-error
|
|
1276
|
+
no-doc-error"
|
|
1277
|
+
role="listitem"
|
|
1278
|
+
aria-label="Divider">
|
|
1279
|
+
<div class="head">
|
|
1280
|
+
<div class="title">
|
|
1281
|
+
<h2><span class="status-dot dot-ok"></span> Divider</h2>
|
|
1282
|
+
<div class="badges">
|
|
1283
|
+
<label for="c-2-components-divider-props" class="badge ok as-toggle">2 prop types</label>
|
|
1284
|
+
|
|
1285
|
+
<label for="c-2-components-divider-stories" class="badge ok as-toggle">10 stories</label>
|
|
1286
|
+
|
|
1287
|
+
</div>
|
|
1288
|
+
</div>
|
|
1289
|
+
<div class="meta" title="./src/divider/divider.stories.tsx">components-divider · ./src/divider/divider.stories.tsx</div>
|
|
1290
|
+
|
|
1291
|
+
<div class="hint">Divider separates content visually along either a horizontal or vertical axis. Use between page or card sections, between inline items in a toolbar or list, or — with the `label` prop — to render an "or"-style break between options. Set `decorative={false}` when the separator carries semantic meaning so it's announced to assistive technologies.</div>
|
|
1292
|
+
|
|
1293
|
+
</div>
|
|
1294
|
+
|
|
1295
|
+
<!-- ⬇️ Hidden toggles must be siblings BEFORE .panels -->
|
|
1296
|
+
|
|
1297
|
+
|
|
1298
|
+
<input id="c-2-components-divider-stories" class="tg tg-stories" type="checkbox" hidden />
|
|
1299
|
+
|
|
1300
|
+
<input id="c-2-components-divider-props" class="tg tg-props" type="checkbox" hidden />
|
|
1301
|
+
|
|
1302
|
+
<div class="panels">
|
|
1303
|
+
|
|
1304
|
+
|
|
1305
|
+
|
|
1306
|
+
<div class="panel panel-props">
|
|
1307
|
+
<div class="note ok">
|
|
1308
|
+
<div class="row">
|
|
1309
|
+
<span class="ex-name">Prop types <small>(react-docgen-typescript)</small></span>
|
|
1310
|
+
<span class="badge ok">2 prop types</span>
|
|
1311
|
+
</div>
|
|
1312
|
+
<pre><code>Component: src/divider/divider.tsx::Divider</code></pre>
|
|
1313
|
+
<pre><code>Props:</code></pre>
|
|
1314
|
+
<pre><code>asChild?: boolean
|
|
1315
|
+
|
|
1316
|
+
/**
|
|
1317
|
+
* Optional label rendered inline between two flanking 1px lines. When set,
|
|
1318
|
+
* Divider renders a styled `<div>` (rather than the underlying separator
|
|
1319
|
+
* primitive) so the label can sit centered between the two line segments.
|
|
1320
|
+
*/
|
|
1321
|
+
label?: ReactNode</code></pre>
|
|
1322
|
+
</div>
|
|
1323
|
+
</div>
|
|
1324
|
+
|
|
1325
|
+
<div class="panel panel-stories">
|
|
1326
|
+
|
|
1327
|
+
|
|
1328
|
+
|
|
1329
|
+
<div class="note ok">
|
|
1330
|
+
<div class="row">
|
|
1331
|
+
<span class="ex-name">Imports</span>
|
|
1332
|
+
</div>
|
|
1333
|
+
<pre><code>import { Button, Divider } from "@agentero/design-system";</code></pre>
|
|
1334
|
+
</div>
|
|
1335
|
+
|
|
1336
|
+
|
|
1337
|
+
<div class="note ok">
|
|
1338
|
+
<div class="row">
|
|
1339
|
+
<span class="ex-name">Default</span>
|
|
1340
|
+
<span class="badge ok">story ok</span>
|
|
1341
|
+
</div>
|
|
1342
|
+
<div>Default horizontal decorative divider</div>
|
|
1343
|
+
<div class="hint">The default horizontal, decorative divider — a 1px line that spans the parent width. Use this form between stacked content blocks.</div>
|
|
1344
|
+
<pre><code>const Default = () => <div
|
|
1345
|
+
className={cn(
|
|
1346
|
+
'flex gap-4 rounded-lg border border-border-default-base-primary bg-bg-default-base-primary p-6',
|
|
1347
|
+
args.orientation === 'vertical' ? 'h-40 w-lg items-stretch' : 'w-80 flex-col'
|
|
1348
|
+
)}>
|
|
1349
|
+
<div className="flex flex-1 flex-col justify-center gap-1">
|
|
1350
|
+
<h3 className="text-base font-semibold text-text-default-base-primary">First section</h3>
|
|
1351
|
+
<p className="text-sm text-text-default-base-secondary">Content on one side of the divider, visually separated from the other.
|
|
1352
|
+
</p>
|
|
1353
|
+
</div>
|
|
1354
|
+
<Divider orientation="horizontal" decorative />
|
|
1355
|
+
<div className="flex flex-1 flex-col justify-center gap-1">
|
|
1356
|
+
<h3 className="text-base font-semibold text-text-default-base-primary">Second section</h3>
|
|
1357
|
+
<p className="text-sm text-text-default-base-secondary">Content on the other side of the divider, clearly separated from the first.
|
|
1358
|
+
</p>
|
|
1359
|
+
</div>
|
|
1360
|
+
</div>;</code></pre>
|
|
1361
|
+
</div>
|
|
1362
|
+
<div class="note ok">
|
|
1363
|
+
<div class="row">
|
|
1364
|
+
<span class="ex-name">Horizontal</span>
|
|
1365
|
+
<span class="badge ok">story ok</span>
|
|
1366
|
+
</div>
|
|
1367
|
+
<div>Horizontal 1px line spanning the parent width</div>
|
|
1368
|
+
<div class="hint">Horizontal divider — a 1px line spanning the parent's full width. The default orientation; use to separate stacked content.</div>
|
|
1369
|
+
<pre><code>const Horizontal = () => (
|
|
1370
|
+
<div className="w-80">
|
|
1371
|
+
<Divider />
|
|
1372
|
+
</div>
|
|
1373
|
+
);</code></pre>
|
|
1374
|
+
</div>
|
|
1375
|
+
<div class="note ok">
|
|
1376
|
+
<div class="row">
|
|
1377
|
+
<span class="ex-name">Vertical</span>
|
|
1378
|
+
<span class="badge ok">story ok</span>
|
|
1379
|
+
</div>
|
|
1380
|
+
<div>Vertical 1px line spanning the parent height</div>
|
|
1381
|
+
<div class="hint">Vertical divider — a 1px line spanning the parent's full height. Parent must establish a height (via `h-*` or an intrinsic flex item height) for the line to be visible.</div>
|
|
1382
|
+
<pre><code>const Vertical = () => (
|
|
1383
|
+
<div className="flex h-24 items-stretch">
|
|
1384
|
+
<Divider orientation="vertical" />
|
|
1385
|
+
</div>
|
|
1386
|
+
);</code></pre>
|
|
1387
|
+
</div>
|
|
1388
|
+
<div class="note ok">
|
|
1389
|
+
<div class="row">
|
|
1390
|
+
<span class="ex-name">With Label</span>
|
|
1391
|
+
<span class="badge ok">story ok</span>
|
|
1392
|
+
</div>
|
|
1393
|
+
<div>Horizontal divider with a centered "or" label</div>
|
|
1394
|
+
<div class="hint">Labelled divider. The label sits centered between two flanking 1px lines — a common pattern for "or" breaks between authentication options.</div>
|
|
1395
|
+
<pre><code>const WithLabel = () => <div className="flex w-80 flex-col gap-2">
|
|
1396
|
+
<Button variant="primary">Continue with email</Button>
|
|
1397
|
+
<Divider orientation="horizontal" decorative label="or" />
|
|
1398
|
+
<Button variant="secondary">Continue with SSO</Button>
|
|
1399
|
+
</div>;</code></pre>
|
|
1400
|
+
</div>
|
|
1401
|
+
<div class="note ok">
|
|
1402
|
+
<div class="row">
|
|
1403
|
+
<span class="ex-name">Vertical With Label</span>
|
|
1404
|
+
<span class="badge ok">story ok</span>
|
|
1405
|
+
</div>
|
|
1406
|
+
<div>Vertical divider with a centered label</div>
|
|
1407
|
+
<div class="hint">Vertical divider with a label. The label sits between two stacked 1px line segments; use sparingly — horizontal labelled dividers are more common.</div>
|
|
1408
|
+
<pre><code>const VerticalWithLabel = () => <div
|
|
1409
|
+
className="flex h-40 items-stretch gap-4 rounded-lg border border-border-default-base-primary bg-bg-default-base-primary p-6">
|
|
1410
|
+
<div className="flex flex-col justify-center gap-1">
|
|
1411
|
+
<h3 className="text-sm font-semibold text-text-default-base-primary">Left panel</h3>
|
|
1412
|
+
<p className="text-xs text-text-default-base-secondary">Content on the left side</p>
|
|
1413
|
+
</div>
|
|
1414
|
+
<Divider orientation="vertical" decorative label="OR" />
|
|
1415
|
+
<div className="flex flex-col justify-center gap-1">
|
|
1416
|
+
<h3 className="text-sm font-semibold text-text-default-base-primary">Right panel</h3>
|
|
1417
|
+
<p className="text-xs text-text-default-base-secondary">Content on the right side</p>
|
|
1418
|
+
</div>
|
|
1419
|
+
</div>;</code></pre>
|
|
1420
|
+
</div>
|
|
1421
|
+
<div class="note ok">
|
|
1422
|
+
<div class="row">
|
|
1423
|
+
<span class="ex-name">Semantic</span>
|
|
1424
|
+
<span class="badge ok">story ok</span>
|
|
1425
|
+
</div>
|
|
1426
|
+
<div>Semantic separator announced to assistive technologies</div>
|
|
1427
|
+
<div class="hint">Semantic divider (`decorative={false}`). Exposes `role="separator"` and `aria-orientation` to assistive technologies, marking a meaningful section break rather than a purely visual one.</div>
|
|
1428
|
+
<pre><code>const Semantic = () => <div
|
|
1429
|
+
className="flex w-80 flex-col gap-4 rounded-lg border border-border-default-base-primary bg-bg-default-base-primary p-6">
|
|
1430
|
+
<section className="flex flex-col gap-1">
|
|
1431
|
+
<h3 className="text-base font-semibold text-text-default-base-primary">Section one</h3>
|
|
1432
|
+
<p className="text-sm text-text-default-base-secondary">Semantically separated from the next section for screen readers.
|
|
1433
|
+
</p>
|
|
1434
|
+
</section>
|
|
1435
|
+
<Divider orientation="horizontal" decorative={false} />
|
|
1436
|
+
<section className="flex flex-col gap-1">
|
|
1437
|
+
<h3 className="text-base font-semibold text-text-default-base-primary">Section two</h3>
|
|
1438
|
+
<p className="text-sm text-text-default-base-secondary">Screen readers will announce this as a separate section.
|
|
1439
|
+
</p>
|
|
1440
|
+
</section>
|
|
1441
|
+
</div>;</code></pre>
|
|
1442
|
+
</div>
|
|
1443
|
+
<div class="note ok">
|
|
1444
|
+
<div class="row">
|
|
1445
|
+
<span class="ex-name">In List</span>
|
|
1446
|
+
<span class="badge ok">story ok</span>
|
|
1447
|
+
</div>
|
|
1448
|
+
<div>Horizontal dividers between stacked list rows</div>
|
|
1449
|
+
<div class="hint">Divider between list rows. Dividers delineate each item without the visual weight of a full border on every row.</div>
|
|
1450
|
+
<pre><code>const InList = () => (
|
|
1451
|
+
<div className="w-80 rounded-lg border border-border-default-base-primary bg-bg-default-base-primary">
|
|
1452
|
+
<div className="flex flex-col gap-1 px-4 py-3">
|
|
1453
|
+
<h4 className="text-sm text-text-default-base-primary">Notification 1</h4>
|
|
1454
|
+
<p className="text-xs text-text-default-base-secondary">
|
|
1455
|
+
You have a new message from Jane.
|
|
1456
|
+
</p>
|
|
1457
|
+
</div>
|
|
1458
|
+
<Divider />
|
|
1459
|
+
<div className="flex flex-col gap-1 px-4 py-3">
|
|
1460
|
+
<h4 className="text-sm text-text-default-base-primary">Notification 2</h4>
|
|
1461
|
+
<p className="text-xs text-text-default-base-secondary">
|
|
1462
|
+
Your report is ready to download.
|
|
1463
|
+
</p>
|
|
1464
|
+
</div>
|
|
1465
|
+
<Divider />
|
|
1466
|
+
<div className="flex flex-col gap-1 px-4 py-3">
|
|
1467
|
+
<h4 className="text-sm text-text-default-base-primary">Notification 3</h4>
|
|
1468
|
+
<p className="text-xs text-text-default-base-secondary">
|
|
1469
|
+
System maintenance is scheduled for tonight.
|
|
1470
|
+
</p>
|
|
1471
|
+
</div>
|
|
1472
|
+
</div>
|
|
1473
|
+
);</code></pre>
|
|
1474
|
+
</div>
|
|
1475
|
+
<div class="note ok">
|
|
1476
|
+
<div class="row">
|
|
1477
|
+
<span class="ex-name">In Toolbar</span>
|
|
1478
|
+
<span class="badge ok">story ok</span>
|
|
1479
|
+
</div>
|
|
1480
|
+
<div>Vertical dividers grouping toolbar actions</div>
|
|
1481
|
+
<div class="hint">Vertical dividers grouping related toolbar actions. Use to separate logical clusters of buttons (editing vs. history vs. settings) without visual weight.</div>
|
|
1482
|
+
<pre><code>const InToolbar = () => (
|
|
1483
|
+
<div className="inline-flex h-10 items-center gap-1 rounded-lg border border-border-default-base-primary bg-bg-default-base-primary px-2 shadow-1">
|
|
1484
|
+
<Button variant="ghost" size="xs">
|
|
1485
|
+
Cut
|
|
1486
|
+
</Button>
|
|
1487
|
+
<Button variant="ghost" size="xs">
|
|
1488
|
+
Copy
|
|
1489
|
+
</Button>
|
|
1490
|
+
<Button variant="ghost" size="xs">
|
|
1491
|
+
Paste
|
|
1492
|
+
</Button>
|
|
1493
|
+
<Divider orientation="vertical" className="mx-1 h-6" />
|
|
1494
|
+
<Button variant="ghost" size="xs">
|
|
1495
|
+
Undo
|
|
1496
|
+
</Button>
|
|
1497
|
+
<Button variant="ghost" size="xs">
|
|
1498
|
+
Redo
|
|
1499
|
+
</Button>
|
|
1500
|
+
<Divider orientation="vertical" className="mx-1 h-6" />
|
|
1501
|
+
<Button variant="ghost" size="xs">
|
|
1502
|
+
Settings
|
|
1503
|
+
</Button>
|
|
1504
|
+
</div>
|
|
1505
|
+
);</code></pre>
|
|
1506
|
+
</div>
|
|
1507
|
+
<div class="note ok">
|
|
1508
|
+
<div class="row">
|
|
1509
|
+
<span class="ex-name">Horizontal In Content</span>
|
|
1510
|
+
<span class="badge ok">story ok</span>
|
|
1511
|
+
</div>
|
|
1512
|
+
<div>Horizontal dividers between content sections</div>
|
|
1513
|
+
<div class="hint">Horizontal dividers between content sections in a long-form layout. Helps create visual hierarchy in content-heavy pages.</div>
|
|
1514
|
+
<pre><code>const HorizontalInContent = () => (
|
|
1515
|
+
<div className="flex w-96 flex-col gap-4 p-6">
|
|
1516
|
+
<div className="flex flex-col gap-1">
|
|
1517
|
+
<h3 className="text-base font-semibold text-text-default-base-primary">Section title</h3>
|
|
1518
|
+
<p className="text-sm text-text-default-base-secondary">
|
|
1519
|
+
Descriptive content for the first section. The divider below separates it from the next.
|
|
1520
|
+
</p>
|
|
1521
|
+
</div>
|
|
1522
|
+
<Divider />
|
|
1523
|
+
<div className="flex flex-col gap-1">
|
|
1524
|
+
<h3 className="text-base font-semibold text-text-default-base-primary">Another section</h3>
|
|
1525
|
+
<p className="text-sm text-text-default-base-secondary">
|
|
1526
|
+
The second section is clearly separated from the previous one.
|
|
1527
|
+
</p>
|
|
1528
|
+
</div>
|
|
1529
|
+
<Divider />
|
|
1530
|
+
<div className="flex flex-col gap-1">
|
|
1531
|
+
<h3 className="text-base font-semibold text-text-default-base-primary">Final section</h3>
|
|
1532
|
+
<p className="text-sm text-text-default-base-secondary">
|
|
1533
|
+
Dividers help establish visual hierarchy in content-heavy layouts.
|
|
1534
|
+
</p>
|
|
1535
|
+
</div>
|
|
1536
|
+
</div>
|
|
1537
|
+
);</code></pre>
|
|
1538
|
+
</div>
|
|
1539
|
+
<div class="note ok">
|
|
1540
|
+
<div class="row">
|
|
1541
|
+
<span class="ex-name">Vertical Between Elements</span>
|
|
1542
|
+
<span class="badge ok">story ok</span>
|
|
1543
|
+
</div>
|
|
1544
|
+
<div>Vertical dividers separating inline elements</div>
|
|
1545
|
+
<div class="hint">Vertical dividers between inline elements. Common for separating a row of related controls or inline links without visual weight.</div>
|
|
1546
|
+
<pre><code>const VerticalBetweenElements = () => (
|
|
1547
|
+
<div className="flex items-stretch gap-3">
|
|
1548
|
+
<Button variant="primary" size="sm">
|
|
1549
|
+
Button 1
|
|
1550
|
+
</Button>
|
|
1551
|
+
<Divider orientation="vertical" />
|
|
1552
|
+
<Button variant="primary" size="sm">
|
|
1553
|
+
Button 2
|
|
1554
|
+
</Button>
|
|
1555
|
+
<Divider orientation="vertical" />
|
|
1556
|
+
<Button variant="primary" size="sm">
|
|
1557
|
+
Button 3
|
|
1558
|
+
</Button>
|
|
1559
|
+
</div>
|
|
1560
|
+
);</code></pre>
|
|
1561
|
+
</div>
|
|
1562
|
+
</div>
|
|
1563
|
+
|
|
1564
|
+
</div>
|
|
1565
|
+
</article>
|
|
1271
1566
|
<article
|
|
1272
1567
|
class="card
|
|
1273
1568
|
no-error
|
|
@@ -1280,9 +1575,9 @@ variant?: ButtonVariantType</code></pre>
|
|
|
1280
1575
|
<div class="title">
|
|
1281
1576
|
<h2><span class="status-dot dot-ok"></span> Loading</h2>
|
|
1282
1577
|
<div class="badges">
|
|
1283
|
-
<label for="c-
|
|
1578
|
+
<label for="c-3-components-loading-props" class="badge ok as-toggle">1 prop type</label>
|
|
1284
1579
|
|
|
1285
|
-
<label for="c-
|
|
1580
|
+
<label for="c-3-components-loading-stories" class="badge ok as-toggle">7 stories</label>
|
|
1286
1581
|
|
|
1287
1582
|
</div>
|
|
1288
1583
|
</div>
|
|
@@ -1295,9 +1590,9 @@ variant?: ButtonVariantType</code></pre>
|
|
|
1295
1590
|
<!-- ⬇️ Hidden toggles must be siblings BEFORE .panels -->
|
|
1296
1591
|
|
|
1297
1592
|
|
|
1298
|
-
<input id="c-
|
|
1593
|
+
<input id="c-3-components-loading-stories" class="tg tg-stories" type="checkbox" hidden />
|
|
1299
1594
|
|
|
1300
|
-
<input id="c-
|
|
1595
|
+
<input id="c-3-components-loading-props" class="tg tg-props" type="checkbox" hidden />
|
|
1301
1596
|
|
|
1302
1597
|
<div class="panels">
|
|
1303
1598
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"v":0,"components":{"components-avatar":{"id":"components-avatar","name":"Avatar","path":"./src/avatar/avatar.stories.tsx","stories":[{"id":"components-avatar--default","name":"Default","snippet":"const Default = () => <Avatar fallback=\"JD\" size=\"md\" variant=\"circle\" />;","description":"The default avatar with fallback initials. Renders as a medium circle when no image source is provided.","summary":"Default avatar with fallback initials"},{"id":"components-avatar--with-image","name":"With Image","snippet":"const WithImage = () => <Avatar\n fallback=\"JD\"\n size=\"md\"\n variant=\"circle\"\n src=\"https://images.unsplash.com/photo-1502823403499-6ccfcf4fb453?&w=256&h=256&q=70&crop=focalpoint&fp-x=0.5&fp-y=0.3&fp-z=1&fit=crop\"\n alt=\"Alex Morgan\" />;","description":"Avatar displaying a user profile photo. The image fills the avatar shape and the fallback is hidden while the image loads successfully.","summary":"Avatar with a profile image"},{"id":"components-avatar--with-fallback-initials","name":"With Fallback Initials","snippet":"const WithFallbackInitials = () => <Avatar\n fallback=\"AM\"\n size=\"md\"\n variant=\"circle\"\n src=\"https://broken-url.example/photo.jpg\" />;","description":"When the image fails to load, the fallback content is displayed. Pass initials, an icon, or any ReactNode as the `fallback` prop.","summary":"Fallback content shown when image is unavailable"},{"id":"components-avatar--circle","name":"Circle","snippet":"const Circle = () => <Avatar fallback=\"CR\" size=\"md\" variant=\"circle\" />;","description":"The circle variant is the default shape, ideal for user profile photos.","summary":"Circle-shaped avatar (default)"},{"id":"components-avatar--square","name":"Square","snippet":"const Square = () => <Avatar fallback=\"WS\" size=\"md\" variant=\"square\" />;","description":"The square variant uses a rounded rectangle, suitable for workspace, team, or organization icons.","summary":"Square-shaped avatar for workspaces"},{"id":"components-avatar--pillow","name":"Pillow","snippet":"const Pillow = () => <Avatar fallback=\"PL\" size=\"md\" variant=\"pillow\" />;","description":"The pillow variant uses a soft, organic squircle shape for a friendly and distinctive appearance.","summary":"Pillow-shaped avatar with organic squircle"},{"id":"components-avatar--pentagon","name":"Pentagon","snippet":"const Pentagon = () => <Avatar fallback=\"PT\" size=\"md\" variant=\"pentagon\" />;","description":"The pentagon variant uses a five-sided mask for a unique visual identity. Note: the border is hidden in this variant due to the mask shape.","summary":"Pentagon-shaped avatar for unique identity"},{"id":"components-avatar--size-xs","name":"Size Xs","snippet":"const SizeXs = () => <Avatar fallback=\"XS\" size=\"xs\" variant=\"circle\" />;","description":"Extra-small avatar (24px) for dense lists and inline indicators.","summary":"Extra-small 24px avatar"},{"id":"components-avatar--size-sm","name":"Size Sm","snippet":"const SizeSm = () => <Avatar fallback=\"SM\" size=\"sm\" variant=\"circle\" />;","description":"Small avatar (32px) for compact layouts and table rows.","summary":"Small 32px avatar"},{"id":"components-avatar--size-lg","name":"Size Lg","snippet":"const SizeLg = () => <Avatar fallback=\"LG\" size=\"lg\" variant=\"circle\" />;","description":"Large avatar (48px) for profile sections and detail views.","summary":"Large 48px avatar"},{"id":"components-avatar--size-xl","name":"Size Xl","snippet":"const SizeXl = () => <Avatar fallback=\"XL\" size=\"xl\" variant=\"circle\" />;","description":"Extra-large avatar (64px) for hero sections and prominent display.","summary":"Extra-large 64px avatar"},{"id":"components-avatar--colorized","name":"Colorized","snippet":"const Colorized = () => <Avatar fallback=\"JD\" size=\"md\" variant=\"circle\" colorize=\"jane doe\" />;","description":"The `colorize` prop deterministically maps a string (typically a user name) to a color from the palette, applying a tinted background and matching text color. Useful for distinguishing users in lists without profile photos.","summary":"Colorized avatar based on user name"},{"id":"components-avatar--all-colorized","name":"All Colorized","snippet":"const AllColorized = () => (\n <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>\n {['alice', 'bob', 'carol', 'dave', 'eve', 'frank', 'grace', 'henry', 'iris'].map(name => (\n <Avatar key={name} size=\"lg\" colorize={name} fallback={name.slice(0, 2).toUpperCase()} />\n ))}\n </div>\n);","description":"Multiple colorized avatars showing how different names map to different colors from the palette for visual distinction.","summary":"Multiple colorized avatars for visual distinction"},{"id":"components-avatar--all-sizes","name":"All Sizes","snippet":"const AllSizes = () => (\n <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>\n {(['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl'] as const).map(size => (\n <Avatar key={size} size={size} fallback={size.toUpperCase()} />\n ))}\n </div>\n);","description":"All available sizes displayed together for visual comparison. Sizes range from `xs` (24px) to `4xl` (128px).","summary":"Visual comparison of all avatar sizes"},{"id":"components-avatar--all-sizes-with-image","name":"All Sizes With Image","snippet":"const AllSizesWithImage = () => (\n <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>\n {(['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl'] as const).map(size => (\n <Avatar\n key={size}\n size={size}\n src=\"https://images.unsplash.com/photo-1502823403499-6ccfcf4fb453?&w=256&h=256&q=70&crop=focalpoint&fp-x=0.5&fp-y=0.3&fp-z=1&fit=crop\"\n alt=\"Alex Morgan\"\n fallback=\"AM\"\n />\n ))}\n </div>\n);","description":"All sizes with a profile image to verify image scaling and quality across the full size range from `xs` (24px) to `4xl` (128px).","summary":"All avatar sizes with a profile image"},{"id":"components-avatar--all-variants","name":"All Variants","snippet":"const AllVariants = () => (\n <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>\n {(['circle', 'square', 'pillow', 'pentagon'] as const).map(variant => (\n <Avatar\n key={variant}\n size=\"lg\"\n variant={variant}\n fallback={variant.slice(0, 2).toUpperCase()}\n />\n ))}\n </div>\n);","description":"All available shape variants displayed together for visual comparison. Each variant serves a different use case: user photos, workspaces, friendly branding, and unique identity.","summary":"Visual comparison of all avatar shapes"},{"id":"components-avatar--all-variants-with-image","name":"All Variants With Image","snippet":"const AllVariantsWithImage = () => (\n <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>\n {(['circle', 'square', 'pillow', 'pentagon'] as const).map(variant => (\n <Avatar\n key={variant}\n size=\"lg\"\n variant={variant}\n src=\"https://images.unsplash.com/photo-1502823403499-6ccfcf4fb453?&w=256&h=256&q=70&crop=focalpoint&fp-x=0.5&fp-y=0.3&fp-z=1&fit=crop\"\n alt=\"Alex Morgan\"\n fallback=\"AM\"\n />\n ))}\n </div>\n);","description":"All shape variants with a profile image to show how each mask clips the photo. Particularly useful for verifying the pentagon mask and pillow shape render correctly with real imagery.","summary":"All avatar shapes with a profile image"}],"import":"import { Avatar } from \"@agentero/design-system\";","jsDocTags":{},"description":"Avatar displays a user's profile image, initials, or a fallback icon. Use for user identification in lists, headers, cards, and comment threads. Supports multiple shapes (`circle`, `square`, `pillow`, `pentagon`) and sizes from `xs` (24px) to `4xl` (128px).","reactDocgenTypescript":{"tags":{"summary":"Displays a user's profile image, initials, or fallback icon","example":"<Avatar src=\"/photos/jane.jpg\" alt=\"Jane Doe\" size=\"md\" variant=\"circle\" />\n<Avatar fallback=\"JD\" size=\"lg\" variant=\"square\" />"},"filePath":"/home/runner/work/design-system/design-system/src/avatar/avatar.tsx","description":"Avatar displays a user's profile image, initials, or a fallback icon.\nUse Avatar for user identification in lists, headers, cards, and comment threads.\n\nDo **not** use Avatar for decorative images or thumbnails unrelated to a person\nor entity — use a standard `<img>` or a Thumbnail component instead.\n\nRenders an image when `src` is provided; otherwise displays `fallback` content\n(typically initials or an icon). Built on Radix UI Avatar primitives.\n\nAvailable shapes: `circle` (default), `square`, `pillow`, and `pentagon`.\nSizes range from `xs` (24px) to `4xl` (128px), defaulting to `md` (40px).","displayName":"Avatar","methods":[],"props":{"asChild":{"defaultValue":null,"description":"","name":"asChild","declarations":[{"fileName":"design-system/node_modules/@radix-ui/react-primitive/dist/index.d.mts","name":"TypeLiteral"}],"required":false,"type":{"name":"boolean"}},"alt":{"defaultValue":null,"description":"Accessible alt text describing the avatar image. Required when `src` is provided.","name":"alt","declarations":[{"fileName":"design-system/src/avatar/avatar.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"string"}},"src":{"defaultValue":null,"description":"Image URL to display. When unavailable or loading fails, `fallback` content is shown instead.","name":"src","declarations":[{"fileName":"design-system/src/avatar/avatar.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"string"}},"fallback":{"defaultValue":null,"description":"Content rendered when `src` is missing or fails to load. Typically user initials (e.g., \"JD\") or an icon.","name":"fallback","declarations":[{"fileName":"design-system/src/avatar/avatar.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"ReactNode"}},"colorize":{"defaultValue":null,"description":"When provided, deterministically maps the string (typically a user name) to a\ncolor from the palette, applying a light background, matching text color, and\nborder color. Useful for distinguishing users in lists without profile photos.","name":"colorize","declarations":[{"fileName":"design-system/src/avatar/avatar.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"string"}},"size":{"defaultValue":null,"description":"Controls the avatar dimensions. Defaults to `'md'` (40px).\n- `xs` (24px) — inline indicators, dense lists\n- `sm` (32px) — compact layouts, table rows\n- `md` (40px) — standard usage, cards, headers\n- `lg` (48px) — profile sections, detail views\n- `xl` (64px) — hero sections, prominent display\n- `2xl` (80px), `3xl` (96px), `4xl` (128px) — large feature areas, profile pages","name":"size","declarations":[{"fileName":"design-system/src/avatar/avatar.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"enum","raw":"\"md\" | \"xs\" | \"sm\" | \"lg\" | \"xl\" | \"2xl\" | \"3xl\" | \"4xl\"","value":[{"value":"\"md\""},{"value":"\"xs\""},{"value":"\"sm\""},{"value":"\"lg\""},{"value":"\"xl\""},{"value":"\"2xl\""},{"value":"\"3xl\""},{"value":"\"4xl\""}]}},"variant":{"defaultValue":null,"description":"Shape of the avatar container. Defaults to `'circle'`.\n- `circle` — standard round avatar for user photos\n- `square` — rounded rectangle, suitable for workspace or team icons\n- `pillow` — soft, organic squircle shape\n- `pentagon` — distinctive five-sided shape for unique visual identity","name":"variant","declarations":[{"fileName":"design-system/src/avatar/avatar.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"enum","raw":"\"circle\" | \"square\" | \"pillow\" | \"pentagon\"","value":[{"value":"\"circle\""},{"value":"\"square\""},{"value":"\"pillow\""},{"value":"\"pentagon\""}]}}},"exportName":"Avatar"}},"components-button":{"id":"components-button","name":"Button","path":"./src/button/button.stories.tsx","stories":[{"id":"components-button--default","name":"Default","snippet":"const Default = () => <Button variant=\"primary\" size=\"sm\">{TEXT}</Button>;","description":"Args-controlled playground. Toggle `variant`, `size`, `status`, `loading`, `disabled`, and `rounded` from the Controls panel to explore every visual combination of the Button.","summary":"Default args playground for Button"},{"id":"components-button--variants","name":"Variants","snippet":"const Variants = () => (\n <Row>\n {VARIANTS.map(variant => (\n <Button key={variant} variant={variant}>\n {TEXT}\n </Button>\n ))}\n </Row>\n);","description":"All five variants at the default `sm` size. Variants express visual hierarchy: `primary` for the main CTA, `secondary` / `tertiary` for supporting actions, `ghost` for low-emphasis inline actions, and `link` for text-only actions.","summary":"All Button variants at default size"},{"id":"components-button--sizes","name":"Sizes","snippet":"const Sizes = () => (\n <Row>\n {SIZES.map(size => (\n <Button key={size} size={size}>\n {TEXT}\n </Button>\n ))}\n </Row>\n);","description":"All four sizes at the default `primary` variant. Sizes scale from `xs` (24px) for dense toolbars up to `lg` (48px) for hero CTAs.","summary":"All Button sizes at default variant"},{"id":"components-button--disabled","name":"Disabled","snippet":"const Disabled = () => (\n <Row>\n {VARIANTS.map(variant => (\n <Button asChild key={variant} variant={variant} disabled>\n <a>{TEXT}</a>\n </Button>\n ))}\n </Row>\n);","description":"Disabled state across all variants. Rendered via `asChild` with `<a>` children to show the disabled treatment applied via className — native anchors ignore the `disabled` attribute, so Button emits `aria-disabled` and `data-disabled` on the child instead.","summary":"Disabled treatment for every variant"},{"id":"components-button--with-icons","name":"With Icons","snippet":"const WithIcons = () => (\n <Stack>\n {VARIANTS.map(variant => (\n <Row key={variant}>\n {SIZES.map(size => (\n <Button key={size} variant={variant} size={size}>\n <IconAdd />\n {TEXT}\n <IconAdd />\n </Button>\n ))}\n </Row>\n ))}\n </Stack>\n);","description":"Variant × size grid with leading and trailing icons.","summary":"Variant × size grid with leading + trailing icons"},{"id":"components-button--only-icon","name":"Only Icon","snippet":"const OnlyIcon = () => (\n <Stack>\n {NON_LINK_VARIANTS.map(variant => (\n <Row key={variant}>\n {SIZES.map(size => (\n <Button key={size} variant={variant} size={size} aria-label=\"Close\">\n <IconClose />\n </Button>\n ))}\n </Row>\n ))}\n </Stack>\n);","description":"Icon-only buttons across the variant × size grid. Excludes `variant=\"link\"` — combining `link` with icon-only children logs a dev-only warning because the link treatment has no padding to accommodate an icon alone.","summary":"Icon-only Button across variant × size (excluding `link`)"},{"id":"components-button--loading","name":"Loading","snippet":"const Loading = () => (\n <Stack>\n {NON_LINK_VARIANTS.map(variant => (\n <Row key={variant}>\n {SIZES.map(size => (\n <div key={size} style={{ display: 'flex', gap: '0.5rem', alignItems: 'center' }}>\n <Button variant={variant} size={size} loading aria-label=\"Loading\">\n <IconAdd />\n </Button>\n <Button variant={variant} size={size} loading>\n {TEXT}\n </Button>\n </div>\n ))}\n </Row>\n ))}\n </Stack>\n);","description":"Loading state across the variant × size grid. Each row shows two buttons per size: one icon-only, one with text. Loading forces `disabled` and overlays a spinner that inherits the variant's text color. Excludes `variant=\"link\"` — combining `link` with `loading` logs a dev-only warning.","summary":"Loading state across variant × size (excluding `link`)"},{"id":"components-button--status","name":"Status","snippet":"const Status = () => (\n <Stack>\n <Row>\n {VARIANTS.map(variant => (\n <Button key={variant} variant={variant} status=\"danger\">\n <IconAdd />\n {TEXT}\n <IconAdd />\n </Button>\n ))}\n </Row>\n <Row>\n {VARIANTS.map(variant => (\n <Button asChild key={variant} variant={variant} status=\"danger\" disabled>\n <a>\n <IconAdd />\n {TEXT}\n <IconAdd />\n </a>\n </Button>\n ))}\n </Row>\n </Stack>\n);","description":"Destructive treatment via `status=\"danger\"`. The top row shows every variant enabled; the bottom row shows every variant disabled. Use `status=\"danger\"` for delete, remove, or disconnect actions regardless of variant.","summary":"`status=\"danger\"` across every variant, enabled + disabled"},{"id":"components-button--rounded","name":"Rounded","snippet":"const Rounded = () => (\n <Stack>\n {NON_LINK_VARIANTS.map(variant => (\n <Row key={variant}>\n {SIZES.map(size => (\n <Button key={size} variant={variant} size={size} rounded>\n <IconAdd />\n {TEXT}\n <IconAdd />\n </Button>\n ))}\n </Row>\n ))}\n </Stack>\n);","description":"Fully pill-shaped buttons across the variant × size grid. Excludes `variant=\"link\"` since the link treatment has no background to round.","summary":"`rounded` pill shape across variant × size (excluding `link`)"},{"id":"components-button--as-child","name":"As Child","snippet":"const AsChild = () => (\n <Row>\n <Button asChild variant=\"primary\">\n <a href=\"/dashboard\">Go to dashboard</a>\n </Button>\n <Button asChild variant=\"secondary\">\n <a href=\"https://agentero.com\" target=\"_blank\" rel=\"noreferrer\">\n Visit Agentero\n </a>\n </Button>\n </Row>\n);","description":"`asChild` renders Button's styles on the nested child element rather than on a `<button>` — the child receives Button's `className`, `ref`, and merged props via Radix's `Slot` primitive. Use it to turn any anchor or framework `Link` into a Button without coupling the design system to a router. In app code, swap the plain `<a>` below for your framework's Link (`next/link`, `react-router`, `@tanstack/react-router`, etc.).","summary":"`asChild` composes Button's styles onto any element"}],"import":"import { Button } from \"@agentero/design-system\";","jsDocTags":{},"description":"Button is the design system's primary actionable control. Pick `variant` to express hierarchy, `size` for prominence, and `status=\"danger\"` for destructive actions. Pass `asChild` to render Button's styles on any nested element — a plain `<a>`, a framework `<Link>`, or a custom component — without Button binding to any particular framework.","reactDocgenTypescript":{"tags":{"summary":"Primary actionable control; renders a `<button>` or, with `asChild`, any nested element","example":"<Button variant=\"primary\" size=\"sm\" onClick={handleSave}>\n Save changes\n</Button>\n<Button asChild variant=\"secondary\">\n <a href=\"https://agentero.com\" target=\"_blank\" rel=\"noreferrer\">Visit Agentero</a>\n</Button>\n// Framework-agnostic: wrap any Link implementation\n<Button asChild variant=\"primary\">\n <Link href=\"/dashboard\">Go to dashboard</Link>\n</Button>\n<Button variant=\"primary\" status=\"danger\" loading={isDeleting} onClick={handleDelete}>\n Delete account\n</Button>"},"filePath":"/home/runner/work/design-system/design-system/src/button/button.tsx","description":"Button is the design system's primary actionable control. Use it for any\ninteraction that triggers behavior, submits a form, or navigates the user.\nBy default Button renders a `<button>`; pass `asChild` to render its single\nchild element as the underlying tag instead — Button merges its styles,\n`className`, `ref`, and props onto whatever the consumer nests. This keeps\nthe design system framework-agnostic: route a plain `<a>`, a Next.js\n`<Link>`, a React Router `<Link>`, or any custom element through the same\nvisual treatment.\n\nPick `variant` to express hierarchy (`primary` for the main CTA,\n`secondary` / `tertiary` for supporting actions, `ghost` for low-emphasis\ninline actions, `link` for text-only actions). Use `status=\"danger\"` for\ndestructive actions and `loading` to block interaction while async work\nresolves.\n\nDo **not** use Button for toggle states (prefer a Switch or ToggleButton),\nfor passive decorative anchors without action intent (use a plain `<a>`),\nor with `variant=\"link\"` when loading or when the button has no text\nchildren — both combinations log a dev-only warning (silent in production).","displayName":"Button","methods":[],"props":{"children":{"defaultValue":null,"description":"Content rendered inside the Button. Accepts a text label, icon elements,\nor any mix of both. Icon-only children switch the Button to a square\naspect ratio and trigger the icon-only layout.\n\nWhen `asChild` is set, the single child element is merged with Button's\nprops and styles; auto-detection of icon-only children is skipped — use\nthe `iconOnly` prop to opt into the square icon-only layout.\n\nNot supported with `variant=\"link\"` when children resolve to icons only\n— passing both logs a dev-only warning (silent in production).","name":"children","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"},{"fileName":"design-system/node_modules/@types/react/index.d.ts","name":"DOMAttributes"}],"required":false,"type":{"name":"ReactNode"}},"variant":{"defaultValue":null,"description":"Visual hierarchy. Defaults to `'primary'`.\n- `primary` — main call-to-action; use once per view.\n- `secondary` — alternative action alongside a primary button.\n- `tertiary` — low-emphasis action, subtle background.\n- `ghost` — minimal background; low-emphasis action in dense layouts.\n- `link` — inline text-style action; no padding or background.","name":"variant","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"enum","raw":"ButtonVariantType","value":[{"value":"\"link\""},{"value":"\"primary\""},{"value":"\"secondary\""},{"value":"\"tertiary\""},{"value":"\"ghost\""}]}},"size":{"defaultValue":null,"description":"Control size. Defaults to `'sm'`.\n- `xs` (24px) — dense toolbars, compact inline actions.\n- `sm` (32px) — standard usage in forms and cards.\n- `md` (40px) — prominent actions in modals or feature rows.\n- `lg` (48px) — hero CTAs and full-width mobile actions.","name":"size","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"enum","raw":"ButtonSizeType","value":[{"value":"\"md\""},{"value":"\"xs\""},{"value":"\"sm\""},{"value":"\"lg\""}]}},"status":{"defaultValue":null,"description":"Semantic status override. Set to `'danger'` for destructive actions\n(delete, remove, disconnect) — applies the destructive color treatment\nacross all variants.","name":"status","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"enum","raw":"\"danger\"","value":[{"value":"\"danger\""}]}},"loading":{"defaultValue":null,"description":"When `true`, shows a spinner overlay and forces the button into a disabled\nstate to block further interaction. Not supported with `variant=\"link\"` —\npassing both logs a dev-only warning (silent in production).","name":"loading","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"boolean"}},"disabled":{"defaultValue":null,"description":"Disables interaction and applies the disabled color treatment. Applied\nvia className so it still affects anchors rendered via `asChild`, which\nignore the native `disabled` attribute — in that case `aria-disabled`\nand `data-disabled` are forwarded to the child element instead.","name":"disabled","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"},{"fileName":"design-system/node_modules/@types/react/index.d.ts","name":"ButtonHTMLAttributes"}],"required":false,"type":{"name":"boolean"}},"iconOnly":{"defaultValue":null,"description":"Forces the icon-only layout (square aspect ratio, no min-width). Useful\nwith `asChild` where the single wrapper child prevents auto-detection.\nFor non-`asChild` usage, prefer passing icon elements as children — the\nicon-only layout is applied automatically.","name":"iconOnly","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"boolean"}},"rounded":{"defaultValue":null,"description":"When `true`, renders a fully pill-shaped button (rounded-full). Otherwise\nuses the variant's default corner radius.","name":"rounded","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"boolean"}},"align":{"defaultValue":null,"description":"Justifies children along the main axis. Defaults to `'center'`.\nUse `'justify'` to push leading and trailing icons to the edges.","name":"align","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"enum","raw":"\"center\" | \"start\" | \"end\" | \"justify\"","value":[{"value":"\"center\""},{"value":"\"start\""},{"value":"\"end\""},{"value":"\"justify\""}]}},"fitContent":{"defaultValue":null,"description":"When `true`, removes the per-size `min-width` floor so the button hugs\nits content. Useful for inline actions inside tight containers.","name":"fitContent","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"boolean"}},"ref":{"defaultValue":null,"description":"Ref forwarded to the underlying element. Typed as a union covering both\n`<button>` and `<a>` because `asChild` lets consumers render either tag\n(or any forwardRef component) through Radix's `Slot`.","name":"ref","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"Ref<HTMLButtonElement | HTMLAnchorElement>"}},"asChild":{"defaultValue":null,"description":"When `true`, Button clones its single child element and merges\nButton's `className`, `ref`, and event handlers onto it rather than\nrendering a `<button>`. Use this to style any element (a plain `<a>`,\na framework `Link`, a `React.forwardRef` component) as a Button.\n\nWhen combined with `disabled`, Button emits `aria-disabled` and\n`data-disabled` on the child instead of the native `disabled`\nattribute (which is ignored by non-form-control elements).","name":"asChild","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"boolean"}}},"exportName":"Button"}},"components-loading":{"id":"components-loading","name":"Loading","path":"./src/loading/loading.stories.tsx","stories":[{"id":"components-loading--default","name":"Default","snippet":"const Default = () => <Loading size=\"sm\" />;","description":"The default spinner at `size=\"sm\"` (1em diameter), inheriting the current text color. Matches the out-of-the-box behavior when Loading is dropped into any layout.","summary":"Default spinner at the `sm` size"},{"id":"components-loading--size-sm","name":"Size Sm","snippet":"const SizeSm = () => <Loading size=\"sm\" />;","description":"Small spinner (1em diameter) — the default. Ideal for inline indicators, buttons, and compact layouts where the spinner needs to sit next to text.","summary":"Small 1em spinner for inline indicators"},{"id":"components-loading--size-md","name":"Size Md","snippet":"const SizeMd = () => <Loading size=\"md\" />;","description":"Medium spinner (1.5em diameter). Use for cards, panels, and standalone loading states where the spinner is the primary visual signal.","summary":"Medium 1.5em spinner for cards and panels"},{"id":"components-loading--size-lg","name":"Size Lg","snippet":"const SizeLg = () => <Loading size=\"lg\" />;","description":"Large spinner (2em diameter). Use for page-level or section-level loading where the spinner needs more visual weight.","summary":"Large 2em spinner for page or section loading"},{"id":"components-loading--sizes","name":"Sizes","snippet":"const Sizes = () => (\n <div style={{ display: 'flex', alignItems: 'center', gap: '2rem' }}>\n {(['sm', 'md', 'lg'] as const).map(size => (\n <Loading key={size} size={size} />\n ))}\n </div>\n);","description":"All three sizes rendered side by side for visual comparison of the `em`-based scaling. Each spinner inherits the same parent text color.","summary":"Visual comparison of all three spinner sizes"},{"id":"components-loading--inherits-color","name":"Inherits Color","snippet":"const InheritsColor = () => (\n <div style={{ display: 'flex', alignItems: 'center', gap: '2rem' }}>\n <div className=\"text-text-default-base-primary\">\n <Loading size=\"md\" />\n </div>\n <div className=\"text-text-default-brand-primary\">\n <Loading size=\"md\" />\n </div>\n <div className=\"text-text-default-danger-primary\">\n <Loading size=\"md\" />\n </div>\n </div>\n);","description":"The spinner color tracks the parent `color` (text color) via `border-current`. Wrap Loading in any element with a text color utility — or set `color` on Loading itself — and the spinner adopts that color without extra props.","summary":"Spinner color inherits from the parent text color"},{"id":"components-loading--on-dark-surface","name":"On Dark Surface","snippet":"const OnDarkSurface = () => (\n <div className=\"flex items-center gap-8 rounded-lg bg-bg-button-primary-enable p-8 text-text-default-base-inverse-primary\">\n <Loading size=\"sm\" />\n <Loading size=\"md\" />\n <Loading size=\"lg\" />\n </div>\n);","description":"Spinner on a dark surface to verify `border-current` contrast. The parent sets a light text color, which the spinner inherits so it remains visible against the dark background.","summary":"Spinner on a dark-background surface"}],"import":"import { Loading } from \"@agentero/design-system\";","jsDocTags":{},"description":"Loading displays a circular spinner that indicates an in-progress operation. Use for inline fetch, form submission, or asynchronous task indicators. The spinner inherits its color from the parent `color` and scales with the parent font size via `em`-based size variants (`sm`, `md`, `lg`).","reactDocgenTypescript":{"tags":{"summary":"Circular spinner for in-progress and loading states","example":"<Loading />\n<Loading size=\"lg\" className=\"text-text-default-brand-primary\" />"},"filePath":"/home/runner/work/design-system/design-system/src/loading/loading.tsx","description":"Loading displays a circular spinner that indicates an in-progress operation.\nUse Loading to signal that content is being fetched, a form is submitting,\nor any asynchronous task is running inline with surrounding content.\n\nThe spinner inherits its color from the parent `color` (text color) via\n`border-current`, so it adapts to the surrounding context without extra\nprops. It fades in on mount and spins continuously until unmounted.\n\nAvailable sizes: `sm` (1em, default), `md` (1.5em), and `lg` (2em). Each\nsize is expressed in `em` units so the spinner scales with the parent\nfont size — wrap the Loading (or its ancestor) with the appropriate\n`text-[size]` utility to override the absolute diameter.\n\nExposes `role=\"status\"` and `aria-label=\"Loading\"` for screen readers, and\n`data-slot=\"loading\"` for styling hooks.\n\nDo **not** use Loading as the busy indicator for a button — the Button\ncomponent has its own built-in loading overlay ([Button](?path=/docs/button--docs)).\nFor full-page or skeleton loading states prefer a dedicated skeleton\nplaceholder instead of a spinner.","displayName":"Loading","methods":[],"props":{"size":{"defaultValue":null,"description":"Controls the spinner diameter in `em` units relative to the parent font size.\nDefaults to `'sm'`.\n- `sm` (1em) — inline indicators, buttons, and compact layouts\n- `md` (1.5em) — cards, panels, and standalone loading states\n- `lg` (2em) — page-level or section-level loading","name":"size","declarations":[{"fileName":"design-system/src/loading/loading.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"enum","raw":"\"md\" | \"sm\" | \"lg\"","value":[{"value":"\"md\""},{"value":"\"sm\""},{"value":"\"lg\""}]}}},"exportName":"Loading"}}},"meta":{"docgen":"react-docgen-typescript","durationMs":1666}}
|
|
1
|
+
{"v":0,"components":{"components-avatar":{"id":"components-avatar","name":"Avatar","path":"./src/avatar/avatar.stories.tsx","stories":[{"id":"components-avatar--default","name":"Default","snippet":"const Default = () => <Avatar fallback=\"JD\" size=\"md\" variant=\"circle\" />;","description":"The default avatar with fallback initials. Renders as a medium circle when no image source is provided.","summary":"Default avatar with fallback initials"},{"id":"components-avatar--with-image","name":"With Image","snippet":"const WithImage = () => <Avatar\n fallback=\"JD\"\n size=\"md\"\n variant=\"circle\"\n src=\"https://images.unsplash.com/photo-1502823403499-6ccfcf4fb453?&w=256&h=256&q=70&crop=focalpoint&fp-x=0.5&fp-y=0.3&fp-z=1&fit=crop\"\n alt=\"Alex Morgan\" />;","description":"Avatar displaying a user profile photo. The image fills the avatar shape and the fallback is hidden while the image loads successfully.","summary":"Avatar with a profile image"},{"id":"components-avatar--with-fallback-initials","name":"With Fallback Initials","snippet":"const WithFallbackInitials = () => <Avatar\n fallback=\"AM\"\n size=\"md\"\n variant=\"circle\"\n src=\"https://broken-url.example/photo.jpg\" />;","description":"When the image fails to load, the fallback content is displayed. Pass initials, an icon, or any ReactNode as the `fallback` prop.","summary":"Fallback content shown when image is unavailable"},{"id":"components-avatar--circle","name":"Circle","snippet":"const Circle = () => <Avatar fallback=\"CR\" size=\"md\" variant=\"circle\" />;","description":"The circle variant is the default shape, ideal for user profile photos.","summary":"Circle-shaped avatar (default)"},{"id":"components-avatar--square","name":"Square","snippet":"const Square = () => <Avatar fallback=\"WS\" size=\"md\" variant=\"square\" />;","description":"The square variant uses a rounded rectangle, suitable for workspace, team, or organization icons.","summary":"Square-shaped avatar for workspaces"},{"id":"components-avatar--pillow","name":"Pillow","snippet":"const Pillow = () => <Avatar fallback=\"PL\" size=\"md\" variant=\"pillow\" />;","description":"The pillow variant uses a soft, organic squircle shape for a friendly and distinctive appearance.","summary":"Pillow-shaped avatar with organic squircle"},{"id":"components-avatar--pentagon","name":"Pentagon","snippet":"const Pentagon = () => <Avatar fallback=\"PT\" size=\"md\" variant=\"pentagon\" />;","description":"The pentagon variant uses a five-sided mask for a unique visual identity. Note: the border is hidden in this variant due to the mask shape.","summary":"Pentagon-shaped avatar for unique identity"},{"id":"components-avatar--size-xs","name":"Size Xs","snippet":"const SizeXs = () => <Avatar fallback=\"XS\" size=\"xs\" variant=\"circle\" />;","description":"Extra-small avatar (24px) for dense lists and inline indicators.","summary":"Extra-small 24px avatar"},{"id":"components-avatar--size-sm","name":"Size Sm","snippet":"const SizeSm = () => <Avatar fallback=\"SM\" size=\"sm\" variant=\"circle\" />;","description":"Small avatar (32px) for compact layouts and table rows.","summary":"Small 32px avatar"},{"id":"components-avatar--size-lg","name":"Size Lg","snippet":"const SizeLg = () => <Avatar fallback=\"LG\" size=\"lg\" variant=\"circle\" />;","description":"Large avatar (48px) for profile sections and detail views.","summary":"Large 48px avatar"},{"id":"components-avatar--size-xl","name":"Size Xl","snippet":"const SizeXl = () => <Avatar fallback=\"XL\" size=\"xl\" variant=\"circle\" />;","description":"Extra-large avatar (64px) for hero sections and prominent display.","summary":"Extra-large 64px avatar"},{"id":"components-avatar--colorized","name":"Colorized","snippet":"const Colorized = () => <Avatar fallback=\"JD\" size=\"md\" variant=\"circle\" colorize=\"jane doe\" />;","description":"The `colorize` prop deterministically maps a string (typically a user name) to a color from the palette, applying a tinted background and matching text color. Useful for distinguishing users in lists without profile photos.","summary":"Colorized avatar based on user name"},{"id":"components-avatar--all-colorized","name":"All Colorized","snippet":"const AllColorized = () => (\n <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>\n {['alice', 'bob', 'carol', 'dave', 'eve', 'frank', 'grace', 'henry', 'iris'].map(name => (\n <Avatar key={name} size=\"lg\" colorize={name} fallback={name.slice(0, 2).toUpperCase()} />\n ))}\n </div>\n);","description":"Multiple colorized avatars showing how different names map to different colors from the palette for visual distinction.","summary":"Multiple colorized avatars for visual distinction"},{"id":"components-avatar--all-sizes","name":"All Sizes","snippet":"const AllSizes = () => (\n <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>\n {(['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl'] as const).map(size => (\n <Avatar key={size} size={size} fallback={size.toUpperCase()} />\n ))}\n </div>\n);","description":"All available sizes displayed together for visual comparison. Sizes range from `xs` (24px) to `4xl` (128px).","summary":"Visual comparison of all avatar sizes"},{"id":"components-avatar--all-sizes-with-image","name":"All Sizes With Image","snippet":"const AllSizesWithImage = () => (\n <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>\n {(['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl'] as const).map(size => (\n <Avatar\n key={size}\n size={size}\n src=\"https://images.unsplash.com/photo-1502823403499-6ccfcf4fb453?&w=256&h=256&q=70&crop=focalpoint&fp-x=0.5&fp-y=0.3&fp-z=1&fit=crop\"\n alt=\"Alex Morgan\"\n fallback=\"AM\"\n />\n ))}\n </div>\n);","description":"All sizes with a profile image to verify image scaling and quality across the full size range from `xs` (24px) to `4xl` (128px).","summary":"All avatar sizes with a profile image"},{"id":"components-avatar--all-variants","name":"All Variants","snippet":"const AllVariants = () => (\n <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>\n {(['circle', 'square', 'pillow', 'pentagon'] as const).map(variant => (\n <Avatar\n key={variant}\n size=\"lg\"\n variant={variant}\n fallback={variant.slice(0, 2).toUpperCase()}\n />\n ))}\n </div>\n);","description":"All available shape variants displayed together for visual comparison. Each variant serves a different use case: user photos, workspaces, friendly branding, and unique identity.","summary":"Visual comparison of all avatar shapes"},{"id":"components-avatar--all-variants-with-image","name":"All Variants With Image","snippet":"const AllVariantsWithImage = () => (\n <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>\n {(['circle', 'square', 'pillow', 'pentagon'] as const).map(variant => (\n <Avatar\n key={variant}\n size=\"lg\"\n variant={variant}\n src=\"https://images.unsplash.com/photo-1502823403499-6ccfcf4fb453?&w=256&h=256&q=70&crop=focalpoint&fp-x=0.5&fp-y=0.3&fp-z=1&fit=crop\"\n alt=\"Alex Morgan\"\n fallback=\"AM\"\n />\n ))}\n </div>\n);","description":"All shape variants with a profile image to show how each mask clips the photo. Particularly useful for verifying the pentagon mask and pillow shape render correctly with real imagery.","summary":"All avatar shapes with a profile image"}],"import":"import { Avatar } from \"@agentero/design-system\";","jsDocTags":{},"description":"Avatar displays a user's profile image, initials, or a fallback icon. Use for user identification in lists, headers, cards, and comment threads. Supports multiple shapes (`circle`, `square`, `pillow`, `pentagon`) and sizes from `xs` (24px) to `4xl` (128px).","reactDocgenTypescript":{"tags":{"summary":"Displays a user's profile image, initials, or fallback icon","example":"<Avatar src=\"/photos/jane.jpg\" alt=\"Jane Doe\" size=\"md\" variant=\"circle\" />\n<Avatar fallback=\"JD\" size=\"lg\" variant=\"square\" />"},"filePath":"/home/runner/work/design-system/design-system/src/avatar/avatar.tsx","description":"Avatar displays a user's profile image, initials, or a fallback icon.\nUse Avatar for user identification in lists, headers, cards, and comment threads.\n\nDo **not** use Avatar for decorative images or thumbnails unrelated to a person\nor entity — use a standard `<img>` or a Thumbnail component instead.\n\nRenders an image when `src` is provided; otherwise displays `fallback` content\n(typically initials or an icon). Built on Radix UI Avatar primitives.\n\nAvailable shapes: `circle` (default), `square`, `pillow`, and `pentagon`.\nSizes range from `xs` (24px) to `4xl` (128px), defaulting to `md` (40px).","displayName":"Avatar","methods":[],"props":{"asChild":{"defaultValue":null,"description":"","name":"asChild","declarations":[{"fileName":"design-system/node_modules/@radix-ui/react-primitive/dist/index.d.mts","name":"TypeLiteral"}],"required":false,"type":{"name":"boolean"}},"alt":{"defaultValue":null,"description":"Accessible alt text describing the avatar image. Required when `src` is provided.","name":"alt","declarations":[{"fileName":"design-system/src/avatar/avatar.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"string"}},"src":{"defaultValue":null,"description":"Image URL to display. When unavailable or loading fails, `fallback` content is shown instead.","name":"src","declarations":[{"fileName":"design-system/src/avatar/avatar.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"string"}},"fallback":{"defaultValue":null,"description":"Content rendered when `src` is missing or fails to load. Typically user initials (e.g., \"JD\") or an icon.","name":"fallback","declarations":[{"fileName":"design-system/src/avatar/avatar.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"ReactNode"}},"colorize":{"defaultValue":null,"description":"When provided, deterministically maps the string (typically a user name) to a\ncolor from the palette, applying a light background, matching text color, and\nborder color. Useful for distinguishing users in lists without profile photos.","name":"colorize","declarations":[{"fileName":"design-system/src/avatar/avatar.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"string"}},"size":{"defaultValue":null,"description":"Controls the avatar dimensions. Defaults to `'md'` (40px).\n- `xs` (24px) — inline indicators, dense lists\n- `sm` (32px) — compact layouts, table rows\n- `md` (40px) — standard usage, cards, headers\n- `lg` (48px) — profile sections, detail views\n- `xl` (64px) — hero sections, prominent display\n- `2xl` (80px), `3xl` (96px), `4xl` (128px) — large feature areas, profile pages","name":"size","declarations":[{"fileName":"design-system/src/avatar/avatar.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"enum","raw":"\"md\" | \"xs\" | \"sm\" | \"lg\" | \"xl\" | \"2xl\" | \"3xl\" | \"4xl\"","value":[{"value":"\"md\""},{"value":"\"xs\""},{"value":"\"sm\""},{"value":"\"lg\""},{"value":"\"xl\""},{"value":"\"2xl\""},{"value":"\"3xl\""},{"value":"\"4xl\""}]}},"variant":{"defaultValue":null,"description":"Shape of the avatar container. Defaults to `'circle'`.\n- `circle` — standard round avatar for user photos\n- `square` — rounded rectangle, suitable for workspace or team icons\n- `pillow` — soft, organic squircle shape\n- `pentagon` — distinctive five-sided shape for unique visual identity","name":"variant","declarations":[{"fileName":"design-system/src/avatar/avatar.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"enum","raw":"\"circle\" | \"square\" | \"pillow\" | \"pentagon\"","value":[{"value":"\"circle\""},{"value":"\"square\""},{"value":"\"pillow\""},{"value":"\"pentagon\""}]}}},"exportName":"Avatar"}},"components-button":{"id":"components-button","name":"Button","path":"./src/button/button.stories.tsx","stories":[{"id":"components-button--default","name":"Default","snippet":"const Default = () => <Button variant=\"primary\" size=\"sm\">{TEXT}</Button>;","description":"Args-controlled playground. Toggle `variant`, `size`, `status`, `loading`, `disabled`, and `rounded` from the Controls panel to explore every visual combination of the Button.","summary":"Default args playground for Button"},{"id":"components-button--variants","name":"Variants","snippet":"const Variants = () => (\n <Row>\n {VARIANTS.map(variant => (\n <Button key={variant} variant={variant}>\n {TEXT}\n </Button>\n ))}\n </Row>\n);","description":"All five variants at the default `sm` size. Variants express visual hierarchy: `primary` for the main CTA, `secondary` / `tertiary` for supporting actions, `ghost` for low-emphasis inline actions, and `link` for text-only actions.","summary":"All Button variants at default size"},{"id":"components-button--sizes","name":"Sizes","snippet":"const Sizes = () => (\n <Row>\n {SIZES.map(size => (\n <Button key={size} size={size}>\n {TEXT}\n </Button>\n ))}\n </Row>\n);","description":"All four sizes at the default `primary` variant. Sizes scale from `xs` (24px) for dense toolbars up to `lg` (48px) for hero CTAs.","summary":"All Button sizes at default variant"},{"id":"components-button--disabled","name":"Disabled","snippet":"const Disabled = () => (\n <Row>\n {VARIANTS.map(variant => (\n <Button asChild key={variant} variant={variant} disabled>\n <a>{TEXT}</a>\n </Button>\n ))}\n </Row>\n);","description":"Disabled state across all variants. Rendered via `asChild` with `<a>` children to show the disabled treatment applied via className — native anchors ignore the `disabled` attribute, so Button emits `aria-disabled` and `data-disabled` on the child instead.","summary":"Disabled treatment for every variant"},{"id":"components-button--with-icons","name":"With Icons","snippet":"const WithIcons = () => (\n <Stack>\n {VARIANTS.map(variant => (\n <Row key={variant}>\n {SIZES.map(size => (\n <Button key={size} variant={variant} size={size}>\n <IconAdd />\n {TEXT}\n <IconAdd />\n </Button>\n ))}\n </Row>\n ))}\n </Stack>\n);","description":"Variant × size grid with leading and trailing icons.","summary":"Variant × size grid with leading + trailing icons"},{"id":"components-button--only-icon","name":"Only Icon","snippet":"const OnlyIcon = () => (\n <Stack>\n {NON_LINK_VARIANTS.map(variant => (\n <Row key={variant}>\n {SIZES.map(size => (\n <Button key={size} variant={variant} size={size} aria-label=\"Close\">\n <IconClose />\n </Button>\n ))}\n </Row>\n ))}\n </Stack>\n);","description":"Icon-only buttons across the variant × size grid. Excludes `variant=\"link\"` — combining `link` with icon-only children logs a dev-only warning because the link treatment has no padding to accommodate an icon alone.","summary":"Icon-only Button across variant × size (excluding `link`)"},{"id":"components-button--loading","name":"Loading","snippet":"const Loading = () => (\n <Stack>\n {NON_LINK_VARIANTS.map(variant => (\n <Row key={variant}>\n {SIZES.map(size => (\n <div key={size} style={{ display: 'flex', gap: '0.5rem', alignItems: 'center' }}>\n <Button variant={variant} size={size} loading aria-label=\"Loading\">\n <IconAdd />\n </Button>\n <Button variant={variant} size={size} loading>\n {TEXT}\n </Button>\n </div>\n ))}\n </Row>\n ))}\n </Stack>\n);","description":"Loading state across the variant × size grid. Each row shows two buttons per size: one icon-only, one with text. Loading forces `disabled` and overlays a spinner that inherits the variant's text color. Excludes `variant=\"link\"` — combining `link` with `loading` logs a dev-only warning.","summary":"Loading state across variant × size (excluding `link`)"},{"id":"components-button--status","name":"Status","snippet":"const Status = () => (\n <Stack>\n <Row>\n {VARIANTS.map(variant => (\n <Button key={variant} variant={variant} status=\"danger\">\n <IconAdd />\n {TEXT}\n <IconAdd />\n </Button>\n ))}\n </Row>\n <Row>\n {VARIANTS.map(variant => (\n <Button asChild key={variant} variant={variant} status=\"danger\" disabled>\n <a>\n <IconAdd />\n {TEXT}\n <IconAdd />\n </a>\n </Button>\n ))}\n </Row>\n </Stack>\n);","description":"Destructive treatment via `status=\"danger\"`. The top row shows every variant enabled; the bottom row shows every variant disabled. Use `status=\"danger\"` for delete, remove, or disconnect actions regardless of variant.","summary":"`status=\"danger\"` across every variant, enabled + disabled"},{"id":"components-button--rounded","name":"Rounded","snippet":"const Rounded = () => (\n <Stack>\n {NON_LINK_VARIANTS.map(variant => (\n <Row key={variant}>\n {SIZES.map(size => (\n <Button key={size} variant={variant} size={size} rounded>\n <IconAdd />\n {TEXT}\n <IconAdd />\n </Button>\n ))}\n </Row>\n ))}\n </Stack>\n);","description":"Fully pill-shaped buttons across the variant × size grid. Excludes `variant=\"link\"` since the link treatment has no background to round.","summary":"`rounded` pill shape across variant × size (excluding `link`)"},{"id":"components-button--as-child","name":"As Child","snippet":"const AsChild = () => (\n <Row>\n <Button asChild variant=\"primary\">\n <a href=\"/dashboard\">Go to dashboard</a>\n </Button>\n <Button asChild variant=\"secondary\">\n <a href=\"https://agentero.com\" target=\"_blank\" rel=\"noreferrer\">\n Visit Agentero\n </a>\n </Button>\n </Row>\n);","description":"`asChild` renders Button's styles on the nested child element rather than on a `<button>` — the child receives Button's `className`, `ref`, and merged props via Radix's `Slot` primitive. Use it to turn any anchor or framework `Link` into a Button without coupling the design system to a router. In app code, swap the plain `<a>` below for your framework's Link (`next/link`, `react-router`, `@tanstack/react-router`, etc.).","summary":"`asChild` composes Button's styles onto any element"}],"import":"import { Button } from \"@agentero/design-system\";","jsDocTags":{},"description":"Button is the design system's primary actionable control. Pick `variant` to express hierarchy, `size` for prominence, and `status=\"danger\"` for destructive actions. Pass `asChild` to render Button's styles on any nested element — a plain `<a>`, a framework `<Link>`, or a custom component — without Button binding to any particular framework.","reactDocgenTypescript":{"tags":{"summary":"Primary actionable control; renders a `<button>` or, with `asChild`, any nested element","example":"<Button variant=\"primary\" size=\"sm\" onClick={handleSave}>\n Save changes\n</Button>\n<Button asChild variant=\"secondary\">\n <a href=\"https://agentero.com\" target=\"_blank\" rel=\"noreferrer\">Visit Agentero</a>\n</Button>\n// Framework-agnostic: wrap any Link implementation\n<Button asChild variant=\"primary\">\n <Link href=\"/dashboard\">Go to dashboard</Link>\n</Button>\n<Button variant=\"primary\" status=\"danger\" loading={isDeleting} onClick={handleDelete}>\n Delete account\n</Button>"},"filePath":"/home/runner/work/design-system/design-system/src/button/button.tsx","description":"Button is the design system's primary actionable control. Use it for any\ninteraction that triggers behavior, submits a form, or navigates the user.\nBy default Button renders a `<button>`; pass `asChild` to render its single\nchild element as the underlying tag instead — Button merges its styles,\n`className`, `ref`, and props onto whatever the consumer nests. This keeps\nthe design system framework-agnostic: route a plain `<a>`, a Next.js\n`<Link>`, a React Router `<Link>`, or any custom element through the same\nvisual treatment.\n\nPick `variant` to express hierarchy (`primary` for the main CTA,\n`secondary` / `tertiary` for supporting actions, `ghost` for low-emphasis\ninline actions, `link` for text-only actions). Use `status=\"danger\"` for\ndestructive actions and `loading` to block interaction while async work\nresolves.\n\nDo **not** use Button for toggle states (prefer a Switch or ToggleButton),\nfor passive decorative anchors without action intent (use a plain `<a>`),\nor with `variant=\"link\"` when loading or when the button has no text\nchildren — both combinations log a dev-only warning (silent in production).","displayName":"Button","methods":[],"props":{"children":{"defaultValue":null,"description":"Content rendered inside the Button. Accepts a text label, icon elements,\nor any mix of both. Icon-only children switch the Button to a square\naspect ratio and trigger the icon-only layout.\n\nWhen `asChild` is set, the single child element is merged with Button's\nprops and styles; auto-detection of icon-only children is skipped — use\nthe `iconOnly` prop to opt into the square icon-only layout.\n\nNot supported with `variant=\"link\"` when children resolve to icons only\n— passing both logs a dev-only warning (silent in production).","name":"children","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"},{"fileName":"design-system/node_modules/@types/react/index.d.ts","name":"DOMAttributes"}],"required":false,"type":{"name":"ReactNode"}},"variant":{"defaultValue":null,"description":"Visual hierarchy. Defaults to `'primary'`.\n- `primary` — main call-to-action; use once per view.\n- `secondary` — alternative action alongside a primary button.\n- `tertiary` — low-emphasis action, subtle background.\n- `ghost` — minimal background; low-emphasis action in dense layouts.\n- `link` — inline text-style action; no padding or background.","name":"variant","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"enum","raw":"ButtonVariantType","value":[{"value":"\"link\""},{"value":"\"primary\""},{"value":"\"secondary\""},{"value":"\"tertiary\""},{"value":"\"ghost\""}]}},"size":{"defaultValue":null,"description":"Control size. Defaults to `'sm'`.\n- `xs` (24px) — dense toolbars, compact inline actions.\n- `sm` (32px) — standard usage in forms and cards.\n- `md` (40px) — prominent actions in modals or feature rows.\n- `lg` (48px) — hero CTAs and full-width mobile actions.","name":"size","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"enum","raw":"ButtonSizeType","value":[{"value":"\"md\""},{"value":"\"xs\""},{"value":"\"sm\""},{"value":"\"lg\""}]}},"status":{"defaultValue":null,"description":"Semantic status override. Set to `'danger'` for destructive actions\n(delete, remove, disconnect) — applies the destructive color treatment\nacross all variants.","name":"status","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"enum","raw":"\"danger\"","value":[{"value":"\"danger\""}]}},"loading":{"defaultValue":null,"description":"When `true`, shows a spinner overlay and forces the button into a disabled\nstate to block further interaction. Not supported with `variant=\"link\"` —\npassing both logs a dev-only warning (silent in production).","name":"loading","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"boolean"}},"disabled":{"defaultValue":null,"description":"Disables interaction and applies the disabled color treatment. Applied\nvia className so it still affects anchors rendered via `asChild`, which\nignore the native `disabled` attribute — in that case `aria-disabled`\nand `data-disabled` are forwarded to the child element instead.","name":"disabled","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"},{"fileName":"design-system/node_modules/@types/react/index.d.ts","name":"ButtonHTMLAttributes"}],"required":false,"type":{"name":"boolean"}},"iconOnly":{"defaultValue":null,"description":"Forces the icon-only layout (square aspect ratio, no min-width). Useful\nwith `asChild` where the single wrapper child prevents auto-detection.\nFor non-`asChild` usage, prefer passing icon elements as children — the\nicon-only layout is applied automatically.","name":"iconOnly","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"boolean"}},"rounded":{"defaultValue":null,"description":"When `true`, renders a fully pill-shaped button (rounded-full). Otherwise\nuses the variant's default corner radius.","name":"rounded","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"boolean"}},"align":{"defaultValue":null,"description":"Justifies children along the main axis. Defaults to `'center'`.\nUse `'justify'` to push leading and trailing icons to the edges.","name":"align","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"enum","raw":"\"center\" | \"start\" | \"end\" | \"justify\"","value":[{"value":"\"center\""},{"value":"\"start\""},{"value":"\"end\""},{"value":"\"justify\""}]}},"fitContent":{"defaultValue":null,"description":"When `true`, removes the per-size `min-width` floor so the button hugs\nits content. Useful for inline actions inside tight containers.","name":"fitContent","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"boolean"}},"ref":{"defaultValue":null,"description":"Ref forwarded to the underlying element. Typed as a union covering both\n`<button>` and `<a>` because `asChild` lets consumers render either tag\n(or any forwardRef component) through Radix's `Slot`.","name":"ref","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"Ref<HTMLButtonElement | HTMLAnchorElement>"}},"asChild":{"defaultValue":null,"description":"When `true`, Button clones its single child element and merges\nButton's `className`, `ref`, and event handlers onto it rather than\nrendering a `<button>`. Use this to style any element (a plain `<a>`,\na framework `Link`, a `React.forwardRef` component) as a Button.\n\nWhen combined with `disabled`, Button emits `aria-disabled` and\n`data-disabled` on the child instead of the native `disabled`\nattribute (which is ignored by non-form-control elements).","name":"asChild","declarations":[{"fileName":"design-system/src/button/button.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"boolean"}}},"exportName":"Button"}},"components-divider":{"id":"components-divider","name":"Divider","path":"./src/divider/divider.stories.tsx","stories":[{"id":"components-divider--default","name":"Default","snippet":"const Default = () => <div\n className={cn(\n 'flex gap-4 rounded-lg border border-border-default-base-primary bg-bg-default-base-primary p-6',\n args.orientation === 'vertical' ? 'h-40 w-lg items-stretch' : 'w-80 flex-col'\n )}>\n <div className=\"flex flex-1 flex-col justify-center gap-1\">\n <h3 className=\"text-base font-semibold text-text-default-base-primary\">First section</h3>\n <p className=\"text-sm text-text-default-base-secondary\">Content on one side of the divider, visually separated from the other.\n </p>\n </div>\n <Divider orientation=\"horizontal\" decorative />\n <div className=\"flex flex-1 flex-col justify-center gap-1\">\n <h3 className=\"text-base font-semibold text-text-default-base-primary\">Second section</h3>\n <p className=\"text-sm text-text-default-base-secondary\">Content on the other side of the divider, clearly separated from the first.\n </p>\n </div>\n</div>;","description":"The default horizontal, decorative divider — a 1px line that spans the parent width. Use this form between stacked content blocks.","summary":"Default horizontal decorative divider"},{"id":"components-divider--horizontal","name":"Horizontal","snippet":"const Horizontal = () => (\n <div className=\"w-80\">\n <Divider />\n </div>\n);","description":"Horizontal divider — a 1px line spanning the parent's full width. The default orientation; use to separate stacked content.","summary":"Horizontal 1px line spanning the parent width"},{"id":"components-divider--vertical","name":"Vertical","snippet":"const Vertical = () => (\n <div className=\"flex h-24 items-stretch\">\n <Divider orientation=\"vertical\" />\n </div>\n);","description":"Vertical divider — a 1px line spanning the parent's full height. Parent must establish a height (via `h-*` or an intrinsic flex item height) for the line to be visible.","summary":"Vertical 1px line spanning the parent height"},{"id":"components-divider--with-label","name":"With Label","snippet":"const WithLabel = () => <div className=\"flex w-80 flex-col gap-2\">\n <Button variant=\"primary\">Continue with email</Button>\n <Divider orientation=\"horizontal\" decorative label=\"or\" />\n <Button variant=\"secondary\">Continue with SSO</Button>\n</div>;","description":"Labelled divider. The label sits centered between two flanking 1px lines — a common pattern for \"or\" breaks between authentication options.","summary":"Horizontal divider with a centered \"or\" label"},{"id":"components-divider--vertical-with-label","name":"Vertical With Label","snippet":"const VerticalWithLabel = () => <div\n className=\"flex h-40 items-stretch gap-4 rounded-lg border border-border-default-base-primary bg-bg-default-base-primary p-6\">\n <div className=\"flex flex-col justify-center gap-1\">\n <h3 className=\"text-sm font-semibold text-text-default-base-primary\">Left panel</h3>\n <p className=\"text-xs text-text-default-base-secondary\">Content on the left side</p>\n </div>\n <Divider orientation=\"vertical\" decorative label=\"OR\" />\n <div className=\"flex flex-col justify-center gap-1\">\n <h3 className=\"text-sm font-semibold text-text-default-base-primary\">Right panel</h3>\n <p className=\"text-xs text-text-default-base-secondary\">Content on the right side</p>\n </div>\n</div>;","description":"Vertical divider with a label. The label sits between two stacked 1px line segments; use sparingly — horizontal labelled dividers are more common.","summary":"Vertical divider with a centered label"},{"id":"components-divider--semantic","name":"Semantic","snippet":"const Semantic = () => <div\n className=\"flex w-80 flex-col gap-4 rounded-lg border border-border-default-base-primary bg-bg-default-base-primary p-6\">\n <section className=\"flex flex-col gap-1\">\n <h3 className=\"text-base font-semibold text-text-default-base-primary\">Section one</h3>\n <p className=\"text-sm text-text-default-base-secondary\">Semantically separated from the next section for screen readers.\n </p>\n </section>\n <Divider orientation=\"horizontal\" decorative={false} />\n <section className=\"flex flex-col gap-1\">\n <h3 className=\"text-base font-semibold text-text-default-base-primary\">Section two</h3>\n <p className=\"text-sm text-text-default-base-secondary\">Screen readers will announce this as a separate section.\n </p>\n </section>\n</div>;","description":"Semantic divider (`decorative={false}`). Exposes `role=\"separator\"` and `aria-orientation` to assistive technologies, marking a meaningful section break rather than a purely visual one.","summary":"Semantic separator announced to assistive technologies"},{"id":"components-divider--in-list","name":"In List","snippet":"const InList = () => (\n <div className=\"w-80 rounded-lg border border-border-default-base-primary bg-bg-default-base-primary\">\n <div className=\"flex flex-col gap-1 px-4 py-3\">\n <h4 className=\"text-sm text-text-default-base-primary\">Notification 1</h4>\n <p className=\"text-xs text-text-default-base-secondary\">\n You have a new message from Jane.\n </p>\n </div>\n <Divider />\n <div className=\"flex flex-col gap-1 px-4 py-3\">\n <h4 className=\"text-sm text-text-default-base-primary\">Notification 2</h4>\n <p className=\"text-xs text-text-default-base-secondary\">\n Your report is ready to download.\n </p>\n </div>\n <Divider />\n <div className=\"flex flex-col gap-1 px-4 py-3\">\n <h4 className=\"text-sm text-text-default-base-primary\">Notification 3</h4>\n <p className=\"text-xs text-text-default-base-secondary\">\n System maintenance is scheduled for tonight.\n </p>\n </div>\n </div>\n);","description":"Divider between list rows. Dividers delineate each item without the visual weight of a full border on every row.","summary":"Horizontal dividers between stacked list rows"},{"id":"components-divider--in-toolbar","name":"In Toolbar","snippet":"const InToolbar = () => (\n <div className=\"inline-flex h-10 items-center gap-1 rounded-lg border border-border-default-base-primary bg-bg-default-base-primary px-2 shadow-1\">\n <Button variant=\"ghost\" size=\"xs\">\n Cut\n </Button>\n <Button variant=\"ghost\" size=\"xs\">\n Copy\n </Button>\n <Button variant=\"ghost\" size=\"xs\">\n Paste\n </Button>\n <Divider orientation=\"vertical\" className=\"mx-1 h-6\" />\n <Button variant=\"ghost\" size=\"xs\">\n Undo\n </Button>\n <Button variant=\"ghost\" size=\"xs\">\n Redo\n </Button>\n <Divider orientation=\"vertical\" className=\"mx-1 h-6\" />\n <Button variant=\"ghost\" size=\"xs\">\n Settings\n </Button>\n </div>\n);","description":"Vertical dividers grouping related toolbar actions. Use to separate logical clusters of buttons (editing vs. history vs. settings) without visual weight.","summary":"Vertical dividers grouping toolbar actions"},{"id":"components-divider--horizontal-in-content","name":"Horizontal In Content","snippet":"const HorizontalInContent = () => (\n <div className=\"flex w-96 flex-col gap-4 p-6\">\n <div className=\"flex flex-col gap-1\">\n <h3 className=\"text-base font-semibold text-text-default-base-primary\">Section title</h3>\n <p className=\"text-sm text-text-default-base-secondary\">\n Descriptive content for the first section. The divider below separates it from the next.\n </p>\n </div>\n <Divider />\n <div className=\"flex flex-col gap-1\">\n <h3 className=\"text-base font-semibold text-text-default-base-primary\">Another section</h3>\n <p className=\"text-sm text-text-default-base-secondary\">\n The second section is clearly separated from the previous one.\n </p>\n </div>\n <Divider />\n <div className=\"flex flex-col gap-1\">\n <h3 className=\"text-base font-semibold text-text-default-base-primary\">Final section</h3>\n <p className=\"text-sm text-text-default-base-secondary\">\n Dividers help establish visual hierarchy in content-heavy layouts.\n </p>\n </div>\n </div>\n);","description":"Horizontal dividers between content sections in a long-form layout. Helps create visual hierarchy in content-heavy pages.","summary":"Horizontal dividers between content sections"},{"id":"components-divider--vertical-between-elements","name":"Vertical Between Elements","snippet":"const VerticalBetweenElements = () => (\n <div className=\"flex items-stretch gap-3\">\n <Button variant=\"primary\" size=\"sm\">\n Button 1\n </Button>\n <Divider orientation=\"vertical\" />\n <Button variant=\"primary\" size=\"sm\">\n Button 2\n </Button>\n <Divider orientation=\"vertical\" />\n <Button variant=\"primary\" size=\"sm\">\n Button 3\n </Button>\n </div>\n);","description":"Vertical dividers between inline elements. Common for separating a row of related controls or inline links without visual weight.","summary":"Vertical dividers separating inline elements"}],"import":"import { Button, Divider } from \"@agentero/design-system\";","jsDocTags":{},"description":"Divider separates content visually along either a horizontal or vertical axis. Use between page or card sections, between inline items in a toolbar or list, or — with the `label` prop — to render an \"or\"-style break between options. Set `decorative={false}` when the separator carries semantic meaning so it's announced to assistive technologies.","reactDocgenTypescript":{"tags":{"summary":"Visual or semantic separator that optionally renders a centered label","param":"orientation - Axis along which the separator renders. Defaults to `'horizontal'`.\n- `horizontal` — 1px line spanning the parent width.\n- `vertical` — 1px line spanning the parent height; parent must establish a height.\ndecorative - When `true` (default), the separator is purely visual and hidden\nfrom assistive technologies. Set to `false` to expose `role=\"separator\"` plus\n`aria-orientation` for meaningful section breaks.\nlabel - Optional inline content rendered between two flanking 1px lines.\nWhen omitted, Divider renders a single line.","example":"<Divider />\n<Divider orientation=\"vertical\" />\n<Divider label=\"or\" />\n<Divider decorative={false} />"},"filePath":"/home/runner/work/design-system/design-system/src/divider/divider.tsx","description":"Divider separates content visually (or semantically, via `decorative={false}`)\nalong either a horizontal or vertical axis. Use Divider between page or card\nsections, between inline items in a toolbar or list, or to break up long\ncontent regions. Pass a `label` to render the \"or\"-style divider with text\ncentered between two line segments — useful for auth flows and step breaks.\n\nBuilt on Radix UI's Separator primitive for the unlabelled case; the\nlabelled case renders a `<div>` that still forwards the correct\n`role`/`aria-orientation` when `decorative={false}`.\n\nDo **not** use Divider as a bare horizontal rule to add vertical rhythm —\nreach for margin utilities or a layout wrapper instead. Divider should carry\nmeaning (visual or semantic section break), not whitespace.","displayName":"Divider","methods":[],"props":{"asChild":{"defaultValue":null,"description":"","name":"asChild","declarations":[{"fileName":"design-system/node_modules/@radix-ui/react-primitive/dist/index.d.mts","name":"TypeLiteral"}],"required":false,"type":{"name":"boolean"}},"label":{"defaultValue":null,"description":"Optional label rendered inline between two flanking 1px lines. When set,\nDivider renders a styled `<div>` (rather than the underlying separator\nprimitive) so the label can sit centered between the two line segments.","name":"label","declarations":[{"fileName":"design-system/src/divider/divider.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"ReactNode"}}},"exportName":"Divider"}},"components-loading":{"id":"components-loading","name":"Loading","path":"./src/loading/loading.stories.tsx","stories":[{"id":"components-loading--default","name":"Default","snippet":"const Default = () => <Loading size=\"sm\" />;","description":"The default spinner at `size=\"sm\"` (1em diameter), inheriting the current text color. Matches the out-of-the-box behavior when Loading is dropped into any layout.","summary":"Default spinner at the `sm` size"},{"id":"components-loading--size-sm","name":"Size Sm","snippet":"const SizeSm = () => <Loading size=\"sm\" />;","description":"Small spinner (1em diameter) — the default. Ideal for inline indicators, buttons, and compact layouts where the spinner needs to sit next to text.","summary":"Small 1em spinner for inline indicators"},{"id":"components-loading--size-md","name":"Size Md","snippet":"const SizeMd = () => <Loading size=\"md\" />;","description":"Medium spinner (1.5em diameter). Use for cards, panels, and standalone loading states where the spinner is the primary visual signal.","summary":"Medium 1.5em spinner for cards and panels"},{"id":"components-loading--size-lg","name":"Size Lg","snippet":"const SizeLg = () => <Loading size=\"lg\" />;","description":"Large spinner (2em diameter). Use for page-level or section-level loading where the spinner needs more visual weight.","summary":"Large 2em spinner for page or section loading"},{"id":"components-loading--sizes","name":"Sizes","snippet":"const Sizes = () => (\n <div style={{ display: 'flex', alignItems: 'center', gap: '2rem' }}>\n {(['sm', 'md', 'lg'] as const).map(size => (\n <Loading key={size} size={size} />\n ))}\n </div>\n);","description":"All three sizes rendered side by side for visual comparison of the `em`-based scaling. Each spinner inherits the same parent text color.","summary":"Visual comparison of all three spinner sizes"},{"id":"components-loading--inherits-color","name":"Inherits Color","snippet":"const InheritsColor = () => (\n <div style={{ display: 'flex', alignItems: 'center', gap: '2rem' }}>\n <div className=\"text-text-default-base-primary\">\n <Loading size=\"md\" />\n </div>\n <div className=\"text-text-default-brand-primary\">\n <Loading size=\"md\" />\n </div>\n <div className=\"text-text-default-danger-primary\">\n <Loading size=\"md\" />\n </div>\n </div>\n);","description":"The spinner color tracks the parent `color` (text color) via `border-current`. Wrap Loading in any element with a text color utility — or set `color` on Loading itself — and the spinner adopts that color without extra props.","summary":"Spinner color inherits from the parent text color"},{"id":"components-loading--on-dark-surface","name":"On Dark Surface","snippet":"const OnDarkSurface = () => (\n <div className=\"flex items-center gap-8 rounded-lg bg-bg-button-primary-enable p-8 text-text-default-base-inverse-primary\">\n <Loading size=\"sm\" />\n <Loading size=\"md\" />\n <Loading size=\"lg\" />\n </div>\n);","description":"Spinner on a dark surface to verify `border-current` contrast. The parent sets a light text color, which the spinner inherits so it remains visible against the dark background.","summary":"Spinner on a dark-background surface"}],"import":"import { Loading } from \"@agentero/design-system\";","jsDocTags":{},"description":"Loading displays a circular spinner that indicates an in-progress operation. Use for inline fetch, form submission, or asynchronous task indicators. The spinner inherits its color from the parent `color` and scales with the parent font size via `em`-based size variants (`sm`, `md`, `lg`).","reactDocgenTypescript":{"tags":{"summary":"Circular spinner for in-progress and loading states","example":"<Loading />\n<Loading size=\"lg\" className=\"text-text-default-brand-primary\" />"},"filePath":"/home/runner/work/design-system/design-system/src/loading/loading.tsx","description":"Loading displays a circular spinner that indicates an in-progress operation.\nUse Loading to signal that content is being fetched, a form is submitting,\nor any asynchronous task is running inline with surrounding content.\n\nThe spinner inherits its color from the parent `color` (text color) via\n`border-current`, so it adapts to the surrounding context without extra\nprops. It fades in on mount and spins continuously until unmounted.\n\nAvailable sizes: `sm` (1em, default), `md` (1.5em), and `lg` (2em). Each\nsize is expressed in `em` units so the spinner scales with the parent\nfont size — wrap the Loading (or its ancestor) with the appropriate\n`text-[size]` utility to override the absolute diameter.\n\nExposes `role=\"status\"` and `aria-label=\"Loading\"` for screen readers, and\n`data-slot=\"loading\"` for styling hooks.\n\nDo **not** use Loading as the busy indicator for a button — the Button\ncomponent has its own built-in loading overlay ([Button](?path=/docs/button--docs)).\nFor full-page or skeleton loading states prefer a dedicated skeleton\nplaceholder instead of a spinner.","displayName":"Loading","methods":[],"props":{"size":{"defaultValue":null,"description":"Controls the spinner diameter in `em` units relative to the parent font size.\nDefaults to `'sm'`.\n- `sm` (1em) — inline indicators, buttons, and compact layouts\n- `md` (1.5em) — cards, panels, and standalone loading states\n- `lg` (2em) — page-level or section-level loading","name":"size","declarations":[{"fileName":"design-system/src/loading/loading.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"enum","raw":"\"md\" | \"sm\" | \"lg\"","value":[{"value":"\"md\""},{"value":"\"sm\""},{"value":"\"lg\""}]}}},"exportName":"Loading"}}},"meta":{"docgen":"react-docgen-typescript","durationMs":1729}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentero/design-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "A React component library built with Tailwind CSS v4 and Radix UI primitives",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -29,6 +29,10 @@
|
|
|
29
29
|
"types": "./src/button/index.d.ts",
|
|
30
30
|
"import": "./src/button/index.js"
|
|
31
31
|
},
|
|
32
|
+
"./divider": {
|
|
33
|
+
"types": "./src/divider/index.d.ts",
|
|
34
|
+
"import": "./src/divider/index.js"
|
|
35
|
+
},
|
|
32
36
|
"./loading": {
|
|
33
37
|
"types": "./src/loading/index.d.ts",
|
|
34
38
|
"import": "./src/loading/index.js"
|
|
@@ -51,6 +55,7 @@
|
|
|
51
55
|
},
|
|
52
56
|
"dependencies": {
|
|
53
57
|
"@radix-ui/react-avatar": "^1.1.11",
|
|
58
|
+
"@radix-ui/react-separator": "^1.1.8",
|
|
54
59
|
"@radix-ui/react-slot": "^1.2.4",
|
|
55
60
|
"clsx": "^2.1.1",
|
|
56
61
|
"tailwind-merge": "^3.5.0",
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { ComponentPropsWithRef, ReactNode } from 'react';
|
|
2
|
+
import { VariantProps } from 'tailwind-variants';
|
|
3
|
+
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
|
4
|
+
/**
|
|
5
|
+
* Style recipe for Divider using tailwind-variants.
|
|
6
|
+
* Defines slots (`root`, `label`) and variants (`orientation`, `hasLabel`).
|
|
7
|
+
* The labelless case renders a single 1px line via `bg-border-default-base-primary`;
|
|
8
|
+
* the labelled case flanks the label with two 1px pseudo-element lines via
|
|
9
|
+
* `border-border-default-base-primary`. Label text routes through
|
|
10
|
+
* `text-text-default-base-tertiary`.
|
|
11
|
+
*
|
|
12
|
+
* @summary Tailwind-variants recipe for the Divider component
|
|
13
|
+
*/
|
|
14
|
+
export declare const dividerRecipe: import('tailwind-variants').TVReturnType<{
|
|
15
|
+
orientation: {
|
|
16
|
+
horizontal: {
|
|
17
|
+
root: string[];
|
|
18
|
+
};
|
|
19
|
+
vertical: {
|
|
20
|
+
root: string[];
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
hasLabel: {
|
|
24
|
+
true: {
|
|
25
|
+
root: string[];
|
|
26
|
+
};
|
|
27
|
+
false: {
|
|
28
|
+
root: string[];
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
}, {
|
|
32
|
+
root: string[];
|
|
33
|
+
label: string[];
|
|
34
|
+
}, undefined, {
|
|
35
|
+
orientation: {
|
|
36
|
+
horizontal: {
|
|
37
|
+
root: string[];
|
|
38
|
+
};
|
|
39
|
+
vertical: {
|
|
40
|
+
root: string[];
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
hasLabel: {
|
|
44
|
+
true: {
|
|
45
|
+
root: string[];
|
|
46
|
+
};
|
|
47
|
+
false: {
|
|
48
|
+
root: string[];
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
}, {
|
|
52
|
+
root: string[];
|
|
53
|
+
label: string[];
|
|
54
|
+
}, import('tailwind-variants').TVReturnType<{
|
|
55
|
+
orientation: {
|
|
56
|
+
horizontal: {
|
|
57
|
+
root: string[];
|
|
58
|
+
};
|
|
59
|
+
vertical: {
|
|
60
|
+
root: string[];
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
hasLabel: {
|
|
64
|
+
true: {
|
|
65
|
+
root: string[];
|
|
66
|
+
};
|
|
67
|
+
false: {
|
|
68
|
+
root: string[];
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
}, {
|
|
72
|
+
root: string[];
|
|
73
|
+
label: string[];
|
|
74
|
+
}, undefined, unknown, unknown, undefined>>;
|
|
75
|
+
export type DividerVariants = VariantProps<typeof dividerRecipe>;
|
|
76
|
+
export type DividerProps = ComponentPropsWithRef<typeof SeparatorPrimitive.Root> & {
|
|
77
|
+
/**
|
|
78
|
+
* Optional label rendered inline between two flanking 1px lines. When set,
|
|
79
|
+
* Divider renders a styled `<div>` (rather than the underlying separator
|
|
80
|
+
* primitive) so the label can sit centered between the two line segments.
|
|
81
|
+
*/
|
|
82
|
+
label?: ReactNode;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Divider separates content visually (or semantically, via `decorative={false}`)
|
|
86
|
+
* along either a horizontal or vertical axis. Use Divider between page or card
|
|
87
|
+
* sections, between inline items in a toolbar or list, or to break up long
|
|
88
|
+
* content regions. Pass a `label` to render the "or"-style divider with text
|
|
89
|
+
* centered between two line segments — useful for auth flows and step breaks.
|
|
90
|
+
*
|
|
91
|
+
* Built on Radix UI's Separator primitive for the unlabelled case; the
|
|
92
|
+
* labelled case renders a `<div>` that still forwards the correct
|
|
93
|
+
* `role`/`aria-orientation` when `decorative={false}`.
|
|
94
|
+
*
|
|
95
|
+
* Do **not** use Divider as a bare horizontal rule to add vertical rhythm —
|
|
96
|
+
* reach for margin utilities or a layout wrapper instead. Divider should carry
|
|
97
|
+
* meaning (visual or semantic section break), not whitespace.
|
|
98
|
+
*
|
|
99
|
+
* @summary Visual or semantic separator that optionally renders a centered label
|
|
100
|
+
*
|
|
101
|
+
* @param orientation - Axis along which the separator renders. Defaults to `'horizontal'`.
|
|
102
|
+
* - `horizontal` — 1px line spanning the parent width.
|
|
103
|
+
* - `vertical` — 1px line spanning the parent height; parent must establish a height.
|
|
104
|
+
* @param decorative - When `true` (default), the separator is purely visual and hidden
|
|
105
|
+
* from assistive technologies. Set to `false` to expose `role="separator"` plus
|
|
106
|
+
* `aria-orientation` for meaningful section breaks.
|
|
107
|
+
* @param label - Optional inline content rendered between two flanking 1px lines.
|
|
108
|
+
* When omitted, Divider renders a single line.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* <Divider />
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* <Divider orientation="vertical" />
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* <Divider label="or" />
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* <Divider decorative={false} />
|
|
121
|
+
*/
|
|
122
|
+
export declare const Divider: ({ className, orientation, decorative, label, ref, ...props }: DividerProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/utils.js";
|
|
3
|
+
import { tv as t } from "tailwind-variants";
|
|
4
|
+
import { jsx as n } from "react/jsx-runtime";
|
|
5
|
+
import * as r from "@radix-ui/react-separator";
|
|
6
|
+
//#region src/divider/divider.tsx
|
|
7
|
+
var i = t({
|
|
8
|
+
slots: {
|
|
9
|
+
root: ["shrink-0"],
|
|
10
|
+
label: ["flex text-text-default-base-tertiary"]
|
|
11
|
+
},
|
|
12
|
+
variants: {
|
|
13
|
+
orientation: {
|
|
14
|
+
horizontal: { root: ["w-full"] },
|
|
15
|
+
vertical: { root: ["h-auto"] }
|
|
16
|
+
},
|
|
17
|
+
hasLabel: {
|
|
18
|
+
true: { root: [
|
|
19
|
+
"flex items-center text-sm",
|
|
20
|
+
"before:flex-1 before:content-[\"\"] before:border-border-default-base-primary",
|
|
21
|
+
"after:flex-1 after:content-[\"\"] after:border-border-default-base-primary"
|
|
22
|
+
] },
|
|
23
|
+
false: { root: ["bg-border-default-base-primary"] }
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
compoundVariants: [
|
|
27
|
+
{
|
|
28
|
+
orientation: "horizontal",
|
|
29
|
+
hasLabel: !1,
|
|
30
|
+
class: { root: "h-px w-full" }
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
orientation: "vertical",
|
|
34
|
+
hasLabel: !1,
|
|
35
|
+
class: { root: "h-auto w-px" }
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
orientation: "horizontal",
|
|
39
|
+
hasLabel: !0,
|
|
40
|
+
class: {
|
|
41
|
+
root: "before:mr-2 before:border-t after:ml-2 after:border-t",
|
|
42
|
+
label: "px-10"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
orientation: "vertical",
|
|
47
|
+
hasLabel: !0,
|
|
48
|
+
class: {
|
|
49
|
+
root: "flex-col before:mb-2 before:border-l after:mt-2 after:border-l",
|
|
50
|
+
label: "py-2"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
defaultVariants: {
|
|
55
|
+
orientation: "horizontal",
|
|
56
|
+
hasLabel: !1
|
|
57
|
+
}
|
|
58
|
+
}), a = ({ className: t, orientation: a = "horizontal", decorative: o = !0, label: s, ref: c, ...l }) => {
|
|
59
|
+
let u = s != null, d = i({
|
|
60
|
+
orientation: a,
|
|
61
|
+
hasLabel: u
|
|
62
|
+
});
|
|
63
|
+
return /* @__PURE__ */ n(r.Root, {
|
|
64
|
+
ref: c,
|
|
65
|
+
"data-slot": "separator",
|
|
66
|
+
decorative: o,
|
|
67
|
+
orientation: a,
|
|
68
|
+
className: e(d.root(), t),
|
|
69
|
+
...l,
|
|
70
|
+
children: u && /* @__PURE__ */ n("div", {
|
|
71
|
+
className: d.label(),
|
|
72
|
+
children: s
|
|
73
|
+
})
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
//#endregion
|
|
77
|
+
export { a as Divider, i as dividerRecipe };
|