@crispy-seed/data-table 0.13.0 → 0.14.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.
- package/dist/data-table-recipe.css +62 -27
- package/dist/data-table-recipe.layered.css +65 -24
- package/dist/index.cjs +463 -342
- package/dist/index.d.ts +18 -0
- package/dist/index.js +463 -342
- package/dist/styles.css +65 -24
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1649,6 +1649,11 @@ const ROOT_MARGIN = "160px";
|
|
|
1649
1649
|
const elementRef = useRef(null);
|
|
1650
1650
|
const [scrolledStart, setScrolledStart] = useState(false);
|
|
1651
1651
|
const [scrolledEnd, setScrolledEnd] = useState(false);
|
|
1652
|
+
// The scroll container's own content-box width (0 until first measured). The
|
|
1653
|
+
// styled layer reads it to cap how much of a narrow viewport the sticky-left
|
|
1654
|
+
// pinned group may occupy (`useEffectiveColumns`) -- without a cap, a pinned
|
|
1655
|
+
// group wider than the container covers every scrolling column for good.
|
|
1656
|
+
const [viewportWidth, setViewportWidth] = useState(0);
|
|
1652
1657
|
const [viewport, setViewport] = useState({
|
|
1653
1658
|
scrollTop: 0,
|
|
1654
1659
|
viewportHeight: 0
|
|
@@ -1669,6 +1674,7 @@ const ROOT_MARGIN = "160px";
|
|
|
1669
1674
|
viewportHeight
|
|
1670
1675
|
});
|
|
1671
1676
|
}
|
|
1677
|
+
setViewportWidth(element.clientWidth);
|
|
1672
1678
|
setScrolledStart(element.scrollLeft > 0);
|
|
1673
1679
|
// A 1px slop: sub-pixel layout can leave `scrollLeft + clientWidth` a fraction
|
|
1674
1680
|
// short of `scrollWidth` even when fully scrolled, which would otherwise leave
|
|
@@ -1678,16 +1684,16 @@ const ROOT_MARGIN = "160px";
|
|
|
1678
1684
|
virtualized,
|
|
1679
1685
|
rowHeight
|
|
1680
1686
|
]);
|
|
1681
|
-
// The container can resize without scrolling (window resize, a
|
|
1682
|
-
// changing height) -- the viewport height feeds the window
|
|
1687
|
+
// The container can resize without scrolling (window resize, rotating a phone, a
|
|
1688
|
+
// bounded parent changing height) -- the viewport height feeds the virtual window
|
|
1689
|
+
// and the width feeds the pinned-group cap, so re-measure then too.
|
|
1683
1690
|
useEffect(()=>{
|
|
1684
1691
|
const element = elementRef.current;
|
|
1685
|
-
if (!
|
|
1692
|
+
if (!element || typeof ResizeObserver === "undefined") return;
|
|
1686
1693
|
const observer = new ResizeObserver(()=>remeasure());
|
|
1687
1694
|
observer.observe(element);
|
|
1688
1695
|
return ()=>observer.disconnect();
|
|
1689
1696
|
}, [
|
|
1690
|
-
virtualized,
|
|
1691
1697
|
remeasure
|
|
1692
1698
|
]);
|
|
1693
1699
|
const scrollAreaRef = useCallback((node)=>{
|
|
@@ -1703,6 +1709,7 @@ const ROOT_MARGIN = "160px";
|
|
|
1703
1709
|
scrollAreaRef,
|
|
1704
1710
|
scrolledStart,
|
|
1705
1711
|
scrolledEnd,
|
|
1712
|
+
viewportWidth,
|
|
1706
1713
|
onScroll,
|
|
1707
1714
|
remeasure,
|
|
1708
1715
|
/** Row-virtualization state; `enabled: false` (the default) means render every row. */ virtual: {
|
|
@@ -3232,19 +3239,20 @@ function StatusCell({ value }) {
|
|
|
3232
3239
|
* same "literal color as a computed prop" call `RatingCell`'s star fill already
|
|
3233
3240
|
* makes. Shared by `ChipCell` (Feature A, single value) and `ChipListCell`/
|
|
3234
3241
|
* editors.tsx's `ChipListEditor` (Feature B, multi value) so all three chip
|
|
3235
|
-
* renderings stay byte-identical. */ function SwatchChip({ value, className, children }) {
|
|
3242
|
+
* renderings stay byte-identical. */ function SwatchChip({ value, label, color, className, children }) {
|
|
3236
3243
|
return /*#__PURE__*/ jsxs("span", {
|
|
3237
3244
|
className: className,
|
|
3238
3245
|
style: {
|
|
3239
|
-
backgroundColor: swatchColorFor(value),
|
|
3240
|
-
color: swatchInkFor(value)
|
|
3246
|
+
backgroundColor: color ?? swatchColorFor(value),
|
|
3247
|
+
color: color ? CHIP_CUSTOM_COLOR_INK : swatchInkFor(value)
|
|
3241
3248
|
},
|
|
3242
3249
|
children: [
|
|
3243
|
-
value,
|
|
3250
|
+
label ?? value,
|
|
3244
3251
|
children
|
|
3245
3252
|
]
|
|
3246
3253
|
});
|
|
3247
3254
|
}
|
|
3255
|
+
const CHIP_CUSTOM_COLOR_INK = "#1f2937";
|
|
3248
3256
|
/** `type: "chip"` (Feature A, #9) -- a single value rendered as one colored chip,
|
|
3249
3257
|
* the color derived deterministically from the value string (`swatchColorFor`):
|
|
3250
3258
|
* same value, same color, every render, every column. For a column like provider/
|
|
@@ -3257,6 +3265,14 @@ function StatusCell({ value }) {
|
|
|
3257
3265
|
className: className
|
|
3258
3266
|
});
|
|
3259
3267
|
}
|
|
3268
|
+
/** The `label`/`color` a `chipOptions` entry gives `tag`, spread onto its chip so a
|
|
3269
|
+
* tag looks identical in the closed cell and in the editor's option list. */ function optionProps(chipOptions, tag) {
|
|
3270
|
+
const option = chipOptions?.find((entry)=>entry.value === tag);
|
|
3271
|
+
return option ? {
|
|
3272
|
+
label: option.label,
|
|
3273
|
+
color: option.color
|
|
3274
|
+
} : {};
|
|
3275
|
+
}
|
|
3260
3276
|
// Feature B rework (#8) -- the chip-list DISPLAY row's own gap, mirrored from the
|
|
3261
3277
|
// qvism recipe's `chipList` slot (`packages/qvism-preset/src/recipes/data-table.ts`'s
|
|
3262
3278
|
// `CHIP_GAP`, measured live off Attio at 3px between chips). Kept as a literal here
|
|
@@ -3289,7 +3305,7 @@ const CHIP_LIST_GAP_PX = 3;
|
|
|
3289
3305
|
* times, not just while a `ResizeObserver` fires, because widening the column back
|
|
3290
3306
|
* out needs to know the width of chips currently hidden behind "+N" to decide
|
|
3291
3307
|
* whether they now fit again.
|
|
3292
|
-
*/ function ChipListCell({ value, className, chipClassName, overflowClassName }) {
|
|
3308
|
+
*/ function ChipListCell({ value, className, chipClassName, overflowClassName, chipOptions }) {
|
|
3293
3309
|
const tags = Array.isArray(value) ? value.filter((tag)=>!!tag) : [];
|
|
3294
3310
|
const containerRef = React.useRef(null);
|
|
3295
3311
|
const measureRef = React.useRef(null);
|
|
@@ -3338,6 +3354,7 @@ const CHIP_LIST_GAP_PX = 3;
|
|
|
3338
3354
|
children: [
|
|
3339
3355
|
tags.slice(0, clampedVisible).map((tag)=>/*#__PURE__*/ jsx(SwatchChip, {
|
|
3340
3356
|
value: tag,
|
|
3357
|
+
...optionProps(chipOptions, tag),
|
|
3341
3358
|
className: chipClassName
|
|
3342
3359
|
}, tag)),
|
|
3343
3360
|
overflowCount > 0 && /*#__PURE__*/ jsxs("span", {
|
|
@@ -3358,6 +3375,7 @@ const CHIP_LIST_GAP_PX = 3;
|
|
|
3358
3375
|
},
|
|
3359
3376
|
children: tags.map((tag)=>/*#__PURE__*/ jsx(SwatchChip, {
|
|
3360
3377
|
value: tag,
|
|
3378
|
+
...optionProps(chipOptions, tag),
|
|
3361
3379
|
className: chipClassName
|
|
3362
3380
|
}, tag))
|
|
3363
3381
|
}),
|
|
@@ -3628,6 +3646,13 @@ function RatingCell({ value, maxRating = 5 }) {
|
|
|
3628
3646
|
});
|
|
3629
3647
|
}
|
|
3630
3648
|
|
|
3649
|
+
/** Share of the scroll container's width the sticky-left pinned group may occupy
|
|
3650
|
+
* before FURTHER pinned columns stop sticking and scroll like any other column. A
|
|
3651
|
+
* pinned group at or past the container's width pins every pixel of it: the
|
|
3652
|
+
* scrolling columns slide in underneath the sticky cells and can never be seen (a
|
|
3653
|
+
* 375px phone with Serial + one more pinned column showed nothing else, ever). The
|
|
3654
|
+
* FIRST pinned column always sticks regardless -- the entity/name column staying
|
|
3655
|
+
* frozen is the whole point of pinning. */ const MAX_PINNED_VIEWPORT_SHARE = 0.6;
|
|
3631
3656
|
/** Fallback width (px) used to compute a pinned column's cumulative sticky offset when
|
|
3632
3657
|
* it has no explicit `width` and hasn't been drag-resized -- pinning needs a STATIC
|
|
3633
3658
|
* number to put in an inline `insetInlineStart`, and `table-layout: fixed` only
|
|
@@ -3647,7 +3672,7 @@ function RatingCell({ value, maxRating = 5 }) {
|
|
|
3647
3672
|
* one and a header row built from the other drift out of sync under `table-layout:
|
|
3648
3673
|
* fixed`'s own column-to-cell matching.
|
|
3649
3674
|
*/ function useEffectiveColumns(columns, options) {
|
|
3650
|
-
const { visibleColumnOrder, getColumnLabel, getColumnWidth, pinnedColumnKeys } = useDataTableContext();
|
|
3675
|
+
const { visibleColumnOrder, getColumnLabel, getColumnWidth, pinnedColumnKeys, viewportWidth } = useDataTableContext();
|
|
3651
3676
|
const { selectable, stickyFirst } = options;
|
|
3652
3677
|
return React.useMemo(()=>{
|
|
3653
3678
|
const byKey = new Map(columns.map((column)=>[
|
|
@@ -3673,11 +3698,14 @@ function RatingCell({ value, maxRating = 5 }) {
|
|
|
3673
3698
|
const bPinned = pinnedSet.has(b) ? 0 : 1;
|
|
3674
3699
|
return aPinned - bPinned;
|
|
3675
3700
|
});
|
|
3701
|
+
// 0 = not measured yet (first paint / jsdom) -- no cap rather than a guess.
|
|
3702
|
+
const pinBudget = viewportWidth ? viewportWidth * MAX_PINNED_VIEWPORT_SHARE : Number.POSITIVE_INFINITY;
|
|
3676
3703
|
let cursor = selectable ? 40 : 0;
|
|
3677
3704
|
let pinnedCount = 0;
|
|
3705
|
+
let budgetSpent = false;
|
|
3678
3706
|
const entries = ordered.map((key)=>byKey.get(key)).filter((column)=>Boolean(column)).map((column)=>{
|
|
3679
3707
|
const rawWidth = getColumnWidth(column.key) ?? column.width;
|
|
3680
|
-
const
|
|
3708
|
+
const inPinnedSet = pinnedSet.has(column.key);
|
|
3681
3709
|
// Fix (0.10.4, screenshot-confirmed pinned-column overlay): a pinned column
|
|
3682
3710
|
// with no explicit/resized width used to keep `width` as `undefined` here,
|
|
3683
3711
|
// which `DataTableColGroup` (DataTable.tsx) renders as an AUTO `<col>` --
|
|
@@ -3697,7 +3725,15 @@ function RatingCell({ value, maxRating = 5 }) {
|
|
|
3697
3725
|
// without its own width now always renders at exactly
|
|
3698
3726
|
// `DEFAULT_PINNED_COLUMN_WIDTH`, matching what every other pinned column's
|
|
3699
3727
|
// offset already assumed it would be.
|
|
3700
|
-
const width =
|
|
3728
|
+
const width = inPinnedSet && rawWidth === undefined ? DEFAULT_PINNED_COLUMN_WIDTH : rawWidth;
|
|
3729
|
+
// Sticks only while the group still fits the pin budget (see
|
|
3730
|
+
// MAX_PINNED_VIEWPORT_SHARE); the first pinned column always sticks.
|
|
3731
|
+
// Once one pinned column overflows, every later one scrolls too -- a narrower
|
|
3732
|
+
// late column must not stick past a gap.
|
|
3733
|
+
if (inPinnedSet && pinnedCount > 0 && cursor + (width ?? DEFAULT_PINNED_COLUMN_WIDTH) > pinBudget) {
|
|
3734
|
+
budgetSpent = true;
|
|
3735
|
+
}
|
|
3736
|
+
const pinned = inPinnedSet && !budgetSpent;
|
|
3701
3737
|
const pinOffset = pinned ? cursor : 0;
|
|
3702
3738
|
if (pinned) {
|
|
3703
3739
|
cursor += width ?? DEFAULT_PINNED_COLUMN_WIDTH;
|
|
@@ -3736,7 +3772,8 @@ function RatingCell({ value, maxRating = 5 }) {
|
|
|
3736
3772
|
getColumnWidth,
|
|
3737
3773
|
pinnedColumnKeys,
|
|
3738
3774
|
selectable,
|
|
3739
|
-
stickyFirst
|
|
3775
|
+
stickyFirst,
|
|
3776
|
+
viewportWidth
|
|
3740
3777
|
]);
|
|
3741
3778
|
}
|
|
3742
3779
|
/** The 40px selection column's own sticky-left state -- `stickyFirst` (the table-wide
|
|
@@ -4120,7 +4157,45 @@ const TextFieldTextarea = /*#__PURE__*/ forwardRef(({ className, autoresize = tr
|
|
|
4120
4157
|
});
|
|
4121
4158
|
TextFieldTextarea.displayName = "TextFieldTextarea";
|
|
4122
4159
|
|
|
4123
|
-
__insertCSS(".seed-data-table__root{box-sizing:border-box;position:relative;display:flex;flex-direction:column;width:100%;border-width:1px;border-style:solid;font-family:Inter,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif}.seed-data-table__table{width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}.seed-data-table__headerCell{box-sizing:border-box;position:sticky;top:0;z-index:2;vertical-align:middle;text-align:start;padding:0;height:var(--seed-dimension-x10);background-color:var(--seed-color-bg-layer-default);border-top:1px solid var(--seed-color-stroke-neutral-muted);border-bottom:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-inline-start:none;color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-medium);letter-spacing:-.14px}.seed-data-table__headerCell:last-child{border-inline-end:none}.seed-data-table__headerCell[data-sortable]{cursor:pointer;user-select:none}.seed-data-table__headerCell [data-chevron]{opacity:0;transition:opacity .12s}.seed-data-table__headerCell[data-sortable]:hover [data-chevron]{opacity:.6}.seed-data-table__headerCell[data-sorted] [data-chevron]{opacity:1;color:var(--seed-color-fg-neutral)}.seed-data-table__headerCell:hover [data-column-menu]{opacity:1}.seed-data-table__headerCell [data-column-menu]:focus-visible,.seed-data-table__headerCell [data-column-menu][data-open]{opacity:1}.seed-data-table__headerCell[data-dragging]{opacity:.5}.seed-data-table__headerCell[data-sticky]{position:sticky;z-index:3;background-color:var(--seed-color-bg-layer-default)}.seed-data-table__headerCell{outline:var(--seed-dimension-x0_5) solid transparent;outline-offset:calc(var(--seed-dimension-x0_5) * -1)}.seed-data-table__headerCell:is(:focus-visible,[data-focus-visible]){outline:var(--seed-dimension-x0_5) solid var(--seed-color-stroke-focus-ring);outline-offset:calc(var(--seed-dimension-x0_5) * -1)}.seed-data-table__headerCell .seed-data-table-resize-handle{position:absolute;top:0;inset-inline-end:calc(7px / -2);width:7px;height:100%;z-index:4;display:flex;align-items:center;justify-content:center;cursor:col-resize;touch-action:none}.seed-data-table__headerCell .seed-data-table-resize-handle-inner{width:3px;height:100%;border-radius:3px;background-color:#0298d9;opacity:0;transition:opacity .1s}.seed-data-table__headerCell .seed-data-table-resize-handle:hover .seed-data-table-resize-handle-inner,.seed-data-table__headerCell .seed-data-table-resize-handle[data-resizing] .seed-data-table-resize-handle-inner{opacity:1}.seed-data-table__headerCellInner{box-sizing:border-box;display:flex;align-items:center;width:100%;height:100%;min-width:0;gap:var(--seed-dimension-x1_5);padding-inline:var(--seed-dimension-x3)}.seed-data-table__headerCellLabel{min-width:0;flex:1 1 0%;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__headerCellIcon{flex-shrink:0;margin-inline-start:auto;display:inline-flex;align-items:center;justify-content:center;width:var(--seed-dimension-x4);height:var(--seed-dimension-x4);color:var(--seed-color-fg-neutral-subtle);border:none;background:0 0;padding:0;font:inherit;cursor:pointer}.seed-data-table__headerCellIcon[data-active]{color:var(--seed-color-fg-neutral)}.seed-data-table__headerCellIcon[data-column-menu]{opacity:0;transition:opacity .12s}.seed-data-table__row{position:relative;background-color:var(--seed-color-bg-layer-default);--seed-data-table-row-bg:var(--seed-color-bg-layer-default)}.seed-data-table__row[data-clickable]{cursor:pointer}.seed-data-table__row:is([aria-selected=true],[data-selected]){background-color:color-mix(in srgb,#0298d9 10%,var(--seed-color-bg-layer-default));--seed-data-table-row-bg:color-mix(in srgb, #0298d9 10%, var(--seed-color-bg-layer-default))}.seed-data-table__row:is([aria-selected=true],[data-selected]):is(:hover,[data-hover]){background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 3%,color-mix(in srgb,#0298d9 10%,var(--seed-color-bg-layer-default)));--seed-data-table-row-bg:color-mix(in srgb, var(--seed-color-fg-neutral) 3%, color-mix(in srgb, #0298d9 10%, var(--seed-color-bg-layer-default)))}.seed-data-table__cell{box-sizing:border-box;position:relative;vertical-align:middle;text-align:start;height:var(--seed-dimension-x9);border-bottom:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-top:none;border-inline-start:none;padding-block:0;padding-inline:var(--seed-dimension-x3);color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-regular);letter-spacing:-.14px;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__cell:not([data-editable]){user-select:none}.seed-data-table__cell:last-child{border-inline-end:none}tbody tr:last-child .seed-data-table__cell{border-bottom:none}.seed-data-table__cell[data-numeric]{text-align:end;font-variant-numeric:tabular-nums}.seed-data-table__cell[data-sticky]{position:sticky;z-index:1;background-color:var(--seed-data-table-row-bg)}.seed-data-table__cell[data-overlay-open]{overflow:visible;z-index:20}.seed-data-table__cell[data-editable]{cursor:default}.seed-data-table__cell .seed-data-table-edit-picker{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);min-width:0}.seed-data-table__cell .seed-data-table-edit-pending{flex-shrink:0;color:var(--seed-color-fg-neutral-subtle);animation:rotate .6s linear infinite}.seed-data-table__cell .seed-data-table-edit-error{position:absolute;top:100%;inset-inline-start:var(--seed-dimension-x3);inset-inline-end:var(--seed-dimension-x3);z-index:2;padding-top:2px;font-size:12px;line-height:1.3;color:var(--seed-color-fg-critical);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__entity{display:flex;align-items:center;min-width:0;gap:var(--seed-dimension-x1_5)}.seed-data-table__entityName{min-width:0;font-weight:var(--seed-font-weight-medium);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__entityName[data-clickable]{cursor:pointer;border:none;background:0 0;padding:0;margin:0;font-family:inherit;font-size:inherit;line-height:inherit;color:inherit;text-align:start}.seed-data-table__entityName[data-clickable]:is(:hover,[data-hover]){text-decoration:underline}.seed-data-table__tagList{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);overflow:hidden;min-width:0}.seed-data-table__entityActions{display:flex;align-items:center;gap:6px;margin-inline-start:auto;flex-shrink:0;opacity:0;transition:opacity .15s}tr:hover .seed-data-table__entityActions{opacity:1}.seed-data-table__entityActions:focus-within{opacity:1}.seed-data-table__entityAction{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin:0;padding:2px;border:none;border-radius:6px;background:0 0;font-family:inherit;color:color-mix(in srgb,var(--seed-color-fg-neutral) 55%,transparent);cursor:pointer;flex-shrink:0;transition:background-color .2s,color .2s,box-shadow .2s}.seed-data-table__entityAction:hover{background:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,transparent);color:var(--seed-color-fg-neutral)}.seed-data-table__link{color:var(--seed-color-fg-neutral);text-decoration:none;min-width:0;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__link:is(:hover,[data-hover]){text-decoration:underline}.seed-data-table__chip{box-sizing:border-box;display:inline-flex;align-items:center;flex-shrink:0;max-width:100%;height:22px;padding:0 4px;border-radius:7px;font-size:13px;font-weight:var(--seed-font-weight-medium);line-height:15px;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__chipList{position:relative;display:flex;align-items:center;flex-wrap:nowrap;gap:3px;overflow:hidden;min-width:0;width:100%}.seed-data-table__chipOverflow{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;height:20px;padding:0 4px;border-radius:6px;background-color:#f6f7f7;color:#000;font-size:10px;font-weight:var(--seed-font-weight-regular);line-height:15px;white-space:nowrap}.seed-data-table__chipListEditor{display:flex;align-items:center;flex-wrap:wrap;gap:3px;min-width:0;width:100%}.seed-data-table__chipRemove{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:12px;height:12px;margin:0;margin-inline-start:2px;padding:0;border:none;border-radius:999px;background:0 0;color:inherit;opacity:.6;cursor:pointer;transition:opacity .12s,background-color .12s}.seed-data-table__chipRemove:hover{opacity:1;background-color:rgba(0,0,0,.08)}.seed-data-table__chipInput{flex:1 1 auto;min-width:40px;height:22px;margin:0;padding:0;border:none;outline:0;background:0 0;font-family:inherit;font-size:var(--seed-font-size-t4);color:var(--seed-color-fg-neutral);letter-spacing:-.14px}.seed-data-table__expandOverlay{box-sizing:border-box;position:absolute;top:-1px;inset-inline-start:-1px;inset-inline-end:-1px;z-index:10;min-height:calc(100% + 2px);display:flex;align-items:flex-start;padding-inline:var(--seed-dimension-x3);padding-block:var(--seed-dimension-x3);background-color:var(--seed-color-bg-layer-floating);border-radius:4px;box-shadow:none;border:1px solid #266df0;color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);letter-spacing:-.14px;cursor:default}.seed-data-table__expandOverlayText{width:100%;min-width:0;white-space:normal;word-break:break-word}.seed-data-table__cellSuffixRow{display:flex;align-items:center;gap:4px;min-width:0;width:100%}.seed-data-table__cellSuffixText{flex:1 1 0%;min-width:0;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__cellSuffixIcon{flex-shrink:0;display:inline-flex;align-items:center;color:color-mix(in srgb,var(--seed-color-fg-neutral) 55%,transparent)}.seed-data-table__toolbar{box-sizing:border-box;display:flex;align-items:center;width:100%;flex-shrink:0;min-height:49px;gap:var(--seed-dimension-x2);padding-inline:var(--seed-dimension-x3);border-top:1px solid var(--seed-color-stroke-neutral-muted)}.seed-data-table__search{position:relative;display:inline-flex;align-items:center;flex:1 1 0%;max-width:280px}.seed-data-table__search svg{position:absolute;inset-inline-start:var(--seed-dimension-x2);width:var(--seed-dimension-x4);height:var(--seed-dimension-x4);color:var(--seed-color-fg-neutral-muted);pointer-events:none}.seed-data-table__search input{width:100%;height:var(--seed-dimension-x8);padding-inline-start:var(--seed-dimension-x7);padding-inline-end:var(--seed-dimension-x2);border:none;border-radius:var(--seed-radius-r2);background-color:var(--seed-color-bg-layer-default);box-shadow:inset 0 0 0 1px var(--seed-color-stroke-neutral-weak);font-family:inherit;font-size:var(--seed-font-size-t4);color:var(--seed-color-fg-neutral);outline:0;transition:box-shadow .1s var(--seed-timing-function-easing)}.seed-data-table__search input::placeholder{color:var(--seed-color-fg-neutral-subtle)}.seed-data-table__search input:focus{box-shadow:inset 0 0 0 2px var(--seed-color-stroke-neutral-contrast)}.seed-data-table__count{flex-shrink:0;color:var(--seed-color-fg-neutral-subtle);font-size:var(--seed-font-size-t3);font-variant-numeric:tabular-nums}.seed-data-table__toolbarEnd{flex-shrink:0;margin-inline-start:auto;display:inline-flex;align-items:center;gap:var(--seed-dimension-x2)}.seed-data-table__scrollArea{position:relative;display:flex;flex-direction:column;width:100%;min-width:0;flex:1 1 auto;min-height:0;overflow-x:auto;overflow-y:auto}.seed-data-table__scrollArea[data-scrolled-start] [data-sticky-edge]{clip-path:inset(0 -38px 0 0);box-shadow:6px 0 16px 4px rgba(0,0,0,.12)}.seed-data-table__scrollArea[data-scrolled-end] [data-sticky-edge-end]{clip-path:inset(0 0 0 -38px);box-shadow:-6px 0 16px 4px rgba(0,0,0,.12)}.seed-data-table__footerCell{box-sizing:border-box;position:sticky;bottom:0;z-index:2;vertical-align:middle;padding:0;height:var(--seed-dimension-x9);background-color:var(--seed-color-bg-layer-default);border-top:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-inline-start:none}.seed-data-table__footerCell:last-child{border-inline-end:none}.seed-data-table__footerCell[data-sticky]{z-index:3}.seed-data-table__footerCell .seed-data-table-column-calc-trigger{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);width:100%;height:100%;min-width:0;margin:0;padding:0 var(--seed-dimension-x3);border:none;background:0 0;color:var(--seed-color-fg-neutral-subtle);font-family:inherit;font-size:var(--seed-font-size-t4);font-weight:var(--seed-font-weight-medium);white-space:nowrap;overflow:clip;cursor:pointer;transition:background-color .12s,color .12s}.seed-data-table__footerCell .seed-data-table-column-calc-trigger:hover{background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,transparent);color:var(--seed-color-fg-neutral)}.seed-data-table__footerCell .seed-data-table-column-calc-trigger[data-align=right]{justify-content:flex-end}.seed-data-table__footerCell .seed-data-table-column-calc-trigger svg{flex-shrink:0;opacity:.7}.seed-data-table__footerCell .seed-data-table-column-calc-placeholder{overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__footerCell .seed-data-table-column-calc-value{min-width:0;flex-shrink:1;color:var(--seed-color-fg-neutral);font-variant-numeric:tabular-nums;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__footerCell .seed-data-table-column-calc-op{min-width:0;flex-shrink:1;color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__emptyState{box-sizing:border-box;text-align:center;padding-block:var(--seed-dimension-x8);padding-inline:var(--seed-dimension-x3);color:var(--seed-color-fg-neutral-subtle);font-size:var(--seed-font-size-t4)}.seed-data-table__loadingState{box-sizing:border-box;display:flex;align-items:center;justify-content:center;gap:10px;padding-block:var(--seed-dimension-x8);padding-inline:var(--seed-dimension-x3);color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-medium)}.seed-data-table__loadingState[data-inline]{padding-block:0;padding-inline:0;height:var(--seed-dimension-x9)}.seed-data-table__loadingState .seed-data-table-loading-spinner{flex-shrink:0;color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);animation:rotate .6s linear infinite}.seed-data-table__addRowCell{box-sizing:border-box;padding:0;border-top:none}.seed-data-table__addRow{box-sizing:border-box;display:flex;align-items:center;width:100%;margin:0;border:none;border-top:1px solid var(--seed-color-stroke-neutral-muted);background-color:var(--seed-color-bg-layer-default);height:var(--seed-dimension-x9);gap:var(--seed-dimension-x2);padding-inline:var(--seed-dimension-x2);color:var(--seed-color-fg-neutral-subtle);font-family:inherit;font-size:var(--seed-font-size-t4);cursor:pointer;transition:background-color .12s,color .12s}.seed-data-table__addRow:hover{background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,var(--seed-color-bg-layer-default));color:var(--seed-color-fg-neutral)}.seed-data-table__addRow svg{flex-shrink:0}.seed-data-table__selectionCell{text-align:center;padding:0}.seed-data-table__bulkBar{box-sizing:border-box;position:absolute;inset-inline-start:50%;transform:translateX(-50%);bottom:var(--seed-dimension-x4);z-index:30;display:flex;align-items:center;gap:var(--seed-dimension-x3);min-height:36px;padding-inline:var(--seed-dimension-x3_5);padding-block:var(--seed-dimension-x2);border-radius:var(--seed-radius-full);box-shadow:var(--seed-shadow-s3);background-color:var(--seed-color-bg-layer-floating);color:var(--seed-color-fg-neutral);font-family:inherit;font-size:var(--seed-font-size-t4);font-weight:var(--seed-font-weight-medium);white-space:nowrap}.seed-data-table__bulkBar[data-above-footer]{bottom:calc(var(--seed-dimension-x4) + var(--seed-dimension-x9))}.seed-data-table__bulkBarCount{flex-shrink:0;color:var(--seed-color-fg-neutral);font-variant-numeric:tabular-nums}.seed-data-table__bulkBarClear{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:20px;height:20px;margin:0;padding:2px;border:none;border-radius:6px;background:0 0;font-family:inherit;color:color-mix(in srgb,var(--seed-color-fg-neutral) 55%,transparent);cursor:pointer;transition:background-color .2s,color .2s}.seed-data-table__bulkBarClear:hover{background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 8%,transparent);color:var(--seed-color-fg-neutral)}.seed-data-table__bulkBarActions{display:flex;align-items:center;flex-shrink:0;gap:var(--seed-dimension-x3);padding-inline-start:var(--seed-dimension-x3);border-inline-start:1px solid color-mix(in srgb,var(--seed-color-fg-neutral) 16%,transparent)}.seed-data-table__root--surface_card{border-color:var(--seed-color-stroke-neutral-muted);background-color:var(--seed-color-bg-layer-default);border-radius:var(--seed-radius-r3)}.seed-data-table__root--surface_bleed{border-color:var(--seed-color-bg-transparent);background-color:var(--seed-color-bg-transparent)}.seed-data-table__row--interactive_true{transition:background-color .12s}.seed-data-table__row--interactive_true:is(:hover,[data-hover]){background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 3%,transparent);--seed-data-table-row-bg:color-mix(in srgb, var(--seed-color-fg-neutral) 3%, var(--seed-color-bg-layer-default))}");
|
|
4160
|
+
// Row-narrowing for the toolbar's search box -- split out of DataTable.tsx the way
|
|
4161
|
+
// cells.tsx splits out cell-type rendering: a self-contained, independently testable
|
|
4162
|
+
// concern DataTable.tsx just calls, rather than inline `.filter()` calls piling up in
|
|
4163
|
+
// the same component that also owns markup. The toolbar's typed Filter CONDITIONS
|
|
4164
|
+
// (field/operator/value chips, DATATABLE-ATTIO-SPEC.md's Attio/crisp model) live in
|
|
4165
|
+
// `toolbar-conditions.tsx` instead, alongside the Sort/Filter chrome that manages
|
|
4166
|
+
// them -- this file is search only now; the old per-column "is/is not" picker
|
|
4167
|
+
// (`matchesFilter`/`DataTableFilterState`) is gone, replaced by that toolbar model.
|
|
4168
|
+
/**
|
|
4169
|
+
* A column's `value(row)` if it supplies one, else the raw field at `column.key` --
|
|
4170
|
+
* the single accessor sort/search/filter/export all read through
|
|
4171
|
+
* (DATATABLE-ATTIO-SPEC.md's Column API), so a consumer only teaches the table how to
|
|
4172
|
+
* read a value ONCE rather than once per feature.
|
|
4173
|
+
*/ function getColumnValue(column, row) {
|
|
4174
|
+
return column.value ? column.value(row) : row[column.key];
|
|
4175
|
+
}
|
|
4176
|
+
/**
|
|
4177
|
+
* Case-insensitive substring match against a row's stringified value -- crisp's own
|
|
4178
|
+
* `applyFilters` "contains" semantics (`tabletoolbar.tsx`), reused here for the
|
|
4179
|
+
* toolbar's single free-text query. `null`/`undefined` never match a non-empty query --
|
|
4180
|
+
* there is no text to search.
|
|
4181
|
+
*/ function matchesSearch(value, query) {
|
|
4182
|
+
if (!query) return true;
|
|
4183
|
+
if (value == null) return false;
|
|
4184
|
+
return String(value).toLowerCase().includes(query.toLowerCase());
|
|
4185
|
+
}
|
|
4186
|
+
/**
|
|
4187
|
+
* The toolbar's search query -- an OR across `searchable` columns, matching GRC's own
|
|
4188
|
+
* `useFilteredRows`. The toolbar's own typed Filter conditions apply SEPARATELY, as a
|
|
4189
|
+
* second pass over this function's result (`toolbar-conditions.tsx`'s
|
|
4190
|
+
* `applyToolbarFilters`, called by `DataTable.tsx` right after this) -- narrowing what
|
|
4191
|
+
* the search box already found, not the other way round.
|
|
4192
|
+
*/ function getVisibleRows(data, columns, query) {
|
|
4193
|
+
const searchableColumns = columns.filter((column)=>column.searchable);
|
|
4194
|
+
if (!query) return data;
|
|
4195
|
+
return data.filter((row)=>searchableColumns.some((column)=>matchesSearch(getColumnValue(column, row), query)));
|
|
4196
|
+
}
|
|
4197
|
+
|
|
4198
|
+
__insertCSS(".seed-data-table__root{box-sizing:border-box;position:relative;display:flex;flex-direction:column;width:100%;border-width:1px;border-style:solid;font-family:Inter,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif}.seed-data-table__table{width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}.seed-data-table__headerCell{box-sizing:border-box;position:sticky;top:0;z-index:2;vertical-align:middle;text-align:start;padding:0;height:var(--seed-dimension-x10);background-color:var(--seed-color-bg-layer-default);border-top:1px solid var(--seed-color-stroke-neutral-muted);border-bottom:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-inline-start:none;color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-medium);letter-spacing:-.14px}.seed-data-table__headerCell:last-child{border-inline-end:none}.seed-data-table__headerCell[data-sortable]{cursor:pointer;user-select:none}.seed-data-table__headerCell [data-chevron]{opacity:0;transition:opacity .12s}.seed-data-table__headerCell[data-sortable]:hover [data-chevron]{opacity:.6}.seed-data-table__headerCell[data-sorted] [data-chevron]{opacity:1;color:var(--seed-color-fg-neutral)}.seed-data-table__headerCell:hover [data-column-menu]{opacity:1}.seed-data-table__headerCell [data-column-menu]:focus-visible,.seed-data-table__headerCell [data-column-menu][data-open]{opacity:1}.seed-data-table__headerCell[data-dragging]{opacity:.5}.seed-data-table__headerCell[data-sticky]{position:sticky;z-index:3;background-color:var(--seed-color-bg-layer-default)}.seed-data-table__headerCell{outline:var(--seed-dimension-x0_5) solid transparent;outline-offset:calc(var(--seed-dimension-x0_5) * -1)}.seed-data-table__headerCell:is(:focus-visible,[data-focus-visible]){outline:var(--seed-dimension-x0_5) solid var(--seed-color-stroke-focus-ring);outline-offset:calc(var(--seed-dimension-x0_5) * -1)}.seed-data-table__headerCell .seed-data-table-resize-handle{position:absolute;top:0;inset-inline-end:calc(7px / -2);width:7px;height:100%;z-index:4;display:flex;align-items:center;justify-content:center;cursor:col-resize;touch-action:none}.seed-data-table__headerCell .seed-data-table-resize-handle-inner{width:3px;height:100%;border-radius:3px;background-color:#0298d9;opacity:0;transition:opacity .1s}.seed-data-table__headerCell .seed-data-table-resize-handle:hover .seed-data-table-resize-handle-inner,.seed-data-table__headerCell .seed-data-table-resize-handle[data-resizing] .seed-data-table-resize-handle-inner{opacity:1}.seed-data-table__headerCellInner{box-sizing:border-box;display:flex;align-items:center;width:100%;height:100%;min-width:0;gap:var(--seed-dimension-x1_5);padding-inline:var(--seed-dimension-x3)}.seed-data-table__headerCellLabel{min-width:0;flex:1 1 0%;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__headerCellIcon{flex-shrink:0;margin-inline-start:auto;display:inline-flex;align-items:center;justify-content:center;width:var(--seed-dimension-x4);height:var(--seed-dimension-x4);color:var(--seed-color-fg-neutral-subtle);border:none;background:0 0;padding:0;font:inherit;cursor:pointer}.seed-data-table__headerCellIcon[data-active]{color:var(--seed-color-fg-neutral)}.seed-data-table__headerCellIcon[data-column-menu]{opacity:0;transition:opacity .12s}.seed-data-table__row{position:relative;background-color:var(--seed-color-bg-layer-default);--seed-data-table-row-bg:var(--seed-color-bg-layer-default)}.seed-data-table__row[data-clickable]{cursor:pointer}.seed-data-table__row:is([aria-selected=true],[data-selected]){background-color:color-mix(in srgb,#0298d9 10%,var(--seed-color-bg-layer-default));--seed-data-table-row-bg:color-mix(in srgb, #0298d9 10%, var(--seed-color-bg-layer-default))}.seed-data-table__row:is([aria-selected=true],[data-selected]):is(:hover,[data-hover]){background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 3%,color-mix(in srgb,#0298d9 10%,var(--seed-color-bg-layer-default)));--seed-data-table-row-bg:color-mix(in srgb, var(--seed-color-fg-neutral) 3%, color-mix(in srgb, #0298d9 10%, var(--seed-color-bg-layer-default)))}.seed-data-table__cell{box-sizing:border-box;position:relative;vertical-align:middle;text-align:start;height:var(--seed-dimension-x9);border-bottom:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-top:none;border-inline-start:none;padding-block:0;padding-inline:var(--seed-dimension-x3);color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-regular);letter-spacing:-.14px;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__cell:not([data-editable]){user-select:none}.seed-data-table__cell:last-child{border-inline-end:none}tbody tr:last-child .seed-data-table__cell{border-bottom:none}.seed-data-table__cell[data-numeric]{text-align:end;font-variant-numeric:tabular-nums}.seed-data-table__cell[data-sticky]{position:sticky;z-index:1;background-color:var(--seed-data-table-row-bg)}.seed-data-table__cell[data-overlay-open]{overflow:visible;z-index:20}.seed-data-table__cell[data-editable]{cursor:default}.seed-data-table__cell .seed-data-table-edit-picker{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);min-width:0}.seed-data-table__cell .seed-data-table-edit-pending{flex-shrink:0;color:var(--seed-color-fg-neutral-subtle);animation:rotate .6s linear infinite}.seed-data-table__cell .seed-data-table-edit-error{position:absolute;top:100%;inset-inline-start:var(--seed-dimension-x3);inset-inline-end:var(--seed-dimension-x3);z-index:2;padding-top:2px;font-size:12px;line-height:1.3;color:var(--seed-color-fg-critical);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__entity{display:flex;align-items:center;min-width:0;gap:var(--seed-dimension-x1_5)}.seed-data-table__entityName{min-width:0;font-weight:var(--seed-font-weight-medium);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__entityName[data-clickable]{cursor:pointer;border:none;background:0 0;padding:0;margin:0;font-family:inherit;font-size:inherit;line-height:inherit;color:inherit;text-align:start}.seed-data-table__entityName[data-clickable]:is(:hover,[data-hover]){text-decoration:underline}.seed-data-table__tagList{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);overflow:hidden;min-width:0}.seed-data-table__entityActions{display:flex;align-items:center;gap:6px;margin-inline-start:auto;flex-shrink:0;opacity:0;transition:opacity .15s}tr:hover .seed-data-table__entityActions{opacity:1}.seed-data-table__entityActions:focus-within{opacity:1}.seed-data-table__entityAction{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin:0;padding:2px;border:none;border-radius:6px;background:0 0;font-family:inherit;color:color-mix(in srgb,var(--seed-color-fg-neutral) 55%,transparent);cursor:pointer;flex-shrink:0;transition:background-color .2s,color .2s,box-shadow .2s}.seed-data-table__entityAction:hover{background:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,transparent);color:var(--seed-color-fg-neutral)}.seed-data-table__link{color:var(--seed-color-fg-neutral);text-decoration:none;min-width:0;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__link:is(:hover,[data-hover]){text-decoration:underline}.seed-data-table__chip{box-sizing:border-box;display:inline-flex;align-items:center;flex-shrink:0;max-width:100%;height:22px;padding:0 4px;border-radius:7px;font-size:13px;font-weight:var(--seed-font-weight-medium);line-height:15px;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__chipList{position:relative;display:flex;align-items:center;flex-wrap:nowrap;gap:3px;overflow:hidden;min-width:0;width:100%}.seed-data-table__chipOverflow{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;height:20px;padding:0 4px;border-radius:6px;background-color:#f6f7f7;color:#000;font-size:10px;font-weight:var(--seed-font-weight-regular);line-height:15px;white-space:nowrap}.seed-data-table__chipPicker{display:flex;flex-direction:column;width:100%;min-width:0}.seed-data-table__chipPickerList{display:flex;flex-direction:column;max-height:240px;overflow-y:auto;padding:0 4px 4px}.seed-data-table__chipPickerRow{box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;min-height:32px;margin:0;padding:4px 8px;border:none;border-radius:6px;background:0 0;font:inherit;color:inherit;text-align:start;cursor:pointer}.seed-data-table__chipPickerRow:hover{background-color:#f6f7f7}.seed-data-table__chipPickerRow:disabled{cursor:default;opacity:.6}.seed-data-table__chipPickerBox{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:16px;height:16px;border-radius:4px;border:1px solid rgba(0,0,0,.25);background-color:#fff;color:#fff}.seed-data-table__chipPickerBox[data-checked]{border-color:#266df0;background-color:#266df0}.seed-data-table__chipPickerBox svg{width:12px;height:12px}.seed-data-table__chipPickerCreate{box-sizing:border-box;display:flex;align-items:center;gap:6px;width:100%;min-height:32px;margin:0;padding:4px 8px;border:none;border-radius:6px;background:0 0;font:inherit;font-size:var(--seed-font-size-t4);color:var(--seed-color-fg-neutral);text-align:start;cursor:pointer}.seed-data-table__chipPickerCreate:hover{background-color:#f6f7f7}.seed-data-table__expandOverlay{box-sizing:border-box;position:absolute;top:-1px;inset-inline-start:-1px;inset-inline-end:-1px;z-index:10;min-height:calc(100% + 2px);display:flex;align-items:flex-start;padding-inline:var(--seed-dimension-x3);padding-block:var(--seed-dimension-x3);background-color:var(--seed-color-bg-layer-floating);border-radius:4px;box-shadow:none;border:1px solid #266df0;color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);letter-spacing:-.14px;cursor:default}.seed-data-table__expandOverlayText{width:100%;min-width:0;white-space:normal;word-break:break-word}.seed-data-table__cellSuffixRow{display:flex;align-items:center;gap:4px;min-width:0;width:100%}.seed-data-table__cellSuffixText{flex:1 1 0%;min-width:0;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__cellSuffixIcon{flex-shrink:0;display:inline-flex;align-items:center;color:color-mix(in srgb,var(--seed-color-fg-neutral) 55%,transparent)}.seed-data-table__toolbar{box-sizing:border-box;display:flex;align-items:center;width:100%;flex-shrink:0;min-height:49px;gap:var(--seed-dimension-x2);padding-inline:var(--seed-dimension-x3);border-top:1px solid var(--seed-color-stroke-neutral-muted)}.seed-data-table__search{position:relative;display:inline-flex;align-items:center;flex:1 1 0%;max-width:280px}.seed-data-table__search svg{position:absolute;inset-inline-start:var(--seed-dimension-x2);width:var(--seed-dimension-x4);height:var(--seed-dimension-x4);color:var(--seed-color-fg-neutral-muted);pointer-events:none}.seed-data-table__search input{width:100%;height:var(--seed-dimension-x8);padding-inline-start:var(--seed-dimension-x7);padding-inline-end:var(--seed-dimension-x2);border:none;border-radius:var(--seed-radius-r2);background-color:var(--seed-color-bg-layer-default);box-shadow:inset 0 0 0 1px var(--seed-color-stroke-neutral-weak);font-family:inherit;font-size:var(--seed-font-size-t4);color:var(--seed-color-fg-neutral);outline:0;transition:box-shadow .1s var(--seed-timing-function-easing)}.seed-data-table__search input::placeholder{color:var(--seed-color-fg-neutral-subtle)}.seed-data-table__search input:focus{box-shadow:inset 0 0 0 2px var(--seed-color-stroke-neutral-contrast)}.seed-data-table__count{flex-shrink:0;color:var(--seed-color-fg-neutral-subtle);font-size:var(--seed-font-size-t3);font-variant-numeric:tabular-nums}.seed-data-table__toolbarEnd{flex-shrink:0;margin-inline-start:auto;display:inline-flex;align-items:center;gap:var(--seed-dimension-x2)}.seed-data-table__scrollArea{position:relative;display:flex;flex-direction:column;width:100%;min-width:0;flex:1 1 auto;min-height:0;overflow-x:auto;overflow-y:auto}.seed-data-table__scrollArea[data-scrolled-start] [data-sticky-edge]{clip-path:inset(0 -38px 0 0);box-shadow:6px 0 16px 4px rgba(0,0,0,.12)}.seed-data-table__scrollArea[data-scrolled-end] [data-sticky-edge-end]{clip-path:inset(0 0 0 -38px);box-shadow:-6px 0 16px 4px rgba(0,0,0,.12)}.seed-data-table__footerCell{box-sizing:border-box;position:sticky;bottom:0;z-index:2;vertical-align:middle;padding:0;height:var(--seed-dimension-x9);background-color:var(--seed-color-bg-layer-default);border-top:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-inline-start:none}.seed-data-table__footerCell:last-child{border-inline-end:none}.seed-data-table__footerCell[data-sticky]{z-index:3}.seed-data-table__footerCell .seed-data-table-column-calc-trigger{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);width:100%;height:100%;min-width:0;margin:0;padding:0 var(--seed-dimension-x3);border:none;background:0 0;color:var(--seed-color-fg-neutral-subtle);font-family:inherit;font-size:var(--seed-font-size-t4);font-weight:var(--seed-font-weight-medium);white-space:nowrap;overflow:clip;cursor:pointer;transition:background-color .12s,color .12s}.seed-data-table__footerCell .seed-data-table-column-calc-trigger:hover{background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,transparent);color:var(--seed-color-fg-neutral)}.seed-data-table__footerCell .seed-data-table-column-calc-trigger[data-align=right]{justify-content:flex-end}.seed-data-table__footerCell .seed-data-table-column-calc-trigger svg{flex-shrink:0;opacity:.7}.seed-data-table__footerCell .seed-data-table-column-calc-placeholder{overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__footerCell .seed-data-table-column-calc-value{min-width:0;flex-shrink:1;color:var(--seed-color-fg-neutral);font-variant-numeric:tabular-nums;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__footerCell .seed-data-table-column-calc-op{min-width:0;flex-shrink:1;color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__emptyState{box-sizing:border-box;text-align:center;padding-block:var(--seed-dimension-x8);padding-inline:var(--seed-dimension-x3);color:var(--seed-color-fg-neutral-subtle);font-size:var(--seed-font-size-t4)}.seed-data-table__loadingState{box-sizing:border-box;display:flex;align-items:center;justify-content:center;gap:10px;padding-block:var(--seed-dimension-x8);padding-inline:var(--seed-dimension-x3);color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-medium)}.seed-data-table__loadingState[data-inline]{padding-block:0;padding-inline:0;height:var(--seed-dimension-x9)}.seed-data-table__loadingState .seed-data-table-loading-spinner{flex-shrink:0;color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);animation:rotate .6s linear infinite}.seed-data-table__addRowCell{box-sizing:border-box;padding:0;border-top:none}.seed-data-table__addRow{box-sizing:border-box;display:flex;align-items:center;width:100%;margin:0;border:none;border-top:1px solid var(--seed-color-stroke-neutral-muted);background-color:var(--seed-color-bg-layer-default);height:var(--seed-dimension-x9);gap:var(--seed-dimension-x2);padding-inline:var(--seed-dimension-x2);color:var(--seed-color-fg-neutral-subtle);font-family:inherit;font-size:var(--seed-font-size-t4);cursor:pointer;transition:background-color .12s,color .12s}.seed-data-table__addRow:hover{background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,var(--seed-color-bg-layer-default));color:var(--seed-color-fg-neutral)}.seed-data-table__addRow svg{flex-shrink:0}.seed-data-table__selectionCell{text-align:center;padding:0}.seed-data-table__bulkBar{box-sizing:border-box;position:absolute;inset-inline-start:50%;transform:translateX(-50%);bottom:var(--seed-dimension-x4);z-index:30;display:flex;align-items:center;gap:var(--seed-dimension-x3);min-height:36px;padding-inline:var(--seed-dimension-x3_5);padding-block:var(--seed-dimension-x2);border-radius:var(--seed-radius-full);box-shadow:var(--seed-shadow-s3);background-color:var(--seed-color-bg-layer-floating);color:var(--seed-color-fg-neutral);font-family:inherit;font-size:var(--seed-font-size-t4);font-weight:var(--seed-font-weight-medium);white-space:nowrap}.seed-data-table__bulkBar[data-above-footer]{bottom:calc(var(--seed-dimension-x4) + var(--seed-dimension-x9))}.seed-data-table__bulkBarCount{flex-shrink:0;color:var(--seed-color-fg-neutral);font-variant-numeric:tabular-nums}.seed-data-table__bulkBarClear{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:20px;height:20px;margin:0;padding:2px;border:none;border-radius:6px;background:0 0;font-family:inherit;color:color-mix(in srgb,var(--seed-color-fg-neutral) 55%,transparent);cursor:pointer;transition:background-color .2s,color .2s}.seed-data-table__bulkBarClear:hover{background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 8%,transparent);color:var(--seed-color-fg-neutral)}.seed-data-table__bulkBarActions{display:flex;align-items:center;flex-shrink:0;gap:var(--seed-dimension-x3);padding-inline-start:var(--seed-dimension-x3);border-inline-start:1px solid color-mix(in srgb,var(--seed-color-fg-neutral) 16%,transparent)}.seed-data-table__root--surface_card{border-color:var(--seed-color-stroke-neutral-muted);background-color:var(--seed-color-bg-layer-default);border-radius:var(--seed-radius-r3)}.seed-data-table__root--surface_bleed{border-color:var(--seed-color-bg-transparent);background-color:var(--seed-color-bg-transparent)}.seed-data-table__row--interactive_true{transition:background-color .12s}.seed-data-table__row--interactive_true:is(:hover,[data-hover]){background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 3%,transparent);--seed-data-table-row-bg:color-mix(in srgb, var(--seed-color-fg-neutral) 3%, var(--seed-color-bg-layer-default))}");
|
|
4124
4199
|
|
|
4125
4200
|
const createClassName = (className, variants, compoundVariants = [])=>{
|
|
4126
4201
|
const variantKeys = Object.keys(variants);
|
|
@@ -4228,16 +4303,24 @@ const dataTableSlotNames = [
|
|
|
4228
4303
|
"seed-data-table__chipOverflow"
|
|
4229
4304
|
],
|
|
4230
4305
|
[
|
|
4231
|
-
"
|
|
4232
|
-
"seed-data-
|
|
4306
|
+
"chipPicker",
|
|
4307
|
+
"seed-data-table__chipPicker"
|
|
4308
|
+
],
|
|
4309
|
+
[
|
|
4310
|
+
"chipPickerList",
|
|
4311
|
+
"seed-data-table__chipPickerList"
|
|
4312
|
+
],
|
|
4313
|
+
[
|
|
4314
|
+
"chipPickerRow",
|
|
4315
|
+
"seed-data-table__chipPickerRow"
|
|
4233
4316
|
],
|
|
4234
4317
|
[
|
|
4235
|
-
"
|
|
4236
|
-
"seed-data-
|
|
4318
|
+
"chipPickerBox",
|
|
4319
|
+
"seed-data-table__chipPickerBox"
|
|
4237
4320
|
],
|
|
4238
4321
|
[
|
|
4239
|
-
"
|
|
4240
|
-
"seed-data-
|
|
4322
|
+
"chipPickerCreate",
|
|
4323
|
+
"seed-data-table__chipPickerCreate"
|
|
4241
4324
|
],
|
|
4242
4325
|
[
|
|
4243
4326
|
"expandOverlay",
|
|
@@ -4856,94 +4939,154 @@ function RatingEditor({ column, value, pending, onCommit }) {
|
|
|
4856
4939
|
});
|
|
4857
4940
|
}
|
|
4858
4941
|
////////////////////////////////////////////////////////////////////////////////////
|
|
4859
|
-
// -- editable: "chip-list"
|
|
4860
|
-
//
|
|
4861
|
-
//
|
|
4862
|
-
//
|
|
4863
|
-
//
|
|
4864
|
-
//
|
|
4865
|
-
//
|
|
4866
|
-
//
|
|
4867
|
-
//
|
|
4868
|
-
//
|
|
4869
|
-
// `
|
|
4870
|
-
//
|
|
4871
|
-
// after the very first tag. `DataTableBodyCell` instead tracks THIS editor's own
|
|
4872
|
-
// open/closed state in its local `overlayOpen`, independent of `editingCell`.
|
|
4873
|
-
// Every add/remove still commits the FULL next array through the same one-string
|
|
4874
|
-
// contract every other editor already uses (`useDataTableEdit`'s own doc
|
|
4875
|
-
// comment): `JSON.stringify(nextTags)`, which the consumer's `onEdit` parses back
|
|
4876
|
-
// -- crisp/GRC's contract stays "one string in, no typed union", not a second
|
|
4877
|
-
// commit shape invented for just this column.
|
|
4942
|
+
// -- editable: "chip-list" -- Attio's multi-select popover (0.14.0; replaces the
|
|
4943
|
+
// 0.10.0-0.13.0 free-text "Add..." tag adder, which stacked an empty input over the
|
|
4944
|
+
// chips and read as broken on an empty cell). Measured off Attio's Company
|
|
4945
|
+
// "Categories" cell: a search field pinned on top, below it a scrolling list of the
|
|
4946
|
+
// column's OPTIONS, each drawn as its own colored chip with a checkbox on the RIGHT
|
|
4947
|
+
// edge (filled blue when the tag is on this row); clicking a row toggles that tag
|
|
4948
|
+
// and the popover STAYS OPEN across toggles; typing filters the list; text matching
|
|
4949
|
+
// no option offers a "Create '<text>'" row (freeform tag columns, e.g. tether's
|
|
4950
|
+
// Labels). `body-cells.tsx`'s `DataTableBodyCell` opens this inside a portaled
|
|
4951
|
+
// `expandOverlay` on a plain click and closes it on blur/outside-click/Escape; it
|
|
4952
|
+
// tracks its own `overlayOpen` rather than `useDataTableEdit`'s `isEditing` gate,
|
|
4953
|
+
// since a sync commit closes `editingCell` on the first toggle.
|
|
4878
4954
|
//
|
|
4879
|
-
//
|
|
4880
|
-
// (
|
|
4881
|
-
//
|
|
4882
|
-
//
|
|
4883
|
-
//
|
|
4884
|
-
|
|
4955
|
+
// Commit contract is unchanged: every toggle/create commits the FULL next array as
|
|
4956
|
+
// `JSON.stringify(nextTags)` through the one-string `onCommit`, which the consumer's
|
|
4957
|
+
// `onEdit` parses back.
|
|
4958
|
+
//
|
|
4959
|
+
// Option source: `column.chipOptions` (value/label?/color?); tags already on the row
|
|
4960
|
+
// but absent from it are still listed (so they can be unchecked); with no
|
|
4961
|
+
// `chipOptions` at all, the distinct tags across the table's rows.
|
|
4962
|
+
/** Adds `tag` when absent, removes it when present -- the picker's one toggle. */ function toggleTag(tags, tag) {
|
|
4963
|
+
return tags.includes(tag) ? tags.filter((existing)=>existing !== tag) : [
|
|
4964
|
+
...tags,
|
|
4965
|
+
tag
|
|
4966
|
+
];
|
|
4967
|
+
}
|
|
4968
|
+
/** The option list a `chip-list` popover shows: declared `chipOptions` first, then any
|
|
4969
|
+
* selected tag not declared, then (only when nothing was declared) the distinct tags
|
|
4970
|
+
* across `rows`. */ function buildChipPickerOptions(column, tags, rows) {
|
|
4971
|
+
const seen = new Set();
|
|
4972
|
+
const out = [];
|
|
4973
|
+
function push(option) {
|
|
4974
|
+
if (!option.value || seen.has(option.value)) return;
|
|
4975
|
+
seen.add(option.value);
|
|
4976
|
+
out.push(option);
|
|
4977
|
+
}
|
|
4978
|
+
for (const option of column.chipOptions ?? [])push(option);
|
|
4979
|
+
for (const tag of tags)push({
|
|
4980
|
+
value: tag
|
|
4981
|
+
});
|
|
4982
|
+
if (!column.chipOptions) {
|
|
4983
|
+
const distinct = new Set();
|
|
4984
|
+
for (const row of rows){
|
|
4985
|
+
const raw = getColumnValue(column, row);
|
|
4986
|
+
if (Array.isArray(raw)) {
|
|
4987
|
+
for (const tag of raw)if (typeof tag === "string") distinct.add(tag);
|
|
4988
|
+
}
|
|
4989
|
+
}
|
|
4990
|
+
for (const tag of [
|
|
4991
|
+
...distinct
|
|
4992
|
+
].sort((x, y)=>x.localeCompare(y)))push({
|
|
4993
|
+
value: tag
|
|
4994
|
+
});
|
|
4995
|
+
}
|
|
4996
|
+
return out;
|
|
4997
|
+
}
|
|
4998
|
+
function ChipListEditor({ column, value, pending, onCommit, classNames, allRows = [] }) {
|
|
4885
4999
|
const tags = Array.isArray(value) ? value.filter((tag)=>!!tag) : [];
|
|
4886
|
-
const
|
|
5000
|
+
const built = buildChipPickerOptions(column, tags, allRows);
|
|
5001
|
+
// Options only ever GROW while the popover is open: with the row-derived fallback,
|
|
5002
|
+
// unchecking a tag that no other row carries would otherwise drop it from the list
|
|
5003
|
+
// and leave no way to re-check it.
|
|
5004
|
+
const knownRef = React.useRef([]);
|
|
5005
|
+
const known = knownRef.current;
|
|
5006
|
+
for (const option of built){
|
|
5007
|
+
const at = known.findIndex((entry)=>entry.value === option.value);
|
|
5008
|
+
if (at === -1) known.push(option);
|
|
5009
|
+
else known[at] = option;
|
|
5010
|
+
}
|
|
5011
|
+
const options = [
|
|
5012
|
+
...known
|
|
5013
|
+
];
|
|
5014
|
+
const optionText = React.useCallback((option)=>option.label ?? option.value, []);
|
|
5015
|
+
const { query, setQuery, filtered } = useSelectSearch(options, optionText);
|
|
5016
|
+
const trimmed = query.trim();
|
|
5017
|
+
const canCreate = column.chipCreatable !== false && trimmed !== "" && !options.some((option)=>option.value.toLowerCase() === trimmed.toLowerCase() || optionText(option).toLowerCase() === trimmed.toLowerCase());
|
|
4887
5018
|
function commitTags(next) {
|
|
4888
5019
|
onCommit(JSON.stringify(next));
|
|
4889
5020
|
}
|
|
4890
|
-
function
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
if (!tag || tags.includes(tag)) return;
|
|
4894
|
-
commitTags([
|
|
4895
|
-
...tags,
|
|
4896
|
-
tag
|
|
4897
|
-
]);
|
|
4898
|
-
}
|
|
4899
|
-
function removeTag(tag) {
|
|
4900
|
-
commitTags(tags.filter((existing)=>existing !== tag));
|
|
5021
|
+
function create() {
|
|
5022
|
+
setQuery("");
|
|
5023
|
+
commitTags(toggleTag(tags, trimmed));
|
|
4901
5024
|
}
|
|
4902
|
-
return(// biome-ignore lint/a11y/noStaticElementInteractions: not a widget -- this
|
|
4903
|
-
/*#__PURE__*/ jsxs("
|
|
4904
|
-
className: classNames.
|
|
5025
|
+
return(// biome-ignore lint/a11y/noStaticElementInteractions: not a widget -- this wrapper never responds to interaction on ITSELF, only stops propagation of events that already occurred on a real interactive descendant (the search input, the option rows). No role fits it because it isn't a control.
|
|
5026
|
+
/*#__PURE__*/ jsxs("div", {
|
|
5027
|
+
className: classNames.chipPicker,
|
|
4905
5028
|
onClick: (event)=>event.stopPropagation(),
|
|
4906
5029
|
children: [
|
|
4907
|
-
|
|
4908
|
-
value: tag,
|
|
4909
|
-
className: classNames.chip,
|
|
4910
|
-
children: /*#__PURE__*/ jsx("button", {
|
|
4911
|
-
type: "button",
|
|
4912
|
-
disabled: pending,
|
|
4913
|
-
"aria-label": `Remove ${tag}`,
|
|
4914
|
-
className: classNames.chipRemove,
|
|
4915
|
-
onClick: ()=>removeTag(tag),
|
|
4916
|
-
children: /*#__PURE__*/ jsx(IconXmarkLine_default, {
|
|
4917
|
-
size: 10
|
|
4918
|
-
})
|
|
4919
|
-
})
|
|
4920
|
-
}, tag)),
|
|
4921
|
-
/*#__PURE__*/ jsx("input", {
|
|
4922
|
-
// biome-ignore lint/a11y/noAutofocus: this editor only ever mounts in response to an explicit click that just opened it (never on page load), matching `SelectEditor`'s own `open` (controlled, always-open-on-mount) -- the same UX every gated editor in this file already gives via a component the linter can't see through (`TextFieldInput`/`SelectSearchField`), just on a bare `<input>` here since `chipInput` has no such wrapper.
|
|
5030
|
+
/*#__PURE__*/ jsx(SelectSearchField, {
|
|
4923
5031
|
autoFocus: true,
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
"aria-label": `Add tag to ${column.key}`,
|
|
4929
|
-
onChange: (event)=>setDraft(event.target.value),
|
|
5032
|
+
value: query,
|
|
5033
|
+
onChange: setQuery,
|
|
5034
|
+
placeholder: column.editorSearchPlaceholder ?? "Search…",
|
|
5035
|
+
"aria-label": `Search ${column.key}`,
|
|
4930
5036
|
onKeyDown: (event)=>{
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
// never reaches the row's own click/keyboard handling.
|
|
4937
|
-
if (event.key === "Escape") return;
|
|
4938
|
-
event.stopPropagation();
|
|
4939
|
-
if (event.key === "Enter") {
|
|
4940
|
-
event.preventDefault();
|
|
4941
|
-
addTag();
|
|
4942
|
-
} else if (event.key === "Backspace" && draft === "" && tags.length > 0) {
|
|
4943
|
-
removeTag(tags[tags.length - 1]);
|
|
4944
|
-
}
|
|
5037
|
+
if (event.key !== "Enter") return;
|
|
5038
|
+
event.preventDefault();
|
|
5039
|
+
if (pending) return;
|
|
5040
|
+
if (canCreate) create();
|
|
5041
|
+
else if (trimmed && filtered.length > 0) commitTags(toggleTag(tags, filtered[0].value));
|
|
4945
5042
|
}
|
|
4946
5043
|
}),
|
|
5044
|
+
/*#__PURE__*/ jsxs("div", {
|
|
5045
|
+
className: classNames.chipPickerList,
|
|
5046
|
+
role: "group",
|
|
5047
|
+
"aria-label": `${column.key} options`,
|
|
5048
|
+
children: [
|
|
5049
|
+
filtered.map((option)=>{
|
|
5050
|
+
const checked = tags.includes(option.value);
|
|
5051
|
+
return /*#__PURE__*/ jsxs("button", {
|
|
5052
|
+
type: "button",
|
|
5053
|
+
role: "checkbox",
|
|
5054
|
+
"aria-checked": checked,
|
|
5055
|
+
disabled: pending,
|
|
5056
|
+
className: classNames.chipPickerRow,
|
|
5057
|
+
// Keep focus in the search field so typing keeps filtering after a toggle.
|
|
5058
|
+
onMouseDown: (event)=>event.preventDefault(),
|
|
5059
|
+
onClick: ()=>commitTags(toggleTag(tags, option.value)),
|
|
5060
|
+
children: [
|
|
5061
|
+
/*#__PURE__*/ jsx(SwatchChip, {
|
|
5062
|
+
value: option.value,
|
|
5063
|
+
label: option.label,
|
|
5064
|
+
color: option.color,
|
|
5065
|
+
className: classNames.chip
|
|
5066
|
+
}),
|
|
5067
|
+
/*#__PURE__*/ jsx("span", {
|
|
5068
|
+
className: classNames.chipPickerBox,
|
|
5069
|
+
"data-checked": checked ? "" : undefined,
|
|
5070
|
+
children: checked && /*#__PURE__*/ jsx(IconCheckmarkFatFill_default, {
|
|
5071
|
+
"aria-hidden": "true"
|
|
5072
|
+
})
|
|
5073
|
+
})
|
|
5074
|
+
]
|
|
5075
|
+
}, option.value);
|
|
5076
|
+
}),
|
|
5077
|
+
canCreate && /*#__PURE__*/ jsx("button", {
|
|
5078
|
+
type: "button",
|
|
5079
|
+
disabled: pending,
|
|
5080
|
+
className: classNames.chipPickerCreate,
|
|
5081
|
+
onMouseDown: (event)=>event.preventDefault(),
|
|
5082
|
+
onClick: create,
|
|
5083
|
+
children: `Create '${trimmed}'`
|
|
5084
|
+
}),
|
|
5085
|
+
!canCreate && filtered.length === 0 && /*#__PURE__*/ jsx(SelectSearchEmpty, {
|
|
5086
|
+
children: column.editorEmptyLabel ?? "No results"
|
|
5087
|
+
})
|
|
5088
|
+
]
|
|
5089
|
+
}),
|
|
4947
5090
|
pending && /*#__PURE__*/ jsx(EditPendingIndicator, {})
|
|
4948
5091
|
]
|
|
4949
5092
|
}));
|
|
@@ -5032,44 +5175,6 @@ function CellExpandOverlay({ className, anchorRef, contentRef, children }) {
|
|
|
5032
5175
|
}), document.body);
|
|
5033
5176
|
}
|
|
5034
5177
|
|
|
5035
|
-
// Row-narrowing for the toolbar's search box -- split out of DataTable.tsx the way
|
|
5036
|
-
// cells.tsx splits out cell-type rendering: a self-contained, independently testable
|
|
5037
|
-
// concern DataTable.tsx just calls, rather than inline `.filter()` calls piling up in
|
|
5038
|
-
// the same component that also owns markup. The toolbar's typed Filter CONDITIONS
|
|
5039
|
-
// (field/operator/value chips, DATATABLE-ATTIO-SPEC.md's Attio/crisp model) live in
|
|
5040
|
-
// `toolbar-conditions.tsx` instead, alongside the Sort/Filter chrome that manages
|
|
5041
|
-
// them -- this file is search only now; the old per-column "is/is not" picker
|
|
5042
|
-
// (`matchesFilter`/`DataTableFilterState`) is gone, replaced by that toolbar model.
|
|
5043
|
-
/**
|
|
5044
|
-
* A column's `value(row)` if it supplies one, else the raw field at `column.key` --
|
|
5045
|
-
* the single accessor sort/search/filter/export all read through
|
|
5046
|
-
* (DATATABLE-ATTIO-SPEC.md's Column API), so a consumer only teaches the table how to
|
|
5047
|
-
* read a value ONCE rather than once per feature.
|
|
5048
|
-
*/ function getColumnValue(column, row) {
|
|
5049
|
-
return column.value ? column.value(row) : row[column.key];
|
|
5050
|
-
}
|
|
5051
|
-
/**
|
|
5052
|
-
* Case-insensitive substring match against a row's stringified value -- crisp's own
|
|
5053
|
-
* `applyFilters` "contains" semantics (`tabletoolbar.tsx`), reused here for the
|
|
5054
|
-
* toolbar's single free-text query. `null`/`undefined` never match a non-empty query --
|
|
5055
|
-
* there is no text to search.
|
|
5056
|
-
*/ function matchesSearch(value, query) {
|
|
5057
|
-
if (!query) return true;
|
|
5058
|
-
if (value == null) return false;
|
|
5059
|
-
return String(value).toLowerCase().includes(query.toLowerCase());
|
|
5060
|
-
}
|
|
5061
|
-
/**
|
|
5062
|
-
* The toolbar's search query -- an OR across `searchable` columns, matching GRC's own
|
|
5063
|
-
* `useFilteredRows`. The toolbar's own typed Filter conditions apply SEPARATELY, as a
|
|
5064
|
-
* second pass over this function's result (`toolbar-conditions.tsx`'s
|
|
5065
|
-
* `applyToolbarFilters`, called by `DataTable.tsx` right after this) -- narrowing what
|
|
5066
|
-
* the search box already found, not the other way round.
|
|
5067
|
-
*/ function getVisibleRows(data, columns, query) {
|
|
5068
|
-
const searchableColumns = columns.filter((column)=>column.searchable);
|
|
5069
|
-
if (!query) return data;
|
|
5070
|
-
return data.filter((row)=>searchableColumns.some((column)=>matchesSearch(getColumnValue(column, row), query)));
|
|
5071
|
-
}
|
|
5072
|
-
|
|
5073
5178
|
// Feature C (#12) -- the click-to-expand gate: measures whether a cell's rendered
|
|
5074
5179
|
// content is ACTUALLY truncated right now, so a single click only opens the
|
|
5075
5180
|
// anchored overlay (editors.tsx's `CellExpandOverlay`) when there's real hidden
|
|
@@ -5135,7 +5240,10 @@ function isCellTruncated(cell) {
|
|
|
5135
5240
|
* `overflow: visible` on every element in between and regardless of how high its
|
|
5136
5241
|
* `z-index` is raised -- neither of which is a stacking-context or overflow bug
|
|
5137
5242
|
* fixable from the INSIDE. A portal sidesteps it entirely by not being a
|
|
5138
|
-
* descendant of the sticky `<td>` at all once mounted. */
|
|
5243
|
+
* descendant of the sticky `<td>` at all once mounted. */ /** The table's full `data`, so an editable chip-list column with no `chipOptions` can
|
|
5244
|
+
* fall back to the distinct tags already present across rows. */ const DataTableRowsContext = /*#__PURE__*/ React.createContext([]);
|
|
5245
|
+
/** Attio's multi-select popover is wider than a narrow tags column. */ const CHIP_PICKER_MIN_WIDTH = 240;
|
|
5246
|
+
function isChipListEditable(column) {
|
|
5139
5247
|
return !!column.editable && column.type === "chip-list";
|
|
5140
5248
|
}
|
|
5141
5249
|
function ColumnBodyCells({ columns, row, classNames, locale, selectable, stickyFirst, stickyLast, cellContextMenu, onViewEditHistory, cellContextMenuItems }) {
|
|
@@ -5195,6 +5303,7 @@ function ColumnBodyCells({ columns, row, classNames, locale, selectable, stickyF
|
|
|
5195
5303
|
const [contextMenuOpen, setContextMenuOpen] = React.useState(false);
|
|
5196
5304
|
const alwaysLive = isAlwaysLiveEditable(column);
|
|
5197
5305
|
const chipListEditable = isChipListEditable(column);
|
|
5306
|
+
const allRows = React.useContext(DataTableRowsContext);
|
|
5198
5307
|
// A gated `editable` column (everything except the always-live widgets AND the
|
|
5199
5308
|
// click-to-edit chip-list) opens on double-click -- Attio's own measured gesture
|
|
5200
5309
|
// (crisp's #411), matched here rather than a single click, which stays "select
|
|
@@ -5224,7 +5333,10 @@ function ColumnBodyCells({ columns, row, classNames, locale, selectable, stickyF
|
|
|
5224
5333
|
top: rect.bottom,
|
|
5225
5334
|
insetInlineStart: rect.left,
|
|
5226
5335
|
insetInlineEnd: "auto",
|
|
5227
|
-
minWidth: rect.width,
|
|
5336
|
+
minWidth: Math.max(rect.width, CHIP_PICKER_MIN_WIDTH),
|
|
5337
|
+
// The multi-select popover owns its own inner padding (search field + option
|
|
5338
|
+
// rows inset themselves); the overlay's cell-editor padding would double it.
|
|
5339
|
+
padding: 0,
|
|
5228
5340
|
// Both override the SAME `expandOverlay` class properties this box also
|
|
5229
5341
|
// carries (`className={classNames.expandOverlay}`, below) -- that class's
|
|
5230
5342
|
// `minHeight: calc(100% + 2px)` resolves against an ANCHORED box's own
|
|
@@ -5371,7 +5483,10 @@ function ColumnBodyCells({ columns, row, classNames, locale, selectable, stickyF
|
|
|
5371
5483
|
chipListEditorOpen,
|
|
5372
5484
|
measurePopoverPosition
|
|
5373
5485
|
]);
|
|
5374
|
-
|
|
5486
|
+
// Never for a chip-list cell: its picker is its own portaled popover, and the
|
|
5487
|
+
// in-cell overlay box would show for the first frame only (a sync commit closes
|
|
5488
|
+
// `isEditing` on the first toggle) and overlap the popover's top edge.
|
|
5489
|
+
const overlayActive = overlayOpen && !chipListEditable && (alwaysLive || isEditing(row.id, column.key) || isPeeking(row.id, column.key));
|
|
5375
5490
|
const rawValue = getColumnValue(column, row);
|
|
5376
5491
|
const pending = isPending(row.id, column.key);
|
|
5377
5492
|
return /*#__PURE__*/ jsxs(Fragment, {
|
|
@@ -5429,7 +5544,8 @@ function ColumnBodyCells({ columns, row, classNames, locale, selectable, stickyF
|
|
|
5429
5544
|
value: resolveEditValue(column, row, rawValue),
|
|
5430
5545
|
pending: pending,
|
|
5431
5546
|
onCommit: (value)=>commitEdit(row.id, column.key, value),
|
|
5432
|
-
classNames: classNames
|
|
5547
|
+
classNames: classNames,
|
|
5548
|
+
allRows: allRows
|
|
5433
5549
|
})
|
|
5434
5550
|
}), document.body)
|
|
5435
5551
|
]
|
|
@@ -5483,7 +5599,8 @@ function ColumnBodyCells({ columns, row, classNames, locale, selectable, stickyF
|
|
|
5483
5599
|
value: rawValue,
|
|
5484
5600
|
className: classNames.chipList,
|
|
5485
5601
|
chipClassName: classNames.chip,
|
|
5486
|
-
overflowClassName: classNames.chipOverflow
|
|
5602
|
+
overflowClassName: classNames.chipOverflow,
|
|
5603
|
+
chipOptions: column.chipOptions
|
|
5487
5604
|
});
|
|
5488
5605
|
} else if (column.editable && isEditing(rowId, column.key)) {
|
|
5489
5606
|
if (column.editor === "select") {
|
|
@@ -5600,7 +5717,8 @@ function DisplayCellContent({ column, row, value, classNames, locale }) {
|
|
|
5600
5717
|
value: value,
|
|
5601
5718
|
className: classNames.chipList,
|
|
5602
5719
|
chipClassName: classNames.chip,
|
|
5603
|
-
overflowClassName: classNames.chipOverflow
|
|
5720
|
+
overflowClassName: classNames.chipOverflow,
|
|
5721
|
+
chipOptions: column.chipOptions
|
|
5604
5722
|
});
|
|
5605
5723
|
case "number":
|
|
5606
5724
|
return /*#__PURE__*/ jsx(Fragment, {
|
|
@@ -12020,223 +12138,226 @@ function DataTableInner(props, ref) {
|
|
|
12020
12138
|
const totalCols = columns.length + (selectable ? 1 : 0);
|
|
12021
12139
|
return /*#__PURE__*/ jsx(ClassNamesProvider, {
|
|
12022
12140
|
value: classNames,
|
|
12023
|
-
children: /*#__PURE__*/
|
|
12024
|
-
|
|
12025
|
-
|
|
12026
|
-
|
|
12027
|
-
|
|
12028
|
-
|
|
12029
|
-
|
|
12030
|
-
|
|
12031
|
-
|
|
12032
|
-
|
|
12033
|
-
|
|
12034
|
-
|
|
12035
|
-
|
|
12036
|
-
|
|
12037
|
-
|
|
12038
|
-
|
|
12039
|
-
|
|
12040
|
-
|
|
12041
|
-
|
|
12042
|
-
|
|
12043
|
-
|
|
12044
|
-
|
|
12045
|
-
|
|
12046
|
-
|
|
12047
|
-
|
|
12048
|
-
|
|
12049
|
-
|
|
12050
|
-
|
|
12051
|
-
|
|
12052
|
-
|
|
12053
|
-
|
|
12054
|
-
|
|
12055
|
-
|
|
12056
|
-
|
|
12057
|
-
|
|
12058
|
-
|
|
12059
|
-
|
|
12060
|
-
|
|
12061
|
-
|
|
12062
|
-
|
|
12063
|
-
|
|
12064
|
-
|
|
12065
|
-
|
|
12066
|
-
|
|
12067
|
-
|
|
12068
|
-
|
|
12069
|
-
|
|
12070
|
-
|
|
12071
|
-
onColumnsChange
|
|
12072
|
-
|
|
12073
|
-
|
|
12074
|
-
|
|
12075
|
-
|
|
12076
|
-
placeholder: searchPlaceholder,
|
|
12077
|
-
label: searchLabel
|
|
12078
|
-
}),
|
|
12079
|
-
/*#__PURE__*/ jsx(SortControl, {
|
|
12080
|
-
columns: columns
|
|
12081
|
-
}),
|
|
12082
|
-
/*#__PURE__*/ jsx(FilterControl, {
|
|
12083
|
-
columns: columns
|
|
12084
|
-
}),
|
|
12085
|
-
(showCount || toolbarActions) && /*#__PURE__*/ jsxs(DataTableToolbarEnd, {
|
|
12086
|
-
children: [
|
|
12087
|
-
toolbarActions,
|
|
12088
|
-
showCount && /*#__PURE__*/ jsx(RowCount, {
|
|
12089
|
-
shown: sortedData.length,
|
|
12090
|
-
total: data.length,
|
|
12091
|
-
countLabel: countLabel
|
|
12092
|
-
})
|
|
12093
|
-
]
|
|
12094
|
-
})
|
|
12095
|
-
]
|
|
12096
|
-
}),
|
|
12097
|
-
/*#__PURE__*/ jsx(DataTableScrollBody, {
|
|
12098
|
-
scrollProps: scrollProps,
|
|
12099
|
-
virtualized: virtualized,
|
|
12100
|
-
children: /*#__PURE__*/ jsxs(DataTableTable, {
|
|
12101
|
-
"aria-rowcount": virtualized ? sortedData.length + 1 : undefined,
|
|
12141
|
+
children: /*#__PURE__*/ jsx(DataTableRowsContext.Provider, {
|
|
12142
|
+
value: data,
|
|
12143
|
+
children: /*#__PURE__*/ jsxs(DataTableRoot, {
|
|
12144
|
+
ref: ref,
|
|
12145
|
+
className: clsx(classNames.root, className),
|
|
12146
|
+
rowIds: rowIds,
|
|
12147
|
+
selectable: selectable,
|
|
12148
|
+
selectedIds: selectedIds,
|
|
12149
|
+
defaultSelectedIds: defaultSelectedIds,
|
|
12150
|
+
onSelectionChange: onSelectionChange,
|
|
12151
|
+
sort: sort,
|
|
12152
|
+
defaultSort: defaultSort,
|
|
12153
|
+
onSortChange: handleSortChange,
|
|
12154
|
+
query: resolvedQuery,
|
|
12155
|
+
onQueryChange: handleQueryChange,
|
|
12156
|
+
toolbarSorts: resolvedToolbarSorts,
|
|
12157
|
+
onToolbarSortsChange: handleToolbarSortsChange,
|
|
12158
|
+
toolbarFilters: resolvedToolbarFilters,
|
|
12159
|
+
onToolbarFiltersChange: handleToolbarFiltersChange,
|
|
12160
|
+
columnKeys: columnKeys,
|
|
12161
|
+
actionsColumnKey: actionsColumnKey,
|
|
12162
|
+
columnOrder: columnOrder,
|
|
12163
|
+
defaultColumnOrder: defaultColumnOrder,
|
|
12164
|
+
onColumnOrderChange: onColumnOrderChange,
|
|
12165
|
+
hiddenColumnKeys: hiddenColumnKeys,
|
|
12166
|
+
defaultHiddenColumnKeys: defaultHiddenColumnKeys,
|
|
12167
|
+
onHiddenColumnKeysChange: onHiddenColumnKeysChange,
|
|
12168
|
+
columnWidths: columnWidths,
|
|
12169
|
+
defaultColumnWidths: defaultColumnWidths,
|
|
12170
|
+
onColumnWidthsChange: onColumnWidthsChange,
|
|
12171
|
+
columnLabels: columnLabels,
|
|
12172
|
+
defaultColumnLabels: defaultColumnLabels,
|
|
12173
|
+
onColumnLabelsChange: onColumnLabelsChange,
|
|
12174
|
+
pinnedColumnKeys: pinnedColumnKeys,
|
|
12175
|
+
defaultPinnedColumnKeys: defaultPinnedColumnKeys,
|
|
12176
|
+
onPinnedColumnKeysChange: onPinnedColumnKeysChange,
|
|
12177
|
+
columnCalcOps: columnCalcOps,
|
|
12178
|
+
defaultColumnCalcOps: defaultColumnCalcOps,
|
|
12179
|
+
onColumnCalcOpsChange: onColumnCalcOpsChange,
|
|
12180
|
+
onEdit: onEdit,
|
|
12181
|
+
onLoadMore: onLoadMore,
|
|
12182
|
+
hasMore: hasMore,
|
|
12183
|
+
loadingMore: loadingMore,
|
|
12184
|
+
virtualized: virtualized,
|
|
12185
|
+
rowHeight: rowHeight,
|
|
12186
|
+
overscan: overscan,
|
|
12187
|
+
...restProps,
|
|
12188
|
+
children: [
|
|
12189
|
+
onColumnsChange && /*#__PURE__*/ jsx(ColumnsChangeEffect, {
|
|
12190
|
+
columns: columns,
|
|
12191
|
+
onColumnsChange: onColumnsChange
|
|
12192
|
+
}),
|
|
12193
|
+
showToolbar && /*#__PURE__*/ jsxs(DataTableToolbar, {
|
|
12102
12194
|
children: [
|
|
12103
|
-
/*#__PURE__*/ jsx(
|
|
12104
|
-
|
|
12105
|
-
|
|
12106
|
-
stickyFirst: stickyFirst
|
|
12195
|
+
searchable && /*#__PURE__*/ jsx(SearchBox, {
|
|
12196
|
+
placeholder: searchPlaceholder,
|
|
12197
|
+
label: searchLabel
|
|
12107
12198
|
}),
|
|
12108
|
-
/*#__PURE__*/
|
|
12199
|
+
/*#__PURE__*/ jsx(SortControl, {
|
|
12200
|
+
columns: columns
|
|
12201
|
+
}),
|
|
12202
|
+
/*#__PURE__*/ jsx(FilterControl, {
|
|
12203
|
+
columns: columns
|
|
12204
|
+
}),
|
|
12205
|
+
(showCount || toolbarActions) && /*#__PURE__*/ jsxs(DataTableToolbarEnd, {
|
|
12109
12206
|
children: [
|
|
12110
|
-
|
|
12111
|
-
|
|
12112
|
-
|
|
12113
|
-
|
|
12114
|
-
|
|
12115
|
-
indeterminateIcon: selectionIndeterminateIcon ?? DEFAULT_INDETERMINATE_ICON
|
|
12116
|
-
})
|
|
12117
|
-
}),
|
|
12118
|
-
/*#__PURE__*/ jsx(ColumnHeaderCells, {
|
|
12119
|
-
columns: columns,
|
|
12120
|
-
columnMenu: columnMenu,
|
|
12121
|
-
reorderable: reorderable,
|
|
12122
|
-
resizable: resizable,
|
|
12123
|
-
sortIcon: sortIcon,
|
|
12124
|
-
selectable: !!selectable,
|
|
12125
|
-
stickyFirst: stickyFirst,
|
|
12126
|
-
stickyLast: resolvedStickyLast
|
|
12207
|
+
toolbarActions,
|
|
12208
|
+
showCount && /*#__PURE__*/ jsx(RowCount, {
|
|
12209
|
+
shown: sortedData.length,
|
|
12210
|
+
total: data.length,
|
|
12211
|
+
countLabel: countLabel
|
|
12127
12212
|
})
|
|
12128
12213
|
]
|
|
12129
|
-
})
|
|
12130
|
-
|
|
12131
|
-
|
|
12132
|
-
|
|
12133
|
-
|
|
12134
|
-
|
|
12135
|
-
|
|
12136
|
-
|
|
12214
|
+
})
|
|
12215
|
+
]
|
|
12216
|
+
}),
|
|
12217
|
+
/*#__PURE__*/ jsx(DataTableScrollBody, {
|
|
12218
|
+
scrollProps: scrollProps,
|
|
12219
|
+
virtualized: virtualized,
|
|
12220
|
+
children: /*#__PURE__*/ jsxs(DataTableTable, {
|
|
12221
|
+
"aria-rowcount": virtualized ? sortedData.length + 1 : undefined,
|
|
12222
|
+
children: [
|
|
12223
|
+
/*#__PURE__*/ jsx(DataTableColGroup, {
|
|
12224
|
+
columns: columns,
|
|
12225
|
+
selectable: !!selectable,
|
|
12226
|
+
stickyFirst: stickyFirst
|
|
12227
|
+
}),
|
|
12228
|
+
/*#__PURE__*/ jsxs(DataTableHeader, {
|
|
12229
|
+
children: [
|
|
12230
|
+
selectable && /*#__PURE__*/ jsx(SelectionHeaderCell, {
|
|
12231
|
+
stickyFirst: stickyFirst,
|
|
12232
|
+
children: /*#__PURE__*/ jsx(SelectAllCheckbox, {
|
|
12233
|
+
label: selectAllLabel,
|
|
12234
|
+
checkedIcon: selectionCheckedIcon ?? DEFAULT_CHECKED_ICON,
|
|
12235
|
+
indeterminateIcon: selectionIndeterminateIcon ?? DEFAULT_INDETERMINATE_ICON
|
|
12236
|
+
})
|
|
12237
|
+
}),
|
|
12238
|
+
/*#__PURE__*/ jsx(ColumnHeaderCells, {
|
|
12239
|
+
columns: columns,
|
|
12240
|
+
columnMenu: columnMenu,
|
|
12241
|
+
reorderable: reorderable,
|
|
12242
|
+
resizable: resizable,
|
|
12243
|
+
sortIcon: sortIcon,
|
|
12244
|
+
selectable: !!selectable,
|
|
12245
|
+
stickyFirst: stickyFirst,
|
|
12246
|
+
stickyLast: resolvedStickyLast
|
|
12137
12247
|
})
|
|
12138
|
-
|
|
12139
|
-
})
|
|
12140
|
-
|
|
12141
|
-
|
|
12142
|
-
children: /*#__PURE__*/ jsx(
|
|
12143
|
-
|
|
12144
|
-
children:
|
|
12248
|
+
]
|
|
12249
|
+
}),
|
|
12250
|
+
/*#__PURE__*/ jsx(DataTableBody, {
|
|
12251
|
+
children: loading ? /*#__PURE__*/ jsx("tr", {
|
|
12252
|
+
children: /*#__PURE__*/ jsx(DataTableCell, {
|
|
12253
|
+
colSpan: totalCols,
|
|
12254
|
+
children: /*#__PURE__*/ jsx(LoadingStateContent, {
|
|
12255
|
+
label: loadingLabel,
|
|
12256
|
+
classNames: classNames
|
|
12257
|
+
})
|
|
12145
12258
|
})
|
|
12146
|
-
})
|
|
12147
|
-
|
|
12148
|
-
|
|
12149
|
-
|
|
12150
|
-
|
|
12151
|
-
|
|
12152
|
-
|
|
12259
|
+
}) : error ? /*#__PURE__*/ jsx("tr", {
|
|
12260
|
+
children: /*#__PURE__*/ jsx(DataTableCell, {
|
|
12261
|
+
colSpan: totalCols,
|
|
12262
|
+
children: /*#__PURE__*/ jsx(EmptyStateContent, {
|
|
12263
|
+
classNames: classNames,
|
|
12264
|
+
children: error
|
|
12265
|
+
})
|
|
12153
12266
|
})
|
|
12154
|
-
})
|
|
12155
|
-
|
|
12156
|
-
children: [
|
|
12157
|
-
/*#__PURE__*/ jsx(WindowedRows, {
|
|
12158
|
-
rows: sortedData,
|
|
12159
|
-
virtualized: virtualized,
|
|
12267
|
+
}) : sortedData.length === 0 ? /*#__PURE__*/ jsx("tr", {
|
|
12268
|
+
children: /*#__PURE__*/ jsx(DataTableCell, {
|
|
12160
12269
|
colSpan: totalCols,
|
|
12161
|
-
children:
|
|
12162
|
-
|
|
12163
|
-
|
|
12164
|
-
|
|
12165
|
-
|
|
12166
|
-
|
|
12167
|
-
|
|
12168
|
-
|
|
12169
|
-
|
|
12170
|
-
|
|
12171
|
-
|
|
12172
|
-
|
|
12173
|
-
|
|
12174
|
-
|
|
12175
|
-
|
|
12176
|
-
|
|
12177
|
-
|
|
12178
|
-
|
|
12179
|
-
|
|
12270
|
+
children: /*#__PURE__*/ jsx(EmptyStateContent, {
|
|
12271
|
+
classNames: classNames,
|
|
12272
|
+
children: empty
|
|
12273
|
+
})
|
|
12274
|
+
})
|
|
12275
|
+
}) : /*#__PURE__*/ jsxs(Fragment, {
|
|
12276
|
+
children: [
|
|
12277
|
+
/*#__PURE__*/ jsx(WindowedRows, {
|
|
12278
|
+
rows: sortedData,
|
|
12279
|
+
virtualized: virtualized,
|
|
12280
|
+
colSpan: totalCols,
|
|
12281
|
+
children: (windowRows, firstIndex)=>/*#__PURE__*/ jsx(Fragment, {
|
|
12282
|
+
children: windowRows.map((row, offset)=>/*#__PURE__*/ jsxs(DataTableRow, {
|
|
12283
|
+
rowId: row.id,
|
|
12284
|
+
"aria-rowindex": virtualized ? firstIndex + offset + 2 : undefined,
|
|
12285
|
+
"data-clickable": onRowClick ? "" : undefined,
|
|
12286
|
+
onClick: onRowClick ? ()=>onRowClick(row) : undefined,
|
|
12287
|
+
children: [
|
|
12288
|
+
selectable && /*#__PURE__*/ jsx(SelectionCell, {
|
|
12289
|
+
// The row itself carries `onClick={onRowClick}` above, and a
|
|
12290
|
+
// native click on this cell's checkbox bubbles up through it
|
|
12291
|
+
// (React attaches DataTableRow's handler on the <tr>, which
|
|
12292
|
+
// sits between the checkbox and anything a consumer could stop
|
|
12293
|
+
// it from at -- so this has to live here, not in the consumer).
|
|
12294
|
+
// Without this, checking a row's box also fires `onRowClick`.
|
|
12295
|
+
onClick: (event)=>event.stopPropagation(),
|
|
12296
|
+
stickyFirst: stickyFirst,
|
|
12297
|
+
children: /*#__PURE__*/ jsx(RowCheckbox, {
|
|
12298
|
+
label: getRowSelectionLabel(row),
|
|
12299
|
+
checkedIcon: selectionCheckedIcon ?? DEFAULT_CHECKED_ICON
|
|
12300
|
+
})
|
|
12301
|
+
}),
|
|
12302
|
+
/*#__PURE__*/ jsx(ColumnBodyCells, {
|
|
12303
|
+
columns: columns,
|
|
12304
|
+
row: row,
|
|
12305
|
+
classNames: classNames,
|
|
12306
|
+
locale: locale,
|
|
12307
|
+
selectable: !!selectable,
|
|
12308
|
+
stickyFirst: stickyFirst,
|
|
12309
|
+
stickyLast: resolvedStickyLast,
|
|
12310
|
+
cellContextMenu: cellContextMenu,
|
|
12311
|
+
onViewEditHistory: onViewEditHistory,
|
|
12312
|
+
cellContextMenuItems: cellContextMenuItems
|
|
12180
12313
|
})
|
|
12181
|
-
|
|
12182
|
-
|
|
12183
|
-
|
|
12184
|
-
|
|
12185
|
-
|
|
12186
|
-
|
|
12187
|
-
|
|
12188
|
-
|
|
12189
|
-
|
|
12190
|
-
|
|
12191
|
-
|
|
12192
|
-
|
|
12193
|
-
|
|
12194
|
-
|
|
12195
|
-
|
|
12196
|
-
|
|
12314
|
+
]
|
|
12315
|
+
}, row.id))
|
|
12316
|
+
})
|
|
12317
|
+
}),
|
|
12318
|
+
onLoadMore && /*#__PURE__*/ jsx(InfiniteScrollRow, {
|
|
12319
|
+
colSpan: totalCols,
|
|
12320
|
+
classNames: classNames,
|
|
12321
|
+
loadingLabel: loadingLabel
|
|
12322
|
+
})
|
|
12323
|
+
]
|
|
12324
|
+
})
|
|
12325
|
+
}),
|
|
12326
|
+
showFooter && /*#__PURE__*/ jsxs(DataTableFooter, {
|
|
12327
|
+
children: [
|
|
12328
|
+
selectable && // The 40px-wide selection SPACER cell is now a plain `DataTableFooterCell`
|
|
12329
|
+
// (not the `selectionCell` slot) -- the `<colgroup>`'s own 40px `<col>`
|
|
12330
|
+
// is what makes every row's selection column line up now, not a matching
|
|
12331
|
+
// per-slot width formula, so there is no more reason for this cell to
|
|
12332
|
+
// borrow a different slot than its footer siblings.
|
|
12333
|
+
/*#__PURE__*/ jsx(SelectionFooterCell, {
|
|
12334
|
+
stickyFirst: stickyFirst
|
|
12197
12335
|
}),
|
|
12198
|
-
|
|
12199
|
-
|
|
12200
|
-
|
|
12201
|
-
|
|
12336
|
+
/*#__PURE__*/ jsx(ColumnCalcCells, {
|
|
12337
|
+
columns: columns,
|
|
12338
|
+
rows: sortedData,
|
|
12339
|
+
selectable: !!selectable,
|
|
12340
|
+
stickyFirst: stickyFirst,
|
|
12341
|
+
stickyLast: resolvedStickyLast
|
|
12202
12342
|
})
|
|
12203
12343
|
]
|
|
12344
|
+
}),
|
|
12345
|
+
onAddRow && /*#__PURE__*/ jsx(AddRowFooter, {
|
|
12346
|
+
onAddRow: onAddRow,
|
|
12347
|
+
addRowLabel: addRowLabel,
|
|
12348
|
+
colSpan: totalCols,
|
|
12349
|
+
classNames: classNames
|
|
12204
12350
|
})
|
|
12205
|
-
|
|
12206
|
-
|
|
12207
|
-
|
|
12208
|
-
|
|
12209
|
-
|
|
12210
|
-
|
|
12211
|
-
|
|
12212
|
-
// borrow a different slot than its footer siblings.
|
|
12213
|
-
/*#__PURE__*/ jsx(SelectionFooterCell, {
|
|
12214
|
-
stickyFirst: stickyFirst
|
|
12215
|
-
}),
|
|
12216
|
-
/*#__PURE__*/ jsx(ColumnCalcCells, {
|
|
12217
|
-
columns: columns,
|
|
12218
|
-
rows: sortedData,
|
|
12219
|
-
selectable: !!selectable,
|
|
12220
|
-
stickyFirst: stickyFirst,
|
|
12221
|
-
stickyLast: resolvedStickyLast
|
|
12222
|
-
})
|
|
12223
|
-
]
|
|
12224
|
-
}),
|
|
12225
|
-
onAddRow && /*#__PURE__*/ jsx(AddRowFooter, {
|
|
12226
|
-
onAddRow: onAddRow,
|
|
12227
|
-
addRowLabel: addRowLabel,
|
|
12228
|
-
colSpan: totalCols,
|
|
12229
|
-
classNames: classNames
|
|
12230
|
-
})
|
|
12231
|
-
]
|
|
12351
|
+
]
|
|
12352
|
+
})
|
|
12353
|
+
}),
|
|
12354
|
+
selectable && /*#__PURE__*/ jsx(DataTableBulkBar, {
|
|
12355
|
+
clearLabel: clearSelectionLabel,
|
|
12356
|
+
aboveFooter: showFooter || !!onAddRow,
|
|
12357
|
+
children: bulkActions
|
|
12232
12358
|
})
|
|
12233
|
-
|
|
12234
|
-
|
|
12235
|
-
clearLabel: clearSelectionLabel,
|
|
12236
|
-
aboveFooter: showFooter || !!onAddRow,
|
|
12237
|
-
children: bulkActions
|
|
12238
|
-
})
|
|
12239
|
-
]
|
|
12359
|
+
]
|
|
12360
|
+
})
|
|
12240
12361
|
})
|
|
12241
12362
|
});
|
|
12242
12363
|
}
|