@crisp-ui-kit/crisp 0.54.7 → 0.54.9

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.
Files changed (130) hide show
  1. package/dist/authshell.css +5 -1
  2. package/dist/authshell.layered.css +5 -1
  3. package/dist/badge.css +5 -5
  4. package/dist/badge.layered.css +5 -5
  5. package/dist/board.css +36 -8
  6. package/dist/board.layered.css +36 -8
  7. package/dist/button.css +3 -1
  8. package/dist/button.layered.css +3 -1
  9. package/dist/cjs/components/badge/badge.recipe.js +28 -5
  10. package/dist/cjs/components/button/button.js +33 -2
  11. package/dist/cjs/components/button/button.recipe.js +31 -5
  12. package/dist/cjs/components/contextmenu/contextmenu.js +2 -2
  13. package/dist/cjs/components/contextmenu/contextmenu.recipe.js +24 -0
  14. package/dist/cjs/components/datatable/datatable.js +590 -41
  15. package/dist/cjs/components/datatable/datatable.recipe.js +118 -5
  16. package/dist/cjs/components/dialog/dialog.js +72 -5
  17. package/dist/cjs/components/dialog/dialog.recipe.js +15 -1
  18. package/dist/cjs/components/tabletoolbar/tabletoolbar.chrome.js +49 -5
  19. package/dist/cjs/components/tabletoolbar/tabletoolbar.js +365 -49
  20. package/dist/cjs/components/tabletoolbar/tabletoolbar.recipe.js +78 -0
  21. package/dist/cjs/components/tabs/tabs.recipe.js +11 -2
  22. package/dist/cjs/components/tooltip/tooltip.js +23 -9
  23. package/dist/cjs/components/tooltip/tooltip.recipe.js +10 -9
  24. package/dist/cjs/product/authshell/authshell.js +14 -1
  25. package/dist/cjs/product/authshell/authshell.recipe.js +13 -1
  26. package/dist/cjs/product/board/board.js +175 -46
  27. package/dist/cjs/product/board/board.recipe.js +56 -4
  28. package/dist/cjs/product/comments/comments.js +34 -12
  29. package/dist/cjs/product/comments/comments.recipe.js +31 -7
  30. package/dist/cjs/product/formdialog/formdialog.js +10 -4
  31. package/dist/cjs/product/navitem/navitem.js +7 -2
  32. package/dist/cjs/product/navitem/navitem.recipe.js +16 -0
  33. package/dist/cjs/product/objectsettings/index.js +1 -2
  34. package/dist/cjs/product/objectsettings/objectsettings.js +3 -13
  35. package/dist/cjs/product/recordstable/recordstable.js +1 -17
  36. package/dist/cjs/product/richtext/richtext.js +76 -1
  37. package/dist/cjs/product/savedviews/savedviews.js +55 -24
  38. package/dist/cjs/product/savedviews/savedviews.recipe.js +27 -0
  39. package/dist/cjs/product/sidebar/sidebar.js +68 -15
  40. package/dist/cjs/product/sidebar/sidebar.recipe.js +6 -1
  41. package/dist/cjs/tokens/palette.js +32 -1
  42. package/dist/cjs/tokens/semantic.js +11 -0
  43. package/dist/comments.css +50 -14
  44. package/dist/comments.layered.css +50 -14
  45. package/dist/contextmenu.css +24 -0
  46. package/dist/contextmenu.layered.css +24 -0
  47. package/dist/datatable.css +101 -37
  48. package/dist/datatable.layered.css +101 -37
  49. package/dist/dialog.css +13 -1
  50. package/dist/dialog.layered.css +13 -1
  51. package/dist/esm/components/badge/badge.recipe.js +28 -5
  52. package/dist/esm/components/button/button.js +34 -3
  53. package/dist/esm/components/button/button.recipe.js +31 -5
  54. package/dist/esm/components/contextmenu/contextmenu.js +2 -2
  55. package/dist/esm/components/contextmenu/contextmenu.recipe.js +24 -0
  56. package/dist/esm/components/datatable/datatable.js +590 -42
  57. package/dist/esm/components/datatable/datatable.recipe.js +119 -6
  58. package/dist/esm/components/dialog/dialog.js +72 -5
  59. package/dist/esm/components/dialog/dialog.recipe.js +15 -1
  60. package/dist/esm/components/tabletoolbar/tabletoolbar.chrome.js +49 -5
  61. package/dist/esm/components/tabletoolbar/tabletoolbar.js +366 -50
  62. package/dist/esm/components/tabletoolbar/tabletoolbar.recipe.js +80 -2
  63. package/dist/esm/components/tabs/tabs.recipe.js +11 -2
  64. package/dist/esm/components/tooltip/tooltip.js +23 -9
  65. package/dist/esm/components/tooltip/tooltip.recipe.js +10 -9
  66. package/dist/esm/product/authshell/authshell.js +15 -2
  67. package/dist/esm/product/authshell/authshell.recipe.js +13 -1
  68. package/dist/esm/product/authshell/index.js +1 -1
  69. package/dist/esm/product/board/board.js +176 -47
  70. package/dist/esm/product/board/board.recipe.js +56 -4
  71. package/dist/esm/product/comments/comments.js +35 -13
  72. package/dist/esm/product/comments/comments.recipe.js +31 -7
  73. package/dist/esm/product/formdialog/formdialog.js +10 -4
  74. package/dist/esm/product/navitem/index.js +1 -1
  75. package/dist/esm/product/navitem/navitem.js +7 -2
  76. package/dist/esm/product/navitem/navitem.recipe.js +16 -0
  77. package/dist/esm/product/objectsettings/index.js +1 -1
  78. package/dist/esm/product/objectsettings/objectsettings.js +2 -12
  79. package/dist/esm/product/recordstable/recordstable.js +2 -18
  80. package/dist/esm/product/richtext/richtext.js +76 -1
  81. package/dist/esm/product/savedviews/savedviews.js +57 -26
  82. package/dist/esm/product/savedviews/savedviews.recipe.js +27 -0
  83. package/dist/esm/product/sidebar/sidebar.js +69 -16
  84. package/dist/esm/product/sidebar/sidebar.recipe.js +6 -1
  85. package/dist/esm/tokens/palette.js +32 -1
  86. package/dist/esm/tokens/semantic.js +11 -0
  87. package/dist/native/tokens.d.ts +1 -1
  88. package/dist/native/tokens.js +16 -2
  89. package/dist/navitem.css +7 -0
  90. package/dist/navitem.layered.css +7 -0
  91. package/dist/recordstable.css +34 -32
  92. package/dist/recordstable.layered.css +34 -32
  93. package/dist/savedviews.css +27 -0
  94. package/dist/savedviews.layered.css +27 -0
  95. package/dist/sidebar.css +6 -1
  96. package/dist/sidebar.layered.css +6 -1
  97. package/dist/styles.css +369 -106
  98. package/dist/styles.layered.css +369 -106
  99. package/dist/tabletoolbar.css +47 -3
  100. package/dist/tabletoolbar.layered.css +47 -3
  101. package/dist/tabs.css +1 -1
  102. package/dist/tabs.layered.css +1 -1
  103. package/dist/tokens.css +9 -1
  104. package/dist/tokens.json +16 -2
  105. package/dist/tooltip.css +1 -1
  106. package/dist/tooltip.layered.css +1 -1
  107. package/dist/types/components/badge/badge.recipe.d.ts +5 -1
  108. package/dist/types/components/button/button.recipe.d.ts +18 -5
  109. package/dist/types/components/contextmenu/contextmenu.d.ts +8 -1
  110. package/dist/types/components/datatable/datatable.d.ts +98 -1
  111. package/dist/types/components/dialog/dialog.d.ts +25 -2
  112. package/dist/types/components/tabletoolbar/tabletoolbar.d.ts +113 -3
  113. package/dist/types/components/tooltip/tooltip.d.ts +12 -4
  114. package/dist/types/components/tooltip/tooltip.recipe.d.ts +1 -1
  115. package/dist/types/product/authshell/authshell.d.ts +26 -2
  116. package/dist/types/product/authshell/index.d.ts +1 -1
  117. package/dist/types/product/board/board.d.ts +53 -6
  118. package/dist/types/product/comments/comments.d.ts +16 -3
  119. package/dist/types/product/formdialog/formdialog.d.ts +2 -1
  120. package/dist/types/product/navitem/index.d.ts +1 -1
  121. package/dist/types/product/navitem/navitem.d.ts +23 -0
  122. package/dist/types/product/objectsettings/index.d.ts +1 -1
  123. package/dist/types/product/objectsettings/objectsettings.d.ts +0 -10
  124. package/dist/types/product/recordstable/recordstable.d.ts +0 -1
  125. package/dist/types/product/savedviews/savedviews.d.ts +45 -8
  126. package/dist/types/product/sidebar/sidebar.d.ts +33 -5
  127. package/dist/types/tokens/contract.d.ts +4 -0
  128. package/dist/types/tokens/palette.d.ts +13 -1
  129. package/dist/types/tokens/semantic.d.ts +11 -0
  130. package/package.json +1 -1
