@exxatdesignux/ui 0.5.4 → 0.5.6
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 +18 -0
- package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +16 -3
- package/consumer-extras/cursor-rules/exxat-no-image-pixel-copy.mdc +35 -0
- package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +2 -0
- package/consumer-extras/cursor-rules/exxat-sidebar-shell.mdc +35 -0
- package/consumer-extras/cursor-rules/exxat-ux-discovery-protocol.mdc +122 -0
- package/consumer-extras/cursor-rules/exxat-ux-principles.mdc +186 -0
- package/consumer-extras/cursor-skills/exxat-senior-ux/SKILL.md +145 -0
- package/consumer-extras/cursor-skills/exxat-token-economy/SKILL.md +2 -1
- package/consumer-extras/handbook/reference-implementations.md +2 -0
- package/consumer-extras/patterns/consumer-upgrade-checklist.md +1 -0
- package/consumer-extras/patterns/jobs/README.md +59 -0
- package/consumer-extras/patterns/jobs/record-detail.md +177 -0
- package/consumer-extras/patterns/modern-saas-patterns.md +165 -0
- package/dist/components/data-table/index.js +28 -22
- package/dist/components/data-table/index.js.map +1 -1
- package/dist/components/data-table/pagination.js +28 -22
- package/dist/components/data-table/pagination.js.map +1 -1
- package/dist/components/data-table/use-table-state.js +20 -17
- package/dist/components/data-table/use-table-state.js.map +1 -1
- package/dist/components/data-views/hub-table.js +28 -22
- package/dist/components/data-views/hub-table.js.map +1 -1
- package/dist/components/data-views/index.js +28 -22
- package/dist/components/data-views/index.js.map +1 -1
- package/dist/index.js +28 -22
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/data-table/index.tsx +10 -6
- package/src/components/data-table/use-table-state.ts +33 -26
- package/template/docs/consumer-upgrade-checklist.md +1 -0
- package/template/docs/jobs/README.md +59 -0
- package/template/docs/jobs/record-detail.md +177 -0
- package/template/docs/modern-saas-patterns.md +165 -0
- package/template/docs/reference-implementations.md +2 -0
- package/template/lib/mock/navigation.tsx +1 -1
- package/tokens/hooks-index.json +2 -2
|
@@ -1443,15 +1443,6 @@ function useTableState(data, columns, defaultSort, paginationOverride, syncedSea
|
|
|
1443
1443
|
});
|
|
1444
1444
|
return [...groups.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([key, groupRows]) => ({ groupKey: key, groupLabel: key, rows: groupRows }));
|
|
1445
1445
|
}, [rows, groupBy]);
|
|
1446
|
-
const LOCKED_KEYS = React9.useMemo(() => new Set(Object.keys(lockedPins)), [lockedPins]);
|
|
1447
|
-
const effectivePins = React9.useMemo(() => {
|
|
1448
|
-
if (isReflowViewport || !isOverflowing) return {};
|
|
1449
|
-
const result = {};
|
|
1450
|
-
for (const [key, pin] of Object.entries(colPins)) {
|
|
1451
|
-
result[key] = pin;
|
|
1452
|
-
}
|
|
1453
|
-
return result;
|
|
1454
|
-
}, [colPins, isOverflowing, isReflowViewport]);
|
|
1455
1446
|
const displayCols = React9.useMemo(() => {
|
|
1456
1447
|
const leftPinned = [];
|
|
1457
1448
|
const free = [];
|
|
@@ -1471,6 +1462,19 @@ function useTableState(data, columns, defaultSort, paginationOverride, syncedSea
|
|
|
1471
1462
|
}
|
|
1472
1463
|
return out;
|
|
1473
1464
|
}, [colOrder, colPins, hiddenCols, columnsByKey]);
|
|
1465
|
+
const totalWidth = React9.useMemo(
|
|
1466
|
+
() => displayCols.reduce((s, c) => s + (colWidths[c.key] ?? c.width ?? 100), 0),
|
|
1467
|
+
[displayCols, colWidths]
|
|
1468
|
+
);
|
|
1469
|
+
const LOCKED_KEYS = React9.useMemo(() => new Set(Object.keys(lockedPins)), [lockedPins]);
|
|
1470
|
+
const effectivePins = React9.useMemo(() => {
|
|
1471
|
+
if (isReflowViewport || !isOverflowing) return {};
|
|
1472
|
+
const result = {};
|
|
1473
|
+
for (const [key, pin] of Object.entries(colPins)) {
|
|
1474
|
+
result[key] = pin;
|
|
1475
|
+
}
|
|
1476
|
+
return result;
|
|
1477
|
+
}, [colPins, isOverflowing, isReflowViewport]);
|
|
1474
1478
|
function startResize(key, e) {
|
|
1475
1479
|
e.preventDefault();
|
|
1476
1480
|
e.stopPropagation();
|
|
@@ -1531,18 +1535,21 @@ function useTableState(data, columns, defaultSort, paginationOverride, syncedSea
|
|
|
1531
1535
|
function toggleWrap(key) {
|
|
1532
1536
|
setColWrap((p) => ({ ...p, [key]: !p[key] }));
|
|
1533
1537
|
}
|
|
1534
|
-
|
|
1538
|
+
const checkOverflow = React9.useCallback(() => {
|
|
1535
1539
|
const el = scrollRef.current;
|
|
1536
1540
|
if (!el) return;
|
|
1537
|
-
setIsOverflowing(
|
|
1538
|
-
}
|
|
1541
|
+
setIsOverflowing(totalWidth > el.clientWidth + 1);
|
|
1542
|
+
}, [totalWidth]);
|
|
1539
1543
|
function handleScroll() {
|
|
1540
1544
|
const el = scrollRef.current;
|
|
1541
1545
|
if (!el) return;
|
|
1542
1546
|
setScrolled(el.scrollLeft > 1);
|
|
1543
1547
|
setScrollEnd(el.scrollLeft >= el.scrollWidth - el.clientWidth - 1);
|
|
1544
|
-
setIsOverflowing(
|
|
1548
|
+
setIsOverflowing(totalWidth > el.clientWidth + 1);
|
|
1545
1549
|
}
|
|
1550
|
+
React9.useLayoutEffect(() => {
|
|
1551
|
+
checkOverflow();
|
|
1552
|
+
}, [checkOverflow]);
|
|
1546
1553
|
function getRowId(row, index, getIdFn) {
|
|
1547
1554
|
return getIdFn ? getIdFn(row, index) : row.id ?? index;
|
|
1548
1555
|
}
|
|
@@ -1595,10 +1602,6 @@ function useTableState(data, columns, defaultSort, paginationOverride, syncedSea
|
|
|
1595
1602
|
},
|
|
1596
1603
|
[effectivePins, isReflowViewport, stickyOffsets]
|
|
1597
1604
|
);
|
|
1598
|
-
const totalWidth = React9.useMemo(
|
|
1599
|
-
() => displayCols.reduce((s, c) => s + (colWidths[c.key] ?? c.width ?? 100), 0),
|
|
1600
|
-
[displayCols, colWidths]
|
|
1601
|
-
);
|
|
1602
1605
|
return {
|
|
1603
1606
|
// Sort
|
|
1604
1607
|
sortRules,
|
|
@@ -2338,7 +2341,7 @@ function DataTableInner({
|
|
|
2338
2341
|
setSheetOpen,
|
|
2339
2342
|
setSheetInitialPanel
|
|
2340
2343
|
} = state;
|
|
2341
|
-
React9.
|
|
2344
|
+
React9.useLayoutEffect(() => {
|
|
2342
2345
|
const syncScrollport = () => {
|
|
2343
2346
|
const el2 = scrollRef.current;
|
|
2344
2347
|
if (el2) {
|
|
@@ -2351,8 +2354,10 @@ function DataTableInner({
|
|
|
2351
2354
|
if (!el) return;
|
|
2352
2355
|
const ro = new ResizeObserver(syncScrollport);
|
|
2353
2356
|
ro.observe(el);
|
|
2357
|
+
const table = el.querySelector("table");
|
|
2358
|
+
if (table) ro.observe(table);
|
|
2354
2359
|
return () => ro.disconnect();
|
|
2355
|
-
}, []);
|
|
2360
|
+
}, [totalWidth, displayCols.length, checkOverflow]);
|
|
2356
2361
|
const columnMenuPendingActionRef = React9.useRef(null);
|
|
2357
2362
|
const pinnedScrollHintDoneRef = React9.useRef(false);
|
|
2358
2363
|
React9.useEffect(() => {
|
|
@@ -2589,11 +2594,12 @@ function DataTableInner({
|
|
|
2589
2594
|
children: /* @__PURE__ */ jsxs(
|
|
2590
2595
|
"table",
|
|
2591
2596
|
{
|
|
2592
|
-
className: "
|
|
2597
|
+
className: "text-sm border-separate border-spacing-0",
|
|
2593
2598
|
style: {
|
|
2594
2599
|
tableLayout: "fixed",
|
|
2595
|
-
|
|
2596
|
-
|
|
2600
|
+
// Explicit column-sum width — `w-full` made the grid stretch to the scrollport
|
|
2601
|
+
// so scrollWidth === clientWidth and the overflow-gated pin rule never fired.
|
|
2602
|
+
width: totalWidth
|
|
2597
2603
|
},
|
|
2598
2604
|
children: [
|
|
2599
2605
|
/* @__PURE__ */ jsx("colgroup", { children: displayCols.map((col) => /* @__PURE__ */ jsx("col", { style: { width: colWidths[col.key] ?? col.width ?? 100 } }, col.key)) }),
|