@crisp-ui-kit/crisp 0.54.8 → 0.54.10
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/board.css +32 -8
- package/dist/board.layered.css +32 -8
- package/dist/cjs/components/contextmenu/contextmenu.js +2 -2
- package/dist/cjs/components/contextmenu/contextmenu.recipe.js +24 -0
- package/dist/cjs/components/datatable/datatable.js +593 -51
- package/dist/cjs/components/datatable/datatable.recipe.js +67 -3
- package/dist/cjs/components/dialog/dialog.js +65 -1
- package/dist/cjs/components/tabletoolbar/tabletoolbar.chrome.js +37 -2
- package/dist/cjs/components/tabletoolbar/tabletoolbar.js +218 -39
- package/dist/cjs/components/tabletoolbar/tabletoolbar.recipe.js +48 -1
- package/dist/cjs/components/text/text.recipe.js +17 -7
- package/dist/cjs/product/board/board.js +62 -28
- package/dist/cjs/product/board/board.recipe.js +42 -2
- package/dist/cjs/product/comments/comments.js +11 -2
- package/dist/cjs/product/comments/comments.recipe.js +14 -4
- package/dist/cjs/product/recordstable/recordstable.js +1 -17
- package/dist/cjs/product/savedviews/savedviews.js +55 -24
- package/dist/cjs/product/savedviews/savedviews.recipe.js +27 -0
- package/dist/comments.css +14 -4
- package/dist/comments.layered.css +14 -4
- package/dist/contextmenu.css +24 -0
- package/dist/contextmenu.layered.css +24 -0
- package/dist/datatable.css +106 -77
- package/dist/datatable.layered.css +106 -77
- package/dist/esm/components/contextmenu/contextmenu.js +2 -2
- package/dist/esm/components/contextmenu/contextmenu.recipe.js +24 -0
- package/dist/esm/components/datatable/datatable.js +593 -52
- package/dist/esm/components/datatable/datatable.recipe.js +68 -4
- package/dist/esm/components/dialog/dialog.js +65 -1
- package/dist/esm/components/tabletoolbar/tabletoolbar.chrome.js +37 -2
- package/dist/esm/components/tabletoolbar/tabletoolbar.js +219 -40
- package/dist/esm/components/tabletoolbar/tabletoolbar.recipe.js +50 -3
- package/dist/esm/components/text/text.recipe.js +17 -7
- package/dist/esm/product/board/board.js +63 -29
- package/dist/esm/product/board/board.recipe.js +42 -2
- package/dist/esm/product/comments/comments.js +12 -3
- package/dist/esm/product/comments/comments.recipe.js +14 -4
- package/dist/esm/product/recordstable/recordstable.js +2 -18
- package/dist/esm/product/savedviews/savedviews.js +57 -26
- package/dist/esm/product/savedviews/savedviews.recipe.js +27 -0
- package/dist/recordstable.css +33 -31
- package/dist/recordstable.layered.css +33 -31
- package/dist/savedviews.css +27 -0
- package/dist/savedviews.layered.css +27 -0
- package/dist/styles.css +282 -125
- package/dist/styles.layered.css +282 -125
- package/dist/tabletoolbar.css +45 -4
- package/dist/tabletoolbar.layered.css +45 -4
- package/dist/text.css +1 -1
- package/dist/text.layered.css +1 -1
- package/dist/types/components/contextmenu/contextmenu.d.ts +8 -1
- package/dist/types/components/datatable/datatable.d.ts +98 -2
- package/dist/types/components/tabletoolbar/tabletoolbar.d.ts +72 -2
- package/dist/types/components/text/text.recipe.d.ts +1 -1
- package/dist/types/product/board/board.d.ts +48 -2
- package/dist/types/product/comments/comments.d.ts +6 -1
- package/dist/types/product/recordstable/recordstable.d.ts +0 -1
- package/dist/types/product/savedviews/savedviews.d.ts +45 -8
- package/package.json +1 -1
package/dist/styles.layered.css
CHANGED
|
@@ -561,6 +561,30 @@
|
|
|
561
561
|
.crisp-contextmenu-item--danger:hover { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
|
|
562
562
|
.crisp-contextmenu-shortcut { margin-inline-start: auto; padding-inline-start: var(--crisp-space-3); color: var(--crisp-fg-muted); font-size: var(--crisp-text-sm); }
|
|
563
563
|
.crisp-contextmenu-sep { height: 1px; margin: var(--crisp-space-1) 0; border: none; background: var(--crisp-border-subtle); }
|
|
564
|
+
/* crisp/#598: Attio's OWN cell-level context menu, measured live on
|
|
565
|
+
app.attio.com/techpartners/companies (right-click a data cell) --
|
|
566
|
+
theme-INDEPENDENT dark chrome, not this app's dark THEME (every
|
|
567
|
+
geometry value above -- 12px/8px radius, 4px/8px padding, 32px item
|
|
568
|
+
height, item gap included below -- already matched what was
|
|
569
|
+
measured here; only the colour pair differs, so only colours are
|
|
570
|
+
overridden). Same "#101112 / #eeeff1" dark-pill ink Tooltip
|
|
571
|
+
already hardcodes for the identical reason (that surface is ALSO
|
|
572
|
+
theme-independent). */
|
|
573
|
+
.crisp-contextmenu-content[data-variant="dark"] { background: #101112; box-shadow: none; }
|
|
574
|
+
.crisp-contextmenu-content[data-variant="dark"] .crisp-contextmenu-item { gap: var(--crisp-space-1-5); color: #eeeff1; }
|
|
575
|
+
.crisp-contextmenu-content[data-variant="dark"] .crisp-contextmenu-item svg { color: #898a8d; }
|
|
576
|
+
/* Plain-item hover re-measured live on the same cell menu (right-click
|
|
577
|
+
"Description" on app.attio.com/techpartners/companies, hover the
|
|
578
|
+
"Copy" row): getComputedStyle on the row is rgba(255,255,255,0.1),
|
|
579
|
+
not the 0.08 this used to guess at. The danger row's own hover
|
|
580
|
+
(hovering "Clear value") still didn't get re-measured -- that one
|
|
581
|
+
remains the derived red-on-black translation below, flagged on
|
|
582
|
+
crisp#598 for someone to confirm live. */
|
|
583
|
+
.crisp-contextmenu-content[data-variant="dark"] .crisp-contextmenu-item:hover { background: rgba(255,255,255,0.1); }
|
|
584
|
+
.crisp-contextmenu-content[data-variant="dark"] .crisp-contextmenu-item--danger { color: #ff5454; }
|
|
585
|
+
.crisp-contextmenu-content[data-variant="dark"] .crisp-contextmenu-item--danger svg { color: #ff5454; }
|
|
586
|
+
.crisp-contextmenu-content[data-variant="dark"] .crisp-contextmenu-item--danger:hover { background: rgba(255,84,84,0.12); }
|
|
587
|
+
.crisp-contextmenu-content[data-variant="dark"] .crisp-contextmenu-sep { background: rgba(255,255,255,0.1); }
|
|
564
588
|
|
|
565
589
|
.crisp-contextmenu {
|
|
566
590
|
display: contents; font-family: var(--crisp-font-sans);
|
|
@@ -585,61 +609,71 @@
|
|
|
585
609
|
& .crisp-datatable-count { margin-inline-start: auto; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
|
|
586
610
|
/* announced, never drawn */
|
|
587
611
|
& .crisp-datatable-live { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
|
|
588
|
-
/*
|
|
612
|
+
/* crisp/#645: visually-hidden-but-focusable, not visually-hidden-and- inert like .crisp-datatable-live above -- same clip-rect shape, this one just needs to actually hold DOM focus so a native copy/paste event has something to fire on (see its own comment in datatable.tsx). resize: none keeps a stray native textarea handle from ever being drawable, even though it's clipped to 1px anyway. */
|
|
613
|
+
& .crisp-datatable-clipboard-proxy {
|
|
614
|
+
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
|
|
615
|
+
overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
|
|
616
|
+
resize: none;
|
|
617
|
+
}
|
|
618
|
+
/* single active cell (crisp/#645 follow-up -- this had no styling of its
|
|
619
|
+
own at all before, a gap against Golden Rule 0: RecordsTable's own measured value, .crisp-recordstable-td[data-selected], brought across unchanged now that a visible anchor actually matters for the Shift+Click range below). */
|
|
620
|
+
& td[data-selected] { outline: 2px solid var(--crisp-bg-brand-solid); outline-offset: -2px; border-radius: var(--crisp-radius-sm); z-index: 3; }
|
|
621
|
+
/* crisp/#645, G-101: a Shift+Click range -- reuses the row-selection tint formula already used twice below (tbody tr[data-selected] td) for the same reason a selected group of rows gets one: a selected GROUP of cells is the same kind of state, just cell-scoped instead of row-scoped. Not independently re-measured against Attio's own range
|
|
622
|
+
highlight (out of scope this slice -- flagged on crisp#645). */
|
|
623
|
+
& td[data-in-range] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 10%, var(--crisp-bg-surface));
|
|
624
|
+
} /* The header cell has no padding of its own -- the button owns the full cell so the whole header is clickable (its own inset is 12px). Mirrors the summary-row fix. `& .crisp-table th`, not bare `& th` (found while re-checking #691's
|
|
589
625
|
own fix live): DataTable's root nests `Table`'s own wrapper, whose
|
|
590
|
-
`table.recipe.ts` carries `& th, & td { padding: 0 12px }
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
626
|
+
`table.recipe.ts` carries `& th, & td { padding: 0 12px }
|
|
627
|
+
` at the SAME specificity (.crisp-table th vs .crisp-datatable th, both one class + one element) -- a bare `& th` here only won by source order, which flipped the moment table.recipe.ts's own CSS file
|
|
628
|
+
happened to land after datatable's in the build (alphabetical: datatable < table), silently reinstating 12px on every header cell in the whole product and making every interactive column's button
|
|
629
|
+
double it to 24px. Scoping through `.crisp-table` adds a second
|
|
630
|
+
class to the selector (0,2,1 beats 0,1,1) so this can never lose a
|
|
631
|
+
specificity tie to source order again. */
|
|
596
632
|
& .crisp-table th { padding: 0; }
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
left to squeeze, the label's own ellipsis CSS (below) had no properly -sized box to truncate against, and the th's own overflow hard-clipped
|
|
601
|
-
it with no "...". Fill the wrapper, scoped to th so Menu's default (correct everywhere else) is untouched. */
|
|
633
|
+
/* Same wrapper trap as AUTHORING.md Lesson 40 (ColumnCalc's summary trigger): Menu wraps its trigger in a flex div that sizes to its content, so a long header grew past the column instead of filling it -- with nothing left to squeeze, the label's own ellipsis CSS (below) had no properly
|
|
634
|
+
-sized box to truncate against, and the th's own overflow hard-clipped it with no "...". Fill the wrapper, scoped to th so Menu's default
|
|
635
|
+
(correct everywhere else) is untouched. */
|
|
602
636
|
& th .crisp-menu { width: 100%; height: 100%; }
|
|
603
637
|
& .crisp-datatable-th-inner { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; min-width: 0; height: 100%; }
|
|
604
638
|
& .crisp-datatable-th-inner > svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
|
|
605
|
-
/* crisp/#605 follow-up: a header with neither a Menu nor a sort button
|
|
606
|
-
columnMenu/sortable at all) renders .crisp-datatable-th-inner as a
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
plain sort `button` both put >=1 more level between `th` and this
|
|
612
|
-
span, so their own 12px (already on the button) isn't doubled. */
|
|
639
|
+
/* crisp/#605 follow-up: a header with neither a Menu nor a sort button
|
|
640
|
+
(the primary/entity column's now-inert path, or any column with no columnMenu/sortable at all) renders .crisp-datatable-th-inner as a DIRECT child of th instead of nested inside a button -- and loses the button's own 12px inset, drifting left of the td's 12px base inset. Measured live on Attio's own Companies grid: the header label
|
|
641
|
+
and the cell's own text land at the exact same x (335px from the viewport, both 40px from the column's left edge) via two different
|
|
642
|
+
padding+icon+gap combinations -- Attio does not leave the inert
|
|
643
|
+
primary header flush left either. The `>` combinator targets only
|
|
644
|
+
the button-less case: Menu's own wrapper (`.crisp-menu`) and the plain sort `button` both put >=1 more level between `th` and this span, so their own 12px (already on the button) isn't doubled. */
|
|
613
645
|
& th > .crisp-datatable-th-inner { box-sizing: border-box; padding: 0 var(--crisp-space-3); }
|
|
614
|
-
|
|
646
|
+
/* The summary cell has NO padding of its own -- the calculation trigger
|
|
647
|
+
owns the whole 246x37 area so a click anywhere in the cell opens the
|
|
648
|
+
menu. Zero the cell's inset and let ColumnCalc supply the 12px. */
|
|
615
649
|
& tfoot td { padding: 0; }
|
|
616
|
-
/* Group heading row -- a view is grouped under a subtle label with the
|
|
617
|
-
|
|
618
|
-
& .crisp-datatable-viewsettings { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); height: var(--crisp-size-row); margin: 0; padding: 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-md); background: transparent; color: var(--crisp-fg-muted); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); white-space: nowrap; cursor: pointer; transition: background-color .12s, color .12s; }
|
|
650
|
+
/* Group heading row -- a view is grouped under a subtle label with the bucket's count beside it. */
|
|
651
|
+
& .crisp-datatable-viewsettings { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); height: var(--crisp-size-row); margin: 0; padding: 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-md); background: transparent; color: var(--crisp-fg-muted); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); white-space: nowrap; cursor: pointer; transition: background-color .12s, color .12s; }
|
|
619
652
|
& .crisp-datatable-viewsettings:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); color: var(--crisp-fg-primary); }
|
|
620
653
|
& .crisp-datatable-group-label { padding: var(--crisp-space-1-5) var(--crisp-space-2) var(--crisp-space-1); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
|
|
621
|
-
|
|
654
|
+
& .crisp-datatable-group { height: var(--crisp-size-menuRow); padding: 0 var(--crisp-space-3); background: var(--crisp-bg-subtle); border-bottom: 1px solid var(--crisp-border-subtle); font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
|
|
622
655
|
& .crisp-datatable-group-count { margin-inline-start: var(--crisp-space-1-5); color: var(--crisp-fg-muted); font-variant-numeric: tabular-nums; }
|
|
623
656
|
& .crisp-datatable-th-rename { width: 100%; min-width: 0; height: var(--crisp-size-row); margin: 0; padding: 0 var(--crisp-space-1); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); outline: none; }
|
|
624
657
|
& .crisp-datatable-th-rename:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
|
|
625
658
|
& .crisp-datatable-th-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
|
|
626
|
-
/* #465: 12px per the comment above (and Attio's measured header cell
|
|
627
|
-
padding: 0 12px) -- was still c.space["2"] (8px), drifted from its
|
|
628
|
-
own documented value. */
|
|
659
|
+
/* #465: 12px per the comment above (and Attio's measured header cell padding: 0 12px) -- was still c.space["2"] (8px), drifted from its own documented value. */
|
|
629
660
|
& .crisp-datatable-sort { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; min-width: 0; height: 100%; margin: 0; padding: 0 var(--crisp-space-3); border: none; background: none; font: inherit; letter-spacing: inherit; color: inherit; text-align: start; cursor: pointer; }
|
|
630
|
-
/* A right-aligned column's header keeps its field-icon + label packed at
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
661
|
+
/* A right-aligned column's header keeps its field-icon + label packed at
|
|
662
|
+
the START, matching its own values only in that the VALUES right-align
|
|
663
|
+
-- Attio's own right-aligned header (measured live: "Twitter follower
|
|
664
|
+
count") keeps the icon+label left and only the trailing column-menu icon sits pinned to the right edge, independent of the label's width
|
|
665
|
+
(#406, reversing #393's own justify-content: flex-end here). The chevron's own margin-inline-start: auto below already pins IT to the
|
|
666
|
+
end of a flex-start row with no override needed -- that's what pins the trailing icon on Attio too. */
|
|
635
667
|
& .crisp-datatable-chevron { margin-inline-start: auto; flex-shrink: 0; color: var(--crisp-fg-muted); opacity: 0; transition: opacity .12s; }
|
|
636
668
|
& .crisp-datatable-sort:hover .crisp-datatable-chevron { opacity: 0.6; }
|
|
637
669
|
& .crisp-datatable-sort[data-sorted] .crisp-datatable-chevron { opacity: 1; color: var(--crisp-fg-primary); }
|
|
638
670
|
/* sticky first column(s) + horizontal scroll shadow — RecordsTable's feel */
|
|
639
671
|
& th[data-sticky], & td[data-sticky] { position: sticky; z-index: 1; background: var(--crisp-bg-surface); }
|
|
640
|
-
& th[data-sticky] { z-index: 3;
|
|
641
|
-
/* #554: a footer sticky-column cell sits in the bottom-sticky row (table.recipe.ts's
|
|
642
|
-
`tfoot td { z-index: 2 }
|
|
672
|
+
& th[data-sticky] { z-index: 3;
|
|
673
|
+
} /* #554: a footer sticky-column cell sits in the bottom-sticky row (table.recipe.ts's
|
|
674
|
+
`tfoot td { z-index: 2 }
|
|
675
|
+
`), which `td[data-sticky]`'s own higher-specificity
|
|
676
|
+
`z-index: 1` would otherwise undercut -- keep it level with the row it's in. */
|
|
643
677
|
& tfoot td[data-sticky] { z-index: 2; }
|
|
644
678
|
& tbody tr[data-selected] td[data-sticky] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 10%, var(--crisp-bg-surface)); }
|
|
645
679
|
& tbody tr:hover td[data-sticky] { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, var(--crisp-bg-surface)); }
|
|
@@ -656,64 +690,84 @@
|
|
|
656
690
|
& tbody tr[data-selected] td { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 10%, var(--crisp-bg-surface)); }
|
|
657
691
|
& tbody tr[data-selected]:hover td { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, color-mix(in srgb, var(--crisp-bg-brand-solid) 10%, var(--crisp-bg-surface))); }
|
|
658
692
|
& .crisp-datatable-editable:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, var(--crisp-bg-surface)); cursor: text; }
|
|
693
|
+
/* crisp/#758: AI-enriched column marker, ported from RecordsTable's own already-measured value -- a full-bleed #9b69ff (bgPurple) wash at 4%, composited OVER whatever row-state background the cell already has (hover, selected), which is why it's an ::after overlay and not a
|
|
694
|
+
plain background. */
|
|
695
|
+
& td[data-enriched]::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: color-mix(in srgb, var(--crisp-bg-purple) 4%, transparent); }
|
|
659
696
|
& .crisp-datatable-edit { width: 100%; height: 28px; margin: 0; padding: 0 var(--crisp-space-1-5); border: none; border-radius: var(--crisp-radius-sm); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); outline: none; vertical-align: middle; }
|
|
660
697
|
& .crisp-datatable-edit:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
|
|
661
|
-
/* An async onEdit's in-flight state (#385) -- the field/picker dims and
|
|
662
|
-
stops accepting input rather than disappearing, so the just-typed or
|
|
663
|
-
just-chosen value stays visible while its commit is pending. Same
|
|
664
|
-
treatment Input already gives its own disabled state. */
|
|
698
|
+
/* An async onEdit's in-flight state (#385) -- the field/picker dims and stops accepting input rather than disappearing, so the just-typed or just-chosen value stays visible while its commit is pending. Same treatment Input already gives its own disabled state. */
|
|
665
699
|
& .crisp-datatable-edit:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
666
700
|
& .crisp-datatable-edit-pending { flex-shrink: 0; margin-inline-start: var(--crisp-space-1); color: var(--crisp-fg-muted); vertical-align: middle; }
|
|
667
|
-
/* The rejection's message, beside the cell's own content -- a sibling in
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
the row below, so it can never end up clipped by the scroll
|
|
671
|
-
container's overflow the way a position:fixed escape would need guarding against. */
|
|
701
|
+
/* The rejection's message, beside the cell's own content -- a sibling in the TableCell, never nested inside a column's own render output, so a
|
|
702
|
+
hover-only wrapper (a Tooltip, say) around a custom render can't hide it. Block-level: the row grows to fit it rather than floating over the row below, so it can never end up clipped by the scroll container's overflow the way a position:fixed escape would need
|
|
703
|
+
guarding against. */
|
|
672
704
|
& .crisp-datatable-edit-error { display: block; padding: var(--crisp-space-0-5) 0 0; font-size: var(--crisp-text-sm); color: var(--crisp-bg-danger); }
|
|
673
|
-
/* editor: "select"/"switch" -- always live, no separate edit mode, so
|
|
674
|
-
|
|
705
|
+
/* editor: "select"/"switch" -- always live, no separate edit mode, so
|
|
706
|
+
the cell IS the picker: same chromeless-fill treatment as
|
|
707
|
+
RecordsTable's own --picker cells (measured there already; DataTable shares RecordsTable's grid, Golden Rule 0). */
|
|
675
708
|
& .crisp-datatable-td--picker { padding: 0; }
|
|
676
709
|
& .crisp-datatable-edit-picker { display: flex; align-items: center; gap: var(--crisp-space-1); height: var(--crisp-size-tableRow); padding: 0 var(--crisp-space-2); }
|
|
677
710
|
& .crisp-datatable-edit-picker .crisp-select-trigger { flex: 1; min-width: 0; height: 100%; min-height: 0; border-radius: 0; box-shadow: none; padding: 0; }
|
|
678
711
|
& .crisp-datatable-td--picker .crisp-datatable-edit-error { padding-inline-start: var(--crisp-space-2); }
|
|
679
|
-
/* reference picker: a leading 16px avatar per option, plus a trailing
|
|
712
|
+
/* reference picker: a leading 16px avatar per option, plus a trailing
|
|
713
|
+
"Create X" row when the consumer supplies one (#449) -- same measured
|
|
714
|
+
values as RecordsTable's own .crisp-recordstable-refoption*. */
|
|
680
715
|
& .crisp-datatable-refoption { display: flex; align-items: center; gap: var(--crisp-space-2); min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
681
716
|
& .crisp-datatable-refoption-avatar { flex-shrink: 0; }
|
|
682
717
|
& .crisp-datatable-refoption--create { color: var(--crisp-fg-muted); }
|
|
683
718
|
& .crisp-datatable-empty { padding: var(--crisp-space-8) var(--crisp-space-3); text-align: center; color: var(--crisp-fg-muted); font-size: var(--crisp-text-lg); }
|
|
684
|
-
/* #579: click-to-expand overlay for a truncated cell -- a read-only,
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
core, not this cell), so growing a row here would fight it. Anchored
|
|
691
|
-
to the SAME column width the cell itself renders at (measured:
|
|
692
|
-
Attio's own overlay came out only slightly wider than the triggering cell's clientWidth -- the overshoot is this padding),
|
|
693
|
-
wrapping onto as many lines as the value needs; it CAN be clipped by
|
|
694
|
-
`.crisp-table-scroll`'s own `overflow: auto` if it grows past the visible viewport, same as the edit-error comment above already notes for any position:absolute escape -- unmeasured against Attio for this exact case, flagged rather than guessed. */
|
|
719
|
+
/* #579: click-to-expand overlay for a truncated cell -- a read-only, full-value card, settled live as click (not Attio's usual
|
|
720
|
+
hover-expand) and measured position: absolute, unlike this file's floating chrome (Menu/Select popovers) which portals and escapes the scroll container. Deliberately NOT the edit-error pattern above (grow the row, block-level, never clipped): a virtualized grid assumes a fixed row height for its scroll math (owned by the grid core, not this cell), so growing a row here would fight it. Anchored to the SAME column width the cell itself renders at (measured: Attio's own overlay came out only slightly wider than the
|
|
721
|
+
triggering cell's clientWidth -- the overshoot is this padding), wrapping onto as many lines as the value needs; it CAN be clipped by `.crisp-table-scroll`'s own `overflow: auto` if it grows past the
|
|
722
|
+
visible viewport, same as the edit-error comment above already
|
|
723
|
+
notes for any position:absolute escape -- unmeasured against Attio
|
|
724
|
+
for this exact case, flagged rather than guessed. */
|
|
695
725
|
& td[data-cell-expanded] { overflow: visible; z-index: 7; }
|
|
696
|
-
& .crisp-datatable-cell-overlay {
|
|
726
|
+
& .crisp-datatable-cell-overlay {
|
|
727
|
+
position: absolute; inset-inline-start: 0; top: 0; width: 100%; box-sizing: border-box;
|
|
728
|
+
padding: var(--crisp-space-2) var(--crisp-space-3); background: var(--crisp-bg-surface);
|
|
729
|
+
border: 1px solid var(--crisp-bg-brand-solid); border-radius: 4px;
|
|
730
|
+
font-family: var(--crisp-font-sans); font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium);
|
|
731
|
+
color: var(--crisp-fg-primary); white-space: normal; word-break: break-word; cursor: default;
|
|
732
|
+
}
|
|
697
733
|
/* fixed layout so column widths (and resize) are exact — like RecordsTable */
|
|
698
734
|
& table { table-layout: fixed; }
|
|
699
|
-
/* read-only/computed column marker (#596) -- sits just inside the
|
|
735
|
+
/* read-only/computed column marker (#596) -- sits just inside the
|
|
736
|
+
resize handle, same absolute-positioned-against-the-th approach the
|
|
737
|
+
handle itself uses, since th has zero padding and the button/inner
|
|
738
|
+
row fills the whole cell with no room left for a trailing sibling. */
|
|
700
739
|
& .crisp-datatable-readonly { position: absolute; top: 50%; inset-inline-end: 11px; transform: translateY(-50%); color: var(--crisp-fg-muted); pointer-events: none; z-index: 5; }
|
|
701
740
|
/* column resize grip */
|
|
702
741
|
& .crisp-datatable-resize { position: absolute; top: 0; inset-inline-end: -3px; width: 9px; height: 100%; cursor: col-resize; z-index: 6; touch-action: none; }
|
|
703
742
|
& .crisp-datatable-resize::after { content: ""; position: absolute; top: 0; inset-inline-start: 3px; width: 2px; height: 100%; background: var(--crisp-bg-brand-solid); opacity: 0; transition: opacity .12s; }
|
|
704
743
|
& .crisp-datatable-resize:hover::after, & .crisp-datatable-resize[data-resizing]::after { opacity: 1; }
|
|
744
|
+
/* crisp/#731 -- column drag-to-reorder. Measured live against Attio's own grid (the issue's own comment): the dragged header keeps full
|
|
745
|
+
opacity and the plain `pointer` cursor throughout (Attio draws no
|
|
746
|
+
ghost and no "grabbing" cursor of its own), so this adds nothing to
|
|
747
|
+
`[data-dragging]` itself -- the ONLY new paint is the drop-indicator
|
|
748
|
+
line, a 3px bar in the same measured brand blue the resize handle's own hover state (above) already uses, positioned on whichever edge of the hovered header the pointer is closer to. */
|
|
749
|
+
& th[data-dragging] { cursor: pointer; }
|
|
750
|
+
& th[data-drop-before]::before, & th[data-drop-after]::after { content: ""; position: absolute; top: 0; width: 3px; height: 100%; background: var(--crisp-bg-brand-solid); z-index: 6; pointer-events: none; }
|
|
751
|
+
& th[data-drop-before]::before { inset-inline-start: -1.5px; }
|
|
752
|
+
& th[data-drop-after]::after { inset-inline-end: -1.5px; }
|
|
705
753
|
/* typed cells — entity (avatar + name), colour-coded tags, numbers, dates */
|
|
706
754
|
& .crisp-datatable-entity { display: flex; align-items: center; gap: var(--crisp-space-1-5); min-width: 0; color: var(--crisp-fg-primary); font-weight: var(--crisp-weight-medium); }
|
|
707
|
-
|
|
708
|
-
|
|
755
|
+
/* crisp/#601, G-050: measured LIVE (getComputedStyle on the name text, plain hover vs rest) that Attio's underline is unconditional, not a
|
|
756
|
+
hover reveal -- identical at rest and on hover: text-decoration-color
|
|
757
|
+
is rgba(0,0,0,0.09), a 9% tint, not the name's own full-contrast text colour. The previous :hover-gated, full-contrast rule here was itself unmeasured and wrong in two ways at once. */
|
|
758
|
+
& .crisp-datatable-entity-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--crisp-fg-primary) 9%, transparent); }
|
|
709
759
|
& button.crisp-datatable-entity-name--link { margin: 0; padding: 0; border: none; background: none; font: inherit; color: inherit; letter-spacing: inherit; text-align: start; cursor: pointer; max-width: 100%; }
|
|
760
|
+
/* crisp/#601, G-048: two 20px ghost icons, right-aligned in the primary column, revealed on ROW hover (the issue's own title says "row
|
|
761
|
+
hover", and a live check confirmed hovering well past the name --
|
|
762
|
+
not just the icons' own hit target -- still reveals them) or keyboard focus. Measured live: border-radius 6px, icon colour rgba(0,0,0,0.55) at rest, darkening to the full text colour with a rgba(0,0,0,0.04) background on the icon's OWN hover -- both
|
|
763
|
+
expressed as color-mix against fgPrimary so they stay correct in
|
|
764
|
+
dark mode instead of a literal black that would invert. */
|
|
765
|
+
& .crisp-datatable-entity-actions { display: flex; align-items: center; gap: var(--crisp-space-1-5); margin-inline-start: auto; flex-shrink: 0; opacity: 0; }
|
|
766
|
+
& tr:hover .crisp-datatable-entity-actions, & .crisp-datatable-entity-actions:focus-within { opacity: 1; }
|
|
767
|
+
& .crisp-datatable-entity-action { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-sm); background: none; font-family: inherit; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); cursor: pointer; flex-shrink: 0; }
|
|
768
|
+
& .crisp-datatable-entity-action:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); color: var(--crisp-fg-primary); }
|
|
710
769
|
& .crisp-datatable-avatar { width: var(--crisp-size-icon); height: var(--crisp-size-icon); border-radius: var(--crisp-radius-sm); flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; font-size: 10px; line-height: 1; font-weight: var(--crisp-weight-semibold); text-transform: uppercase; color: var(--crisp-fg-on-brand); background: var(--crisp-bg-brand-solid); }
|
|
711
|
-
& .crisp-datatable-avatar[data-tone="success"] { background: var(--crisp-bg-success); }
|
|
712
|
-
& .crisp-datatable-avatar[data-tone="warning"] { background: var(--crisp-bg-warning); }
|
|
713
|
-
& .crisp-datatable-avatar[data-tone="danger"] { background: var(--crisp-bg-danger); }
|
|
714
|
-
& .crisp-datatable-avatar[data-tone="purple"] { background: var(--crisp-bg-purple); }
|
|
715
|
-
& .crisp-datatable-avatar[data-tone="cyan"] { background: var(--crisp-bg-cyan); }
|
|
716
|
-
& .crisp-datatable-avatar[data-tone="orange"] { background: var(--crisp-bg-orange); }
|
|
770
|
+
& .crisp-datatable-avatar[data-tone="success"] { background: var(--crisp-bg-success); } & .crisp-datatable-avatar[data-tone="warning"] { background: var(--crisp-bg-warning); } & .crisp-datatable-avatar[data-tone="danger"] { background: var(--crisp-bg-danger); } & .crisp-datatable-avatar[data-tone="purple"] { background: var(--crisp-bg-purple); } & .crisp-datatable-avatar[data-tone="cyan"] { background: var(--crisp-bg-cyan); } & .crisp-datatable-avatar[data-tone="orange"] { background: var(--crisp-bg-orange); }
|
|
717
771
|
& .crisp-datatable-avatar img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; }
|
|
718
772
|
& .crisp-datatable-tags { display: flex; align-items: center; gap: var(--crisp-space-1); overflow: hidden; }
|
|
719
773
|
& .crisp-datatable-tag { display: inline-flex; align-items: center; height: var(--crisp-size-chip); padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-chip); font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); white-space: nowrap; background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: color-mix(in srgb, var(--crisp-fg-primary) 82%, transparent); }
|
|
@@ -726,20 +780,19 @@
|
|
|
726
780
|
& .crisp-datatable-tag[data-tone="orange"] { background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); }
|
|
727
781
|
& .crisp-datatable-num { font-variant-numeric: tabular-nums; }
|
|
728
782
|
& .crisp-datatable-muted { color: var(--crisp-fg-muted); }
|
|
729
|
-
/* url/email cell types (#654) -- same measured values as RecordsTable's
|
|
730
|
-
own .crisp-recordstable-link, which this mirrors: no underline at
|
|
731
|
-
rest, underline on hover, own-colour text rather than a browser-blue
|
|
732
|
-
link. */
|
|
783
|
+
/* url/email cell types (#654) -- same measured values as RecordsTable's own .crisp-recordstable-link, which this mirrors: no underline at rest, underline on hover, own-colour text rather than a browser-blue link. */
|
|
733
784
|
& .crisp-datatable-link { color: var(--crisp-fg-primary); text-decoration: none; overflow: hidden; text-overflow: ellipsis; }
|
|
734
785
|
& .crisp-datatable-link:hover { text-decoration: underline; }
|
|
735
|
-
/* row drag-to-reorder -- a Settings > Objects > Attributes screen measures
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
(RecordsTable's reorderColumn) -- not a proprietary
|
|
786
|
+
/* row drag-to-reorder -- a Settings > Objects > Attributes screen measures a leading 20px grip column, a 16px grip icon, and the row's own
|
|
787
|
+
hairline doubling as the drop indicator (it tints toward the brand
|
|
788
|
+
colour as the active drop target). The affordance + geometry are
|
|
789
|
+
measured; the drag MECHANISM is crisp's existing house idiom -- HTML5 draggable + dataTransfer, the same one column reorder already uses (RecordsTable's reorderColumn) -- not a proprietary
|
|
790
|
+
pointer-events implementation. */
|
|
739
791
|
& .crisp-datatable-col-grip { width: 20px; padding: 0; text-align: center; }
|
|
740
792
|
& .crisp-datatable-grip { display: inline-flex; align-items: center; justify-content: center; width: 100%; height: 100%; margin: 0; border: none; border-radius: 0; background: none; font-family: inherit; color: var(--crisp-fg-muted); cursor: grab; }
|
|
741
793
|
& .crisp-datatable-grip:active { cursor: grabbing; }
|
|
742
794
|
& tbody tr[data-drop-target] td, & tbody tr[data-drop-target] th { box-shadow: inset 0 2px 0 0 var(--crisp-bg-brand-solid); transition: box-shadow .12s; }
|
|
795
|
+
[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
|
|
743
796
|
}
|
|
744
797
|
|
|
745
798
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -1807,7 +1860,7 @@
|
|
|
1807
1860
|
& .crisp-tabletoolbar-sort-learn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); font-size: var(--crisp-text-lg); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); text-decoration: none; }
|
|
1808
1861
|
& .crisp-tabletoolbar-sort-learn svg { flex-shrink: 0; }
|
|
1809
1862
|
& .crisp-tabletoolbar-sort-learn:hover { color: var(--crisp-fg-primary); }
|
|
1810
|
-
& .crisp-tabletoolbar-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
|
|
1863
|
+
& .crisp-tabletoolbar-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); text-align: left; text-decoration: none; cursor: pointer; }
|
|
1811
1864
|
& .crisp-tabletoolbar-menu-item:hover { background: var(--crisp-bg-raised); }
|
|
1812
1865
|
& .crisp-tabletoolbar-menu-item:disabled { opacity: 0.4; cursor: default; }
|
|
1813
1866
|
& .crisp-tabletoolbar-menu-item:disabled:hover { background: none; }
|
|
@@ -1815,7 +1868,25 @@
|
|
|
1815
1868
|
& .crisp-tabletoolbar-menu-item[data-on] svg { color: var(--crisp-bg-brand-solid); }
|
|
1816
1869
|
& .crisp-tabletoolbar-menu-item .crisp-tabletoolbar-menu-check { margin-left: auto; }
|
|
1817
1870
|
& .crisp-tabletoolbar-menu-input { height: var(--crisp-size-row); margin: var(--crisp-space-0-5); padding: 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-md); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); background: var(--crisp-bg-surface); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); outline: none; }
|
|
1818
|
-
& .crisp-tabletoolbar-menu-sep { height: 1px; background: var(--crisp-border-subtle); margin: var(--crisp-space-0-5) 0; }
|
|
1871
|
+
& .crisp-tabletoolbar-menu-sep { height: 1px; border: none; background: var(--crisp-border-subtle); margin: var(--crisp-space-0-5) 0; }
|
|
1872
|
+
/* #592: the Filter field picker's nested-scope header (back control +
|
|
1873
|
+
search, once drilled into a nestedColumns column) and a search
|
|
1874
|
+
result's own breadcrumb row ("Team › Twitter follower count", surfaced by the SAME query matching a nested column). menu-back reuses the established 28px icon-only control pattern this file already uses twice (sort-remove, the kebab segment) rather than an independent measurement of Attio's own back arrow. The breadcrumb
|
|
1875
|
+
colours ARE measured live: the parent segment muted at the same
|
|
1876
|
+
exact color-mix 63% sort-learn above already uses, the
|
|
1877
|
+
separator chevron and leaf segment both full fgPrimary (the
|
|
1878
|
+
generic menu-item svg rule below defaults every icon to
|
|
1879
|
+
fgMuted, so the separator needs its own override to read
|
|
1880
|
+
correctly here). */
|
|
1881
|
+
& .crisp-tabletoolbar-menu-nesthead { display: flex; align-items: center; gap: var(--crisp-space-1); margin: var(--crisp-space-0-5); }
|
|
1882
|
+
& .crisp-tabletoolbar-menu-nesthead .crisp-tabletoolbar-menu-input { flex: 1; margin: 0; }
|
|
1883
|
+
& .crisp-tabletoolbar-menu-back { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; flex-shrink: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-muted); cursor: pointer; }
|
|
1884
|
+
& .crisp-tabletoolbar-menu-back:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
|
|
1885
|
+
& .crisp-tabletoolbar-menu-item--expand { justify-content: space-between; }
|
|
1886
|
+
& .crisp-tabletoolbar-menu-item-path { display: inline-flex; align-items: center; gap: 2px; min-width: 0; overflow: hidden; }
|
|
1887
|
+
& .crisp-tabletoolbar-menu-item-path-parent { flex-shrink: 0; overflow: hidden; text-overflow: ellipsis; max-width: 100px; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
|
|
1888
|
+
& .crisp-tabletoolbar-menu-item-path-sep { flex-shrink: 0; color: var(--crisp-fg-primary); }
|
|
1889
|
+
& .crisp-tabletoolbar-menu-item-path > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1819
1890
|
& .crisp-tabletoolbar-menu--up { top: auto; bottom: calc(100% + var(--crisp-space-1)); transform-origin: bottom; }
|
|
1820
1891
|
& .crisp-tabletoolbar-menu--right { left: auto; right: 0; }
|
|
1821
1892
|
& .crisp-tabletoolbar-menu--fixed { position: fixed; top: auto; left: auto; z-index: 40; }
|
|
@@ -1836,21 +1907,44 @@
|
|
|
1836
1907
|
& .crisp-tabletoolbar-count { font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
|
|
1837
1908
|
& .crisp-tabletoolbar-new { display: inline-flex; align-items: center; gap: var(--crisp-space-1); height: var(--crisp-size-row); padding: 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-brand-solid); color: var(--crisp-fg-on-brand); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; transition: background-color .12s; }
|
|
1838
1909
|
& .crisp-tabletoolbar-new:hover { background: var(--crisp-bg-brand-solid-pressed); }
|
|
1910
|
+
|
|
1839
1911
|
& .crisp-tabletoolbar-fcond { display: inline-flex; align-items: center; height: var(--crisp-size-row); font-size: var(--crisp-text-md); color: var(--crisp-fg-primary); white-space: nowrap; }
|
|
1840
1912
|
& .crisp-tabletoolbar-fcond-seg { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); height: 100%; margin: 0; padding: 0 var(--crisp-space-2); border: none; background: var(--crisp-bg-surface-muted); box-shadow: inset 0 0 0 1px var(--crisp-border-divider); font-family: inherit; font-size: inherit; color: inherit; cursor: pointer; }
|
|
1841
1913
|
& .crisp-tabletoolbar-fcond-seg svg { flex-shrink: 0; }
|
|
1842
|
-
& .crisp-tabletoolbar-fcond[data-complete] .crisp-tabletoolbar-fcond-seg--field,
|
|
1843
|
-
& .crisp-tabletoolbar-fcond-
|
|
1914
|
+
& .crisp-tabletoolbar-fcond[data-complete] .crisp-tabletoolbar-fcond-seg--field,
|
|
1915
|
+
& .crisp-tabletoolbar-fcond[data-complete] .crisp-tabletoolbar-fcond-seg--val { background: var(--crisp-bg-surface); }
|
|
1916
|
+
& .crisp-tabletoolbar-fcond-seg--field { border-radius: var(--crisp-radius-md) 0 0 var(--crisp-radius-md); font-weight: var(--crisp-weight-medium); max-width: 200px; }
|
|
1844
1917
|
& .crisp-tabletoolbar-fcond-seg--field svg { color: var(--crisp-fg-muted); }
|
|
1918
|
+
/* #592: a nested pick's field segment ("Team › Twitter follower
|
|
1919
|
+
count") — measured live: BOTH path segments the same colour (chip context only; the picker's own menu rows keep the parent muted, see
|
|
1920
|
+
tabletoolbar.chrome.ts), each independently truncated. Attio's own layout gives the leaf segment priority (it stays fully readable longer, the parent truncates first) via a two-part min-content measurement this reproduces qualitatively with a flex-shrink differential rather than byte-for-byte (the exact px split Attio computes is content-length-dependent, not a fixed value) — not independently re-verified at other path-segment lengths. */
|
|
1921
|
+
& .crisp-tabletoolbar-fcond-path { display: inline-flex; align-items: center; gap: 2px; min-width: 0; max-width: 178px; }
|
|
1922
|
+
& .crisp-tabletoolbar-fcond-path-seg { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1 1 auto; }
|
|
1923
|
+
& .crisp-tabletoolbar-fcond-path-seg:first-child { flex: 0 1 auto; }
|
|
1924
|
+
& .crisp-tabletoolbar-fcond-path-sep { flex-shrink: 0; color: inherit; }
|
|
1845
1925
|
& .crisp-tabletoolbar-fcond-seg--op { background: var(--crisp-bg-surface); color: var(--crisp-fg-muted); }
|
|
1846
1926
|
& .crisp-tabletoolbar-fcond-seg--val { font-weight: var(--crisp-weight-medium); max-width: 140px; overflow: hidden; text-overflow: ellipsis; }
|
|
1847
1927
|
& .crisp-tabletoolbar-fcond-seg--kebab { background: var(--crisp-bg-surface); justify-content: center; width: 28px; padding: 0; border-radius: 0 var(--crisp-radius-md) var(--crisp-radius-md) 0; color: var(--crisp-fg-muted); }
|
|
1848
1928
|
& .crisp-tabletoolbar-fcond-seg--kebab:hover { color: var(--crisp-fg-primary); }
|
|
1929
|
+
/* #754: the sort row's own field trigger, replacing a plain Select
|
|
1930
|
+
with the same nested-drill-down popover Filter's field picker already has — reuses Select's own already-measured trigger chrome
|
|
1931
|
+
verbatim (its class is scoped under Select's own root class, so it can't be reused as a bare class name outside an actual Select tree;
|
|
1932
|
+
these values are copied, not re-measured). */
|
|
1933
|
+
& .crisp-tabletoolbar-sort-field-picker { position: relative; display: inline-flex; flex: 1; min-width: 0; }
|
|
1934
|
+
& .crisp-tabletoolbar-sort-field-trigger { box-sizing: border-box; display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); height: var(--crisp-size-menuRow); width: 100%; min-width: 0; margin: 0; padding: 0 var(--crisp-space-1-5) 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-md); background: transparent; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 7%, transparent); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); cursor: pointer; transition: background-color .12s ease, box-shadow .12s ease; }
|
|
1935
|
+
& .crisp-tabletoolbar-sort-field-trigger:hover { background: var(--crisp-bg-raised); }
|
|
1936
|
+
& .crisp-tabletoolbar-sort-field-trigger[aria-expanded="true"],
|
|
1937
|
+
& .crisp-tabletoolbar-sort-field-trigger:focus-visible { outline: none; box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); background: var(--crisp-bg-surface); }
|
|
1938
|
+
& .crisp-tabletoolbar-sort-field-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: start; }
|
|
1939
|
+
& .crisp-tabletoolbar-sort-field-picker .crisp-tabletoolbar-menu { min-width: 200px; }
|
|
1849
1940
|
& .crisp-tabletoolbar-menu--val { min-width: 134px; }
|
|
1850
1941
|
& .crisp-tabletoolbar-datepop { width: 300px; }
|
|
1851
1942
|
& .crisp-tabletoolbar-datepop-presets { display: flex; flex-wrap: wrap; gap: var(--crisp-space-1); margin-top: var(--crisp-space-2); padding: 0 var(--crisp-space-1); }
|
|
1852
1943
|
& .crisp-tabletoolbar-datepop-preset { height: var(--crisp-size-chip); padding: 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-chip); background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-sm); cursor: pointer; }
|
|
1853
1944
|
& .crisp-tabletoolbar-datepop-preset:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 8%, transparent); }
|
|
1945
|
+
|
|
1946
|
+
& .crisp-tabletoolbar-tool--raised { border: none; background: var(--crisp-bg-surface-muted); box-shadow: inset 0 0 0 1px var(--crisp-ring-neutral), 0 0 2px rgba(28,40,64,0.18), 0 1px 3px rgba(0,0,0,0.04); font-family: inherit; cursor: pointer; }
|
|
1947
|
+
[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
|
|
1854
1948
|
}
|
|
1855
1949
|
|
|
1856
1950
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -1893,7 +1987,7 @@
|
|
|
1893
1987
|
}
|
|
1894
1988
|
|
|
1895
1989
|
.crisp-text {
|
|
1896
|
-
|
|
1990
|
+
vertical-align: baseline;
|
|
1897
1991
|
}
|
|
1898
1992
|
.crisp-text--tone_default {
|
|
1899
1993
|
color: var(--crisp-fg-primary);
|
|
@@ -2104,8 +2198,25 @@
|
|
|
2104
2198
|
}
|
|
2105
2199
|
|
|
2106
2200
|
.crisp-board {
|
|
2107
|
-
display: flex; gap: var(--crisp-space-2); height: 100%; box-sizing: border-box;
|
|
2108
|
-
|
|
2201
|
+
display: flex; flex-direction: column; gap: var(--crisp-space-2); height: 100%; box-sizing: border-box; font-family: var(--crisp-font-sans); /* #718: the density toolbar's own row -- everything that used to be on
|
|
2202
|
+
the root (padding/overflow/the columns themselves) moves to
|
|
2203
|
+
.crisp-board-row below so this can sit above it, unscrolled. */
|
|
2204
|
+
& .crisp-board-toolbar { display: flex; align-items: center; justify-content: flex-end; gap: var(--crisp-space-2); padding: 0 var(--crisp-space-3); flex-shrink: 0; }
|
|
2205
|
+
/* Measured live (Deals pipeline): a 54×28px group, 24×24px buttons,
|
|
2206
|
+
2px padding/gap -- an 8px gap between the two groups comes from the
|
|
2207
|
+
toolbar's own `gap` above. */
|
|
2208
|
+
& .crisp-board-density { display: flex; align-items: center; gap: 2px; padding: 2px; border-radius: 10px; background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
|
|
2209
|
+
& .crisp-board-density button { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; padding: 0; border: none; border-radius: 8px; background: none; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); font-family: inherit; cursor: pointer; }
|
|
2210
|
+
& .crisp-board-density button[data-state="on"] { background: var(--crisp-bg-surface); color: var(--crisp-fg-primary); }
|
|
2211
|
+
& .crisp-board-row { display: flex; gap: var(--crisp-space-2); flex: 1; min-height: 0; box-sizing: border-box; padding: var(--crisp-space-3); overflow-x: auto; align-items: flex-start; }
|
|
2212
|
+
& .crisp-board-col { display: flex; flex-direction: column; width: 268px; flex-shrink: 0; max-height: 100%; box-sizing: border-box; transition: width 0.15s; }
|
|
2213
|
+
/* #718: a collapsed column is a 52px vertical rail -- header only (dot + count stacked above a vertical-rl title), body/footer hidden entirely. Measured live: 52px width, 8px 0 padding on the header, 14px/600 title text. */
|
|
2214
|
+
& .crisp-board-col[data-density="collapse"] { width: 52px; }
|
|
2215
|
+
& .crisp-board-col[data-density="collapse"] .crisp-board-col-header { flex-direction: column; align-items: center; height: auto; padding: var(--crisp-space-2) 0; gap: var(--crisp-space-1); }
|
|
2216
|
+
/* Measured stacking order (top to bottom): dot, count, THEN the vertical title -- reordered visually via `order`, not by changing the JSX/DOM order, which stays dot/title/count (reading order, unaffected by density). */
|
|
2217
|
+
& .crisp-board-col[data-density="collapse"] .crisp-board-col-title { order: 1; writing-mode: vertical-rl; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); }
|
|
2218
|
+
& .crisp-board-col[data-density="collapse"] .crisp-board-col-count { order: 0; }
|
|
2219
|
+
& .crisp-board-col[data-density="collapse"] .crisp-board-col-body, & .crisp-board-col[data-density="collapse"] .crisp-board-col-footer { display: none; }
|
|
2109
2220
|
& .crisp-board-col-header { display: flex; align-items: center; gap: var(--crisp-space-2); height: 36px; padding: 0 var(--crisp-space-1); flex-shrink: 0; }
|
|
2110
2221
|
& .crisp-board-col-dot { width: 12px; height: 12px; border-radius: var(--crisp-radius-full); flex-shrink: 0; }
|
|
2111
2222
|
& .crisp-board-col-title { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); }
|
|
@@ -2120,23 +2231,30 @@
|
|
|
2120
2231
|
& .crisp-board-newcard { display: flex; align-items: center; justify-content: center; gap: var(--crisp-space-1-5); height: 32px; flex-shrink: 0; border: none; border-radius: var(--crisp-radius-md); background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); color: var(--crisp-fg-muted); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; }
|
|
2121
2232
|
& .crisp-board-newcard:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 7%, transparent); color: var(--crisp-fg-primary); }
|
|
2122
2233
|
& .crisp-board-card { display: flex; flex-direction: column; gap: var(--crisp-space-2); box-sizing: border-box; padding: var(--crisp-space-2-5) var(--crisp-space-3); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); cursor: grab; touch-action: none; }
|
|
2234
|
+
/* #718: a collapsed card is a single 40px row -- measured live and independent of `c.size.tableRow`/`tableHeader` (36/40px) even though it happens to match the latter; a plain literal, not a cross-reference to a token measured for a different surface. `renderCard`'s own second argument is what actually decides what a
|
|
2235
|
+
collapsed card SHOWS (Board never sees inside its opaque output);
|
|
2236
|
+
this only supplies the row-shaped box that content sits in. */
|
|
2237
|
+
& .crisp-board-card[data-density="collapse"] { flex-direction: row; align-items: center; height: 40px; padding: 0 var(--crisp-space-3); }
|
|
2123
2238
|
& .crisp-board-card:active { cursor: grabbing; }
|
|
2124
2239
|
& .crisp-board-card[data-dragging] { opacity: 0.4; }
|
|
2125
2240
|
& .crisp-board-card:focus { outline: none; }
|
|
2126
2241
|
& .crisp-board-card:focus-visible { outline: 2px solid var(--crisp-bg-brand-solid); outline-offset: 1px; }
|
|
2127
|
-
/* #674: the pointer-events drag's own drag image -- the same card
|
|
2128
|
-
surface above, just pinned to the pointer instead of the flex flow.
|
|
2129
|
-
No shadow lift or scale: neither was measured against Attio, and this
|
|
2130
|
-
is the same card, momentarily somewhere else, not a new look. */
|
|
2242
|
+
/* #674: the pointer-events drag's own drag image -- the same card surface above, just pinned to the pointer instead of the flex flow. No shadow lift or scale: neither was measured against Attio, and this is the same card, momentarily somewhere else, not a new look. */
|
|
2131
2243
|
& .crisp-board-ghost { position: fixed; z-index: 1; pointer-events: none; cursor: grabbing; }
|
|
2132
|
-
/* #604: a per-column calc footer, mirroring the table's own (measured
|
|
2133
|
-
|
|
2244
|
+
/* #604: a per-column calc footer, mirroring the table's own (measured
|
|
2245
|
+
live, Deals pipeline). Sits below the scrollable card body, not
|
|
2246
|
+
inside it or pinned to it -- Attio's own is position: static, not sticky, so it's a plain flex-shrink:0 sibling here too. */
|
|
2134
2247
|
& .crisp-board-col-footer { flex-shrink: 0; padding: var(--crisp-space-1) 0; }
|
|
2135
2248
|
& .crisp-board-col-calc { display: flex; align-items: center; justify-content: center; gap: var(--crisp-space-1); width: 100%; height: 28px; padding: var(--crisp-space-1) var(--crisp-space-2); margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); cursor: pointer; }
|
|
2136
2249
|
& .crisp-board-col-calc:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
|
|
2137
2250
|
& .crisp-board-col-calc[data-empty] { opacity: 0.7; }
|
|
2138
2251
|
& .crisp-board-col-calc-label { text-transform: capitalize; }
|
|
2139
2252
|
& .crisp-board-col-calc-value { color: var(--crisp-fg-primary); font-variant-numeric: tabular-nums; }
|
|
2253
|
+
/* #718: "Add stage" -- measured live: 52×52px, transparent, a 1px
|
|
2254
|
+
dashed border (rgb(230,231,234), exactly `borderDropzone`/`line150`
|
|
2255
|
+
-- the same dashed-border colour ImportDialog's own dropzone already uses, not borderSubtle/line100, a close but different value), radius.xl (16px), a centered 16px "+". */
|
|
2256
|
+
& .crisp-board-addstage { display: inline-flex; align-items: center; justify-content: center; width: 52px; height: 52px; flex-shrink: 0; border: 1px dashed var(--crisp-border-dropzone); border-radius: var(--crisp-radius-xl); background: none; color: var(--crisp-fg-primary); font-family: inherit; cursor: pointer; }
|
|
2257
|
+
& .crisp-board-addstage:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
|
|
2140
2258
|
/* announced, never drawn */
|
|
2141
2259
|
& .crisp-board-live { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
|
|
2142
2260
|
}
|
|
@@ -2204,11 +2322,21 @@
|
|
|
2204
2322
|
|
|
2205
2323
|
/* Row badge (CommentCountBadge) -- lives in its own class family so the
|
|
2206
2324
|
grid lanes can drop it into a cell without pulling in the panel's
|
|
2207
|
-
CSS.
|
|
2208
|
-
|
|
2209
|
-
|
|
2325
|
+
CSS. Re-measured live on a real commented row (crisp/#601
|
|
2326
|
+
supersession, right-aligned in a DataTable primary column): a 6px
|
|
2327
|
+
grey dot at rest (unchanged, already matched); on hover, the trigger
|
|
2328
|
+
button is auto-width with a 12px icon + 12px/500 count text,
|
|
2329
|
+
"padding: 2px 6px 2px 4px", radius 6px -- distinct from the preview
|
|
2330
|
+
button beside it, a fixed 20px square with a 16px icon, same radius.
|
|
2331
|
+
Both share the 55%-ink idle colour and darken on their OWN hover
|
|
2332
|
+
(color-mix 4%, the same formula DataTable's own #601 icons use). */
|
|
2333
|
+
.crisp-comments-badge { box-sizing: border-box; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); }
|
|
2210
2334
|
.crisp-comments-badge-dot { box-sizing: border-box; width: 6px; height: 6px; border-radius: var(--crisp-radius-full); background: color-mix(in srgb, var(--crisp-fg-primary) 38%, transparent); }
|
|
2211
|
-
.crisp-comments-badge-
|
|
2335
|
+
.crisp-comments-badge-trigger { box-sizing: border-box; display: inline-flex; align-items: center; gap: var(--crisp-space-1); height: 20px; margin: 0; padding: 2px var(--crisp-space-1-5) 2px var(--crisp-space-1); border: none; border-radius: var(--crisp-radius-sm); background: none; font-family: inherit; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); cursor: pointer; }
|
|
2336
|
+
.crisp-comments-badge-trigger:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); color: var(--crisp-fg-primary); }
|
|
2337
|
+
.crisp-comments-badge-preview { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-sm); background: none; font-family: inherit; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); cursor: pointer; flex-shrink: 0; }
|
|
2338
|
+
.crisp-comments-badge-preview:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); color: var(--crisp-fg-primary); }
|
|
2339
|
+
.crisp-comments-badge-count { font-size: 12px; line-height: 16px; font-weight: var(--crisp-weight-medium); }
|
|
2212
2340
|
[dir="rtl"] .crisp-comments-badge [data-rtl-flip] { transform: scaleX(-1); }
|
|
2213
2341
|
|
|
2214
2342
|
.crisp-comments {
|
|
@@ -2871,7 +2999,7 @@
|
|
|
2871
2999
|
& .crisp-recordstable-sort-learn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); font-size: var(--crisp-text-lg); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); text-decoration: none; }
|
|
2872
3000
|
& .crisp-recordstable-sort-learn svg { flex-shrink: 0; }
|
|
2873
3001
|
& .crisp-recordstable-sort-learn:hover { color: var(--crisp-fg-primary); }
|
|
2874
|
-
& .crisp-recordstable-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
|
|
3002
|
+
& .crisp-recordstable-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); text-align: left; text-decoration: none; cursor: pointer; }
|
|
2875
3003
|
& .crisp-recordstable-menu-item:hover { background: var(--crisp-bg-raised); }
|
|
2876
3004
|
& .crisp-recordstable-menu-item:disabled { opacity: 0.4; cursor: default; }
|
|
2877
3005
|
& .crisp-recordstable-menu-item:disabled:hover { background: none; }
|
|
@@ -2879,7 +3007,25 @@
|
|
|
2879
3007
|
& .crisp-recordstable-menu-item[data-on] svg { color: var(--crisp-bg-brand-solid); }
|
|
2880
3008
|
& .crisp-recordstable-menu-item .crisp-recordstable-menu-check { margin-left: auto; }
|
|
2881
3009
|
& .crisp-recordstable-menu-input { height: var(--crisp-size-row); margin: var(--crisp-space-0-5); padding: 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-md); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); background: var(--crisp-bg-surface); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); outline: none; }
|
|
2882
|
-
& .crisp-recordstable-menu-sep { height: 1px; background: var(--crisp-border-subtle); margin: var(--crisp-space-0-5) 0; }
|
|
3010
|
+
& .crisp-recordstable-menu-sep { height: 1px; border: none; background: var(--crisp-border-subtle); margin: var(--crisp-space-0-5) 0; }
|
|
3011
|
+
/* #592: the Filter field picker's nested-scope header (back control +
|
|
3012
|
+
search, once drilled into a nestedColumns column) and a search
|
|
3013
|
+
result's own breadcrumb row ("Team › Twitter follower count", surfaced by the SAME query matching a nested column). menu-back reuses the established 28px icon-only control pattern this file already uses twice (sort-remove, the kebab segment) rather than an independent measurement of Attio's own back arrow. The breadcrumb
|
|
3014
|
+
colours ARE measured live: the parent segment muted at the same
|
|
3015
|
+
exact color-mix 63% sort-learn above already uses, the
|
|
3016
|
+
separator chevron and leaf segment both full fgPrimary (the
|
|
3017
|
+
generic menu-item svg rule below defaults every icon to
|
|
3018
|
+
fgMuted, so the separator needs its own override to read
|
|
3019
|
+
correctly here). */
|
|
3020
|
+
& .crisp-recordstable-menu-nesthead { display: flex; align-items: center; gap: var(--crisp-space-1); margin: var(--crisp-space-0-5); }
|
|
3021
|
+
& .crisp-recordstable-menu-nesthead .crisp-recordstable-menu-input { flex: 1; margin: 0; }
|
|
3022
|
+
& .crisp-recordstable-menu-back { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; flex-shrink: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-muted); cursor: pointer; }
|
|
3023
|
+
& .crisp-recordstable-menu-back:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
|
|
3024
|
+
& .crisp-recordstable-menu-item--expand { justify-content: space-between; }
|
|
3025
|
+
& .crisp-recordstable-menu-item-path { display: inline-flex; align-items: center; gap: 2px; min-width: 0; overflow: hidden; }
|
|
3026
|
+
& .crisp-recordstable-menu-item-path-parent { flex-shrink: 0; overflow: hidden; text-overflow: ellipsis; max-width: 100px; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
|
|
3027
|
+
& .crisp-recordstable-menu-item-path-sep { flex-shrink: 0; color: var(--crisp-fg-primary); }
|
|
3028
|
+
& .crisp-recordstable-menu-item-path > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2883
3029
|
& .crisp-recordstable-menu--up { top: auto; bottom: calc(100% + var(--crisp-space-1)); transform-origin: bottom; }
|
|
2884
3030
|
& .crisp-recordstable-menu--right { left: auto; right: 0; }
|
|
2885
3031
|
& .crisp-recordstable-menu--fixed { position: fixed; top: auto; left: auto; z-index: 40; }
|
|
@@ -2900,6 +3046,7 @@
|
|
|
2900
3046
|
& .crisp-recordstable-count { font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
|
|
2901
3047
|
& .crisp-recordstable-new { display: inline-flex; align-items: center; gap: var(--crisp-space-1); height: var(--crisp-size-row); padding: 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-brand-solid); color: var(--crisp-fg-on-brand); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; transition: background-color .12s; }
|
|
2902
3048
|
& .crisp-recordstable-new:hover { background: var(--crisp-bg-brand-solid-pressed); }
|
|
3049
|
+
|
|
2903
3050
|
/* scroll frame + table */
|
|
2904
3051
|
& .crisp-recordstable-scroll { flex: 1; min-height: 0; overflow: auto; background: var(--crisp-bg-surface); border-top: 1px solid var(--crisp-border-subtle); scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--crisp-fg-primary) 22%, transparent) transparent; }
|
|
2905
3052
|
& .crisp-recordstable-scroll::-webkit-scrollbar { width: 10px; height: 10px; }
|
|
@@ -2917,16 +3064,20 @@
|
|
|
2917
3064
|
& .crisp-recordstable-sort { flex-shrink: 0; opacity: 0.4; transition: opacity .12s; color: color-mix(in srgb, var(--crisp-fg-primary) 45%, transparent); }
|
|
2918
3065
|
& .crisp-recordstable-th:hover .crisp-recordstable-sort, & .crisp-recordstable-th[data-sorted] .crisp-recordstable-sort { opacity: 1; }
|
|
2919
3066
|
& .crisp-recordstable-th[data-sorted="desc"] .crisp-recordstable-sort svg { transform: rotate(180deg); }
|
|
3067
|
+
|
|
2920
3068
|
/* column resize handle */
|
|
2921
3069
|
& .crisp-recordstable-resize { position: absolute; top: 0; inset-inline-end: -3px; width: 9px; height: 100%; cursor: col-resize; z-index: 6; touch-action: none; }
|
|
2922
3070
|
& .crisp-recordstable-resize::after { content: ""; position: absolute; top: 0; inset-inline-start: 3px; width: 2px; height: 100%; background: var(--crisp-bg-brand-solid); opacity: 0; transition: opacity .12s; }
|
|
2923
3071
|
& .crisp-recordstable-resize:hover::after, & .crisp-recordstable-resize[data-resizing]::after { opacity: 1; }
|
|
3072
|
+
|
|
2924
3073
|
/* add-column header */
|
|
2925
3074
|
& .crisp-recordstable-addcol { min-width: 44px; }
|
|
2926
3075
|
& .crisp-recordstable-addcol button { display: flex; align-items: center; justify-content: center; width: 44px; height: 100%; border: none; background: none; color: var(--crisp-fg-muted); cursor: pointer; }
|
|
2927
3076
|
& .crisp-recordstable-addcol button:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
|
|
2928
|
-
|
|
2929
|
-
|
|
3077
|
+
|
|
3078
|
+
/* cells */
|
|
3079
|
+
/* font-weight is explicit because the first cell of each row is a
|
|
3080
|
+
th[scope=row] — the record's name is what the row IS — and a th defaults to bold. Measured before the change and unchanged after: 400. */
|
|
2930
3081
|
& .crisp-recordstable-td { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-regular); color: var(--crisp-fg-primary); background: var(--crisp-bg-surface); cursor: default; }
|
|
2931
3082
|
& .crisp-recordstable-td--editable { cursor: text; }
|
|
2932
3083
|
/* keyboard/click cell selection (spreadsheet-style) */
|
|
@@ -2942,10 +3093,8 @@
|
|
|
2942
3093
|
& .crisp-recordstable-td--picker .crisp-multiselect-chips .crisp-recordstable-tag { flex-shrink: 0; max-width: none; }
|
|
2943
3094
|
& .crisp-recordstable-td--picker .crisp-multiselect-chevron { display: none; }
|
|
2944
3095
|
& .crisp-recordstable-td--picker .crisp-multiselect-placeholder { color: var(--crisp-fg-muted); }
|
|
2945
|
-
/* reference picker: a leading 16px avatar per option, plus a trailing
|
|
2946
|
-
|
|
2947
|
-
against Attio's own picker (16px circular avatar, 16px plain icon for the create row, both sitting in the option's existing 8px gap, no new
|
|
2948
|
-
gap value invented). */
|
|
3096
|
+
/* reference picker: a leading 16px avatar per option, plus a trailing "Create X" row when the consumer supplies one (#449) -- measured live against Attio's own picker (16px circular avatar, 16px plain icon for
|
|
3097
|
+
the create row, both sitting in the option's existing 8px gap, no new gap value invented). */
|
|
2949
3098
|
& .crisp-recordstable-refoption { display: flex; align-items: center; gap: var(--crisp-space-2); min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
2950
3099
|
& .crisp-recordstable-refoption-avatar { flex-shrink: 0; }
|
|
2951
3100
|
& .crisp-recordstable-refoption--create { color: var(--crisp-fg-muted); }
|
|
@@ -2973,46 +3122,33 @@
|
|
|
2973
3122
|
& tbody tr:hover .crisp-recordstable-open { opacity: 1; }
|
|
2974
3123
|
& .crisp-recordstable-link { color: var(--crisp-fg-primary); text-decoration: none; overflow: hidden; text-overflow: ellipsis; }
|
|
2975
3124
|
& .crisp-recordstable-link:hover { text-decoration: underline; }
|
|
2976
|
-
|
|
2977
3125
|
/* inline edit input */
|
|
2978
3126
|
& .crisp-recordstable-edit { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0 var(--crisp-space-2); border: none; outline: 2px solid var(--crisp-bg-brand-solid); outline-offset: -2px; border-radius: var(--crisp-radius-sm); background: var(--crisp-bg-surface); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); z-index: 5; }
|
|
2979
3127
|
& .crisp-recordstable-edit--num { text-align: end; font-variant-numeric: tabular-nums; }
|
|
2980
|
-
|
|
2981
3128
|
/* selection / hover / sticky */
|
|
2982
3129
|
& .crisp-recordstable-col-check { width: 40px; min-width: 40px; padding: 0; }
|
|
2983
3130
|
& .crisp-recordstable-check-inner { display: flex; align-items: center; justify-content: center; height: 100%; }
|
|
2984
3131
|
& .crisp-recordstable-col-check, & .crisp-recordstable-col-entity { position: sticky; z-index: 3; background: var(--crisp-bg-surface); }
|
|
2985
|
-
/* The sticky pin is a LOGICAL offset: with physical `left` these columns
|
|
2986
|
-
were not pinned at all under RTL -- scrolled, they left the viewport
|
|
2987
|
-
entirely (measured: viewport 13..773, check column at x=1333). Nothing in
|
|
2988
|
-
JS measures these, so converting them is safe; the two properties below
|
|
2989
|
-
that have no logical form get an explicit RTL rule rather than being
|
|
2990
|
-
left to point the wrong way. */
|
|
3132
|
+
/* The sticky pin is a LOGICAL offset: with physical `left` these columns were not pinned at all under RTL -- scrolled, they left the viewport entirely (measured: viewport 13..773, check column at x=1333). Nothing in JS measures these, so converting them is safe; the two properties below that have no logical form get an explicit RTL rule rather than being left to point the wrong way. */
|
|
2991
3133
|
& .crisp-recordstable-col-check { inset-inline-start: 0; }
|
|
2992
3134
|
& .crisp-recordstable-col-entity { inset-inline-start: 40px; clip-path: inset(0 -38px 0 0); transition: box-shadow .2s ease; }
|
|
2993
3135
|
[dir="rtl"] & .crisp-recordstable-col-entity { clip-path: inset(0 0 0 -38px); }
|
|
2994
3136
|
& thead .crisp-recordstable-col-check, & thead .crisp-recordstable-col-entity { z-index: 4; }
|
|
2995
3137
|
/* soft shadow on the sticky column edge once the grid is scrolled horizontally */
|
|
2996
3138
|
& .crisp-recordstable-scroll[data-scrolled] .crisp-recordstable-col-entity { box-shadow: 6px 0 16px 4px rgba(0,0,0,0.12); }
|
|
2997
|
-
/* box-shadow has no logical form either: the bleed follows the scrolled
|
|
2998
|
-
content, which is the opposite side under RTL. */
|
|
3139
|
+
/* box-shadow has no logical form either: the bleed follows the scrolled content, which is the opposite side under RTL. */
|
|
2999
3140
|
[dir="rtl"] & .crisp-recordstable-scroll[data-scrolled] .crisp-recordstable-col-entity { box-shadow: -6px 0 16px 4px rgba(0,0,0,0.12); }
|
|
3000
|
-
/* AI-enriched values carry a purple wash. Measured live:
|
|
3001
|
-
a full-bleed overlay at #9b69ff 4% (== bgPurple), composited OVER
|
|
3002
|
-
whatever row-state background the cell already has, which is why it
|
|
3003
|
-
is an ::after and not a background. */
|
|
3141
|
+
/* AI-enriched values carry a purple wash. Measured live: a full-bleed overlay at #9b69ff 4% (== bgPurple), composited OVER whatever row-state background the cell already has, which is why it is an ::after and not a background. */
|
|
3004
3142
|
& .crisp-recordstable-td[data-enriched]::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: color-mix(in srgb, var(--crisp-bg-purple) 4%, transparent); }
|
|
3005
3143
|
& tbody tr:hover .crisp-recordstable-td { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, var(--crisp-bg-surface)); }
|
|
3006
3144
|
& tbody tr[data-selected] .crisp-recordstable-td { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 10%, var(--crisp-bg-surface)); }
|
|
3007
3145
|
& tbody tr[data-selected]:hover .crisp-recordstable-td { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, color-mix(in srgb, var(--crisp-bg-brand-solid) 10%, var(--crisp-bg-surface))); }
|
|
3008
3146
|
& .crisp-recordstable-th:last-child, & .crisp-recordstable-td:last-child { border-inline-end: none; }
|
|
3009
|
-
|
|
3010
3147
|
/* add-row footer */
|
|
3011
3148
|
& .crisp-recordstable-addrow { display: flex; align-items: center; gap: var(--crisp-space-2); width: 100%; height: var(--crisp-size-tableRow); padding: 0 var(--crisp-space-2); border: none; border-top: 1px solid var(--crisp-border-subtle); background: var(--crisp-bg-surface); color: var(--crisp-fg-muted); font-family: inherit; font-size: var(--crisp-text-lg); cursor: pointer; }
|
|
3012
3149
|
& .crisp-recordstable-addrow:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
|
|
3013
3150
|
/* zero-row empty state — centred in the body region (headers + summary stay) */
|
|
3014
3151
|
& .crisp-recordstable-empty { display: flex; align-items: center; justify-content: center; min-height: 320px; padding: var(--crisp-space-8) var(--crisp-space-4); }
|
|
3015
|
-
|
|
3016
3152
|
/* summary footer — per-column aggregation, sticky to the bottom */
|
|
3017
3153
|
& .crisp-recordstable-sum { position: sticky; bottom: 0; z-index: 2; height: var(--crisp-size-tableRow); padding: 0; border-top: 1px solid var(--crisp-border-subtle); border-bottom: 1px solid var(--crisp-border-subtle); border-inline-end: 1px solid var(--crisp-border-subtle); background: var(--crisp-bg-surface); }
|
|
3018
3154
|
& tfoot .crisp-recordstable-col-check, & tfoot .crisp-recordstable-col-entity { position: sticky; bottom: 0; z-index: 3; }
|
|
@@ -3025,18 +3161,12 @@
|
|
|
3025
3161
|
& .crisp-recordstable-pin { flex-shrink: 0; margin-inline-start: var(--crisp-space-1); color: var(--crisp-bg-warning); fill: color-mix(in srgb, var(--crisp-bg-warning) 35%, transparent); }
|
|
3026
3162
|
& .crisp-recordstable-sum-btn[data-empty] { opacity: 0; justify-content: flex-start; }
|
|
3027
3163
|
& .crisp-recordstable-sum-btn[data-empty]:hover { opacity: 1; }
|
|
3028
|
-
|
|
3029
3164
|
/* bulk action bar lives in its own component now — see components/bulkbar */
|
|
3030
3165
|
& .crisp-recordstable-bulk-sep { width: 1px; height: 20px; margin: 0 var(--crisp-space-0-5); background: var(--crisp-border-subtle); }
|
|
3031
3166
|
& .crisp-recordstable-bulk-close { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: transparent; color: var(--crisp-fg-muted); cursor: pointer; }
|
|
3032
3167
|
& .crisp-recordstable-bulk-close:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
|
|
3033
|
-
|
|
3034
3168
|
/* announced, never drawn */
|
|
3035
|
-
& .crisp-recordstable-live {
|
|
3036
|
-
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
|
|
3037
|
-
overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
|
|
3038
|
-
}
|
|
3039
|
-
|
|
3169
|
+
& .crisp-recordstable-live { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
|
|
3040
3170
|
[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
|
|
3041
3171
|
}
|
|
3042
3172
|
|
|
@@ -3132,6 +3262,21 @@
|
|
|
3132
3262
|
.crisp-savedviews-panel[data-up] { transform-origin: bottom left; }
|
|
3133
3263
|
.crisp-savedviews-panel { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
|
|
3134
3264
|
|
|
3265
|
+
/* #618 (P-007): the panel's own "Search views..." box — measured live:
|
|
3266
|
+
32px tall, 6px/8px padding, NO border/background/leading icon of its
|
|
3267
|
+
own (unlike Select's own bordered searchable-input pill), 14px text.
|
|
3268
|
+
A hairline divider (borderSubtle, 1px, 3px top margin) separates it
|
|
3269
|
+
from the view list, matching the divider Attio's own kebab menu uses
|
|
3270
|
+
between its action items and the "Created by" footer below. */
|
|
3271
|
+
.crisp-savedviews-search {
|
|
3272
|
+
box-sizing: border-box; display: block; width: 100%; height: 32px; flex-shrink: 0;
|
|
3273
|
+
margin: 0; padding: var(--crisp-space-1-5) var(--crisp-space-2); border: none; background: none;
|
|
3274
|
+
font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); outline: none;
|
|
3275
|
+
}
|
|
3276
|
+
.crisp-savedviews-search::placeholder { color: var(--crisp-fg-muted); }
|
|
3277
|
+
.crisp-savedviews-search-sep { height: 1px; flex-shrink: 0; margin: 3px 0 0; background: var(--crisp-border-subtle); }
|
|
3278
|
+
.crisp-savedviews-empty { padding: var(--crisp-space-1-5) var(--crisp-space-2); font-size: var(--crisp-text-lg); color: var(--crisp-fg-muted); }
|
|
3279
|
+
|
|
3135
3280
|
.crisp-savedviews-row {
|
|
3136
3281
|
box-sizing: border-box; position: relative; display: flex; align-items: center; gap: var(--crisp-space-1-5);
|
|
3137
3282
|
height: var(--crisp-size-menuRow); flex-shrink: 0; padding: var(--crisp-space-1-5) var(--crisp-space-2);
|
|
@@ -3163,6 +3308,18 @@
|
|
|
3163
3308
|
.crisp-savedviews-row:focus-within .crisp-savedviews-kebab,
|
|
3164
3309
|
.crisp-savedviews-kebab[data-open] { opacity: 1; }
|
|
3165
3310
|
.crisp-savedviews-kebab:hover, .crisp-savedviews-kebab[data-open] { background: var(--crisp-bg-surface); color: var(--crisp-fg-primary); }
|
|
3311
|
+
|
|
3312
|
+
/* #618 (P-008): the kebab menu's own "Created by X" / date footer —
|
|
3313
|
+
measured live: 2 stacked lines, 6px/8px padding, 2px gap between
|
|
3314
|
+
them, 12px/500 text, BOTH lines the same color-mix 50% muted (a
|
|
3315
|
+
distinct value from the 63% mix #592's chip breadcrumb uses —
|
|
3316
|
+
independently measured, not assumed to match). */
|
|
3317
|
+
.crisp-savedviews-kebab-footer {
|
|
3318
|
+
display: flex; flex-direction: column; gap: 2px;
|
|
3319
|
+
padding: var(--crisp-space-1-5) var(--crisp-space-2);
|
|
3320
|
+
font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium);
|
|
3321
|
+
color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent);
|
|
3322
|
+
}
|
|
3166
3323
|
|
|
3167
3324
|
.crisp-savedviews {
|
|
3168
3325
|
position: relative; display: inline-flex; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; /* Trigger fill measured rgb(246,247,247); bgRaised's light value is
|