@reopt-ai/opt-ui 1.11.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMPONENT_CATALOG.md +394 -201
- package/README.md +43 -5
- package/dist/core/index.cjs +2 -2
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +2 -2
- package/dist/docs/02-components/01-core.md +150 -84
- package/dist/docs/02-components/02-visuals.md +1 -1
- package/dist/docs/02-components/03-shells.md +258 -117
- package/dist/docs/02-components/04-surfaces.md +1 -1
- package/dist/docs/02-components/index.md +5 -5
- package/dist/docs/03-recipes/02-dashboards.md +126 -10
- package/dist/{field-sidebar-DAuN4jPV.cjs → field-sidebar-BYgEmdy0.cjs} +1539 -1536
- package/dist/{field-sidebar-BXl5RJ3q.js → field-sidebar-BuO37l4c.js} +1540 -1539
- package/dist/{field-sidebar-B5SQC35J.d.cts → field-sidebar-CrYlRZew.d.ts} +164 -154
- package/dist/{field-sidebar-CBeWE8xX.d.ts → field-sidebar-uXmoyvd7.d.cts} +164 -154
- package/dist/id-registry.cjs +78 -6
- package/dist/id-registry.d.cts +1 -2
- package/dist/id-registry.d.ts +1 -2
- package/dist/id-registry.js +78 -8
- package/dist/id-registry.json +168 -19
- package/dist/index.cjs +1127 -224
- package/dist/index.d.cts +567 -58
- package/dist/index.d.ts +567 -58
- package/dist/index.js +1118 -227
- package/dist/{key-pad-menu-BxTy_u0Q.d.cts → key-pad-menu-CwcY_Vps.d.cts} +2 -3
- package/dist/{key-pad-menu-wXkWn1I1.js → key-pad-menu-Di2aRGbM.js} +4 -6
- package/dist/{key-pad-menu-Cg6rZBie.cjs → key-pad-menu-SItoHPLu.cjs} +1 -1
- package/dist/{key-pad-menu-u5GTJl9B.d.ts → key-pad-menu-WBJShCJn.d.ts} +3 -4
- package/dist/meta.cjs +678 -19
- package/dist/meta.d.cts +12 -36
- package/dist/meta.d.ts +12 -36
- package/dist/meta.js +678 -21
- package/dist/query.d.cts +1 -2
- package/dist/query.d.ts +1 -2
- package/dist/query.js +0 -2
- package/dist/shells/index.cjs +1 -1
- package/dist/shells/index.d.cts +1 -1
- package/dist/shells/index.d.ts +1 -1
- package/dist/shells/index.js +1 -1
- package/dist/{text-truncate-DW78lg4S.d.cts → text-truncate-CQyfUZvq.d.cts} +31 -3
- package/dist/{text-truncate-DW78lg4S.d.ts → text-truncate-CQyfUZvq.d.ts} +31 -3
- package/dist/{text-truncate-C17HHCR-.js → text-truncate-DSuZECy0.js} +43 -10
- package/dist/{text-truncate-BZdL1k5Z.cjs → text-truncate-I1XLWmRa.cjs} +48 -7
- package/dist/theme/server.d.cts +1 -2
- package/dist/theme/server.d.ts +1 -2
- package/dist/theme/server.js +0 -2
- package/dist/visuals/index.js +0 -1
- package/package.json +4 -3
- package/dist/field-sidebar-B5SQC35J.d.cts.map +0 -1
- package/dist/field-sidebar-BXl5RJ3q.js.map +0 -1
- package/dist/field-sidebar-CBeWE8xX.d.ts.map +0 -1
- package/dist/id-registry.d.cts.map +0 -1
- package/dist/id-registry.d.ts.map +0 -1
- package/dist/id-registry.js.map +0 -1
- package/dist/index.d.cts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/key-pad-menu-BxTy_u0Q.d.cts.map +0 -1
- package/dist/key-pad-menu-u5GTJl9B.d.ts.map +0 -1
- package/dist/key-pad-menu-wXkWn1I1.js.map +0 -1
- package/dist/meta.d.cts.map +0 -1
- package/dist/meta.d.ts.map +0 -1
- package/dist/meta.js.map +0 -1
- package/dist/query.d.cts.map +0 -1
- package/dist/query.d.ts.map +0 -1
- package/dist/query.js.map +0 -1
- package/dist/text-truncate-C17HHCR-.js.map +0 -1
- package/dist/text-truncate-DW78lg4S.d.cts.map +0 -1
- package/dist/text-truncate-DW78lg4S.d.ts.map +0 -1
- package/dist/theme/server.d.cts.map +0 -1
- package/dist/theme/server.d.ts.map +0 -1
- package/dist/theme/server.js.map +0 -1
|
@@ -380,18 +380,134 @@ export function ActivityDashboard() {
|
|
|
380
380
|
}
|
|
381
381
|
```
|
|
382
382
|
|
|
383
|
+
## 4. Analytics Detail Investigation
|
|
384
|
+
|
|
385
|
+
Keep the result list visible while the reader investigates one profile. The
|
|
386
|
+
row owns identity fallback, the flyout owns disclosure and focus return, and
|
|
387
|
+
the evidence inside the panel stays semantic: facts are a definition list,
|
|
388
|
+
score axes are named, and events preserve session boundaries.
|
|
389
|
+
|
|
390
|
+
```tsx
|
|
391
|
+
"use client";
|
|
392
|
+
|
|
393
|
+
import { useState } from "react";
|
|
394
|
+
import {
|
|
395
|
+
Button,
|
|
396
|
+
DescriptionList,
|
|
397
|
+
EventTimeline,
|
|
398
|
+
Flyout,
|
|
399
|
+
Identity,
|
|
400
|
+
ScoreBreakdown,
|
|
401
|
+
type EventTimelineGroup,
|
|
402
|
+
} from "@reopt-ai/opt-ui";
|
|
403
|
+
|
|
404
|
+
const customer = {
|
|
405
|
+
id: "usr_01J5Q8M2N7W4",
|
|
406
|
+
name: "Mina Park",
|
|
407
|
+
email: "mina.park@example.com",
|
|
408
|
+
company: "Northstar Labs",
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
const sessions: EventTimelineGroup[] = [
|
|
412
|
+
{
|
|
413
|
+
id: "checkout-recovery",
|
|
414
|
+
title: "Checkout recovery",
|
|
415
|
+
meta: "12m · 2 events",
|
|
416
|
+
items: [
|
|
417
|
+
{
|
|
418
|
+
id: "order",
|
|
419
|
+
name: "Order completed",
|
|
420
|
+
timestamp: "2026-08-27T01:17:44.000Z",
|
|
421
|
+
tone: "success",
|
|
422
|
+
properties: { order_id: "R-1842", value: 128000 },
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
id: "coupon",
|
|
426
|
+
name: "Recovery coupon applied",
|
|
427
|
+
timestamp: "2026-08-27T01:14:09.000Z",
|
|
428
|
+
properties: { code: "RECOVER20" },
|
|
429
|
+
},
|
|
430
|
+
],
|
|
431
|
+
},
|
|
432
|
+
];
|
|
433
|
+
|
|
434
|
+
export function CustomerInvestigation() {
|
|
435
|
+
const [open, setOpen] = useState(false);
|
|
436
|
+
|
|
437
|
+
return (
|
|
438
|
+
<div className="grid gap-group lg:grid-cols-[1fr_30rem]">
|
|
439
|
+
<button type="button" onClick={() => setOpen(true)}>
|
|
440
|
+
<Identity
|
|
441
|
+
name={customer.name}
|
|
442
|
+
secondary={customer.email}
|
|
443
|
+
id={customer.id}
|
|
444
|
+
state="identified"
|
|
445
|
+
/>
|
|
446
|
+
</button>
|
|
447
|
+
|
|
448
|
+
<Flyout
|
|
449
|
+
open={open}
|
|
450
|
+
onClose={() => setOpen(false)}
|
|
451
|
+
type="inline"
|
|
452
|
+
title={customer.name}
|
|
453
|
+
footer={
|
|
454
|
+
<Button variant="secondary" onClick={() => setOpen(false)}>
|
|
455
|
+
Close
|
|
456
|
+
</Button>
|
|
457
|
+
}
|
|
458
|
+
>
|
|
459
|
+
<div className="flex flex-col gap-group">
|
|
460
|
+
<DescriptionList
|
|
461
|
+
columns={2}
|
|
462
|
+
items={[
|
|
463
|
+
{
|
|
464
|
+
id: "id",
|
|
465
|
+
term: "Profile ID",
|
|
466
|
+
description: customer.id,
|
|
467
|
+
copyValue: customer.id,
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
id: "company",
|
|
471
|
+
term: "Company",
|
|
472
|
+
description: customer.company,
|
|
473
|
+
},
|
|
474
|
+
]}
|
|
475
|
+
/>
|
|
476
|
+
<ScoreBreakdown
|
|
477
|
+
score={76}
|
|
478
|
+
axes={[
|
|
479
|
+
{ id: "recency", label: "Recency", value: 92, weight: 0.5 },
|
|
480
|
+
{ id: "depth", label: "Depth", value: 60, weight: 0.5 },
|
|
481
|
+
]}
|
|
482
|
+
/>
|
|
483
|
+
<EventTimeline groups={sessions} showGaps />
|
|
484
|
+
</div>
|
|
485
|
+
</Flyout>
|
|
486
|
+
</div>
|
|
487
|
+
);
|
|
488
|
+
}
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
Do not wrap an interactive `StatCard` or `Identity` row in a second control.
|
|
492
|
+
Let the component or one row button own the focus stop. `Flyout` is deliberately
|
|
493
|
+
non-modal, so use it for comparison and investigation; use `Dialog` when the
|
|
494
|
+
reader must finish or cancel a blocking task before returning to the page.
|
|
495
|
+
|
|
383
496
|
## Composition Notes
|
|
384
497
|
|
|
385
|
-
| Pattern
|
|
386
|
-
|
|
|
387
|
-
| KPI stats row
|
|
388
|
-
| Trend visualization
|
|
389
|
-
| Tabular detail
|
|
390
|
-
| Date filtering
|
|
391
|
-
| Segment filtering
|
|
392
|
-
| Quick metrics
|
|
393
|
-
| Activity timeline
|
|
394
|
-
|
|
|
498
|
+
| Pattern | Key Components | Data Types |
|
|
499
|
+
| -------------------- | ---------------------------------------- | ---------------------------------------- |
|
|
500
|
+
| KPI stats row | `SummaryRow` | `StatCard[]` (aliased as `StatCardType`) |
|
|
501
|
+
| Trend visualization | `TrendChart` or `ChartContainer` + chart | `ChartDataPoint[]` + `ChartSeriesDef[]` |
|
|
502
|
+
| Tabular detail | `DataTable` | `ColumnDef<T>[]` + data array |
|
|
503
|
+
| Date filtering | `TimeRangeSelector` | `DateRange` |
|
|
504
|
+
| Segment filtering | `FilterBar` | `FilterGroupDef[]` |
|
|
505
|
+
| Quick metrics | `MetricsCard` | inline props + `sparklineData: number[]` |
|
|
506
|
+
| Activity timeline | `ActivityFeed` | `ActivityDef[]` |
|
|
507
|
+
| Detail investigation | `Identity`, `Flyout`, `DescriptionList` | profile + labelled facts |
|
|
508
|
+
| Explainable score | `ScoreBreakdown` | `ScoreAxis[]` + `ScoreBand[]` |
|
|
509
|
+
| Session evidence | `EventTimeline` | `EventTimelineGroup[]` |
|
|
510
|
+
| Task tracking | `TaskList` | `TaskDef[]` |
|
|
395
511
|
|
|
396
512
|
All page-level layouts use `SurfaceLayout` for consistent `gap-section` spacing.
|
|
397
513
|
Use `gap-group` for grid gaps and `gap-element` for tightly spaced items.
|