@@ -39,7 +39,7 @@
39
39
  & .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; }
40
40
  & .crisp-tabletoolbar-sort-learn svg { flex-shrink: 0; }
41
41
  & .crisp-tabletoolbar-sort-learn:hover { color: var(--crisp-fg-primary); }
42
- & .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; }
42
+ & .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; }
43
43
  & .crisp-tabletoolbar-menu-item:hover { background: var(--crisp-bg-raised); }
44
44
  & .crisp-tabletoolbar-menu-item:disabled { opacity: 0.4; cursor: default; }
45
45
  & .crisp-tabletoolbar-menu-item:disabled:hover { background: none; }
@@ -47,12 +47,30 @@
47
47
  & .crisp-tabletoolbar-menu-item[data-on] svg { color: var(--crisp-bg-brand-solid); }
48
48
  & .crisp-tabletoolbar-menu-item .crisp-tabletoolbar-menu-check { margin-left: auto; }
49
49
  & .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; }
50
- & .crisp-tabletoolbar-menu-sep { height: 1px; background: var(--crisp-border-subtle); margin: var(--crisp-space-0-5) 0; }
50
+ & .crisp-tabletoolbar-menu-sep { height: 1px; border: none; background: var(--crisp-border-subtle); margin: var(--crisp-space-0-5) 0; }
51
+ /* #592: the Filter field picker's nested-scope header (back control +
52
+ search, once drilled into a nestedColumns column) and a search
53
+ 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
54
+ colours ARE measured live: the parent segment muted at the same
55
+ exact color-mix 63% sort-learn above already uses, the
56
+ separator chevron and leaf segment both full fgPrimary (the
57
+ generic menu-item svg rule below defaults every icon to
58
+ fgMuted, so the separator needs its own override to read
59
+ correctly here). */
60
+ & .crisp-tabletoolbar-menu-nesthead { display: flex; align-items: center; gap: var(--crisp-space-1); margin: var(--crisp-space-0-5); }
61
+ & .crisp-tabletoolbar-menu-nesthead .crisp-tabletoolbar-menu-input { flex: 1; margin: 0; }
62
+ & .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; }
63
+ & .crisp-tabletoolbar-menu-back:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
64
+ & .crisp-tabletoolbar-menu-item--expand { justify-content: space-between; }
65
+ & .crisp-tabletoolbar-menu-item-path { display: inline-flex; align-items: center; gap: 2px; min-width: 0; overflow: hidden; }
66
+ & .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); }
67
+ & .crisp-tabletoolbar-menu-item-path-sep { flex-shrink: 0; color: var(--crisp-fg-primary); }
68
+ & .crisp-tabletoolbar-menu-item-path > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
51
69
  & .crisp-tabletoolbar-menu--up { top: auto; bottom: calc(100% + var(--crisp-space-1)); transform-origin: bottom; }
52
70
  & .crisp-tabletoolbar-menu--right { left: auto; right: 0; }
53
71
  & .crisp-tabletoolbar-menu--fixed { position: fixed; top: auto; left: auto; z-index: 40; }
54
72
  & .crisp-tabletoolbar-menu--hdr { min-width: 200px; }
55
- & .crisp-tabletoolbar-menu--op { min-width: 134px; }
73
+ & .crisp-tabletoolbar-menu--op { min-width: 0; }
56
74
  & .crisp-tabletoolbar-menu-item--danger { color: var(--crisp-bg-danger); }
57
75
  & .crisp-tabletoolbar-menu-item--danger svg { color: var(--crisp-bg-danger); }
