@ai-matrx/associations 0.7.2 → 0.7.4
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/CHANGELOG.md +21 -0
- package/dist/react/index.cjs +106 -87
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +106 -87
- package/dist/react/index.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog — @ai-matrx/associations
|
|
2
2
|
|
|
3
|
+
## 0.7.4 — 2026-09-02 (bounded universal-picker results)
|
|
4
|
+
|
|
5
|
+
- The universal picker now keeps type filters in one horizontally scrollable
|
|
6
|
+
rail instead of wrapping the full token cloud through the results viewport.
|
|
7
|
+
- Search results retain a labelled, minimum-height vertical region inside
|
|
8
|
+
bounded desktop and mobile hosts, so a visible candidate remains reachable
|
|
9
|
+
and its attach button can enter the normal attach/detach lifecycle.
|
|
10
|
+
- A failing-then-passing constrained-layout regression searches and activates
|
|
11
|
+
`Canary Usage Confirmation` at 1440×900 and 390×844, then proves the control
|
|
12
|
+
flips from Attach to Detach. Full package suite: 193 tests.
|
|
13
|
+
|
|
14
|
+
## 0.7.3 — 2026-09-01 (favorites surface in universal recents)
|
|
15
|
+
|
|
16
|
+
- Empty-query universal pickers now include a newly favorited entity even when
|
|
17
|
+
no detail route has stamped `last_viewed_at` yet. Previously the canonical
|
|
18
|
+
favorite write succeeded but the picker silently filtered the row out.
|
|
19
|
+
- Favorites sort ahead of ordinary recents, with view recency preserving the
|
|
20
|
+
order inside each group.
|
|
21
|
+
- A failing-then-passing hook regression covers a favorite with no viewed
|
|
22
|
+
timestamp alongside an ordinary recent item. Full package suite: 191 tests.
|
|
23
|
+
|
|
3
24
|
## 0.7.2 — 2026-09-01 (verified republish of universal-search repair)
|
|
4
25
|
|
|
5
26
|
- Republishes the 0.7.1 reference-pickable universal-search repair under a
|
package/dist/react/index.cjs
CHANGED
|
@@ -1472,8 +1472,11 @@ async function loadRecents(store, tokens) {
|
|
|
1472
1472
|
if (!res.ok) return [];
|
|
1473
1473
|
const tokenSet = new Set(tokens);
|
|
1474
1474
|
const rows = res.data.items.filter(
|
|
1475
|
-
(i) => tokenSet.has(i.entityType) && isEntityTypeToken(i.entityType) && i.lastViewedAt
|
|
1476
|
-
).sort((a, b) =>
|
|
1475
|
+
(i) => tokenSet.has(i.entityType) && isEntityTypeToken(i.entityType) && (i.isFavorite || i.lastViewedAt)
|
|
1476
|
+
).sort((a, b) => {
|
|
1477
|
+
if (a.isFavorite !== b.isFavorite) return a.isFavorite ? -1 : 1;
|
|
1478
|
+
return (b.lastViewedAt ?? "").localeCompare(a.lastViewedAt ?? "");
|
|
1479
|
+
}).slice(0, RECENTS_LIMIT);
|
|
1477
1480
|
if (rows.length === 0) return [];
|
|
1478
1481
|
const byToken = /* @__PURE__ */ new Map();
|
|
1479
1482
|
for (const r of rows) {
|
|
@@ -2535,27 +2538,35 @@ function UniversalAssociationPicker(props) {
|
|
|
2535
2538
|
),
|
|
2536
2539
|
loading && browseToken === null && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SpinnerIcon, { className: "absolute right-2.5 top-1/2 h-4 w-4 -translate-y-1/2 animate-spin text-muted-foreground" })
|
|
2537
2540
|
] }),
|
|
2538
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
"
|
|
2544
|
-
{
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2541
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2542
|
+
"div",
|
|
2543
|
+
{
|
|
2544
|
+
role: "group",
|
|
2545
|
+
"aria-label": "Entity type filters",
|
|
2546
|
+
className: "flex shrink-0 flex-nowrap gap-1 overflow-x-auto pb-1",
|
|
2547
|
+
children: tokens.map((t) => {
|
|
2548
|
+
const info = store.registry.getEntityInfo(t);
|
|
2549
|
+
const ChipIcon = info.Icon ?? DefaultEntityIcon;
|
|
2550
|
+
const active = browseToken === t;
|
|
2551
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2552
|
+
"button",
|
|
2553
|
+
{
|
|
2554
|
+
type: "button",
|
|
2555
|
+
onClick: () => setBrowseToken(active ? null : t),
|
|
2556
|
+
className: (0, import_design_system4.cn)(
|
|
2557
|
+
"inline-flex shrink-0 items-center gap-1 rounded-md border px-1.5 py-0.5 text-[11px] transition-colors",
|
|
2558
|
+
active ? "border-primary/50 bg-primary/10 text-foreground" : "border-border text-muted-foreground hover:text-foreground hover:bg-accent"
|
|
2559
|
+
),
|
|
2560
|
+
children: [
|
|
2561
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ChipIcon, { className: "h-3 w-3" }),
|
|
2562
|
+
info.labelPlural
|
|
2563
|
+
]
|
|
2564
|
+
},
|
|
2565
|
+
t
|
|
2566
|
+
);
|
|
2567
|
+
})
|
|
2568
|
+
}
|
|
2569
|
+
),
|
|
2559
2570
|
browseToken && BrowseOverride ? (
|
|
2560
2571
|
// The token's canonical host picker (e.g. the stored-files browser)
|
|
2561
2572
|
// owns per-token browsing when registered — never a plain list twin.
|
|
@@ -2588,71 +2599,79 @@ function UniversalAssociationPicker(props) {
|
|
|
2588
2599
|
onAttach: (id, title) => onAttach(browseToken, id, title),
|
|
2589
2600
|
onDetach: (id) => onDetach(browseToken, id)
|
|
2590
2601
|
}
|
|
2591
|
-
) }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
{
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2602
|
+
) }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2603
|
+
"div",
|
|
2604
|
+
{
|
|
2605
|
+
role: "region",
|
|
2606
|
+
"aria-label": "Association search results",
|
|
2607
|
+
className: "-mx-1 min-h-24 flex-1 overflow-y-auto overscroll-contain px-1",
|
|
2608
|
+
children: results.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "py-6 text-center text-[12px] text-muted-foreground", children: loading ? "Searching\u2026" : query.trim() ? "No matches \u2014 narrow with a type chip to browse." : "No recent items. Type to search, or pick a type to browse." }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-2", children: [
|
|
2609
|
+
isRecents && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "px-1 text-[10px] font-medium uppercase tracking-wider text-muted-foreground/60", children: "Recent" }),
|
|
2610
|
+
[...groups.entries()].map(([token, items]) => {
|
|
2611
|
+
const info = store.registry.getEntityInfo(token);
|
|
2612
|
+
const GroupIcon = info.Icon ?? DefaultEntityIcon;
|
|
2613
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-0.5", children: [
|
|
2614
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { className: "flex items-center gap-1 px-1 text-[10px] font-medium uppercase tracking-wider text-muted-foreground/70", children: [
|
|
2615
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(GroupIcon, { className: "h-3 w-3" }),
|
|
2616
|
+
info.labelPlural
|
|
2617
|
+
] }),
|
|
2618
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("ul", { className: "space-y-0.5", children: items.map((c) => {
|
|
2619
|
+
const key = attachedKey(c.token, c.id);
|
|
2620
|
+
const attached = attachedKeys.has(key);
|
|
2621
|
+
const busy = busyKey === key;
|
|
2622
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2623
|
+
"li",
|
|
2624
|
+
{
|
|
2625
|
+
className: (0, import_design_system4.cn)(
|
|
2626
|
+
"group/entity-ref group flex items-center gap-1 rounded-md pr-1.5 transition-colors",
|
|
2627
|
+
"hover:bg-accent",
|
|
2628
|
+
attached && "bg-accent/40"
|
|
2629
|
+
),
|
|
2630
|
+
children: [
|
|
2631
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2632
|
+
"button",
|
|
2633
|
+
{
|
|
2634
|
+
type: "button",
|
|
2635
|
+
disabled: busy,
|
|
2636
|
+
onClick: () => toggle(c),
|
|
2637
|
+
title: attached ? `Detach "${c.title}"` : `Attach "${c.title}"`,
|
|
2638
|
+
className: (0, import_design_system4.cn)(
|
|
2639
|
+
"flex min-w-0 flex-1 items-center gap-2 rounded-md px-2.5 py-1.5 text-left text-sm",
|
|
2640
|
+
"disabled:opacity-50"
|
|
2641
|
+
),
|
|
2642
|
+
children: [
|
|
2643
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "min-w-0 flex-1 truncate text-foreground", children: c.title }),
|
|
2644
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2645
|
+
"span",
|
|
2646
|
+
{
|
|
2647
|
+
className: (0, import_design_system4.cn)(
|
|
2648
|
+
"flex h-5 w-5 shrink-0 items-center justify-center rounded-full",
|
|
2649
|
+
attached ? "bg-primary text-primary-foreground" : "border border-border text-muted-foreground group-hover:border-primary/60"
|
|
2650
|
+
),
|
|
2651
|
+
children: busy ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SpinnerIcon, { className: "h-3 w-3 animate-spin" }) : attached ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CheckIcon, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PlusIcon, { className: "h-3 w-3" })
|
|
2652
|
+
}
|
|
2653
|
+
)
|
|
2654
|
+
]
|
|
2655
|
+
}
|
|
2624
2656
|
),
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
token: c.token,
|
|
2644
|
-
id: c.id,
|
|
2645
|
-
name: c.title
|
|
2646
|
-
}
|
|
2647
|
-
)
|
|
2648
|
-
]
|
|
2649
|
-
},
|
|
2650
|
-
key
|
|
2651
|
-
);
|
|
2652
|
-
}) })
|
|
2653
|
-
] }, token);
|
|
2654
|
-
})
|
|
2655
|
-
] }) })
|
|
2657
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2658
|
+
DoorControlsSlot,
|
|
2659
|
+
{
|
|
2660
|
+
token: c.token,
|
|
2661
|
+
id: c.id,
|
|
2662
|
+
name: c.title
|
|
2663
|
+
}
|
|
2664
|
+
)
|
|
2665
|
+
]
|
|
2666
|
+
},
|
|
2667
|
+
key
|
|
2668
|
+
);
|
|
2669
|
+
}) })
|
|
2670
|
+
] }, token);
|
|
2671
|
+
})
|
|
2672
|
+
] })
|
|
2673
|
+
}
|
|
2674
|
+
)
|
|
2656
2675
|
] });
|
|
2657
2676
|
}
|
|
2658
2677
|
|