58
76
  & .crisp-tabletoolbar-menu-item--danger:hover { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
@@ -68,6 +86,32 @@
68
86
  & .crisp-tabletoolbar-count { font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
69
87
  & .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; }
70
88
  & .crisp-tabletoolbar-new:hover { background: var(--crisp-bg-brand-solid-pressed); }
89
+
90
+ & .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; }
91
+ & .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; }
92
+ & .crisp-tabletoolbar-fcond-seg svg { flex-shrink: 0; }
93
+ & .crisp-tabletoolbar-fcond[data-complete] .crisp-tabletoolbar-fcond-seg--field,
94
+ & .crisp-tabletoolbar-fcond[data-complete] .crisp-tabletoolbar-fcond-seg--val { background: var(--crisp-bg-surface); }
95
+ & .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; }
96
+ & .crisp-tabletoolbar-fcond-seg--field svg { color: var(--crisp-fg-muted); }
97
+ /* #592: a nested pick's field segment ("Team › Twitter follower
98
+ count") — measured live: BOTH path segments the same colour (chip context only; the picker's own menu rows keep the parent muted, see
99
+ 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. */
100
+ & .crisp-tabletoolbar-fcond-path { display: inline-flex; align-items: center; gap: 2px; min-width: 0; max-width: 178px; }
101
+ & .crisp-tabletoolbar-fcond-path-seg { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1 1 auto; }
102
+ & .crisp-tabletoolbar-fcond-path-seg:first-child { flex: 0 1 auto; }
103
+ & .crisp-tabletoolbar-fcond-path-sep { flex-shrink: 0; color: inherit; }
104
+ & .crisp-tabletoolbar-fcond-seg--op { background: var(--crisp-bg-surface); color: var(--crisp-fg-muted); }
105
+ & .crisp-tabletoolbar-fcond-seg--val { font-weight: var(--crisp-weight-medium); max-width: 140px; overflow: hidden; text-overflow: ellipsis; }
106
+ & .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); }
107
+ & .crisp-tabletoolbar-fcond-seg--kebab:hover { color: var(--crisp-fg-primary); }
108
+ & .crisp-tabletoolbar-menu--val { min-width: 134px; }
109
+ & .crisp-tabletoolbar-datepop { width: 300px; }
110
+ & .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); }
111
+ & .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; }
112
+ & .crisp-tabletoolbar-datepop-preset:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 8%, transparent); }
113
+ & .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; }
114
+ [dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
71
115
  }
72
116
 
73
117
  @media (prefers-reduced-motion: reduce) {
@@ -40,7 +40,7 @@
40
40
  & .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; }
41
41
  & .crisp-tabletoolbar-sort-learn svg { flex-shrink: 0; }
42
42
  & .crisp-tabletoolbar-sort-learn:hover { color: var(--crisp-fg-primary); }
43
- & .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; }
43
+ & .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; }
44
44
  & .crisp-tabletoolbar-menu-item:hover { background: var(--crisp-bg-raised); }
45
45
  & .crisp-tabletoolbar-menu-item:disabled { opacity: 0.4; cursor: default; }
46
46
  & .crisp-tabletoolbar-menu-item:disabled:hover { background: none; }
@@ -48,12 +48,30 @@
48
48
  & .crisp-tabletoolbar-menu-item[data-on] svg { color: var(--crisp-bg-brand-solid); }
49
49
  & .crisp-tabletoolbar-menu-item .crisp-tabletoolbar-menu-check { margin-left: auto; }
50
50
  & .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; }
51
- & .crisp-tabletoolbar-menu-sep { height: 1px; background: var(--crisp-border-subtle); margin: var(--crisp-space-0-5) 0; }
51
+ & .crisp-tabletoolbar-menu-sep { height: 1px; border: none; background: var(--crisp-border-subtle); margin: var(--crisp-space-0-5) 0; }
52
+ /* #592: the Filter field picker's nested-scope header (back control +
53
+ search, once drilled into a nestedColumns column) and a search
54
+ 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
55
+ colours ARE measured live: the parent segment muted at the same
56
+ exact color-mix 63% sort-learn above already uses, the
57
+ separator chevron and leaf segment both full fgPrimary (the
58
+ generic menu-item svg rule below defaults every icon to
59
+ fgMuted, so the separator needs its own override to read
60
+ correctly here). */
61
+ & .crisp-tabletoolbar-menu-nesthead { display: flex; align-items: center; gap: var(--crisp-space-1); margin: var(--crisp-space-0-5); }
62
+ & .crisp-tabletoolbar-menu-nesthead .crisp-tabletoolbar-menu-input { flex: 1; margin: 0; }
63
+ & .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; }
64
+ & .crisp-tabletoolbar-menu-back:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
65
+ & .crisp-tabletoolbar-menu-item--expand { justify-content: space-between; }
66
+ & .crisp-tabletoolbar-menu-item-path { display: inline-flex; align-items: center; gap: 2px; min-width: 0; overflow: hidden; }
67
+ & .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); }
68
+ & .crisp-tabletoolbar-menu-item-path-sep { flex-shrink: 0; color: var(--crisp-fg-primary); }
69
+ & .crisp-tabletoolbar-menu-item-path > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
52
70
  & .crisp-tabletoolbar-menu--up { top: auto; bottom: calc(100% + var(--crisp-space-1)); transform-origin: bottom; }
53
71
  & .crisp-tabletoolbar-menu--right { left: auto; right: 0; }
54
72
  & .crisp-tabletoolbar-menu--fixed { position: fixed; top: auto; left: auto; z-index: 40; }
55
73
  & .crisp-tabletoolbar-menu--hdr { min-width: 200px; }
56
- & .crisp-tabletoolbar-menu--op { min-width: 134px; }
74
+ & .crisp-tabletoolbar-menu--op { min-width: 0; }
57
75
  & .crisp-tabletoolbar-menu-item--danger { color: var(--crisp-bg-danger); }
58
76
  & .crisp-tabletoolbar-menu-item--danger svg { color: var(--crisp-bg-danger); }
59
77
  & .crisp-tabletoolbar-menu-item--danger:hover { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
@@ -69,6 +87,32 @@
69
87
  & .crisp-tabletoolbar-count { font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
70
88
  & .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; }
71
89
  & .crisp-tabletoolbar-new:hover { background: var(--crisp-bg-brand-solid-pressed); }
90
+
91
+ & .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; }
92
+ & .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; }
93
+ & .crisp-tabletoolbar-fcond-seg svg { flex-shrink: 0; }
94
+ & .crisp-tabletoolbar-fcond[data-complete] .crisp-tabletoolbar-fcond-seg--field,
95
+ & .crisp-tabletoolbar-fcond[data-complete] .crisp-tabletoolbar-fcond-seg--val { background: var(--crisp-bg-surface); }
96
+ & .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; }
97
+ & .crisp-tabletoolbar-fcond-seg--field svg { color: var(--crisp-fg-muted); }
98
+ /* #592: a nested pick's field segment ("Team › Twitter follower
99
+ count") — measured live: BOTH path segments the same colour (chip context only; the picker's own menu rows keep the parent muted, see
100
+ 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. */
101
+ & .crisp-tabletoolbar-fcond-path { display: inline-flex; align-items: center; gap: 2px; min-width: 0; max-width: 178px; }
102
+ & .crisp-tabletoolbar-fcond-path-seg { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1 1 auto; }
103
+ & .crisp-tabletoolbar-fcond-path-seg:first-child { flex: 0 1 auto; }
104
+ & .crisp-tabletoolbar-fcond-path-sep { flex-shrink: 0; color: inherit; }
105
+ & .crisp-tabletoolbar-fcond-seg--op { background: var(--crisp-bg-surface); color: var(--crisp-fg-muted); }
106
+ & .crisp-tabletoolbar-fcond-seg--val { font-weight: var(--crisp-weight-medium); max-width: 140px; overflow: hidden; text-overflow: ellipsis; }
107
+ & .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); }
108
+ & .crisp-tabletoolbar-fcond-seg--kebab:hover { color: var(--crisp-fg-primary); }
109
+ & .crisp-tabletoolbar-menu--val { min-width: 134px; }
110
+ & .crisp-tabletoolbar-datepop { width: 300px; }
111
+ & .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); }
112
+ & .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; }
113
+ & .crisp-tabletoolbar-datepop-preset:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 8%, transparent); }
114
+ & .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; }
115
+ [dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
72
116
  }
73
117
 
74
118
  @media (prefers-reduced-motion: reduce) {
package/dist/tabs.css CHANGED
@@ -8,7 +8,7 @@
8
8
  & .crisp-tabs-tab:hover:not([data-selected]) { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); color: var(--crisp-fg-primary); }
9
9
  & .crisp-tabs-tab[data-selected] { color: var(--crisp-fg-primary); background: var(--crisp-bg-subtle); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); }
10
10
  & .crisp-tabs-tab:focus-visible { outline: 2px solid var(--crisp-bg-brand-solid); outline-offset: 1px; }
11
- & .crisp-tabs-tab-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 16px; padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); font-size: var(--crisp-text-xs); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
11
+ & .crisp-tabs-tab-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 14px; height: 14px; padding: 0 var(--crisp-space-1); border-radius: 4px; background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); font-size: 10px; line-height: 14px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-neutral-soft); }
12
12
  & .crisp-tabs-tab[data-selected] .crisp-tabs-tab-badge { color: var(--crisp-fg-primary); }
13
13
  & .crisp-tabs-indicator { position: absolute; bottom: 0; left: 0; z-index: 1; height: 1px; background: var(--crisp-fg-primary); border-radius: 2px 2px 0 0; transition: transform .2s cubic-bezier(.4,0,.2,1), width .2s cubic-bezier(.4,0,.2,1); pointer-events: none; }
14
14
  & .crisp-tabs-panel { display: flex; flex-direction: column; flex: 1; min-height: 0; padding-top: var(--crisp-space-8); }
@@ -9,7 +9,7 @@
9
9
  & .crisp-tabs-tab:hover:not([data-selected]) { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); color: var(--crisp-fg-primary); }
10
10
  & .crisp-tabs-tab[data-selected] { color: var(--crisp-fg-primary); background: var(--crisp-bg-subtle); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); }
11
11
  & .crisp-tabs-tab:focus-visible { outline: 2px solid var(--crisp-bg-brand-solid); outline-offset: 1px; }
12
- & .crisp-tabs-tab-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 16px; padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); font-size: var(--crisp-text-xs); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
12
+ & .crisp-tabs-tab-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 14px; height: 14px; padding: 0 var(--crisp-space-1); border-radius: 4px; background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); font-size: 10px; line-height: 14px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-neutral-soft); }
13
13
  & .crisp-tabs-tab[data-selected] .crisp-tabs-tab-badge { color: var(--crisp-fg-primary); }
14
14
  & .crisp-tabs-indicator { position: absolute; bottom: 0; left: 0; z-index: 1; height: 1px; background: var(--crisp-fg-primary); border-radius: 2px 2px 0 0; transition: transform .2s cubic-bezier(.4,0,.2,1), width .2s cubic-bezier(.4,0,.2,1); pointer-events: none; }
15
15
  & .crisp-tabs-panel { display: flex; flex-direction: column; flex: 1; min-height: 0; padding-top: var(--crisp-space-8); }
package/dist/tokens.css CHANGED
@@ -5,14 +5,18 @@
5
5
  --crisp-fg-on-tone: #101112;
6
6
  --crisp-bg-surface: #ffffff;
7
7
  --crisp-bg-raised: #f4f4f5;
8
+ --crisp-bg-surface-muted: #f6f7f7;
8
9
  --crisp-border-default: #e4e4e7;
9
10
  --crisp-border-subtle: #eeeff1;
10
11
  --crisp-border-dropzone: #e6e7ea;
12
+ --crisp-border-divider: #e6e7ea;
11
13
  --crisp-ring-neutral: transparent;
12
14
  --crisp-ring-field: rgba(0,0,0,0.06);
13
15
  --crisp-ring-switch: #d9dade;
14
16
  --crisp-bg-tile-active: #ffffff;
15
17
  --crisp-shadow-tile-active: rgba(0,0,0,0.04);
18
+ --crisp-bg-scrim: rgba(0,0,0,0.25);
19
+ --crisp-fg-alert-description: rgba(0,0,0,0.63);
16
20
  --crisp-bg-overlay-frost: #ffffff;
17
21
  --crisp-shadow-overlay1: rgba(28,40,64,0.12);
18
22
  --crisp-shadow-overlay2: rgba(28,40,64,0.16);
@@ -46,7 +50,7 @@
46
50
  --crisp-fg-success-soft: #186b3d;
47
51
  --crisp-fg-warning-soft: #80520d;
48
52
  --crisp-fg-danger-soft: #a33539;
49
- --crisp-fg-neutral-soft: #686870;
53
+ --crisp-fg-neutral-soft: #505155;
50
54
  --crisp-bg-purple-soft: #f5f0ff;
51
55
  --crisp-fg-purple-soft: #6238b5;
52
56
  --crisp-ring-purple-soft: #e8ddfe;
@@ -59,14 +63,18 @@
59
63
  --crisp-fg-on-tone: #101112;
60
64
  --crisp-bg-surface: #0a0a0a;
61
65
  --crisp-bg-raised: #101112;
66
+ --crisp-bg-surface-muted: #101112;
62
67
  --crisp-border-default: #212224;
63
68
  --crisp-border-subtle: #1c1d1f;
64
69
  --crisp-border-dropzone: #212224;
70
+ --crisp-border-divider: #212224;
65
71
  --crisp-ring-neutral: #212224;
66
72
  --crisp-ring-field: #212224;
67
73
  --crisp-ring-switch: #212224;
68
74
  --crisp-bg-tile-active: #101112;
69
75
  --crisp-shadow-tile-active: rgba(0,0,0,0);
76
+ --crisp-bg-scrim: rgba(0,0,0,0.55);
77
+ --crisp-fg-alert-description: rgba(255,255,255,0.6);
70
78
  --crisp-bg-overlay-frost: #1c1d1f;
71
79
  --crisp-shadow-overlay1: rgba(0,0,0,0.48);
72
80
  --crisp-shadow-overlay2: rgba(0,0,0,0.64);
package/dist/tokens.json CHANGED
@@ -7,14 +7,18 @@
7
7
  "fgOnTone": "#101112",
8
8
  "bgSurface": "#ffffff",
9
9
  "bgRaised": "#f4f4f5",
10
+ "bgSurfaceMuted": "#f6f7f7",
10
11
  "borderDefault": "#e4e4e7",
11
12
  "borderSubtle": "#eeeff1",
12
13
  "borderDropzone": "#e6e7ea",
14
+ "borderDivider": "#e6e7ea",
13
15
  "ringNeutral": "transparent",
14
16
  "ringField": "rgba(0,0,0,0.06)",
15
17
  "ringSwitch": "#d9dade",
16
18
  "bgTileActive": "#ffffff",
17
19
  "shadowTileActive": "rgba(0,0,0,0.04)",
20
+ "bgScrim": "rgba(0,0,0,0.25)",
21
+ "fgAlertDescription": "rgba(0,0,0,0.63)",
18
22
  "bgOverlayFrost": "#ffffff",
19
23
  "shadowOverlay1": "rgba(28,40,64,0.12)",
20
24
  "shadowOverlay2": "rgba(28,40,64,0.16)",
@@ -48,7 +52,7 @@
48
52
  "fgSuccessSoft": "#186b3d",
49
53
  "fgWarningSoft": "#80520d",
50
54
  "fgDangerSoft": "#a33539",
51
- "fgNeutralSoft": "#686870",
55
+ "fgNeutralSoft": "#505155",
52
56
  "bgPurpleSoft": "#f5f0ff",
53
57
  "fgPurpleSoft": "#6238b5",
54
58
  "ringPurpleSoft": "#e8ddfe"
@@ -60,14 +64,18 @@
60
64
  "fgOnTone": "#101112",
61
65
  "bgSurface": "#0a0a0a",
62
66
  "bgRaised": "#101112",
67
+ "bgSurfaceMuted": "#101112",
63
68
  "borderDefault": "#212224",
64
69
  "borderSubtle": "#1c1d1f",
65
70
  "borderDropzone": "#212224",
71
+ "borderDivider": "#212224",
66
72
  "ringNeutral": "#212224",
67
73
  "ringField": "#212224",
68
74
  "ringSwitch": "#212224",
69
75
  "bgTileActive": "#101112",
70
76
  "shadowTileActive": "rgba(0,0,0,0)",
77
+ "bgScrim": "rgba(0,0,0,0.55)",
78
+ "fgAlertDescription": "rgba(255,255,255,0.6)",
71
79
  "bgOverlayFrost": "#1c1d1f",
72
80
  "shadowOverlay1": "rgba(0,0,0,0.48)",
73
81
  "shadowOverlay2": "rgba(0,0,0,0.64)",
@@ -117,11 +125,14 @@
117
125
  "line200": "#e4e4e7",
118
126
  "line100": "#eeeff1",
119
127
  "line150": "#e6e7ea",
128
+ "gray25": "#f6f7f7",
120
129
  "ringNeutral": "transparent",
121
130
  "ringField": "rgba(0,0,0,0.06)",
122
131
  "ringSwitch": "#d9dade",
123
132
  "tileActive": "#ffffff",
124
133
  "tileActiveShadow": "rgba(0,0,0,0.04)",
134
+ "bgScrim": "rgba(0,0,0,0.25)",
135
+ "fgAlertDescription": "rgba(0,0,0,0.63)",
125
136
  "overlayFrost": "#ffffff",
126
137
  "shadowOverlay1": "rgba(28,40,64,0.12)",
127
138
  "shadowOverlay2": "rgba(28,40,64,0.16)",
@@ -155,7 +166,7 @@
155
166
  "softSuccessText": "#186b3d",
156
167
  "softWarningText": "#80520d",
157
168
  "softDangerText": "#a33539",
158
- "softNeutralText": "#686870",
169
+ "softNeutralText": "#505155",
159
170
  "purpleTint": "#f5f0ff",
160
171
  "softPurpleText": "#6238b5",
161
172
  "purpleRing": "#e8ddfe"
@@ -169,11 +180,14 @@
169
180
  "line200": "#212224",
170
181
  "line100": "#1c1d1f",
171
182
  "line150": "#212224",
183
+ "gray25": "#101112",
172
184
  "ringNeutral": "#212224",
173
185
  "ringField": "#212224",
174
186
  "ringSwitch": "#212224",
175
187
  "tileActive": "#101112",
176
188
  "tileActiveShadow": "rgba(0,0,0,0)",
189
+ "bgScrim": "rgba(0,0,0,0.55)",
190
+ "fgAlertDescription": "rgba(255,255,255,0.6)",
177
191
  "overlayFrost": "#1c1d1f",
178
192
  "shadowOverlay1": "rgba(0,0,0,0.48)",
179
193
  "shadowOverlay2": "rgba(0,0,0,0.64)",
package/dist/tooltip.css CHANGED
@@ -1,5 +1,5 @@
1
1
  .crisp-tooltip {
2
- position: fixed; z-index: 70; box-sizing: border-box; pointer-events: none; max-width: 260px; padding: var(--crisp-space-1-5) var(--crisp-space-2); border-radius: var(--crisp-radius-md); background: #101112; color: #eeeff1; font-family: var(--crisp-font-sans); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); line-height: 1.45; box-shadow: 0 4px 14px -2px rgba(28,40,64,0.28), 0 0 0 1px rgba(255,255,255,0.04); opacity: 1; transition: opacity 0.12s ease;
2
+ position: fixed; z-index: 70; box-sizing: border-box; pointer-events: none; max-width: 260px; padding: var(--crisp-space-1-5) var(--crisp-space-2); border-radius: var(--crisp-radius-md); background: #101112; color: #eeeff1; font-family: var(--crisp-font-sans); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); line-height: 1.45; box-shadow: rgb(33,34,36) 0 0 0 1px inset, rgba(0,0,0,0.04) 0 0 2px 0, rgba(0,0,0,0.12) 0 1px 3px 0; opacity: 1; transition: opacity 0.12s ease;
3
3
  @starting-style { opacity: 0; }
4
4
  & .crisp-tooltip-reference-row { display: inline-flex; align-items: center; gap: var(--crisp-space-1); }
5
5
  }
@@ -1,6 +1,6 @@
1
1
  @layer crisp-components {
2
2
  .crisp-tooltip {
3
- position: fixed; z-index: 70; box-sizing: border-box; pointer-events: none; max-width: 260px; padding: var(--crisp-space-1-5) var(--crisp-space-2); border-radius: var(--crisp-radius-md); background: #101112; color: #eeeff1; font-family: var(--crisp-font-sans); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); line-height: 1.45; box-shadow: 0 4px 14px -2px rgba(28,40,64,0.28), 0 0 0 1px rgba(255,255,255,0.04); opacity: 1; transition: opacity 0.12s ease;
3
+ position: fixed; z-index: 70; box-sizing: border-box; pointer-events: none; max-width: 260px; padding: var(--crisp-space-1-5) var(--crisp-space-2); border-radius: var(--crisp-radius-md); background: #101112; color: #eeeff1; font-family: var(--crisp-font-sans); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); line-height: 1.45; box-shadow: rgb(33,34,36) 0 0 0 1px inset, rgba(0,0,0,0.04) 0 0 2px 0, rgba(0,0,0,0.12) 0 1px 3px 0; opacity: 1; transition: opacity 0.12s ease;
4
4
  @starting-style { opacity: 0; }
5
5
  & .crisp-tooltip-reference-row { display: inline-flex; align-items: center; gap: var(--crisp-space-1); }
6
6
  }
@@ -7,7 +7,7 @@ declare const spec: {
7
7
  readonly gap: `var(--${string})`;
8
8
  readonly fontFamily: `var(--${string})`;
9
9
  readonly fontWeight: `var(--${string})`;
10
- readonly letterSpacing: "-0.1px";
10
+ readonly letterSpacing: "normal";
11
11
  readonly whiteSpace: "nowrap";
12
12
  };
13
13
  readonly parts: [{
@@ -59,18 +59,22 @@ declare const spec: {
59
59
  readonly height: "16px";
60
60
  readonly paddingInline: `var(--${string})`;
61
61
  readonly fontSize: `var(--${string})`;
62
+ readonly lineHeight: "16px";
62
63
  readonly borderRadius: `var(--${string})`;
63
64
  };
64
65
  readonly medium: {
65
66
  readonly height: "20px";
66
67
  readonly paddingInline: `var(--${string})`;
67
68
  readonly fontSize: `var(--${string})`;
69
+ readonly lineHeight: "16px";
70
+ readonly gap: "3px";
68
71
  readonly borderRadius: `var(--${string})`;
69
72
  };
70
73
  readonly large: {
71
74
  readonly height: `var(--${string})`;
72
75
  readonly paddingInline: "9px";
73
76
  readonly fontSize: `var(--${string})`;
77
+ readonly letterSpacing: "-0.1px";
74
78
  readonly borderRadius: `var(--${string})`;
75
79
  };
76
80
  };
@@ -7,7 +7,7 @@ declare const spec: {
7
7
  readonly gap: `var(--${string})`;
8
8
  readonly fontFamily: `var(--${string})`;
9
9
  readonly fontWeight: `var(--${string})`;
10
- readonly letterSpacing: "-0.14px";
10
+ readonly letterSpacing: "-0.07px";
11
11
  readonly lineHeight: "20px";
12
12
  readonly whiteSpace: "nowrap";
13
13
  readonly border: "none";
@@ -95,10 +95,23 @@ declare const spec: {
95
95
  readonly borderRadius: `var(--${string})`;
96
96
  };
97
97
  readonly md: {
98
- readonly height: "28px";
99
- readonly paddingInline: `var(--${string})`;
100
- readonly fontSize: `var(--${string})`;
101
- readonly borderRadius: `var(--${string})`;
98
+ readonly decls: {
99
+ readonly height: "28px";
100
+ readonly paddingInline: `var(--${string})`;
101
+ readonly fontSize: `var(--${string})`;
102
+ readonly borderRadius: `var(--${string})`;
103
+ };
104
+ readonly parts: [{
105
+ readonly selector: "&[data-icon-start]";
106
+ readonly decls: {
107
+ paddingInlineStart: `var(--${string})`;
108
+ };
109
+ }, {
110
+ readonly selector: "&[data-icon-end]";
111
+ readonly decls: {
112
+ paddingInlineEnd: `var(--${string})`;
113
+ };
114
+ }];
102
115
  };
103
116
  readonly lg: {
104
117
  readonly height: "40px";
@@ -27,13 +27,20 @@ export type ContextMenuProps = {
27
27
  * element, same as any other `asChild` in crisp (`core/primitive.tsx`).
28
28
  */
29
29
  asChild?: boolean;
30
+ /** `"light"` (default) is this component's own original popover surface.
31
+ * `"dark"` is Attio's OWN cell-level context menu (`DataTable`'s #598) —
32
+ * measured live as a fixed, theme-INDEPENDENT dark chrome (background
33
+ * `#101112`, text `#eeeff1`), the same "dark pill" ink pair `Tooltip`
34
+ * already hardcodes for the same reason: this surface doesn't follow the
35
+ * app's light/dark theme, Attio always renders it dark. */
36
+ variant?: "light" | "dark";
30
37
  };
31
38
  /**
32
39
  * A right-click context menu — the popover surface positioned at the cursor.
33
40
  * Wrap the target; right-clicking it opens the menu (flipping at the viewport
34
41
  * edges), closing on select, outside pointer-down, and Escape.
35
42
  */
36
- export declare function ContextMenu({ children, items, menuLabel: menuLabelProp, className, asChild, }: ContextMenuProps): React.JSX.Element;
43
+ export declare function ContextMenu({ children, items, menuLabel: menuLabelProp, className, asChild, variant, }: ContextMenuProps): React.JSX.Element;
37
44
  export declare namespace ContextMenu {
38
45
  var displayName: string;
39
46
  }
@@ -1,4 +1,5 @@
1
1
  import * as React from "react";
2
+ import { type CalcOp } from "../columncalc";
2
3
  type IconType = React.ComponentType<{
3
4
  size?: number;
4
5
  strokeWidth?: number;
@@ -7,6 +8,7 @@ export declare function isLabelTruncated(el: {
7
8
  scrollWidth: number;
8
9
  clientWidth: number;
9
10
  }): boolean;
11
+ export declare function reorderColumns<T>(cols: DataTableColumn<T>[], order: string[] | undefined): DataTableColumn<T>[];
10
12
  export type EntityValue = {
11
13
  name: string;
12
14
  avatar?: string;
@@ -140,10 +142,42 @@ export type DataTableColumn<T> = {
140
142
  format?: (value: unknown, row: T) => string;
141
143
  /** Footer summary for this column (shown when any column supplies one). */
142
144
  summary?: (rows: T[]) => React.ReactNode;
145
+ /**
146
+ * Give this column an aggregation footer via `ColumnCalc`, matching
147
+ * Attio's own per-type set exactly (crisp/#602, checklist G-073;
148
+ * confirmed live against `app.attio.com`'s "Add calculation" menu on
149
+ * both a text and a numeric column): Count empty / Count filled /
150
+ * Percent empty / Percent filled on every column, plus Sum / Average /
151
+ * Min / Max on `"number"`/`"currency"` columns, plus an explicit "None"
152
+ * once one is active. RecordsTable's own OLDER, separate calc footer
153
+ * predates `ColumnCalc` and gives a flat, per-type-WRONG set (no
154
+ * Percent empty/filled at all, "Count all" instead of "Count empty" +
155
+ * "Count filled" as two ops) — that duplicate implementation is not
156
+ * touched here; this is DataTable's own footer only. Wins over
157
+ * `summary` when both are set on the same column. */
158
+ calc?: {
159
+ defaultOp?: CalcOp;
160
+ op?: CalcOp;
161
+ onOpChange?: (op: CalcOp) => void;
162
+ };
143
163
  /** Opt this column out of the header menu's Hide/Move/Rename items. */
144
164
  managed?: boolean;
145
165
  /** Hidden from the grid but still listed in the column manager. */
146
166
  hidden?: boolean;
167
+ /** A "no-edit" marker icon before the resize handle, for a read-only/
168
+ * computed column (crisp/#596, checklist G-027 — seen live on Attio's
169
+ * "Connection strength"/"Last interaction"). Attio's own icon is
170
+ * proprietary and isn't reproduced (AUTHORING.md: never copy Attio's
171
+ * icon set); this uses a Lucide `Lock`, the same substitution every
172
+ * other crisp icon makes. Purely a visual marker — it does NOT disable
173
+ * editing on its own; a column that shouldn't be editable simply
174
+ * doesn't set `editable: true`, the same as any other column.
175
+ * Also used by the cell context menu (crisp/#598, #645): matching
176
+ * Attio's own "no copy handler at all" for a computed field (checklist
177
+ * G-100), a `readOnly` cell's Copy item is disabled and its keyboard/
178
+ * native-copy path writes nothing to the clipboard, and its Clear-value
179
+ * item is disabled (there is nothing editable to clear). */
180
+ readOnly?: boolean;
147
181
  /** `type: "entity"` only (#501) — makes the cell's name its own click
148
182
  * target, separate from the row's own `onRowClick`: the name renders as a
149
183
  * `stopPropagation`-guarded button instead of a plain span, the same
@@ -154,6 +188,30 @@ export type DataTableColumn<T> = {
154
188
  * row's own record — that's what `onRowClick` is for. Ignored on any
155
189
  * other `type`. */
156
190
  onEntityClick?: (row: T) => void;
191
+ /** `type: "entity"` only (crisp/#601, checklist G-048) — a right-aligned
192
+ * "Open preview" icon that appears on row hover (or keyboard focus),
193
+ * alongside `onOpenComments` below. Matches Attio's own measured pair
194
+ * exactly: a 20px ghost button, `radius.sm`, muted at rest, darkening on
195
+ * its own hover. Omit to render neither icon (default). Ignored on any
196
+ * other `type`, same as `onEntityClick`. */
197
+ onOpenPreview?: (row: T) => void;
198
+ /** `type: "entity"` only (crisp/#601, checklist G-048) — the OTHER
199
+ * hover icon next to `onOpenPreview`. Measured live: its button carries
200
+ * `aria-controls="comment-drawer"`, not the "possibly drag-to-reorder"
201
+ * the issue's own first-pass guess landed on — it opens a comment
202
+ * drawer for the row. Once set, renders via `CommentCountBadge`
203
+ * (product/comments, crisp/#625) rather than a plain icon — a persistent
204
+ * dot once the row has ≥1 comment, replaced on hover by the count (see
205
+ * `commentCount`); `onOpenPreview` above rides along as that badge's own
206
+ * second icon instead of rendering separately. Setting `onOpenPreview`
207
+ * with NO `onOpenComments` keeps the old plain-icon-only rendering (a
208
+ * column with a preview affordance but no comments concept at all). */
209
+ onOpenComments?: (row: T) => void;
210
+ /** The row's own comment count, read by `CommentCountBadge` when
211
+ * `onOpenComments` is set. Omit to always pass `0` — the badge still
212
+ * renders (a plain icon, no dot, no digit) once `onOpenComments` is set;
213
+ * it just can't show a real count without this. */
214
+ commentCount?: (row: T) => number;
157
215
  };
158
216
  export type SortState = {
159
217
  key: string;
@@ -218,8 +276,35 @@ export type DataTableProps<T extends {
218
276
  viewSettingsLabel?: string;
219
277
  /** That menu's own "Columns" section heading. */
220
278
  columnsGroupLabel?: string;
279
+ /** Accessible name for the cell context menu (crisp/#598) and the hidden
280
+ * clipboard-proxy textarea its Copy/Cmd+C share (crisp/#645). */
281
+ cellMenuLabel?: string;
282
+ /** The cell context menu's four items, matching Attio's own exactly
283
+ * (checklist G-043 — "identical menu regardless of field type"). */
284
+ copyLabel?: string;
285
+ pasteLabel?: string;
286
+ viewEditHistoryLabel?: string;
287
+ /** "Clear value" commits an empty string via the existing `onEdit`, same
288
+ * as clearing a plain text editor by hand -- no separate callback. */
289
+ clearValueLabel?: string;
221
290
  /** Called with the next column list after a move, rename or hide. */
222
291
  onColumnsChange?: (columns: DataTableColumn<T>[]) => void;
292
+ /**
293
+ * Controlled column order — a plain array of `key`s (crisp/#731), lighter
294
+ * than `onColumnsChange`'s full column definitions (which can't round-trip
295
+ * through JSON: `render`/`accessor`/etc. are functions) and so the shape a
296
+ * saved view actually persists. Omit for an uncontrolled default seeded
297
+ * from `columns`' own order and updated internally by a header drag or the
298
+ * column menu's Move left/right. A key this doesn't mention (a column
299
+ * added since the order was last saved) renders after every key it DOES
300
+ * mention, in `columns`' own relative order — see `reorderColumns`. Column
301
+ * drag-to-reorder itself is always available (like resize); this prop only
302
+ * changes who owns the resulting order.
303
+ */
304
+ columnOrder?: string[];
305
+ /** Called with the next `columnOrder` after a header drag or the column
306
+ * menu's Move left/right — whichever changed the order. */
307
+ onColumnOrderChange?: (order: string[]) => void;
223
308
  /** Group rows under a heading row, the way a grouped view does. */
224
309
  groupBy?: (row: T) => string;
225
310
  /**
@@ -232,6 +317,11 @@ export type DataTableProps<T extends {
232
317
  onRowsReorder?: (rows: T[]) => void;
233
318
  /** aria-label on each row's drag grip (default "Reorder row"). */
234
319
  reorderRowLabel?: string;
320
+ /** aria-label on the entity column's "Open preview" hover icon (crisp/#601;
321
+ * only rendered when a column sets `onOpenPreview`). Also passed through
322
+ * to `CommentCountBadge`'s own `previewLabel` when a column sets
323
+ * `onOpenComments` too (crisp/#601 supersession). */
324
+ openPreviewLabel?: string;
235
325
  /**
236
326
  * Render an error state in place of the rows. Uses the same measured
237
327
  * `EmptyState variant="page"` surface as the zero-row state.
@@ -256,6 +346,13 @@ export type DataTableProps<T extends {
256
346
  * outside `render`'s own output so a hover-only wrapper (a `Tooltip`, say)
257
347
  * can't swallow it. */
258
348
  onEdit?: (id: string, key: string, value: string) => Promise<void> | void;
349
+ /** The cell context menu's "View edit history" item (crisp/#598, checklist
350
+ * G-043 -- Attio's own item carries a "Pro" pill crisp has no billing
351
+ * concept to gate on, so the item itself always renders; see the
352
+ * component's own comment). Omitted: the item still renders (matching
353
+ * Attio, which shows it regardless of field type) but disabled, since
354
+ * there is nothing for it to open. */
355
+ onViewEditHistory?: (id: string, key: string) => void;
259
356
  /** Sticky the first column(s) with a horizontal scroll shadow (default true). */
260
357
  stickyFirst?: boolean;
261
358
  /** Sticky the LAST column with a horizontal scroll shadow, mirroring
@@ -328,7 +425,7 @@ export type DataTableProps<T extends {
328
425
  };
329
426
  export declare function DataTable<T extends {
330
427
  id: string;
331
- }>({ columns: columnsProp, data, selectable, selectedIds, onSelectionChange, selectAllLabel: selectAllLabelProp, selectRowLabel, selectionAnnouncement, columnMenu, onColumnsChange, groupBy, onRowsReorder, error, sort: sortProp, defaultSort, onSortChange, filterable, searchPlaceholder: searchPlaceholderProp, searchLabel: searchLabelProp, onEdit, stickyFirst, stickyLast, scrollProps, locale: localeProp, avatarTone, surface, interactive, onRowClick, onAddRow, addRowLabel: addRowLabelProp, empty: emptyProp, showCount, countLabel, toolbar, height, className, reorderRowLabel: reorderRowLabelProp, sortAscendingLabel: sortAscendingLabelProp, sortDescendingLabel: sortDescendingLabelProp, moveColumnLeftLabel: moveColumnLeftLabelProp, moveColumnRightLabel: moveColumnRightLabelProp, editColumnLabel: editColumnLabelProp, hideColumnLabel: hideColumnLabelProp, renameColumnLabel: renameColumnLabelProp, viewSettingsLabel: viewSettingsLabelProp, columnsGroupLabel: columnsGroupLabelProp, ...rest }: DataTableProps<T>): React.JSX.Element;
428
+ }>({ columns: columnsProp, data, selectable, selectedIds, onSelectionChange, selectAllLabel: selectAllLabelProp, selectRowLabel, selectionAnnouncement, columnMenu, onColumnsChange, columnOrder, onColumnOrderChange, groupBy, onRowsReorder, error, sort: sortProp, defaultSort, onSortChange, filterable, searchPlaceholder: searchPlaceholderProp, searchLabel: searchLabelProp, onEdit, onViewEditHistory, stickyFirst, stickyLast, scrollProps, locale: localeProp, avatarTone, surface, interactive, onRowClick, onAddRow, addRowLabel: addRowLabelProp, empty: emptyProp, showCount, countLabel, toolbar, height, className, reorderRowLabel: reorderRowLabelProp, openPreviewLabel: openPreviewLabelProp, sortAscendingLabel: sortAscendingLabelProp, sortDescendingLabel: sortDescendingLabelProp, moveColumnLeftLabel: moveColumnLeftLabelProp, moveColumnRightLabel: moveColumnRightLabelProp, editColumnLabel: editColumnLabelProp, hideColumnLabel: hideColumnLabelProp, renameColumnLabel: renameColumnLabelProp, viewSettingsLabel: viewSettingsLabelProp, columnsGroupLabel: columnsGroupLabelProp, cellMenuLabel: cellMenuLabelProp, copyLabel: copyLabelProp, pasteLabel: pasteLabelProp, viewEditHistoryLabel: viewEditHistoryLabelProp, clearValueLabel: clearValueLabelProp, ...rest }: DataTableProps<T>): React.JSX.Element;
332
429
  export declare namespace DataTable {
333
430
  var displayName: string;
334
431
  }